.
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. _____________________________________________________________________________