Ruby  2.0.0p594(2014-10-27revision48167)
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 #else /* !POSIX_SIGNAL */
537 #define ruby_signal(sig,handler) (/* rb_trap_accept_nativethreads[(sig)] = 0,*/ signal((sig),(handler)))
538 #if 0 /* def HAVE_NATIVETHREAD */
539 static sighandler_t
540 ruby_nativethread_signal(int signum, sighandler_t handler)
541 {
542  sighandler_t old;
543 
544  old = signal(signum, handler);
545  rb_trap_accept_nativethreads[signum] = 1;
546  return old;
547 }
548 #endif
549 #endif
550 
551 static RETSIGTYPE
552 sighandler(int sig)
553 {
554  ATOMIC_INC(signal_buff.cnt[sig]);
555  ATOMIC_INC(signal_buff.size);
557 #if !defined(BSD_SIGNAL) && !defined(POSIX_SIGNAL)
558  ruby_signal(sig, sighandler);
559 #endif
560 }
561 
562 int
564 {
565  return signal_buff.size;
566 }
567 
568 #if HAVE_PTHREAD_H
569 #include <pthread.h>
570 #endif
571 
572 static void
574 {
575 #ifdef HAVE_PTHREAD_SIGMASK
576  sigset_t mask;
577  sigfillset(&mask);
578  pthread_sigmask(SIG_SETMASK, &mask, NULL);
579 #endif
580 }
581 
582 static void
584 {
585 #ifdef HAVE_PTHREAD_SIGMASK
586  sigset_t mask;
587  sigemptyset(&mask);
588  pthread_sigmask(SIG_SETMASK, &mask, NULL);
589 #endif
590 }
591 
592 int
594 {
595  int i, sig = 0;
596 
597  if (signal_buff.size != 0) {
598  for (i=1; i<RUBY_NSIG; i++) {
599  if (signal_buff.cnt[i] > 0) {
600  ATOMIC_DEC(signal_buff.cnt[i]);
601  ATOMIC_DEC(signal_buff.size);
602  sig = i;
603  break;
604  }
605  }
606  }
607  return sig;
608 }
609 
610 
611 #if defined(USE_SIGALTSTACK) || defined(_WIN32)
612 static void
613 check_stack_overflow(const void *addr)
614 {
615  int ruby_stack_overflowed_p(const rb_thread_t *, const void *);
618  if (ruby_stack_overflowed_p(th, addr)) {
620  }
621 }
622 #ifdef _WIN32
623 #define CHECK_STACK_OVERFLOW() check_stack_overflow(0)
624 #else
625 #define CHECK_STACK_OVERFLOW() check_stack_overflow(info->si_addr)
626 #endif
627 #else
628 #define CHECK_STACK_OVERFLOW() (void)0
629 #endif
630 
631 #ifdef SIGBUS
632 static RETSIGTYPE
633 sigbus(int sig SIGINFO_ARG)
634 {
635 /*
636  * Mac OS X makes KERN_PROTECTION_FAILURE when thread touch guard page.
637  * and it's delivered as SIGBUS instaed of SIGSEGV to userland. It's crazy
638  * wrong IMHO. but anyway we have to care it. Sigh.
639  */
640 #if defined __APPLE__
642 #endif
643  rb_bug("Bus Error");
644 }
645 #endif
646 
647 #ifdef SIGSEGV
648 static void ruby_abort(void)
649 {
650 #ifdef __sun
651  /* Solaris's abort() is async signal unsafe. Of course, it is not
652  * POSIX compliant.
653  */
654  raise(SIGABRT);
655 #else
656  abort();
657 #endif
658 
659 }
660 
661 static int segv_received = 0;
662 extern int ruby_disable_gc_stress;
663 
664 static RETSIGTYPE
665 sigsegv(int sig SIGINFO_ARG)
666 {
667  if (segv_received) {
668  ssize_t RB_UNUSED_VAR(err);
669  char msg[] = "SEGV received in SEGV handler\n";
670 
671  err = write(2, msg, sizeof(msg));
672  ruby_abort();
673  }
674 
676 
677  segv_received = 1;
678  ruby_disable_gc_stress = 1;
679  rb_bug("Segmentation fault");
680 }
681 #endif
682 
683 static void
684 signal_exec(VALUE cmd, int safe, int sig)
685 {
686  rb_thread_t *cur_th = GET_THREAD();
687  volatile unsigned long old_interrupt_mask = cur_th->interrupt_mask;
688  int state;
689 
690  /*
691  * workaround the following race:
692  * 1. signal_enque queues signal for execution
693  * 2. user calls trap(sig, "IGNORE"), setting SIG_IGN
694  * 3. rb_signal_exec runs on queued signal
695  */
696  if (IMMEDIATE_P(cmd))
697  return;
698 
700  TH_PUSH_TAG(cur_th);
701  if ((state = EXEC_TAG()) == 0) {
702  VALUE signum = INT2NUM(sig);
703  rb_eval_cmd(cmd, rb_ary_new3(1, signum), safe);
704  }
705  TH_POP_TAG();
706  cur_th = GET_THREAD();
707  cur_th->interrupt_mask = old_interrupt_mask;
708 
709  if (state) {
710  /* XXX: should be replaced with rb_threadptr_pending_interrupt_enque() */
711  JUMP_TAG(state);
712  }
713 }
714 
715 void
717 {
718  rb_vm_t *vm = GET_VM();
719  VALUE trap_exit = vm->trap_list[0].cmd;
720 
721  if (trap_exit) {
722  vm->trap_list[0].cmd = 0;
723  signal_exec(trap_exit, vm->trap_list[0].safe, 0);
724  }
725 }
726 
727 void
729 {
730  rb_vm_t *vm = GET_VM();
731  VALUE cmd = vm->trap_list[sig].cmd;
732  int safe = vm->trap_list[sig].safe;
733 
734  if (cmd == 0) {
735  switch (sig) {
736  case SIGINT:
737  rb_interrupt();
738  break;
739 #ifdef SIGHUP
740  case SIGHUP:
741 #endif
742 #ifdef SIGQUIT
743  case SIGQUIT:
744 #endif
745 #ifdef SIGTERM
746  case SIGTERM:
747 #endif
748 #ifdef SIGALRM
749  case SIGALRM:
750 #endif
751 #ifdef SIGUSR1
752  case SIGUSR1:
753 #endif
754 #ifdef SIGUSR2
755  case SIGUSR2:
756 #endif
757  rb_threadptr_signal_raise(th, sig);
758  break;
759  }
760  }
761  else if (cmd == Qundef) {
763  }
764  else {
765  signal_exec(cmd, safe, sig);
766  }
767 }
768 
769 static sighandler_t
771 {
773  switch (sig) {
774  case SIGINT:
775 #ifdef SIGHUP
776  case SIGHUP:
777 #endif
778 #ifdef SIGQUIT
779  case SIGQUIT:
780 #endif
781 #ifdef SIGTERM
782  case SIGTERM:
783 #endif
784 #ifdef SIGALRM
785  case SIGALRM:
786 #endif
787 #ifdef SIGUSR1
788  case SIGUSR1:
789 #endif
790 #ifdef SIGUSR2
791  case SIGUSR2:
792 #endif
793  func = sighandler;
794  break;
795 #ifdef SIGBUS
796  case SIGBUS:
797  func = (sighandler_t)sigbus;
798  break;
799 #endif
800 #ifdef SIGSEGV
801  case SIGSEGV:
802  func = (sighandler_t)sigsegv;
803  break;
804 #endif
805 #ifdef SIGPIPE
806  case SIGPIPE:
807  func = SIG_IGN;
808  break;
809 #endif
810  default:
811  func = SIG_DFL;
812  break;
813  }
814 
815  return func;
816 }
817 
818 static sighandler_t
820 {
822  VALUE command;
823 
824  if (NIL_P(*cmd)) {
825  func = SIG_IGN;
826  }
827  else {
828  command = rb_check_string_type(*cmd);
829  if (NIL_P(command) && SYMBOL_P(*cmd)) {
830  command = rb_id2str(SYM2ID(*cmd));
831  if (!command) rb_raise(rb_eArgError, "bad handler");
832  }
833  if (!NIL_P(command)) {
834  SafeStringValue(command); /* taint check */
835  *cmd = command;
836  switch (RSTRING_LEN(command)) {
837  case 0:
838  goto sig_ign;
839  break;
840  case 14:
841  if (strncmp(RSTRING_PTR(command), "SYSTEM_DEFAULT", 14) == 0) {
842  func = SIG_DFL;
843  *cmd = 0;
844  }
845  break;
846  case 7:
847  if (strncmp(RSTRING_PTR(command), "SIG_IGN", 7) == 0) {
848 sig_ign:
849  func = SIG_IGN;
850  *cmd = Qtrue;
851  }
852  else if (strncmp(RSTRING_PTR(command), "SIG_DFL", 7) == 0) {
853 sig_dfl:
854  func = default_handler(sig);
855  *cmd = 0;
856  }
857  else if (strncmp(RSTRING_PTR(command), "DEFAULT", 7) == 0) {
858  goto sig_dfl;
859  }
860  break;
861  case 6:
862  if (strncmp(RSTRING_PTR(command), "IGNORE", 6) == 0) {
863  goto sig_ign;
864  }
865  break;
866  case 4:
867  if (strncmp(RSTRING_PTR(command), "EXIT", 4) == 0) {
868  *cmd = Qundef;
869  }
870  break;
871  }
872  }
873  else {
874  rb_proc_t *proc;
875  GetProcPtr(*cmd, proc);
876  (void)proc;
877  }
878  }
879 
880  return func;
881 }
882 
883 static int
885 {
886  int sig = -1;
887  const char *s;
888 
889  switch (TYPE(vsig)) {
890  case T_FIXNUM:
891  sig = FIX2INT(vsig);
892  if (sig < 0 || sig >= NSIG) {
893  rb_raise(rb_eArgError, "invalid signal number (%d)", sig);
894  }
895  break;
896 
897  case T_SYMBOL:
898  s = rb_id2name(SYM2ID(vsig));
899  if (!s) rb_raise(rb_eArgError, "bad signal");
900  goto str_signal;
901 
902  default:
903  s = StringValuePtr(vsig);
904 
905  str_signal:
906  if (strncmp("SIG", s, 3) == 0)
907  s += 3;
908  sig = signm2signo(s);
909  if (sig == 0 && strcmp(s, "EXIT") != 0)
910  rb_raise(rb_eArgError, "unsupported signal SIG%s", s);
911  }
912  return sig;
913 }
914 
915 static VALUE
916 trap(int sig, sighandler_t func, VALUE command)
917 {
918  sighandler_t oldfunc;
919  VALUE oldcmd;
920  rb_vm_t *vm = GET_VM();
921 
922  /*
923  * Be careful. ruby_signal() and trap_list[sig].cmd must be changed
924  * atomically. In current implementation, we only need to don't call
925  * RUBY_VM_CHECK_INTS().
926  */
927  oldfunc = ruby_signal(sig, func);
928  oldcmd = vm->trap_list[sig].cmd;
929  switch (oldcmd) {
930  case 0:
931  case Qtrue:
932  if (oldfunc == SIG_IGN) oldcmd = rb_str_new2("IGNORE");
933  else if (oldfunc == sighandler) oldcmd = rb_str_new2("DEFAULT");
934  else oldcmd = Qnil;
935  break;
936  case Qnil:
937  break;
938  case Qundef:
939  oldcmd = rb_str_new2("EXIT");
940  break;
941  }
942 
943  vm->trap_list[sig].cmd = command;
944  vm->trap_list[sig].safe = rb_safe_level();
945 
946  return oldcmd;
947 }
948 
949 static int
951 {
952 /* Synchronous signal can't deliver to main thread */
953 #ifdef SIGSEGV
954  if (signo == SIGSEGV)
955  return 1;
956 #endif
957 #ifdef SIGBUS
958  if (signo == SIGBUS)
959  return 1;
960 #endif
961 #ifdef SIGILL
962  if (signo == SIGILL)
963  return 1;
964 #endif
965 #ifdef SIGFPE
966  if (signo == SIGFPE)
967  return 1;
968 #endif
969 
970 /* used ubf internal see thread_pthread.c. */
971 #ifdef SIGVTALRM
972  if (signo == SIGVTALRM)
973  return 1;
974 #endif
975 
976  return 0;
977 }
978 
979 /*
980  * call-seq:
981  * Signal.trap( signal, command ) -> obj
982  * Signal.trap( signal ) {| | block } -> obj
983  *
984  * Specifies the handling of signals. The first parameter is a signal
985  * name (a string such as ``SIGALRM'', ``SIGUSR1'', and so on) or a
986  * signal number. The characters ``SIG'' may be omitted from the
987  * signal name. The command or block specifies code to be run when the
988  * signal is raised.
989  * If the command is the string ``IGNORE'' or ``SIG_IGN'', the signal
990  * will be ignored.
991  * If the command is ``DEFAULT'' or ``SIG_DFL'', the Ruby's default handler
992  * will be invoked.
993  * If the command is ``EXIT'', the script will be terminated by the signal.
994  * If the command is ``SYSTEM_DEFAULT'', the operating system's default
995  * handler will be invoked.
996  * Otherwise, the given command or block will be run.
997  * The special signal name ``EXIT'' or signal number zero will be
998  * invoked just prior to program termination.
999  * trap returns the previous handler for the given signal.
1000  *
1001  * Signal.trap(0, proc { puts "Terminating: #{$$}" })
1002  * Signal.trap("CLD") { puts "Child died" }
1003  * fork && Process.wait
1004  *
1005  * produces:
1006  * Terminating: 27461
1007  * Child died
1008  * Terminating: 27460
1009  */
1010 static VALUE
1012 {
1013  int sig;
1015  VALUE cmd;
1016 
1017  rb_secure(2);
1018  rb_check_arity(argc, 1, 2);
1019 
1020  sig = trap_signm(argv[0]);
1021  if (reserved_signal_p(sig)) {
1022  const char *name = signo2signm(sig);
1023  if (name)
1024  rb_raise(rb_eArgError, "can't trap reserved signal: SIG%s", name);
1025  else
1026  rb_raise(rb_eArgError, "can't trap reserved signal: %d", sig);
1027  }
1028 
1029  if (argc == 1) {
1030  cmd = rb_block_proc();
1031  func = sighandler;
1032  }
1033  else {
1034  cmd = argv[1];
1035  func = trap_handler(&cmd, sig);
1036  }
1037 
1038  if (OBJ_TAINTED(cmd)) {
1039  rb_raise(rb_eSecurityError, "Insecure: tainted signal trap");
1040  }
1041 
1042  return trap(sig, func, cmd);
1043 }
1044 
1045 /*
1046  * call-seq:
1047  * Signal.list -> a_hash
1048  *
1049  * Returns a list of signal names mapped to the corresponding
1050  * underlying signal numbers.
1051  *
1052  * 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}
1053  */
1054 static VALUE
1056 {
1057  VALUE h = rb_hash_new();
1058  const struct signals *sigs;
1059 
1060  for (sigs = siglist; sigs->signm; sigs++) {
1061  rb_hash_aset(h, rb_str_new2(sigs->signm), INT2FIX(sigs->signo));
1062  }
1063  return h;
1064 }
1065 
1066 static void
1067 install_sighandler(int signum, sighandler_t handler)
1068 {
1069  sighandler_t old;
1070 
1071  /* At this time, there is no subthread. Then sigmask guarantee atomics. */
1073  old = ruby_signal(signum, handler);
1074  /* signal handler should be inherited during exec. */
1075  if (old != SIG_DFL) {
1076  ruby_signal(signum, old);
1077  }
1079 }
1080 
1081 #if defined(SIGCLD) || defined(SIGCHLD)
1082 static void
1083 init_sigchld(int sig)
1084 {
1085  sighandler_t oldfunc;
1086 
1088  oldfunc = ruby_signal(sig, SIG_DFL);
1089  if (oldfunc != SIG_DFL && oldfunc != SIG_IGN) {
1090  ruby_signal(sig, oldfunc);
1091  } else {
1092  GET_VM()->trap_list[sig].cmd = 0;
1093  }
1095 }
1096 #endif
1097 
1098 void
1100 {
1101  sighandler_t oldfunc;
1102 
1103  oldfunc = ruby_signal(SIGINT, SIG_IGN);
1104  if (oldfunc == sighandler) {
1105  ruby_signal(SIGINT, SIG_DFL);
1106  }
1107 }
1108 
1109 
1111 #ifndef RUBY_DEBUG_ENV
1112 #define ruby_enable_coredump 0
1113 #endif
1114 
1115 /*
1116  * Many operating systems allow signals to be sent to running
1117  * processes. Some signals have a defined effect on the process, while
1118  * others may be trapped at the code level and acted upon. For
1119  * example, your process may trap the USR1 signal and use it to toggle
1120  * debugging, and may use TERM to initiate a controlled shutdown.
1121  *
1122  * pid = fork do
1123  * Signal.trap("USR1") do
1124  * $debug = !$debug
1125  * puts "Debug now: #$debug"
1126  * end
1127  * Signal.trap("TERM") do
1128  * puts "Terminating..."
1129  * shutdown()
1130  * end
1131  * # . . . do some work . . .
1132  * end
1133  *
1134  * Process.detach(pid)
1135  *
1136  * # Controlling program:
1137  * Process.kill("USR1", pid)
1138  * # ...
1139  * Process.kill("USR1", pid)
1140  * # ...
1141  * Process.kill("TERM", pid)
1142  *
1143  * produces:
1144  * Debug now: true
1145  * Debug now: false
1146  * Terminating...
1147  *
1148  * The list of available signal names and their interpretation is
1149  * system dependent. Signal delivery semantics may also vary between
1150  * systems; in particular signal delivery may not always be reliable.
1151  */
1152 void
1154 {
1155  VALUE mSignal = rb_define_module("Signal");
1156 
1157  rb_define_global_function("trap", sig_trap, -1);
1158  rb_define_module_function(mSignal, "trap", sig_trap, -1);
1159  rb_define_module_function(mSignal, "list", sig_list, 0);
1160  rb_define_module_function(mSignal, "signame", sig_signame, 1);
1161 
1162  rb_define_method(rb_eSignal, "initialize", esignal_init, -1);
1164  rb_alias(rb_eSignal, rb_intern("signm"), rb_intern("message"));
1165  rb_define_method(rb_eInterrupt, "initialize", interrupt_init, -1);
1166 
1168 #ifdef SIGHUP
1169  install_sighandler(SIGHUP, sighandler);
1170 #endif
1171 #ifdef SIGQUIT
1172  install_sighandler(SIGQUIT, sighandler);
1173 #endif
1174 #ifdef SIGTERM
1175  install_sighandler(SIGTERM, sighandler);
1176 #endif
1177 #ifdef SIGALRM
1178  install_sighandler(SIGALRM, sighandler);
1179 #endif
1180 #ifdef SIGUSR1
1181  install_sighandler(SIGUSR1, sighandler);
1182 #endif
1183 #ifdef SIGUSR2
1184  install_sighandler(SIGUSR2, sighandler);
1185 #endif
1186 
1187  if (!ruby_enable_coredump) {
1188 #ifdef SIGBUS
1189  install_sighandler(SIGBUS, (sighandler_t)sigbus);
1190 #endif
1191 #ifdef SIGSEGV
1192 # ifdef USE_SIGALTSTACK
1193  rb_register_sigaltstack(GET_THREAD());
1194 # endif
1195  install_sighandler(SIGSEGV, (sighandler_t)sigsegv);
1196 #endif
1197  }
1198 #ifdef SIGPIPE
1199  install_sighandler(SIGPIPE, SIG_IGN);
1200 #endif
1201 
1202 #if defined(SIGCLD)
1203  init_sigchld(SIGCLD);
1204 #elif defined(SIGCHLD)
1205  init_sigchld(SIGCHLD);
1206 #endif
1207 }
static VALUE sig_list(void)
Definition: signal.c:1055
static void signal_exec(VALUE cmd, int safe, int sig)
Definition: signal.c:684
VP_EXPORT int
Definition: bigdecimal.c:5071
void rb_interrupt(void)
Definition: eval.c:545
void ruby_thread_stack_overflow(rb_thread_t *th)
Definition: thread.c:2036
void rb_bug(const char *fmt,...)
Definition: error.c:295
static VALUE VALUE th
Definition: tcltklib.c:2947
static VALUE trap(int sig, sighandler_t func, VALUE command)
Definition: signal.c:916
const char * rb_obj_classname(VALUE)
Definition: variable.c:396
VALUE cmd
Definition: vm_core.h:372
VALUE rb_id2str(ID id)
Definition: ripper.c:16940
VALUE rb_iv_set(VALUE, const char *, VALUE)
Definition: variable.c:2594
VALUE rb_eSignal
Definition: error.c:512
VALUE rb_eval_cmd(VALUE, VALUE, int)
Definition: vm_eval.c:1443
#define UNLIMITED_ARGUMENTS
const char * signm
Definition: signal.c:56
#define GetProcPtr(obj, ptr)
Definition: vm_core.h:665
#define NUM2PIDT(v)
Definition: ruby.h:332
VALUE proc
Definition: tcltklib.c:2958
#define SIGINFO_ARG
Definition: signal.c:446
SSL_METHOD *(* func)(void)
Definition: ossl_ssl.c:108
static VALUE interrupt_init(int argc, VALUE *argv, VALUE self)
Definition: signal.c:313
void rb_secure(int)
Definition: safe.c:79
ssize_t i
Definition: bigdecimal.c:5676
static void rb_enable_interrupt(void)
Definition: signal.c:583
VALUE rb_str_new_cstr(const char *)
Definition: string.c:447
void rb_threadptr_signal_raise(rb_thread_t *th, int sig)
Definition: thread.c:2012
VALUE rb_iv_get(VALUE, const char *)
Definition: variable.c:2586
static struct signals siglist[]
#define RUBY_NSIG
Definition: vm_core.h:57
#define OBJ_TAINTED(x)
RETSIGTYPE ruby_sigaction_t(int)
Definition: signal.c:445
#define TYPE(x)
void rb_signal_exec(rb_thread_t *th, int sig)
Definition: signal.c:728
#define ruby_enable_coredump
Definition: signal.c:1112
#define RSTRING_PTR(str)
int kill(int, int)
Definition: win32.c:4083
NIL_P(eventloop_thread)
Definition: tcltklib.c:4067
int safe
Definition: tcltklib.c:6403
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:1788
return Qtrue
Definition: tcltklib.c:9609
#define SIGKILL
Definition: win32.h:463
#define SafeStringValue(v)
VALUE rb_ary_new3(long n,...)
Definition: array.c:432
VALUE rb_eSecurityError
Definition: error.c:525
#define rb_str_new2
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:1530
int state
Definition: tcltklib.c:1461
#define RB_UNUSED_VAR(x)
VALUE VALUE args
Definition: tcltklib.c:2560
static sighandler_t trap_handler(VALUE *cmd, int sig)
Definition: signal.c:819
#define NORETURN(x)
Definition: ruby.h:31
rb_atomic_t ruby_atomic_compare_and_swap(rb_atomic_t *ptr, rb_atomic_t cmp, rb_atomic_t newval)
Definition: signal.c:36
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
RETSIGTYPE(* sighandler_t)(int)
Definition: signal.c:440
VALUE rb_block_proc(void)
Definition: proc.c:458
int ruby_disable_gc_stress
Definition: gc.c:336
static int reserved_signal_p(int signo)
Definition: signal.c:950
#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 Qnil
Definition: tcltklib.c:1895
#define StringValuePtr(v)
#define val
Definition: tcltklib.c:1948
int signo
Definition: signal.c:57
static VALUE char * str
Definition: tcltklib.c:3546
static RETSIGTYPE sighandler(int sig)
Definition: signal.c:552
#define JUMP_TAG(st)
Definition: eval_intern.h:148
Definition: signal.c:55
int pthread_sigmask(int how, const sigset_t *set, sigset_t *oset)
Definition: missing-pips.c:22
static void install_sighandler(int signum, sighandler_t handler)
Definition: signal.c:1067
#define RSTRING_LEN(str)
#define FIX2INT(x)
#define INT2FIX(i)
VALUE rb_check_to_integer(VALUE, const char *)
Definition: object.c:2443
#define T_STRING
void rb_trap_exit(void)
Definition: signal.c:716
VALUE rb_call_super(int, const VALUE *)
Definition: vm_eval.c:273
int err
Definition: win32.c:87
static sighandler_t default_handler(int sig)
Definition: signal.c:770
static VALUE sig_trap(int argc, VALUE *argv)
Definition: signal.c:1011
VALUE * argv
Definition: tcltklib.c:1970
static int signm2signo(const char *nm)
Definition: signal.c:195
VALUE rb_hash_aset(VALUE, VALUE, VALUE)
void rb_define_module_function(VALUE module, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a module function for module.
Definition: class.c:1516
int errno
void Init_signal(void)
Definition: signal.c:1153
VALUE rb_sprintf(const char *format,...)
Definition: sprintf.c:1275
register char * s
Definition: os2.c:56
VP_EXPORT void
Definition: bigdecimal.c:5104
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:1574
VALUE rb_eInterrupt
Definition: error.c:511
const char * ruby_signal_name(int)
Definition: signal.c:237
VALUE rb_f_kill(int, VALUE *)
Definition: signal.c:364
#define T_FIXNUM
int argc
Definition: tcltklib.c:1969
void rb_alias(VALUE, ID, ID)
Definition: vm_method.c:1203
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:573
void rb_bug_errno(const char *mesg, int errno_arg)
Definition: error.c:318
#define TH_PUSH_TAG(th)
Definition: eval_intern.h:122
const char * cmd
Definition: tcltklib.c:278
#define NSIG
Definition: vm_core.h:54
void rb_sys_fail(const char *mesg)
Definition: error.c:1907
return ptr
Definition: tcltklib.c:784
#define ATOMIC_INC(var)
Definition: ruby_atomic.h:128
VALUE msg
Definition: tcltklib.c:846
#define T_SYMBOL
int size
Definition: encoding.c:52
#define CHECK_STACK_OVERFLOW()
Definition: signal.c:628
#define SYMBOL_P(x)
sighandler_t signal(int signum, sighandler_t handler)
#define Qundef
unsigned long interrupt_mask
Definition: vm_core.h:555
void ruby_sig_finalize(void)
Definition: signal.c:1099
int rb_signal_buff_size(void)
Definition: signal.c:563
#define INT2NUM(x)
static VALUE esignal_init(int argc, VALUE *argv, VALUE self)
Definition: signal.c:252
static struct @138 signal_buff
void ruby_default_signal(int)
Definition: signal.c:323
int rb_atomic_t
Definition: ruby_atomic.h:120
#define rb_safe_level()
Definition: tcltklib.c:94
#define NUM2INT(x)
VALUE rb_hash_new(void)
Definition: hash.c:234
static int trap_signm(VALUE vsig)
Definition: signal.c:884
const char * rb_id2name(ID id)
Definition: ripper.c:17006
int cnt
Definition: tcltklib.c:6148
#define rb_check_arity(argc, min, max)
#define killpg(pg, sig)
#define ruby_signal(sig, handler)
Definition: signal.c:537
unsigned long VALUE
Definition: ripper.y:104
int rb_sigaltstack_size(void)
VALUE rb_define_module(const char *name)
Definition: class.c:621
#define rb_intern(str)
#define NULL
Definition: _sdbm.c:103
int rb_get_next_signal(void)
Definition: signal.c:593
const char * name
Definition: nkf.c:208
VALUE rb_check_string_type(VALUE)
Definition: string.c:1509
#define IMMEDIATE_P(x)
static rb_thread_t * GET_THREAD(void)
Definition: vm_core.h:888
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1348
#define SYM2ID(x)
struct rb_vm_struct::@152 trap_list[RUBY_NSIG]
VALUE rb_eArgError
Definition: error.c:517
static ID cmp
Definition: compar.c:16
rb_atomic_t ruby_atomic_exchange(rb_atomic_t *ptr, rb_atomic_t val)
Definition: signal.c:28
void rb_threadptr_signal_exit(rb_thread_t *th)
Definition: thread.c:2022
#define SIGINT
Definition: win32.h:460
#define GET_VM()
Definition: vm_core.h:881