summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArnold D. Robbins <arnold@skeeve.com>2023-12-21 13:10:37 +0200
committerArnold D. Robbins <arnold@skeeve.com>2023-12-21 13:10:37 +0200
commitf346791bba5d53a516571e9826805d884097a1fa (patch)
treecf5501cf08501dd766f37bbecd82afe8ceb632e1
parent605a77387523a07e3636d3a72c7a612dc15a5b31 (diff)
downloadgawk-f346791bba5d53a516571e9826805d884097a1fa.tar.gz
Attempt to close SIGPIPE race condition.
-rw-r--r--ChangeLog15
-rw-r--r--awk.h5
-rw-r--r--builtin.c2
-rw-r--r--io.c20
4 files changed, 37 insertions, 5 deletions
diff --git a/ChangeLog b/ChangeLog
index 4a3d20d..8b4a012 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2023-12-21 Arnold D. Robbins <arnold@skeeve.com>
+
+ Try to close a race condition window on SIGPIPE. See the thread at
+ https://lists.gnu.org/archive/html/bug-gawk/2023-12/msg00011.html.
+ Thanks to Andreas Schwab <schwab@suse.de>.
+
+ * awk.h (ignore_sigpipe, set_sigpipe_to_default): Remove decls,
+ they're not functions.
+ (do_nothing_on_signal): Add declaration.
+ (silent_catch_sigpipe): New macro.
+ * builtin.c (do_system): Replace call of set_sigpipe_to_default()
+ with call to silent_catch_sigpipe().
+ * io.c (redirect_string, gawk_popen): Ditto.
+ (do_nothing_on_signal): New function.
+
2023-12-12 Eli Zaretskii <eliz@gnu.org>
* io.c (redirect_string): Check registered parsers before failing
diff --git a/awk.h b/awk.h
index 8e38976..08ef36c 100644
--- a/awk.h
+++ b/awk.h
@@ -1668,8 +1668,7 @@ extern bool inrec(IOBUF *iop, int *errcode);
extern int nextfile(IOBUF **curfile, bool skipping);
extern bool is_non_fatal_std(FILE *fp);
extern bool is_non_fatal_redirect(const char *str, size_t len);
-extern void ignore_sigpipe(void);
-extern void set_sigpipe_to_default(void);
+extern void do_nothing_on_signal(int sig);
extern bool non_fatal_flush_std_file(FILE *fp);
extern size_t gawk_fwrite(const void *buf, size_t size, size_t count, FILE *fp, void *opaque);
@@ -2160,9 +2159,11 @@ str_terminate_f(NODE *n, char *savep)
#define ignore_sigpipe() signal(SIGPIPE, SIG_IGN)
#define set_sigpipe_to_default() signal(SIGPIPE, SIG_DFL)
#define die_via_sigpipe() (signal(SIGPIPE, SIG_DFL), kill(getpid(), SIGPIPE))
+#define silent_catch_sigpipe() signal(SIGPIPE, do_nothing_on_signal)
#else
#define ignore_sigpipe()
#define set_sigpipe_to_default()
+#define silent_catch_sigpipe()
#ifdef __MINGW32__
/* 0xC0000008 is EXCEPTION_INVALID_HANDLE, somewhat appropriate for EPIPE */
#define die_via_sigpipe() exit(0xC0000008)
diff --git a/builtin.c b/builtin.c
index 6fc76b7..84a0dff 100644
--- a/builtin.c
+++ b/builtin.c
@@ -2269,7 +2269,7 @@ do_system(int nargs)
cmd[tmp->stlen] = '\0';
os_restore_mode(fileno(stdin));
- set_sigpipe_to_default();
+ silent_catch_sigpipe();
status = system(cmd);
/*
diff --git a/io.c b/io.c
index 3ffac79..881178e 100644
--- a/io.c
+++ b/io.c
@@ -947,7 +947,7 @@ redirect_string(const char *str, size_t explen, bool not_string,
(void) flush_io();
os_restore_mode(fileno(stdin));
- set_sigpipe_to_default();
+ silent_catch_sigpipe();
/*
* Don't check failure_fatal; see input pipe below.
* Note that the failure happens upon failure to fork,
@@ -2774,7 +2774,7 @@ gawk_popen(const char *cmd, struct redirect *rp)
FILE *current;
os_restore_mode(fileno(stdin));
- set_sigpipe_to_default();
+ silent_catch_sigpipe();
current = popen(cmd, binmode("r"));
@@ -4593,3 +4593,19 @@ avoid_flush(const char *name)
return in_PROCINFO(bufferpipe, NULL, NULL) != NULL
|| in_PROCINFO(name, bufferpipe, NULL) != NULL;
}
+
+/* do_nothing_on_signal --- empty signal catcher for SIGPIPE */
+
+/*
+ * See the thread starting at
+ * https://lists.gnu.org/archive/html/bug-gawk/2023-12/msg00011.html.
+ *
+ * The hope is that by using this do-nothing function to catch
+ * SIGPIPE, instead of setting it to default, that when race conditions
+ * occur, gawk won't fatal out.
+ */
+
+void
+do_nothing_on_signal(int sig)
+{
+}