commit 43c1019eca5e6d67e239cb38d54cd9c359577827
parent b79e7f2d747a7ad926e15eb1395616a3babb6671
Author: tgoodwin <tgoodwin>
Date: Tue, 21 Jul 1998 14:27:42 +0000
fix for Linux with glibc2 so system calls are not restarted
Diffstat:
3 files changed, 48 insertions(+), 16 deletions(-)
diff --git a/acconfig.h b/acconfig.h
@@ -69,3 +69,6 @@
/* Define to release date. */
#undef RELDATE
+
+/* Define if you have SA_INTERRUPT (and sigaction()). */
+#undef HAVE_SA_INTERRUPT
diff --git a/configure.ac b/configure.ac
@@ -35,14 +35,6 @@ AC_TYPE_SIZE_T
AC_TYPE_UID_T
AC_CHECK_TYPE(ssize_t, long)
-dnl Check type of sig_atomic_t.
-AC_CACHE_CHECK(for sig_atomic_t, rc_cv_sig_atomic_t,
- AC_EGREP_HEADER(sig_atomic_t, signal.h,
- rc_cv_sig_atomic_t=yes, rc_cv_sig_atomic_t=no))
-case "$rc_cv_sig_atomic_t" in
-no) AC_DEFINE(sig_atomic_t, int) ;;
-esac
-
AC_CHECK_FUNCS(getgroups setpgrp setrlimit)
@@ -133,7 +125,31 @@ main(){
;;
esac
-AC_SYS_RESTARTABLE_SYSCALLS
+dnl Check type of sig_atomic_t.
+AC_CACHE_CHECK(for sig_atomic_t, rc_cv_sig_atomic_t,
+ AC_EGREP_HEADER(sig_atomic_t, signal.h,
+ rc_cv_sig_atomic_t=yes, rc_cv_sig_atomic_t=no))
+case "$rc_cv_sig_atomic_t" in
+no) AC_DEFINE(sig_atomic_t, int) ;;
+esac
+
+dnl We prefer system calls that don't restart. If we have sigaction() and
+dnl SA_INTERRUPT, we'll use 'em. Otherwise, we check whether
+dnl good ol' signal() produces interruptible system calls.
+AC_CACHE_CHECK(for sigaction and SA_INTERRUPT, rc_cv_sa_int,
+ AC_TRY_COMPILE([
+#include <signal.h>
+ ], [
+struct sigaction foo;
+foo.sa_flags = SA_INTERRUPT;
+sigaction(SIGINT, 0, 0);
+ ], rc_cv_sa_int=yes, rc_cv_sa_int=no
+ )
+)
+case "$rc_cv_sa_int" in
+yes) AC_DEFINE(HAVE_SA_INTERRUPT) ;;
+no) AC_SYS_RESTARTABLE_SYSCALLS ;;
+esac
AM_CONDITIONAL(AMC_RESTART, test "$ac_cv_sys_restartable_syscalls" = yes)
dnl Do we have SysV SIGCLD semantics? In other words, if we set the
diff --git a/signal.c b/signal.c
@@ -7,6 +7,19 @@
#include "sigmsgs.h"
#include "jbwrap.h"
+#if HAVE_SA_INTERRUPT
+static void (*sys_signal(int signum, void (*handler)(int)))(int) {
+ struct sigaction new, old;
+
+ new.sa_handler = handler;
+ new.sa_flags = SA_INTERRUPT;
+ sigaction(signum, &new, &old);
+ return old.sa_handler;
+}
+#else
+#define sys_signal signal
+#endif
+
void (*sighandlers[NUMOFSIGNALS])(int);
static volatile sig_atomic_t sigcount, caught[NUMOFSIGNALS];
@@ -16,7 +29,7 @@ extern void catcher(int s) {
sigcount++;
caught[s] = 1;
}
- signal(s, catcher);
+ sys_signal(s, catcher);
#if READLINE
if (rl_active)
@@ -59,11 +72,11 @@ extern void (*rc_signal(int s, void (*h)(int)))(int) {
sigchk();
old = sighandlers[s];
if (h == SIG_DFL || h == SIG_IGN) {
- signal(s, h);
sighandlers[s] = h;
+ sys_signal(s, h);
} else {
sighandlers[s] = h;
- signal(s, catcher);
+ sys_signal(s, catcher);
}
return old;
}
@@ -73,16 +86,16 @@ extern void initsignal() {
int i;
for (i = 1; i < NUMOFSIGNALS; i++) {
- h = signal(i, SIG_DFL);
+ h = sys_signal(i, SIG_DFL);
if (h != SIG_DFL && h != SIG_ERR)
- signal(i, h);
+ sys_signal(i, h);
sighandlers[i] = h;
}
#if HAVE_SYSV_SIGCLD
/* Ensure that SIGCLD is not SIG_IGN. Solaris's rshd does this. :-( */
- h = signal(SIGCLD, SIG_DFL);
+ h = sys_signal(SIGCLD, SIG_DFL);
if (h != SIG_IGN && h != SIG_ERR)
- signal(SIGCLD, h);
+ sys_signal(SIGCLD, h);
#endif
}