libposix: honor SIG_IGN by doing nothing (DRAFT)

This commit is contained in:
Giacomo Tesio 2017-05-29 02:04:48 +02:00
parent 9dc9001469
commit d1e285f721
6 changed files with 69 additions and 14 deletions

View File

@ -213,7 +213,14 @@ extern int libposix_translate_exit_status(PosixExitStatusTranslator translator);
/* Dispatch the signal to the registered handlers. /* 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); 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); extern int libposix_define_realtime_signals(int sigrtmin, int sigrtmax);
/* Enable SIGCHLD emulation /* Enable SIGCHLD emulation
*/ */
extern int libposix_emulate_SIGCHLD(void); extern int libposix_emulate_SIGCHLD(void);

View File

@ -143,8 +143,11 @@ POSIX_read(int *errnop, int fd, char *buf, size_t len)
*errnop = __libposix_get_errno(PosixEBADF); *errnop = __libposix_get_errno(PosixEBADF);
return -1; return -1;
} }
SignalReenter:
r = sys_pread(fd, buf, len, -1); r = sys_pread(fd, buf, len, -1);
if(r < 0){ if(r < 0){
if(__libposix_restart_syscall())
goto SignalReenter;
*errnop = __libposix_translate_errstr((uintptr_t)POSIX_read); *errnop = __libposix_translate_errstr((uintptr_t)POSIX_read);
return -1; return -1;
} }
@ -160,8 +163,11 @@ POSIX_write(int *errnop, int fd, const void *buf, size_t len)
*errnop = __libposix_get_errno(PosixEBADF); *errnop = __libposix_get_errno(PosixEBADF);
return -1; return -1;
} }
SignalReenter:
w = sys_pwrite(fd, buf, len, -1); w = sys_pwrite(fd, buf, len, -1);
if(w < 0){ if(w < 0){
if(__libposix_restart_syscall())
goto SignalReenter;
*errnop = __libposix_translate_errstr((uintptr_t)POSIX_write); *errnop = __libposix_translate_errstr((uintptr_t)POSIX_write);
return -1; return -1;
} }
@ -269,9 +275,12 @@ POSIX_fstat(int *errnop, int file, void *pstat)
*errnop = __libposix_get_errno(PosixEBADF); *errnop = __libposix_get_errno(PosixEBADF);
return -1; return -1;
} }
SignalReenter:
d = dirfstat(file); d = dirfstat(file);
if(d == nil) if(d == nil)
{ {
if(__libposix_restart_syscall())
goto SignalReenter;
*errnop = __libposix_translate_errstr((uintptr_t)POSIX_fstat); *errnop = __libposix_translate_errstr((uintptr_t)POSIX_fstat);
return -1; return -1;
} }

View File

@ -24,6 +24,9 @@ extern int *__libposix_errors_codes;
extern WaitList **__libposix_wait_list; extern WaitList **__libposix_wait_list;
extern ChildList **__libposix_child_list; extern ChildList **__libposix_child_list;
static int __initialized; static int __initialized;
static unsigned char signals_to_code[256];
static unsigned char code_to_signal[256];
int *__libposix_sigchld_target_pid; 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 *__signals_to_code_map;
extern unsigned char *__code_to_signal_map; extern unsigned char *__code_to_signal_map;
extern int *__handling_external_signal; extern int *__handling_external_signal;
extern int *__restart_syscall;
extern int *__libposix_sigchld_target_pid; extern int *__libposix_sigchld_target_pid;
WaitList *wait_list; WaitList *wait_list;
ChildList *child_list; ChildList *child_list;
int status; int status;
int error_codes[ERRNO_LAST-ERRNO_FIRST]; int error_codes[ERRNO_LAST-ERRNO_FIRST];
unsigned char signals_to_code[256];
unsigned char code_to_signal[256];
int handling_signal; int handling_signal;
int sigchld_target_pid; int sigchld_target_pid;
int restart_syscall;
assert(__initialized == 0); assert(__initialized == 0);
@ -69,10 +72,10 @@ libposix_init(int argc, char *argv[], PosixInit init)
__libposix_child_list = &child_list; __libposix_child_list = &child_list;
/* initialize signal handling */ /* initialize signal handling */
memset(signals_to_code, 0, sizeof(signals_to_code)); restart_syscall = 0;
memset(code_to_signal, 0, sizeof(code_to_signal));
handling_signal = 0; handling_signal = 0;
sigchld_target_pid = 0; sigchld_target_pid = 0;
__restart_syscall = &restart_syscall;
__signals_to_code_map = signals_to_code; __signals_to_code_map = signals_to_code;
__code_to_signal_map = code_to_signal; __code_to_signal_map = code_to_signal;
__handling_external_signal = &handling_signal; __handling_external_signal = &handling_signal;

