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.
*/
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);

View File

@ -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;
}

View File

@ -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;

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_receive_signal(int sig);
extern int __libposix_restart_syscall(void);

View File

@ -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;
}

View File

@ -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)
{