Ruby  2.0.0p648(2015-12-16revision53162)
signal.c
Go to the documentation of this file.
1 /**********************************************************************
2 
3  signal.c -
4 
5  $Author: usa $
6  created at: Tue Dec 20 10:13:44 JST 1994
7 
8  Copyright (C) 1993-2007 Yukihiro Matsumoto
9  Copyright (C) 2000 Network Applied Communication Laboratory, Inc.
10  Copyright (C) 2000 Information-technology Promotion Agency, Japan
11 
12 **********************************************************************/
13 
14 #include "ruby/ruby.h"
15 #include "vm_core.h"
16 #include <signal.h>
17 #include <stdio.h>
18 #include <errno.h>
19 #include "ruby_atomic.h"
20 #include "eval_intern.h"
21 
22 #if defined(__native_client__) && defined(NACL_NEWLIB)
23 # include "nacl/signal.h"
24 #endif
25 
26 #ifdef NEED_RUBY_ATOMIC_OPS
29 {
30  rb_atomic_t old = *ptr;
31  *ptr = val;
32  return old;
33 }
34 
37  rb_atomic_t newval)
38 {
39  rb_atomic_t old = *ptr;
40  if (old == cmp) {
41  *ptr = newval;
42  }
43  return old;
44 }
45 #endif
46 
47 #if defined(__BEOS__) || defined(__HAIKU__)
48 #undef SIGBUS
49 #endif
50 
51 #ifndef NSIG
52 # define NSIG (_SIGMAX + 1) /* For QNX */
53 #endif
54 
55 static const struct signals {
56  const char *signm;
57  int signo;
58 } siglist [] = {
59  {"EXIT", 0},
60 #ifdef SIGHUP
61  {"HUP", SIGHUP},
62 #endif
63  {"INT", SIGINT},
64 #ifdef SIGQUIT
65  {"QUIT", SIGQUIT},
66 #endif
67 #ifdef SIGILL
68  {"ILL", SIGILL},
69 #endif
70 #ifdef SIGTRAP
71  {"TRAP", SIGTRAP},
72 #endif
73 #ifdef SIGIOT
74  {"IOT", SIGIOT},
75 #endif
76 #ifdef SIGABRT
77  {"ABRT", SIGABRT},
78 #endif
79 #ifdef SIGEMT
80  {"EMT", SIGEMT},
81 #endif
82 #ifdef SIGFPE
83  {"FPE", SIGFPE},
84 #endif
85 #ifdef SIGKILL
86  {"KILL", SIGKILL},
87 #endif
88 #ifdef SIGBUS
89  {"BUS", SIGBUS},
90 #endif
91 #ifdef SIGSEGV
92  {"SEGV", SIGSEGV},
93 #endif
94 #ifdef SIGSYS
95  {"SYS", SIGSYS},
96 #endif
97 #ifdef SIGPIPE
98  {"PIPE", SIGPIPE},
99 #endif
100 #ifdef SIGALRM
101  {"ALRM", SIGALRM},
102 #endif
103 #ifdef SIGTERM
104  {"TERM", SIGTERM},
105 #endif
106 #ifdef SIGURG
107  {"URG", SIGURG},
108 #endif
109 #ifdef SIGSTOP
110  {"STOP", SIGSTOP},
111 #endif
112 #ifdef SIGTSTP
113  {"TSTP", SIGTSTP},
114 #endif
115 #ifdef SIGCONT
116  {"CONT", SIGCONT},
117 #endif
118 #ifdef SIGCHLD
119  {"CHLD", SIGCHLD},
120 #endif
121 #ifdef SIGCLD
122  {"CLD", SIGCLD},
123 #else
124 # ifdef SIGCHLD
125  {"CLD", SIGCHLD},
126 # endif
127 #endif
128 #ifdef SIGTTIN
129  {"TTIN", SIGTTIN},
130 #endif
131 #ifdef SIGTTOU
132  {"TTOU", SIGTTOU},
133 #endif
134 #ifdef SIGIO
135  {"IO", SIGIO},
136 #endif
137 #ifdef SIGXCPU
138  {"XCPU", SIGXCPU},
139 #endif
140 #ifdef SIGXFSZ
141  {"XFSZ", SIGXFSZ},
142 #endif
143 #ifdef SIGVTALRM
144  {"VTALRM", SIGVTALRM},
145 #endif
146 #ifdef SIGPROF
147  {"PROF", SIGPROF},
148 #endif
149 #ifdef SIGWINCH
150  {"WINCH", SIGWINCH},
151 #endif
152 #ifdef SIGUSR1
153  {"USR1", SIGUSR1},
154 #endif
155 #ifdef SIGUSR2
156  {"USR2", SIGUSR2},
157 #endif
158 #ifdef SIGLOST
159  {"LOST", SIGLOST},
160 #endif
161 #ifdef SIGMSG
162  {"MSG", SIGMSG},
163 #endif
164 #ifdef SIGPWR
165  {"PWR", SIGPWR},
166 #endif
167 #ifdef SIGPOLL
168  {"POLL", SIGPOLL},
169 #endif
170 #ifdef SIGDANGER
171  {"DANGER", SIGDANGER},
172 #endif
173 #ifdef SIGMIGRATE
174  {"MIGRATE", SIGMIGRATE},
175 #endif
176 #ifdef SIGPRE
177  {"PRE", SIGPRE},
178 #endif
179 #ifdef SIGGRANT
180  {"GRANT", SIGGRANT},
181 #endif
182 #ifdef SIGRETRACT
183  {"RETRACT", SIGRETRACT},
184 #endif
185 #ifdef SIGSOUND
186  {"SOUND", SIGSOUND},
187 #endif
188 #ifdef SIGINFO
189  {"INFO", SIGINFO},
190 #endif
191  {NULL, 0}
192 };
193 
194 static int
195 signm2signo(const char *nm)
196 {
197  const struct signals *sigs;
198 
199  for (sigs = siglist; sigs->signm; sigs++)
200  if (strcmp(sigs->signm, nm) == 0)
201  return sigs->signo;
202  return 0;
203 }
204 
205 static const char*
206 signo2signm(int no)
207 {
208  const struct signals *sigs;
209 
210  for (sigs = siglist; sigs->signm; sigs++)
211  if (sigs->signo == no)
212  return sigs->signm;
213  return 0;
214 }
215 
216 /*
217  * call-seq:
218  * Signal.signame(signo) -> string
219  *
220  * convert signal number to signal name
221  *
222  * Signal.trap("INT") { |signo| puts Signal.signame(signo) }
223  * Process.kill("INT", 0)
224  *
225  * <em>produces:</em>
226  *
227  * INT
228  */
229 static VALUE
231 {
232  const char *signame = signo2signm(NUM2INT(signo));
233  return rb_str_new_cstr(signame);
234 }
235 
236 const char *
238 {
239  return signo2signm(no);
240 }
241 
242 /*
243  * call-seq:
244  * SignalException.new(sig_name) -> signal_exception
245  * SignalException.new(sig_number [, name]) -> signal_exception
246  *
247  * Construct a new SignalException object. +sig_name+ should be a known
248  * signal name.
249  */
250 
251 static VALUE
253 {
254  int argnum = 1;
255  VALUE sig = Qnil;
256  int signo;
257  const char *signm;
258 
259  if (argc > 0) {
260  sig = rb_check_to_integer(argv[0], "to_int");
261  if (!NIL_P(sig)) argnum = 2;
262  else sig = argv[0];
263  }
264  rb_check_arity(argc, 1, argnum);
265  if (argnum == 2) {
266  signo = NUM2INT(sig);
267  if (signo < 0 || signo > NSIG) {
268  rb_raise(rb_eArgError, "invalid signal number (%d)", signo);
269  }
270  if (argc > 1) {
271  sig = argv[1];
272  }
273  else {
274  signm = signo2signm(signo);
275  if (signm) {
276  sig = rb_sprintf("SIG%s", signm);
277  }
278  else {
279  sig = rb_sprintf("SIG%u", signo);
280  }
281  }
282  }
283  else {
284  signm = SYMBOL_P(sig) ? rb_id2name(SYM2ID(sig)) : StringValuePtr(sig);
285  if (strncmp(signm, "SIG", 3) == 0) signm += 3;
286  signo = signm2signo(signm);
287  if (!signo) {
288  rb_raise(rb_eArgError, "unsupported name `SIG%s'", signm);
289  }
290  sig = rb_sprintf("SIG%s", signm);
291  }
292  rb_call_super(1, &sig);
293  rb_iv_set(self, "signo", INT2NUM(signo));
294 
295  return self;
296 }
297 
298 /*
299  * call-seq:
300  * signal_exception.signo -> num
301  *
302  * Returns a signal number.
303  */
304 
305 static VALUE
307 {
308  return rb_iv_get(self, "signo");
309 }
310 
311 /* :nodoc: */
312 static VALUE
314 {
315  VALUE args[2];
316 
317  args[0] = INT2FIX(SIGINT);
318  rb_scan_args(argc, argv, "01", &args[1]);
319  return rb_call_super(2, args);
320 }
321 
322 void
324 {
325  signal(sig, SIG_DFL);
326  raise(sig);
327 }
328 
329 /*
330  * call-seq:
331  * Process.kill(signal, pid, ...) -> fixnum
332  *
333  * Sends the given signal to the specified process id(s) if _pid_ is positive.
334  * If _pid_ is zero _signal_ is sent to all processes whose group ID is equal
335  * to the group ID of the process. _signal_ may be an integer signal number or
336  * a POSIX signal name (either with or without a +SIG+ prefix). If _signal_ is
337  * negative (or starts with a minus sign), kills process groups instead of
338  * processes. Not all signals are available on all platforms.
339  *
340  * pid = fork do
341  * Signal.trap("HUP") { puts "Ouch!"; exit }
342  * # ... do some work ...
343  * end
344  * # ...
345  * Process.kill("HUP", pid)
346  * Process.wait
347  *
348  * <em>produces:</em>
349  *
350  * Ouch!
351  *
352  * If _signal_ is an integer but wrong for signal,
353  * <code>Errno::EINVAL</code> or +RangeError+ will be raised.
354  * Otherwise unless _signal_ is a +String+ or a +Symbol+, and a known
355  * signal name, +ArgumentError+ will be raised.
356  *
357  * Also, <code>Errno::ESRCH</code> or +RangeError+ for invalid _pid_,
358  * <code>Errno::EPERM</code> when failed because of no privilege,
359  * will be raised. In these cases, signals may have been sent to
360  * preceding processes.
361  */
362 
363 VALUE
365 {
366 #ifndef HAVE_KILLPG
367 #define killpg(pg, sig) kill(-(pg), (sig))
368 #endif
369  int negative = 0;
370  int sig;
371  int i;
372  volatile VALUE str;
373  const char *s;
374 
375  rb_secure(2);
377 
378  switch (TYPE(argv[0])) {
379  case T_FIXNUM:
380  sig = FIX2INT(argv[0]);
381  break;
382 
383  case T_SYMBOL:
384  s = rb_id2name(SYM2ID(argv[0]));
385  if (!s) rb_raise(rb_eArgError, "bad signal");
386  goto str_signal;
387 
388  case T_STRING:
389  s = RSTRING_PTR(argv[0]);
390  str_signal:
391  if (s[0] == '-') {
392  negative++;
393  s++;
394  }
395  if (strncmp("SIG", s, 3) == 0)
396  s += 3;
397  if ((sig = signm2signo(s)) == 0)
398  rb_raise(rb_eArgError, "unsupported name `SIG%s'", s);
399 
400  if (negative)
401  sig = -sig;
402  break;
403 
404  default:
405  str = rb_check_string_type(argv[0]);
406  if (!NIL_P(str)) {
407  s = RSTRING_PTR(str);
408  goto str_signal;
409  }
410  rb_raise(rb_eArgError, "bad signal type %s",
411  rb_obj_classname(argv[0]));
412  break;
413  }
414 
415  if (sig < 0) {
416  sig = -sig;
417  for (i=1; i<argc; i++) {
418  if (killpg(NUM2PIDT(argv[i]), sig) < 0)
419  rb_sys_fail(0);
420  }
421  }
422  else {
423  for (i=1; i<argc; i++) {
424  if (kill(NUM2PIDT(argv[i]), sig) < 0)
425  rb_sys_fail(0);
426  }
427  }
428  return INT2FIX(i-1);
429 }
430 
431 static struct {
434 } signal_buff;
435 
436 #ifdef __dietlibc__
437 #define sighandler_t sh_t
438 #endif
439 
440 typedef RETSIGTYPE (*sighandler_t)(int);
441 #ifdef USE_SIGALTSTACK
442 typedef void ruby_sigaction_t(int, siginfo_t*, void*);
443 #define SIGINFO_ARG , siginfo_t *info, void *ctx
444 #else
445 typedef RETSIGTYPE ruby_sigaction_t(int);
446 #define SIGINFO_ARG
447 #endif
448 
449 #ifdef USE_SIGALTSTACK
450 int rb_sigaltstack_size(void)
451 {
452  /* XXX: BSD_vfprintf() uses >1500KiB stack and x86-64 need >5KiB stack. */
453  int size = 8192;
454 
455 #ifdef MINSIGSTKSZ
456  if (size < MINSIGSTKSZ)
457  size = MINSIGSTKSZ;
458 #endif
459 #if defined(HAVE_SYSCONF) && defined(_SC_PAGE_SIZE)
460  {
461  int pagesize;
462  pagesize = (int)sysconf(_SC_PAGE_SIZE);
463  if (size < pagesize)
464  size = pagesize;
465  }
466 #endif
467 
468  return size;
469 }
470 
471 /* alternate stack for SIGSEGV */
472 void
473 rb_register_sigaltstack(rb_thread_t *th)
474 {
475  stack_t newSS, oldSS;
476 
477  if (!th->altstack)
478  rb_bug("rb_register_sigaltstack: th->altstack not initialized\n");
479 
480  newSS.ss_sp = th->altstack;
481  newSS.ss_size = rb_sigaltstack_size();
482  newSS.ss_flags = 0;
483 
484  sigaltstack(&newSS, &oldSS); /* ignore error. */
485 }
486 #endif /* USE_SIGALTSTACK */
487 
488 #ifdef POSIX_SIGNAL
489 static sighandler_t
490 ruby_signal(int signum, sighandler_t handler)
491 {
492  struct sigaction sigact, old;
493 
494 #if 0
495  rb_trap_accept_nativethreads[signum] = 0;
496 #endif
497 
498  sigemptyset(&sigact.sa_mask);
499 #ifdef USE_SIGALTSTACK
500  sigact.sa_sigaction = (ruby_sigaction_t*)handler;
501  sigact.sa_flags = SA_SIGINFO;
502 #else
503  sigact.sa_handler = handler;
504  sigact.sa_flags = 0;
505 #endif
506 
507 #ifdef SA_NOCLDWAIT
508  if (signum == SIGCHLD && handler == SIG_IGN)
509  sigact.sa_flags |= SA_NOCLDWAIT;
510 #endif
511 #if defined(SA_ONSTACK) && defined(USE_SIGALTSTACK)
512  if (signum == SIGSEGV
513 #ifdef SIGBUS
514  || signum == SIGBUS
515 #endif
516  )
517  sigact.sa_flags |= SA_ONSTACK;
518 #endif
519  if (sigaction(signum, &sigact, &old) < 0) {
520  if (errno != 0 && errno != EINVAL) {
521  rb_bug_errno("sigaction", errno);
522  }
523  }
524  if (old.sa_flags & SA_SIGINFO)
525  return (sighandler_t)old.sa_sigaction;
526  else
527  return old.sa_handler;
528 }
529 
531 posix_signal(int signum, sighandler_t handler)
532 {
533  return ruby_signal(signum, handler);
534 }
535 
536 #elif defined _WIN32
537 static inline sighandler_t
538 ruby_signal(int signum, sighandler_t handler)
539 {
540  if (signum == SIGKILL) {
541  errno = EINVAL;
542  return SIG_ERR;
543  }
544  return signal(signum, handler);
545 }
546 
547 #else /* !POSIX_SIGNAL */
548 #define ruby_signal(sig,handler) (/* rb_trap_accept_nativethreads[(sig)] = 0,*/ signal((sig),(handler)))
549 #if 0 /* def HAVE_NATIVETHREAD */
550 static sighandler_t
551 ruby_nativethread_signal(int signum, sighandler_t handler)
552 {
553  sighandler_t old;
554 
555  old = signal(signum, handler);
556  rb_trap_accept_nativethreads[signum] = 1;
557  return old;
558 }
559 #endif
560 #endif
561 
562 static RETSIGTYPE
563 sighandler(int sig)
564 {
565  ATOMIC_INC(signal_buff.cnt[sig]);
566  ATOMIC_INC(signal_buff.size);
568 #if !defined(BSD_SIGNAL) && !defined(POSIX_SIGNAL)
569  ruby_signal(sig, sighandler);
570 #endif
571 }
572 
573 int
575 {
576  return signal_buff.size;
577 }
578 
579 #if HAVE_PTHREAD_H
580 #include <pthread.h>
581 #endif
582 
583 static void
585 {
586 #ifdef HAVE_PTHREAD_SIGMASK
587  sigset_t mask;
588  sigfillset(&mask);
589  pthread_sigmask(SIG_SETMASK, &mask, NULL);
590 #endif
591 }
592 
593 static void
595 {
596 #ifdef HAVE_PTHREAD_SIGMASK
597  sigset_t mask;
598  sigemptyset(&mask);
599  pthread_sigmask(SIG_SETMASK, &mask, NULL);
600 #endif
601 }
602 
603 int
605 {
606  int i, sig = 0;
607 
608  if (signal_buff.size != 0) {
609  for (i=1; i<RUBY_NSIG; i++) {
610  if (signal_buff.cnt[i] > 0) {
611  ATOMIC_DEC(signal_buff.cnt[i]);
612  ATOMIC_DEC(signal_buff.size);
613  sig = i;
614  break;
615  }
616  }
617  }
618  return sig;
619 }
620 
621 
622 #if defined(USE_SIGALTSTACK) || defined(_WIN32)
623 static void
624 check_stack_overflow(const void *addr)
625 {
626  int ruby_stack_overflowed_p(const rb_thread_t *, const void *);
629  if (ruby_stack_overflowed_p(th, addr)) {
631  }
632 }
633 #ifdef _WIN32
634 #define CHECK_STACK_OVERFLOW() check_stack_overflow(0)
635 #else
636 #define CHECK_STACK_OVERFLOW() check_stack_overflow(info->si_addr)
637 #endif
638 #else
639 #define CHECK_STACK_OVERFLOW() (void)0
640 #endif
641 
642 #ifdef SIGBUS
643 static RETSIGTYPE
644 sigbus(int sig SIGINFO_ARG)
645 {
646 /*
647  * Mac OS X makes KERN_PROTECTION_FAILURE when thread touch guard page.
648  * and it's delivered as SIGBUS instaed of SIGSEGV to userland. It's crazy
649  * wrong IMHO. but anyway we have to care it. Sigh.
650  */
651  /* Seems Linux also delivers SIGBUS. */
652 #if defined __APPLE__ || defined __linux__
654 #endif
655  rb_bug("Bus Error");
656 }
657 #endif
658 
659 #ifdef SIGSEGV
660 static void ruby_abort(void)
661 {
662 #ifdef __sun
663  /* Solaris's abort() is async signal unsafe. Of course, it is not
664  * POSIX compliant.
665  */
666  raise(SIGABRT);
667 #else
668  abort();
669 #endif
670 
671 }
672 
673 static int segv_received = 0;
674 extern int ruby_disable_gc_stress;
675 
676 static RETSIGTYPE
677 sigsegv(int sig SIGINFO_ARG)
678 {
679  if (segv_received) {
680  ssize_t RB_UNUSED_VAR(err);
681  char msg[] = "SEGV received in SEGV handler\n";
682 
683  err = write(2, msg, sizeof(msg));
684  ruby_abort();
685  }
686 
688 
689  segv_received = 1;
690  ruby_disable_gc_stress = 1;
691  rb_bug("Segmentation fault");
692 }
693 #endif
694 
695 static void
696 signal_exec(VALUE cmd, int safe, int sig)
697 {
698  rb_thread_t *cur_th = GET_THREAD();
699  volatile unsigned long old_interrupt_mask = cur_th->interrupt_mask;
700  int state;
701 
702  /*
703  * workaround the following race:
704  * 1. signal_enque queues signal for execution
705  * 2. user calls trap(sig, "IGNORE"), setting SIG_IGN
706  * 3. rb_signal_exec runs on queued signal
707  */
708  if (IMMEDIATE_P(cmd))
709  return;
710 
712  TH_PUSH_TAG(cur_th);
713  if ((state = EXEC_TAG()) == 0) {
714  VALUE signum = INT2NUM(sig);
715  rb_eval_cmd(cmd, rb_ary_new3(1, signum), safe);
716  }
717  TH_POP_TAG();
718  cur_th = GET_THREAD();
719  cur_th->interrupt_mask = old_interrupt_mask;
720 
721  if (state) {
722  /* XXX: should be replaced with rb_threadptr_pending_interrupt_enque() */
723  JUMP_TAG(state);
724  }
725 }
726 
727 void
729 {
730  rb_vm_t *vm = GET_VM();
731  VALUE trap_exit = vm->trap_list[0].cmd;
732 
733  if (trap_exit) {
734  vm->trap_list[0].cmd = 0;
735  signal_exec(trap_exit, vm->trap_list[0].safe, 0);
736  }
737 }
738 
739 void
741 {
742  rb_vm_t *vm = GET_VM();
743  VALUE cmd = vm->trap_list[sig].cmd;
744  int safe = vm->trap_list[sig].safe;
745 
746  if (cmd == 0) {
747  switch (sig) {
748  case SIGINT:
749  rb_interrupt();
750  break;
751 #ifdef SIGHUP
752  case SIGHUP:
753 #endif
754 #ifdef SIGQUIT
755  case SIGQUIT:
756 #endif
757 #ifdef SIGTERM
758  case SIGTERM:
759 #endif
760 #ifdef SIGALRM
761  case SIGALRM:
762 #endif
763 #ifdef SIGUSR1
764  case SIGUSR1:
765 #endif
766 #ifdef SIGUSR2
767  case SIGUSR2:
768 #endif
769  rb_threadptr_signal_raise(th, sig);
770  break;
771  }
772  }
773  else if (cmd == Qundef) {
775  }
776  else {
777  signal_exec(cmd, safe, sig);
778  }
779 }
780 
781 static sighandler_t
783 {
785  switch (sig) {
786  case SIGINT:
787 #ifdef SIGHUP
788  case SIGHUP:
789 #endif
790 #ifdef SIGQUIT
791  case SIGQUIT:
792 #endif
793 #ifdef SIGTERM
794  case SIGTERM:
795 #endif
796 #ifdef SIGALRM
797  case SIGALRM:
798 #endif
799 #ifdef SIGUSR1
800  case SIGUSR1:
801 #endif
802 #ifdef SIGUSR2
803  case SIGUSR2:
804 #endif
805  func = sighandler;
806  break;
807 #ifdef SIGBUS
808  case SIGBUS:
809  func = (sighandler_t)sigbus;
810  break;
811 #endif
812 #ifdef SIGSEGV
813  case SIGSEGV:
814  func = (sighandler_t)sigsegv;
815  break;
816 #endif
817 #ifdef SIGPIPE
818  case SIGPIPE:
819  func = SIG_IGN;
820  break;
821 #endif
822  default:
823  func = SIG_DFL;
824  break;
825  }
826 
827  return func;
828 }
829 
830 static sighandler_t
831 trap_handler(VALUE *cmd, int sig)
832 {
834  VALUE command;
835 
836  if (NIL_P(*cmd)) {
837  func = SIG_IGN;
838  }
839  else {
840  command = rb_check_string_type(*cmd);
841  if (NIL_P(command) && SYMBOL_P(*cmd)) {
842  command = rb_id2str(SYM2ID(*cmd));
843  if (!command) rb_raise(rb_eArgError, "bad handler");
844  }
845  if (!NIL_P(command)) {
846  SafeStringValue(command); /* taint check */
847  *cmd = command;
848  switch (RSTRING_LEN(command)) {
849  case 0:
850  goto sig_ign;
851  break;
852  case 14:
853  if (strncmp(RSTRING_PTR(command), "SYSTEM_DEFAULT", 14) == 0) {
854  func = SIG_DFL;
855  *cmd = 0;
856  }
857  break;
858  case 7:
859  if (strncmp(RSTRING_PTR(command), "SIG_IGN", 7) == 0) {
860 sig_ign:
861  func = SIG_IGN;
862  *cmd = Qtrue;
863  }
864  else if (strncmp(RSTRING_PTR(command), "SIG_DFL", 7) == 0) {
865 sig_dfl:
866  func = default_handler(sig);
867  *cmd = 0;
868  }
869  else if (strncmp(RSTRING_PTR(command), "DEFAULT", 7) == 0) {
870  goto sig_dfl;
871  }
872  break;
873  case 6:
874  if (strncmp(RSTRING_PTR(command), "IGNORE", 6) == 0) {
875  goto sig_ign;
876  }
877  break;
878  case 4:
879  if (strncmp(RSTRING_PTR(command), "EXIT", 4) == 0) {
880  *cmd = Qundef;
881  }
882  break;
883  }
884  }
885  else {
886  rb_proc_t *proc;
887  GetProcPtr(*cmd, proc);
888  (void)proc;
889  }
890  }
891 
892  return func;
893 }
894 
895 static int
897 {
898  int sig = -1;
899  const char *s;
900 
901  switch (TYPE(vsig)) {
902  case T_FIXNUM:
903  sig = FIX2INT(vsig);
904  if (sig < 0 || sig >= NSIG) {
905  rb_raise(rb_eArgError, "invalid signal number (%d)", sig);
906  }
907  break;
908 
909  case T_SYMBOL:
910  s = rb_id2name(SYM2ID(vsig));
911  if (!s) rb_raise(rb_eArgError, "bad signal");
912  goto str_signal;
913 
914  default:
915  s = StringValuePtr(vsig);
916 
917  str_signal:
918  if (strncmp("SIG", s, 3) == 0)
919  s += 3;
920  sig = signm2signo(s);
921  if (sig == 0 && strcmp(s, "EXIT") != 0)
922  rb_raise(rb_eArgError, "unsupported signal SIG%s", s);
923  }
924  return sig;
925 }
926 
927 static VALUE
928 trap(int sig, sighandler_t func, VALUE command)
929 {
930  sighandler_t oldfunc;
931  VALUE oldcmd;
932  rb_vm_t *vm = GET_VM();
933 
934  /*
935  * Be careful. ruby_signal() and trap_list[sig].cmd must be changed
936  * atomically. In current implementation, we only need to don't call
937  * RUBY_VM_CHECK_INTS().
938  */
939  oldfunc = ruby_signal(sig, func);
940  oldcmd = vm->trap_list[sig].cmd;
941  switch (oldcmd) {
942  case 0:
943  case Qtrue:
944  if (oldfunc == SIG_IGN) oldcmd = rb_str_new2("IGNORE");
945  else if (oldfunc == sighandler) oldcmd = rb_str_new2("DEFAULT");
946  else oldcmd = Qnil;
947  break;
948  case Qnil:
949  break;
950  case Qundef:
951  oldcmd = rb_str_new2("EXIT");
952  break;
953  }
954 
955  vm->trap_list[sig].cmd = command;
956  vm->trap_list[sig].safe = rb_safe_level();
957 
958  return oldcmd;
959 }
960 
961 static int
963 {
964 /* Synchronous signal can't deliver to main thread */
965 #ifdef SIGSEGV
966  if (signo == SIGSEGV)
967  return 1;
968 #endif
969 #ifdef SIGBUS
970  if (signo == SIGBUS)
971  return 1;
972 #endif
973 #ifdef SIGILL
974  if (signo == SIGILL)
975  return 1;
976 #endif
977 #ifdef SIGFPE
978  if (signo == SIGFPE)
979  return 1;
980 #endif
981 
982 /* used ubf internal see thread_pthread.c. */
983 #ifdef SIGVTALRM
984  if (signo == SIGVTALRM)
985  return 1;
986 #endif
987 
988  return 0;
989 }
990 
991 /*
992  * call-seq:
993  * Signal.trap( signal, command ) -> obj
994  * Signal.trap( signal ) {| | block } -> obj
995  *
996  * Specifies the handling of signals. The first parameter is a signal
997  * name (a string such as ``SIGALRM'', ``SIGUSR1'', and so on) or a
998  * signal number. The characters ``SIG'' may be omitted from the
999  * signal name. The command or block specifies code to be run when the
1000  * signal is raised.
1001  * If the command is the string ``IGNORE'' or ``SIG_IGN'', the signal
1002  * will be ignored.
1003  * If the command is ``DEFAULT'' or ``SIG_DFL'', the Ruby's default handler
1004  * will be invoked.
1005  * If the command is ``EXIT'', the script will be terminated by the signal.
1006  * If the command is ``SYSTEM_DEFAULT'', the operating system's default
1007  * handler will be invoked.
1008  * Otherwise, the given command or block will be run.
1009  * The special signal name ``EXIT'' or signal number zero will be
1010  * invoked just prior to program termination.
1011  * trap returns the previous handler for the given signal.
1012  *
1013  * Signal.trap(0, proc { puts "Terminating: #{$$}" })
1014  * Signal.trap("CLD") { puts "Child died" }
1015  * fork && Process.wait
1016  *
1017  * produces:
1018  * Terminating: 27461
1019  * Child died
1020  * Terminating: 27460
1021  */
1022 static VALUE
1024 {
1025  int sig;
1027  VALUE cmd;
1028 
1029  rb_secure(2);
1030  rb_check_arity(argc, 1, 2);
1031 
1032  sig = trap_signm(argv[0]);
1033  if (reserved_signal_p(sig)) {
1034  const char *name = signo2signm(sig);
1035  if (name)
1036  rb_raise(rb_eArgError, "can't trap reserved signal: SIG%s", name);
1037  else
1038  rb_raise(rb_eArgError, "can't trap reserved signal: %d", sig);
1039  }
1040 
1041  if (argc == 1) {
1042  cmd = rb_block_proc();
1043  func = sighandler;
1044  }
1045  else {
1046  cmd = argv[1];
1047  func = trap_handler(&cmd, sig);
1048  }
1049 
1050  if (OBJ_TAINTED(cmd)) {
1051  rb_raise(rb_eSecurityError, "Insecure: tainted signal trap");
1052  }
1053 
1054  return trap(sig, func, cmd);
1055 }
1056 
1057 /*
1058  * call-seq:
1059  * Signal.list -> a_hash
1060  *
1061  * Returns a list of signal names mapped to the corresponding
1062  * underlying signal numbers.
1063  *
1064  * 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}
1065  */
1066 static VALUE
1068 {
1069  VALUE h = rb_hash_new();
1070  const struct signals *sigs;
1071 
1072  for (sigs = siglist; sigs->signm; sigs++) {
1073  rb_hash_aset(h, rb_str_new2(sigs->signm), INT2FIX(sigs->signo));
1074  }
1075  return h;
1076 }
1077 
1078 static void
1079 install_sighandler(int signum, sighandler_t handler)
1080 {
1081  sighandler_t old;
1082 
1083  /* At this time, there is no subthread. Then sigmask guarantee atomics. */
1085  old = ruby_signal(signum, handler);
1086  /* signal handler should be inherited during exec. */
1087  if (old != SIG_DFL) {
1088  ruby_signal(signum, old);
1089  }
1091 }
1092 
1093 #if defined(SIGCLD) || defined(SIGCHLD)
1094 static void
1095 init_sigchld(int sig)
1096 {
1097  sighandler_t oldfunc;
1098 
1100  oldfunc = ruby_signal(sig, SIG_DFL);
1101  if (oldfunc != SIG_DFL && oldfunc != SIG_IGN) {
1102  ruby_signal(sig, oldfunc);
1103  } else {
1104  GET_VM()->trap_list[sig].cmd = 0;
1105  }
1107 }
1108 #endif
1109 
1110 void
1112 {
1113  sighandler_t oldfunc;
1114 
1115  oldfunc = ruby_signal(SIGINT, SIG_IGN);
1116  if (oldfunc == sighandler) {
1117  ruby_signal(SIGINT, SIG_DFL);
1118  }
1119 }
1120 
1121 
1123 #ifndef RUBY_DEBUG_ENV
1124 #define ruby_enable_coredump 0
1125 #endif
1126 
1127 /*
1128  * Many operating systems allow signals to be sent to running
1129  * processes. Some signals have a defined effect on the process, while
1130  * others may be trapped at the code level and acted upon. For
1131  * example, your process may trap the USR1 signal and use it to toggle
1132  * debugging, and may use TERM to initiate a controlled shutdown.
1133  *
1134  * pid = fork do
1135  * Signal.trap("USR1") do
1136  * $debug = !$debug
1137  * puts "Debug now: #$debug"
1138  * end
1139  * Signal.trap("TERM") do
1140  * puts "Terminating..."
1141  * shutdown()
1142  * end
1143  * # . . . do some work . . .
1144  * end
1145  *
1146  * Process.detach(pid)
1147  *
1148  * # Controlling program:
1149  * Process.kill("USR1", pid)
1150  * # ...
1151  * Process.kill("USR1", pid)
1152  * # ...
1153  * Process.kill("TERM", pid)
1154  *
1155  * produces:
1156  * Debug now: true
1157  * Debug now: false
1158  * Terminating...
1159  *
1160  * The list of available signal names and their interpretation is
1161  * system dependent. Signal delivery semantics may also vary between
1162  * systems; in particular signal delivery may not always be reliable.
1163  */
1164 void
1166 {
1167  VALUE mSignal = rb_define_module("Signal");
1168 
1169  rb_define_global_function("trap", sig_trap, -1);
1170  rb_define_module_function(mSignal, "trap", sig_trap, -1);
1171  rb_define_module_function(mSignal, "list", sig_list, 0);
1172  rb_define_module_function(mSignal, "signame", sig_signame, 1);
1173 
1174  rb_define_method(rb_eSignal, "initialize", esignal_init, -1);
1176  rb_alias(rb_eSignal, rb_intern("signm"), rb_intern("message"));
1177  rb_define_method(rb_eInterrupt, "initialize", interrupt_init, -1);
1178 
1180 #ifdef SIGHUP
1181  install_sighandler(SIGHUP, sighandler);
1182 #endif
1183 #ifdef SIGQUIT
1184  install_sighandler(SIGQUIT, sighandler);
1185 #endif
1186 #ifdef SIGTERM
1187  install_sighandler(SIGTERM, sighandler);
1188 #endif
1189 #ifdef SIGALRM
1190  install_sighandler(SIGALRM, sighandler);
1191 #endif
1192 #ifdef SIGUSR1
1193  install_sighandler(SIGUSR1, sighandler);
1194 #endif
1195 #ifdef SIGUSR2
1196  install_sighandler(SIGUSR2, sighandler);
1197 #endif
1198 
1199  if (!ruby_enable_coredump) {
1200 #ifdef SIGBUS
1201  install_sighandler(SIGBUS, (sighandler_t)sigbus);
1202 #endif
1203 #ifdef SIGSEGV
1204 # ifdef USE_SIGALTSTACK
1205  rb_register_sigaltstack(GET_THREAD());
1206 # endif
1207  install_sighandler(SIGSEGV, (sighandler_t)sigsegv);
1208 #endif
1209  }
1210 #ifdef SIGPIPE
1211  install_sighandler(SIGPIPE, SIG_IGN);
1212 #endif
1213 
1214 #if defined(SIGCLD)
1215  init_sigchld(SIGCLD);
1216 #elif defined(SIGCHLD)
1217  init_sigchld(SIGCHLD);
1218 #endif
1219 }
#define T_SYMBOL
Definition: ruby.h:502
static VALUE sig_list(void)
Definition: signal.c:1067
static void signal_exec(VALUE cmd, int safe, int sig)
Definition: signal.c:696
const char * ruby_signal_name(int no)
Definition: signal.c:237
void rb_interrupt(void)
Definition: eval.c:545
void ruby_thread_stack_overflow(rb_thread_t *th)
Definition: thread.c:2039
void rb_bug(const char *fmt,...)
Definition: error.c:295
#define INT2NUM(x)
Definition: ruby.h:1178
static VALUE trap(int sig, sighandler_t func, VALUE command)
Definition: signal.c:928
int i
Definition: win32ole.c:784
#define T_FIXNUM
Definition: ruby.h:497
VALUE cmd
Definition: vm_core.h:372
VALUE rb_id2str(ID id)
Definition: ripper.c:16946
rb_atomic_t ruby_atomic_exchange(rb_atomic_t *ptr, rb_atomic_t val)
Definition: signal.c:28
VALUE rb_eSignal
Definition: error.c:512
const char * signm
Definition: signal.c:56
#define NUM2INT(x)
Definition: ruby.h:622
#define GetProcPtr(obj, ptr)
Definition: vm_core.h:665
#define NUM2PIDT(v)
Definition: ruby.h:332
#define SIGINFO_ARG
Definition: signal.c:446
static VALUE interrupt_init(int argc, VALUE *argv, VALUE self)
Definition: signal.c:313
#define Qtrue
Definition: ruby.h:434
static void rb_enable_interrupt(void)
Definition: signal.c:594
void rb_threadptr_signal_raise(rb_thread_t *th, int sig)
Definition: thread.c:2015
#define RUBY_NSIG
Definition: vm_core.h:57
SSL_METHOD *(* func)(void)
Definition: ossl_ssl.c:108
void rb_trap_exit(void)
Definition: signal.c:728
RETSIGTYPE ruby_sigaction_t(int)
Definition: signal.c:445
#define SYM2ID(x)
Definition: ruby.h:364
void rb_signal_exec(rb_thread_t *th, int sig)
Definition: signal.c:740
#define ruby_enable_coredump
Definition: signal.c:1124
int kill(int, int)
Definition: win32.c:4089
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:1788
#define SIGKILL
Definition: win32.h:463
VALUE rb_ary_new3(long n,...)
Definition: array.c:432
VALUE rb_eSecurityError
Definition: error.c:525
rb_atomic_t size
Definition: signal.c:433
void ruby_default_signal(int sig)
Definition: signal.c:323
static VALUE esignal_signo(VALUE self)
Definition: signal.c:306
void rb_define_global_function(const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a global function.
Definition: class.c:1526
RETSIGTYPE(* sighandler_t)(int)
Definition: signal.c:440
VALUE rb_check_to_integer(VALUE, const char *)
Definition: object.c:2468
static sighandler_t trap_handler(VALUE *cmd, int sig)
Definition: signal.c:831
#define OBJ_TAINTED(x)
Definition: ruby.h:1153
const char * rb_obj_classname(VALUE)
Definition: variable.c:396
#define NORETURN(x)
Definition: ruby.h:31
int args
Definition: win32ole.c:785
static VALUE sig_signame(VALUE recv, VALUE signo)
Definition: signal.c:230
sighandler_t posix_signal(int signum, sighandler_t handler)
Definition: missing-pips.c:43
#define TH_POP_TAG()
Definition: eval_intern.h:129
int ruby_disable_gc_stress
Definition: gc.c:336
static int reserved_signal_p(int signo)
Definition: signal.c:962
#define ATOMIC_DEC(var)
Definition: ruby_atomic.h:129
void rb_thread_wakeup_timer_thread(void)
#define EXEC_TAG()
Definition: eval_intern.h:141
#define val
int signo
Definition: signal.c:57
static RETSIGTYPE sighandler(int sig)
Definition: signal.c:563
VALUE rb_iv_get(VALUE, const char *)
Definition: variable.c:2586
#define JUMP_TAG(st)
Definition: eval_intern.h:148
#define NIL_P(v)
Definition: ruby.h:446
Definition: signal.c:55
int pthread_sigmask(int how, const sigset_t *set, sigset_t *oset)
Definition: missing-pips.c:22
static char msg[50]
Definition: strerror.c:8
static void install_sighandler(int signum, sighandler_t handler)
Definition: signal.c:1079
static const struct signals siglist[]
rb_atomic_t cnt[RUBY_NSIG]
Definition: signal.c:432
#define TYPE(x)
Definition: ruby.h:513
int argc
Definition: ruby.c:130
int err
Definition: win32.c:87
#define RB_UNUSED_VAR(x)
Definition: ruby.h:535
static sighandler_t default_handler(int sig)
Definition: signal.c:782
static VALUE sig_trap(int argc, VALUE *argv)
Definition: signal.c:1023
static int signm2signo(const char *nm)
Definition: signal.c:195
#define RSTRING_LEN(str)
Definition: ruby.h:862
void rb_define_module_function(VALUE module, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a module function for module.
Definition: class.c:1512
int errno
void Init_signal(void)
Definition: signal.c:1165
VALUE rb_sprintf(const char *format,...)
Definition: sprintf.c:1275
VALUE rb_hash_new(void)
Definition: hash.c:234
VALUE rb_iv_set(VALUE, const char *, VALUE)
Definition: variable.c:2594
struct rb_vm_struct::@130 trap_list[RUBY_NSIG]
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:1570
VALUE rb_eInterrupt
Definition: error.c:511
#define Qnil
Definition: ruby.h:435
unsigned long VALUE
Definition: ruby.h:104
static const char * signo2signm(int no)
Definition: signal.c:206
rb_thread_t * ruby_current_thread
Definition: vm.c:96
static void rb_disable_interrupt(void)
Definition: signal.c:584
#define FIX2INT(x)
Definition: ruby.h:624
static struct @116 signal_buff
void rb_bug_errno(const char *mesg, int errno_arg)
Definition: error.c:318
void rb_alias(VALUE, ID, ID)
Definition: vm_method.c:1209
#define TH_PUSH_TAG(th)
Definition: eval_intern.h:122
VALUE rb_call_super(int, const VALUE *)
Definition: vm_eval.c:273
VALUE rb_str_new_cstr(const char *)
Definition: string.c:447
int rb_sigaltstack_size(void)
#define NSIG
Definition: vm_core.h:54
void rb_sys_fail(const char *mesg)
Definition: error.c:1907
#define ATOMIC_INC(var)
Definition: ruby_atomic.h:128
#define IMMEDIATE_P(x)
Definition: ruby.h:360
int rb_get_next_signal(void)
Definition: signal.c:604
#define RSTRING_PTR(str)
Definition: ruby.h:866
VALUE rb_f_kill(int argc, VALUE *argv)
Definition: signal.c:364
rb_atomic_t ruby_atomic_compare_and_swap(rb_atomic_t *ptr, rb_atomic_t cmp, rb_atomic_t newval)
Definition: signal.c:36
#define CHECK_STACK_OVERFLOW()
Definition: signal.c:639
#define rb_check_arity(argc, min, max)
Definition: intern.h:277
#define INT2FIX(i)
Definition: ruby.h:241
#define UNLIMITED_ARGUMENTS
Definition: intern.h:54
sighandler_t signal(int signum, sighandler_t handler)
unsigned long interrupt_mask
Definition: vm_core.h:555
VALUE rb_block_proc(void)
Definition: proc.c:458
void ruby_sig_finalize(void)
Definition: signal.c:1111
VALUE rb_check_string_type(VALUE)
Definition: string.c:1509
int rb_signal_buff_size(void)
Definition: signal.c:574
#define T_STRING
Definition: ruby.h:490
static VALUE esignal_init(int argc, VALUE *argv, VALUE self)
Definition: signal.c:252
VALUE rb_eval_cmd(VALUE, VALUE, int)
Definition: vm_eval.c:1444
#define SafeStringValue(v)
Definition: ruby.h:552
int rb_atomic_t
Definition: ruby_atomic.h:120
#define rb_safe_level()
Definition: tcltklib.c:94
const char * name
Definition: nkf.c:208
static int trap_signm(VALUE vsig)
Definition: signal.c:896
const char * rb_id2name(ID id)
Definition: ripper.c:17012
#define StringValuePtr(v)
Definition: ruby.h:547
#define killpg(pg, sig)
#define ruby_signal(sig, handler)
Definition: signal.c:548
void rb_secure(int)
Definition: safe.c:79
VALUE rb_define_module(const char *name)
Definition: class.c:606
#define rb_intern(str)
#define SYMBOL_P(x)
Definition: ruby.h:362
#define NULL
Definition: _sdbm.c:102
#define Qundef
Definition: ruby.h:436
VALUE rb_hash_aset(VALUE, VALUE, VALUE)
static rb_thread_t * GET_THREAD(void)
Definition: vm_core.h:890
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1344
VALUE rb_str_new2(const char *)
VALUE rb_eArgError
Definition: error.c:517
static ID cmp
Definition: compar.c:16
void rb_threadptr_signal_exit(rb_thread_t *th)
Definition: thread.c:2025
char ** argv
Definition: ruby.c:131
#define SIGINT
Definition: win32.h:460
#define GET_VM()
Definition: vm_core.h:883