jeff@fluke.UUCP (Jeff Stearns) (11/28/84)
Index: usr.bin/awk 4.2BSD
Description:
If one redirects awk output through a filter, awk does not wait
for the filter to terminate before awk itself terminates. The
output therefore appears asynchronously while subsequent commands
are being processed. In a shell script, this can be fatal if the
filter is, for example, sort(1).
Repeat-By:
% awk 'END { print "echo hi" | "sh" }' </dev/null
Note that the result is (usually):
% awk 'END { print "echo hi" | "sh" }' </dev/null
% hi
rather than:
% awk 'END { print "echo hi" | "sh" }' </dev/null
hi
%
Try this, and note the changing size of the sorted-output file:
% awk '{ print $0 | "sort -o sorted-output" }' <big-file
% wc sorted-output
% wc sorted-output
% wc sorted-output
% wc sorted-output
Fix:
(Suggestion only)
Before exiting, awk should call pclose(3) on each stream pointer
which was created via a popen(3) in run.c. The pclose(3) will
wait(3) on the subordinate child before returning.
--
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!jeffjeff@fluke.UUCP (Jeff Stearns) (01/15/85)
Index: usr.bin/awk/main.c 4.2BSD
Description:
If one redirects awk output through a filter, awk does not wait
for the filter to terminate before awk itself terminates. The
output therefore appears asynchronously while subsequent commands
are being processed. In a shell script, this can be fatal if the
filter is, for example, sort(1).
Repeat-By:
% awk 'END { print "echo hi" | "sh" }' </dev/null
Note that the result is (usually):
% awk 'END { print "echo hi" | "sh" }' </dev/null
% hi
rather than:
% awk 'END { print "echo hi" | "sh" }' </dev/null
hi
%
Try this, and note the changing size of the sorted-output file:
% awk '{ print $0 | "sort -o sorted-output" }' <big-file
% wc sorted-output
% wc sorted-output
% wc sorted-output
% wc sorted-output
Fix:
The following context diff shows the additions made to the file
/usr/src/usr.bin/awk/main.c:
*** /usr/src/usr.bin/awk/main.old Mon Jan 14 15:51:47 1985
--- /usr/src/usr.bin/awk/main.c Mon Jan 14 15:08:44 1985
***************
*** 91,93
run();
exit(errorflag);
}
--- 91,102 -----
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.
+ */
+ while (wait (0) != -1)
+ ;
exit(errorflag);
}jeff@fluke.UUCP (Jeff Stearns) (01/15/85)
Index: bin/awk/main.c 4.2BSD
Description:
If one redirects awk output through a filter, awk does not wait
for the filter to terminate before awk itself terminates. The
output therefore appears asynchronously while subsequent commands
are being processed. In a shell script, this can be fatal if the
filter is, for example, sort(1).
Repeat-By:
% awk 'END { print "echo hi" | "sh" }' </dev/null
Note that the result is (usually):
% awk 'END { print "echo hi" | "sh" }' </dev/null
% hi
rather than:
% awk 'END { print "echo hi" | "sh" }' </dev/null
hi
%
Try this, and note the changing size of the sorted-output file:
% awk '{ print $0 | "sort -o sorted-output" }' <big-file
% wc sorted-output
% wc sorted-output
% wc sorted-output
% wc sorted-output
Fix:
The following context diff shows the additions made to the file
/usr/src/bin/awk/main.c:
*** /usr/src/bin/awk/main.old Mon Jan 14 15:51:47 1985
--- /usr/src/bin/awk/main.c Mon Jan 14 17:15:56 1985
***************
*** 8,9
#include "awk.h"
#define TOLOWER(c) (isupper(c) ? tolower(c) : c) /* ugh!!! */
--- 8,10 -----
#include "awk.h"
+ #include <sys/param.h>
#define TOLOWER(c) (isupper(c) ? tolower(c) : c) /* ugh!!! */
***************
*** 89,91
run();
exit(errorflag);
}
--- 92,107 -----
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.
+ */
+ {
+ int i; for (i = 0; i < NOFILE; i++)
+ (void) close (i);
+ while (wait (0) != -1)
+ ;
+ }
exit(errorflag);
}
--
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