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