Awk doesn't wait for child processes
Jeff Stearns
jeff at fluke.UUCP
Thu Jan 31 09:07:19 AEST 1985
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:
</etc/passwd awk '{ print $0 | "sort" }' >/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<FILENUM; i++) {
+ if (files[i].fp && files[i].CreatedByPopen) {
+ (void) pclose (files[i].fp);
+ files[i].fp = 0;
+ }
+ }
}
--
Jeff Stearns (206) 356-5064
John Fluke Mfg. Co.
P.O. Box C9090 Everett WA 98043
{uw-beaver,decvax!microsof,ucbvax!lbl-csam,allegra,ssc-vax}!fluke!jeff
More information about the Comp.bugs.4bsd.ucb-fixes
mailing list