diff options
Diffstat (limited to 'shells/pdksh/files/trap.c')
-rw-r--r-- | shells/pdksh/files/trap.c | 53 |
1 files changed, 40 insertions, 13 deletions
diff --git a/shells/pdksh/files/trap.c b/shells/pdksh/files/trap.c index 3adee9e8311..8f646ad8866 100644 --- a/shells/pdksh/files/trap.c +++ b/shells/pdksh/files/trap.c @@ -1,6 +1,14 @@ +/* $NetBSD: trap.c,v 1.2 2008/05/31 16:47:37 tnn Exp $ */ + /* * signal handling */ +#include <sys/cdefs.h> + +#ifndef lint +__RCSID("$NetBSD: trap.c,v 1.2 2008/05/31 16:47:37 tnn Exp $"); +#endif + /* Kludge to avoid bogus re-declaration of sigtraps[] error on AIX 3.2.5 */ #define FROM_TRAP_C @@ -12,9 +20,9 @@ * list of signals */ Trap sigtraps[SIGNALS+1] = { - { SIGEXIT_, "EXIT", "Signal 0" }, + { .signal = SIGEXIT_, .name = "EXIT", .mess = "Signal 0" }, #include "siglist.out" /* generated by siglist.sh */ - { SIGERR_, "ERR", "Error handler" }, + { .signal = SIGERR_, .name = "ERR", .mess = "Error handler" }, }; static struct sigaction Sigact_ign, Sigact_trap; @@ -46,7 +54,7 @@ inittraps() sigtraps[SIGHUP].flags |= TF_FATAL; sigtraps[SIGCHLD].flags |= TF_SHELL_USES; - /* these are always caught so we can clean up any temproary files. */ + /* these are always caught so we can clean up any temporary files. */ setsig(&sigtraps[SIGINT], trapsig, SS_RESTORE_ORIG); setsig(&sigtraps[SIGQUIT], trapsig, SS_RESTORE_ORIG); setsig(&sigtraps[SIGTERM], trapsig, SS_RESTORE_ORIG); @@ -68,6 +76,8 @@ static RETSIGTYPE alarm_catcher(sig) int sig; { + int errno_ = errno; + if (ksh_tmout_state == TMOUT_READING) { int left = alarm(0); @@ -77,6 +87,7 @@ alarm_catcher(sig) } else alarm(left); } + errno = errno_; return RETSIGVAL; } #endif /* KSH */ @@ -97,9 +108,20 @@ gettrap(name, igncase) return NULL; } for (p = sigtraps, i = SIGNALS+1; --i >= 0; p++) - if (p->name && (igncase ? strcasecmp(p->name, name) == 0 - : strcmp(p->name, name) == 0)) - return p; + if (p->name) { + if (igncase) { + if (p->name && (!strcasecmp(p->name, name) || + (strlen(name) > 3 && !strncasecmp("SIG", + p->name, 3) && + !strcasecmp(p->name, name + 3)))) + return p; + } else { + if (p->name && (!strcmp(p->name, name) || + (strlen(name) > 3 && !strncmp("SIG", + p->name, 3) && !strcmp(p->name, name + 3)))) + return p; + } + } return NULL; } @@ -111,6 +133,7 @@ trapsig(i) int i; { Trap *p = &sigtraps[i]; + int errno_ = errno; trap = p->set = 1; if (p->flags & TF_DFL_INTR) @@ -125,6 +148,7 @@ trapsig(i) if (sigtraps[i].cursig == trapsig) /* this for SIGCHLD,SIGALRM */ sigaction(i, &Sigact_trap, (struct sigaction *) 0); #endif /* V7_SIGNALS */ + errno = errno_; return RETSIGVAL; } @@ -156,7 +180,7 @@ fatal_trap_check() } /* Returns the signal number of any pending traps: ie, a signal which has - * occured for which a trap has been set or for which the TF_DFL_INTR flag + * occurred for which a trap has been set or for which the TF_DFL_INTR flag * is set. */ int @@ -252,7 +276,7 @@ runtrap(p) p->flags |= old_changed; } } - + /* clear pending traps and reset user's trap handlers; used after fork(2) */ void cleartraps() @@ -292,11 +316,14 @@ settrap(p, s) if (p->trap) afree(p->trap, APERM); - p->trap = str_save(s, APERM); /* handles s == 0 */ - p->flags |= TF_CHANGED; - f = !s ? SIG_DFL : s[0] ? trapsig : SIG_IGN; - - p->flags |= TF_USER_SET; + p->flags |= TF_CHANGED|TF_USER_SET; + if (s) { + p->trap = str_save(s, APERM); + f = s[0] ? trapsig : SIG_IGN; + } else { + p->trap = NULL; + f = SIG_DFL; + } if ((p->flags & (TF_DFL_INTR|TF_FATAL)) && f == SIG_DFL) f = trapsig; else if (p->flags & TF_SHELL_USES) { |