Make I/O errors fatal instead of mere warnings (#63)
An input/output error indicates a fatal condition, even if it occurs when closing a file. Awk should not return success on I/O error, but treat I/O errors as it already treats write errors. Test case: $ (trap '' PIPE; awk 'BEGIN { print "hi"; }'; echo "E $?" >&2) | : awk: i/o error occurred while closing /dev/stdout source line number 1 E 2 The test case pipes a line into a dummy command that reads no input, with SIGPIPE ignored so we rely on awk's own I/O checking. No write error is detected, because the pipe is buffered; the broken pipe is only detected as an I/O error on closing stdout. Before this commit, "E 0" was printed (indicating status 0/success) because an I/O error merely produced a warning. A shell script was unable to detect the I/O error using the exit status.
This commit is contained in:
parent
2976507cc1
commit
fed1a562c3
4
FIXES
4
FIXES
@ -25,6 +25,10 @@ THIS SOFTWARE.
|
|||||||
This file lists all bug fixes, changes, etc., made since the AWK book
|
This file lists all bug fixes, changes, etc., made since the AWK book
|
||||||
was sent to the printers in August, 1987.
|
was sent to the printers in August, 1987.
|
||||||
|
|
||||||
|
January 9, 2020:
|
||||||
|
Input/output errors on closing files are now fatal instead of
|
||||||
|
mere warnings. Thanks to Martijn Dekker <martijn@inlv.org>.
|
||||||
|
|
||||||
January 5, 2020:
|
January 5, 2020:
|
||||||
Fix a bug in the concatentation of two string constants into
|
Fix a bug in the concatentation of two string constants into
|
||||||
one done in the grammar. Fixes GitHub issue #61. Thanks
|
one done in the grammar. Fixes GitHub issue #61. Thanks
|
||||||
|
8
run.c
8
run.c
@ -1769,13 +1769,13 @@ Cell *closefile(Node **a, int n)
|
|||||||
for (i = 0; i < nfiles; i++) {
|
for (i = 0; i < nfiles; i++) {
|
||||||
if (files[i].fname && strcmp(x->sval, files[i].fname) == 0) {
|
if (files[i].fname && strcmp(x->sval, files[i].fname) == 0) {
|
||||||
if (ferror(files[i].fp))
|
if (ferror(files[i].fp))
|
||||||
WARNING( "i/o error occurred on %s", files[i].fname );
|
FATAL( "i/o error occurred on %s", files[i].fname );
|
||||||
if (files[i].mode == '|' || files[i].mode == LE)
|
if (files[i].mode == '|' || files[i].mode == LE)
|
||||||
stat = pclose(files[i].fp);
|
stat = pclose(files[i].fp);
|
||||||
else
|
else
|
||||||
stat = fclose(files[i].fp);
|
stat = fclose(files[i].fp);
|
||||||
if (stat == EOF)
|
if (stat == EOF)
|
||||||
WARNING( "i/o error occurred closing %s", files[i].fname );
|
FATAL( "i/o error occurred closing %s", files[i].fname );
|
||||||
if (i > 2) /* don't do /dev/std... */
|
if (i > 2) /* don't do /dev/std... */
|
||||||
xfree(files[i].fname);
|
xfree(files[i].fname);
|
||||||
files[i].fname = NULL; /* watch out for ref thru this */
|
files[i].fname = NULL; /* watch out for ref thru this */
|
||||||
@ -1795,13 +1795,13 @@ void closeall(void)
|
|||||||
for (i = 0; i < FOPEN_MAX; i++) {
|
for (i = 0; i < FOPEN_MAX; i++) {
|
||||||
if (files[i].fp) {
|
if (files[i].fp) {
|
||||||
if (ferror(files[i].fp))
|
if (ferror(files[i].fp))
|
||||||
WARNING( "i/o error occurred on %s", files[i].fname );
|
FATAL( "i/o error occurred on %s", files[i].fname );
|
||||||
if (files[i].mode == '|' || files[i].mode == LE)
|
if (files[i].mode == '|' || files[i].mode == LE)
|
||||||
stat = pclose(files[i].fp);
|
stat = pclose(files[i].fp);
|
||||||
else
|
else
|
||||||
stat = fclose(files[i].fp);
|
stat = fclose(files[i].fp);
|
||||||
if (stat == EOF)
|
if (stat == EOF)
|
||||||
WARNING( "i/o error occurred while closing %s", files[i].fname );
|
FATAL( "i/o error occurred while closing %s", files[i].fname );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -466,3 +466,8 @@ echo '' >foo0
|
|||||||
$awk 'END { print NF, $0 }' foo0 >foo1
|
$awk 'END { print NF, $0 }' foo0 >foo1
|
||||||
awk '{ print NF, $0 }' foo0| tail -1 >foo2
|
awk '{ print NF, $0 }' foo0| tail -1 >foo2
|
||||||
cmp -s foo1 foo2 || echo 'BAD: T.misc END must preserve $0'
|
cmp -s foo1 foo2 || echo 'BAD: T.misc END must preserve $0'
|
||||||
|
|
||||||
|
# Check for nonzero exit status on I/O error.
|
||||||
|
echo 'E 2' >foo1
|
||||||
|
(trap '' PIPE; "$awk" 'BEGIN { print "hi"; }' 2>/dev/null; echo "E $?" >foo2) | :
|
||||||
|
cmp -s foo1 foo2 || echo 'BAD: T.misc exit status on I/O error'
|
||||||
|
Loading…
Reference in New Issue
Block a user