.
Last update: 1997-05-20
9945-2-28
Class: Defect situation
The standards states what it states, and conforming implementations
must conform to this. However, concerns have been raised about this
which are being referred to the Sponsors of the standard for consideration as
a future amendment.
_____________________________________________________________________________
Topic: C Binding for execute command
Relevant Sections: E.9.3.1
Defect Report:
-----------------------
The POSIX.2 specification for system() says that SIGCHLD is
to be blocked (in the parent process) for the duration of
the function. This is intended to prevent interception of a
generated SIGCHLD due to the death of the created process
before the waitpid() can get its status. This is good, but
it doesn't cover another circumstance: when SIGCHLD has been
set to SIG_IGN on many systems.
On these systems, when the caller has set SIGCHLD to be
ignored, no death of child signal is generated and
system()'s waitpid() will return -1 once all children are
finished and have set errno to ECHILD. Since it is quite
likely that the command worked, it is unfortunate that the
caller cannot tell.
Since POSIX.2 explicitly says that SIGCHLD is blocked, the
caller that has set SIGCHLD to be caught can distinguish
between a system() that temporarily resets SIGCHLD to
SIG_DFL and one that temporarily blocks it, since there's a
signal delivered in the second case.
To ensure that an application that sets SIGCHLD to SIG_IGN
does not get "bad" behavior from system(), it would be
better to implement system() along these lines:
1. Set SIGINT, SIGQUIT to SIG_IGN, noting the previous
settings.
2. Block SIGCHLD.
3. Inquire about SIGCHLD's disposition. If currently
SIG_IGN, reset it to SIG_DFL.
4. fork() child:
a. Reset SIGINT, SIGQUIT (and SIGCHLD if touched in
3.)
b. Unblock SIGCHLD.
c. exec the shell command string.
d. _exit(127). (The exec must have failed.)
5. (parent) waitpid(), looping only on EINTR.
6. Reset SIGINT, SIGQUIT (and SIGCHLD if touched in 3.)
7. Unblock SIGCHLD.
8. Return the child's status.
All child processes produced by the exec'd shell command
will have SIGCHLD as the shell and the commands choose, just
like with the current POSIX.2 and XPG4 specification. If
SIGCHLD had a handler, the signal will be delivered just
before the return as it has been blocked until that point.
Again, this matches the standards. For the duration of the
function, SIGCHLD is reset to SIG_DFL only if it came in set
to SIG_IGN.
I believe this will otherwise behave the same as what is
currently defined in the standard as far as any caller can
tell.
I propose making the following changes to 9945-2 Draft 12:
1. Page 1086 - Add the following paragraph after line
11829:
If the setting of SIGCHLD to SIG_IGN precludes
waitpid() from returning the status of any
particular child, as is the case in System V, then
after blocking SIGCHLD, if SIGCHLD is set to
SIG_IGN, SIGCHLD should be temporarily reset to
SIG_DFL. This is not necessary for those
implementations in which waitpid() is unaffected by
the setting of SIGCHLD. For such implementations,
lines <new_lines_added_below> in the sample
system() implementation shown in Figure E-8 would
not be necessary.
2. Page 1087 - Change line 11854 to:
struct sigaction sa, savintr, savequit, savechld;
3. Page 1087 - Add the following after line 11866:
sigaction(SIGCHLD, (struct sigaction *)0, &savechld);
if (savechld.sa_handler == SIG_IGN) {
sa.sa_handler = SIGDFL;
sigaction(SIGCHLD, &sa, (struct sigaction *)0);
}
4. Page 1087 - Add the following after line 11869 and
after line 11884:
if (savechld.sa_handler == SIG_IGN)
sigaction(SIGCHLD, &savechld, (struct sigaction *)0);
WG15 response for 9945-2:1993
-----------------------------------
While the rationale does indeed say what is described by the requestor,
the normative text description of the behavior (Section B.3.1.2) overrides
the description in the rationale, and is the expected behavior. Concerns
about this wording will be forwarded to the Sponsors of the standard.
Rationale for Interpretation:
-----------------------------
None.
_____________________________________________________________________________