Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!uunet!mcsun!hp4nl!star.cs.vu.nl!maart From: maart@cs.vu.nl (Maarten Litmaath) Newsgroups: comp.unix.wizards Subject: Re: sh/csh and wait() Message-ID: <7127@star.cs.vu.nl> Date: 17 Jul 90 02:04:59 GMT References: Sender: news@cs.vu.nl Reply-To: maart@cs.vu.nl (Maarten Litmaath) Organization: VU Dept. of Computer Science, Amsterdam, The Netherlands Lines: 66 In article , Anselmo-Ed@cs.yale.edu (Ed Anselmo) shows a program containing various bugs. )... ) for (i = 2; i < argc; i++) { /* Create chain of processes */ ) pipe (fd); ) if ((pid = fork()) < 0) ) errorExit(-1); ) else if (pid == 0) { /* Child process */ ) close (fd[0]); /* stdout to parent */ ) if (fd[1] != 1) { ) dup2 (fd[1], 1); ) close (fd[1]); ) } `fd[1]' must ALWAYS be closed, even if fd[1] == 1. ) execlp (argv[i-1], argv[i-1],0); /* Overlay by (i-1)st filter */ ) errorExit(-1); ) } ) else { /* Parent process */ ) table[i-1].pid = pid; /* Save child pid */ ) close (fd[1]); ) if (fd[0] != 0) { /* stdin from child */ ) dup2 (fd[0], 0); ) close (fd[0]); ) } `fd[0]' must always be closed as well. ) } ) } ) ) if ((pid = fork()) < 0) /* Create last process in chain */ ) errorExit(-1); ) else if (pid == 0) { /* Child process */ ) execlp(argv[argc-1],argv[argc-1],0); /* Overlay by last filter */ ) errorExit(-1); ) } Add (in parent): close(0); ) table[argc-1].pid = pid; /* Save child pid */ ) ) for (i = 1; i < argc; i++) { /* Wait for all children to die */ ) pid = wait(&status); ) for (j = 1; table[j].pid != pid; j++) ) ; ) table[j].status = status; `pid' is NOT guaranteed to be in the table! (Question: what could have happened?) So change the code to something like this: for (j = 1; j < argc && table[j].pid != pid; j++) ; if (j == argc) i--; /* hack */ else table[j].status = status; ) } )... -- "and with a sudden plop it lands on usenet. what is it? omigosh, it must[...] be a new user! quick kill it before it multiplies!" (Loren J. Miller)