WG15 Defect Report Ref: 9945-2-28
Topic: C Binding for execute command


This is an approved interpretation of 9945-2:1993.

.

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