aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew J. Schorr <aschorr@telemetry-investments.com>2013-07-07 12:57:40 -0400
committerAndrew J. Schorr <aschorr@telemetry-investments.com>2013-07-07 12:57:40 -0400
commitfaf3affc19f760a330153b22a8e56fc9a13a0cb6 (patch)
treedd00789c54a6b35a6dda2da7f8a0acd268d715ea
parent2376c18714fe197fbf56a19f8271e5f256ec7caf (diff)
downloadegawk-faf3affc19f760a330153b22a8e56fc9a13a0cb6.tar.gz
egawk-faf3affc19f760a330153b22a8e56fc9a13a0cb6.tar.bz2
egawk-faf3affc19f760a330153b22a8e56fc9a13a0cb6.zip
In io.c:wait_any, use sigprocmask if available.
-rw-r--r--ChangeLog6
-rw-r--r--configh.in3
-rwxr-xr-xconfigure3
-rw-r--r--configure.ac3
-rw-r--r--io.c27
5 files changed, 39 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index 8fc992d3..9bdbf836 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2013-07-07 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * configure.ac (AC_CHECK_FUNCS): Check for sigprocmask.
+ * io.c (wait_any): If sigprocmask is available, block signals instead
+ of ignoring them temporarily.
+
2013-07-05 Andrew J. Schorr <aschorr@telemetry-investments.com>
* gawkapi.h (gawk_api): Document that the api_get_file function will not
diff --git a/configh.in b/configh.in
index 68d5bf76..999e5db5 100644
--- a/configh.in
+++ b/configh.in
@@ -171,6 +171,9 @@
/* Define to 1 if you have the `setsid' function. */
#undef HAVE_SETSID
+/* Define to 1 if you have the `sigprocmask' function. */
+#undef HAVE_SIGPROCMASK
+
/* Define to 1 if you have the `snprintf' function. */
#undef HAVE_SNPRINTF
diff --git a/configure b/configure
index fccfcea0..62f0413d 100755
--- a/configure
+++ b/configure
@@ -10018,7 +10018,8 @@ esac
for ac_func in atexit btowc fmod getgrent getgroups grantpt \
isascii iswctype iswlower iswupper mbrlen \
memcmp memcpy memcpy_ulong memmove memset \
- memset_ulong mkstemp posix_openpt setenv setlocale setsid snprintf strchr \
+ memset_ulong mkstemp posix_openpt setenv setlocale setsid sigprocmask \
+ snprintf strchr \
strerror strftime strncasecmp strcoll strtod strtoul \
system tmpfile towlower towupper tzset usleep waitpid wcrtomb \
wcscoll wctype
diff --git a/configure.ac b/configure.ac
index ba242c51..9f2878b0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -274,7 +274,8 @@ esac
AC_CHECK_FUNCS(atexit btowc fmod getgrent getgroups grantpt \
isascii iswctype iswlower iswupper mbrlen \
memcmp memcpy memcpy_ulong memmove memset \
- memset_ulong mkstemp posix_openpt setenv setlocale setsid snprintf strchr \
+ memset_ulong mkstemp posix_openpt setenv setlocale setsid sigprocmask \
+ snprintf strchr \
strerror strftime strncasecmp strcoll strtod strtoul \
system tmpfile towlower towupper tzset usleep waitpid wcrtomb \
wcscoll wctype)
diff --git a/io.c b/io.c
index 42c92e47..01dc7cbe 100644
--- a/io.c
+++ b/io.c
@@ -2177,17 +2177,34 @@ use_pipes:
*
* Note: on platforms that do not support waitpid with WNOHANG, when called with
* a zero argument, this function will hang until all children have exited.
+ *
+ * AJS, 2013-07-07: I do not see why we need to ignore signals during this
+ * function. This function just waits and updates the pid and status fields.
+ * I don't see why that should interfere with any signal handlers. But I am
+ * reluctant to remove this protection. So I changed to use sigprocmask to
+ * block signals instead to avoid interfering with installed signal handlers.
*/
static int
wait_any(int interesting) /* pid of interest, if any */
{
- RETSIGTYPE (*hstat)(int), (*istat)(int), (*qstat)(int);
int pid;
int status = 0;
struct redirect *redp;
+#ifdef HAVE_SIGPROCMASK
+ sigset_t set, oldset;
+
+ /* I have no idea why we are blocking signals during this function... */
+ sigemptyset(& set);
+ sigaddset(& set, SIGINT);
+ sigaddset(& set, SIGHUP);
+ sigaddset(& set, SIGQUIT);
+ sigprocmask(SIG_BLOCK, & set, & oldset);
+#else
+ RETSIGTYPE (*hstat)(int), (*istat)(int), (*qstat)(int);
istat = signal(SIGINT, SIG_IGN);
+#endif
#ifdef __MINGW32__
if (interesting < 0) {
status = -1;
@@ -2204,8 +2221,10 @@ wait_any(int interesting) /* pid of interest, if any */
}
}
#else
+#ifndef HAVE_SIGPROCMASK
hstat = signal(SIGHUP, SIG_IGN);
qstat = signal(SIGQUIT, SIG_IGN);
+#endif
for (;;) {
# if defined(HAVE_WAITPID) && defined(WNOHANG)
if ((pid = waitpid(-1, & status, WNOHANG)) == 0)
@@ -2229,10 +2248,16 @@ wait_any(int interesting) /* pid of interest, if any */
if (pid == -1 && errno == ECHILD)
break;
}
+#ifndef HAVE_SIGPROCMASK
signal(SIGHUP, hstat);
signal(SIGQUIT, qstat);
#endif
+#endif
+#ifndef HAVE_SIGPROCMASK
signal(SIGINT, istat);
+#else
+ sigprocmask(SIG_SETMASK, & oldset, NULL);
+#endif
return status;
}