[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

Re: fork()/exec() dumping



On Wed, 23 Jun 1999 09:26:55 -0600 (MDT), Michael J. Hammel wrote:
> Thus spoke Erik Mouw
>> On Tue, 22 Jun 1999 14:51:12 -0600 (MDT), gtk-app-devel-list@redhat.com
> (Michael J. Hammel) wrote:
>> > You don't want to wait on the child if you exec().  You should do a SIG_IGN
>> > for children that call exec() or you'll end up with zombies.
>> 
>> True, but that only works with the System V SIGCLD signal. AFAIK, it is
>> not supported by the POSIX SIGCHLD (note the "H") signal. Since most
>> modern Unix variants claim to be POSIX complaint, you have to
>> wait()/waitpid() for the child.
> 
> According to Stevens:
> 
>    POSIX.1 does not specify what happens when SIGCHLD is ignored, so this
>    behaviour [ignoring the child] is allowed.

I also read it, but I interpreted it as: POSIX does not specify it, so it
is possible that you still create zombies when you ignore the signal. To
avoid zombies, always use waitpid().

>    4.3+BSD always generates zombies if SIGCHLD is ignored.  If we want to
>    avoid zombies, we have to wati for our children.
> 
>    With SVR4, if either signal or sigset is called to set the disposition of
>    SIGCHLD to be ignored, zombies ar never generated.

Which led me to the conclusion: the most portable way to avoid zombies is
to waitpid() for the child.

> The issue of zombie creation is related to whether a signal handler has
> been installed or not.  If no signal handler is installed (SIG_IGN is set)
> then for both POSIX and SVR4 boxes you don't need to wait for the child to
> exit.  If you're on a BSD 4.3 derived Unix box (that is not POSIX compliant), 
> you'd probably want to do the waitpid() call.

See my comments above. I think we mean the same, I want to make code that
works on all platform while you assume POSIX compatibility.

> The problem here is that the original question related to the use of
> exec().  Since exec() doesn't exit the child routine - it replaces the
> running process with another process - the child never returns.  It's
> questionable whether waiting on the child is "a good thing" or not.

The child actually does return. The exec() system call overlays the
current process with a new process. The new process becomes the child, so
if it exit()s the parent still has to handle its death somehow. Like in
this next figure:

  father, name = /bin/bash, pid = 42, ppid=41
     |
     |
    fork() ----------> child, name = /bin/bash,  pid = 43, ppid=42
     |                    |
     |                    |
     |                   exec("/bin/ls")
     |                    |
     |                 child, name = /bin/ls, pid = 43, ppid=42
     |                    |
     |                    |
     |<--- SIGCHLD  ---- exit()
     |                    |   child is a zombie now
     |                    |
    waitpid() <-----------+ exit status
     |                        exit status collected by parent, child is dead
     |

pid = Process ID, ppid = Parent Process ID.

I can't find this particular figure in Stevens, Figure 9.9 (p. 254,
section 9.9 "Shell execution of Programs") comes close but forgets about
the exit() calls. I must have seen it in the Unix Programming Manual.
Anyway, I hope my figure explains what I mean.


Erik
   
-- 
J.A.K. (Erik) Mouw, Information and Communication Theory Group, Department
of Electrical Engineering, Faculty of Information Technology and Systems,
Delft University of Technology, PO BOX 5031,  2600 GA Delft, The Netherlands
Phone: +31-15-2785859  Fax: +31-15-2781843  Email J.A.K.Mouw@its.tudelft.nl
WWW: http://www-ict.its.tudelft.nl/~erik/




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]