Ruby 2.1.5p273(2014-11-13revision48405)

- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

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
44 rb_atomic_t
45 ruby_atomic_exchange(rb_atomic_t *ptr, rb_atomic_t val)
46 {
47 rb_atomic_t old = *ptr;
48 *ptr = val;
49 return old;
50 }
51
52 rb_atomic_t
53 ruby_atomic_compare_and_swap(rb_atomic_t *ptr, rb_atomic_t cmp,
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
247 sig_signame(VALUE recv, VALUE signo)
248 {
249 const char *signame = signo2signm(NUM2INT(signo));
250 return rb_str_new_cstr(signame);
251 }
252
253 const char *
254 ruby_signal_name(int no)
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
269 esignal_init(int argc, VALUE *argv, VALUE self)
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
323 esignal_signo(VALUE self)
324 {
325 return rb_iv_get(self, "signo");
326 }
327
328 /* :nodoc: */
329 static VALUE
330 interrupt_init(int argc, VALUE *argv, VALUE self)
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
340 ruby_default_signal(int sig)
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
385 rb_f_kill(int argc, VALUE *argv)
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);
397 rb_check_arity(argc, 2, UNLIMITED_ARGUMENTS);
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 }
490 rb_thread_execute_interrupts(rb_thread_current());
491
492 return INT2FIX(i-1);
493 }
494
495 static struct {
496 rb_atomic_t cnt[RUBY_NSIG];
497 rb_atomic_t size;
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
517 rb_sigaltstack_size(void)
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
598 sighandler_t
599 posix_signal(int signum, sighandler_t handler)
600 {
601 return ruby_signal(signum, handler);
602 }
603
604 #else /* !POSIX_SIGNAL */
605 #define ruby_signal(sig,handler) (/* rb_trap_accept_nativethreads[(sig)] = 0,*/ signal((sig),(handler)))
606 #if 0 /* def HAVE_NATIVETHREAD */
607 static sighandler_t
608 ruby_nativethread_signal(int signum, sighandler_t handler)
609 {
610 sighandler_t old;
611
612 old = signal(signum, handler);
613 rb_trap_accept_nativethreads[signum] = 1;
614 return old;
615 }
616 #endif
617 #endif
618
619 static int
620 signal_ignored(int sig)
621 {
622 sighandler_t func;
623 #ifdef POSIX_SIGNAL
624 struct sigaction old;
625 (void)VALGRIND_MAKE_MEM_DEFINED(&old, sizeof(old));
626 if (sigaction(sig, NULL, &old) < 0) return FALSE;
627 func = old.sa_handler;
628 #else
629 sighandler_t old = signal(sig, SIG_DFL);
630 signal(sig, old);
631 func = old;
632 #endif
633 if (func == SIG_IGN) return 1;
634 return func == sighandler ? 0 : -1;
635 }
636
637 static void
638 signal_enque(int sig)
639 {
640 ATOMIC_INC(signal_buff.cnt[sig]);
641 ATOMIC_INC(signal_buff.size);
642 }
643
644 static RETSIGTYPE
645 sighandler(int sig)
646 {
647 signal_enque(sig);
648 rb_thread_wakeup_timer_thread();
649 #if !defined(BSD_SIGNAL) && !defined(POSIX_SIGNAL)
650 ruby_signal(sig, sighandler);
651 #endif
652 }
653
654 int
655 rb_signal_buff_size(void)
656 {
657 return signal_buff.size;
658 }
659
660 #if HAVE_PTHREAD_H
661 #include <pthread.h>
662 #endif
663
664 static void
665 rb_disable_interrupt(void)
666 {
667 #ifdef HAVE_PTHREAD_SIGMASK
668 sigset_t mask;
669 sigfillset(&mask);
670 pthread_sigmask(SIG_SETMASK, &mask, NULL);
671 #endif
672 }
673
674 static void
675 rb_enable_interrupt(void)
676 {
677 #ifdef HAVE_PTHREAD_SIGMASK
678 sigset_t mask;
679 sigemptyset(&mask);
680 pthread_sigmask(SIG_SETMASK, &mask, NULL);
681 #endif
682 }
683
684 int
685 rb_get_next_signal(void)
686 {
687 int i, sig = 0;
688
689 if (signal_buff.size != 0) {
690 for (i=1; i<RUBY_NSIG; i++) {
691 if (signal_buff.cnt[i] > 0) {
692 ATOMIC_DEC(signal_buff.cnt[i]);
693 ATOMIC_DEC(signal_buff.size);
694 sig = i;
695 break;
696 }
697 }
698 }
699 return sig;
700 }
701
702
703 #if defined(USE_SIGALTSTACK) || defined(_WIN32)
704 NORETURN(void ruby_thread_stack_overflow(rb_thread_t *th));
705 #if defined(HAVE_UCONTEXT_H) && defined __linux__ && (defined __i386__ || defined __x86_64__)
706 # define USE_UCONTEXT_REG 1
707 #endif
708 #ifdef USE_UCONTEXT_REG
709 static void
710 check_stack_overflow(const uintptr_t addr, const ucontext_t *ctx)
711 {
712 # if defined REG_RSP
713 const greg_t sp = ctx->uc_mcontext.gregs[REG_RSP];
714 # else
715 const greg_t sp = ctx->uc_mcontext.gregs[REG_ESP];
716 # endif
717 enum {pagesize = 4096};
718 const uintptr_t sp_page = (uintptr_t)sp / pagesize;
719 const uintptr_t fault_page = addr / pagesize;
720
721 /* SP in ucontext is not decremented yet when `push` failed, so
722 * the fault page can be the next. */
723 if (sp_page == fault_page || sp_page == fault_page + 1) {
724 rb_thread_t *th = ruby_current_thread;
725 if ((uintptr_t)th->tag->buf / pagesize == sp_page) {
726 /* drop the last tag if it is close to the fault,
727 * otherwise it can cause stack overflow again at the same
728 * place. */
729 th->tag = th->tag->prev;
730 }
731 ruby_thread_stack_overflow(th);
732 }
733 }
734 #else
735 static void
736 check_stack_overflow(const void *addr)
737 {
738 int ruby_stack_overflowed_p(const rb_thread_t *, const void *);
739 rb_thread_t *th = ruby_current_thread;
740 if (ruby_stack_overflowed_p(th, addr)) {
741 ruby_thread_stack_overflow(th);
742 }
743 }
744 #endif
745 #ifdef _WIN32
746 #define CHECK_STACK_OVERFLOW() check_stack_overflow(0)
747 #else
748 #define FAULT_ADDRESS info->si_addr
749 # ifdef USE_UCONTEXT_REG
750 # define CHECK_STACK_OVERFLOW() check_stack_overflow((uintptr_t)FAULT_ADDRESS, ctx)
751 #else
752 # define CHECK_STACK_OVERFLOW() check_stack_overflow(FAULT_ADDRESS)
753 #endif
754 #define MESSAGE_FAULT_ADDRESS " at %p", FAULT_ADDRESS
755 #endif
756 #else
757 #define CHECK_STACK_OVERFLOW() (void)0
758 #endif
759 #ifndef MESSAGE_FAULT_ADDRESS
760 #define MESSAGE_FAULT_ADDRESS
761 #endif
762
763 #ifdef SIGBUS
764 static RETSIGTYPE
765 sigbus(int sig SIGINFO_ARG)
766 {
767 /*
768 * Mac OS X makes KERN_PROTECTION_FAILURE when thread touch guard page.
769 * and it's delivered as SIGBUS instead of SIGSEGV to userland. It's crazy
770 * wrong IMHO. but anyway we have to care it. Sigh.
771 */
772 #if defined __APPLE__
773 CHECK_STACK_OVERFLOW();
774 #endif
775 rb_bug("Bus Error" MESSAGE_FAULT_ADDRESS);
776 }
777 #endif
778
779 #ifdef SIGSEGV
780 static void
781 ruby_abort(void)
782 {
783 #ifdef __sun
784 /* Solaris's abort() is async signal unsafe. Of course, it is not
785 * POSIX compliant.
786 */
787 raise(SIGABRT);
788 #else
789 abort();
790 #endif
791
792 }
793
794 static int segv_received = 0;
795 extern int ruby_disable_gc_stress;
796
797 static RETSIGTYPE
798 sigsegv(int sig SIGINFO_ARG)
799 {
800 if (segv_received) {
801 ssize_t RB_UNUSED_VAR(err);
802 char msg[] = "SEGV received in SEGV handler\n";
803
804 err = write(2, msg, sizeof(msg));
805 ruby_abort();
806 }
807
808 CHECK_STACK_OVERFLOW();
809
810 segv_received = 1;
811 ruby_disable_gc_stress = 1;
812 rb_bug("Segmentation fault" MESSAGE_FAULT_ADDRESS);
813 }
814 #endif
815
816 static void
817 signal_exec(VALUE cmd, int safe, int sig)
818 {
819 rb_thread_t *cur_th = GET_THREAD();
820 volatile unsigned long old_interrupt_mask = cur_th->interrupt_mask;
821 int state;
822
823 /*
824 * workaround the following race:
825 * 1. signal_enque queues signal for execution
826 * 2. user calls trap(sig, "IGNORE"), setting SIG_IGN
827 * 3. rb_signal_exec runs on queued signal
828 */
829 if (IMMEDIATE_P(cmd))
830 return;
831
832 cur_th->interrupt_mask |= TRAP_INTERRUPT_MASK;
833 TH_PUSH_TAG(cur_th);
834 if ((state = EXEC_TAG()) == 0) {
835 VALUE signum = INT2NUM(sig);
836 rb_eval_cmd(cmd, rb_ary_new3(1, signum), safe);
837 }
838 TH_POP_TAG();
839 cur_th = GET_THREAD();
840 cur_th->interrupt_mask = old_interrupt_mask;
841
842 if (state) {
843 /* XXX: should be replaced with rb_threadptr_pending_interrupt_enque() */
844 JUMP_TAG(state);
845 }
846 }
847
848 void
849 rb_trap_exit(void)
850 {
851 rb_vm_t *vm = GET_VM();
852 VALUE trap_exit = vm->trap_list[0].cmd;
853
854 if (trap_exit) {
855 vm->trap_list[0].cmd = 0;
856 signal_exec(trap_exit, vm->trap_list[0].safe, 0);
857 }
858 }
859
860 void
861 rb_signal_exec(rb_thread_t *th, int sig)
862 {
863 rb_vm_t *vm = GET_VM();
864 VALUE cmd = vm->trap_list[sig].cmd;
865 int safe = vm->trap_list[sig].safe;
866
867 if (cmd == 0) {
868 switch (sig) {
869 case SIGINT:
870 rb_interrupt();
871 break;
872 #ifdef SIGHUP
873 case SIGHUP:
874 #endif
875 #ifdef SIGQUIT
876 case SIGQUIT:
877 #endif
878 #ifdef SIGTERM
879 case SIGTERM:
880 #endif
881 #ifdef SIGALRM
882 case SIGALRM:
883 #endif
884 #ifdef SIGUSR1
885 case SIGUSR1:
886 #endif
887 #ifdef SIGUSR2
888 case SIGUSR2:
889 #endif
890 rb_threadptr_signal_raise(th, sig);
891 break;
892 }
893 }
894 else if (cmd == Qundef) {
895 rb_threadptr_signal_exit(th);
896 }
897 else {
898 signal_exec(cmd, safe, sig);
899 }
900 }
901
902 static sighandler_t
903 default_handler(int sig)
904 {
905 sighandler_t func;
906 switch (sig) {
907 case SIGINT:
908 #ifdef SIGHUP
909 case SIGHUP:
910 #endif
911 #ifdef SIGQUIT
912 case SIGQUIT:
913 #endif
914 #ifdef SIGTERM
915 case SIGTERM:
916 #endif
917 #ifdef SIGALRM
918 case SIGALRM:
919 #endif
920 #ifdef SIGUSR1
921 case SIGUSR1:
922 #endif
923 #ifdef SIGUSR2
924 case SIGUSR2:
925 #endif
926 func = sighandler;
927 break;
928 #ifdef SIGBUS
929 case SIGBUS:
930 func = (sighandler_t)sigbus;
931 break;
932 #endif
933 #ifdef SIGSEGV
934 case SIGSEGV:
935 func = (sighandler_t)sigsegv;
936 break;
937 #endif
938 #ifdef SIGPIPE
939 case SIGPIPE:
940 func = SIG_IGN;
941 break;
942 #endif
943 default:
944 func = SIG_DFL;
945 break;
946 }
947
948 return func;
949 }
950
951 static sighandler_t
952 trap_handler(VALUE *cmd, int sig)
953 {
954 sighandler_t func = sighandler;
955 VALUE command;
956
957 if (NIL_P(*cmd)) {
958 func = SIG_IGN;
959 }
960 else {
961 command = rb_check_string_type(*cmd);
962 if (NIL_P(command) && SYMBOL_P(*cmd)) {
963 command = rb_id2str(SYM2ID(*cmd));
964 if (!command) rb_raise(rb_eArgError, "bad handler");
965 }
966 if (!NIL_P(command)) {
967 SafeStringValue(command); /* taint check */
968 *cmd = command;
969 switch (RSTRING_LEN(command)) {
970 case 0:
971 goto sig_ign;
972 break;
973 case 14:
974 if (strncmp(RSTRING_PTR(command), "SYSTEM_DEFAULT", 14) == 0) {
975 func = SIG_DFL;
976 *cmd = 0;
977 }
978 break;
979 case 7:
980 if (strncmp(RSTRING_PTR(command), "SIG_IGN", 7) == 0) {
981 sig_ign:
982 func = SIG_IGN;
983 *cmd = Qtrue;
984 }
985 else if (strncmp(RSTRING_PTR(command), "SIG_DFL", 7) == 0) {
986 sig_dfl:
987 func = default_handler(sig);
988 *cmd = 0;
989 }
990 else if (strncmp(RSTRING_PTR(command), "DEFAULT", 7) == 0) {
991 goto sig_dfl;
992 }
993 break;
994 case 6:
995 if (strncmp(RSTRING_PTR(command), "IGNORE", 6) == 0) {
996 goto sig_ign;
997 }
998 break;
999 case 4:
1000 if (strncmp(RSTRING_PTR(command), "EXIT", 4) == 0) {
1001 *cmd = Qundef;
1002 }
1003 break;
1004 }
1005 }
1006 else {
1007 rb_proc_t *proc;
1008 GetProcPtr(*cmd, proc);
1009 (void)proc;
1010 }
1011 }
1012
1013 return func;
1014 }
1015
1016 static int
1017 trap_signm(VALUE vsig)
1018 {
1019 int sig = -1;
1020 const char *s;
1021
1022 switch (TYPE(vsig)) {
1023 case T_FIXNUM:
1024 sig = FIX2INT(vsig);
1025 if (sig < 0 || sig >= NSIG) {
1026 rb_raise(rb_eArgError, "invalid signal number (%d)", sig);
1027 }
1028 break;
1029
1030 case T_SYMBOL:
1031 s = rb_id2name(SYM2ID(vsig));
1032 if (!s) rb_raise(rb_eArgError, "bad signal");
1033 goto str_signal;
1034
1035 default:
1036 s = StringValuePtr(vsig);
1037
1038 str_signal:
1039 if (strncmp("SIG", s, 3) == 0)
1040 s += 3;
1041 sig = signm2signo(s);
1042 if (sig == 0 && strcmp(s, "EXIT") != 0)
1043 rb_raise(rb_eArgError, "unsupported signal SIG%s", s);
1044 }
1045 return sig;
1046 }
1047
1048 static VALUE
1049 trap(int sig, sighandler_t func, VALUE command)
1050 {
1051 sighandler_t oldfunc;
1052 VALUE oldcmd;
1053 rb_vm_t *vm = GET_VM();
1054
1055 /*
1056 * Be careful. ruby_signal() and trap_list[sig].cmd must be changed
1057 * atomically. In current implementation, we only need to don't call
1058 * RUBY_VM_CHECK_INTS().
1059 */
1060 oldfunc = ruby_signal(sig, func);
1061 oldcmd = vm->trap_list[sig].cmd;
1062 switch (oldcmd) {
1063 case 0:
1064 case Qtrue:
1065 if (oldfunc == SIG_IGN) oldcmd = rb_str_new2("IGNORE");
1066 else if (oldfunc == sighandler) oldcmd = rb_str_new2("DEFAULT");
1067 else oldcmd = Qnil;
1068 break;
1069 case Qnil:
1070 break;
1071 case Qundef:
1072 oldcmd = rb_str_new2("EXIT");
1073 break;
1074 }
1075
1076 vm->trap_list[sig].cmd = command;
1077 vm->trap_list[sig].safe = rb_safe_level();
1078
1079 return oldcmd;
1080 }
1081
1082 static int
1083 reserved_signal_p(int signo)
1084 {
1085 /* Synchronous signal can't deliver to main thread */
1086 #ifdef SIGSEGV
1087 if (signo == SIGSEGV)
1088 return 1;
1089 #endif
1090 #ifdef SIGBUS
1091 if (signo == SIGBUS)
1092 return 1;
1093 #endif
1094 #ifdef SIGILL
1095 if (signo == SIGILL)
1096 return 1;
1097 #endif
1098 #ifdef SIGFPE
1099 if (signo == SIGFPE)
1100 return 1;
1101 #endif
1102
1103 /* used ubf internal see thread_pthread.c. */
1104 #ifdef SIGVTALRM
1105 if (signo == SIGVTALRM)
1106 return 1;
1107 #endif
1108
1109 return 0;
1110 }
1111
1112 /*
1113 * call-seq:
1114 * Signal.trap( signal, command ) -> obj
1115 * Signal.trap( signal ) {| | block } -> obj
1116 *
1117 * Specifies the handling of signals. The first parameter is a signal
1118 * name (a string such as ``SIGALRM'', ``SIGUSR1'', and so on) or a
1119 * signal number. The characters ``SIG'' may be omitted from the
1120 * signal name. The command or block specifies code to be run when the
1121 * signal is raised.
1122 * If the command is the string ``IGNORE'' or ``SIG_IGN'', the signal
1123 * will be ignored.
1124 * If the command is ``DEFAULT'' or ``SIG_DFL'', the Ruby's default handler
1125 * will be invoked.
1126 * If the command is ``EXIT'', the script will be terminated by the signal.
1127 * If the command is ``SYSTEM_DEFAULT'', the operating system's default
1128 * handler will be invoked.
1129 * Otherwise, the given command or block will be run.
1130 * The special signal name ``EXIT'' or signal number zero will be
1131 * invoked just prior to program termination.
1132 * trap returns the previous handler for the given signal.
1133 *
1134 * Signal.trap(0, proc { puts "Terminating: #{$$}" })
1135 * Signal.trap("CLD") { puts "Child died" }
1136 * fork && Process.wait
1137 *
1138 * produces:
1139 * Terminating: 27461
1140 * Child died
1141 * Terminating: 27460
1142 */
1143 static VALUE
1144 sig_trap(int argc, VALUE *argv)
1145 {
1146 int sig;
1147 sighandler_t func;
1148 VALUE cmd;
1149
1150 rb_secure(2);
1151 rb_check_arity(argc, 1, 2);
1152
1153 sig = trap_signm(argv[0]);
1154 if (reserved_signal_p(sig)) {
1155 const char *name = signo2signm(sig);
1156 if (name)
1157 rb_raise(rb_eArgError, "can't trap reserved signal: SIG%s", name);
1158 else
1159 rb_raise(rb_eArgError, "can't trap reserved signal: %d", sig);
1160 }
1161
1162 if (argc == 1) {
1163 cmd = rb_block_proc();
1164 func = sighandler;
1165 }
1166 else {
1167 cmd = argv[1];
1168 func = trap_handler(&cmd, sig);
1169 }
1170
1171 if (OBJ_TAINTED(cmd)) {
1172 rb_raise(rb_eSecurityError, "Insecure: tainted signal trap");
1173 }
1174
1175 return trap(sig, func, cmd);
1176 }
1177
1178 /*
1179 * call-seq:
1180 * Signal.list -> a_hash
1181 *
1182 * Returns a list of signal names mapped to the corresponding
1183 * underlying signal numbers.
1184 *
1185 * 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}
1186 */
1187 static VALUE
1188 sig_list(void)
1189 {
1190 VALUE h = rb_hash_new();
1191 const struct signals *sigs;
1192
1193 for (sigs = siglist; sigs->signm; sigs++) {
1194 rb_hash_aset(h, rb_str_new2(sigs->signm), INT2FIX(sigs->signo));
1195 }
1196 return h;
1197 }
1198
1199 static void
1200 install_sighandler(int signum, sighandler_t handler)
1201 {
1202 sighandler_t old;
1203
1204 /* At this time, there is no subthread. Then sigmask guarantee atomics. */
1205 rb_disable_interrupt();
1206 old = ruby_signal(signum, handler);
1207 /* signal handler should be inherited during exec. */
1208 if (old != SIG_DFL) {
1209 ruby_signal(signum, old);
1210 }
1211 rb_enable_interrupt();
1212 }
1213
1214 #if defined(SIGCLD) || defined(SIGCHLD)
1215 static void
1216 init_sigchld(int sig)
1217 {
1218 sighandler_t oldfunc;
1219
1220 rb_disable_interrupt();
1221 oldfunc = ruby_signal(sig, SIG_DFL);
1222 if (oldfunc != SIG_DFL && oldfunc != SIG_IGN) {
1223 ruby_signal(sig, oldfunc);
1224 } else {
1225 GET_VM()->trap_list[sig].cmd = 0;
1226 }
1227 rb_enable_interrupt();
1228 }
1229 #endif
1230
1231 void
1232 ruby_sig_finalize(void)
1233 {
1234 sighandler_t oldfunc;
1235
1236 oldfunc = ruby_signal(SIGINT, SIG_IGN);
1237 if (oldfunc == sighandler) {
1238 ruby_signal(SIGINT, SIG_DFL);
1239 }
1240 }
1241
1242
1243 int ruby_enable_coredump = 0;
1244 #ifndef RUBY_DEBUG_ENV
1245 #define ruby_enable_coredump 0
1246 #endif
1247
1248 /*
1249 * Many operating systems allow signals to be sent to running
1250 * processes. Some signals have a defined effect on the process, while
1251 * others may be trapped at the code level and acted upon. For
1252 * example, your process may trap the USR1 signal and use it to toggle
1253 * debugging, and may use TERM to initiate a controlled shutdown.
1254 *
1255 * pid = fork do
1256 * Signal.trap("USR1") do
1257 * $debug = !$debug
1258 * puts "Debug now: #$debug"
1259 * end
1260 * Signal.trap("TERM") do
1261 * puts "Terminating..."
1262 * shutdown()
1263 * end
1264 * # . . . do some work . . .
1265 * end
1266 *
1267 * Process.detach(pid)
1268 *
1269 * # Controlling program:
1270 * Process.kill("USR1", pid)
1271 * # ...
1272 * Process.kill("USR1", pid)
1273 * # ...
1274 * Process.kill("TERM", pid)
1275 *
1276 * produces:
1277 * Debug now: true
1278 * Debug now: false
1279 * Terminating...
1280 *
1281 * The list of available signal names and their interpretation is
1282 * system dependent. Signal delivery semantics may also vary between
1283 * systems; in particular signal delivery may not always be reliable.
1284 */
1285 void
1286 Init_signal(void)
1287 {
1288 VALUE mSignal = rb_define_module("Signal");
1289
1290 rb_define_global_function("trap", sig_trap, -1);
1291 rb_define_module_function(mSignal, "trap", sig_trap, -1);
1292 rb_define_module_function(mSignal, "list", sig_list, 0);
1293 rb_define_module_function(mSignal, "signame", sig_signame, 1);
1294
1295 rb_define_method(rb_eSignal, "initialize", esignal_init, -1);
1296 rb_define_method(rb_eSignal, "signo", esignal_signo, 0);
1297 rb_alias(rb_eSignal, rb_intern("signm"), rb_intern("message"));
1298 rb_define_method(rb_eInterrupt, "initialize", interrupt_init, -1);
1299
1300 install_sighandler(SIGINT, sighandler);
1301 #ifdef SIGHUP
1302 install_sighandler(SIGHUP, sighandler);
1303 #endif
1304 #ifdef SIGQUIT
1305 install_sighandler(SIGQUIT, sighandler);
1306 #endif
1307 #ifdef SIGTERM
1308 install_sighandler(SIGTERM, sighandler);
1309 #endif
1310 #ifdef SIGALRM
1311 install_sighandler(SIGALRM, sighandler);
1312 #endif
1313 #ifdef SIGUSR1
1314 install_sighandler(SIGUSR1, sighandler);
1315 #endif
1316 #ifdef SIGUSR2
1317 install_sighandler(SIGUSR2, sighandler);
1318 #endif
1319
1320 if (!ruby_enable_coredump) {
1321 #ifdef SIGBUS
1322 install_sighandler(SIGBUS, (sighandler_t)sigbus);
1323 #endif
1324 #ifdef SIGSEGV
1325 # ifdef USE_SIGALTSTACK
1326 rb_register_sigaltstack(GET_THREAD());
1327 # endif
1328 install_sighandler(SIGSEGV, (sighandler_t)sigsegv);
1329 #endif
1330 }
1331 #ifdef SIGPIPE
1332 install_sighandler(SIGPIPE, SIG_IGN);
1333 #endif
1334
1335 #if defined(SIGCLD)
1336 init_sigchld(SIGCLD);
1337 #elif defined(SIGCHLD)
1338 init_sigchld(SIGCHLD);
1339 #endif
1340 }
T_SYMBOL
#define T_SYMBOL
Definition: ruby.h:494
sig_list
static VALUE sig_list(void)
Definition: signal.c:1188
signal_exec
static void signal_exec(VALUE cmd, int safe, int sig)
Definition: signal.c:817
MESSAGE_FAULT_ADDRESS
#define MESSAGE_FAULT_ADDRESS
Definition: signal.c:760
signal_enque
static void signal_enque(int sig)
Definition: signal.c:638
ruby_signal_name
const char * ruby_signal_name(int no)
Definition: signal.c:254
rb_interrupt
void rb_interrupt(void)
Definition: eval.c:585
ruby_thread_stack_overflow
void ruby_thread_stack_overflow(rb_thread_t *th)
Definition: thread.c:2084
rb_bug
void rb_bug(const char *fmt,...)
Definition: error.c:327
FALSE
#define FALSE
Definition: nkf.h:174
INT2NUM
#define INT2NUM(x)
Definition: ruby.h:1288
trap
static VALUE trap(int sig, sighandler_t func, VALUE command)
Definition: signal.c:1049
signal_buff
static struct @152 signal_buff
T_FIXNUM
#define T_FIXNUM
Definition: ruby.h:489
rb_vm_struct::cmd
VALUE cmd
Definition: vm_core.h:383
rb_id2str
VALUE rb_id2str(ID id)
Definition: ripper.c:17160
ruby_atomic_exchange
rb_atomic_t ruby_atomic_exchange(rb_atomic_t *ptr, rb_atomic_t val)
Definition: signal.c:45
rb_eSignal
VALUE rb_eSignal
Definition: error.c:544
signals::signm
const char * signm
Definition: signal.c:73
NUM2INT
#define NUM2INT(x)
Definition: ruby.h:630
GetProcPtr
#define GetProcPtr(obj, ptr)
Definition: vm_core.h:697
ruby.h
NUM2PIDT
#define NUM2PIDT(v)
Definition: ruby.h:324
signal_ignored
static int signal_ignored(int sig)
Definition: signal.c:620
SIGINFO_ARG
#define SIGINFO_ARG
Definition: signal.c:512
interrupt_init
static VALUE interrupt_init(int argc, VALUE *argv, VALUE self)
Definition: signal.c:330
Qtrue
#define Qtrue
Definition: ruby.h:426
rb_enable_interrupt
static void rb_enable_interrupt(void)
Definition: signal.c:675
eval_intern.h
rb_threadptr_signal_raise
void rb_threadptr_signal_raise(rb_thread_t *th, int sig)
Definition: thread.c:2060
RUBY_NSIG
#define RUBY_NSIG
Definition: vm_core.h:51
rb_check_arity
#define rb_check_arity
Definition: intern.h:296
rb_trap_exit
void rb_trap_exit(void)
Definition: signal.c:849
ruby_sigaction_t
RETSIGTYPE ruby_sigaction_t(int)
Definition: signal.c:511
SYM2ID
#define SYM2ID(x)
Definition: ruby.h:356
rb_signal_exec
void rb_signal_exec(rb_thread_t *th, int sig)
Definition: signal.c:861
ruby_enable_coredump
#define ruby_enable_coredump
Definition: signal.c:1245
kill
int kill(int, int)
Definition: win32.c:4439
rb_iv_set
VALUE rb_iv_set(VALUE, const char *, VALUE)
Definition: variable.c:2609
rb_iv_get
VALUE rb_iv_get(VALUE, const char *)
Definition: variable.c:2601
rb_raise
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:1857
SIGKILL
#define SIGKILL
Definition: win32.h:498
rb_eSecurityError
VALUE rb_eSecurityError
Definition: error.c:557
size
rb_atomic_t size
Definition: signal.c:497
ruby_default_signal
void ruby_default_signal(int sig)
Definition: signal.c:340
esignal_signo
static VALUE esignal_signo(VALUE self)
Definition: signal.c:323
rb_define_global_function
void rb_define_global_function(const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a global function.
Definition: class.c:1684
rb_thread_struct
Definition: vm_core.h:524
rb_check_to_integer
VALUE rb_check_to_integer(VALUE, const char *)
Definition: object.c:2665
sighandler_t
#define sighandler_t
Definition: signal.c:503
trap_handler
static sighandler_t trap_handler(VALUE *cmd, int sig)
Definition: signal.c:952
OBJ_TAINTED
#define OBJ_TAINTED(x)
Definition: ruby.h:1176
rb_obj_classname
const char * rb_obj_classname(VALUE)
Definition: variable.c:406
NORETURN
#define NORETURN(x)
Definition: ruby.h:33
sig_signame
static VALUE sig_signame(VALUE recv, VALUE signo)
Definition: signal.c:247
posix_signal
sighandler_t posix_signal(int signum, sighandler_t handler)
Definition: missing-pips.c:43
TH_POP_TAG
#define TH_POP_TAG()
Definition: eval_intern.h:128
ruby_disable_gc_stress
int ruby_disable_gc_stress
Definition: gc.c:650
reserved_signal_p
static int reserved_signal_p(int signo)
Definition: signal.c:1083
ATOMIC_DEC
#define ATOMIC_DEC(var)
Definition: ruby_atomic.h:129
rb_thread_wakeup_timer_thread
void rb_thread_wakeup_timer_thread(void)
rb_hash_aset
VALUE rb_hash_aset(VALUE hash, VALUE key, VALUE val)
Definition: hash.c:1393
EXEC_TAG
#define EXEC_TAG()
Definition: eval_intern.h:168
ruby_atomic.h
val
#define val
signals::signo
int signo
Definition: signal.c:74
sighandler
static RETSIGTYPE sighandler(int sig)
Definition: signal.c:645
rb_thread_current
VALUE rb_thread_current(void)
Definition: thread.c:2401
JUMP_TAG
#define JUMP_TAG(st)
Definition: eval_intern.h:173
rb_vm_struct::trap_list
struct rb_vm_struct::@167 trap_list[RUBY_NSIG]
NIL_P
#define NIL_P(v)
Definition: ruby.h:438
signals
Definition: signal.c:72
pthread_sigmask
int pthread_sigmask(int how, const sigset_t *set, sigset_t *oset)
Definition: missing-pips.c:22
msg
static char msg[50]
Definition: strerror.c:8
install_sighandler
static void install_sighandler(int signum, sighandler_t handler)
Definition: signal.c:1200
siglist
static const struct signals siglist[]
unistd.h
cnt
rb_atomic_t cnt[RUBY_NSIG]
Definition: signal.c:496
signal.h
rb_threadptr_check_signal
void rb_threadptr_check_signal(rb_thread_t *mth)
Definition: thread.c:3815
TYPE
#define TYPE(x)
Definition: ruby.h:505
argc
int argc
Definition: ruby.c:131
rb_str_new2
#define rb_str_new2
Definition: intern.h:840
err
int err
Definition: win32.c:114
RB_UNUSED_VAR
#define RB_UNUSED_VAR(x)
Definition: ruby.h:528
default_handler
static sighandler_t default_handler(int sig)
Definition: signal.c:903
sig_trap
static VALUE sig_trap(int argc, VALUE *argv)
Definition: signal.c:1144
rb_vm_struct::safe
int safe
Definition: vm_core.h:384
signm2signo
static int signm2signo(const char *nm)
Definition: signal.c:212
RSTRING_LEN
#define RSTRING_LEN(str)
Definition: ruby.h:841
rb_define_module_function
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
func
SSL_METHOD *(* func)(void)
Definition: ossl_ssl.c:113
errno
int errno
Init_signal
void Init_signal(void)
Definition: signal.c:1286
rb_sprintf
VALUE rb_sprintf(const char *format,...)
Definition: sprintf.c:1250
rb_proc_t
Definition: vm_core.h:700
rb_hash_new
VALUE rb_hash_new(void)
Definition: hash.c:298
rb_scan_args
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:1728
rb_thread_execute_interrupts
void rb_thread_execute_interrupts(VALUE th)
Definition: thread.c:2026
internal.h
rb_eInterrupt
VALUE rb_eInterrupt
Definition: error.c:543
Qnil
#define Qnil
Definition: ruby.h:427
uintptr_t
unsigned int uintptr_t
Definition: win32.h:103
vm_core.h
VALUE
unsigned long VALUE
Definition: ruby.h:88
signo2signm
static const char * signo2signm(int no)
Definition: signal.c:223
ruby_current_thread
rb_thread_t * ruby_current_thread
Definition: vm.c:104
VALGRIND_MAKE_MEM_DEFINED
#define VALGRIND_MAKE_MEM_DEFINED(p, n)
Definition: signal.c:35
rb_disable_interrupt
static void rb_disable_interrupt(void)
Definition: signal.c:665
FIX2INT
#define FIX2INT(x)
Definition: ruby.h:632
rb_bug_errno
void rb_bug_errno(const char *mesg, int errno_arg)
Definition: error.c:350
rb_alias
void rb_alias(VALUE, ID, ID)
Definition: vm_method.c:1244
rb_ary_new3
#define rb_ary_new3
Definition: intern.h:91
TH_PUSH_TAG
#define TH_PUSH_TAG(th)
Definition: eval_intern.h:122
rb_call_super
VALUE rb_call_super(int, const VALUE *)
Definition: vm_eval.c:274
rb_str_new_cstr
VALUE rb_str_new_cstr(const char *)
Definition: string.c:560
rb_sigaltstack_size
int rb_sigaltstack_size(void)
NSIG
#define NSIG
Definition: vm_core.h:48
rb_sys_fail
void rb_sys_fail(const char *mesg)
Definition: error.c:1976
ATOMIC_INC
#define ATOMIC_INC(var)
Definition: ruby_atomic.h:128
IMMEDIATE_P
#define IMMEDIATE_P(x)
Definition: ruby.h:352
rb_get_next_signal
int rb_get_next_signal(void)
Definition: signal.c:685
RSTRING_PTR
#define RSTRING_PTR(str)
Definition: ruby.h:845
rb_f_kill
VALUE rb_f_kill(int argc, VALUE *argv)
Definition: signal.c:385
ruby_atomic_compare_and_swap
rb_atomic_t ruby_atomic_compare_and_swap(rb_atomic_t *ptr, rb_atomic_t cmp, rb_atomic_t newval)
Definition: signal.c:53
CHECK_STACK_OVERFLOW
#define CHECK_STACK_OVERFLOW()
Definition: signal.c:757
INT2FIX
#define INT2FIX(i)
Definition: ruby.h:231
UNLIMITED_ARGUMENTS
#define UNLIMITED_ARGUMENTS
Definition: intern.h:44
signal
sighandler_t signal(int signum, sighandler_t handler)
rb_thread_struct::interrupt_mask
unsigned long interrupt_mask
Definition: vm_core.h:586
rb_block_proc
VALUE rb_block_proc(void)
Definition: proc.c:620
TRAP_INTERRUPT_MASK
Definition: vm_core.h:956
ruby_sig_finalize
void ruby_sig_finalize(void)
Definition: signal.c:1232
rb_check_string_type
VALUE rb_check_string_type(VALUE)
Definition: string.c:1679
rb_signal_buff_size
int rb_signal_buff_size(void)
Definition: signal.c:655
T_STRING
#define T_STRING
Definition: ruby.h:482
esignal_init
static VALUE esignal_init(int argc, VALUE *argv, VALUE self)
Definition: signal.c:269
rb_eval_cmd
VALUE rb_eval_cmd(VALUE, VALUE, int)
Definition: vm_eval.c:1464
SafeStringValue
#define SafeStringValue(v)
Definition: ruby.h:545
rb_atomic_t
int rb_atomic_t
Definition: ruby_atomic.h:120
rb_safe_level
#define rb_safe_level()
Definition: tcltklib.c:95
ruby_kill
void ruby_kill(rb_pid_t pid, int sig)
Definition: thread.c:5319
name
const char * name
Definition: nkf.c:208
rb_vm_struct
Definition: vm_core.h:348
trap_signm
static int trap_signm(VALUE vsig)
Definition: signal.c:1017
rb_id2name
const char * rb_id2name(ID id)
Definition: ripper.c:17230
rb_vm_tag::buf
rb_jmpbuf_t buf
Definition: vm_core.h:491
StringValuePtr
#define StringValuePtr(v)
Definition: ruby.h:540
rb_thread_struct::tag
struct rb_vm_tag * tag
Definition: vm_core.h:593
killpg
#define killpg(pg, sig)
ruby_signal
#define ruby_signal(sig, handler)
Definition: signal.c:605
rb_vm_tag::prev
struct rb_vm_tag * prev
Definition: vm_core.h:492
rb_secure
void rb_secure(int)
Definition: safe.c:88
rb_define_module
VALUE rb_define_module(const char *name)
Definition: class.c:746
rb_intern
#define rb_intern(str)
SYMBOL_P
#define SYMBOL_P(x)
Definition: ruby.h:354
NULL
#define NULL
Definition: _sdbm.c:103
Qundef
#define Qundef
Definition: ruby.h:428
GET_THREAD
static rb_thread_t * GET_THREAD(void)
Definition: vm_core.h:927
rb_define_method
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1488
rb_eArgError
VALUE rb_eArgError
Definition: error.c:549
cmp
static ID cmp
Definition: compar.c:16
rb_threadptr_signal_exit
void rb_threadptr_signal_exit(rb_thread_t *th)
Definition: thread.c:2070
argv
char ** argv
Definition: ruby.c:132
SIGINT
#define SIGINT
Definition: win32.h:495
GET_VM
#define GET_VM()
Definition: vm_core.h:920