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

Re: fork()/exec() dumping



On Tue, 22 Jun 1999 17:02:24 -0400, kahn@zk3.dec.com (Andy Kahn) wrote:
> On Tue, Jun 22, 1999 at 09:14:44PM +0200, Erik Mouw wrote:
>> This is becoming a FAQ. Never mind, here we go again:
> 
> Indeed, this should be in a FAQ somewhere.  Your program below isn't
> very clear either:

It's not my example. It's the standard fork() code snippet. You can find
it in every Unix programming book because it is copied from the original
Unix programmers manual (Written by Dennis Ritchie and Ken Thomson IIRC,
can't find my copy now. It's *somewhere* in a box, that's the only thing
you know for sure when you moved ;-).

..

> system() will also do a fork(), followed by exec() and wait().
> Further more, system() fork's /bin/sh, to interpret the command, which
> unless it's a builtin sh command, will then fork *AGAIN* to carry out
> the command.

You're right. It's because I pasted it from a reply I posted a week or two
ago which actually used system() instead of one of the exec() functions.

> Effectively, there are now three child processes where most likely,
> most people just want one.

But the nice thing about system() is that you can build a command line
with snprintf() without having to mess with the execv*() char *argv[]
argument ;-).

> Your code example is a good idea, but the reasons behind using _exit()
> instead of exit() clearly needs to be stuck in a FAQ (and not any of
> the invisible GTK documentation).

OK, here is the example again, but this time with an exec() function.

  pid_t pid;
  int status;

  pid = fork();

  if(pid < 0)
    {
      /* error! */
      perror("fork");
      exit(-1);
    }
  else if(pid == 0) /* child */
    {
      /* child code: start an xterm with an ftp session */
      execlp("/usr/bin/X11/xterm", "-e", "ftp", "ftp.gtk.org", NULL);
    }
  else
    {
       /* parent code: just wait for the child to exit */
       waitpid(pid, &status, WUNTRACED); /* anti zombie */
    } 

The example above is more or less an implementation of system(), except
that it doesn't call a shell to execute the program. Instead of just
waiting until the child dies, the parent can also install a signal handler
for SIGCHLD. Or with GTK you can use gtk_timeout_add() to add a timeout
function that periodically calls waitpid(-1, &status, WNOHANG).

The reason why in the original _exit() was called instead of exit(), is
that exit() calls all the installed atexit() handlers, including the one
that shuts down the X connection with the X display. So if the child calls
exit(), it shuts down the parents X connection and the parent will no
longer be able to display.


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]