rc

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

commit 3b39a6827f68a5183ce44637ca6b39c464d30067
parent dc327f40c8d4981bb5dce27f8e967aacfcf4fb23
Author: tgoodwin <tgoodwin>
Date:   Thu,  5 Feb 1998 15:22:28 +0000

use sigsetjmp, etc.

Diffstat:
Mbuiltins.c | 2+-
Mconfigure.ac | 40+++++++++++++++++++++++-----------------
Mexcept.c | 2+-
Minput.c | 4++--
Mjbwrap.h | 2+-
Mrc.h | 8++++++++
Msignal.c | 2+-
Mutils.c | 4++--
Mwait.c | 2+-
Mwalk.c | 4++--
10 files changed, 42 insertions(+), 28 deletions(-)

diff --git a/builtins.c b/builtins.c @@ -72,7 +72,7 @@ extern void funcall(char **av) { Jbwrap j; Estack e1, e2; Edata jreturn, star; - if (setjmp(j.j)) + if (sigsetjmp(j.j, 1)) return; starassign(*av, av+1, TRUE); jreturn.jb = &j; diff --git a/configure.ac b/configure.ac @@ -18,23 +18,11 @@ AC_CHECK_HEADERS(sys/resource.h sys/time.h sys/types.h unistd.h) AC_HEADER_DIRENT AC_HEADER_STDC -dnl Linux puts real signal names in /usr/include/asm/signal.h. NT puts -dnl them somewhere else altogether. This attempts to parse the output -dnl of saying `#include <signal.h>' to find the full path of files named -dnl signal.h, then examines each of those to see if it contains the -dnl `#define's we want. What a hack. - -echo '#include <signal.h>' > temp.c -AC_CACHE_CHECK(for full paths of <signal.h>, rc_cv_full_signal_h, [ - rc_cv_full_signal_h=`$CPP temp.c |sed -n 's/.*"\(.*signal.h\)".*/\1/p' |sort -u |sed 'y/ -/ /'` - case "x$rc_cv_full_signal_h" in - x) - rc_cv_full_signal_h='/usr/include/sys/signal.h /usr/include/asm/signal.h' - ;; - esac -]) -rm temp.c +dnl At some point, we might attempt to parse the output of saying +dnl `#include <signal.h>' using something like +dnl rc_cv_full_signal_h=`$CPP temp.c |sed -n 's/.*"\(.*signal.h\)".*/\1/p' |sort -u |sed 'y/\n/ /'` +dnl (but that doesn't work quite right). +rc_cv_full_signal_h='/usr/include/signal.h /usr/include/sys/signal.h /usr/include/asm/signal.h' AC_CACHE_CHECK(for signal names, rc_cv_signal_h, for i in $rc_cv_full_signal_h; do @@ -60,8 +48,25 @@ AC_TYPE_UID_T AC_CHECK_FUNCS(getgroups setpgrp setrlimit) + +dnl sigsetjmp() isn't a real function in some places. +AC_CACHE_CHECK(for sigsetjmp, rc_cv_sigsetjmp, + AC_TRY_LINK([ +#include <setjmp.h> + ], [ +jmp_buf e; +setjmp(e); + ], rc_cv_sigsetjmp=yes, rc_cv_sigsetjmp=no)) +case "x$rc_cv_sigsetjmp" in +xyes) + AC_DEFINE(HAVE_SIGSETJMP) + ;; +esac + + AC_FUNC_SETPGRP + dnl HPUX needs _KERNEL defined to pick up RLIMIT_foo defines. (Why?) AC_CACHE_CHECK(if _KERNEL is required for RLIMIT defines, rc_cv_kernel_rlimit, AC_TRY_COMPILE([ @@ -85,6 +90,7 @@ xyes) ;; esac + dnl Look for rlim_t in sys/types.h and sys/resource.h AC_CACHE_CHECK(for rlim_t, rc_cv_have_rlim_t, AC_EGREP_CPP(rlim_t, [ diff --git a/except.c b/except.c @@ -91,7 +91,7 @@ extern void rc_raise(ecodes e) { interactive = estack->interactive; estack = estack->prev; - longjmp(j->j, 1); + siglongjmp(j->j, 1); } } rc_exit(1); /* top of exception stack */ diff --git a/input.c b/input.c @@ -92,7 +92,7 @@ static int stringgchar() { static char *rc_readline(char *prompt) { char *r; interrupt_happened = FALSE; - if (!setjmp(slowbuf.j)) { + if (!sigsetjmp(slowbuf.j, 1)) { slow = TRUE; if (!interrupt_happened) r = readline(prompt); @@ -256,7 +256,7 @@ extern Node *doit(bool execit) { if (dashen) execit = FALSE; - setjmp(j.j); + sigsetjmp(j.j, 1); jerror.jb = &j; except(eError, jerror, &e1); for (eof = FALSE; !eof;) { diff --git a/jbwrap.h b/jbwrap.h @@ -3,7 +3,7 @@ /* certain braindamaged environments don't define jmp_buf as an array, so... */ struct Jbwrap { - jmp_buf j; + sigjmp_buf j; }; extern Jbwrap slowbuf; /* for getting out of interrupts while performing slow i/o on BSD */ diff --git a/rc.h b/rc.h @@ -36,6 +36,14 @@ #endif /*HAVE_SETPGRP */ +#if HAVE_SIGSETJMP +/* Smells like POSIX. */ +#else +/* Assume BSD. Probably fails on traditional SysV. */ +#define sigsetjmp setjmp +#define siglongjmp longjmp +#endif /* HAVE_SIGSETJMP */ + typedef void builtin_t(char **); typedef struct Block Block; typedef struct Dup Dup; diff --git a/signal.c b/signal.c @@ -21,7 +21,7 @@ extern void catcher(int s) { interrupt_happened = TRUE; #ifdef HAVE_RESTARTABLE_SYSCALLS if (slow) - longjmp(slowbuf.j, 1); + siglongjmp(slowbuf.j, 1); #endif } diff --git a/utils.c b/utils.c @@ -76,7 +76,7 @@ extern void writeall(int fd, char *buf, size_t remain) { safe_remain = remain; for (i = 0; safe_remain > 0; buf += i, safe_remain -= i) { interrupt_happened = FALSE; - if (!setjmp(slowbuf.j)) { + if (!sigsetjmp(slowbuf.j, 1)) { slow = TRUE; if (interrupt_happened) break; @@ -93,7 +93,7 @@ extern void writeall(int fd, char *buf, size_t remain) { extern int rc_read(int fd, char *buf, size_t n) { long /*ssize_t*/ r; interrupt_happened = FALSE; - if (!setjmp(slowbuf.j)) { + if (!sigsetjmp(slowbuf.j, 1)) { slow = TRUE; if (!interrupt_happened) r = read(fd, buf, n); diff --git a/wait.c b/wait.c @@ -137,7 +137,7 @@ static pid_t rc_wait(int *stat) { gotint = 0; old = signal(SIGINT, gotint_handler); - if (!setjmp(slowbuf.j)) { + if (!sigsetjmp(slowbuf.j, 1)) { slow = TRUE; if (!interrupt_happened) r = wait(stat); diff --git a/walk.c b/walk.c @@ -108,7 +108,7 @@ top: sigchk(); cond = oldcond; break; } - if (setjmp(j.j)) + if (sigsetjmp(j.j, 1)) break; jbreak.jb = &j; except(eBreak, jbreak, &e1); @@ -131,7 +131,7 @@ top: sigchk(); Jbwrap j; Estack e1, e2; Edata jbreak; - if (setjmp(j.j)) + if (sigsetjmp(j.j, 1)) break; jbreak.jb = &j; except(eBreak, jbreak, &e1);