Advanced Programming in the UNIX® Environment

(lily) #1
ptg10805159

Section 10.18 systemFunction 371


POSIX.1 states that ifwaitorwaitpidreturns the status of a child process whileSIGCHLDis
pending, thenSIGCHLDshould not be delivered to the process unless the status of another
child process is also available. FreeBSD 8.0, Mac OS X 10.6.8, and Solaris 10 all implement this
semantic. Linux 3.2.0, however,doesn’t —SIGCHLDremains pending after thesystem
function callswaitpid;when the signal is unblocked, it is delivered to the caller.If we called
waitin thesig_chldfunction in Figure10.26, a Linux system would return−1witherrno
set toECHILD,since thesystemfunction already retrieved the termination status of the child.

Many older texts show the ignoring of the interrupt and quit signals as follows:
if ((pid = fork()) < 0) {
err_sys("fork error");
}else if (pid == 0) {
/* child */
execl(...);
_exit(127);
}

/* parent */
old_intr = signal(SIGINT, SIG_IGN);
old_quit = signal(SIGQUIT, SIG_IGN);
waitpid(pid, &status, 0)
signal(SIGINT, old_intr);
signal(SIGQUIT, old_quit);
The problem with this sequence of code is that we have no guarantee after thefork
regarding whether the parent or child runs first. If the child runs first and the parent
doesn’t run for some time after, an interrupt signal might be generated beforethe parent
is able to change its disposition to be ignored. For this reason, in Figure10.28, we
change the disposition of the signals beforethefork.
Note that we have to reset the dispositions of these two signals in the child before
the call toexecl.This allowsexeclto change their dispositions to the default, based
on the caller’s dispositions, as we described in Section 8.10.

Return Value fromsystem


The return value fromsystemis the termination status of the shell, which isn’t always
the termination status of the command string.We saw some examples in Figure8.23,
and the results were as we expected: if we execute a simple command, such asdate,
the termination status is 0. Executing the shell command exit 44 gave us a
termination status of 44. What happens with signals?
Let’s run the program in Figure8.24 and send some signals to the command that’s
executing:
$tsys "sleep 30"
ˆCnormal termination, exit status = 130 we press the interrupt key
$tsys "sleep 30"
ˆ\sh: 946 Quit we press the quit key
normal termination, exit status = 131
Free download pdf