diff options
Diffstat (limited to 'src/util/posix_signals.c')
-rw-r--r-- | src/util/posix_signals.c | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/src/util/posix_signals.c b/src/util/posix_signals.c new file mode 100644 index 0000000..8ccddf0 --- /dev/null +++ b/src/util/posix_signals.c @@ -0,0 +1,126 @@ +/*++ +/* NAME +/* posix_signals 3 +/* SUMMARY +/* POSIX signal handling compatibility +/* SYNOPSIS +/* #include <posix_signals.h> +/* +/* int sigemptyset(m) +/* sigset_t *m; +/* +/* int sigaddset(set, signum) +/* sigset_t *set; +/* int signum; +/* +/* int sigprocmask(how, set, old) +/* int how; +/* sigset_t *set; +/* sigset_t *old; +/* +/* int sigaction(sig, act, oact) +/* int sig; +/* struct sigaction *act; +/* struct sigaction *oact; +/* DESCRIPTION +/* These routines emulate the POSIX signal handling interface. +/* AUTHOR(S) +/* Pieter Schoenmakers +/* Eindhoven University of Technology +/* P.O. Box 513 +/* 5600 MB Eindhoven +/* The Netherlands +/*--*/ + +/* System library. */ + +#include "sys_defs.h" +#include <signal.h> +#include <errno.h> + +/* Utility library.*/ + +#include "posix_signals.h" + +#ifdef MISSING_SIGSET_T + +int sigemptyset(sigset_t *m) +{ + return *m = 0; +} + +int sigaddset(sigset_t *set, int signum) +{ + *set |= sigmask(signum); + return 0; +} + +int sigprocmask(int how, sigset_t *set, sigset_t *old) +{ + int previous; + + if (how == SIG_BLOCK) + previous = sigblock(*set); + else if (how == SIG_SETMASK) + previous = sigsetmask(*set); + else if (how == SIG_UNBLOCK) { + int m = sigblock(0); + + previous = sigsetmask(m & ~*set); + } else { + errno = EINVAL; + return -1; + } + + if (old) + *old = previous; + return 0; +} + +#endif + +#ifdef MISSING_SIGACTION + +static struct sigaction actions[NSIG] = {}; + +static int sighandle(int signum) +{ + if (signum == SIGCHLD) { + /* XXX If the child is just stopped, don't invoke the handler. */ + } + actions[signum].sa_handler(signum); +} + +int sigaction(int sig, struct sigaction *act, struct sigaction *oact) +{ + static int initialized = 0; + + if (!initialized) { + int i; + + for (i = 0; i < NSIG; i++) + actions[i].sa_handler = SIG_DFL; + initialized = 1; + } + if (sig <= 0 || sig >= NSIG) { + errno = EINVAL; + return -1; + } + if (oact) + *oact = actions[sig]; + + { + struct sigvec mine = { + sighandle, act->sa_mask, + act->sa_flags & SA_RESTART ? SV_INTERRUPT : 0 + }; + + if (sigvec(sig, &mine, NULL)) + return -1; + } + + actions[sig] = *act; + return 0; +} + +#endif |