1 /**********************************************************************
6 created at: Tue Dec 20 10:13:44 JST 1994
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
12 **********************************************************************/
14 #include "ruby/internal/config.h"
28 #ifdef HAVE_UCONTEXT_H
29 # include <ucontext.h>
36 #include "debug_counter.h"
37 #include "eval_intern.h"
39 #include "internal/eval.h"
40 #include "internal/sanitizers.h"
41 #include "internal/signal.h"
42 #include "internal/string.h"
43 #include "internal/thread.h"
44 #include "ruby_atomic.h"
46 #include "ractor_core.h"
48 #ifdef NEED_RUBY_ATOMIC_OPS
50 ruby_atomic_exchange(rb_atomic_t
*ptr
, rb_atomic_t val
)
52 rb_atomic_t old
= *ptr
;
58 ruby_atomic_compare_and_swap(rb_atomic_t
*ptr
, rb_atomic_t cmp
,
61 rb_atomic_t old
= *ptr
;
69 #define FOREACH_SIGNAL(sig, offset) \
70 for (sig = siglist + (offset); sig < siglist + numberof(siglist); ++sig)
71 enum { LONGEST_SIGNAME
= 7 }; /* MIGRATE and RETRACT */
72 static const struct signals
{
73 char signm
[LONGEST_SIGNAME
+ 1];
136 {"CHLD", RUBY_SIGCHLD
},
137 {"CLD", RUBY_SIGCHLD
},
155 {"VTALRM", SIGVTALRM
},
182 {"DANGER", SIGDANGER
},
185 {"MIGRATE", SIGMIGRATE
},
194 {"RETRACT", SIGRETRACT
},
204 static const char signame_prefix
[] = "SIG";
205 static const int signame_prefix_len
= 3;
208 signm2signo(VALUE
*sig_ptr
, int negative
, int exit
, int *prefix_ptr
)
210 const struct signals
*sigs
;
211 VALUE vsig
= *sig_ptr
;
216 if (RB_SYMBOL_P(vsig
)) {
217 *sig_ptr
= vsig
= rb_sym2str(vsig
);
219 else if (!RB_TYPE_P(vsig
, T_STRING
)) {
220 VALUE str
= rb_check_string_type(vsig
);
222 rb_raise(rb_eArgError
, "bad signal type %s",
223 rb_obj_classname(vsig
));
225 *sig_ptr
= vsig
= str
;
228 rb_must_asciicompat(vsig
);
229 RSTRING_GETMEM(vsig
, nm
, len
);
230 if (memchr(nm
, '\0', len
)) {
231 rb_raise(rb_eArgError
, "signal name with null byte");
234 if (len
> 0 && nm
[0] == '-') {
236 rb_raise(rb_eArgError
, "negative signal name: % "PRIsVALUE
, vsig
);
242 if (len
>= prefix
+ signame_prefix_len
) {
243 if (memcmp(nm
+ prefix
, signame_prefix
, signame_prefix_len
) == 0)
244 prefix
+= signame_prefix_len
;
246 if (len
<= (long)prefix
) {
250 if (prefix_ptr
) *prefix_ptr
= prefix
;
251 nmlen
= len
- prefix
;
253 if (nmlen
> LONGEST_SIGNAME
) goto unsupported
;
254 FOREACH_SIGNAL(sigs
, !exit
) {
255 if (memcmp(sigs
->signm
, nm
, nmlen
) == 0 &&
256 sigs
->signm
[nmlen
] == '\0') {
257 return negative
? -sigs
->signo
: sigs
->signo
;
262 if (prefix
== signame_prefix_len
) {
265 else if (prefix
> signame_prefix_len
) {
266 prefix
-= signame_prefix_len
;
268 vsig
= rb_str_subseq(vsig
, prefix
, len
);
273 vsig
= rb_str_subseq(vsig
, prefix
, len
);
274 prefix
= signame_prefix_len
;
276 rb_raise(rb_eArgError
, "unsupported signal `%.*s%"PRIsVALUE
"'",
277 prefix
, signame_prefix
, vsig
);
278 UNREACHABLE_RETURN(0);
284 const struct signals
*sigs
;
286 FOREACH_SIGNAL(sigs
, 0) {
287 if (sigs
->signo
== no
)
295 * Signal.signame(signo) -> string or nil
297 * Convert signal number to signal name.
298 * Returns +nil+ if the signo is an invalid signal number.
300 * Signal.trap("INT") { |signo| puts Signal.signame(signo) }
301 * Process.kill("INT", 0)
308 sig_signame(VALUE recv
, VALUE signo
)
310 const char *signame
= signo2signm(NUM2INT(signo
));
311 if (!signame
) return Qnil
;
312 return rb_str_new_cstr(signame
);
316 ruby_signal_name(int no
)
318 return signo2signm(no
);
322 rb_signo2signm(int signo
)
324 const char *const signm
= signo2signm(signo
);
326 return rb_sprintf("SIG%s", signm
);
329 return rb_sprintf("SIG%u", signo
);
335 * SignalException.new(sig_name) -> signal_exception
336 * SignalException.new(sig_number [, name]) -> signal_exception
338 * Construct a new SignalException object. +sig_name+ should be a known
343 esignal_init(int argc
, VALUE
*argv
, VALUE self
)
350 sig
= rb_check_to_integer(argv
[0], "to_int");
351 if (!NIL_P(sig
)) argnum
= 2;
354 rb_check_arity(argc
, 1, argnum
);
356 signo
= NUM2INT(sig
);
357 if (signo
< 0 || signo
> NSIG
) {
358 rb_raise(rb_eArgError
, "invalid signal number (%d)", signo
);
364 sig
= rb_signo2signm(signo
);
369 signo
= signm2signo(&sig
, FALSE
, FALSE
, &prefix
);
370 if (prefix
!= signame_prefix_len
) {
371 sig
= rb_str_append(rb_str_new_cstr("SIG"), sig
);
374 rb_call_super(1, &sig
);
375 rb_ivar_set(self
, id_signo
, INT2NUM(signo
));
382 * signal_exception.signo -> num
384 * Returns a signal number.
388 esignal_signo(VALUE self
)
390 return rb_ivar_get(self
, id_signo
);
395 interrupt_init(int argc
, VALUE
*argv
, VALUE self
)
399 args
[0] = INT2FIX(SIGINT
);
400 args
[1] = rb_check_arity(argc
, 0, 1) ? argv
[0] : Qnil
;
401 return rb_call_super(2, args
);
404 void rb_malloc_info_show_results(void); /* gc.c */
407 ruby_default_signal(int sig
)
409 #if USE_DEBUG_COUNTER
410 rb_debug_counter_show_results("killed by signal.");
412 rb_malloc_info_show_results();
414 signal(sig
, SIG_DFL
);
418 static void sighandler(int sig
);
419 static int signal_ignored(int sig
);
420 static void signal_enque(int sig
);
423 rb_f_kill(int argc
, const VALUE
*argv
)
426 #define killpg(pg, sig) kill(-(pg), (sig))
432 rb_check_arity(argc
, 2, UNLIMITED_ARGUMENTS
);
434 if (FIXNUM_P(argv
[0])) {
435 sig
= FIX2INT(argv
[0]);
439 sig
= signm2signo(&str
, TRUE
, FALSE
, NULL
);
442 if (argc
<= 1) return INT2FIX(0);
446 for (i
=1; i
<argc
; i
++) {
447 if (killpg(NUM2PIDT(argv
[i
]), sig
) < 0)
452 const rb_pid_t self
= (GET_THREAD() == GET_VM()->ractor
.main_thread
) ? getpid() : -1;
455 for (i
=1; i
<argc
; i
++) {
456 rb_pid_t pid
= NUM2PIDT(argv
[i
]);
458 if ((sig
!= 0) && (self
!= -1) && (pid
== self
)) {
461 * When target pid is self, many caller assume signal will be
462 * delivered immediately and synchronously.
484 t
= signal_ignored(sig
);
486 if (t
< 0 && kill(pid
, sig
))
494 else if (kill(pid
, sig
) < 0) {
499 rb_threadptr_check_signal(GET_VM()->ractor
.main_thread
);
502 rb_thread_execute_interrupts(rb_thread_current());
508 rb_atomic_t cnt
[RUBY_NSIG
];
512 volatile unsigned int ruby_nocldwait
;
515 #define sighandler_t ruby_sighandler_t
517 #ifdef USE_SIGALTSTACK
518 typedef void ruby_sigaction_t(int, siginfo_t
*, void*);
519 #define SIGINFO_ARG , siginfo_t *info, void *ctx
520 #define SIGINFO_CTX ctx
522 typedef void ruby_sigaction_t(int);
524 #define SIGINFO_CTX 0
527 #ifdef USE_SIGALTSTACK
528 /* XXX: BSD_vfprintf() uses >1500B stack and x86-64 need >5KiB stack. */
529 #define RUBY_SIGALTSTACK_SIZE (16*1024)
532 rb_sigaltstack_size(void)
534 int size
= RUBY_SIGALTSTACK_SIZE
;
538 int minsigstksz
= (int)MINSIGSTKSZ
;
539 if (size
< minsigstksz
)
543 #if defined(HAVE_SYSCONF) && defined(_SC_PAGE_SIZE)
546 pagesize
= (int)sysconf(_SC_PAGE_SIZE
);
555 static int rb_sigaltstack_size_value
= 0;
558 rb_allocate_sigaltstack(void)
561 if (!rb_sigaltstack_size_value
) {
562 rb_sigaltstack_size_value
= rb_sigaltstack_size();
564 altstack
= malloc(rb_sigaltstack_size_value
);
565 if (!altstack
) rb_memerror();
569 /* alternate stack for SIGSEGV */
571 rb_register_sigaltstack(void *altstack
)
573 stack_t newSS
, oldSS
;
575 newSS
.ss_size
= rb_sigaltstack_size_value
;
576 newSS
.ss_sp
= altstack
;
579 sigaltstack(&newSS
, &oldSS
); /* ignore error. */
583 #endif /* USE_SIGALTSTACK */
587 ruby_signal(int signum
, sighandler_t handler
)
589 struct sigaction sigact
, old
;
592 rb_trap_accept_nativethreads
[signum
] = 0;
595 sigemptyset(&sigact
.sa_mask
);
596 #ifdef USE_SIGALTSTACK
597 if (handler
== SIG_IGN
|| handler
== SIG_DFL
) {
598 sigact
.sa_handler
= handler
;
602 sigact
.sa_sigaction
= (ruby_sigaction_t
*)handler
;
603 sigact
.sa_flags
= SA_SIGINFO
;
606 sigact
.sa_handler
= handler
;
613 if (handler
== SIG_IGN
) {
615 # ifdef USE_SIGALTSTACK
616 if (sigact
.sa_flags
& SA_SIGINFO
) {
617 sigact
.sa_sigaction
= (ruby_sigaction_t
*)sighandler
;
620 sigact
.sa_handler
= sighandler
;
623 sigact
.sa_handler
= handler
;
632 #if defined(SA_ONSTACK) && defined(USE_SIGALTSTACK)
637 sigact
.sa_flags
|= SA_ONSTACK
;
641 (void)VALGRIND_MAKE_MEM_DEFINED(&old
, sizeof(old
));
642 if (sigaction(signum
, &sigact
, &old
) < 0) {
645 if (old
.sa_flags
& SA_SIGINFO
)
646 handler
= (sighandler_t
)old
.sa_sigaction
;
648 handler
= old
.sa_handler
;
649 ASSUME(handler
!= SIG_ERR
);
654 posix_signal(int signum
, sighandler_t handler
)
656 return ruby_signal(signum
, handler
);
660 static inline sighandler_t
661 ruby_signal(int signum
, sighandler_t handler
)
663 if (signum
== SIGKILL
) {
667 return signal(signum
, handler
);
670 #else /* !POSIX_SIGNAL */
671 #define ruby_signal(sig,handler) (/* rb_trap_accept_nativethreads[(sig)] = 0,*/ signal((sig),(handler)))
672 #if 0 /* def HAVE_NATIVETHREAD */
674 ruby_nativethread_signal(int signum
, sighandler_t handler
)
678 old
= signal(signum
, handler
);
679 rb_trap_accept_nativethreads
[signum
] = 1;
686 signal_ignored(int sig
)
690 struct sigaction old
;
691 (void)VALGRIND_MAKE_MEM_DEFINED(&old
, sizeof(old
));
692 if (sigaction(sig
, NULL
, &old
) < 0) return FALSE
;
693 func
= old
.sa_handler
;
695 sighandler_t old
= signal(sig
, SIG_DFL
);
699 if (func
== SIG_IGN
) return 1;
700 return func
== sighandler
? 0 : -1;
704 signal_enque(int sig
)
706 ATOMIC_INC(signal_buff
.cnt
[sig
]);
707 ATOMIC_INC(signal_buff
.size
);
711 static rb_atomic_t sigchld_hit
;
712 /* destructive getter than simple predicate */
713 # define GET_SIGCHLD_HIT() ATOMIC_EXCHANGE(sigchld_hit, 0)
715 # define GET_SIGCHLD_HIT() 0
721 int old_errnum
= errno
;
723 /* the VM always needs to handle SIGCHLD for rb_waitpid */
724 if (sig
== RUBY_SIGCHLD
) {
726 rb_vm_t
*vm
= GET_VM();
727 ATOMIC_EXCHANGE(sigchld_hit
, 1);
729 /* avoid spurious wakeup in main thread if and only if nobody uses trap(:CHLD) */
730 if (vm
&& ACCESS_ONCE(VALUE
, vm
->trap_list
.cmd
[sig
])) {
738 rb_thread_wakeup_timer_thread(sig
);
739 #if !defined(BSD_SIGNAL) && !defined(POSIX_SIGNAL)
740 ruby_signal(sig
, sighandler
);
747 rb_signal_buff_size(void)
749 return signal_buff
.size
;
753 rb_disable_interrupt(void)
755 #ifdef HAVE_PTHREAD_SIGMASK
758 pthread_sigmask(SIG_SETMASK
, &mask
, NULL
);
763 rb_enable_interrupt(void)
765 #ifdef HAVE_PTHREAD_SIGMASK
768 pthread_sigmask(SIG_SETMASK
, &mask
, NULL
);
773 rb_get_next_signal(void)
777 if (signal_buff
.size
!= 0) {
778 for (i
=1; i
<RUBY_NSIG
; i
++) {
779 if (signal_buff
.cnt
[i
] > 0) {
780 ATOMIC_DEC(signal_buff
.cnt
[i
]);
781 ATOMIC_DEC(signal_buff
.size
);
790 #if defined SIGSEGV || defined SIGBUS || defined SIGILL || defined SIGFPE
791 static const char *received_signal
;
792 # define clear_received_signal() (void)(ruby_disable_gc = 0, received_signal = 0)
794 # define clear_received_signal() ((void)0)
797 #if defined(USE_SIGALTSTACK) || defined(_WIN32)
798 NORETURN(void rb_ec_stack_overflow(rb_execution_context_t
*ec
, int crit
));
799 # if defined __HAIKU__
800 # define USE_UCONTEXT_REG 1
801 # elif !(defined(HAVE_UCONTEXT_H) && (defined __i386__ || defined __x86_64__ || defined __amd64__))
802 # elif defined __linux__
803 # define USE_UCONTEXT_REG 1
804 # elif defined __APPLE__
805 # define USE_UCONTEXT_REG 1
806 # elif defined __FreeBSD__
807 # define USE_UCONTEXT_REG 1
809 #if defined(HAVE_PTHREAD_SIGMASK)
810 # define ruby_sigunmask pthread_sigmask
811 #elif defined(HAVE_SIGPROCMASK)
812 # define ruby_sigunmask sigprocmask
815 reset_sigmask(int sig
)
817 #if defined(ruby_sigunmask)
820 clear_received_signal();
821 #if defined(ruby_sigunmask)
823 sigaddset(&mask
, sig
);
824 if (ruby_sigunmask(SIG_UNBLOCK
, &mask
, NULL
)) {
825 rb_bug_errno(STRINGIZE(ruby_sigunmask
)":unblock", errno
);
830 # ifdef USE_UCONTEXT_REG
832 check_stack_overflow(int sig
, const uintptr_t addr
, const ucontext_t
*ctx
)
834 const DEFINE_MCONTEXT_PTR(mctx
, ctx
);
835 # if defined __linux__
837 const greg_t sp
= mctx
->gregs
[REG_RSP
];
838 const greg_t bp
= mctx
->gregs
[REG_RBP
];
840 const greg_t sp
= mctx
->gregs
[REG_ESP
];
841 const greg_t bp
= mctx
->gregs
[REG_EBP
];
843 # elif defined __APPLE__
845 # define MCTX_SS_REG(reg) __ss.__##reg
847 # define MCTX_SS_REG(reg) ss.reg
849 # if defined(__LP64__)
850 const uintptr_t sp
= mctx
->MCTX_SS_REG(rsp
);
851 const uintptr_t bp
= mctx
->MCTX_SS_REG(rbp
);
853 const uintptr_t sp
= mctx
->MCTX_SS_REG(esp
);
854 const uintptr_t bp
= mctx
->MCTX_SS_REG(ebp
);
856 # elif defined __FreeBSD__
857 # if defined(__amd64__)
858 const __register_t sp
= mctx
->mc_rsp
;
859 const __register_t bp
= mctx
->mc_rbp
;
861 const __register_t sp
= mctx
->mc_esp
;
862 const __register_t bp
= mctx
->mc_ebp
;
864 # elif defined __HAIKU__
865 # if defined(__amd64__)
866 const unsigned long sp
= mctx
->rsp
;
867 const unsigned long bp
= mctx
->rbp
;
869 const unsigned long sp
= mctx
->esp
;
870 const unsigned long bp
= mctx
->ebp
;
873 enum {pagesize
= 4096};
874 const uintptr_t sp_page
= (uintptr_t)sp
/ pagesize
;
875 const uintptr_t bp_page
= (uintptr_t)bp
/ pagesize
;
876 const uintptr_t fault_page
= addr
/ pagesize
;
878 /* SP in ucontext is not decremented yet when `push` failed, so
879 * the fault page can be the next. */
880 if (sp_page
== fault_page
|| sp_page
== fault_page
+ 1 ||
881 (sp_page
<= fault_page
&& fault_page
<= bp_page
)) {
882 rb_execution_context_t
*ec
= GET_EC();
884 int uplevel
= roomof(pagesize
, sizeof(*ec
->tag
)) / 2; /* XXX: heuristic */
885 while ((uintptr_t)ec
->tag
->buf
/ pagesize
<= fault_page
+ 1) {
886 /* drop the last tag if it is close to the fault,
887 * otherwise it can cause stack overflow again at the same
889 if ((crit
= (!ec
->tag
->prev
|| !--uplevel
)) != FALSE
) break;
890 ec
->tag
= ec
->tag
->prev
;
893 rb_ec_stack_overflow(ec
, crit
);
898 check_stack_overflow(int sig
, const void *addr
)
900 int ruby_stack_overflowed_p(const rb_thread_t
*, const void *);
901 rb_thread_t
*th
= GET_THREAD();
902 if (ruby_stack_overflowed_p(th
, addr
)) {
904 rb_ec_stack_overflow(th
->ec
, FALSE
);
909 # define CHECK_STACK_OVERFLOW() check_stack_overflow(sig, 0)
911 # define FAULT_ADDRESS info->si_addr
912 # ifdef USE_UCONTEXT_REG
913 # define CHECK_STACK_OVERFLOW() check_stack_overflow(sig, (uintptr_t)FAULT_ADDRESS, ctx)
915 # define CHECK_STACK_OVERFLOW() check_stack_overflow(sig, FAULT_ADDRESS)
917 # define MESSAGE_FAULT_ADDRESS " at %p", FAULT_ADDRESS
920 # define CHECK_STACK_OVERFLOW() (void)0
922 #ifndef MESSAGE_FAULT_ADDRESS
923 # define MESSAGE_FAULT_ADDRESS
926 #if defined SIGSEGV || defined SIGBUS || defined SIGILL || defined SIGFPE
927 NOINLINE(static void check_reserved_signal_(const char *name
, size_t name_len
));
928 /* noinine to reduce stack usage in signal handers */
930 #define check_reserved_signal(name) check_reserved_signal_(name, sizeof(name)-1)
934 static sighandler_t default_sigbus_handler
;
935 NORETURN(static ruby_sigaction_t sigbus
);
938 sigbus(int sig SIGINFO_ARG
)
940 check_reserved_signal("BUS");
942 * Mac OS X makes KERN_PROTECTION_FAILURE when thread touch guard page.
943 * and it's delivered as SIGBUS instead of SIGSEGV to userland. It's crazy
944 * wrong IMHO. but anyway we have to care it. Sigh.
946 /* Seems Linux also delivers SIGBUS. */
947 #if defined __APPLE__ || defined __linux__
948 CHECK_STACK_OVERFLOW();
950 rb_bug_for_fatal_signal(default_sigbus_handler
, sig
, SIGINFO_CTX
, "Bus Error" MESSAGE_FAULT_ADDRESS
);
956 static sighandler_t default_sigsegv_handler
;
957 NORETURN(static ruby_sigaction_t sigsegv
);
960 sigsegv(int sig SIGINFO_ARG
)
962 check_reserved_signal("SEGV");
963 CHECK_STACK_OVERFLOW();
964 rb_bug_for_fatal_signal(default_sigsegv_handler
, sig
, SIGINFO_CTX
, "Segmentation fault" MESSAGE_FAULT_ADDRESS
);
970 static sighandler_t default_sigill_handler
;
971 NORETURN(static ruby_sigaction_t sigill
);
974 sigill(int sig SIGINFO_ARG
)
976 check_reserved_signal("ILL");
977 #if defined __APPLE__ || defined __linux__
978 CHECK_STACK_OVERFLOW();
980 rb_bug_for_fatal_signal(default_sigill_handler
, sig
, SIGINFO_CTX
, "Illegal instruction" MESSAGE_FAULT_ADDRESS
);
985 NORETURN(static void ruby_abort(void));
992 /* Solaris's abort() is async signal unsafe. Of course, it is not
1002 check_reserved_signal_(const char *name
, size_t name_len
)
1004 const char *prev
= ATOMIC_PTR_EXCHANGE(received_signal
, name
);
1007 ssize_t
RB_UNUSED_VAR(err
);
1008 #define NOZ(name, str) name[sizeof(str)-1] = str
1009 static const char NOZ(msg1
, " received in ");
1010 static const char NOZ(msg2
, " handler\n");
1013 struct iovec iov
[4];
1015 iov
[0].iov_base
= (void *)name
;
1016 iov
[0].iov_len
= name_len
;
1017 iov
[1].iov_base
= (void *)msg1
;
1018 iov
[1].iov_len
= sizeof(msg1
);
1019 iov
[2].iov_base
= (void *)prev
;
1020 iov
[2].iov_len
= strlen(prev
);
1021 iov
[3].iov_base
= (void *)msg2
;
1022 iov
[3].iov_len
= sizeof(msg2
);
1023 err
= writev(2, iov
, 4);
1025 err
= write(2, name
, name_len
);
1026 err
= write(2, msg1
, sizeof(msg1
));
1027 err
= write(2, prev
, strlen(prev
));
1028 err
= write(2, msg2
, sizeof(msg2
));
1033 ruby_disable_gc
= 1;
1037 #if defined SIGPIPE || defined SIGSYS
1039 sig_do_nothing(int sig
)
1045 signal_exec(VALUE cmd
, int sig
)
1047 rb_execution_context_t
*ec
= GET_EC();
1048 volatile rb_atomic_t old_interrupt_mask
= ec
->interrupt_mask
;
1049 enum ruby_tag_type state
;
1052 * workaround the following race:
1053 * 1. signal_enque queues signal for execution
1054 * 2. user calls trap(sig, "IGNORE"), setting SIG_IGN
1055 * 3. rb_signal_exec runs on queued signal
1057 if (IMMEDIATE_P(cmd
))
1060 ec
->interrupt_mask
|= TRAP_INTERRUPT_MASK
;
1062 if ((state
= EC_EXEC_TAG()) == TAG_NONE
) {
1063 VALUE signum
= INT2NUM(sig
);
1064 rb_eval_cmd_kw(cmd
, rb_ary_new3(1, signum
), RB_NO_KEYWORDS
);
1068 ec
->interrupt_mask
= old_interrupt_mask
;
1071 /* XXX: should be replaced with rb_threadptr_pending_interrupt_enque() */
1072 EC_JUMP_TAG(ec
, state
);
1078 rb_vm_trap_exit(rb_vm_t
*vm
)
1080 VALUE trap_exit
= vm
->trap_list
.cmd
[0];
1083 vm
->trap_list
.cmd
[0] = 0;
1084 signal_exec(trap_exit
, 0);
1088 void ruby_waitpid_all(rb_vm_t
*); /* process.c */
1091 ruby_sigchld_handler(rb_vm_t
*vm
)
1093 if (SIGCHLD_LOSSY
|| GET_SIGCHLD_HIT()) {
1094 ruby_waitpid_all(vm
);
1098 /* returns true if a trap handler was run, false otherwise */
1100 rb_signal_exec(rb_thread_t
*th
, int sig
)
1102 rb_vm_t
*vm
= GET_VM();
1103 VALUE cmd
= vm
->trap_list
.cmd
[sig
];
1128 rb_threadptr_signal_raise(th
, sig
);
1132 else if (cmd
== Qundef
) {
1133 rb_threadptr_signal_exit(th
);
1136 return signal_exec(cmd
, sig
);
1142 default_handler(int sig
)
1172 func
= (sighandler_t
)sigbus
;
1177 func
= (sighandler_t
)sigsegv
;
1182 func
= sig_do_nothing
;
1187 func
= sig_do_nothing
;
1199 trap_handler(VALUE
*cmd
, int sig
)
1201 sighandler_t func
= sighandler
;
1208 command
= rb_check_string_type(*cmd
);
1209 if (NIL_P(command
) && SYMBOL_P(*cmd
)) {
1210 command
= rb_sym2str(*cmd
);
1211 if (!command
) rb_raise(rb_eArgError
, "bad handler");
1213 if (!NIL_P(command
)) {
1216 StringValue(command
);
1218 RSTRING_GETMEM(command
, cptr
, len
);
1225 func
= default_handler(sig
);
1232 if (memcmp(cptr
, "SYSTEM_DEFAULT", 14) == 0) {
1233 if (sig
== RUBY_SIGCHLD
) {
1241 if (memcmp(cptr
, "SIG_IGN", 7) == 0) {
1244 else if (memcmp(cptr
, "SIG_DFL", 7) == 0) {
1247 else if (memcmp(cptr
, "DEFAULT", 7) == 0) {
1252 if (memcmp(cptr
, "IGNORE", 6) == 0) {
1257 if (memcmp(cptr
, "EXIT", 4) == 0) {
1265 GetProcPtr(*cmd
, proc
);
1274 trap_signm(VALUE vsig
)
1278 if (FIXNUM_P(vsig
)) {
1279 sig
= FIX2INT(vsig
);
1280 if (sig
< 0 || sig
>= NSIG
) {
1281 rb_raise(rb_eArgError
, "invalid signal number (%d)", sig
);
1285 sig
= signm2signo(&vsig
, FALSE
, TRUE
, NULL
);
1291 trap(int sig
, sighandler_t func
, VALUE command
)
1293 sighandler_t oldfunc
;
1295 rb_vm_t
*vm
= GET_VM();
1298 * Be careful. ruby_signal() and trap_list.cmd[sig] must be changed
1299 * atomically. In current implementation, we only need to don't call
1300 * RUBY_VM_CHECK_INTS().
1306 oldfunc
= ruby_signal(sig
, func
);
1307 if (oldfunc
== SIG_ERR
) rb_sys_fail_str(rb_signo2signm(sig
));
1309 oldcmd
= vm
->trap_list
.cmd
[sig
];
1313 if (oldfunc
== SIG_IGN
) oldcmd
= rb_str_new2("IGNORE");
1314 else if (oldfunc
== SIG_DFL
) oldcmd
= rb_str_new2("SYSTEM_DEFAULT");
1315 else if (oldfunc
== sighandler
) oldcmd
= rb_str_new2("DEFAULT");
1321 oldcmd
= rb_str_new2("EXIT");
1325 ACCESS_ONCE(VALUE
, vm
->trap_list
.cmd
[sig
]) = command
;
1331 reserved_signal_p(int signo
)
1333 /* Synchronous signal can't deliver to main thread */
1335 if (signo
== SIGSEGV
)
1339 if (signo
== SIGBUS
)
1343 if (signo
== SIGILL
)
1347 if (signo
== SIGFPE
)
1351 /* used ubf internal see thread_pthread.c. */
1353 if (signo
== SIGVTALRM
)
1362 * Signal.trap( signal, command ) -> obj
1363 * Signal.trap( signal ) {| | block } -> obj
1365 * Specifies the handling of signals. The first parameter is a signal
1366 * name (a string such as ``SIGALRM'', ``SIGUSR1'', and so on) or a
1367 * signal number. The characters ``SIG'' may be omitted from the
1368 * signal name. The command or block specifies code to be run when the
1370 * If the command is the string ``IGNORE'' or ``SIG_IGN'', the signal
1372 * If the command is ``DEFAULT'' or ``SIG_DFL'', the Ruby's default handler
1374 * If the command is ``EXIT'', the script will be terminated by the signal.
1375 * If the command is ``SYSTEM_DEFAULT'', the operating system's default
1376 * handler will be invoked.
1377 * Otherwise, the given command or block will be run.
1378 * The special signal name ``EXIT'' or signal number zero will be
1379 * invoked just prior to program termination.
1380 * trap returns the previous handler for the given signal.
1382 * Signal.trap(0, proc { puts "Terminating: #{$$}" })
1383 * Signal.trap("CLD") { puts "Child died" }
1384 * fork && Process.wait
1387 * Terminating: 27461
1389 * Terminating: 27460
1392 sig_trap(int argc
, VALUE
*argv
, VALUE _
)
1398 rb_check_arity(argc
, 1, 2);
1400 sig
= trap_signm(argv
[0]);
1401 if (reserved_signal_p(sig
)) {
1402 const char *name
= signo2signm(sig
);
1404 rb_raise(rb_eArgError
, "can't trap reserved signal: SIG%s", name
);
1406 rb_raise(rb_eArgError
, "can't trap reserved signal: %d", sig
);
1410 cmd
= rb_block_proc();
1415 func
= trap_handler(&cmd
, sig
);
1418 if (rb_obj_is_proc(cmd
) &&
1419 !rb_ractor_main_p() && !rb_ractor_shareable_p(cmd
)) {
1420 cmd
= rb_proc_isolate(cmd
);
1423 return trap(sig
, func
, cmd
);
1428 * Signal.list -> a_hash
1430 * Returns a list of signal names mapped to the corresponding
1431 * underlying signal numbers.
1433 * 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}
1438 VALUE h
= rb_hash_new();
1439 const struct signals
*sigs
;
1441 FOREACH_SIGNAL(sigs
, 0) {
1442 rb_hash_aset(h
, rb_fstring_cstr(sigs
->signm
), INT2FIX(sigs
->signo
));
1447 #define INSTALL_SIGHANDLER(cond, signame, signum) do { \
1448 static const char failed[] = "failed to install "signame" handler"; \
1449 if (!(cond)) break; \
1450 if (reserved_signal_p(signum)) rb_bug(failed); \
1454 install_sighandler_core(int signum
, sighandler_t handler
, sighandler_t
*old_handler
)
1458 old
= ruby_signal(signum
, handler
);
1459 if (old
== SIG_ERR
) return -1;
1461 *old_handler
= (old
== SIG_DFL
|| old
== SIG_IGN
) ? 0 : old
;
1464 /* signal handler should be inherited during exec. */
1465 if (old
!= SIG_DFL
) {
1466 ruby_signal(signum
, old
);
1472 # define install_sighandler(signum, handler) \
1473 INSTALL_SIGHANDLER(install_sighandler_core(signum, handler, NULL), #signum, signum)
1474 # define force_install_sighandler(signum, handler, old_handler) \
1475 INSTALL_SIGHANDLER(install_sighandler_core(signum, handler, old_handler), #signum, signum)
1479 init_sigchld(int sig
)
1481 sighandler_t oldfunc
;
1482 sighandler_t func
= sighandler
;
1484 oldfunc
= ruby_signal(sig
, SIG_DFL
);
1485 if (oldfunc
== SIG_ERR
) return -1;
1486 ruby_signal(sig
, func
);
1487 ACCESS_ONCE(VALUE
, GET_VM()->trap_list
.cmd
[sig
]) = 0;
1492 # define init_sigchld(signum) \
1493 INSTALL_SIGHANDLER(init_sigchld(signum), #signum, signum)
1497 ruby_sig_finalize(void)
1499 sighandler_t oldfunc
;
1501 oldfunc
= ruby_signal(SIGINT
, SIG_IGN
);
1502 if (oldfunc
== sighandler
) {
1503 ruby_signal(SIGINT
, SIG_DFL
);
1508 int ruby_enable_coredump
= 0;
1511 * Many operating systems allow signals to be sent to running
1512 * processes. Some signals have a defined effect on the process, while
1513 * others may be trapped at the code level and acted upon. For
1514 * example, your process may trap the USR1 signal and use it to toggle
1515 * debugging, and may use TERM to initiate a controlled shutdown.
1518 * Signal.trap("USR1") do
1520 * puts "Debug now: #$debug"
1522 * Signal.trap("TERM") do
1523 * puts "Terminating..."
1526 * # . . . do some work . . .
1529 * Process.detach(pid)
1531 * # Controlling program:
1532 * Process.kill("USR1", pid)
1534 * Process.kill("USR1", pid)
1536 * Process.kill("TERM", pid)
1543 * The list of available signal names and their interpretation is
1544 * system dependent. Signal delivery semantics may also vary between
1545 * systems; in particular signal delivery may not always be reliable.
1550 VALUE mSignal
= rb_define_module("Signal");
1552 rb_define_global_function("trap", sig_trap
, -1);
1553 rb_define_module_function(mSignal
, "trap", sig_trap
, -1);
1554 rb_define_module_function(mSignal
, "list", sig_list
, 0);
1555 rb_define_module_function(mSignal
, "signame", sig_signame
, 1);
1557 rb_define_method(rb_eSignal
, "initialize", esignal_init
, -1);
1558 rb_define_method(rb_eSignal
, "signo", esignal_signo
, 0);
1559 rb_alias(rb_eSignal
, rb_intern_const("signm"), rb_intern_const("message"));
1560 rb_define_method(rb_eInterrupt
, "initialize", interrupt_init
, -1);
1562 /* At this time, there is no subthread. Then sigmask guarantee atomics. */
1563 rb_disable_interrupt();
1565 install_sighandler(SIGINT
, sighandler
);
1567 install_sighandler(SIGHUP
, sighandler
);
1570 install_sighandler(SIGQUIT
, sighandler
);
1573 install_sighandler(SIGTERM
, sighandler
);
1576 install_sighandler(SIGALRM
, sighandler
);
1579 install_sighandler(SIGUSR1
, sighandler
);
1582 install_sighandler(SIGUSR2
, sighandler
);
1585 if (!ruby_enable_coredump
) {
1587 force_install_sighandler(SIGBUS
, (sighandler_t
)sigbus
, &default_sigbus_handler
);
1590 force_install_sighandler(SIGILL
, (sighandler_t
)sigill
, &default_sigill_handler
);
1593 RB_ALTSTACK_INIT(GET_VM()->main_altstack
, rb_allocate_sigaltstack());
1594 force_install_sighandler(SIGSEGV
, (sighandler_t
)sigsegv
, &default_sigsegv_handler
);
1598 install_sighandler(SIGPIPE
, sig_do_nothing
);
1601 install_sighandler(SIGSYS
, sig_do_nothing
);
1605 init_sigchld(RUBY_SIGCHLD
);
1608 rb_enable_interrupt();
1611 #if defined(HAVE_GRANTPT)
1612 extern int grantpt(int);
1615 fake_grantfd(int masterfd
)
1620 #define grantpt(fd) fake_grantfd(fd)
1624 rb_grantpt(int masterfd
)
1627 rb_vm_t
*vm
= GET_VM();
1631 * Prevent waitpid calls from Ruby by taking waitpid_lock.
1632 * Pedantically, grantpt(3) is undefined if a non-default
1633 * SIGCHLD handler is defined, but preventing conflicting
1634 * waitpid calls ought to be sufficient.
1636 * We could install the default sighandler temporarily, but that
1637 * could cause SIGCHLD to be missed by other threads. Blocking
1638 * SIGCHLD won't work here, either, unless we stop and restart
1639 * timer-thread (as only timer-thread sees SIGCHLD), but that
1640 * seems like overkill.
1642 rb_nativethread_lock_lock(&vm
->waitpid_lock
);
1644 ret
= grantpt(masterfd
); /* may spawn `pt_chown' and wait on it */
1645 if (ret
< 0) e
= errno
;
1647 rb_nativethread_lock_unlock(&vm
->waitpid_lock
);
1649 if (ret
< 0) errno
= e
;
1653 return grantpt(masterfd
);