rc

[fork] interactive rc shell
Log | Files | Refs | README | LICENSE

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:
Macconfig.h | 3+++
Mconfigure.ac | 34+++++++++++++++++++++++++---------
Msignal.c | 27++++++++++++++++++++-------
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 }