Ruby  2.1.3p242(2014-09-19revision47630)
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 int signal_ignored(int sig);
347 static void signal_enque(int sig);
348 
349 /*
350  * call-seq:
351  * Process.kill(signal, pid, ...) -> fixnum
352  *
353  * Sends the given signal to the specified process id(s) if _pid_ is positive.
354  * If _pid_ is zero _signal_ is sent to all processes whose group ID is equal
355  * to the group ID of the process. _signal_ may be an integer signal number or
356  * a POSIX signal name (either with or without a +SIG+ prefix). If _signal_ is
357  * negative (or starts with a minus sign), kills process groups instead of
358  * processes. Not all signals are available on all platforms.
359  *
360  * pid = fork do
361  * Signal.trap("HUP") { puts "Ouch!"; exit }
362  * # ... do some work ...
363  * end
364  * # ...
365  * Process.kill("HUP", pid)
366  * Process.wait
367  *
368  * <em>produces:</em>
369  *
370  * Ouch!
371  *
372  * If _signal_ is an integer but wrong for signal,
373  * <code>Errno::EINVAL</code> or +RangeError+ will be raised.
374  * Otherwise unless _signal_ is a +String+ or a +Symbol+, and a known
375  * signal name, +ArgumentError+ will be raised.
376  *
377  * Also, <code>Errno::ESRCH</code> or +RangeError+ for invalid _pid_,
378  * <code>Errno::EPERM</code> when failed because of no privilege,
379  * will be raised. In these cases, signals may have been sent to
380  * preceding processes.
381  */
382 
383 VALUE
385 {
386 #ifndef HAVE_KILLPG
387 #define killpg(pg, sig) kill(-(pg), (sig))
388 #endif
389  int negative = 0;
390  int sig;
391  int i;
392  volatile VALUE str;
393  const char *s;
394 
395  rb_secure(2);
397 
398  switch (TYPE(argv[0])) {
399  case T_FIXNUM:
400  sig = FIX2INT(argv[0]);
401  break;
402 
403  case T_SYMBOL:
404  s = rb_id2name(SYM2ID(argv[0]));
405  if (!s) rb_raise(rb_eArgError, "bad signal");
406  goto str_signal;
407 
408  case T_STRING:
409  s = RSTRING_PTR(argv[0]);
410  str_signal:
411  if (s[0] == '-') {
412  negative++;
413  s++;
414  }
415  if (strncmp("SIG", s, 3) == 0)
416  s += 3;
417  if ((sig = signm2signo(s)) == 0)
418  rb_raise(rb_eArgError, "unsupported name `SIG%s'", s);
419 
420  if (negative)
421  sig = -sig;
422  break;
423 
424  default:
425  str = rb_check_string_type(argv[0]);
426  if (!NIL_P(str)) {
427  s = RSTRING_PTR(str);
428  goto str_signal;
429  }
430  rb_raise(rb_eArgError, "bad signal type %s",
431  rb_obj_classname(argv[0]));
432  break;
433  }
434 
435  if (argc <= 1) return INT2FIX(0);
436 
437  if (sig < 0) {
438  sig = -sig;
439  for (i=1; i<argc; i++) {
440  if (killpg(NUM2PIDT(argv[i]), sig) < 0)
441  rb_sys_fail(0);
442  }
443  }
444  else {
445  const rb_pid_t self = (GET_THREAD() == GET_VM()->main_thread) ? getpid() : -1;
446  int wakeup = 0;
447 
448  for (i=1; i<argc; i++) {
449  rb_pid_t pid = NUM2PIDT(argv[i]);
450 
451  if ((sig != 0) && (self != -1) && (pid == self)) {
452  /*
453  * When target pid is self, many caller assume signal will be
454  * delivered immediately and synchronously.
455  */
456  switch (sig) {
457  case SIGSEGV:
458 #ifdef SIGBUS
459  case SIGBUS:
460 #endif
461 #ifdef SIGKILL
462  case SIGKILL:
463 #endif
464 #ifdef SIGSTOP
465  case SIGSTOP:
466 #endif
467  ruby_kill(pid, sig);
468  break;
469  default:
470  if (signal_ignored(sig)) break;
471  signal_enque(sig);
472  wakeup = 1;
473  }
474  }
475  else if (kill(pid, sig) < 0) {
476  rb_sys_fail(0);
477  }
478  }
479  if (wakeup) {
480  rb_threadptr_check_signal(GET_VM()->main_thread);
481  }
482  }
484 
485  return INT2FIX(i-1);
486 }
487 
488 static struct {
491 } signal_buff;
492 
493 #ifdef __dietlibc__
494 #define sighandler_t sh_t
495 #else
496 #define sighandler_t ruby_sighandler_t
497 #endif
498 
499 typedef RETSIGTYPE (*sighandler_t)(int);
500 #ifdef USE_SIGALTSTACK
501 typedef void ruby_sigaction_t(int, siginfo_t*, void*);
502 #define SIGINFO_ARG , siginfo_t *info, void *ctx
503 #else
504 typedef RETSIGTYPE ruby_sigaction_t(int);
505 #define SIGINFO_ARG
506 #endif
507 
508 #ifdef USE_SIGALTSTACK
509 int
511 {
512  /* XXX: BSD_vfprintf() uses >1500KiB stack and x86-64 need >5KiB stack. */
513  int size = 8192;
514 
515 #ifdef MINSIGSTKSZ
516  if (size < MINSIGSTKSZ)
517  size = MINSIGSTKSZ;
518 #endif
519 #if defined(HAVE_SYSCONF) && defined(_SC_PAGE_SIZE)
520  {
521  int pagesize;
522  pagesize = (int)sysconf(_SC_PAGE_SIZE);
523  if (size < pagesize)
524  size = pagesize;
525  }
526 #endif
527 
528  return size;
529 }
530 
531 /* alternate stack for SIGSEGV */
532 void
533 rb_register_sigaltstack(rb_thread_t *th)
534 {
535  stack_t newSS, oldSS;
536 
537  if (!th->altstack)
538  rb_bug("rb_register_sigaltstack: th->altstack not initialized\n");
539 
540  newSS.ss_sp = th->altstack;
541  newSS.ss_size = rb_sigaltstack_size();
542  newSS.ss_flags = 0;
543 
544  sigaltstack(&newSS, &oldSS); /* ignore error. */
545 }
546 #endif /* USE_SIGALTSTACK */
547 
548 #ifdef POSIX_SIGNAL
549 static sighandler_t
550 ruby_signal(int signum, sighandler_t handler)
551 {
552  struct sigaction sigact, old;
553 
554 #if 0
555  rb_trap_accept_nativethreads[signum] = 0;
556 #endif
557 
558  sigemptyset(&sigact.sa_mask);
559 #ifdef USE_SIGALTSTACK
560  sigact.sa_sigaction = (ruby_sigaction_t*)handler;
561  sigact.sa_flags = SA_SIGINFO;
562 #else
563  sigact.sa_handler = handler;
564  sigact.sa_flags = 0;
565 #endif
566 
567 #ifdef SA_NOCLDWAIT
568  if (signum == SIGCHLD && handler == SIG_IGN)
569  sigact.sa_flags |= SA_NOCLDWAIT;
570 #endif
571 #if defined(SA_ONSTACK) && defined(USE_SIGALTSTACK)
572  if (signum == SIGSEGV
573 #ifdef SIGBUS
574  || signum == SIGBUS
575 #endif
576  )
577  sigact.sa_flags |= SA_ONSTACK;
578 #endif
579  (void)VALGRIND_MAKE_MEM_DEFINED(&old, sizeof(old));
580  if (sigaction(signum, &sigact, &old) < 0) {
581  if (errno != 0 && errno != EINVAL) {
582  rb_bug_errno("sigaction", errno);
583  }
584  }
585  if (old.sa_flags & SA_SIGINFO)
586  return (sighandler_t)old.sa_sigaction;
587  else
588  return old.sa_handler;
589 }
590 
592 posix_signal(int signum, sighandler_t handler)
593 {
594  return ruby_signal(signum, handler);
595 }
596 
597 #else /* !POSIX_SIGNAL */
598 #define ruby_signal(sig,handler) (/* rb_trap_accept_nativethreads[(sig)] = 0,*/ signal((sig),(handler)))
599 #if 0 /* def HAVE_NATIVETHREAD */
600 static sighandler_t
601 ruby_nativethread_signal(int signum, sighandler_t handler)
602 {
603  sighandler_t old;
604 
605  old = signal(signum, handler);
606  rb_trap_accept_nativethreads[signum] = 1;
607  return old;
608 }
609 #endif
610 #endif
611 
612 static int
614 {
615 #ifdef POSIX_SIGNAL
616  struct sigaction old;
617  (void)VALGRIND_MAKE_MEM_DEFINED(&old, sizeof(old));
618  if (sigaction(sig, NULL, &old) < 0) return FALSE;
619  return old.sa_handler == SIG_IGN;
620 #else
621  sighandler_t old = signal(sig, SIG_DFL);
622  signal(sig, old);
623  return old == SIG_IGN;
624 #endif
625 }
626 
627 static void
628 signal_enque(int sig)
629 {
630  ATOMIC_INC(signal_buff.cnt[sig]);
631  ATOMIC_INC(signal_buff.size);
632 }
633 
634 static RETSIGTYPE
635 sighandler(int sig)
636 {
637  signal_enque(sig);
639 #if !defined(BSD_SIGNAL) && !defined(POSIX_SIGNAL)
640  ruby_signal(sig, sighandler);
641 #endif
642 }
643 
644 int
646 {
647  return signal_buff.size;
648 }
649 
650 #if HAVE_PTHREAD_H
651 #include <pthread.h>
652 #endif
653 
654 static void
656 {
657 #ifdef HAVE_PTHREAD_SIGMASK
658  sigset_t mask;
659  sigfillset(&mask);
660  pthread_sigmask(SIG_SETMASK, &mask, NULL);
661 #endif
662 }
663 
664 static void
666 {
667 #ifdef HAVE_PTHREAD_SIGMASK
668  sigset_t mask;
669  sigemptyset(&mask);
670  pthread_sigmask(SIG_SETMASK, &mask, NULL);
671 #endif
672 }
673 
674 int
676 {
677  int i, sig = 0;
678 
679  if (signal_buff.size != 0) {
680  for (i=1; i<RUBY_NSIG; i++) {
681  if (signal_buff.cnt[i] > 0) {
682  ATOMIC_DEC(signal_buff.cnt[i]);
683  ATOMIC_DEC(signal_buff.size);
684  sig = i;
685  break;
686  }
687  }
688  }
689  return sig;
690 }
691 
692 
693 #if defined(USE_SIGALTSTACK) || defined(_WIN32)
695 #if defined(HAVE_UCONTEXT_H) && defined __linux__ && (defined __i386__ || defined __x86_64__)
696 # define USE_UCONTEXT_REG 1
697 #endif
698 #ifdef USE_UCONTEXT_REG
699 static void
700 check_stack_overflow(const uintptr_t addr, const ucontext_t *ctx)
701 {
702 # if defined REG_RSP
703  const greg_t sp = ctx->uc_mcontext.gregs[REG_RSP];
704 # else
705  const greg_t sp = ctx->uc_mcontext.gregs[REG_ESP];
706 # endif
707  enum {pagesize = 4096};
708  const uintptr_t sp_page = (uintptr_t)sp / pagesize;
709  const uintptr_t fault_page = addr / pagesize;
710 
711  /* SP in ucontext is not decremented yet when `push` failed, so
712  * the fault page can be the next. */
713  if (sp_page == fault_page || sp_page == fault_page + 1) {
715  if ((uintptr_t)th->tag->buf / pagesize == sp_page) {
716  /* drop the last tag if it is close to the fault,
717  * otherwise it can cause stack overflow again at the same
718  * place. */
719  th->tag = th->tag->prev;
720  }
722  }
723 }
724 #else
725 static void
726 check_stack_overflow(const void *addr)
727 {
728  int ruby_stack_overflowed_p(const rb_thread_t *, const void *);
730  if (ruby_stack_overflowed_p(th, addr)) {
732  }
733 }
734 #endif
735 #ifdef _WIN32
736 #define CHECK_STACK_OVERFLOW() check_stack_overflow(0)
737 #else
738 #define FAULT_ADDRESS info->si_addr
739 # ifdef USE_UCONTEXT_REG
740 # define CHECK_STACK_OVERFLOW() check_stack_overflow((uintptr_t)FAULT_ADDRESS, ctx)
741 #else
742 # define CHECK_STACK_OVERFLOW() check_stack_overflow(FAULT_ADDRESS)
743 #endif
744 #define MESSAGE_FAULT_ADDRESS " at %p", FAULT_ADDRESS
745 #endif
746 #else
747 #define CHECK_STACK_OVERFLOW() (void)0
748 #endif
749 #ifndef MESSAGE_FAULT_ADDRESS
750 #define MESSAGE_FAULT_ADDRESS
751 #endif
752 
753 #ifdef SIGBUS
754 static RETSIGTYPE
755 sigbus(int sig SIGINFO_ARG)
756 {
757 /*
758  * Mac OS X makes KERN_PROTECTION_FAILURE when thread touch guard page.
759  * and it's delivered as SIGBUS instead of SIGSEGV to userland. It's crazy
760  * wrong IMHO. but anyway we have to care it. Sigh.
761  */
762 #if defined __APPLE__
764 #endif
765  rb_bug("Bus Error" MESSAGE_FAULT_ADDRESS);
766 }
767 #endif
768 
769 #ifdef SIGSEGV
770 static void
771 ruby_abort(void)
772 {
773 #ifdef __sun
774  /* Solaris's abort() is async signal unsafe. Of course, it is not
775  * POSIX compliant.
776  */
777  raise(SIGABRT);
778 #else
779  abort();
780 #endif
781 
782 }
783 
784 static int segv_received = 0;
785 extern int ruby_disable_gc_stress;
786 
787 static RETSIGTYPE
788 sigsegv(int sig SIGINFO_ARG)
789 {
790  if (segv_received) {
791  ssize_t RB_UNUSED_VAR(err);
792  char msg[] = "SEGV received in SEGV handler\n";
793 
794  err = write(2, msg, sizeof(msg));
795  ruby_abort();
796  }
797 
799 
800  segv_received = 1;
801  ruby_disable_gc_stress = 1;
802  rb_bug("Segmentation fault" MESSAGE_FAULT_ADDRESS);
803 }
804 #endif
805 
806 static void
807 signal_exec(VALUE cmd, int safe, int sig)
808 {
809  rb_thread_t *cur_th = GET_THREAD();
810  volatile unsigned long old_interrupt_mask = cur_th->interrupt_mask;
811  int state;
812 
813  /*
814  * workaround the following race:
815  * 1. signal_enque queues signal for execution
816  * 2. user calls trap(sig, "IGNORE"), setting SIG_IGN
817  * 3. rb_signal_exec runs on queued signal
818  */
819  if (IMMEDIATE_P(cmd))
820  return;
821 
823  TH_PUSH_TAG(cur_th);
824  if ((state = EXEC_TAG()) == 0) {
825  VALUE signum = INT2NUM(sig);
826  rb_eval_cmd(cmd, rb_ary_new3(1, signum), safe);
827  }
828  TH_POP_TAG();
829  cur_th = GET_THREAD();
830  cur_th->interrupt_mask = old_interrupt_mask;
831 
832  if (state) {
833  /* XXX: should be replaced with rb_threadptr_pending_interrupt_enque() */
834  JUMP_TAG(state);
835  }
836 }
837 
838 void
840 {
841  rb_vm_t *vm = GET_VM();
842  VALUE trap_exit = vm->trap_list[0].cmd;
843 
844  if (trap_exit) {
845  vm->trap_list[0].cmd = 0;
846  signal_exec(trap_exit, vm->trap_list[0].safe, 0);
847  }
848 }
849 
850 void
852 {
853  rb_vm_t *vm = GET_VM();
854  VALUE cmd = vm->trap_list[sig].cmd;
855  int safe = vm->trap_list[sig].safe;
856 
857  if (cmd == 0) {
858  switch (sig) {
859  case SIGINT:
860  rb_interrupt();
861  break;
862 #ifdef SIGHUP
863  case SIGHUP:
864 #endif
865 #ifdef SIGQUIT
866  case SIGQUIT:
867 #endif
868 #ifdef SIGTERM
869  case SIGTERM:
870 #endif
871 #ifdef SIGALRM
872  case SIGALRM:
873 #endif
874 #ifdef SIGUSR1
875  case SIGUSR1:
876 #endif
877 #ifdef SIGUSR2
878  case SIGUSR2:
879 #endif
880  rb_threadptr_signal_raise(th, sig);
881  break;
882  }
883  }
884  else if (cmd == Qundef) {
886  }
887  else {
888  signal_exec(cmd, safe, sig);
889  }
890 }
891 
892 static sighandler_t
894 {
896  switch (sig) {
897  case SIGINT:
898 #ifdef SIGHUP
899  case SIGHUP:
900 #endif
901 #ifdef SIGQUIT
902  case SIGQUIT:
903 #endif
904 #ifdef SIGTERM
905  case SIGTERM:
906 #endif
907 #ifdef SIGALRM
908  case SIGALRM:
909 #endif
910 #ifdef SIGUSR1
911  case SIGUSR1:
912 #endif
913 #ifdef SIGUSR2
914  case SIGUSR2:
915 #endif
916  func = sighandler;
917  break;
918 #ifdef SIGBUS
919  case SIGBUS:
920  func = (sighandler_t)sigbus;
921  break;
922 #endif
923 #ifdef SIGSEGV
924  case SIGSEGV:
925  func = (sighandler_t)sigsegv;
926  break;
927 #endif
928 #ifdef SIGPIPE
929  case SIGPIPE:
930  func = SIG_IGN;
931  break;
932 #endif
933  default:
934  func = SIG_DFL;
935  break;
936  }
937 
938  return func;
939 }
940 
941 static sighandler_t
942 trap_handler(VALUE *cmd, int sig)
943 {
945  VALUE command;
946 
947  if (NIL_P(*cmd)) {
948  func = SIG_IGN;
949  }
950  else {
951  command = rb_check_string_type(*cmd);
952  if (NIL_P(command) && SYMBOL_P(*cmd)) {
953  command = rb_id2str(SYM2ID(*cmd));
954  if (!command) rb_raise(rb_eArgError, "bad handler");
955  }
956  if (!NIL_P(command)) {
957  SafeStringValue(command); /* taint check */
958  *cmd = command;
959  switch (RSTRING_LEN(command)) {
960  case 0:
961  goto sig_ign;
962  break;
963  case 14:
964  if (strncmp(RSTRING_PTR(command), "SYSTEM_DEFAULT", 14) == 0) {
965  func = SIG_DFL;
966  *cmd = 0;
967  }
968  break;
969  case 7:
970  if (strncmp(RSTRING_PTR(command), "SIG_IGN", 7) == 0) {
971 sig_ign:
972  func = SIG_IGN;
973  *cmd = Qtrue;
974  }
975  else if (strncmp(RSTRING_PTR(command), "SIG_DFL", 7) == 0) {
976 sig_dfl:
977  func = default_handler(sig);
978  *cmd = 0;
979  }
980  else if (strncmp(RSTRING_PTR(command), "DEFAULT", 7) == 0) {
981  goto sig_dfl;
982  }
983  break;
984  case 6:
985  if (strncmp(RSTRING_PTR(command), "IGNORE", 6) == 0) {
986  goto sig_ign;
987  }
988  break;
989  case 4:
990  if (strncmp(RSTRING_PTR(command), "EXIT", 4) == 0) {
991  *cmd = Qundef;
992  }
993  break;
994  }
995  }
996  else {
997  rb_proc_t *proc;
998  GetProcPtr(*cmd, proc);
999  (void)proc;
1000  }
1001  }
1002 
1003  return func;
1004 }
1005 
1006 static int
1008 {
1009  int sig = -1;
1010  const char *s;
1011 
1012  switch (TYPE(vsig)) {
1013  case T_FIXNUM:
1014  sig = FIX2INT(vsig);
1015  if (sig < 0 || sig >= NSIG) {
1016  rb_raise(rb_eArgError, "invalid signal number (%d)", sig);
1017  }
1018  break;
1019 
1020  case T_SYMBOL:
1021  s = rb_id2name(SYM2ID(vsig));
1022  if (!s) rb_raise(rb_eArgError, "bad signal");
1023  goto str_signal;
1024 
1025  default:
1026  s = StringValuePtr(vsig);
1027 
1028  str_signal:
1029  if (strncmp("SIG", s, 3) == 0)
1030  s += 3;
1031  sig = signm2signo(s);
1032  if (sig == 0 && strcmp(s, "EXIT") != 0)
1033  rb_raise(rb_eArgError, "unsupported signal SIG%s", s);
1034  }
1035  return sig;
1036 }
1037 
1038 static VALUE
1039 trap(int sig, sighandler_t func, VALUE command)
1040 {
1041  sighandler_t oldfunc;
1042  VALUE oldcmd;
1043  rb_vm_t *vm = GET_VM();
1044 
1045  /*
1046  * Be careful. ruby_signal() and trap_list[sig].cmd must be changed
1047  * atomically. In current implementation, we only need to don't call
1048  * RUBY_VM_CHECK_INTS().
1049  */
1050  oldfunc = ruby_signal(sig, func);
1051  oldcmd = vm->trap_list[sig].cmd;
1052  switch (oldcmd) {
1053  case 0:
1054  case Qtrue:
1055  if (oldfunc == SIG_IGN) oldcmd = rb_str_new2("IGNORE");
1056  else if (oldfunc == sighandler) oldcmd = rb_str_new2("DEFAULT");
1057  else oldcmd = Qnil;
1058  break;
1059  case Qnil:
1060  break;
1061  case Qundef:
1062  oldcmd = rb_str_new2("EXIT");
1063  break;
1064  }
1065 
1066  vm->trap_list[sig].cmd = command;
1067  vm->trap_list[sig].safe = rb_safe_level();
1068 
1069  return oldcmd;
1070 }
1071 
1072 static int
1074 {
1075 /* Synchronous signal can't deliver to main thread */
1076 #ifdef SIGSEGV
1077  if (signo == SIGSEGV)
1078  return 1;
1079 #endif
1080 #ifdef SIGBUS
1081  if (signo == SIGBUS)
1082  return 1;
1083 #endif
1084 #ifdef SIGILL
1085  if (signo == SIGILL)
1086  return 1;
1087 #endif
1088 #ifdef SIGFPE
1089  if (signo == SIGFPE)
1090  return 1;
1091 #endif
1092 
1093 /* used ubf internal see thread_pthread.c. */
1094 #ifdef SIGVTALRM
1095  if (signo == SIGVTALRM)
1096  return 1;
1097 #endif
1098 
1099  return 0;
1100 }
1101 
1102 /*
1103  * call-seq:
1104  * Signal.trap( signal, command ) -> obj
1105  * Signal.trap( signal ) {| | block } -> obj
1106  *
1107  * Specifies the handling of signals. The first parameter is a signal
1108  * name (a string such as ``SIGALRM'', ``SIGUSR1'', and so on) or a
1109  * signal number. The characters ``SIG'' may be omitted from the
1110  * signal name. The command or block specifies code to be run when the
1111  * signal is raised.
1112  * If the command is the string ``IGNORE'' or ``SIG_IGN'', the signal
1113  * will be ignored.
1114  * If the command is ``DEFAULT'' or ``SIG_DFL'', the Ruby's default handler
1115  * will be invoked.
1116  * If the command is ``EXIT'', the script will be terminated by the signal.
1117  * If the command is ``SYSTEM_DEFAULT'', the operating system's default
1118  * handler will be invoked.
1119  * Otherwise, the given command or block will be run.
1120  * The special signal name ``EXIT'' or signal number zero will be
1121  * invoked just prior to program termination.
1122  * trap returns the previous handler for the given signal.
1123  *
1124  * Signal.trap(0, proc { puts "Terminating: #{$$}" })
1125  * Signal.trap("CLD") { puts "Child died" }
1126  * fork && Process.wait
1127  *
1128  * produces:
1129  * Terminating: 27461
1130  * Child died
1131  * Terminating: 27460
1132  */
1133 static VALUE
1135 {
1136  int sig;
1138  VALUE cmd;
1139 
1140  rb_secure(2);
1141  rb_check_arity(argc, 1, 2);
1142 
1143  sig = trap_signm(argv[0]);
1144  if (reserved_signal_p(sig)) {
1145  const char *name = signo2signm(sig);
1146  if (name)
1147  rb_raise(rb_eArgError, "can't trap reserved signal: SIG%s", name);
1148  else
1149  rb_raise(rb_eArgError, "can't trap reserved signal: %d", sig);
1150  }
1151 
1152  if (argc == 1) {
1153  cmd = rb_block_proc();
1154  func = sighandler;
1155  }
1156  else {
1157  cmd = argv[1];
1158  func = trap_handler(&cmd, sig);
1159  }
1160 
1161  if (OBJ_TAINTED(cmd)) {
1162  rb_raise(rb_eSecurityError, "Insecure: tainted signal trap");
1163  }
1164 
1165  return trap(sig, func, cmd);
1166 }
1167 
1168 /*
1169  * call-seq:
1170  * Signal.list -> a_hash
1171  *
1172  * Returns a list of signal names mapped to the corresponding
1173  * underlying signal numbers.
1174  *
1175  * 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}
1176  */
1177 static VALUE
1179 {
1180  VALUE h = rb_hash_new();
1181  const struct signals *sigs;
1182 
1183  for (sigs = siglist; sigs->signm; sigs++) {
1184  rb_hash_aset(h, rb_str_new2(sigs->signm), INT2FIX(sigs->signo));
1185  }
1186  return h;
1187 }
1188 
1189 static void
1190 install_sighandler(int signum, sighandler_t handler)
1191 {
1192  sighandler_t old;
1193 
1194  /* At this time, there is no subthread. Then sigmask guarantee atomics. */
1196  old = ruby_signal(signum, handler);
1197  /* signal handler should be inherited during exec. */
1198  if (old != SIG_DFL) {
1199  ruby_signal(signum, old);
1200  }
1202 }
1203 
1204 #if defined(SIGCLD) || defined(SIGCHLD)
1205 static void
1206 init_sigchld(int sig)
1207 {
1208  sighandler_t oldfunc;
1209 
1211  oldfunc = ruby_signal(sig, SIG_DFL);
1212  if (oldfunc != SIG_DFL && oldfunc != SIG_IGN) {
1213  ruby_signal(sig, oldfunc);
1214  } else {
1215  GET_VM()->trap_list[sig].cmd = 0;
1216  }
1218 }
1219 #endif
1220 
1221 void
1223 {
1224  sighandler_t oldfunc;
1225 
1226  oldfunc = ruby_signal(SIGINT, SIG_IGN);
1227  if (oldfunc == sighandler) {
1228  ruby_signal(SIGINT, SIG_DFL);
1229  }
1230 }
1231 
1232 
1234 #ifndef RUBY_DEBUG_ENV
1235 #define ruby_enable_coredump 0
1236 #endif
1237 
1238 /*
1239  * Many operating systems allow signals to be sent to running
1240  * processes. Some signals have a defined effect on the process, while
1241  * others may be trapped at the code level and acted upon. For
1242  * example, your process may trap the USR1 signal and use it to toggle
1243  * debugging, and may use TERM to initiate a controlled shutdown.
1244  *
1245  * pid = fork do
1246  * Signal.trap("USR1") do
1247  * $debug = !$debug
1248  * puts "Debug now: #$debug"
1249  * end
1250  * Signal.trap("TERM") do
1251  * puts "Terminating..."
1252  * shutdown()
1253  * end
1254  * # . . . do some work . . .
1255  * end
1256  *
1257  * Process.detach(pid)
1258  *
1259  * # Controlling program:
1260  * Process.kill("USR1", pid)
1261  * # ...
1262  * Process.kill("USR1", pid)
1263  * # ...
1264  * Process.kill("TERM", pid)
1265  *
1266  * produces:
1267  * Debug now: true
1268  * Debug now: false
1269  * Terminating...
1270  *
1271  * The list of available signal names and their interpretation is
1272  * system dependent. Signal delivery semantics may also vary between
1273  * systems; in particular signal delivery may not always be reliable.
1274  */
1275 void
1277 {
1278  VALUE mSignal = rb_define_module("Signal");
1279 
1280  rb_define_global_function("trap", sig_trap, -1);
1281  rb_define_module_function(mSignal, "trap", sig_trap, -1);
1282  rb_define_module_function(mSignal, "list", sig_list, 0);
1283  rb_define_module_function(mSignal, "signame", sig_signame, 1);
1284 
1285  rb_define_method(rb_eSignal, "initialize", esignal_init, -1);
1287  rb_alias(rb_eSignal, rb_intern("signm"), rb_intern("message"));
1288  rb_define_method(rb_eInterrupt, "initialize", interrupt_init, -1);
1289 
1291 #ifdef SIGHUP
1292  install_sighandler(SIGHUP, sighandler);
1293 #endif
1294 #ifdef SIGQUIT
1295  install_sighandler(SIGQUIT, sighandler);
1296 #endif
1297 #ifdef SIGTERM
1298  install_sighandler(SIGTERM, sighandler);
1299 #endif
1300 #ifdef SIGALRM
1301  install_sighandler(SIGALRM, sighandler);
1302 #endif
1303 #ifdef SIGUSR1
1304  install_sighandler(SIGUSR1, sighandler);
1305 #endif
1306 #ifdef SIGUSR2
1307  install_sighandler(SIGUSR2, sighandler);
1308 #endif
1309 
1310  if (!ruby_enable_coredump) {
1311 #ifdef SIGBUS
1312  install_sighandler(SIGBUS, (sighandler_t)sigbus);
1313 #endif
1314 #ifdef SIGSEGV
1315 # ifdef USE_SIGALTSTACK
1316  rb_register_sigaltstack(GET_THREAD());
1317 # endif
1318  install_sighandler(SIGSEGV, (sighandler_t)sigsegv);
1319 #endif
1320  }
1321 #ifdef SIGPIPE
1322  install_sighandler(SIGPIPE, SIG_IGN);
1323 #endif
1324 
1325 #if defined(SIGCLD)
1326  init_sigchld(SIGCLD);
1327 #elif defined(SIGCHLD)
1328  init_sigchld(SIGCHLD);
1329 #endif
1330 }
#define T_SYMBOL
Definition: ruby.h:494
static VALUE sig_list(void)
Definition: signal.c:1178
static void signal_exec(VALUE cmd, int safe, int sig)
Definition: signal.c:807
#define MESSAGE_FAULT_ADDRESS
Definition: signal.c:750
static void signal_enque(int sig)
Definition: signal.c:628
const char * ruby_signal_name(int no)
Definition: signal.c:254
void rb_interrupt(void)
Definition: eval.c:585
void ruby_thread_stack_overflow(rb_thread_t *th)
Definition: thread.c:2084
void rb_bug(const char *fmt,...)
Definition: error.c:327
#define FALSE
Definition: nkf.h:174
#define INT2NUM(x)
Definition: ruby.h:1288
static VALUE trap(int sig, sighandler_t func, VALUE command)
Definition: signal.c:1039
static struct @152 signal_buff
#define T_FIXNUM
Definition: ruby.h:489
VALUE cmd
Definition: vm_core.h:383
VALUE rb_id2str(ID id)
Definition: ripper.c:17157
rb_atomic_t ruby_atomic_exchange(rb_atomic_t *ptr, rb_atomic_t val)
Definition: signal.c:45
VALUE rb_eSignal
Definition: error.c:544
const char * signm
Definition: signal.c:73
#define NUM2INT(x)
Definition: ruby.h:630
#define GetProcPtr(obj, ptr)
Definition: vm_core.h:697
#define NUM2PIDT(v)
Definition: ruby.h:324
static int signal_ignored(int sig)
Definition: signal.c:613
#define SIGINFO_ARG
Definition: signal.c:505
static VALUE interrupt_init(int argc, VALUE *argv, VALUE self)
Definition: signal.c:330
#define Qtrue
Definition: ruby.h:426
static void rb_enable_interrupt(void)
Definition: signal.c:665
void rb_threadptr_signal_raise(rb_thread_t *th, int sig)
Definition: thread.c:2060
#define RUBY_NSIG
Definition: vm_core.h:51
#define rb_check_arity
Definition: intern.h:296
void rb_trap_exit(void)
Definition: signal.c:839
RETSIGTYPE ruby_sigaction_t(int)
Definition: signal.c:504
#define SYM2ID(x)
Definition: ruby.h:356
void rb_signal_exec(rb_thread_t *th, int sig)
Definition: signal.c:851
#define ruby_enable_coredump
Definition: signal.c:1235
int kill(int, int)
Definition: win32.c:4439
VALUE rb_iv_set(VALUE, const char *, VALUE)
Definition: variable.c:2609
VALUE rb_iv_get(VALUE, const char *)
Definition: variable.c:2601
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:1854
#define SIGKILL
Definition: win32.h:498
VALUE rb_eSecurityError
Definition: error.c:557
rb_atomic_t size
Definition: signal.c:490
void ruby_default_signal(int sig)
Definition: signal.c:340
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:1684
VALUE rb_check_to_integer(VALUE, const char *)
Definition: object.c:2666
#define sighandler_t
Definition: signal.c:496
static sighandler_t trap_handler(VALUE *cmd, int sig)
Definition: signal.c:942
#define OBJ_TAINTED(x)
Definition: ruby.h:1176
const char * rb_obj_classname(VALUE)
Definition: variable.c:406
#define NORETURN(x)
Definition: ruby.h:33
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
int ruby_disable_gc_stress
Definition: gc.c:650
static int reserved_signal_p(int signo)
Definition: signal.c:1073
#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:1393
#define EXEC_TAG()
Definition: eval_intern.h:168
#define val
int signo
Definition: signal.c:74
static RETSIGTYPE sighandler(int sig)
Definition: signal.c:635
VALUE rb_thread_current(void)
Definition: thread.c:2401
#define JUMP_TAG(st)
Definition: eval_intern.h:173
struct rb_vm_struct::@167 trap_list[RUBY_NSIG]
#define NIL_P(v)
Definition: ruby.h:438
Definition: signal.c:72
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:1190
static const struct signals siglist[]
rb_atomic_t cnt[RUBY_NSIG]
Definition: signal.c:489
void rb_threadptr_check_signal(rb_thread_t *mth)
Definition: thread.c:3815
#define TYPE(x)
Definition: ruby.h:505
int argc
Definition: ruby.c:131
#define rb_str_new2
Definition: intern.h:840
int err
Definition: win32.c:114
#define RB_UNUSED_VAR(x)
Definition: ruby.h:528
static sighandler_t default_handler(int sig)
Definition: signal.c:893
static VALUE sig_trap(int argc, VALUE *argv)
Definition: signal.c:1134
static int signm2signo(const char *nm)
Definition: signal.c:212
#define RSTRING_LEN(str)
Definition: ruby.h:841
void rb_define_module_function(VALUE module, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a module function for module.
Definition: class.c:1670
SSL_METHOD *(* func)(void)
Definition: ossl_ssl.c:113
int errno
void Init_signal(void)
Definition: signal.c:1276
VALUE rb_sprintf(const char *format,...)
Definition: sprintf.c:1250
VALUE rb_hash_new(void)
Definition: hash.c:298
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:1728
void rb_thread_execute_interrupts(VALUE th)
Definition: thread.c:2026
VALUE rb_eInterrupt
Definition: error.c:543
#define Qnil
Definition: ruby.h:427
unsigned int uintptr_t
Definition: win32.h:103
unsigned long VALUE
Definition: ruby.h:88
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
static void rb_disable_interrupt(void)
Definition: signal.c:655
#define FIX2INT(x)
Definition: ruby.h:632
void rb_bug_errno(const char *mesg, int errno_arg)
Definition: error.c:350
void rb_alias(VALUE, ID, ID)
Definition: vm_method.c:1243
#define rb_ary_new3
Definition: intern.h:91
#define TH_PUSH_TAG(th)
Definition: eval_intern.h:122
VALUE rb_call_super(int, const VALUE *)
Definition: vm_eval.c:274
VALUE rb_str_new_cstr(const char *)
Definition: string.c:560
int rb_sigaltstack_size(void)
#define NSIG
Definition: vm_core.h:48
void rb_sys_fail(const char *mesg)
Definition: error.c:1973
#define ATOMIC_INC(var)
Definition: ruby_atomic.h:128
#define IMMEDIATE_P(x)
Definition: ruby.h:352
int rb_get_next_signal(void)
Definition: signal.c:675
#define RSTRING_PTR(str)
Definition: ruby.h:845
VALUE rb_f_kill(int argc, VALUE *argv)
Definition: signal.c:384
rb_atomic_t ruby_atomic_compare_and_swap(rb_atomic_t *ptr, rb_atomic_t cmp, rb_atomic_t newval)
Definition: signal.c:53
#define CHECK_STACK_OVERFLOW()
Definition: signal.c:747
#define INT2FIX(i)
Definition: ruby.h:231
#define UNLIMITED_ARGUMENTS
Definition: intern.h:44
sighandler_t signal(int signum, sighandler_t handler)
unsigned long interrupt_mask
Definition: vm_core.h:586
VALUE rb_block_proc(void)
Definition: proc.c:641
void ruby_sig_finalize(void)
Definition: signal.c:1222
VALUE rb_check_string_type(VALUE)
Definition: string.c:1679
int rb_signal_buff_size(void)
Definition: signal.c:645
#define T_STRING
Definition: ruby.h:482
static VALUE esignal_init(int argc, VALUE *argv, VALUE self)
Definition: signal.c:269
VALUE rb_eval_cmd(VALUE, VALUE, int)
Definition: vm_eval.c:1463
#define SafeStringValue(v)
Definition: ruby.h:545
int rb_atomic_t
Definition: ruby_atomic.h:120
#define rb_safe_level()
Definition: tcltklib.c:95
void ruby_kill(rb_pid_t pid, int sig)
Definition: thread.c:5319
const char * name
Definition: nkf.c:208
static int trap_signm(VALUE vsig)
Definition: signal.c:1007
const char * rb_id2name(ID id)
Definition: ripper.c:17227
rb_jmpbuf_t buf
Definition: vm_core.h:491
#define StringValuePtr(v)
Definition: ruby.h:540
struct rb_vm_tag * tag
Definition: vm_core.h:593
#define killpg(pg, sig)
#define ruby_signal(sig, handler)
Definition: signal.c:598
struct rb_vm_tag * prev
Definition: vm_core.h:492
void rb_secure(int)
Definition: safe.c:88
VALUE rb_define_module(const char *name)
Definition: class.c:746
#define rb_intern(str)
#define SYMBOL_P(x)
Definition: ruby.h:354
#define NULL
Definition: _sdbm.c:103
#define Qundef
Definition: ruby.h:428
static rb_thread_t * GET_THREAD(void)
Definition: vm_core.h:924
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1488
VALUE rb_eArgError
Definition: error.c:549
static ID cmp
Definition: compar.c:16
void rb_threadptr_signal_exit(rb_thread_t *th)
Definition: thread.c:2070
char ** argv
Definition: ruby.c:132
#define SIGINT
Definition: win32.h:495
#define GET_VM()
Definition: vm_core.h:917