Advanced Programming in the UNIX® Environment

(lily) #1
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;
Free download pdf