ptg10805159
Section 10.18 systemFunction 369
Recall from Section 9.6 that typing the interrupt character causes the interrupt signal to
be sent to all the processes in the foreground process group. Figure10.27 shows the
arrangement of the processes when the editor is running.
login shell forkexec a.out forkexec /bin/sh forkexec /bin/ed
background process group foreground process group
Figure 10.27Foreground and background process groups for Figure10.26
In this example,SIGINTis sent to all three foreground processes. (The shell ignores
it.) As we can see from the output, both thea.outprocess and the editor catch the
signal. But when we’rerunning another program with the system function, we
shouldn’t have both the parent and the child catching the two terminal-generated
signals: interrupt and quit. Instead, these two signals should be sent to the program
that is running: the child. Since the command that is executed bysystemcan be an
interactive command (as is theedprogram in this example) and since the caller of
systemgives up control while the program executes, waiting for it to finish, the caller
ofsystemshould not be receiving these two terminal-generated signals. For this
reason, POSIX.1 specifies that thesystemfunction should ignorethese two signals
while waiting for the command to complete.
Example
Figure10.28 shows an implementation of thesystemfunction with the required signal
handling.
#include <sys/wait.h>
#include <errno.h>
#include <signal.h>
#include <unistd.h>
int
system(const char *cmdstring) /* with appropriate signal handling */
{
pid_t pid;
int status;
struct sigaction ignore, saveintr, savequit;
sigset_t chldmask, savemask;
if (cmdstring == NULL)
return(1); /* always a command processor with UNIX */
ignore.sa_handler = SIG_IGN; /* ignore SIGINT and SIGQUIT */
sigemptyset(&ignore.sa_mask);
ignore.sa_flags = 0;