Change how SIGPIPE is ignored, and add a unit test to io.launcher.unix to ensure that this ignoredness is not inherited by child processes

db4
Slava Pestov 2010-09-02 22:11:45 -07:00
parent cdc9538540
commit 7374d868e7
3 changed files with 29 additions and 5 deletions

View File

@ -3,7 +3,8 @@ USING: io.files io.files.temp io.directories io.pathnames
tools.test io.launcher arrays io namespaces continuations math tools.test io.launcher arrays io namespaces continuations math
io.encodings.binary io.encodings.ascii accessors kernel io.encodings.binary io.encodings.ascii accessors kernel
sequences io.encodings.utf8 destructors io.streams.duplex locals sequences io.encodings.utf8 destructors io.streams.duplex locals
concurrency.promises threads unix.process calendar unix ; concurrency.promises threads unix.process calendar unix
unix.process debugger.unix io.timeouts io.launcher.unix ;
[ ] [ [ ] [
[ "launcher-test-1" temp-file delete-file ] ignore-errors [ "launcher-test-1" temp-file delete-file ] ignore-errors
@ -138,3 +139,21 @@ concurrency.promises threads unix.process calendar unix ;
s 3 seconds ?promise-timeout 0 = s 3 seconds ?promise-timeout 0 =
] ]
] unit-test ] unit-test
! Make sure that subprocesses don't inherit our signal mask
! First, ensure that the Factor VM ignores SIGPIPE
: send-sigpipe ( pid -- )
"SIGPIPE" signal-names index 1 +
kill io-error ;
[ ] [ current-process-handle send-sigpipe ] unit-test
! Spawn a process
[ T{ signal f 13 } ] [
"sleep 1000" run-detached
[ handle>> send-sigpipe ]
[ 2 seconds swap set-timeout ]
[ wait-for-process ]
tri
] unit-test

View File

@ -135,6 +135,10 @@ void misc_signal_handler(int signal, siginfo_t *siginfo, void *uap)
vm->dispatch_signal(uap,factor::misc_signal_handler_impl); vm->dispatch_signal(uap,factor::misc_signal_handler_impl);
} }
void ignore_signal_handler(int signal, siginfo_t *siginfo, void *uap)
{
}
void fpe_signal_handler(int signal, siginfo_t *siginfo, void *uap) void fpe_signal_handler(int signal, siginfo_t *siginfo, void *uap)
{ {
factor_vm *vm = current_vm(); factor_vm *vm = current_vm();
@ -206,9 +210,13 @@ void factor_vm::unix_init_signals()
sigaction_safe(SIGQUIT,&misc_sigaction,NULL); sigaction_safe(SIGQUIT,&misc_sigaction,NULL);
sigaction_safe(SIGILL,&misc_sigaction,NULL); sigaction_safe(SIGILL,&misc_sigaction,NULL);
/* We don't use SA_IGN here because then the ignore action is inherited
by subprocesses, which we don't want. There is a unit test in
io.launcher.unix for this. */
memset(&ignore_sigaction,0,sizeof(struct sigaction)); memset(&ignore_sigaction,0,sizeof(struct sigaction));
sigemptyset(&ignore_sigaction.sa_mask); sigemptyset(&ignore_sigaction.sa_mask);
ignore_sigaction.sa_handler = SIG_IGN; ignore_sigaction.sa_sigaction = ignore_signal_handler;
ignore_sigaction.sa_flags = SA_SIGINFO | SA_ONSTACK;
sigaction_safe(SIGPIPE,&ignore_sigaction,NULL); sigaction_safe(SIGPIPE,&ignore_sigaction,NULL);
} }

View File

@ -37,9 +37,6 @@ typedef pthread_t THREADHANDLE;
THREADHANDLE start_thread(void *(*start_routine)(void *),void *args); THREADHANDLE start_thread(void *(*start_routine)(void *),void *args);
inline static THREADHANDLE thread_id() { return pthread_self(); } inline static THREADHANDLE thread_id() { return pthread_self(); }
void signal_handler(int signal, siginfo_t* siginfo, void* uap);
void dump_stack_signal(int signal, siginfo_t* siginfo, void* uap);
u64 nano_count(); u64 nano_count();
void sleep_nanos(u64 nsec); void sleep_nanos(u64 nsec);
void open_console(); void open_console();