diff options
Diffstat (limited to 'signal.c')
-rw-r--r-- | signal.c | 131 |
1 files changed, 100 insertions, 31 deletions
@@ -179,6 +179,18 @@ signm2signo(nm) return 0; } +static char* +signo2signm(no) + int no; +{ + struct signals *sigs; + + for (sigs = siglist; sigs->signm; sigs++) + if (sigs->signo == no) + return sigs->signm; + return 0; +} + VALUE rb_f_kill(argc, argv) int argc; @@ -200,7 +212,7 @@ rb_f_kill(argc, argv) sig = FIX2UINT(argv[0]); if (sig >= NSIG) { s = rb_id2name(sig); - if (!s) rb_raise(rb_eArgError, "Bad signal"); + if (!s) rb_raise(rb_eArgError, "bad signal"); goto str_signal; } break; @@ -216,7 +228,7 @@ rb_f_kill(argc, argv) if (strncmp("SIG", s, 3) == 0) s += 3; if((sig = signm2signo(s)) == 0) - rb_raise(rb_eArgError, "Unrecognized signal name `%s'", s); + rb_raise(rb_eArgError, "unrecognized signal name `%s'", s); if (negative) sig = -sig; @@ -284,30 +296,62 @@ posix_signal(signum, handler) sigact.sa_flags = 0; sigaction(signum, &sigact, 0); } +#define ruby_signal(sig,handle) posix_signal((sig),(handle)) +#else +#define ruby_signal(sig,handle) signal((sig),(handle)) #endif -#ifdef USE_THREAD -# define rb_interrupt rb_thread_interrupt -# define rb_trap_eval rb_thread_trap_eval +static void +signal_exec(sig) + int sig; +{ + if (trap_list[sig] == 0) { + switch (sig) { + case SIGINT: + rb_thread_interrupt(); + break; +#ifndef NT + case SIGHUP: +#endif +#ifdef SIGPIPE + case SIGPIPE: #endif +#ifdef SIGQUIT + case SIGQUIT: +#endif +#ifdef SIGALRM + case SIGALRM: +#endif +#ifdef SIGUSR1 + case SIGUSR1: +#endif +#ifdef SIGUSR2 + case SIGUSR2: +#endif + rb_thread_signal_raise(signo2signm(sig)); + break; + } + } + else { + rb_thread_trap_eval(trap_list[sig], sig); + } +} static RETSIGTYPE sighandle(sig) int sig; { - if (sig >= NSIG ||(sig != SIGINT && !trap_list[sig])) + if (sig >= NSIG) { rb_bug("trap_handler: Bad signal %d", sig); + } #if !defined(POSIX_SIGNAL) && !defined(BSD_SIGNAL) - signal(sig, sighandle); + ruby_signal(sig, sighandle); #endif if (rb_trap_immediate) { rb_trap_immediate = 0; - if (sig == SIGINT && !trap_list[SIGINT]) { - rb_interrupt(); - } - rb_trap_eval(trap_list[sig], sig); + signal_exec(sig); rb_trap_immediate = 1; } else { @@ -353,11 +397,7 @@ rb_trap_exec() for (i=0; i<NSIG; i++) { if (trap_pending_list[i]) { trap_pending_list[i] = 0; - if (i == SIGINT && trap_list[SIGINT] == 0) { - rb_interrupt(); - return; - } - rb_trap_eval(trap_list[i], i); + signal_exec(i); } } #endif /* MACOS_UNUSE_SIGNAL */ @@ -438,15 +478,15 @@ trap(arg) s += 3; sig = signm2signo(s); if (sig == 0 && strcmp(s, "EXIT") != 0) - rb_raise(rb_eArgError, "Invalid signal SIG%s", s); + rb_raise(rb_eArgError, "invalid signal SIG%s", s); } else { sig = NUM2INT(arg->sig); } if (sig < 0 || sig > NSIG) { - rb_raise(rb_eArgError, "Invalid signal no %d", sig); + rb_raise(rb_eArgError, "invalid signal number (%d)", sig); } -#if defined(USE_THREAD) && defined(HAVE_SETITIMER) && !defined(__BOW__) +#if defined(HAVE_SETITIMER) && !defined(__BOW__) if (sig == SIGVTALRM) { rb_raise(rb_eArgError, "SIGVTALRM reserved for Thread; cannot set handler"); } @@ -454,6 +494,24 @@ trap(arg) if (func == SIG_DFL) { switch (sig) { case SIGINT: +#ifndef NT + case SIGHUP: +#endif +#ifdef SIGQUIT + case SIGQUIT: +#endif +#ifdef SIGALRM + case SIGALRM: +#endif +#ifdef SIGUSR1 + case SIGUSR1: +#endif +#ifdef SIGUSR2 + case SIGUSR2: +#endif +#ifdef SIGPIPE + case SIGPIPE: +#endif func = sighandle; break; #ifdef SIGBUS @@ -468,11 +526,7 @@ trap(arg) #endif } } -#ifdef POSIX_SIGNAL - posix_signal(sig, func); -#else - signal(sig, func); -#endif + ruby_signal(sig, func); old = trap_list[sig]; if (!old) old = Qnil; @@ -507,7 +561,7 @@ trap_ensure(arg) void rb_trap_restore_mask() { -#ifndef NT +#if !defined(NT) && !defined(USE_CWGUSI) # ifdef HAVE_SIGPROCMASK sigprocmask(SIG_SETMASK, &trap_last_mask, NULL); # else @@ -556,16 +610,31 @@ Init_signal() { #ifndef MACOS_UNUSE_SIGNAL rb_define_global_function("trap", rb_f_trap, -1); -#ifdef POSIX_SIGNAL - posix_signal(SIGINT, sighandle); -#else - signal(SIGINT, sighandle); + ruby_signal(SIGINT, sighandle); +#ifndef NT + ruby_signal(SIGHUP, sighandle); +#endif +#ifdef SIGPIPE + ruby_signal(SIGPIPE, sighandle); +#endif +#ifdef SIGQUIT + ruby_signal(SIGQUIT, sighandle); +#endif +#ifdef SIGALRM + ruby_signal(SIGALRM, sighandle); +#endif +#ifdef SIGUSR1 + ruby_signal(SIGUSR1, sighandle); +#endif +#ifdef SIGUSR2 + ruby_signal(SIGUSR2, sighandle); #endif + #ifdef SIGBUS - signal(SIGBUS, sigbus); + ruby_signal(SIGBUS, sigbus); #endif #ifdef SIGSEGV - signal(SIGSEGV, sigsegv); + ruby_signal(SIGSEGV, sigsegv); #endif #endif /* MACOS_UNUSE_SIGNAL */ } |