static int trap_signm(VALUE vsig) { int sig = -1; const char *s; switch (TYPE(vsig)) { case T_FIXNUM: sig = FIX2INT(vsig); if (sig < 0 || sig >= NSIG) { rb_raise(rb_eArgError, "invalid signal number (%d)", sig); } break; case T_SYMBOL: s = rb_id2name(SYM2ID(vsig)); if (!s) rb_raise(rb_eArgError, "bad signal"); goto str_signal; default: s = StringValuePtr(vsig); str_signal: if (strncmp("SIG", s, 3) == 0) s += 3; sig = signm2signo(s); if (sig == 0 && strcmp(s, "EXIT") != 0) rb_raise(rb_eArgError, "unsupported signal SIG%s", s); } return sig; }
static int trap_signm(VALUE vsig) { int sig = -1; const char *s; switch (TYPE(vsig)) { case T_FIXNUM: sig = FIX2INT(vsig); if (sig < 0 || sig >= NSIG) { rb_raise(rb_eArgError, "invalid signal number (%d)", sig); } break; case T_SYMBOL: vsig = rb_sym2str(vsig); s = RSTRING_PTR(vsig); goto str_signal; default: s = StringValuePtr(vsig); str_signal: if (strncmp(signame_prefix, s, sizeof(signame_prefix)) == 0) s += 3; sig = signm2signo(s); if (sig == 0 && strcmp(s, "EXIT") != 0) { long ofs = s - RSTRING_PTR(vsig); if (ofs) vsig = rb_str_subseq(vsig, ofs, RSTRING_LEN(vsig)-ofs); rb_raise(rb_eArgError, "unsupported signal SIG%"PRIsVALUE"", vsig); } } return sig; }
static int trap_signm(VALUE vsig) { int sig = -1; const char *s; if (TYPE(vsig) == T_FIXNUM) { sig = FIX2INT(vsig); if (sig < 0 || sig >= NSIG) { rb_raise(rb_eArgError, "invalid signal number (%d)", sig); } } else { if (TYPE(vsig) == T_SYMBOL) { s = rb_sym2name(vsig); if (s == NULL) rb_raise(rb_eArgError, "bad signal"); } else s = StringValuePtr(vsig); if (strncmp("SIG", s, 3) == 0) s += 3; sig = signm2signo(s); if (sig == 0 && strcmp(s, "EXIT") != 0) rb_raise(rb_eArgError, "unsupported signal SIG%s", s); } return sig; }
static int trap_signm(mrb_state *mrb, mrb_value vsig) { int sig = -1; const char *s; switch (mrb_type(vsig)) { case MRB_TT_FIXNUM: sig = mrb_fixnum(vsig); if (sig < 0 || sig >= NSIG) { mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid signal number (%S)", vsig); } break; case MRB_TT_SYMBOL: s = mrb_sym2name(mrb, mrb_symbol(vsig)); if (!s) mrb_raise(mrb, E_ARGUMENT_ERROR, "bad signal"); goto str_signal; default: vsig = mrb_string_type(mrb, vsig); s = RSTRING_PTR(vsig); str_signal: if (memcmp("SIG", s, 3) == 0) s += 3; sig = signm2signo(s); if (sig == 0 && strcmp(s, "EXIT") != 0) mrb_raise(mrb, E_ARGUMENT_ERROR, "unsupported signal"); break; } return sig; }
static VALUE esignal_init(int argc, VALUE *argv, VALUE self) { int argnum = 1; VALUE sig = Qnil; int signo; const char *signm; if (argc > 0) { sig = rb_check_to_integer(argv[0], "to_int"); if (!NIL_P(sig)) argnum = 2; } if (argc < 1 || argnum < argc) { rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", argc, argnum); } if (argnum == 2) { signo = NUM2INT(sig); if (signo < 0 || signo > NSIG) { rb_raise(rb_eArgError, "invalid signal number (%d)", signo); } if (argc > 1) { sig = argv[1]; } else { signm = signo2signm(signo); if (signm) { sig = rb_sprintf("SIG%s", signm); } else { sig = rb_sprintf("SIG%u", signo); } } } else { signm = SYMBOL_P(sig) ? rb_id2name(SYM2ID(sig)) : StringValuePtr(sig); if (strncmp(signm, "SIG", 3) == 0) signm += 3; signo = signm2signo(signm); if (!signo) { rb_raise(rb_eArgError, "unsupported name `SIG%s'", signm); } if (SYMBOL_P(sig)) { sig = rb_str_new2(signm); } } rb_call_super(1, &sig); rb_iv_set(self, "signo", INT2NUM(signo)); return self; }
static VALUE esignal_init(int argc, VALUE *argv, VALUE self) { int argnum = 1; VALUE sig = Qnil; int signo; const char *signm; if (argc > 0) { sig = rb_check_to_integer(argv[0], "to_int"); if (!NIL_P(sig)) argnum = 2; else sig = argv[0]; } rb_check_arity(argc, 1, argnum); if (argnum == 2) { signo = NUM2INT(sig); if (signo < 0 || signo > NSIG) { rb_raise(rb_eArgError, "invalid signal number (%d)", signo); } if (argc > 1) { sig = argv[1]; } else { sig = rb_signo2signm(signo); } } else { int len = sizeof(signame_prefix); if (SYMBOL_P(sig)) sig = rb_sym2str(sig); else StringValue(sig); signm = RSTRING_PTR(sig); if (strncmp(signm, signame_prefix, len) == 0) { signm += len; len = 0; } signo = signm2signo(signm); if (!signo) { rb_raise(rb_eArgError, "unsupported name `%.*s%"PRIsVALUE"'", len, signame_prefix, sig); } sig = rb_sprintf("SIG%s", signm); } rb_call_super(1, &sig); rb_iv_set(self, "signo", INT2NUM(signo)); return self; }
VALUE rb_f_kill(int argc, const VALUE *argv) { #ifndef HAVE_KILLPG #define killpg(pg, sig) kill(-(pg), (sig)) #endif int negative = 0; int sig; int i; VALUE str; const char *s; rb_secure(2); rb_check_arity(argc, 2, UNLIMITED_ARGUMENTS); switch (TYPE(argv[0])) { case T_FIXNUM: sig = FIX2INT(argv[0]); break; case T_SYMBOL: str = rb_sym2str(argv[0]); goto str_signal; case T_STRING: str = argv[0]; str_signal: s = RSTRING_PTR(str); if (s[0] == '-') { negative++; s++; } if (strncmp(signame_prefix, s, sizeof(signame_prefix)) == 0) s += 3; if ((sig = signm2signo(s)) == 0) { long ofs = s - RSTRING_PTR(str); if (ofs) str = rb_str_subseq(str, ofs, RSTRING_LEN(str)-ofs); rb_raise(rb_eArgError, "unsupported name `SIG%"PRIsVALUE"'", str); } if (negative) sig = -sig; break; default: str = rb_check_string_type(argv[0]); if (!NIL_P(str)) { goto str_signal; } rb_raise(rb_eArgError, "bad signal type %s", rb_obj_classname(argv[0])); break; } if (argc <= 1) return INT2FIX(0); if (sig < 0) { sig = -sig; for (i=1; i<argc; i++) { if (killpg(NUM2PIDT(argv[i]), sig) < 0) rb_sys_fail(0); } } else { const rb_pid_t self = (GET_THREAD() == GET_VM()->main_thread) ? getpid() : -1; int wakeup = 0; for (i=1; i<argc; i++) { rb_pid_t pid = NUM2PIDT(argv[i]); if ((sig != 0) && (self != -1) && (pid == self)) { int t; /* * When target pid is self, many caller assume signal will be * delivered immediately and synchronously. */ switch (sig) { case SIGSEGV: #ifdef SIGBUS case SIGBUS: #endif #ifdef SIGKILL case SIGKILL: #endif #ifdef SIGSTOP case SIGSTOP: #endif ruby_kill(pid, sig); break; default: t = signal_ignored(sig); if (t) { if (t < 0 && kill(pid, sig)) rb_sys_fail(0); break; } signal_enque(sig); wakeup = 1; } } else if (kill(pid, sig) < 0) { rb_sys_fail(0); } } if (wakeup) { rb_threadptr_check_signal(GET_VM()->main_thread); } } rb_thread_execute_interrupts(rb_thread_current()); return INT2FIX(i-1); }
VALUE rb_f_kill(int argc, VALUE *argv) { #ifndef HAS_KILLPG #define killpg(pg, sig) kill(-(pg), sig) #endif int negative = 0; int sig; int i; const char *s; rb_secure(2); if (argc < 2) rb_raise(rb_eArgError, "wrong number of arguments -- kill(sig, pid...)"); switch (TYPE(argv[0])) { case T_FIXNUM: sig = FIX2INT(argv[0]); break; case T_SYMBOL: s = rb_id2name(SYM2ID(argv[0])); if (!s) rb_raise(rb_eArgError, "bad signal"); goto str_signal; case T_STRING: s = RSTRING_PTR(argv[0]); if (s[0] == '-') { negative++; s++; } str_signal: if (strncmp("SIG", s, 3) == 0) s += 3; if((sig = signm2signo(s)) == 0) rb_raise(rb_eArgError, "unsupported name `SIG%s'", s); if (negative) sig = -sig; break; default: { VALUE str; str = rb_check_string_type(argv[0]); if (!NIL_P(str)) { s = RSTRING_PTR(str); goto str_signal; } rb_raise(rb_eArgError, "bad signal type %s", rb_obj_classname(argv[0])); } break; } if (sig < 0) { sig = -sig; for (i=1; i<argc; i++) { if (killpg(NUM2PIDT(argv[i]), sig) < 0) rb_sys_fail(0); } } else { for (i=1; i<argc; i++) { if (kill(NUM2PIDT(argv[i]), sig) < 0) rb_sys_fail(0); } } rb_thread_polling(); return INT2FIX(i-1); }
VALUE rb_f_kill(VALUE self, SEL sel, int argc, VALUE *argv) { int negative = 0; int sig; int i; int type; const char *s = NULL; rb_secure(2); if (argc < 2) rb_raise(rb_eArgError, "wrong number of arguments -- kill(sig, pid...)"); type = TYPE(argv[0]); if (type == T_FIXNUM) { sig = FIX2INT(argv[0]); } else { if (type == T_SYMBOL) { s = rb_sym2name(argv[0]); if (!s) rb_raise(rb_eArgError, "bad signal"); } else if (type == T_STRING) { s = RSTRING_PTR(argv[0]); if (s[0] == '-') { negative++; s++; } } else { VALUE str; str = rb_check_string_type(argv[0]); if (!NIL_P(str)) { s = RSTRING_PTR(str); } } if (s == NULL) rb_raise(rb_eArgError, "bad signal type %s", rb_obj_classname(argv[0])); if (strncmp("SIG", s, 3) == 0) s += 3; if ((sig = signm2signo(s)) == 0) rb_raise(rb_eArgError, "unsupported name `SIG%s'", s); if (negative) sig = -sig; } if (sig < 0) { sig = -sig; for (i = 1; i < argc; i++) { if (killpg(NUM2PIDT(argv[i]), sig) < 0) rb_sys_fail(0); } } else { for (i = 1; i < argc; i++) { if (kill(NUM2PIDT(argv[i]), sig) < 0) rb_sys_fail(0); } } rb_thread_polling(); return INT2FIX(i - 1); }
static VALUE trap(struct trap_arg *arg) { sighandler_t func, oldfunc; VALUE command, oldcmd; int sig = -1; const char *s; func = sighandler; if (NIL_P(arg->cmd)) { func = SIG_IGN; } else { command = rb_check_string_type(arg->cmd); if (!NIL_P(command)) { SafeStringValue(command); /* taint check */ switch (RSTRING_LEN(command)) { case 0: func = SIG_IGN; break; case 7: if (strncmp(RSTRING_PTR(command), "SIG_IGN", 7) == 0) { func = SIG_IGN; } else if (strncmp(RSTRING_PTR(command), "SIG_DFL", 7) == 0) { func = SIG_DFL; } else if (strncmp(RSTRING_PTR(command), "DEFAULT", 7) == 0) { func = SIG_DFL; } break; case 6: if (strncmp(RSTRING_PTR(command), "IGNORE", 6) == 0) { func = SIG_IGN; } break; case 4: if (strncmp(RSTRING_PTR(command), "EXIT", 4) == 0) { arg->cmd = Qundef; } break; } } } if (func == SIG_IGN || func == SIG_DFL) { command = 0; } else { command = arg->cmd; } switch (TYPE(arg->sig)) { case T_FIXNUM: sig = FIX2INT(arg->sig); break; case T_SYMBOL: s = rb_id2name(SYM2ID(arg->sig)); if (!s) rb_raise(rb_eArgError, "bad signal"); goto str_signal; case T_STRING: s = RSTRING_PTR(arg->sig); str_signal: if (strncmp("SIG", s, 3) == 0) s += 3; sig = signm2signo(s); if (sig == 0 && strcmp(s, "EXIT") != 0) rb_raise(rb_eArgError, "unsupported signal SIG%s", s); } if (sig < 0 || sig >= NSIG) { rb_raise(rb_eArgError, "invalid signal number (%d)", sig); } #if defined(HAVE_SETITIMER) if (sig == SIGVTALRM) { rb_raise(rb_eArgError, "SIGVTALRM reserved for Thread; can't set handler"); } #endif if (func == SIG_DFL) { switch (sig) { case SIGINT: #ifdef SIGHUP case SIGHUP: #endif #ifdef SIGQUIT case SIGQUIT: #endif #ifdef SIGALRM case SIGALRM: #endif #ifdef SIGUSR1 case SIGUSR1: #endif #ifdef SIGUSR2 case SIGUSR2: #endif func = sighandler; break; #ifdef SIGBUS case SIGBUS: func = sigbus; break; #endif #ifdef SIGSEGV case SIGSEGV: func = sigsegv; break; #endif #ifdef SIGPIPE case SIGPIPE: func = sigpipe; break; #endif } } oldfunc = ruby_signal(sig, func); oldcmd = trap_list[sig].cmd; if (!oldcmd) { if (oldfunc == SIG_IGN) oldcmd = rb_str_new2("IGNORE"); else if (oldfunc == sighandler) oldcmd = rb_str_new2("DEFAULT"); else oldcmd = Qnil; } trap_list[sig].cmd = command; trap_list[sig].safe = rb_safe_level(); /* enable at least specified signal. */ #ifndef _WIN32 #ifdef HAVE_SIGPROCMASK sigdelset(&arg->mask, sig); #else arg->mask &= ~sigmask(sig); #endif #endif return oldcmd; }
VALUE rb_f_kill(int argc, VALUE *argv) { #ifndef HAVE_KILLPG #define killpg(pg, sig) kill(-(pg), (sig)) #endif int negative = 0; int sig; int i; volatile VALUE str; const char *s; rb_secure(2); rb_check_arity(argc, 2, UNLIMITED_ARGUMENTS); switch (TYPE(argv[0])) { case T_FIXNUM: sig = FIX2INT(argv[0]); break; case T_SYMBOL: s = rb_id2name(SYM2ID(argv[0])); if (!s) rb_raise(rb_eArgError, "bad signal"); goto str_signal; case T_STRING: s = RSTRING_PTR(argv[0]); str_signal: if (s[0] == '-') { negative++; s++; } if (strncmp("SIG", s, 3) == 0) s += 3; if ((sig = signm2signo(s)) == 0) rb_raise(rb_eArgError, "unsupported name `SIG%s'", s); if (negative) sig = -sig; break; default: str = rb_check_string_type(argv[0]); if (!NIL_P(str)) { s = RSTRING_PTR(str); goto str_signal; } rb_raise(rb_eArgError, "bad signal type %s", rb_obj_classname(argv[0])); break; } if (sig < 0) { sig = -sig; for (i=1; i<argc; i++) { if (killpg(NUM2PIDT(argv[i]), sig) < 0) rb_sys_fail(0); } } else { for (i=1; i<argc; i++) { ruby_kill(NUM2PIDT(argv[i]), sig); } } rb_thread_execute_interrupts(rb_thread_current()); return INT2FIX(i-1); }