Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.2.fluke 9/24/84; site fluke.UUCP Path: utzoo!watmath!clyde!burl!ulysses!mhuxr!ihnp4!houxm!vax135!cornell!uw-beaver!microsoft!fluke!jeff From: jeff@fluke.UUCP (Jeff Stearns) Newsgroups: net.bugs.4bsd Subject: Awk doesn't wait for child processes Message-ID: <2120@vax4.fluke.UUCP> Date: Wed, 30-Jan-85 18:07:19 EST Article-I.D.: vax4.2120 Posted: Wed Jan 30 18:07:19 1985 Date-Received: Sat, 2-Feb-85 00:38:13 EST Organization: John Fluke Mfg. Co., Inc., Everett, WA Lines: 116 e shell scripts to fail in mysterious and non-deterministic ways. Repeat-By: Arrange for awk to pipe some data to a slow-running process such as sort. When awk is finished, it will exit without waiting for its child: /tmp/awkout # Now note that the size changes as sort continues to run: wc /tmp/awkout wc /tmp/awkout wc /tmp/awkout wc /tmp/awkout Fix: My previous bug report included a bogus bug fix which would fail under some race conditions. Here is a proper bug fix which works. Two files are affected: main.c and run.c: *** main.c.old Wed Jan 30 14:47:01 1985 --- main.c Wed Jan 30 14:45:27 1985 *************** *** 89,94 exit(0); } run(); exit(errorflag); } --- 89,102 ----- exit(0); } run(); + /* + * Awk may have spawned some children (printf "....." | sort). + * The children may still be alive (sort can be quite slow). + * It is a bad idea to exit before our children have completed, + * as the next command to be executed may depend on ALL of our + * processing being complete. Thus we wait for our kids. + */ + WaitForChildren(); exit(errorflag); } *** run.c.old Wed Jan 30 14:47:21 1985 --- run.c Wed Jan 30 14:45:50 1985 *************** *** 13,18 { FILE *fp; char *fname; } files[FILENUM]; FILE *popen(); --- 13,19 ----- { FILE *fp; char *fname; + int CreatedByPopen; } files[FILENUM]; FILE *popen(); *************** *** 858,863 if (i >= FILENUM) error(FATAL, "too many output files %d", i); if (a == '|') /* a pipe! */ files[i].fp = popen(x.optr->sval, "w"); else if (a == APPEND) files[i].fp = fopen(x.optr->sval, "a"); --- 859,865 ----- if (i >= FILENUM) error(FATAL, "too many output files %d", i); if (a == '|') /* a pipe! */ + files[i].CreatedByPopen = 1, /* so we remember to pclose it */ files[i].fp = popen(x.optr->sval, "w"); else if (a == APPEND) files[i].fp = fopen(x.optr->sval, "a"); *************** *** 872,875 fflush(files[i].fp); /* in case someone is waiting for the output */ #endif tempfree(x); } --- 874,894 ----- fflush(files[i].fp); /* in case someone is waiting for the output */ #endif tempfree(x); + } + + /* + * Awk may have spawned some children (printf "....." | sort). + * The children may still be alive (sort can be quite slow). + * It is a bad idea to exit before our children have completed, + * as the next command to be executed may depend on ALL of our + * processing being complete. Thus we wait for our kids. + */ + WaitForChildren () { + int i; + for (i=0; i