]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
tee: avoid undefined behavior after fclose()
authorPádraig Brady <P@draigBrady.com>
Mon, 13 Mar 2023 21:26:21 +0000 (21:26 +0000)
committerPádraig Brady <P@draigBrady.com>
Mon, 13 Mar 2023 21:26:21 +0000 (21:26 +0000)
* iopoll.c (fclose_wait): Rename from confusing fclose_nonblock name.
Also adjust to do no operations on the stream after fclose()
as this is undefined. Instead use fflush() to determine EAGAIN status.
(fwrite_wait): Renamed from confusing fwrite_nonblock name.

src/iopoll.c
src/iopoll.h
src/tee.c

index b211dafc8b872120a7c4ee48ecb60c2527ff2913..321a1245e21e8c903ff0328d8ebbca0aebae308f 100644 (file)
@@ -204,23 +204,25 @@ fail:
 /* wrapper for fclose() that also waits for F if non blocking.  */
 
 extern bool
-fclose_nonblock (FILE *f)
+fclose_wait (FILE *f)
 {
   for (;;)
     {
-      if (fclose (f) == 0)
-        return true;
+      if (fflush (f) == 0)
+        break;
 
       if (! fwait_for_nonblocking_write (f))
-        return false;
+        break;
     }
+
+  return fclose (f) == 0;
 }
 
 
 /* wrapper for fwrite() that also waits for F if non blocking.  */
 
 extern bool
-fwrite_nonblock (char const *buf, ssize_t size, FILE *f)
+fwrite_wait (char const *buf, ssize_t size, FILE *f)
 {
   for (;;)
     {
index 79d5ccfeff7d94835fac2e2acfb3b06e78cb5d4f..0177a4d25c40822288bdab30ddea9474dfa4d875 100644 (file)
@@ -5,5 +5,5 @@ int iopoll (int fdin, int fdout, bool block);
 bool iopoll_input_ok (int fdin);
 bool iopoll_output_ok (int fdout);
 
-bool fclose_nonblock (FILE *f);
-bool fwrite_nonblock (char const *buf, ssize_t size, FILE *f);
+bool fclose_wait (FILE *f);
+bool fwrite_wait (char const *buf, ssize_t size, FILE *f);
index 7785942d6f4881c369e64cdd11c303f4049b4ae8..a1c0578162fdb4f7e50345d384ebc7d3cb4da3d9 100644 (file)
--- a/src/tee.c
+++ b/src/tee.c
@@ -314,7 +314,7 @@ tee_files (int nfiles, char **files, bool pipe_check)
          Standard output is the first one.  */
       for (i = 0; i <= nfiles; i++)
         if (descriptors[i]
-            && ! fwrite_nonblock (buffer, bytes_read, descriptors[i]))
+            && ! fwrite_wait (buffer, bytes_read, descriptors[i]))
           {
             if (fail_output (descriptors, files, i))
               ok = false;
@@ -332,7 +332,7 @@ tee_files (int nfiles, char **files, bool pipe_check)
 
   /* Close the files, but not standard output.  */
   for (i = 1; i <= nfiles; i++)
-    if (descriptors[i] && ! fclose_nonblock (descriptors[i]))
+    if (descriptors[i] && ! fclose_wait (descriptors[i]))
       {
         error (0, errno, "%s", quotef (files[i]));
         ok = false;