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