Ruby  2.0.0p594(2014-10-27revision48167)
signal.c
Go to the documentation of this file.
00001 /**********************************************************************
00002 
00003   signal.c -
00004 
00005   $Author: usa $
00006   created at: Tue Dec 20 10:13:44 JST 1994
00007 
00008   Copyright (C) 1993-2007 Yukihiro Matsumoto
00009   Copyright (C) 2000  Network Applied Communication Laboratory, Inc.
00010   Copyright (C) 2000  Information-technology Promotion Agency, Japan
00011 
00012 **********************************************************************/
00013 
00014 #include "ruby/ruby.h"
00015 #include "vm_core.h"
00016 #include <signal.h>
00017 #include <stdio.h>
00018 #include <errno.h>
00019 #include "ruby_atomic.h"
00020 #include "eval_intern.h"
00021 
00022 #if defined(__native_client__) && defined(NACL_NEWLIB)
00023 # include "nacl/signal.h"
00024 #endif
00025 
00026 #ifdef NEED_RUBY_ATOMIC_OPS
00027 rb_atomic_t
00028 ruby_atomic_exchange(rb_atomic_t *ptr, rb_atomic_t val)
00029 {
00030     rb_atomic_t old = *ptr;
00031     *ptr = val;
00032     return old;
00033 }
00034 
00035 rb_atomic_t
00036 ruby_atomic_compare_and_swap(rb_atomic_t *ptr, rb_atomic_t cmp,
00037                              rb_atomic_t newval)
00038 {
00039     rb_atomic_t old = *ptr;
00040     if (old == cmp) {
00041       *ptr = newval;
00042     }
00043     return old;
00044 }
00045 #endif
00046 
00047 #if defined(__BEOS__) || defined(__HAIKU__)
00048 #undef SIGBUS
00049 #endif
00050 
00051 #ifndef NSIG
00052 # define NSIG (_SIGMAX + 1)      /* For QNX */
00053 #endif
00054 
00055 static const struct signals {
00056     const char *signm;
00057     int  signo;
00058 } siglist [] = {
00059     {"EXIT", 0},
00060 #ifdef SIGHUP
00061     {"HUP", SIGHUP},
00062 #endif
00063     {"INT", SIGINT},
00064 #ifdef SIGQUIT
00065     {"QUIT", SIGQUIT},
00066 #endif
00067 #ifdef SIGILL
00068     {"ILL", SIGILL},
00069 #endif
00070 #ifdef SIGTRAP
00071     {"TRAP", SIGTRAP},
00072 #endif
00073 #ifdef SIGIOT
00074     {"IOT", SIGIOT},
00075 #endif
00076 #ifdef SIGABRT
00077     {"ABRT", SIGABRT},
00078 #endif
00079 #ifdef SIGEMT
00080     {"EMT", SIGEMT},
00081 #endif
00082 #ifdef SIGFPE
00083     {"FPE", SIGFPE},
00084 #endif
00085 #ifdef SIGKILL
00086     {"KILL", SIGKILL},
00087 #endif
00088 #ifdef SIGBUS
00089     {"BUS", SIGBUS},
00090 #endif
00091 #ifdef SIGSEGV
00092     {"SEGV", SIGSEGV},
00093 #endif
00094 #ifdef SIGSYS
00095     {"SYS", SIGSYS},
00096 #endif
00097 #ifdef SIGPIPE
00098     {"PIPE", SIGPIPE},
00099 #endif
00100 #ifdef SIGALRM
00101     {"ALRM", SIGALRM},
00102 #endif
00103 #ifdef SIGTERM
00104     {"TERM", SIGTERM},
00105 #endif
00106 #ifdef SIGURG
00107     {"URG", SIGURG},
00108 #endif
00109 #ifdef SIGSTOP
00110     {"STOP", SIGSTOP},
00111 #endif
00112 #ifdef SIGTSTP
00113     {"TSTP", SIGTSTP},
00114 #endif
00115 #ifdef SIGCONT
00116     {"CONT", SIGCONT},
00117 #endif
00118 #ifdef SIGCHLD
00119     {"CHLD", SIGCHLD},
00120 #endif
00121 #ifdef SIGCLD
00122     {"CLD", SIGCLD},
00123 #else
00124 # ifdef SIGCHLD
00125     {"CLD", SIGCHLD},
00126 # endif
00127 #endif
00128 #ifdef SIGTTIN
00129     {"TTIN", SIGTTIN},
00130 #endif
00131 #ifdef SIGTTOU
00132     {"TTOU", SIGTTOU},
00133 #endif
00134 #ifdef SIGIO
00135     {"IO", SIGIO},
00136 #endif
00137 #ifdef SIGXCPU
00138     {"XCPU", SIGXCPU},
00139 #endif
00140 #ifdef SIGXFSZ
00141     {"XFSZ", SIGXFSZ},
00142 #endif
00143 #ifdef SIGVTALRM
00144     {"VTALRM", SIGVTALRM},
00145 #endif
00146 #ifdef SIGPROF
00147     {"PROF", SIGPROF},
00148 #endif
00149 #ifdef SIGWINCH
00150     {"WINCH", SIGWINCH},
00151 #endif
00152 #ifdef SIGUSR1
00153     {"USR1", SIGUSR1},
00154 #endif
00155 #ifdef SIGUSR2
00156     {"USR2", SIGUSR2},
00157 #endif
00158 #ifdef SIGLOST
00159     {"LOST", SIGLOST},
00160 #endif
00161 #ifdef SIGMSG
00162     {"MSG", SIGMSG},
00163 #endif
00164 #ifdef SIGPWR
00165     {"PWR", SIGPWR},
00166 #endif
00167 #ifdef SIGPOLL
00168     {"POLL", SIGPOLL},
00169 #endif
00170 #ifdef SIGDANGER
00171     {"DANGER", SIGDANGER},
00172 #endif
00173 #ifdef SIGMIGRATE
00174     {"MIGRATE", SIGMIGRATE},
00175 #endif
00176 #ifdef SIGPRE
00177     {"PRE", SIGPRE},
00178 #endif
00179 #ifdef SIGGRANT
00180     {"GRANT", SIGGRANT},
00181 #endif
00182 #ifdef SIGRETRACT
00183     {"RETRACT", SIGRETRACT},
00184 #endif
00185 #ifdef SIGSOUND
00186     {"SOUND", SIGSOUND},
00187 #endif
00188 #ifdef SIGINFO
00189     {"INFO", SIGINFO},
00190 #endif
00191     {NULL, 0}
00192 };
00193 
00194 static int
00195 signm2signo(const char *nm)
00196 {
00197     const struct signals *sigs;
00198 
00199     for (sigs = siglist; sigs->signm; sigs++)
00200         if (strcmp(sigs->signm, nm) == 0)
00201             return sigs->signo;
00202     return 0;
00203 }
00204 
00205 static const char*
00206 signo2signm(int no)
00207 {
00208     const struct signals *sigs;
00209 
00210     for (sigs = siglist; sigs->signm; sigs++)
00211         if (sigs->signo == no)
00212             return sigs->signm;
00213     return 0;
00214 }
00215 
00216 /*
00217  * call-seq:
00218  *     Signal.signame(signo)  ->  string
00219  *
00220  *  convert signal number to signal name
00221  *
00222  *     Signal.trap("INT") { |signo| puts Signal.signame(signo) }
00223  *     Process.kill("INT", 0)
00224  *
00225  *  <em>produces:</em>
00226  *
00227  *     INT
00228  */
00229 static VALUE
00230 sig_signame(VALUE recv, VALUE signo)
00231 {
00232     const char *signame = signo2signm(NUM2INT(signo));
00233     return rb_str_new_cstr(signame);
00234 }
00235 
00236 const char *
00237 ruby_signal_name(int no)
00238 {
00239     return signo2signm(no);
00240 }
00241 
00242 /*
00243  * call-seq:
00244  *    SignalException.new(sig_name)              ->  signal_exception
00245  *    SignalException.new(sig_number [, name])   ->  signal_exception
00246  *
00247  *  Construct a new SignalException object.  +sig_name+ should be a known
00248  *  signal name.
00249  */
00250 
00251 static VALUE
00252 esignal_init(int argc, VALUE *argv, VALUE self)
00253 {
00254     int argnum = 1;
00255     VALUE sig = Qnil;
00256     int signo;
00257     const char *signm;
00258 
00259     if (argc > 0) {
00260         sig = rb_check_to_integer(argv[0], "to_int");
00261         if (!NIL_P(sig)) argnum = 2;
00262         else sig = argv[0];
00263     }
00264     rb_check_arity(argc, 1, argnum);
00265     if (argnum == 2) {
00266         signo = NUM2INT(sig);
00267         if (signo < 0 || signo > NSIG) {
00268             rb_raise(rb_eArgError, "invalid signal number (%d)", signo);
00269         }
00270         if (argc > 1) {
00271             sig = argv[1];
00272         }
00273         else {
00274             signm = signo2signm(signo);
00275             if (signm) {
00276                 sig = rb_sprintf("SIG%s", signm);
00277             }
00278             else {
00279                 sig = rb_sprintf("SIG%u", signo);
00280             }
00281         }
00282     }
00283     else {
00284         signm = SYMBOL_P(sig) ? rb_id2name(SYM2ID(sig)) : StringValuePtr(sig);
00285         if (strncmp(signm, "SIG", 3) == 0) signm += 3;
00286         signo = signm2signo(signm);
00287         if (!signo) {
00288             rb_raise(rb_eArgError, "unsupported name `SIG%s'", signm);
00289         }
00290         sig = rb_sprintf("SIG%s", signm);
00291     }
00292     rb_call_super(1, &sig);
00293     rb_iv_set(self, "signo", INT2NUM(signo));
00294 
00295     return self;
00296 }
00297 
00298 /*
00299  * call-seq:
00300  *    signal_exception.signo   ->  num
00301  *
00302  *  Returns a signal number.
00303  */
00304 
00305 static VALUE
00306 esignal_signo(VALUE self)
00307 {
00308     return rb_iv_get(self, "signo");
00309 }
00310 
00311 /* :nodoc: */
00312 static VALUE
00313 interrupt_init(int argc, VALUE *argv, VALUE self)
00314 {
00315     VALUE args[2];
00316 
00317     args[0] = INT2FIX(SIGINT);
00318     rb_scan_args(argc, argv, "01", &args[1]);
00319     return rb_call_super(2, args);
00320 }
00321 
00322 void
00323 ruby_default_signal(int sig)
00324 {
00325     signal(sig, SIG_DFL);
00326     raise(sig);
00327 }
00328 
00329 /*
00330  *  call-seq:
00331  *     Process.kill(signal, pid, ...)    -> fixnum
00332  *
00333  *  Sends the given signal to the specified process id(s) if _pid_ is positive.
00334  *  If _pid_ is zero _signal_ is sent to all processes whose group ID is equal
00335  *  to the group ID of the process. _signal_ may be an integer signal number or
00336  *  a POSIX signal name (either with or without a +SIG+ prefix). If _signal_ is
00337  *  negative (or starts with a minus sign), kills process groups instead of
00338  *  processes. Not all signals are available on all platforms.
00339  *
00340  *     pid = fork do
00341  *        Signal.trap("HUP") { puts "Ouch!"; exit }
00342  *        # ... do some work ...
00343  *     end
00344  *     # ...
00345  *     Process.kill("HUP", pid)
00346  *     Process.wait
00347  *
00348  *  <em>produces:</em>
00349  *
00350  *     Ouch!
00351  *
00352  *  If _signal_ is an integer but wrong for signal,
00353  *  <code>Errno::EINVAL</code> or +RangeError+ will be raised.
00354  *  Otherwise unless _signal_ is a +String+ or a +Symbol+, and a known
00355  *  signal name, +ArgumentError+ will be raised.
00356  *
00357  *  Also, <code>Errno::ESRCH</code> or +RangeError+ for invalid _pid_,
00358  *  <code>Errno::EPERM</code> when failed because of no privilege,
00359  *  will be raised.  In these cases, signals may have been sent to
00360  *  preceding processes.
00361  */
00362 
00363 VALUE
00364 rb_f_kill(int argc, VALUE *argv)
00365 {
00366 #ifndef HAVE_KILLPG
00367 #define killpg(pg, sig) kill(-(pg), (sig))
00368 #endif
00369     int negative = 0;
00370     int sig;
00371     int i;
00372     volatile VALUE str;
00373     const char *s;
00374 
00375     rb_secure(2);
00376     rb_check_arity(argc, 2, UNLIMITED_ARGUMENTS);
00377 
00378     switch (TYPE(argv[0])) {
00379       case T_FIXNUM:
00380         sig = FIX2INT(argv[0]);
00381         break;
00382 
00383       case T_SYMBOL:
00384         s = rb_id2name(SYM2ID(argv[0]));
00385         if (!s) rb_raise(rb_eArgError, "bad signal");
00386         goto str_signal;
00387 
00388       case T_STRING:
00389         s = RSTRING_PTR(argv[0]);
00390       str_signal:
00391         if (s[0] == '-') {
00392             negative++;
00393             s++;
00394         }
00395         if (strncmp("SIG", s, 3) == 0)
00396             s += 3;
00397         if ((sig = signm2signo(s)) == 0)
00398             rb_raise(rb_eArgError, "unsupported name `SIG%s'", s);
00399 
00400         if (negative)
00401             sig = -sig;
00402         break;
00403 
00404       default:
00405         str = rb_check_string_type(argv[0]);
00406         if (!NIL_P(str)) {
00407             s = RSTRING_PTR(str);
00408             goto str_signal;
00409         }
00410         rb_raise(rb_eArgError, "bad signal type %s",
00411                  rb_obj_classname(argv[0]));
00412         break;
00413     }
00414 
00415     if (sig < 0) {
00416         sig = -sig;
00417         for (i=1; i<argc; i++) {
00418             if (killpg(NUM2PIDT(argv[i]), sig) < 0)
00419                 rb_sys_fail(0);
00420         }
00421     }
00422     else {
00423         for (i=1; i<argc; i++) {
00424             if (kill(NUM2PIDT(argv[i]), sig) < 0)
00425                 rb_sys_fail(0);
00426         }
00427     }
00428     return INT2FIX(i-1);
00429 }
00430 
00431 static struct {
00432     rb_atomic_t cnt[RUBY_NSIG];
00433     rb_atomic_t size;
00434 } signal_buff;
00435 
00436 #ifdef __dietlibc__
00437 #define sighandler_t sh_t
00438 #endif
00439 
00440 typedef RETSIGTYPE (*sighandler_t)(int);
00441 #ifdef USE_SIGALTSTACK
00442 typedef void ruby_sigaction_t(int, siginfo_t*, void*);
00443 #define SIGINFO_ARG , siginfo_t *info, void *ctx
00444 #else
00445 typedef RETSIGTYPE ruby_sigaction_t(int);
00446 #define SIGINFO_ARG
00447 #endif
00448 
00449 #ifdef USE_SIGALTSTACK
00450 int rb_sigaltstack_size(void)
00451 {
00452     /* XXX: BSD_vfprintf() uses >1500KiB stack and x86-64 need >5KiB stack. */
00453     int size = 8192;
00454 
00455 #ifdef MINSIGSTKSZ
00456     if (size < MINSIGSTKSZ)
00457         size = MINSIGSTKSZ;
00458 #endif
00459 #if defined(HAVE_SYSCONF) && defined(_SC_PAGE_SIZE)
00460     {
00461         int pagesize;
00462         pagesize = (int)sysconf(_SC_PAGE_SIZE);
00463         if (size < pagesize)
00464             size = pagesize;
00465     }
00466 #endif
00467 
00468     return size;
00469 }
00470 
00471 /* alternate stack for SIGSEGV */
00472 void
00473 rb_register_sigaltstack(rb_thread_t *th)
00474 {
00475     stack_t newSS, oldSS;
00476 
00477     if (!th->altstack)
00478         rb_bug("rb_register_sigaltstack: th->altstack not initialized\n");
00479 
00480     newSS.ss_sp = th->altstack;
00481     newSS.ss_size = rb_sigaltstack_size();
00482     newSS.ss_flags = 0;
00483 
00484     sigaltstack(&newSS, &oldSS); /* ignore error. */
00485 }
00486 #endif /* USE_SIGALTSTACK */
00487 
00488 #ifdef POSIX_SIGNAL
00489 static sighandler_t
00490 ruby_signal(int signum, sighandler_t handler)
00491 {
00492     struct sigaction sigact, old;
00493 
00494 #if 0
00495     rb_trap_accept_nativethreads[signum] = 0;
00496 #endif
00497 
00498     sigemptyset(&sigact.sa_mask);
00499 #ifdef USE_SIGALTSTACK
00500     sigact.sa_sigaction = (ruby_sigaction_t*)handler;
00501     sigact.sa_flags = SA_SIGINFO;
00502 #else
00503     sigact.sa_handler = handler;
00504     sigact.sa_flags = 0;
00505 #endif
00506 
00507 #ifdef SA_NOCLDWAIT
00508     if (signum == SIGCHLD && handler == SIG_IGN)
00509         sigact.sa_flags |= SA_NOCLDWAIT;
00510 #endif
00511 #if defined(SA_ONSTACK) && defined(USE_SIGALTSTACK)
00512     if (signum == SIGSEGV
00513 #ifdef SIGBUS
00514         || signum == SIGBUS
00515 #endif
00516        )
00517         sigact.sa_flags |= SA_ONSTACK;
00518 #endif
00519     if (sigaction(signum, &sigact, &old) < 0) {
00520         if (errno != 0 && errno != EINVAL) {
00521             rb_bug_errno("sigaction", errno);
00522         }
00523     }
00524     if (old.sa_flags & SA_SIGINFO)
00525         return (sighandler_t)old.sa_sigaction;
00526     else
00527         return old.sa_handler;
00528 }
00529 
00530 sighandler_t
00531 posix_signal(int signum, sighandler_t handler)
00532 {
00533     return ruby_signal(signum, handler);
00534 }
00535 
00536 #else /* !POSIX_SIGNAL */
00537 #define ruby_signal(sig,handler) (/* rb_trap_accept_nativethreads[(sig)] = 0,*/ signal((sig),(handler)))
00538 #if 0 /* def HAVE_NATIVETHREAD */
00539 static sighandler_t
00540 ruby_nativethread_signal(int signum, sighandler_t handler)
00541 {
00542     sighandler_t old;
00543 
00544     old = signal(signum, handler);
00545     rb_trap_accept_nativethreads[signum] = 1;
00546     return old;
00547 }
00548 #endif
00549 #endif
00550 
00551 static RETSIGTYPE
00552 sighandler(int sig)
00553 {
00554     ATOMIC_INC(signal_buff.cnt[sig]);
00555     ATOMIC_INC(signal_buff.size);
00556     rb_thread_wakeup_timer_thread();
00557 #if !defined(BSD_SIGNAL) && !defined(POSIX_SIGNAL)
00558     ruby_signal(sig, sighandler);
00559 #endif
00560 }
00561 
00562 int
00563 rb_signal_buff_size(void)
00564 {
00565     return signal_buff.size;
00566 }
00567 
00568 #if HAVE_PTHREAD_H
00569 #include <pthread.h>
00570 #endif
00571 
00572 static void
00573 rb_disable_interrupt(void)
00574 {
00575 #ifdef HAVE_PTHREAD_SIGMASK
00576     sigset_t mask;
00577     sigfillset(&mask);
00578     pthread_sigmask(SIG_SETMASK, &mask, NULL);
00579 #endif
00580 }
00581 
00582 static void
00583 rb_enable_interrupt(void)
00584 {
00585 #ifdef HAVE_PTHREAD_SIGMASK
00586     sigset_t mask;
00587     sigemptyset(&mask);
00588     pthread_sigmask(SIG_SETMASK, &mask, NULL);
00589 #endif
00590 }
00591 
00592 int
00593 rb_get_next_signal(void)
00594 {
00595     int i, sig = 0;
00596 
00597     if (signal_buff.size != 0) {
00598         for (i=1; i<RUBY_NSIG; i++) {
00599             if (signal_buff.cnt[i] > 0) {
00600                 ATOMIC_DEC(signal_buff.cnt[i]);
00601                 ATOMIC_DEC(signal_buff.size);
00602                 sig = i;
00603                 break;
00604             }
00605         }
00606     }
00607     return sig;
00608 }
00609 
00610 
00611 #if defined(USE_SIGALTSTACK) || defined(_WIN32)
00612 static void
00613 check_stack_overflow(const void *addr)
00614 {
00615     int ruby_stack_overflowed_p(const rb_thread_t *, const void *);
00616     NORETURN(void ruby_thread_stack_overflow(rb_thread_t *th));
00617     rb_thread_t *th = ruby_current_thread;
00618     if (ruby_stack_overflowed_p(th, addr)) {
00619         ruby_thread_stack_overflow(th);
00620     }
00621 }
00622 #ifdef _WIN32
00623 #define CHECK_STACK_OVERFLOW() check_stack_overflow(0)
00624 #else
00625 #define CHECK_STACK_OVERFLOW() check_stack_overflow(info->si_addr)
00626 #endif
00627 #else
00628 #define CHECK_STACK_OVERFLOW() (void)0
00629 #endif
00630 
00631 #ifdef SIGBUS
00632 static RETSIGTYPE
00633 sigbus(int sig SIGINFO_ARG)
00634 {
00635 /*
00636  * Mac OS X makes KERN_PROTECTION_FAILURE when thread touch guard page.
00637  * and it's delivered as SIGBUS instaed of SIGSEGV to userland. It's crazy
00638  * wrong IMHO. but anyway we have to care it. Sigh.
00639  */
00640 #if defined __APPLE__
00641     CHECK_STACK_OVERFLOW();
00642 #endif
00643     rb_bug("Bus Error");
00644 }
00645 #endif
00646 
00647 #ifdef SIGSEGV
00648 static void ruby_abort(void)
00649 {
00650 #ifdef __sun
00651     /* Solaris's abort() is async signal unsafe. Of course, it is not
00652      *  POSIX compliant.
00653      */
00654     raise(SIGABRT);
00655 #else
00656     abort();
00657 #endif
00658 
00659 }
00660 
00661 static int segv_received = 0;
00662 extern int ruby_disable_gc_stress;
00663 
00664 static RETSIGTYPE
00665 sigsegv(int sig SIGINFO_ARG)
00666 {
00667     if (segv_received) {
00668         ssize_t RB_UNUSED_VAR(err);
00669         char msg[] = "SEGV received in SEGV handler\n";
00670 
00671         err = write(2, msg, sizeof(msg));
00672         ruby_abort();
00673     }
00674 
00675     CHECK_STACK_OVERFLOW();
00676 
00677     segv_received = 1;
00678     ruby_disable_gc_stress = 1;
00679     rb_bug("Segmentation fault");
00680 }
00681 #endif
00682 
00683 static void
00684 signal_exec(VALUE cmd, int safe, int sig)
00685 {
00686     rb_thread_t *cur_th = GET_THREAD();
00687     volatile unsigned long old_interrupt_mask = cur_th->interrupt_mask;
00688     int state;
00689 
00690     /*
00691      * workaround the following race:
00692      * 1. signal_enque queues signal for execution
00693      * 2. user calls trap(sig, "IGNORE"), setting SIG_IGN
00694      * 3. rb_signal_exec runs on queued signal
00695      */
00696     if (IMMEDIATE_P(cmd))
00697         return;
00698 
00699     cur_th->interrupt_mask |= TRAP_INTERRUPT_MASK;
00700     TH_PUSH_TAG(cur_th);
00701     if ((state = EXEC_TAG()) == 0) {
00702         VALUE signum = INT2NUM(sig);
00703         rb_eval_cmd(cmd, rb_ary_new3(1, signum), safe);
00704     }
00705     TH_POP_TAG();
00706     cur_th = GET_THREAD();
00707     cur_th->interrupt_mask = old_interrupt_mask;
00708 
00709     if (state) {
00710         /* XXX: should be replaced with rb_threadptr_pending_interrupt_enque() */
00711         JUMP_TAG(state);
00712     }
00713 }
00714 
00715 void
00716 rb_trap_exit(void)
00717 {
00718     rb_vm_t *vm = GET_VM();
00719     VALUE trap_exit = vm->trap_list[0].cmd;
00720 
00721     if (trap_exit) {
00722         vm->trap_list[0].cmd = 0;
00723         signal_exec(trap_exit, vm->trap_list[0].safe, 0);
00724     }
00725 }
00726 
00727 void
00728 rb_signal_exec(rb_thread_t *th, int sig)
00729 {
00730     rb_vm_t *vm = GET_VM();
00731     VALUE cmd = vm->trap_list[sig].cmd;
00732     int safe = vm->trap_list[sig].safe;
00733 
00734     if (cmd == 0) {
00735         switch (sig) {
00736           case SIGINT:
00737             rb_interrupt();
00738             break;
00739 #ifdef SIGHUP
00740           case SIGHUP:
00741 #endif
00742 #ifdef SIGQUIT
00743           case SIGQUIT:
00744 #endif
00745 #ifdef SIGTERM
00746           case SIGTERM:
00747 #endif
00748 #ifdef SIGALRM
00749           case SIGALRM:
00750 #endif
00751 #ifdef SIGUSR1
00752           case SIGUSR1:
00753 #endif
00754 #ifdef SIGUSR2
00755           case SIGUSR2:
00756 #endif
00757             rb_threadptr_signal_raise(th, sig);
00758             break;
00759         }
00760     }
00761     else if (cmd == Qundef) {
00762         rb_threadptr_signal_exit(th);
00763     }
00764     else {
00765         signal_exec(cmd, safe, sig);
00766     }
00767 }
00768 
00769 static sighandler_t
00770 default_handler(int sig)
00771 {
00772     sighandler_t func;
00773     switch (sig) {
00774       case SIGINT:
00775 #ifdef SIGHUP
00776       case SIGHUP:
00777 #endif
00778 #ifdef SIGQUIT
00779       case SIGQUIT:
00780 #endif
00781 #ifdef SIGTERM
00782       case SIGTERM:
00783 #endif
00784 #ifdef SIGALRM
00785       case SIGALRM:
00786 #endif
00787 #ifdef SIGUSR1
00788       case SIGUSR1:
00789 #endif
00790 #ifdef SIGUSR2
00791       case SIGUSR2:
00792 #endif
00793         func = sighandler;
00794         break;
00795 #ifdef SIGBUS
00796       case SIGBUS:
00797         func = (sighandler_t)sigbus;
00798         break;
00799 #endif
00800 #ifdef SIGSEGV
00801       case SIGSEGV:
00802         func = (sighandler_t)sigsegv;
00803         break;
00804 #endif
00805 #ifdef SIGPIPE
00806       case SIGPIPE:
00807         func = SIG_IGN;
00808         break;
00809 #endif
00810       default:
00811         func = SIG_DFL;
00812         break;
00813     }
00814 
00815     return func;
00816 }
00817 
00818 static sighandler_t
00819 trap_handler(VALUE *cmd, int sig)
00820 {
00821     sighandler_t func = sighandler;
00822     VALUE command;
00823 
00824     if (NIL_P(*cmd)) {
00825         func = SIG_IGN;
00826     }
00827     else {
00828         command = rb_check_string_type(*cmd);
00829         if (NIL_P(command) && SYMBOL_P(*cmd)) {
00830             command = rb_id2str(SYM2ID(*cmd));
00831             if (!command) rb_raise(rb_eArgError, "bad handler");
00832         }
00833         if (!NIL_P(command)) {
00834             SafeStringValue(command);   /* taint check */
00835             *cmd = command;
00836             switch (RSTRING_LEN(command)) {
00837               case 0:
00838                 goto sig_ign;
00839                 break;
00840               case 14:
00841                 if (strncmp(RSTRING_PTR(command), "SYSTEM_DEFAULT", 14) == 0) {
00842                     func = SIG_DFL;
00843                     *cmd = 0;
00844                 }
00845                 break;
00846               case 7:
00847                 if (strncmp(RSTRING_PTR(command), "SIG_IGN", 7) == 0) {
00848 sig_ign:
00849                     func = SIG_IGN;
00850                     *cmd = Qtrue;
00851                 }
00852                 else if (strncmp(RSTRING_PTR(command), "SIG_DFL", 7) == 0) {
00853 sig_dfl:
00854                     func = default_handler(sig);
00855                     *cmd = 0;
00856                 }
00857                 else if (strncmp(RSTRING_PTR(command), "DEFAULT", 7) == 0) {
00858                     goto sig_dfl;
00859                 }
00860                 break;
00861               case 6:
00862                 if (strncmp(RSTRING_PTR(command), "IGNORE", 6) == 0) {
00863                     goto sig_ign;
00864                 }
00865                 break;
00866               case 4:
00867                 if (strncmp(RSTRING_PTR(command), "EXIT", 4) == 0) {
00868                     *cmd = Qundef;
00869                 }
00870                 break;
00871             }
00872         }
00873         else {
00874             rb_proc_t *proc;
00875             GetProcPtr(*cmd, proc);
00876             (void)proc;
00877         }
00878     }
00879 
00880     return func;
00881 }
00882 
00883 static int
00884 trap_signm(VALUE vsig)
00885 {
00886     int sig = -1;
00887     const char *s;
00888 
00889     switch (TYPE(vsig)) {
00890       case T_FIXNUM:
00891         sig = FIX2INT(vsig);
00892         if (sig < 0 || sig >= NSIG) {
00893             rb_raise(rb_eArgError, "invalid signal number (%d)", sig);
00894         }
00895         break;
00896 
00897       case T_SYMBOL:
00898         s = rb_id2name(SYM2ID(vsig));
00899         if (!s) rb_raise(rb_eArgError, "bad signal");
00900         goto str_signal;
00901 
00902       default:
00903         s = StringValuePtr(vsig);
00904 
00905       str_signal:
00906         if (strncmp("SIG", s, 3) == 0)
00907             s += 3;
00908         sig = signm2signo(s);
00909         if (sig == 0 && strcmp(s, "EXIT") != 0)
00910             rb_raise(rb_eArgError, "unsupported signal SIG%s", s);
00911     }
00912     return sig;
00913 }
00914 
00915 static VALUE
00916 trap(int sig, sighandler_t func, VALUE command)
00917 {
00918     sighandler_t oldfunc;
00919     VALUE oldcmd;
00920     rb_vm_t *vm = GET_VM();
00921 
00922     /*
00923      * Be careful. ruby_signal() and trap_list[sig].cmd must be changed
00924      * atomically. In current implementation, we only need to don't call
00925      * RUBY_VM_CHECK_INTS().
00926      */
00927     oldfunc = ruby_signal(sig, func);
00928     oldcmd = vm->trap_list[sig].cmd;
00929     switch (oldcmd) {
00930       case 0:
00931       case Qtrue:
00932         if (oldfunc == SIG_IGN) oldcmd = rb_str_new2("IGNORE");
00933         else if (oldfunc == sighandler) oldcmd = rb_str_new2("DEFAULT");
00934         else oldcmd = Qnil;
00935         break;
00936       case Qnil:
00937         break;
00938       case Qundef:
00939         oldcmd = rb_str_new2("EXIT");
00940         break;
00941     }
00942 
00943     vm->trap_list[sig].cmd = command;
00944     vm->trap_list[sig].safe = rb_safe_level();
00945 
00946     return oldcmd;
00947 }
00948 
00949 static int
00950 reserved_signal_p(int signo)
00951 {
00952 /* Synchronous signal can't deliver to main thread */
00953 #ifdef SIGSEGV
00954     if (signo == SIGSEGV)
00955         return 1;
00956 #endif
00957 #ifdef SIGBUS
00958     if (signo == SIGBUS)
00959         return 1;
00960 #endif
00961 #ifdef SIGILL
00962     if (signo == SIGILL)
00963         return 1;
00964 #endif
00965 #ifdef SIGFPE
00966     if (signo == SIGFPE)
00967         return 1;
00968 #endif
00969 
00970 /* used ubf internal see thread_pthread.c. */
00971 #ifdef SIGVTALRM
00972     if (signo == SIGVTALRM)
00973         return 1;
00974 #endif
00975 
00976     return 0;
00977 }
00978 
00979 /*
00980  * call-seq:
00981  *   Signal.trap( signal, command ) -> obj
00982  *   Signal.trap( signal ) {| | block } -> obj
00983  *
00984  * Specifies the handling of signals. The first parameter is a signal
00985  * name (a string such as ``SIGALRM'', ``SIGUSR1'', and so on) or a
00986  * signal number. The characters ``SIG'' may be omitted from the
00987  * signal name. The command or block specifies code to be run when the
00988  * signal is raised.
00989  * If the command is the string ``IGNORE'' or ``SIG_IGN'', the signal
00990  * will be ignored.
00991  * If the command is ``DEFAULT'' or ``SIG_DFL'', the Ruby's default handler
00992  * will be invoked.
00993  * If the command is ``EXIT'', the script will be terminated by the signal.
00994  * If the command is ``SYSTEM_DEFAULT'', the operating system's default
00995  * handler will be invoked.
00996  * Otherwise, the given command or block will be run.
00997  * The special signal name ``EXIT'' or signal number zero will be
00998  * invoked just prior to program termination.
00999  * trap returns the previous handler for the given signal.
01000  *
01001  *     Signal.trap(0, proc { puts "Terminating: #{$$}" })
01002  *     Signal.trap("CLD")  { puts "Child died" }
01003  *     fork && Process.wait
01004  *
01005  * produces:
01006  *     Terminating: 27461
01007  *     Child died
01008  *     Terminating: 27460
01009  */
01010 static VALUE
01011 sig_trap(int argc, VALUE *argv)
01012 {
01013     int sig;
01014     sighandler_t func;
01015     VALUE cmd;
01016 
01017     rb_secure(2);
01018     rb_check_arity(argc, 1, 2);
01019 
01020     sig = trap_signm(argv[0]);
01021     if (reserved_signal_p(sig)) {
01022         const char *name = signo2signm(sig);
01023         if (name)
01024             rb_raise(rb_eArgError, "can't trap reserved signal: SIG%s", name);
01025         else
01026             rb_raise(rb_eArgError, "can't trap reserved signal: %d", sig);
01027     }
01028 
01029     if (argc == 1) {
01030         cmd = rb_block_proc();
01031         func = sighandler;
01032     }
01033     else {
01034         cmd = argv[1];
01035         func = trap_handler(&cmd, sig);
01036     }
01037 
01038     if (OBJ_TAINTED(cmd)) {
01039         rb_raise(rb_eSecurityError, "Insecure: tainted signal trap");
01040     }
01041 
01042     return trap(sig, func, cmd);
01043 }
01044 
01045 /*
01046  * call-seq:
01047  *   Signal.list -> a_hash
01048  *
01049  * Returns a list of signal names mapped to the corresponding
01050  * underlying signal numbers.
01051  *
01052  *   Signal.list   #=> {"EXIT"=>0, "HUP"=>1, "INT"=>2, "QUIT"=>3, "ILL"=>4, "TRAP"=>5, "IOT"=>6, "ABRT"=>6, "FPE"=>8, "KILL"=>9, "BUS"=>7, "SEGV"=>11, "SYS"=>31, "PIPE"=>13, "ALRM"=>14, "TERM"=>15, "URG"=>23, "STOP"=>19, "TSTP"=>20, "CONT"=>18, "CHLD"=>17, "CLD"=>17, "TTIN"=>21, "TTOU"=>22, "IO"=>29, "XCPU"=>24, "XFSZ"=>25, "VTALRM"=>26, "PROF"=>27, "WINCH"=>28, "USR1"=>10, "USR2"=>12, "PWR"=>30, "POLL"=>29}
01053  */
01054 static VALUE
01055 sig_list(void)
01056 {
01057     VALUE h = rb_hash_new();
01058     const struct signals *sigs;
01059 
01060     for (sigs = siglist; sigs->signm; sigs++) {
01061         rb_hash_aset(h, rb_str_new2(sigs->signm), INT2FIX(sigs->signo));
01062     }
01063     return h;
01064 }
01065 
01066 static void
01067 install_sighandler(int signum, sighandler_t handler)
01068 {
01069     sighandler_t old;
01070 
01071     /* At this time, there is no subthread. Then sigmask guarantee atomics. */
01072     rb_disable_interrupt();
01073     old = ruby_signal(signum, handler);
01074     /* signal handler should be inherited during exec. */
01075     if (old != SIG_DFL) {
01076         ruby_signal(signum, old);
01077     }
01078     rb_enable_interrupt();
01079 }
01080 
01081 #if defined(SIGCLD) || defined(SIGCHLD)
01082 static void
01083 init_sigchld(int sig)
01084 {
01085     sighandler_t oldfunc;
01086 
01087     rb_disable_interrupt();
01088     oldfunc = ruby_signal(sig, SIG_DFL);
01089     if (oldfunc != SIG_DFL && oldfunc != SIG_IGN) {
01090         ruby_signal(sig, oldfunc);
01091     } else {
01092         GET_VM()->trap_list[sig].cmd = 0;
01093     }
01094     rb_enable_interrupt();
01095 }
01096 #endif
01097 
01098 void
01099 ruby_sig_finalize(void)
01100 {
01101     sighandler_t oldfunc;
01102 
01103     oldfunc = ruby_signal(SIGINT, SIG_IGN);
01104     if (oldfunc == sighandler) {
01105         ruby_signal(SIGINT, SIG_DFL);
01106     }
01107 }
01108 
01109 
01110 int ruby_enable_coredump = 0;
01111 #ifndef RUBY_DEBUG_ENV
01112 #define ruby_enable_coredump 0
01113 #endif
01114 
01115 /*
01116  * Many operating systems allow signals to be sent to running
01117  * processes. Some signals have a defined effect on the process, while
01118  * others may be trapped at the code level and acted upon. For
01119  * example, your process may trap the USR1 signal and use it to toggle
01120  * debugging, and may use TERM to initiate a controlled shutdown.
01121  *
01122  *     pid = fork do
01123  *       Signal.trap("USR1") do
01124  *         $debug = !$debug
01125  *         puts "Debug now: #$debug"
01126  *       end
01127  *       Signal.trap("TERM") do
01128  *         puts "Terminating..."
01129  *         shutdown()
01130  *       end
01131  *       # . . . do some work . . .
01132  *     end
01133  *
01134  *     Process.detach(pid)
01135  *
01136  *     # Controlling program:
01137  *     Process.kill("USR1", pid)
01138  *     # ...
01139  *     Process.kill("USR1", pid)
01140  *     # ...
01141  *     Process.kill("TERM", pid)
01142  *
01143  * produces:
01144  *     Debug now: true
01145  *     Debug now: false
01146  *    Terminating...
01147  *
01148  * The list of available signal names and their interpretation is
01149  * system dependent. Signal delivery semantics may also vary between
01150  * systems; in particular signal delivery may not always be reliable.
01151  */
01152 void
01153 Init_signal(void)
01154 {
01155     VALUE mSignal = rb_define_module("Signal");
01156 
01157     rb_define_global_function("trap", sig_trap, -1);
01158     rb_define_module_function(mSignal, "trap", sig_trap, -1);
01159     rb_define_module_function(mSignal, "list", sig_list, 0);
01160     rb_define_module_function(mSignal, "signame", sig_signame, 1);
01161 
01162     rb_define_method(rb_eSignal, "initialize", esignal_init, -1);
01163     rb_define_method(rb_eSignal, "signo", esignal_signo, 0);
01164     rb_alias(rb_eSignal, rb_intern("signm"), rb_intern("message"));
01165     rb_define_method(rb_eInterrupt, "initialize", interrupt_init, -1);
01166 
01167     install_sighandler(SIGINT, sighandler);
01168 #ifdef SIGHUP
01169     install_sighandler(SIGHUP, sighandler);
01170 #endif
01171 #ifdef SIGQUIT
01172     install_sighandler(SIGQUIT, sighandler);
01173 #endif
01174 #ifdef SIGTERM
01175     install_sighandler(SIGTERM, sighandler);
01176 #endif
01177 #ifdef SIGALRM
01178     install_sighandler(SIGALRM, sighandler);
01179 #endif
01180 #ifdef SIGUSR1
01181     install_sighandler(SIGUSR1, sighandler);
01182 #endif
01183 #ifdef SIGUSR2
01184     install_sighandler(SIGUSR2, sighandler);
01185 #endif
01186 
01187     if (!ruby_enable_coredump) {
01188 #ifdef SIGBUS
01189         install_sighandler(SIGBUS, (sighandler_t)sigbus);
01190 #endif
01191 #ifdef SIGSEGV
01192 # ifdef USE_SIGALTSTACK
01193         rb_register_sigaltstack(GET_THREAD());
01194 # endif
01195         install_sighandler(SIGSEGV, (sighandler_t)sigsegv);
01196 #endif
01197     }
01198 #ifdef SIGPIPE
01199     install_sighandler(SIGPIPE, SIG_IGN);
01200 #endif
01201 
01202 #if defined(SIGCLD)
01203     init_sigchld(SIGCLD);
01204 #elif defined(SIGCHLD)
01205     init_sigchld(SIGCHLD);
01206 #endif
01207 }
01208