View File

@ -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_notify_signal_to_process(int pid, int signal);
extern PosixError __libposix_receive_signal(int sig); extern PosixError __libposix_receive_signal(int sig);
extern int __libposix_restart_syscall(void);

View File

@ -204,8 +204,11 @@ POSIX_wait(int *errnop, int *status)
return pid; return pid;
} }
SignalReenter:
w = wait(); w = wait();
if(w == nil){ if(w == nil){
if(__libposix_restart_syscall())
goto SignalReenter;
*errnop = __libposix_get_errno(PosixECHILD); *errnop = __libposix_get_errno(PosixECHILD);
return -1; return -1;
} }
@ -290,8 +293,11 @@ POSIX_waitpid(int *errnop, int reqpid, int *status, int options)
} }
WaitAgain: WaitAgain:
SignalReenter:
w = wait(); w = wait();
if(w == nil){ if(w == nil){
if(__libposix_restart_syscall())
goto SignalReenter;
*errnop = __libposix_get_errno(PosixECHILD); *errnop = __libposix_get_errno(PosixECHILD);
return -1; return -1;
} }

View File

@ -124,6 +124,7 @@
unsigned char *__signals_to_code_map; unsigned char *__signals_to_code_map;
unsigned char *__code_to_signal_map; unsigned char *__code_to_signal_map;
int *__handling_external_signal; int *__handling_external_signal;
int *__restart_syscall;
static int __sigrtmin; static int __sigrtmin;
static int __sigrtmax; static int __sigrtmax;
@ -189,14 +190,19 @@ ErrorBeforeOpen:
static int static int
execute_disposition(int sig, PosixSignalDisposition action) execute_disposition(int sig, PosixSignalDisposition action)
{ {
int aborted_by_signal;
switch(action){ switch(action){
case ResumeTheProcess: // the sender resumed us already case ResumeTheProcess: // the sender resumed us already
case SignalHandled: case SignalHandled:
return 1; return 1;
case TerminateTheProcess: case TerminateTheProcess:
case TerminateTheProcessAndCoreDump:
terminated_by_signal(sig); terminated_by_signal(sig);
break; break;
case TerminateTheProcessAndCoreDump:
aborted_by_signal = 0;
assert(aborted_by_signal);
break;
case StopTheProcess: case StopTheProcess:
return __libposix_send_control_msg(getpid(), "stop"); return __libposix_send_control_msg(getpid(), "stop");
} }
@ -254,16 +260,29 @@ default_signal_disposition(int code)
PosixError PosixError
__libposix_receive_signal(int sig) __libposix_receive_signal(int sig)
{ {
PosixSignalDisposition action; PosixSignalAction action = SignalDefault;
PosixSignals psig = __code_to_signal_map[sig]; PosixSignals psig = __code_to_signal_map[sig];
PosixSignalDisposition disposition;
if(psig != PosixSIGKILL && psig != PosixSIGSTOP if(psig != PosixSIGKILL && psig != PosixSIGSTOP)
&& __libposix_signal_trampoline(sig)) action = __libposix_signal_trampoline(sig);
action = SignalHandled; if(psig == PosixSIGABRT)
else action = SignalDefault; // lets abort despite the user will
action = default_signal_disposition(sig);
if(!execute_disposition(sig, action)) switch(action){
return PosixEPERM; 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; return 0;
} }
@ -427,6 +446,14 @@ libposix_set_signal_trampoline(PosixSignalTrampoline trampoline)
return 1; return 1;
} }
int
__libposix_restart_syscall(void)
{
int r = *__restart_syscall;
*__restart_syscall = 0;
return r;
}
void void
__libposix_signal_check_conf(void) __libposix_signal_check_conf(void)
{ {