From d1e285f72192a7b1813692405c55e82f34af60e3 Mon Sep 17 00:00:00 2001 From: Giacomo Tesio Date: Mon, 29 May 2017 02:04:48 +0200 Subject: [PATCH] libposix: honor SIG_IGN by doing nothing (DRAFT) --- sys/include/posix.h | 10 +++++++- sys/src/lib/posix/files.c | 9 +++++++ sys/src/lib/posix/initlib.c | 11 +++++---- sys/src/lib/posix/internal.h | 2 ++ sys/src/lib/posix/processes.c | 6 +++++ sys/src/lib/posix/signals.c | 45 ++++++++++++++++++++++++++++------- 6 files changed, 69 insertions(+), 14 deletions(-) diff --git a/sys/include/posix.h b/sys/include/posix.h index 08560ee..1f3d006 100644 --- a/sys/include/posix.h +++ b/sys/include/posix.h @@ -213,7 +213,14 @@ extern int libposix_translate_exit_status(PosixExitStatusTranslator translator); /* Dispatch the signal to the registered handlers. */ -typedef int (*PosixSignalTrampoline)(int signal); +typedef enum PosixSignalAction +{ + SignalCatched = 1, + SignalIgnored, + SignalError, + SignalDefault +} PosixSignalAction; +typedef PosixSignalAction (*PosixSignalTrampoline)(int signal); extern int libposix_set_signal_trampoline(PosixSignalTrampoline trampoline); @@ -221,6 +228,7 @@ extern int libposix_define_signal(PosixSignals signal, int code); extern int libposix_define_realtime_signals(int sigrtmin, int sigrtmax); + /* Enable SIGCHLD emulation */ extern int libposix_emulate_SIGCHLD(void); diff --git a/sys/src/lib/posix/files.c b/sys/src/lib/posix/files.c index 9aec161..39f3455 100644 --- a/sys/src/lib/posix/files.c +++ b/sys/src/lib/posix/files.c @@ -143,8 +143,11 @@ POSIX_read(int *errnop, int fd, char *buf, size_t len) *errnop = __libposix_get_errno(PosixEBADF); return -1; } +SignalReenter: r = sys_pread(fd, buf, len, -1); if(r < 0){ + if(__libposix_restart_syscall()) + goto SignalReenter; *errnop = __libposix_translate_errstr((uintptr_t)POSIX_read); return -1; } @@ -160,8 +163,11 @@ POSIX_write(int *errnop, int fd, const void *buf, size_t len) *errnop = __libposix_get_errno(PosixEBADF); return -1; } +SignalReenter: w = sys_pwrite(fd, buf, len, -1); if(w < 0){ + if(__libposix_restart_syscall()) + goto SignalReenter; *errnop = __libposix_translate_errstr((uintptr_t)POSIX_write); return -1; } @@ -269,9 +275,12 @@ POSIX_fstat(int *errnop, int file, void *pstat) *errnop = __libposix_get_errno(PosixEBADF); return -1; } +SignalReenter: d = dirfstat(file); if(d == nil) { + if(__libposix_restart_syscall()) + goto SignalReenter; *errnop = __libposix_translate_errstr((uintptr_t)POSIX_fstat); return -1; } diff --git a/sys/src/lib/posix/initlib.c b/sys/src/lib/posix/initlib.c index 1b5b5e1..d87df55 100644 --- a/sys/src/lib/posix/initlib.c +++ b/sys/src/lib/posix/initlib.c @@ -24,6 +24,9 @@ extern int *__libposix_errors_codes; extern WaitList **__libposix_wait_list; extern ChildList **__libposix_child_list; static int __initialized; +static unsigned char signals_to_code[256]; +static unsigned char code_to_signal[256]; + int *__libposix_sigchld_target_pid; @@ -43,16 +46,16 @@ libposix_init(int argc, char *argv[], PosixInit init) extern unsigned char *__signals_to_code_map; extern unsigned char *__code_to_signal_map; extern int *__handling_external_signal; + extern int *__restart_syscall; extern int *__libposix_sigchld_target_pid; WaitList *wait_list; ChildList *child_list; int status; int error_codes[ERRNO_LAST-ERRNO_FIRST]; - unsigned char signals_to_code[256]; - unsigned char code_to_signal[256]; int handling_signal; int sigchld_target_pid; + int restart_syscall; assert(__initialized == 0); @@ -69,10 +72,10 @@ libposix_init(int argc, char *argv[], PosixInit init) __libposix_child_list = &child_list; /* initialize signal handling */ - memset(signals_to_code, 0, sizeof(signals_to_code)); - memset(code_to_signal, 0, sizeof(code_to_signal)); + restart_syscall = 0; handling_signal = 0; sigchld_target_pid = 0; + __restart_syscall = &restart_syscall; __signals_to_code_map = signals_to_code; __code_to_signal_map = code_to_signal; __handling_external_signal = &handling_signal; diff --git a/sys/src/lib/posix/internal.h b/sys/src/lib/posix/internal.h index 8c7768a..f2a7a96 100644 --- a/sys/src/lib/posix/internal.h +++ b/sys/src/lib/posix/internal.h @@ -62,3 +62,5 @@ extern int __libposix_send_control_msg(int pid, char *msg); extern PosixError __libposix_notify_signal_to_process(int pid, int signal); extern PosixError __libposix_receive_signal(int sig); + +extern int __libposix_restart_syscall(void); diff --git a/sys/src/lib/posix/processes.c b/sys/src/lib/posix/processes.c index aba3627..3f4ee4c 100644 --- a/sys/src/lib/posix/processes.c +++ b/sys/src/lib/posix/processes.c @@ -204,8 +204,11 @@ POSIX_wait(int *errnop, int *status) return pid; } +SignalReenter: w = wait(); if(w == nil){ + if(__libposix_restart_syscall()) + goto SignalReenter; *errnop = __libposix_get_errno(PosixECHILD); return -1; } @@ -290,8 +293,11 @@ POSIX_waitpid(int *errnop, int reqpid, int *status, int options) } WaitAgain: +SignalReenter: w = wait(); if(w == nil){ + if(__libposix_restart_syscall()) + goto SignalReenter; *errnop = __libposix_get_errno(PosixECHILD); return -1; } diff --git a/sys/src/lib/posix/signals.c b/sys/src/lib/posix/signals.c index b54501e..a0cf8fc 100644 --- a/sys/src/lib/posix/signals.c +++ b/sys/src/lib/posix/signals.c @@ -124,6 +124,7 @@ unsigned char *__signals_to_code_map; unsigned char *__code_to_signal_map; int *__handling_external_signal; +int *__restart_syscall; static int __sigrtmin; static int __sigrtmax; @@ -189,14 +190,19 @@ ErrorBeforeOpen: static int execute_disposition(int sig, PosixSignalDisposition action) { + int aborted_by_signal; + switch(action){ case ResumeTheProcess: // the sender resumed us already case SignalHandled: return 1; case TerminateTheProcess: - case TerminateTheProcessAndCoreDump: terminated_by_signal(sig); break; + case TerminateTheProcessAndCoreDump: + aborted_by_signal = 0; + assert(aborted_by_signal); + break; case StopTheProcess: return __libposix_send_control_msg(getpid(), "stop"); } @@ -254,16 +260,29 @@ default_signal_disposition(int code) PosixError __libposix_receive_signal(int sig) { - PosixSignalDisposition action; + PosixSignalAction action = SignalDefault; PosixSignals psig = __code_to_signal_map[sig]; + PosixSignalDisposition disposition; - if(psig != PosixSIGKILL && psig != PosixSIGSTOP - && __libposix_signal_trampoline(sig)) - action = SignalHandled; - else - action = default_signal_disposition(sig); - if(!execute_disposition(sig, action)) - return PosixEPERM; + if(psig != PosixSIGKILL && psig != PosixSIGSTOP) + action = __libposix_signal_trampoline(sig); + if(psig == PosixSIGABRT) + action = SignalDefault; // lets abort despite the user will + + switch(action){ + case SignalCatched: + return 0; + case SignalIgnored: + *__restart_syscall = 1; + return 0; + case SignalDefault: + disposition = default_signal_disposition(sig); + if(!execute_disposition(sig, disposition)) + return PosixEPERM; + break; + case SignalError: + return PosixEINVAL; + } return 0; } @@ -427,6 +446,14 @@ libposix_set_signal_trampoline(PosixSignalTrampoline trampoline) return 1; } +int +__libposix_restart_syscall(void) +{ + int r = *__restart_syscall; + *__restart_syscall = 0; + return r; +} + void __libposix_signal_check_conf(void) {