aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorozan yigit <ozan.yigit@gmail.com>2021-12-26 13:44:58 -0500
committerozan yigit <ozan.yigit@gmail.com>2021-12-26 13:44:58 -0500
commitb9c01f51224fd302519e8a35bd06effc06f6d3d1 (patch)
treedaa1e0e59f05398663fb0c451e8b5104f002505d
parent01749f04cf1366ac50d998c4747acc89549c082f (diff)
parent7816d47dc8abc54a77a7a11eff45317b459184bf (diff)
downloadone-true-awk-b9c01f51224fd302519e8a35bd06effc06f6d3d1.tar.gz
Merge branch 'mpinjr-fix-ioerrors' into staging
-rw-r--r--FIXES5
-rw-r--r--main.c2
-rw-r--r--run.c37
3 files changed, 31 insertions, 13 deletions
diff --git a/FIXES b/FIXES
index f6eb98c..8e49fe9 100644
--- a/FIXES
+++ b/FIXES
@@ -25,6 +25,11 @@ THIS SOFTWARE.
This file lists all bug fixes, changes, etc., made since the AWK book
was sent to the printers in August, 1987.
+December 8, 2021:
+ The error handling in closefile and closeall was mangled. Long
+ standing warnings had been made fatal and some fatal errors went
+ undetected. Thanks to Miguel Pineiro Jr. <mpj@pineiro.cc>.
+
Nov 03, 2021:
getline accesses uninitialized data after getrec()
returns 0 on EOF and leaves the contents of buf unchanged.
diff --git a/main.c b/main.c
index ee8b82b..986f1a3 100644
--- a/main.c
+++ b/main.c
@@ -22,7 +22,7 @@ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
-const char *version = "version 20211103";
+const char *version = "version 20211208";
#define DEBUG
#include <stdio.h>
diff --git a/run.c b/run.c
index 3ad9ecf..f5c19a1 100644
--- a/run.c
+++ b/run.c
@@ -1860,8 +1860,8 @@ const char *filename(FILE *fp)
return "???";
}
- Cell *closefile(Node **a, int n)
- {
+Cell *closefile(Node **a, int n)
+{
Cell *x;
size_t i;
bool stat;
@@ -1872,8 +1872,15 @@ const char *filename(FILE *fp)
for (i = 0; i < nfiles; i++) {
if (!files[i].fname || strcmp(x->sval, files[i].fname) != 0)
continue;
- if (ferror(files[i].fp))
- FATAL("i/o error occurred on %s", files[i].fname);
+ if (files[i].mode == GT || files[i].mode == '|')
+ fflush(files[i].fp);
+ if (ferror(files[i].fp)) {
+ if ((files[i].mode == GT && files[i].fp != stderr)
+ || files[i].mode == '|')
+ FATAL("write error on %s", files[i].fname);
+ else
+ WARNING("i/o error occurred on %s", files[i].fname);
+ }
if (files[i].fp == stdin || files[i].fp == stdout ||
files[i].fp == stderr)
stat = freopen("/dev/null", "r+", files[i].fp) == NULL;
@@ -1882,7 +1889,7 @@ const char *filename(FILE *fp)
else
stat = fclose(files[i].fp) == EOF;
if (stat)
- FATAL("i/o error occurred closing %s", files[i].fname);
+ WARNING("i/o error occurred closing %s", files[i].fname);
if (i > 2) /* don't do /dev/std... */
xfree(files[i].fname);
files[i].fname = NULL; /* watch out for ref thru this */
@@ -1893,7 +1900,7 @@ const char *filename(FILE *fp)
x = gettemp();
setfval(x, (Awkfloat) (stat ? -1 : 0));
return(x);
- }
+}
void closeall(void)
{
@@ -1903,18 +1910,24 @@ void closeall(void)
for (i = 0; i < nfiles; i++) {
if (! files[i].fp)
continue;
- if (ferror(files[i].fp))
- FATAL( "i/o error occurred on %s", files[i].fname );
- if (files[i].fp == stdin)
+ if (files[i].mode == GT || files[i].mode == '|')
+ fflush(files[i].fp);
+ if (ferror(files[i].fp)) {
+ if ((files[i].mode == GT && files[i].fp != stderr)
+ || files[i].mode == '|')
+ FATAL("write error on %s", files[i].fname);
+ else
+ WARNING("i/o error occurred on %s", files[i].fname);
+ }
+ if (files[i].fp == stdin || files[i].fp == stdout ||
+ files[i].fp == stderr)
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)
- FATAL( "i/o error occurred while closing %s", files[i].fname );
+ WARNING("i/o error occurred while closing %s", files[i].fname);
}
}