o Add a wrapper around sigaction(2), so we can insert our own wrapper

around signals.
o Lock the process global signal action table.
This commit is contained in:
mtm 2003-12-09 11:04:36 +00:00
parent 4e519fdfeb
commit 3fb7bc9aec
3 changed files with 62 additions and 0 deletions

View File

@ -46,6 +46,7 @@ SRCS+= \
thr_spec.c \
thr_spinlock.c \
thr_stack.c \
thr_subr.c \
thr_suspend_np.c \
thr_syscalls.c \
thr_yield.c

View File

@ -801,6 +801,9 @@ void _thread_critical_enter(pthread_t);
void _thread_critical_exit(pthread_t);
void _thread_sigblock();
void _thread_sigunblock();
void proc_sigact_copyin(int, const struct sigaction *);
void proc_sigact_copyout(int, struct sigaction *);
struct sigaction *proc_sigact_sigaction(int);
/* #include <sys/aio.h> */
#ifdef _SYS_AIO_H_

View File

@ -94,6 +94,7 @@ extern int __creat(const char *, mode_t);
extern int __sleep(unsigned int);
extern int __sys_nanosleep(const struct timespec *, struct timespec *);
extern int __sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
extern int __sys_sigaction(int, const struct sigaction *, struct sigaction *);
extern int __system(const char *);
extern int __tcdrain(int);
extern pid_t __wait(int *);
@ -314,6 +315,63 @@ _select(int numfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
return ret;
}
__weak_reference(_sigaction, sigaction);
int
_sigaction(int sig, const struct sigaction *act, struct sigaction *oact)
{
struct sigaction *tmpact;
struct sigaction oldact, wrapperact;
int error;
/* Detect invalid signals. Signal SIGTHR is silently ignored */
if (sig < 1 || sig > NSIG) {
errno = EINVAL;
return (-1);
}
if (sig == SIGTHR)
return (0);
/*
* If act is not NULL the library's signal wrapper is passed into the
* kernel only if the action is not SIG_DFL or SIG_IGN.
* On the other hand if act is NULL the caller only wants
* the old value so there is no need to call into the kernel.
*/
error = 0;
tmpact = NULL;
proc_sigact_copyout(sig, &oldact);
if (act != NULL) {
proc_sigact_copyin(sig, act);
tmpact = proc_sigact_sigaction(sig);
if (tmpact->sa_handler != SIG_DFL &&
tmpact->sa_handler != SIG_IGN) {
bcopy((const void *)tmpact, (void *)&wrapperact,
sizeof(struct sigaction));
tmpact->sa_flags &= SA_SIGINFO;
wrapperact.sa_sigaction = &_thread_sig_wrapper;
tmpact = &wrapperact;
}
error = __sys_sigaction(sig, tmpact, NULL);
}
if (error == 0) {
/* If successful, return the old sigaction to the user */
if (oact != NULL )
bcopy((const void *)&oldact, (void *)oact,
sizeof(struct sigaction));
} else {
/*
* The only time error is non-zero is if the syscall failed,
* which means the sigaction in the process global list
* was altered before the syscall. Return it to it's old value.
*/
proc_sigact_copyin(sig, &oldact);
}
return (error);
}
__weak_reference(_sleep, sleep);
unsigned int