shithub: trueawk

Download patch

ref: b9c01f51224fd302519e8a35bd06effc06f6d3d1
parent: 01749f04cf1366ac50d998c4747acc89549c082f
parent: 7816d47dc8abc54a77a7a11eff45317b459184bf
author: ozan yigit <ozan.yigit@gmail.com>
date: Sun Dec 26 08:44:58 EST 2021

Merge branch 'mpinjr-fix-ioerrors' into staging

--- a/FIXES
+++ b/FIXES
@@ -25,6 +25,11 @@
 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.
--- a/main.c
+++ b/main.c
@@ -22,7 +22,7 @@
 THIS SOFTWARE.
 ****************************************************************/
 
-const char	*version = "version 20211103";
+const char	*version = "version 20211208";
 
 #define DEBUG
 #include <stdio.h>
--- a/run.c
+++ b/run.c
@@ -1860,8 +1860,8 @@
 	return "???";
 }
 
- Cell *closefile(Node **a, int n)
- {
+Cell *closefile(Node **a, int n)
+{
  	Cell *x;
 	size_t i;
 	bool stat;
@@ -1872,8 +1872,15 @@
  	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 @@
 		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 @@
  	x = gettemp();
 	setfval(x, (Awkfloat) (stat ? -1 : 0));
  	return(x);
- }
+}
 
 void closeall(void)
 {
@@ -1903,18 +1910,24 @@
 	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);
 	}
 }
 
--