On Mon, Jul 11, 2022 at 08:31:04AM -0600, Todd C. Miller wrote:
> On Sun, 10 Jul 2022 20:58:35 -0900, Philip Guenther wrote:
> 
> > Three thoughts:
> > 1) Since stdio errors are sticky, is there any real advantage to checking
> > each call instead of just checking the final fclose()?

My thinking was that we have no idea how many arguments we're going to
print, so we may as well fail as soon as possible.

Maybe in more complex programs there would be a code-length or
complexity-reducing upside to deferring the ferror(3) check until,
say, the end of a subroutine or something.

> > [...]
> 
> Will that really catch all errors?  From what I can tell, fclose(3)
> can succeed even if the error flag was set.  The pattern I prefer
> is to use a final fflush(3) followed by a call to ferror(3) before
> the fclose(3).

That's weird, I was under the impression POSIX mandated an error case
for the implicit fflush(3) done by fclose(3).  But I'm looking at the
standard and seeing nothing specific.

So, yes?  It is probably more portable to check fflush(3) explicitly?

This feels redundant though.  Like, obviously I want to flush the
descriptor when we close the stream, and obviously I would want to
know if the flush failed.  That's why I'm using stdio.

Index: echo.c
===================================================================
RCS file: /cvs/src/bin/echo/echo.c,v
retrieving revision 1.10
diff -u -p -r1.10 echo.c
--- echo.c      9 Oct 2015 01:37:06 -0000       1.10
+++ echo.c      11 Jul 2022 18:19:39 -0000
@@ -53,12 +53,15 @@ main(int argc, char *argv[])
                nflag = 0;
 
        while (*argv) {
-               (void)fputs(*argv, stdout);
-               if (*++argv)
-                       putchar(' ');
+               if (fputs(*argv, stdout) == EOF)
+                       err(1, "stdout");
+               if (*++argv && putchar(' ') == EOF)
+                       err(1, "stdout");
        }
-       if (!nflag)
-               putchar('\n');
+       if (!nflag && putchar('\n') == EOF)
+               err(1, "stdout");
+       if (fflush(stdout) == EOF || fclose(stdout) == EOF)
+               err(1, "stdout");
 
        return 0;
 }

Reply via email to