Hi,
I writing a C-Extension for ruby using "rb_fork(0,0,0,Qnil)" to create a
new process.
Behaviour:
1) before fork a SIGTERM send to the parent terminate the parent
2) after fork a SIGTERM is ignored
Analyze:
SIGTERM is initialized in "Init_signal" using
#ifdef SIGTERM
install_sighandler(SIGTERM, sighandler);
#endif
but the fork code does in "rb_fork_err"
...
for (; before_fork(), (pid = fork()) < 0; prefork()) {
after_fork();
...
after_fork();
...
The problem is the "after_fork" is called for parent and child:
#define after_fork() (GET_THREAD()->thrown_errinfo = 0, after_exec())
#define after_exec() \
(rb_thread_reset_timer_thread(), rb_thread_start_timer_thread(),
forked_child = 0, rb_disable_interrupt())
void
rb_disable_interrupt(void)
{
#if USE_TRAP_MASK
sigset_t mask;
sigfillset(&mask);
sigdelset(&mask, SIGVTALRM);
sigdelset(&mask, SIGSEGV);
pthread_sigmask(SIG_SETMASK, &mask, NULL);
#endif
}
and all signals are blocked except SIGVTALRM and SIGSEGV
after adding
sigdelset(&mask, SIGTERM);
to rb_disable_interrupt the code is working but a real solution should
save the initial mask and later on enable the mask again ...
mfg
Andreas Otto