bug-gawk
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [bug-gawk] Behavior of fflush with SIGPIPE on stdout [PATCH]


From: arnold
Subject: Re: [bug-gawk] Behavior of fflush with SIGPIPE on stdout [PATCH]
Date: Thu, 23 Mar 2017 13:36:40 -0600
User-agent: Heirloom mailx 12.4 7/29/08

"Andrew J. Schorr" <address@hidden> wrote:

> I see that you committed the patch. I have a few questions:
>
> - Shouldn't we update ERRNO if fflush causes an I/O error that we ignore
> because non-fatal is set? I don't think your patch does this. I based my patch
> on builtin.c:efwrite, assuming that the behavior should be consistent.
> This is an issue in builtin.c:do_fflush and in io.c:non_fatal_flush_std_file.
>
> - Also in io.c:efwrite, I fixed a bug in the fatal message where it always
> says "standard output", even if the actual problem occurred writing standard
> error:
>
> @@ -139,7 +139,7 @@ wrerror:
>               update_ERRNO_int(errno);
>       else
>               fatal(_("%s to \"%s\" failed (%s)"), from,
> -                     rp ? rp->value : _("standard output"),
> +                     rp ? rp->value : ((fp == stdout) ? _("standard output") 
> : _("standard error")),
>                       errno ? strerror(errno) : _("reason unknown"));
>  }
>  
> - In io.c:flush_io, when flushing all open files in the redirection list,
> an error return from rp->output.gawk_fflush never triggers a fatal error.
> Is that an oversight or intentional? It seems to be inconsistent with
> print/printf behavior, as implemented in builtin.c:efwrite.
>
> Regards,
> Andy

I think this patch addresses all your issues.

Arnold
---------------------------------
diff --git a/builtin.c b/builtin.c
index b92eb19..322df4d 100644
--- a/builtin.c
+++ b/builtin.c
@@ -131,14 +131,18 @@ wrerror:
 #endif
        /* die silently on EPIPE to stdout */
        if (fp == stdout && errno == EPIPE)
-               gawk_exit(EXIT_FATAL);
+               gawk_exit(EXIT_SUCCESS);        // a la SIGPIPE
 
        /* otherwise die verbosely */
        if ((rp != NULL) ? is_non_fatal_redirect(rp->value, strlen(rp->value)) 
: is_non_fatal_std(fp))
                update_ERRNO_int(errno);
        else
                fatal(_("%s to \"%s\" failed (%s)"), from,
-                       rp ? rp->value : _("standard output"),
+                       rp != NULL
+                               ? rp->value
+                               : fp == stdout
+                                       ? _("standard output")
+                                       : _("standard error"),
                        errno ? strerror(errno) : _("reason unknown"));
 }
 
@@ -215,6 +219,8 @@ do_fflush(int nargs)
        /* fflush() */
        if (nargs == 0) {
                status = flush_io();
+               if (status != 0)
+                       update_ERRNO_int(errno);
                return make_number((AWKNUM) status);
        }
 
@@ -225,6 +231,8 @@ do_fflush(int nargs)
        /* fflush("") */
        if (tmp->stlen == 0) {
                status = flush_io();
+               if (status != 0)
+                       update_ERRNO_int(errno);
                DEREF(tmp);
                return make_number((AWKNUM) status);
        }
@@ -251,6 +259,7 @@ do_fflush(int nargs)
                                if (! is_non_fatal_redirect(tmp->stptr, 
tmp->stlen))
                                        fatal(_("fflush: cannot flush file 
`%.*s': %s"),
                                                len, file, strerror(errno));
+                               update_ERRNO_int(errno);
                        }
                } else if ((rp->flag & RED_TWOWAY) != 0)
                                warning(_("fflush: cannot flush: two-way pipe 
`%.*s' has closed write end"),
diff --git a/io.c b/io.c
index 0da2757..5fa3960 100644
--- a/io.c
+++ b/io.c
@@ -1407,6 +1407,7 @@ non_fatal_flush_std_file(FILE *fp)
                                        : _("fflush: cannot flush standard 
error: %s"),
                                                strerror(errno));
                } else {
+                       update_ERRNO_int(errno);
                        warning(fp == stdout
                                ? _("error writing standard output (%s)")
                                : _("error writing standard error (%s)"),
@@ -1434,19 +1435,24 @@ flush_io()
        if (! non_fatal_flush_std_file(stderr))
                status++;
 
+
        // now for all open redirections
        for (rp = red_head; rp != NULL; rp = rp->next) {
+               void (*messagefunc)(const char *mesg, ...) = fatal;
+               if (is_non_fatal_redirect(rp->value, strlen(rp->value)))
+                       messagefunc = warning;
+
                /* flush both files and pipes, what the heck */
                if ((rp->flag & RED_WRITE) != 0 && rp->output.fp != NULL) {
                        if (rp->output.gawk_fflush(rp->output.fp, 
rp->output.opaque) != 0) {
                                if ((rp->flag & RED_PIPE) != 0)
-                                       warning(_("pipe flush of `%s' failed 
(%s)."),
+                                       messagefunc(_("pipe flush of `%s' 
failed (%s)."),
                                                rp->value, strerror(errno));
                                else if ((rp->flag & RED_TWOWAY) != 0)
-                                       warning(_("co-process flush of pipe to 
`%s' failed (%s)."),
+                                       messagefunc(_("co-process flush of pipe 
to `%s' failed (%s)."),
                                                rp->value, strerror(errno));
                                else
-                                       warning(_("file flush of `%s' failed 
(%s)."),
+                                       messagefunc(_("file flush of `%s' 
failed (%s)."),
                                                rp->value, strerror(errno));
                                status++;
                        }




reply via email to

[Prev in Thread] Current Thread [Next in Thread]