From 2b6df533b9a20f6f364b72de4f0db41ab9c67c6d Mon Sep 17 00:00:00 2001 From: tg Date: Fri, 31 Dec 2004 17:29:28 +0000 Subject: [PATCH] Use the BSD sig_t instead of homegrown handler_t Remove KSH_SA_FLAGS From: Todd C. Miller sanitise signal handling a bit (will be revisited) --- aclocal.m4 | 115 ++--------------------------------------------------- c_ksh.c | 16 ++++---- c_sh.c | 6 +-- conf-end.h | 17 +------- config.h | 20 +--------- proto.h | 6 +-- sh.h | 43 ++++---------------- trap.c | 36 ++++++++--------- 8 files changed, 44 insertions(+), 215 deletions(-) diff --git a/aclocal.m4 b/aclocal.m4 index 6bdf7ea..515e35e 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -1,4 +1,4 @@ -dnl $MirBSD: src/bin/ksh/aclocal.m4,v 2.3 2004/12/13 19:05:08 tg Exp $ +dnl $MirBSD: src/bin/ksh/aclocal.m4,v 2.4 2004/12/31 17:29:28 tg Exp $ dnl- dnl Copyright (c) 2004 dnl Thorsten "mirabile" Glaser @@ -436,117 +436,8 @@ AC_DEFUN(KSH_SIGNAL_CHECK, sigset(SIGINT, foo); sigrelse(SIGINT); sighold(SIGINT); sigpause(SIGINT); ], ksh_cv_signal_check=bsd41, ksh_cv_signal_check=v7)))]) - if test $ksh_cv_signal_check = posix; then - AC_DEFINE(POSIX_SIGNALS) - else - AC_DEFINE(USE_FAKE_SIGACT) - if test $ksh_cv_signal_check = bsd42; then - AC_DEFINE(BSD42_SIGNALS) - elif test $ksh_cv_signal_check = bsd41; then - AC_DEFINE(BSD41_SIGNALS) - AC_CACHE_CHECK(if signals interrupt read(), ksh_cv_signals_interrupt, - [AC_TRY_RUN([ -#include -#include - - extern int errno; - int flag = 0; - - RETSIGTYPE - catcher(int sig) - { - flag = 1; - return RETSIGVAL; - } - - int - main() - { - int pid; - int fdc[2]; /* child writes to parent */ - int fdp[2]; /* parent writes to child */ - char buf; - int nread; - - if (pipe(fdc) < 0) - exit(1); - if (pipe(fdp) < 0) - exit(2); - if ((pid = fork()) < 0) - exit(3); - if (pid == 0) { - close(fdc[0]); - close(fdp[1]); - if (read(fdp[0], &buf, 1) != 0) - exit(10); - sleep(1); /* let parent into read */ - if (kill(getppid(), SIGALRM) < 0) - exit(11); - sleep(1); /* ensure parent gets to run */ - write(fdc[1], "1", 1); - close(fdc[1]); - exit(0); - } - close(fdc[1]); - close(fdp[0]); - - /* Use native routines for test as this is what the shell - * will be using... - */ -#ifdef POSIX_SIGNALS - { - struct sigaction sa, osa; - sa.sa_handler = catcher; - sigemptyset(&sa.sa_mask); - sa.sa_flags = 0; - sigaction(SIGALRM, &sa, &osa); - } -#else /* POSIX_SIGNALS */ -# ifdef BSD42_SIGNALS - { - struct sigvec vec, ovec; - vec.sv_handler = catcher; - vec.sv_mask = 0; - vec.sv_flags = 0; -# ifdef SV_INTERRUPT - vec.sv_flags |= SV_INTERRUPT; -# endif /* SV_INTERRUPT */ - sigvec(SIGALRM, &vec, &ovec); - } -# else /* BSD42_SIGNALS */ -# ifdef BSD41_SIGNALS - sigset(SIGALRM, catcher); -# else /* BSD41_SIGNALS */ -# ifdef V7_SIGNALS - signal(SIGALRM, catcher); -# else /* V7_SIGNALS */ - what kind of signals do you have? -# endif /* V7_SIGNALS */ -# endif /* BSD41_SIGNALS */ -# endif /* BSD42_SIGNALS */ -#endif /* POSIX_SIGNALS */ - close(fdp[1]); /* start child */ - nread = read(fdc[0], &buf, 1); - if (nread == 0) - exit(4); - if (nread > 0) - exit(5); - if (errno != EINTR) - exit(6); - if (!flag) - exit(7); - exit(0); - return 0; - } - ], ksh_cv_signals_interrupt=yes, ksh_cv_signals_interrupt=no, - AC_MSG_ERROR(cannot determine if signals interrupt read() when cross compiling) - )]) - if test $ksh_cv_signals_interrupt = no ; then - AC_DEFINE(SIGNALS_DONT_INTERRUPT) - fi - else - AC_DEFINE(V7_SIGNALS) - fi + if test $ksh_cv_signal_check != posix; then + AC_MSG_WARN(no posix signals) fi ])dnl dnl diff --git a/c_ksh.c b/c_ksh.c index fc2c323..c25e4a4 100644 --- a/c_ksh.c +++ b/c_ksh.c @@ -1,4 +1,4 @@ -/** $MirBSD: src/bin/ksh/c_ksh.c,v 2.6 2004/12/28 22:32:08 tg Exp $ */ +/** $MirBSD: src/bin/ksh/c_ksh.c,v 2.7 2004/12/31 17:29:28 tg Exp $ */ /* $OpenBSD: c_ksh.c,v 1.18 2004/02/10 13:03:36 jmc Exp $ */ /* @@ -13,7 +13,7 @@ #include #endif /* __CYGWIN__ */ -__RCSID("$MirBSD: src/bin/ksh/c_ksh.c,v 2.6 2004/12/28 22:32:08 tg Exp $"); +__RCSID("$MirBSD: src/bin/ksh/c_ksh.c,v 2.7 2004/12/31 17:29:28 tg Exp $"); int c_cd(char **wp) @@ -1173,16 +1173,16 @@ c_kill(char **wp) for (; wp[i]; i++) { if (!bi_getn(wp[i], &n)) return 1; - if (n > 128 && n < 128 + SIGNALS) + if (n > 128 && n < 128 + NSIG) n -= 128; - if (n > 0 && n < SIGNALS && sigtraps[n].name) + if (n > 0 && n < NSIG && sigtraps[n].name) shprintf("%s\n", sigtraps[n].name); else shprintf("%d\n", n); } } else if (Flag(FPOSIX)) { p = null; - for (i = 1; i < SIGNALS; i++, p = space) + for (i = 1; i < NSIG; i++, p = space) if (sigtraps[i].name) shprintf("%s%s", p, sigtraps[i].name); shprintf(newline); @@ -1191,10 +1191,10 @@ c_kill(char **wp) size_t w, mess_width; struct kill_info ki; - for (i = SIGNALS, ki.num_width = 1; i >= 10; i /= 10) + for (i = NSIG, ki.num_width = 1; i >= 10; i /= 10) ki.num_width++; ki.name_width = mess_width = 0; - for (i = 0; i < SIGNALS; i++) { + for (i = 0; i < NSIG; i++) { w = sigtraps[i].name ? strlen(sigtraps[i].name) : ki.num_width; if (w > ki.name_width) @@ -1204,7 +1204,7 @@ c_kill(char **wp) mess_width = w; } - print_columns(shl_stdout, SIGNALS - 1, + print_columns(shl_stdout, NSIG - 1, kill_fmt_entry, (void *) &ki, ki.num_width + ki.name_width + mess_width + 3, 1); } diff --git a/c_sh.c b/c_sh.c index 595fc67..c198e80 100644 --- a/c_sh.c +++ b/c_sh.c @@ -1,4 +1,4 @@ -/** $MirBSD: src/bin/ksh/c_sh.c,v 2.8 2004/12/28 22:40:39 tg Exp $ */ +/** $MirBSD: src/bin/ksh/c_sh.c,v 2.9 2004/12/31 17:29:28 tg Exp $ */ /* $OpenBSD: c_sh.c,v 1.26 2004/12/22 18:57:28 otto Exp $ */ /* @@ -10,7 +10,7 @@ #include "ksh_time.h" #include "ksh_times.h" -__RCSID("$MirBSD: src/bin/ksh/c_sh.c,v 2.8 2004/12/28 22:40:39 tg Exp $"); +__RCSID("$MirBSD: src/bin/ksh/c_sh.c,v 2.9 2004/12/31 17:29:28 tg Exp $"); static char *clocktos(clock_t t); @@ -461,7 +461,7 @@ c_trap(char **wp) if (*wp == NULL) { int anydfl = 0; - for (p = sigtraps, i = SIGNALS+1; --i >= 0; p++) { + for (p = sigtraps, i = NSIG + 1; --i >= 0; p++) { if (p->trap == NULL) anydfl = 1; else { diff --git a/conf-end.h b/conf-end.h index 1016f43..26914e1 100644 --- a/conf-end.h +++ b/conf-end.h @@ -1,4 +1,4 @@ -/** $MirBSD: src/bin/ksh/conf-end.h,v 2.8 2004/12/28 22:47:04 tg Exp $ */ +/** $MirBSD: src/bin/ksh/conf-end.h,v 2.9 2004/12/31 17:29:28 tg Exp $ */ /* $OpenBSD: conf-end.h,v 1.2 1996/08/25 12:37:58 downsj Exp $ */ #ifndef CONF_END_H @@ -33,8 +33,7 @@ #endif /* Can we safely catch sigchld and wait for processes? */ -#if (defined(HAVE_WAITPID) || defined(HAVE_WAIT3)) \ - && (defined(POSIX_SIGNALS) || defined(BSD42_SIGNALS)) +#if defined(HAVE_WAITPID) || defined(HAVE_WAIT3) # define JOB_SIGS #endif @@ -54,18 +53,6 @@ # include #endif -/* pdksh assumes system calls return EINTR if a signal happened (this so - * the signal handler doesn't have to longjmp()). I don't know if this - * happens (or can be made to happen) with sigset() et. al. (the bsd41 signal - * routines), so, the autoconf stuff checks what they do and defines - * SIGNALS_DONT_INTERRUPT if signals don't interrupt read(). - * If SIGNALS_DONT_INTERRUPT isn't defined and your compiler chokes on this, - * delete the hash in front of the error (and file a bug report). - */ -#ifdef SIGNALS_DONT_INTERRUPT - # error pdksh needs interruptable system calls. -#endif /* SIGNALS_DONT_INTERRUPT */ - #ifdef HAVE_GCC_FUNC_ATTR # define GCC_FUNC_ATTR(x) __attribute__((x)) # define GCC_FUNC_ATTR2(x,y) __attribute__((x,y)) diff --git a/config.h b/config.h index 5f5dfa0..3d0a6ba 100644 --- a/config.h +++ b/config.h @@ -1,4 +1,4 @@ -/** $MirBSD: src/bin/ksh/config.h,v 2.3 2004/12/28 22:44:39 tg Exp $ */ +/** $MirBSD: src/bin/ksh/config.h,v 2.4 2004/12/31 17:29:28 tg Exp $ */ /* $OpenBSD: config.h,v 1.9 2003/10/22 07:40:38 jmc Exp $ */ /* @@ -82,24 +82,6 @@ /* Define as the return value of signal handlers (0 or ). */ #define RETSIGVAL -/* Define if you have posix signal routines (sigaction(), et. al.) */ -#define POSIX_SIGNALS 1 - -/* Define if you have BSD4.2 signal routines (sigsetmask(), et. al.) */ -/* #undef BSD42_SIGNALS */ - -/* Define if you have BSD4.1 signal routines (sigset(), et. al.) */ -/* #undef BSD41_SIGNALS */ - -/* Define if you have v7 signal routines (signal(), signal reset on delivery) */ -/* #undef V7_SIGNALS */ - -/* Define to use the fake posix signal routines (sigact.[ch]) */ -/* #undef USE_FAKE_SIGACT */ - -/* Define if signals don't interrupt read() */ -/* #undef SIGNALS_DONT_INTERRUPT */ - /* Define if you have bsd versions of the setpgrp() and getpgrp() routines */ /* #undef BSD_PGRP */ diff --git a/proto.h b/proto.h index cc61009..2cac291 100644 --- a/proto.h +++ b/proto.h @@ -1,9 +1,9 @@ -/** $MirBSD: src/bin/ksh/proto.h,v 2.8 2004/12/28 22:40:40 tg Exp $ */ +/** $MirBSD: src/bin/ksh/proto.h,v 2.9 2004/12/31 17:29:28 tg Exp $ */ /* $OpenBSD: proto.h,v 1.11 2003/05/16 19:58:57 jsyn Exp $ */ /* $From: proto.h,v 1.3 1994/05/19 18:32:40 michael Exp michael $ */ #ifndef PROTO_H -/* $OpenBSD: proto.h,v 1.23 2004/12/22 18:57:28 otto Exp $ */ +/* $OpenBSD: proto.h,v 1.17 2004/12/18 21:58:39 millert Exp $ */ /* * prototypes for PD-KSH @@ -236,7 +236,7 @@ void restoresigs(void); void settrap(Trap *p, char *s); int block_pipe(void); void restore_pipe(int restore_dfl); -int setsig(Trap *p, handler_t f, int flags); +int setsig(Trap *p, sig_t f, int flags); void setexecsig(Trap *p, int restore); /* tree.c */ int fptreef(struct shf *f, int indent, const char *fmt, ...); diff --git a/sh.h b/sh.h index 28e0dbd..b95dc59 100644 --- a/sh.h +++ b/sh.h @@ -1,8 +1,8 @@ -/** $MirBSD: src/bin/ksh/sh.h,v 2.9 2004/12/31 17:08:29 tg Exp $ */ +/** $MirBSD: src/bin/ksh/sh.h,v 2.10 2004/12/31 17:29:28 tg Exp $ */ /* $OpenBSD: sh.h,v 1.23 2004/12/18 22:11:43 millert Exp $ */ #ifndef SH_H -#define SH_H +/* $OpenBSD: sh.h,v 1.22 2004/12/18 21:58:39 millert Exp $ */ /* * mirbsdksh - MirOS Project Korn-Shell @@ -146,35 +146,8 @@ void *memmove(void *d, const void *s, size_t n); #endif /* HAVE_LIMITS_H */ #include -#ifdef NSIG -# define SIGNALS NSIG -#else -# ifdef _MINIX -# define SIGNALS (_NSIG+1) /* _NSIG is # of signals used, excluding 0. */ -# else -# ifdef _SIGMAX /* QNX */ -# define SIGNALS _SIGMAX -# else /* _SIGMAX */ -# define SIGNALS 32 -# endif /* _SIGMAX */ -# endif /* _MINIX */ -#endif /* NSIG */ -#ifndef SIGCHLD -# define SIGCHLD SIGCLD -#endif -/* struct sigaction.sa_flags is set to KSH_SA_FLAGS. Used to ensure - * system calls are interrupted - */ -#ifdef SA_INTERRUPT -# define KSH_SA_FLAGS SA_INTERRUPT -#else /* SA_INTERRUPT */ -# define KSH_SA_FLAGS 0 -#endif /* SA_INTERRUPT */ - -typedef RETSIGTYPE (*handler_t)(int); /* signal handler */ - -#ifdef USE_FAKE_SIGACT -# include "sigact.h" /* use sjg's fake sigaction() */ +#ifndef NSIG +#define NSIG 32 #endif #ifdef HAVE_PATHS_H @@ -504,8 +477,8 @@ typedef struct trap { char *trap; /* trap command */ volatile sig_atomic_t set; /* trap pending */ int flags; /* TF_* */ - handler_t cursig; /* current handler (valid if TF_ORIG_* set) */ - handler_t shtrap; /* shell signal handler */ + sig_t cursig; /* current handler (valid if TF_ORIG_* set) */ + sig_t shtrap; /* shell signal handler */ } Trap; /* values for Trap.flags */ @@ -531,14 +504,14 @@ typedef struct trap { #define SS_SHTRAP BIT(5) /* trap for internal use (CHLD,ALRM,WINCH) */ #define SIGEXIT_ 0 /* for trap EXIT */ -#define SIGERR_ SIGNALS /* for trap ERR */ +#define SIGERR_ NSIG /* for trap ERR */ EXTERN volatile sig_atomic_t trap; /* traps pending? */ EXTERN volatile sig_atomic_t intrsig; /* pending trap interrupts executing command */ EXTERN volatile sig_atomic_t fatal_trap;/* received a fatal signal */ #ifndef FROM_TRAP_C /* Kludge to avoid bogus re-declaration of sigtraps[] error on AIX 3.2.5 */ -extern Trap sigtraps[SIGNALS+1]; +extern Trap sigtraps[NSIG + 1]; #endif /* !FROM_TRAP_C */ /* diff --git a/trap.c b/trap.c index ca08543..0a0178f 100644 --- a/trap.c +++ b/trap.c @@ -1,5 +1,5 @@ -/** $MirBSD: src/bin/ksh/trap.c,v 2.4 2004/12/28 22:32:08 tg Exp $ */ -/* $OpenBSD: trap.c,v 1.13 2003/02/28 09:45:09 jmc Exp $ */ +/** $MirBSD: src/bin/ksh/trap.c,v 2.5 2004/12/31 17:29:28 tg Exp $ */ +/* $OpenBSD: trap.c,v 1.17 2004/12/18 21:58:39 millert Exp $ */ /* * signal handling @@ -9,14 +9,14 @@ #define FROM_TRAP_C #include "sh.h" -__RCSID("$MirBSD: src/bin/ksh/trap.c,v 2.4 2004/12/28 22:32:08 tg Exp $"); +__RCSID("$MirBSD: src/bin/ksh/trap.c,v 2.5 2004/12/31 17:29:28 tg Exp $"); /* Table is indexed by signal number * * The script siglist.sh generates siglist.out, which is a sorted, complete * list of signals */ -Trap sigtraps[SIGNALS+1] = { +Trap sigtraps[NSIG + 1] = { { SIGEXIT_, "EXIT", "Signal 0", NULL, 0, 0, 0, 0 }, #include "siglist.out" /* generated by siglist.sh */ { SIGERR_, "ERR", "Error handler", NULL, 0, 0, 0, 0 }, @@ -40,7 +40,7 @@ inittraps(void) #endif /* HAVE_SYS_SIGLIST */ sigemptyset(&Sigact_ign.sa_mask); - Sigact_ign.sa_flags = KSH_SA_FLAGS; + Sigact_ign.sa_flags = 0; /* interruptible */ Sigact_ign.sa_handler = SIG_IGN; Sigact_trap = Sigact_ign; Sigact_trap.sa_handler = trapsig; @@ -95,11 +95,11 @@ gettrap(const char *name, int igncase) if (digit(*name)) { int n; - if (getn(name, &n) && 0 <= n && n < SIGNALS) + if (getn(name, &n) && 0 <= n && n < NSIG) return &sigtraps[n]; return NULL; } - for (p = sigtraps, i = SIGNALS+1; --i >= 0; p++) + for (p = sigtraps, i = NSIG+1; --i >= 0; p++) if (p->name) { if (igncase) { if (p->name && (!strcasecmp(p->name, name) || @@ -135,10 +135,6 @@ trapsig(int i) } if (p->shtrap) (*p->shtrap)(i); -#ifdef V7_SIGNALS - if (sigtraps[i].cursig == trapsig) /* this for SIGCHLD,SIGALRM */ - sigaction(i, &Sigact_trap, NULL); -#endif /* V7_SIGNALS */ errno = errno_; return RETSIGVAL; } @@ -163,7 +159,7 @@ fatal_trap_check(void) Trap *p; /* todo: should check if signal is fatal, not the TF_DFL_INTR flag */ - for (p = sigtraps, i = SIGNALS+1; --i >= 0; p++) + for (p = sigtraps, i = NSIG + 1; --i >= 0; p++) if (p->set && (p->flags & (TF_DFL_INTR|TF_FATAL))) /* return value is used as an exit code */ return 128 + p->signal; @@ -180,7 +176,7 @@ trap_pending(void) int i; Trap *p; - for (p = sigtraps, i = SIGNALS+1; --i >= 0; p++) + for (p = sigtraps, i = NSIG + 1; --i >= 0; p++) if (p->set && ((p->trap && p->trap[0]) || ((p->flags & (TF_DFL_INTR|TF_FATAL)) && !p->trap))) @@ -213,7 +209,7 @@ runtraps(int flag) intrsig = 0; if (flag & TF_FATAL) fatal_trap = 0; - for (p = sigtraps, i = SIGNALS+1; --i >= 0; p++) + for (p = sigtraps, i = NSIG + 1; --i >= 0; p++) if (p->set && (!flag || ((p->flags & flag) && p->trap == NULL))) runtrap(p); @@ -274,7 +270,7 @@ cleartraps(void) trap = 0; intrsig = 0; fatal_trap = 0; - for (i = SIGNALS+1, p = sigtraps; --i >= 0; p++) { + for (i = NSIG + 1, p = sigtraps; --i >= 0; p++) { p->set = 0; if ((p->flags & TF_USER_SET) && (p->trap && p->trap[0])) settrap(p, NULL); @@ -288,7 +284,7 @@ restoresigs(void) int i; Trap *p; - for (i = SIGNALS+1, p = sigtraps; --i >= 0; p++) + for (i = NSIG + 1, p = sigtraps; --i >= 0; p++) if (p->flags & (TF_EXEC_IGN|TF_EXEC_DFL)) setsig(p, (p->flags & TF_EXEC_IGN) ? SIG_IGN : SIG_DFL, SS_RESTORE_CURR|SS_FORCE); @@ -297,7 +293,7 @@ restoresigs(void) void settrap(Trap *p, char *s) { - handler_t f; + sig_t f; if (p->trap) afree(p->trap, APERM); @@ -360,7 +356,7 @@ restore_pipe(int restore_dfl) * FTALKING. */ int -setsig(Trap *p, handler_t f, int flags) +setsig(Trap *p, sig_t f, int flags) { struct sigaction sigact; @@ -392,7 +388,7 @@ setsig(Trap *p, handler_t f, int flags) * all users of shtrap are lifetime users (SIGCHLD, SIGALRM, SIGWINCH). */ if (!(flags & SS_USER)) - p->shtrap = (handler_t) 0; + p->shtrap = NULL; if (flags & SS_SHTRAP) { p->shtrap = f; f = trapsig; @@ -401,7 +397,7 @@ setsig(Trap *p, handler_t f, int flags) if (p->cursig != f) { p->cursig = f; sigemptyset(&sigact.sa_mask); - sigact.sa_flags = KSH_SA_FLAGS; + sigact.sa_flags = 0 /* interruptible */; sigact.sa_handler = f; sigaction(p->signal, &sigact, NULL); }