Ruby  2.0.0p247(2013-06-27revision41674)
signal.c
Go to the documentation of this file.
00001 /**********************************************************************
00002 
00003   signal.c -
00004 
00005   $Author: nagachika $
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     return old.sa_handler;
00525 }
00526 
00527 sighandler_t
00528 posix_signal(int signum, sighandler_t handler)
00529 {
00530     return ruby_signal(signum, handler);
00531 }
00532 
00533 #else /* !POSIX_SIGNAL */
00534 #define ruby_signal(sig,handler) (/* rb_trap_accept_nativethreads[(sig)] = 0,*/ signal((sig),(handler)))
00535 #if 0 /* def HAVE_NATIVETHREAD */
00536 static sighandler_t
00537 ruby_nativethread_signal(int signum, sighandler_t handler)
00538 {
00539     sighandler_t old;
00540 
00541     old = signal(signum, handler);
00542     rb_trap_accept_nativethreads[signum] = 1;
00543     return old;
00544 }
00545 #endif
00546 #endif
00547 
00548 static RETSIGTYPE
00549 sighandler(int sig)
00550 {
00551     ATOMIC_INC(signal_buff.cnt[sig]);
00552     ATOMIC_INC(signal_buff.size);
00553     rb_thread_wakeup_timer_thread();
00554 #if !defined(BSD_SIGNAL) && !defined(POSIX_SIGNAL)
00555     ruby_signal(sig, sighandler);
00556 #endif
00557 }
00558 
00559 int
00560 rb_signal_buff_size(void)
00561 {
00562     return signal_buff.size;
00563 }
00564 
00565 #if HAVE_PTHREAD_H
00566 #include <pthread.h>
00567 #endif
00568 
00569 static void
00570 rb_disable_interrupt(void)
00571 {
00572 #ifdef HAVE_PTHREAD_SIGMASK
00573     sigset_t mask;
00574     sigfillset(&mask);
00575     pthread_sigmask(SIG_SETMASK, &mask, NULL);
00576 #endif
00577 }
00578 
00579 static void
00580 rb_enable_interrupt(void)
00581 {
00582 #ifdef HAVE_PTHREAD_SIGMASK
00583     sigset_t mask;
00584     sigemptyset(&mask);
00585     pthread_sigmask(SIG_SETMASK, &mask, NULL);
00586 #endif
00587 }
00588 
00589 int
00590 rb_get_next_signal(void)
00591 {
00592     int i, sig = 0;
00593 
00594     if (signal_buff.size != 0) {
00595         for (i=1; i<RUBY_NSIG; i++) {
00596             if (signal_buff.cnt[i] > 0) {
00597                 ATOMIC_DEC(signal_buff.cnt[i]);
00598                 ATOMIC_DEC(signal_buff.size);
00599                 sig = i;
00600                 break;
00601             }
00602         }
00603     }
00604     return sig;
00605 }
00606 
00607 
00608 #ifdef USE_SIGALTSTACK
00609 static void
00610 check_stack_overflow(const void *addr)
00611 {
00612     int ruby_stack_overflowed_p(const rb_thread_t *, const void *);
00613     NORETURN(void ruby_thread_stack_overflow(rb_thread_t *th));
00614     rb_thread_t *th = GET_THREAD();
00615     if (ruby_stack_overflowed_p(th, addr)) {
00616         ruby_thread_stack_overflow(th);
00617     }
00618 }
00619 #define CHECK_STACK_OVERFLOW() check_stack_overflow(info->si_addr)
00620 #else
00621 #define CHECK_STACK_OVERFLOW() (void)0
00622 #endif
00623 
00624 #ifdef SIGBUS
00625 static RETSIGTYPE
00626 sigbus(int sig SIGINFO_ARG)
00627 {
00628 /*
00629  * Mac OS X makes KERN_PROTECTION_FAILURE when thread touch guard page.
00630  * and it's delivered as SIGBUS instaed of SIGSEGV to userland. It's crazy
00631  * wrong IMHO. but anyway we have to care it. Sigh.
00632  */
00633 #if defined __APPLE__
00634     CHECK_STACK_OVERFLOW();
00635 #endif
00636     rb_bug("Bus Error");
00637 }
00638 #endif
00639 
00640 #ifdef SIGSEGV
00641 static void ruby_abort(void)
00642 {
00643 #ifdef __sun
00644     /* Solaris's abort() is async signal unsafe. Of course, it is not
00645      *  POSIX compliant.
00646      */
00647     raise(SIGABRT);
00648 #else
00649     abort();
00650 #endif
00651 
00652 }
00653 
00654 static int segv_received = 0;
00655 extern int ruby_disable_gc_stress;
00656 
00657 static RETSIGTYPE
00658 sigsegv(int sig SIGINFO_ARG)
00659 {
00660     if (segv_received) {
00661         ssize_t RB_UNUSED_VAR(err);
00662         char msg[] = "SEGV received in SEGV handler\n";
00663 
00664         err = write(2, msg, sizeof(msg));
00665         ruby_abort();
00666     }
00667 
00668     CHECK_STACK_OVERFLOW();
00669 
00670     segv_received = 1;
00671     ruby_disable_gc_stress = 1;
00672     rb_bug("Segmentation fault");
00673 }
00674 #endif
00675 
00676 static void
00677 signal_exec(VALUE cmd, int safe, int sig)
00678 {
00679     rb_thread_t *cur_th = GET_THREAD();
00680     volatile unsigned long old_interrupt_mask = cur_th->interrupt_mask;
00681     int state;
00682 
00683     cur_th->interrupt_mask |= TRAP_INTERRUPT_MASK;
00684     TH_PUSH_TAG(cur_th);
00685     if ((state = EXEC_TAG()) == 0) {
00686         VALUE signum = INT2NUM(sig);
00687         rb_eval_cmd(cmd, rb_ary_new3(1, signum), safe);
00688     }
00689     TH_POP_TAG();
00690     cur_th = GET_THREAD();
00691     cur_th->interrupt_mask = old_interrupt_mask;
00692 
00693     if (state) {
00694         /* XXX: should be replaced with rb_threadptr_pending_interrupt_enque() */
00695         JUMP_TAG(state);
00696     }
00697 }
00698 
00699 void
00700 rb_trap_exit(void)
00701 {
00702     rb_vm_t *vm = GET_VM();
00703     VALUE trap_exit = vm->trap_list[0].cmd;
00704 
00705     if (trap_exit) {
00706         vm->trap_list[0].cmd = 0;
00707         signal_exec(trap_exit, vm->trap_list[0].safe, 0);
00708     }
00709 }
00710 
00711 void
00712 rb_signal_exec(rb_thread_t *th, int sig)
00713 {
00714     rb_vm_t *vm = GET_VM();
00715     VALUE cmd = vm->trap_list[sig].cmd;
00716     int safe = vm->trap_list[sig].safe;
00717 
00718     if (cmd == 0) {
00719         switch (sig) {
00720           case SIGINT:
00721             rb_interrupt();
00722             break;
00723 #ifdef SIGHUP
00724           case SIGHUP:
00725 #endif
00726 #ifdef SIGQUIT
00727           case SIGQUIT:
00728 #endif
00729 #ifdef SIGTERM
00730           case SIGTERM:
00731 #endif
00732 #ifdef SIGALRM
00733           case SIGALRM:
00734 #endif
00735 #ifdef SIGUSR1
00736           case SIGUSR1:
00737 #endif
00738 #ifdef SIGUSR2
00739           case SIGUSR2:
00740 #endif
00741             rb_threadptr_signal_raise(th, sig);
00742             break;
00743         }
00744     }
00745     else if (cmd == Qundef) {
00746         rb_threadptr_signal_exit(th);
00747     }
00748     else {
00749         signal_exec(cmd, safe, sig);
00750     }
00751 }
00752 
00753 static sighandler_t
00754 default_handler(int sig)
00755 {
00756     sighandler_t func;
00757     switch (sig) {
00758       case SIGINT:
00759 #ifdef SIGHUP
00760       case SIGHUP:
00761 #endif
00762 #ifdef SIGQUIT
00763       case SIGQUIT:
00764 #endif
00765 #ifdef SIGTERM
00766       case SIGTERM:
00767 #endif
00768 #ifdef SIGALRM
00769       case SIGALRM:
00770 #endif
00771 #ifdef SIGUSR1
00772       case SIGUSR1:
00773 #endif
00774 #ifdef SIGUSR2
00775       case SIGUSR2:
00776 #endif
00777         func = sighandler;
00778         break;
00779 #ifdef SIGBUS
00780       case SIGBUS:
00781         func = (sighandler_t)sigbus;
00782         break;
00783 #endif
00784 #ifdef SIGSEGV
00785       case SIGSEGV:
00786         func = (sighandler_t)sigsegv;
00787         break;
00788 #endif
00789 #ifdef SIGPIPE
00790       case SIGPIPE:
00791         func = SIG_IGN;
00792         break;
00793 #endif
00794       default:
00795         func = SIG_DFL;
00796         break;
00797     }
00798 
00799     return func;
00800 }
00801 
00802 static sighandler_t
00803 trap_handler(VALUE *cmd, int sig)
00804 {
00805     sighandler_t func = sighandler;
00806     VALUE command;
00807 
00808     if (NIL_P(*cmd)) {
00809         func = SIG_IGN;
00810     }
00811     else {
00812         command = rb_check_string_type(*cmd);
00813         if (NIL_P(command) && SYMBOL_P(*cmd)) {
00814             command = rb_id2str(SYM2ID(*cmd));
00815             if (!command) rb_raise(rb_eArgError, "bad handler");
00816         }
00817         if (!NIL_P(command)) {
00818             SafeStringValue(command);   /* taint check */
00819             *cmd = command;
00820             switch (RSTRING_LEN(command)) {
00821               case 0:
00822                 goto sig_ign;
00823                 break;
00824               case 14:
00825                 if (strncmp(RSTRING_PTR(command), "SYSTEM_DEFAULT", 14) == 0) {
00826                     func = SIG_DFL;
00827                     *cmd = 0;
00828                 }
00829                 break;
00830               case 7:
00831                 if (strncmp(RSTRING_PTR(command), "SIG_IGN", 7) == 0) {
00832 sig_ign:
00833                     func = SIG_IGN;
00834                     *cmd = 0;
00835                 }
00836                 else if (strncmp(RSTRING_PTR(command), "SIG_DFL", 7) == 0) {
00837 sig_dfl:
00838                     func = default_handler(sig);
00839                     *cmd = 0;
00840                 }
00841                 else if (strncmp(RSTRING_PTR(command), "DEFAULT", 7) == 0) {
00842                     goto sig_dfl;
00843                 }
00844                 break;
00845               case 6:
00846                 if (strncmp(RSTRING_PTR(command), "IGNORE", 6) == 0) {
00847                     goto sig_ign;
00848                 }
00849                 break;
00850               case 4:
00851                 if (strncmp(RSTRING_PTR(command), "EXIT", 4) == 0) {
00852                     *cmd = Qundef;
00853                 }
00854                 break;
00855             }
00856         }
00857         else {
00858             rb_proc_t *proc;
00859             GetProcPtr(*cmd, proc);
00860             (void)proc;
00861         }
00862     }
00863 
00864     return func;
00865 }
00866 
00867 static int
00868 trap_signm(VALUE vsig)
00869 {
00870     int sig = -1;
00871     const char *s;
00872 
00873     switch (TYPE(vsig)) {
00874       case T_FIXNUM:
00875         sig = FIX2INT(vsig);
00876         if (sig < 0 || sig >= NSIG) {
00877             rb_raise(rb_eArgError, "invalid signal number (%d)", sig);
00878         }
00879         break;
00880 
00881       case T_SYMBOL:
00882         s = rb_id2name(SYM2ID(vsig));
00883         if (!s) rb_raise(rb_eArgError, "bad signal");
00884         goto str_signal;
00885 
00886       default:
00887         s = StringValuePtr(vsig);
00888 
00889       str_signal:
00890         if (strncmp("SIG", s, 3) == 0)
00891             s += 3;
00892         sig = signm2signo(s);
00893         if (sig == 0 && strcmp(s, "EXIT") != 0)
00894             rb_raise(rb_eArgError, "unsupported signal SIG%s", s);
00895     }
00896     return sig;
00897 }
00898 
00899 static VALUE
00900 trap(int sig, sighandler_t func, VALUE command)
00901 {
00902     sighandler_t oldfunc;
00903     VALUE oldcmd;
00904     rb_vm_t *vm = GET_VM();
00905 
00906     /*
00907      * Be careful. ruby_signal() and trap_list[sig].cmd must be changed
00908      * atomically. In current implementation, we only need to don't call
00909      * RUBY_VM_CHECK_INTS().
00910      */
00911     oldfunc = ruby_signal(sig, func);
00912     oldcmd = vm->trap_list[sig].cmd;
00913     switch (oldcmd) {
00914       case 0:
00915         if (oldfunc == SIG_IGN) oldcmd = rb_str_new2("IGNORE");
00916         else if (oldfunc == sighandler) oldcmd = rb_str_new2("DEFAULT");
00917         else oldcmd = Qnil;
00918         break;
00919       case Qundef:
00920         oldcmd = rb_str_new2("EXIT");
00921         break;
00922     }
00923 
00924     vm->trap_list[sig].cmd = command;
00925     vm->trap_list[sig].safe = rb_safe_level();
00926 
00927     return oldcmd;
00928 }
00929 
00930 static int
00931 reserved_signal_p(int signo)
00932 {
00933 /* Synchronous signal can't deliver to main thread */
00934 #ifdef SIGSEGV
00935     if (signo == SIGSEGV)
00936         return 1;
00937 #endif
00938 #ifdef SIGBUS
00939     if (signo == SIGBUS)
00940         return 1;
00941 #endif
00942 #ifdef SIGILL
00943     if (signo == SIGILL)
00944         return 1;
00945 #endif
00946 #ifdef SIGFPE
00947     if (signo == SIGFPE)
00948         return 1;
00949 #endif
00950 
00951 /* used ubf internal see thread_pthread.c. */
00952 #ifdef SIGVTALRM
00953     if (signo == SIGVTALRM)
00954         return 1;
00955 #endif
00956 
00957     return 0;
00958 }
00959 
00960 /*
00961  * call-seq:
00962  *   Signal.trap( signal, command ) -> obj
00963  *   Signal.trap( signal ) {| | block } -> obj
00964  *
00965  * Specifies the handling of signals. The first parameter is a signal
00966  * name (a string such as ``SIGALRM'', ``SIGUSR1'', and so on) or a
00967  * signal number. The characters ``SIG'' may be omitted from the
00968  * signal name. The command or block specifies code to be run when the
00969  * signal is raised.
00970  * If the command is the string ``IGNORE'' or ``SIG_IGN'', the signal
00971  * will be ignored.
00972  * If the command is ``DEFAULT'' or ``SIG_DFL'', the Ruby's default handler
00973  * will be invoked.
00974  * If the command is ``EXIT'', the script will be terminated by the signal.
00975  * If the command is ``SYSTEM_DEFAULT'', the operating system's default
00976  * handler will be invoked.
00977  * Otherwise, the given command or block will be run.
00978  * The special signal name ``EXIT'' or signal number zero will be
00979  * invoked just prior to program termination.
00980  * trap returns the previous handler for the given signal.
00981  *
00982  *     Signal.trap(0, proc { puts "Terminating: #{$$}" })
00983  *     Signal.trap("CLD")  { puts "Child died" }
00984  *     fork && Process.wait
00985  *
00986  * produces:
00987  *     Terminating: 27461
00988  *     Child died
00989  *     Terminating: 27460
00990  */
00991 static VALUE
00992 sig_trap(int argc, VALUE *argv)
00993 {
00994     int sig;
00995     sighandler_t func;
00996     VALUE cmd;
00997 
00998     rb_secure(2);
00999     rb_check_arity(argc, 1, 2);
01000 
01001     sig = trap_signm(argv[0]);
01002     if (reserved_signal_p(sig)) {
01003         const char *name = signo2signm(sig);
01004         if (name)
01005             rb_raise(rb_eArgError, "can't trap reserved signal: SIG%s", name);
01006         else
01007             rb_raise(rb_eArgError, "can't trap reserved signal: %d", sig);
01008     }
01009 
01010     if (argc == 1) {
01011         cmd = rb_block_proc();
01012         func = sighandler;
01013     }
01014     else {
01015         cmd = argv[1];
01016         func = trap_handler(&cmd, sig);
01017     }
01018 
01019     if (OBJ_TAINTED(cmd)) {
01020         rb_raise(rb_eSecurityError, "Insecure: tainted signal trap");
01021     }
01022 
01023     return trap(sig, func, cmd);
01024 }
01025 
01026 /*
01027  * call-seq:
01028  *   Signal.list -> a_hash
01029  *
01030  * Returns a list of signal names mapped to the corresponding
01031  * underlying signal numbers.
01032  *
01033  *   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}
01034  */
01035 static VALUE
01036 sig_list(void)
01037 {
01038     VALUE h = rb_hash_new();
01039     const struct signals *sigs;
01040 
01041     for (sigs = siglist; sigs->signm; sigs++) {
01042         rb_hash_aset(h, rb_str_new2(sigs->signm), INT2FIX(sigs->signo));
01043     }
01044     return h;
01045 }
01046 
01047 static void
01048 install_sighandler(int signum, sighandler_t handler)
01049 {
01050     sighandler_t old;
01051 
01052     /* At this time, there is no subthread. Then sigmask guarantee atomics. */
01053     rb_disable_interrupt();
01054     old = ruby_signal(signum, handler);
01055     /* signal handler should be inherited during exec. */
01056     if (old != SIG_DFL) {
01057         ruby_signal(signum, old);
01058     }
01059     rb_enable_interrupt();
01060 }
01061 
01062 #if defined(SIGCLD) || defined(SIGCHLD)
01063 static void
01064 init_sigchld(int sig)
01065 {
01066     sighandler_t oldfunc;
01067 
01068     rb_disable_interrupt();
01069     oldfunc = ruby_signal(sig, SIG_DFL);
01070     if (oldfunc != SIG_DFL && oldfunc != SIG_IGN) {
01071         ruby_signal(sig, oldfunc);
01072     } else {
01073         GET_VM()->trap_list[sig].cmd = 0;
01074     }
01075     rb_enable_interrupt();
01076 }
01077 #endif
01078 
01079 void
01080 ruby_sig_finalize(void)
01081 {
01082     sighandler_t oldfunc;
01083 
01084     oldfunc = ruby_signal(SIGINT, SIG_IGN);
01085     if (oldfunc == sighandler) {
01086         ruby_signal(SIGINT, SIG_DFL);
01087     }
01088 }
01089 
01090 
01091 int ruby_enable_coredump = 0;
01092 #ifndef RUBY_DEBUG_ENV
01093 #define ruby_enable_coredump 0
01094 #endif
01095 
01096 /*
01097  * Many operating systems allow signals to be sent to running
01098  * processes. Some signals have a defined effect on the process, while
01099  * others may be trapped at the code level and acted upon. For
01100  * example, your process may trap the USR1 signal and use it to toggle
01101  * debugging, and may use TERM to initiate a controlled shutdown.
01102  *
01103  *     pid = fork do
01104  *       Signal.trap("USR1") do
01105  *         $debug = !$debug
01106  *         puts "Debug now: #$debug"
01107  *       end
01108  *       Signal.trap("TERM") do
01109  *         puts "Terminating..."
01110  *         shutdown()
01111  *       end
01112  *       # . . . do some work . . .
01113  *     end
01114  *
01115  *     Process.detach(pid)
01116  *
01117  *     # Controlling program:
01118  *     Process.kill("USR1", pid)
01119  *     # ...
01120  *     Process.kill("USR1", pid)
01121  *     # ...
01122  *     Process.kill("TERM", pid)
01123  *
01124  * produces:
01125  *     Debug now: true
01126  *     Debug now: false
01127  *    Terminating...
01128  *
01129  * The list of available signal names and their interpretation is
01130  * system dependent. Signal delivery semantics may also vary between
01131  * systems; in particular signal delivery may not always be reliable.
01132  */
01133 void
01134 Init_signal(void)
01135 {
01136     VALUE mSignal = rb_define_module("Signal");
01137 
01138     rb_define_global_function("trap", sig_trap, -1);
01139     rb_define_module_function(mSignal, "trap", sig_trap, -1);
01140     rb_define_module_function(mSignal, "list", sig_list, 0);
01141     rb_define_module_function(mSignal, "signame", sig_signame, 1);
01142 
01143     rb_define_method(rb_eSignal, "initialize", esignal_init, -1);
01144     rb_define_method(rb_eSignal, "signo", esignal_signo, 0);
01145     rb_alias(rb_eSignal, rb_intern("signm"), rb_intern("message"));
01146     rb_define_method(rb_eInterrupt, "initialize", interrupt_init, -1);
01147 
01148     install_sighandler(SIGINT, sighandler);
01149 #ifdef SIGHUP
01150     install_sighandler(SIGHUP, sighandler);
01151 #endif
01152 #ifdef SIGQUIT
01153     install_sighandler(SIGQUIT, sighandler);
01154 #endif
01155 #ifdef SIGTERM
01156     install_sighandler(SIGTERM, sighandler);
01157 #endif
01158 #ifdef SIGALRM
01159     install_sighandler(SIGALRM, sighandler);
01160 #endif
01161 #ifdef SIGUSR1
01162     install_sighandler(SIGUSR1, sighandler);
01163 #endif
01164 #ifdef SIGUSR2
01165     install_sighandler(SIGUSR2, sighandler);
01166 #endif
01167 
01168     if (!ruby_enable_coredump) {
01169 #ifdef SIGBUS
01170         install_sighandler(SIGBUS, (sighandler_t)sigbus);
01171 #endif
01172 #ifdef SIGSEGV
01173 # ifdef USE_SIGALTSTACK
01174         rb_register_sigaltstack(GET_THREAD());
01175 # endif
01176         install_sighandler(SIGSEGV, (sighandler_t)sigsegv);
01177 #endif
01178     }
01179 #ifdef SIGPIPE
01180     install_sighandler(SIGPIPE, SIG_IGN);
01181 #endif
01182 
01183 #if defined(SIGCLD)
01184     init_sigchld(SIGCLD);
01185 #elif defined(SIGCHLD)
01186     init_sigchld(SIGCHLD);
01187 #endif
01188 }
01189