diff options
author | kosaki <kosaki@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2011-05-28 13:52:03 +0000 |
---|---|---|
committer | kosaki <kosaki@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2011-05-28 13:52:03 +0000 |
commit | ed02c4122a67f209c7c9c4ebdd09647d0ae88e6d (patch) | |
tree | 07a9576a8d68c622988debe9c891414897e23657 /process.c | |
parent | e39b50d4b5531b84386862b47c3d3d273e6c32c7 (diff) |
* process.c (before_exec, after_exec): change SIGPIPE handler to SIG_DFL
before calling execve(). Because r31760 reintroduced an issue that
system() may hang up (i.e. [ruby-dev:12261]).
* process.c (save_sigpipe, restore_sigpipe): new.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@31761 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'process.c')
-rw-r--r-- | process.c | 36 |
1 files changed, 29 insertions, 7 deletions
@@ -984,14 +984,41 @@ void rb_thread_reset_timer_thread(void); static int forked_child = 0; +#ifdef SIGPIPE +static RETSIGTYPE (*saved_sigpipe_handler)(int) = 0; +#endif + +#if defined(POSIX_SIGNAL) +# define signal(a,b) posix_signal((a),(b)) +#endif + +static void save_sigpipe(void) +{ +#ifdef SIGPIPE + /* + * Some OS commands don't initialize signal handler properly. Thus we have to + * reset signal handler before exec(). Otherwise, system() and similar child process + * interaction might fail. (e.g. ruby -e "system 'yes | ls'") [ruby-dev:12261] + */ + saved_sigpipe_handler = signal(SIGPIPE, SIG_DFL); +#endif +} + +static void restore_sigpipe(void) +{ +#ifdef SIGPIPE + signal(SIGPIPE, saved_sigpipe_handler); +#endif +} + /* * On old MacOS X, exec() may return ENOTSUPP if the process have multiple threads. * Therefore we have to kill internal threads at once. [ruby-core: 10583] */ #define before_exec() \ - (rb_enable_interrupt(), (void)(forked_child ? 0 : (rb_thread_stop_timer_thread(), 1))) + (rb_enable_interrupt(), save_sigpipe(), (void)(forked_child ? 0 : (rb_thread_stop_timer_thread(), 1))) #define after_exec() \ - (rb_thread_reset_timer_thread(), rb_thread_start_timer_thread(), forked_child = 0, rb_disable_interrupt()) + (rb_thread_reset_timer_thread(), rb_thread_start_timer_thread(), forked_child = 0, restore_sigpipe(), rb_disable_interrupt()) #define before_fork() before_exec() #define after_fork() (GET_THREAD()->thrown_errinfo = 0, after_exec()) @@ -2907,11 +2934,6 @@ rb_f_abort(int argc, VALUE *argv) return Qnil; /* not reached */ } - -#if defined(POSIX_SIGNAL) -# define signal(a,b) posix_signal((a),(b)) -#endif - void rb_syswait(rb_pid_t pid) { |