diff --git a/arch/aarch64/signal.S b/arch/aarch64/signal.S index 97fdd95f..984c85aa 100644 --- a/arch/aarch64/signal.S +++ b/arch/aarch64/signal.S @@ -20,12 +20,13 @@ .globl _signal_trampoline .type _signal_trampoline, %function _signal_trampoline: - /* Signal number, oldmask - keep stack aligned to 16 */ - ldp x0, x19, [sp], #0x10 - bl _signal_handler + /* Signal number, handler address - stack aligned to 16 */ + ldp x0, x1, [sp], #0x10 + blr x1 + + ldp x0, x1, [sp], #0x10 /* oldmask, cpu_context_t * */ + ldp x2, x3, [sp], #0x10 /* pc, sp, psr */ + ldr x4, [sp], #0x10 /* psr, skip padding at the end */ - mov x0, x19 /* move oldmask to x0 */ - ldp x1, x2, [sp], #0x10 /* cpu_context_t *, pc */ - ldp x3, x4, [sp], #0x10 /* sp, psr */ bl sigreturn .size _signal_trampoline, .-_signal_trampoline diff --git a/arch/arm/signal.S b/arch/arm/signal.S index 531fb602..fb477c3c 100644 --- a/arch/arm/signal.S +++ b/arch/arm/signal.S @@ -20,14 +20,11 @@ .globl _signal_trampoline .type _signal_trampoline, %function _signal_trampoline: - /* Signal number, oldmask - keep stack aligned to 8 */ - pop {r0,r4} - blx _signal_handler + /* Signal number, handler */ + pop {r0, r1} + blx r1 - mov r0, r4 /* move oldmask to r0 */ - pop {r1,r2,r3,r4} /* cpu_context_t *, pc, psp, psr */ - - /* put psr back on stack, keep aligned to 8 (r5 as padding value) */ - push {r4,r5} + pop {r0,r1,r2,r3} /* oldmask, cpu_context_t *, pc, psp */ + /* psr on stack */ bl sigreturn .size _signal_trampoline, .-_signal_trampoline diff --git a/arch/ia32/signal.S b/arch/ia32/signal.S index 1b887015..f62404f6 100644 --- a/arch/ia32/signal.S +++ b/arch/ia32/signal.S @@ -20,8 +20,9 @@ .globl _signal_trampoline .type _signal_trampoline, %function _signal_trampoline: + pop %ebx /* handler */ /* Signal number on stack */ - call _signal_handler + call %ebx addl $4, %esp /* oldmask is now on top of the stack */ diff --git a/arch/riscv64/signal.S b/arch/riscv64/signal.S index b87e41db..fb9c4c68 100644 --- a/arch/riscv64/signal.S +++ b/arch/riscv64/signal.S @@ -20,14 +20,15 @@ .globl _signal_trampoline .type _signal_trampoline, %function _signal_trampoline: - /* Get signal number from stack */ + /* Get signal number and handler address from stack */ lw a0, (sp) - call _signal_handler + ld a1, 8(sp) + jalr ra, a1, 0 - lw a0, 8(sp) /* old signal mask */ - ld a1, 16(sp) /* cpu context * */ - ld a2, 24(sp) /* sepc */ - ld a3, 32(sp) /* sp */ - addi sp, sp, 40 + lw a0, 16(sp) /* old signal mask */ + ld a1, 24(sp) /* cpu context * */ + ld a2, 32(sp) /* sepc */ + ld a3, 40(sp) /* sp */ + addi sp, sp, 48 call sigreturn .size _signal_trampoline, .-_signal_trampoline diff --git a/arch/sparcv8leon/signal.S b/arch/sparcv8leon/signal.S index b97e6df5..796f28bf 100644 --- a/arch/sparcv8leon/signal.S +++ b/arch/sparcv8leon/signal.S @@ -26,14 +26,15 @@ _signal_trampoline: save %sp, -0x60, %sp add %sp, 0xc0, %i0 - call _signal_handler + ld [%i0 + 0x04], %o1 /* handler address */ + jmpl %o1 + 0, %o7 ld [%i0], %o0 /* signal number */ - ld [%i0 + 0x04], %o0 /* old signal mask */ - ld [%i0 + 0x08], %o1 /* cpu_context * */ - ld [%i0 + 0x0c], %o2 /* pc */ - ld [%i0 + 0x10], %o3 /* npc */ - ld [%i0 + 0x14], %o4 /* sp */ + ld [%i0 + 0x08], %o0 /* old signal mask */ + ld [%i0 + 0x0c], %o1 /* cpu_context * */ + ld [%i0 + 0x10], %o2 /* pc */ + ld [%i0 + 0x14], %o3 /* npc */ + ld [%i0 + 0x18], %o4 /* sp */ call sigreturn - ld [%i0 + 0x18], %o5 /* psr */ + ld [%i0 + 0x1c], %o5 /* psr */ .size _signal_trampoline, .-_signal_trampoline diff --git a/include/signal.h b/include/signal.h index 541203c6..1225c924 100644 --- a/include/signal.h +++ b/include/signal.h @@ -17,8 +17,7 @@ #define _LIBPHOENIX_SIGNAL_H_ -#include -#include +#include #ifdef __cplusplus @@ -28,87 +27,6 @@ extern "C" { typedef void (*sighandler_t)(int); -#define SIGHUP 1 -#define SIGINT 2 -#define SIGQUIT 3 -#define SIGILL 4 -#define SIGTRAP 5 -#define SIGABRT 6 -#define SIGIOT SIGABRT -#define SIGEMT 7 -#define SIGFPE 8 -#define SIGKILL 9 -#define SIGBUS 10 -#define SIGSEGV 11 -#define SIGSYS 12 -#define SIGPIPE 13 -#define SIGALRM 14 -#define SIGTERM 15 -#define SIGURG 16 -#define SIGSTOP 17 -#define SIGTSTP 18 -#define SIGCONT 19 -#define SIGCHLD 20 -#define SIGTTIN 21 -#define SIGTTOU 22 -#define SIGIO 23 -#define SIGXCPU 24 -#define SIGXFSZ 25 -#define SIGVTALRM 26 -#define SIGPROF 27 -#define SIGWINCH 28 -#define SIGINFO 29 -#define SIGUSR1 30 -#define SIGUSR2 31 - -#define NSIG 32 - -#define SIG_ERR ((sighandler_t)-1) -#define SIG_DFL ((sighandler_t)-2) -#define SIG_IGN ((sighandler_t)-3) - - -enum { SIG_BLOCK, SIG_SETMASK, SIG_UNBLOCK }; - - -#define SA_NOCLDSTOP 1 << 0 -#define SA_NOCLDWAIT 1 << 1 -#define SA_NODEFER 1 << 2 -#define SA_ONSTACK 1 << 3 -#define SA_RESETHAND 1 << 4 -#define SA_RESTART 1 << 5 -#define SA_RESTORER 1 << 6 -#define SA_SIGINFO 1 << 7 - - -typedef int sigset_t; -typedef int sig_atomic_t; - - -union sigval { - int sival_int; - void *sival_ptr; -}; - - -typedef struct { - int si_signo; - int si_code; - pid_t si_pid; - uid_t si_uid; - void *si_addr; - int si_status; - union sigval si_value; -} siginfo_t; - - -struct sigaction { - void (*sa_handler) (int); - sigset_t sa_mask; - int sa_flags; - void (*sa_sigaction) (int, siginfo_t *, void *); -}; - extern void (*bsd_signal(int, void (*)(int)))(int); @@ -173,9 +91,6 @@ extern int sigsuspend(const sigset_t *); extern int sigwait(const sigset_t *, int *); -extern int signalPostPosix(int pid, int tid, int signal); - - #ifdef __cplusplus } #endif diff --git a/include/sys/threads.h b/include/sys/threads.h index 04d47197..f35a82a7 100644 --- a/include/sys/threads.h +++ b/include/sys/threads.h @@ -155,10 +155,10 @@ extern int condBroadcast(handle_t h); extern int resourceDestroy(handle_t h); -extern int signalHandle(void (*handler)(void), unsigned mask, unsigned mmask); +extern int signalAction(int signal, const struct sigaction *act, struct sigaction *oact, void (*trampoline)(void)); -extern int signalPost(int pid, int tid, int signal); +extern int sys_tkill(int pid, int tid, int signal); extern int signalReturn(int signal); diff --git a/include/sys/wait.h b/include/sys/wait.h index 5ece2f02..3368bd65 100644 --- a/include/sys/wait.h +++ b/include/sys/wait.h @@ -30,13 +30,10 @@ enum { }; -extern const int _signals_phx2posix[]; - - -#define WTERMSIG(stat_val) (_signals_phx2posix[(stat_val >> 8) & 0x7f]) -#define WEXITSTATUS(stat_val) ((stat_val) & 0xff) -#define WIFEXITED(stat_val) (WTERMSIG(stat_val) == 0) -#define WIFSIGNALED(stat_val) (WTERMSIG(stat_val) != 0) +#define WTERMSIG(stat_val) ((stat_val >> 8) & 0x7f) +#define WEXITSTATUS(stat_val) ((stat_val) & 0xff) +#define WIFEXITED(stat_val) (WTERMSIG(stat_val) == 0) +#define WIFSIGNALED(stat_val) (WTERMSIG(stat_val) != 0) #define WIFSTOPPED(stat_val) 0 #define WSTOPSIG(stat_val) 0 #define WIFCONTINUED(stat_val) 0 diff --git a/misc/init.c b/misc/init.c index eba32b43..a0603efa 100644 --- a/misc/init.c +++ b/misc/init.c @@ -16,7 +16,6 @@ extern void _malloc_init(void); extern int _env_init(void); -extern void _signals_init(void); extern void _file_init(void); extern void _errno_init(void); extern void _atexit_init(void); @@ -30,7 +29,6 @@ void _libc_init(void) _errno_init(); _malloc_init(); _env_init(); - _signals_init(); _file_init(); _pthread_init(); } diff --git a/pthread/pthread.c b/pthread/pthread.c index af76c7f3..215f079a 100644 --- a/pthread/pthread.c +++ b/pthread/pthread.c @@ -455,7 +455,7 @@ int pthread_cancel(pthread_t thread) mutexUnlock(pthread_common.pthread_list_lock); pthread_key_cleanup(ctx); pthread_ctx_put(ctx); - err = signalPost(getpid(), id, signal_cancel); + err = sys_tkill(getpid(), id, PH_SIGCANCEL); } else { _pthread_ctx_put(ctx); @@ -1070,7 +1070,7 @@ int pthread_sigmask(int how, const sigset_t *__restrict__ set, sigset_t *__restr int pthread_kill(pthread_t thread, int sig) { pthread_ctx *ctx = (pthread_ctx *)thread; - int ret = -signalPostPosix(getpid(), ctx->id, sig); + int ret = -sys_tkill(getpid(), ctx->id, sig); return ret; } diff --git a/signal/signal.c b/signal/signal.c index b6666edc..89cb0356 100644 --- a/signal/signal.c +++ b/signal/signal.c @@ -26,134 +26,18 @@ extern int sys_tkill(int pid, int tid, int signal); -struct { - sighandler_t sightab[NSIG]; - sigset_t sigset[NSIG]; - handle_t lock; -} signal_common; - - -const int _signals_phx2posix[] = { 0, SIGKILL, SIGSEGV, SIGILL, SIGFPE, SIGHUP, SIGINT, SIGQUIT, SIGTRAP, - SIGABRT, SIGEMT, SIGBUS, SIGSYS, SIGPIPE, SIGALRM, SIGTERM, SIGURG, SIGSTOP, SIGTSTP, SIGCONT, SIGCHLD, - SIGTTIN, SIGTTOU, SIGIO, SIGXCPU, SIGXFSZ, SIGVTALRM, SIGPROF, SIGWINCH, SIGINFO, SIGUSR1, SIGUSR2 }; - - -static const int _signals_posix2phx[] = { 0, 5, 6, 7, 3, 8, 9, 10, 4, 1, 11, 2, 12, 13, 14, 15, 16, 17, 18, 19, - 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 }; - - -static void _signal_bug(int sig) -{ -#ifndef NDEBUG - printf("%u: BUG - received signal #0\n", getpid()); -#endif -} - - -static void _signal_ignore(int sig) -{ -} - - -static void _signal_terminate(int sig) -{ - int phxsig = _signals_posix2phx[sig]; - - _exit(((phxsig) & 0x7f) << 8); -} - - -static void (*_signal_getdefault(int sig))(int) -{ - switch (sig) { - case 0: - return _signal_bug; - - case SIGHUP: - case SIGINT: - case SIGQUIT: - case SIGILL: - case SIGTRAP: - case SIGABRT: /* And SIGIOT */ - case SIGEMT: - case SIGFPE: /* Should be handled by the kernel? */ - case SIGKILL: /* Should kill the process before handler is ever invoked */ - case SIGBUS: - case SIGSEGV: - case SIGSYS: - case SIGPIPE: - case SIGALRM: - case SIGTERM: - case SIGIO: - case SIGXCPU: - case SIGXFSZ: - case SIGVTALRM: - case SIGPROF: - case SIGUSR1: - case SIGUSR2: - return _signal_terminate; - - case SIGURG: - case SIGSTOP: /* TODO: Stop process. Should be handled by the kernel? */ - case SIGTSTP: /* TODO: Stop process. Should be handled by the kernel? */ - case SIGCONT: /* TODO: Continue process. Should be handled by the kernel? */ - case SIGCHLD: - case SIGTTIN: /* TODO: Stop process. Should be handled by the kernel? */ - case SIGTTOU: /* TODO: Stop process. Should be handled by the kernel? */ - case SIGWINCH: - case SIGINFO: - return _signal_ignore; - - default: - return NULL; - } -} - - -static int _signal_ismutable(int sig) -{ - switch (sig) { - case SIGKILL: - case SIGSTOP: - return 0; - - default: - return 1; - } -} - - -void _signal_handler(int phxsig) -{ - int sig; - - if ((phxsig < 0) || (phxsig >= NSIG)) { - /* Don't know what to do, ignore it */ - return; - } - - /* Received Phoenix signal, need to convert it to POSIX signal */ - sig = _signals_phx2posix[phxsig]; - - /* POSIX: sa_mask should be ORed with current process signal mask */ - signalMask(signal_common.sigset[sig], signal_common.sigset[sig]); - - /* Invoke handler */ - (signal_common.sightab[sig])(sig); - - /* oldmask kept on stack and restored by sigreturn */ -} +extern void _signal_trampoline(void); int raise(int sig) { - return SET_ERRNO(sys_tkill(getpid(), gettid(), _signals_posix2phx[sig])); + return SET_ERRNO(sys_tkill(getpid(), gettid(), sig)); } int kill(pid_t pid, int sig) { - return SET_ERRNO(sys_tkill(pid, 0, _signals_posix2phx[sig])); + return SET_ERRNO(sys_tkill(pid, 0, sig)); } @@ -166,173 +50,60 @@ int killpg(pid_t pgrp, int sig) pgrp = -pgrp; } - return SET_ERRNO(sys_tkill(pgrp, 0, _signals_posix2phx[sig])); + return SET_ERRNO(sys_tkill(pgrp, 0, sig)); } void (*signal(int signum, void (*handler)(int)))(int) { - sighandler_t t; - unsigned int oldmask; - - if ((signum <= 0) || (signum >= NSIG)) { - (void)SET_ERRNO(-EINVAL); - return SIG_ERR; - } + struct sigaction act; + act.sa_handler = handler; + act.sa_flags = 0; + sigemptyset(&act.sa_mask); - if (_signal_ismutable(signum) == 0) { - (void)SET_ERRNO(-EINVAL); + struct sigaction oact = { 0 }; + if (sigaction(signum, &act, &oact) < 0) { return SIG_ERR; } - - /* Mask signal before change */ - mutexLock(signal_common.lock); - oldmask = signalMask(1UL << _signals_posix2phx[signum], 1UL << _signals_posix2phx[signum]); - - t = signal_common.sightab[signum]; - - if (handler == SIG_DFL) { - signal_common.sightab[signum] = _signal_getdefault(signum); - } - else if (handler == SIG_IGN) { - signal_common.sightab[signum] = _signal_ignore; - } - else { - signal_common.sightab[signum] = handler; - } - - signalMask(oldmask, 0xffffffffUL); - mutexUnlock(signal_common.lock); - - if (t == _signal_ignore) { - return SIG_IGN; - } - else if (t == _signal_getdefault(signum)) { - return SIG_DFL; - } - else { - return t; - } + return oact.sa_handler; } -/* TODO: Handle flags */ int sigaction(int sig, const struct sigaction *act, struct sigaction *oact) { - unsigned int oldmask; - int i; - - if ((sig <= 0) || (sig >= NSIG)) { - return SET_ERRNO(-EINVAL); - } - - if (oact != NULL) { - mutexLock(signal_common.lock); - if (signal_common.sightab[sig] == _signal_ignore) { - oact->sa_handler = (sighandler_t)SIG_IGN; - } - else if (signal_common.sightab[sig] == _signal_getdefault(sig)) { - oact->sa_handler = (sighandler_t)SIG_DFL; - } - else { - oact->sa_handler = signal_common.sightab[sig]; - } - - /* convert phx signals to POSIX */ - oact->sa_mask = 0; - for (i = 0; i < NSIG; ++i) { - if (signal_common.sigset[sig] & (1UL << i)) { - /* FIXME: support SA_NODEFER correctly (do not modify sa_mask when installing handler) */ - oact->sa_mask |= 1UL << _signals_phx2posix[i]; - } - } - - oact->sa_flags = 0; /* TODO: flags */ - mutexUnlock(signal_common.lock); - } - - if (act != NULL) { - if (_signal_ismutable(sig) == 0) { - return SET_ERRNO(-EINVAL); - } - - /* Mask signal before change */ - mutexLock(signal_common.lock); - oldmask = signalMask(1UL << _signals_posix2phx[sig], 1UL << _signals_posix2phx[sig]); - - if (act->sa_handler == (sighandler_t)SIG_IGN) { - signal_common.sightab[sig] = _signal_ignore; - } - else if (act->sa_handler == (sighandler_t)SIG_DFL) { - signal_common.sightab[sig] = _signal_getdefault(sig); - } - else { - signal_common.sightab[sig] = act->sa_handler; - } - - for (i = 0, signal_common.sigset[sig] = 0; i < NSIG; ++i) { - if (act->sa_mask & (1UL << i)) { - signal_common.sigset[sig] |= (1UL << _signals_posix2phx[i]); - } - } - - if ((act->sa_flags & SA_NODEFER) == 0) { - signal_common.sigset[sig] |= 1UL << _signals_posix2phx[sig]; - } - - signalMask(oldmask, 0xffffffffUL); - mutexUnlock(signal_common.lock); - } - - if ((oact == NULL) && (act == NULL)) { - return SET_ERRNO(-EINVAL); - } - - return EOK; + return SET_ERRNO(signalAction(sig, act, oact, _signal_trampoline)); } int sigprocmask(int how, const sigset_t *set, sigset_t *oldset) { - int i; - unsigned int phxv = 0u, mask = 0u, old; + unsigned int mask = 0u, mmask = 0u, old; if ((set == NULL) && (oldset == NULL)) { return EOK; } if (set != NULL) { - for (i = 0; i < NSIG; ++i) { - if ((*set & (1UL << i)) && (_signal_ismutable(i) != 0)) { - phxv |= (1UL << _signals_posix2phx[i]); - } - } - if (how == SIG_BLOCK) { - mask = phxv; - phxv = 0xffffffffUL; + mask = 0xffffffffU; + mmask = *set; } else if (how == SIG_UNBLOCK) { - mask = phxv; - phxv = 0; + mask = 0; + mmask = *set; } else if (how == SIG_SETMASK) { - mask = 0xffffffffUL; + mask = *set; + mmask = 0xffffffffU; } else { return SET_ERRNO(-EINVAL); } } - old = signalMask(phxv, mask); - + old = signalMask(mask, mmask); if (oldset != NULL) { - memset(oldset, 0, sizeof(sigset_t)); - for (i = 0; i < NSIG; ++i) { - if (old & (1UL << i)) { - (*oldset) |= (1UL << _signals_phx2posix[i]); - } - } + *oldset = old; } return EOK; @@ -341,15 +112,7 @@ int sigprocmask(int how, const sigset_t *set, sigset_t *oldset) int sigsuspend(const sigset_t *sigmask) { - unsigned int phxv = 0u, i; - - for (i = 0; i < NSIG; ++i) { - if (*sigmask & (1UL << i)) { - phxv |= (1UL << _signals_posix2phx[i]); - } - } - - return SET_ERRNO(signalSuspend(phxv)); + return SET_ERRNO(signalSuspend(*sigmask)); } @@ -370,7 +133,7 @@ int sigaddset(sigset_t *set, int signo) return SET_ERRNO(-EINVAL); } - *set |= (1UL << signo); + *set |= (1U << signo); return 0; } @@ -381,7 +144,7 @@ int sigismember(const sigset_t *set, int signum) return SET_ERRNO(-EINVAL); } - return !!(*set & (1UL << signum)); + return !!(*set & (1U << signum)); } @@ -416,32 +179,6 @@ int sigdelset(sigset_t *set, int signum) return SET_ERRNO(-EINVAL); } - *set &= ~(1UL << signum); + *set &= ~(1U << signum); return 0; } - - -int signalPostPosix(int pid, int tid, int signal) -{ - return signalPost(pid, tid, _signals_posix2phx[signal]); -} - - -extern void _signal_trampoline(void); - - -void _signals_init(void) -{ - int i; - - /* Set default actions */ - for (i = 0; i < NSIG; ++i) { - signal_common.sightab[i] = _signal_getdefault(i); - signal_common.sigset[i] = 1UL << _signals_posix2phx[i]; - } - - mutexCreate(&signal_common.lock); - - /* Register userspace handler */ - signalHandle(_signal_trampoline, 0, 0xffffffffUL); -}