aboutsummaryrefslogtreecommitdiff
path: root/run.c
diff options
context:
space:
mode:
authorTodd C. Miller <Todd.Miller@sudo.ws>2020-07-27 01:03:58 -0600
committerGitHub <noreply@github.com>2020-07-27 10:03:58 +0300
commitb82b649aa65fbdff45869d1fd6d72fd2b85946cd (patch)
tree7c03c0af92460196857a670d65d716c578109c97 /run.c
parent2a4146ec3027d12e375209e03ed1c5a9ab230da4 (diff)
downloadone-true-awk-b82b649aa65fbdff45869d1fd6d72fd2b85946cd.tar.gz
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.
Diffstat (limited to 'run.c')
-rw-r--r--run.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/run.c b/run.c
index 98787f1..bb6b7fe 100644
--- a/run.c
+++ b/run.c
@@ -1846,7 +1846,10 @@ const char *filename(FILE *fp)
continue;
if (ferror(files[i].fp))
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;
else
stat = fclose(files[i].fp) == EOF;
@@ -1856,6 +1859,7 @@ const char *filename(FILE *fp)
xfree(files[i].fname);
files[i].fname = NULL; /* watch out for ref thru this */
files[i].fp = NULL;
+ break;
}
tempfree(x);
x = gettemp();
@@ -1873,8 +1877,12 @@ void closeall(void)
continue;
if (ferror(files[i].fp))
FATAL( "i/o error occurred on %s", files[i].fname );
+ if (files[i].fp == stdin)
+ continue;
if (files[i].mode == '|' || files[i].mode == LE)
stat = pclose(files[i].fp) == -1;
+ else if (files[i].fp == stdout || files[i].fp == stderr)
+ stat = fflush(files[i].fp) == EOF;
else
stat = fclose(files[i].fp) == EOF;
if (stat)