libposix: honor SIG_IGN by doing nothing (DRAFT)
This commit is contained in:
parent
9dc9001469
commit
d1e285f721
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
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)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue