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