Use the BSD sig_t instead of homegrown handler_t

Remove KSH_SA_FLAGS
From: Todd C. Miller <millert@cvs.openbsd.org>

sanitise signal handling a bit (will be revisited)
This commit is contained in:
tg 2004-12-31 17:29:28 +00:00
parent 0799af5fdb
commit 2b6df533b9
8 changed files with 44 additions and 215 deletions

115
aclocal.m4 vendored
View File

@ -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 <tg@66h.42h.de>
@ -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 <errno.h>
#include <signal.h>
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

16
c_ksh.c
View File

@ -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 <sys/cygwin.h>
#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);
}

6
c_sh.c
View File

@ -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 {

View File

@ -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 <stdint.h>
#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))

View File

@ -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 */

View File

@ -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, ...);

43
sh.h
View File

@ -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 <signal.h>
#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 */
/*

36
trap.c
View File

@ -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);
}