Avoid using stdio streams after they have been closed. (#89)
* In closeall(), skip stdin and flush std{err,out} instead of closing. Otherwise awk could fclose(stdin) twice (it may appear more than once) and closing stderr means awk cannot report errors with other streams. For example, "awk 'BEGIN { getline < "-" }' < /dev/null" will call fclose(stdin) twice, with undefined results. * If closefile() is called on std{in,out,err}, freopen() /dev/null instead. Otherwise, awk will continue trying to perform I/O on a closed stdio stream, the behavior of which is undefined.
This commit is contained in:
parent
2a4146ec30
commit
b82b649aa6
10
run.c
10
run.c
@ -1846,7 +1846,10 @@ const char *filename(FILE *fp)
|
|||||||
continue;
|
continue;
|
||||||
if (ferror(files[i].fp))
|
if (ferror(files[i].fp))
|
||||||
FATAL("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].fp == stdin || files[i].fp == stdout ||
|
||||||
|
files[i].fp == stderr)
|
||||||
|
stat = freopen("/dev/null", "r+", files[i].fp) == NULL;
|
||||||
|
else if (files[i].mode == '|' || files[i].mode == LE)
|
||||||
stat = pclose(files[i].fp) == -1;
|
stat = pclose(files[i].fp) == -1;
|
||||||
else
|
else
|
||||||
stat = fclose(files[i].fp) == EOF;
|
stat = fclose(files[i].fp) == EOF;
|
||||||
@ -1856,6 +1859,7 @@ const char *filename(FILE *fp)
|
|||||||
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 */
|
||||||
files[i].fp = NULL;
|
files[i].fp = NULL;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
tempfree(x);
|
tempfree(x);
|
||||||
x = gettemp();
|
x = gettemp();
|
||||||
@ -1873,8 +1877,12 @@ void closeall(void)
|
|||||||
continue;
|
continue;
|
||||||
if (ferror(files[i].fp))
|
if (ferror(files[i].fp))
|
||||||
FATAL( "i/o error occurred on %s", files[i].fname );
|
FATAL( "i/o error occurred on %s", files[i].fname );
|
||||||
|
if (files[i].fp == stdin)
|
||||||
|
continue;
|
||||||
if (files[i].mode == '|' || files[i].mode == LE)
|
if (files[i].mode == '|' || files[i].mode == LE)
|
||||||
stat = pclose(files[i].fp) == -1;
|
stat = pclose(files[i].fp) == -1;
|
||||||
|
else if (files[i].fp == stdout || files[i].fp == stderr)
|
||||||
|
stat = fflush(files[i].fp) == EOF;
|
||||||
else
|
else
|
||||||
stat = fclose(files[i].fp) == EOF;
|
stat = fclose(files[i].fp) == EOF;
|
||||||
if (stat)
|
if (stat)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user