00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "ruby.h"
00016 #include "rubysig.h"
00017 #include <signal.h>
00018 #include <stdio.h>
00019
00020 #ifdef __BEOS__
00021 #undef SIGBUS
00022 #endif
00023
00024 #ifndef NSIG
00025 # ifdef DJGPP
00026 # define NSIG SIGMAX
00027 # else
00028 # define NSIG (_SIGMAX + 1)
00029 # endif
00030 #endif
00031
00032 static struct signals {
00033 char *signm;
00034 int signo;
00035 } siglist [] = {
00036 {"EXIT", 0},
00037 #ifdef SIGHUP
00038 {"HUP", SIGHUP},
00039 #endif
00040 {"INT", SIGINT},
00041 #ifdef SIGQUIT
00042 {"QUIT", SIGQUIT},
00043 #endif
00044 #ifdef SIGILL
00045 {"ILL", SIGILL},
00046 #endif
00047 #ifdef SIGTRAP
00048 {"TRAP", SIGTRAP},
00049 #endif
00050 #ifdef SIGIOT
00051 {"IOT", SIGIOT},
00052 #endif
00053 #ifdef SIGABRT
00054 {"ABRT", SIGABRT},
00055 #endif
00056 #ifdef SIGEMT
00057 {"EMT", SIGEMT},
00058 #endif
00059 #ifdef SIGFPE
00060 {"FPE", SIGFPE},
00061 #endif
00062 #ifdef SIGKILL
00063 {"KILL", SIGKILL},
00064 #endif
00065 #ifdef SIGBUS
00066 {"BUS", SIGBUS},
00067 #endif
00068 #ifdef SIGSEGV
00069 {"SEGV", SIGSEGV},
00070 #endif
00071 #ifdef SIGSYS
00072 {"SYS", SIGSYS},
00073 #endif
00074 #ifdef SIGPIPE
00075 {"PIPE", SIGPIPE},
00076 #endif
00077 #ifdef SIGALRM
00078 {"ALRM", SIGALRM},
00079 #endif
00080 #ifdef SIGTERM
00081 {"TERM", SIGTERM},
00082 #endif
00083 #ifdef SIGURG
00084 {"URG", SIGURG},
00085 #endif
00086 #ifdef SIGSTOP
00087 {"STOP", SIGSTOP},
00088 #endif
00089 #ifdef SIGTSTP
00090 {"TSTP", SIGTSTP},
00091 #endif
00092 #ifdef SIGCONT
00093 {"CONT", SIGCONT},
00094 #endif
00095 #ifdef SIGCHLD
00096 {"CHLD", SIGCHLD},
00097 #endif
00098 #ifdef SIGCLD
00099 {"CLD", SIGCLD},
00100 #else
00101 # ifdef SIGCHLD
00102 {"CLD", SIGCHLD},
00103 # endif
00104 #endif
00105 #ifdef SIGTTIN
00106 {"TTIN", SIGTTIN},
00107 #endif
00108 #ifdef SIGTTOU
00109 {"TTOU", SIGTTOU},
00110 #endif
00111 #ifdef SIGIO
00112 {"IO", SIGIO},
00113 #endif
00114 #ifdef SIGXCPU
00115 {"XCPU", SIGXCPU},
00116 #endif
00117 #ifdef SIGXFSZ
00118 {"XFSZ", SIGXFSZ},
00119 #endif
00120 #ifdef SIGVTALRM
00121 {"VTALRM", SIGVTALRM},
00122 #endif
00123 #ifdef SIGPROF
00124 {"PROF", SIGPROF},
00125 #endif
00126 #ifdef SIGWINCH
00127 {"WINCH", SIGWINCH},
00128 #endif
00129 #ifdef SIGUSR1
00130 {"USR1", SIGUSR1},
00131 #endif
00132 #ifdef SIGUSR2
00133 {"USR2", SIGUSR2},
00134 #endif
00135 #ifdef SIGLOST
00136 {"LOST", SIGLOST},
00137 #endif
00138 #ifdef SIGMSG
00139 {"MSG", SIGMSG},
00140 #endif
00141 #ifdef SIGPWR
00142 {"PWR", SIGPWR},
00143 #endif
00144 #ifdef SIGPOLL
00145 {"POLL", SIGPOLL},
00146 #endif
00147 #ifdef SIGDANGER
00148 {"DANGER", SIGDANGER},
00149 #endif
00150 #ifdef SIGMIGRATE
00151 {"MIGRATE", SIGMIGRATE},
00152 #endif
00153 #ifdef SIGPRE
00154 {"PRE", SIGPRE},
00155 #endif
00156 #ifdef SIGGRANT
00157 {"GRANT", SIGGRANT},
00158 #endif
00159 #ifdef SIGRETRACT
00160 {"RETRACT", SIGRETRACT},
00161 #endif
00162 #ifdef SIGSOUND
00163 {"SOUND", SIGSOUND},
00164 #endif
00165 #ifdef SIGINFO
00166 {"INFO", SIGINFO},
00167 #endif
00168 {NULL, 0}
00169 };
00170
00171 static int
00172 signm2signo(nm)
00173 char *nm;
00174 {
00175 struct signals *sigs;
00176
00177 for (sigs = siglist; sigs->signm; sigs++)
00178 if (strcmp(sigs->signm, nm) == 0)
00179 return sigs->signo;
00180 return 0;
00181 }
00182
00183 static char*
00184 signo2signm(no)
00185 int no;
00186 {
00187 struct signals *sigs;
00188
00189 for (sigs = siglist; sigs->signm; sigs++)
00190 if (sigs->signo == no)
00191 return sigs->signm;
00192 return 0;
00193 }
00194
00195 const char *
00196 ruby_signal_name(no)
00197 int no;
00198 {
00199 return signo2signm(no);
00200 }
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226 VALUE
00227 rb_f_kill(argc, argv)
00228 int argc;
00229 VALUE *argv;
00230 {
00231 int negative = 0;
00232 int sig;
00233 int i;
00234 char *s;
00235
00236 rb_secure(2);
00237 if (argc < 2)
00238 rb_raise(rb_eArgError, "wrong number of arguments -- kill(sig, pid...)");
00239 switch (TYPE(argv[0])) {
00240 case T_FIXNUM:
00241 sig = FIX2INT(argv[0]);
00242 break;
00243
00244 case T_SYMBOL:
00245 s = rb_id2name(SYM2ID(argv[0]));
00246 if (!s) rb_raise(rb_eArgError, "bad signal");
00247 goto str_signal;
00248
00249 case T_STRING:
00250 s = RSTRING(argv[0])->ptr;
00251 if (s[0] == '-') {
00252 negative++;
00253 s++;
00254 }
00255 str_signal:
00256 if (strncmp("SIG", s, 3) == 0)
00257 s += 3;
00258 if((sig = signm2signo(s)) == 0)
00259 rb_raise(rb_eArgError, "unsupported name `SIG%s'", s);
00260
00261 if (negative)
00262 sig = -sig;
00263 break;
00264
00265 default:
00266 {
00267 VALUE str;
00268
00269 str = rb_check_string_type(argv[0]);
00270 if (!NIL_P(str)) {
00271 s = RSTRING(str)->ptr;
00272 goto str_signal;
00273 }
00274 rb_raise(rb_eArgError, "bad signal type %s",
00275 rb_obj_classname(argv[0]));
00276 }
00277 break;
00278 }
00279
00280 if (sig < 0) {
00281 sig = -sig;
00282 for (i=1; i<argc; i++) {
00283 int pid = NUM2INT(argv[i]);
00284 #ifdef HAS_KILLPG
00285 if (killpg(pid, sig) < 0)
00286 #else
00287 if (kill(-pid, sig) < 0)
00288 #endif
00289 rb_sys_fail(0);
00290 }
00291 }
00292 else {
00293 for (i=1; i<argc; i++) {
00294 Check_Type(argv[i], T_FIXNUM);
00295 if (kill(FIX2INT(argv[i]), sig) < 0)
00296 rb_sys_fail(0);
00297 }
00298 }
00299 return INT2FIX(i-1);
00300 }
00301
00302 static struct {
00303 VALUE cmd;
00304 int safe;
00305 } trap_list[NSIG];
00306 static rb_atomic_t trap_pending_list[NSIG];
00307 rb_atomic_t rb_trap_pending;
00308 rb_atomic_t rb_trap_immediate;
00309 int rb_prohibit_interrupt = 1;
00310
00311 void
00312 rb_gc_mark_trap_list()
00313 {
00314 #ifndef MACOS_UNUSE_SIGNAL
00315 int i;
00316
00317 for (i=0; i<NSIG; i++) {
00318 if (trap_list[i].cmd)
00319 rb_gc_mark(trap_list[i].cmd);
00320 }
00321 #endif
00322 }
00323
00324 #ifdef __dietlibc__
00325 #define sighandler_t sh_t
00326 #endif
00327
00328 typedef RETSIGTYPE (*sighandler_t)(int);
00329
00330 #ifdef POSIX_SIGNAL
00331 static sighandler_t
00332 ruby_signal(signum, handler)
00333 int signum;
00334 sighandler_t handler;
00335 {
00336 struct sigaction sigact, old;
00337
00338 sigact.sa_handler = handler;
00339 sigemptyset(&sigact.sa_mask);
00340 sigact.sa_flags = 0;
00341 #if defined(SA_RESTART)
00342
00343
00344
00345 if (signum != SIGVTALRM) {
00346 sigact.sa_flags |= SA_RESTART;
00347 }
00348 #endif
00349 #ifdef SA_NOCLDWAIT
00350 if (signum == SIGCHLD && handler == SIG_IGN)
00351 sigact.sa_flags |= SA_NOCLDWAIT;
00352 #endif
00353 sigaction(signum, &sigact, &old);
00354 return old.sa_handler;
00355 }
00356
00357 void
00358 posix_signal(signum, handler)
00359 int signum;
00360 sighandler_t handler;
00361 {
00362 ruby_signal(signum, handler);
00363 }
00364 #else
00365 #define ruby_signal(sig,handler) signal((sig),(handler))
00366 #endif
00367
00368 static void signal_exec (int sig);
00369 static void
00370 signal_exec(sig)
00371 int sig;
00372 {
00373 if (trap_list[sig].cmd == 0) {
00374 switch (sig) {
00375 case SIGINT:
00376 rb_thread_interrupt();
00377 break;
00378 #ifdef SIGHUP
00379 case SIGHUP:
00380 #endif
00381 #ifdef SIGQUIT
00382 case SIGQUIT:
00383 #endif
00384 #ifdef SIGALRM
00385 case SIGALRM:
00386 #endif
00387 #ifdef SIGUSR1
00388 case SIGUSR1:
00389 #endif
00390 #ifdef SIGUSR2
00391 case SIGUSR2:
00392 #endif
00393 rb_thread_signal_raise(signo2signm(sig));
00394 break;
00395 }
00396 }
00397 else {
00398 rb_thread_trap_eval(trap_list[sig].cmd, sig, trap_list[sig].safe);
00399 }
00400 }
00401
00402 static RETSIGTYPE sighandler (int);
00403 static RETSIGTYPE
00404 sighandler(sig)
00405 int sig;
00406 {
00407 #ifdef _WIN32
00408 #define IN_MAIN_CONTEXT(f, a) (rb_w32_main_context(a, f) ? (void)0 : f(a))
00409 #else
00410 #define IN_MAIN_CONTEXT(f, a) f(a)
00411 #endif
00412
00413 if (sig >= NSIG) {
00414 rb_bug("trap_handler: Bad signal %d", sig);
00415 }
00416
00417 #if !defined(BSD_SIGNAL) && !defined(POSIX_SIGNAL)
00418 ruby_signal(sig, sighandler);
00419 #endif
00420
00421 if (ATOMIC_TEST(rb_trap_immediate)) {
00422 IN_MAIN_CONTEXT(signal_exec, sig);
00423 ATOMIC_SET(rb_trap_immediate, 1);
00424 }
00425 else {
00426 ATOMIC_INC(rb_trap_pending);
00427 ATOMIC_INC(trap_pending_list[sig]);
00428 }
00429 }
00430
00431 #ifdef SIGBUS
00432 static RETSIGTYPE sigbus (int);
00433 static RETSIGTYPE
00434 sigbus(sig)
00435 int sig;
00436 {
00437 rb_bug("Bus Error");
00438 }
00439 #endif
00440
00441 #ifdef SIGSEGV
00442 static RETSIGTYPE sigsegv (int);
00443 static RETSIGTYPE
00444 sigsegv(sig)
00445 int sig;
00446 {
00447 rb_bug("Segmentation fault");
00448 }
00449 #endif
00450
00451 #ifdef SIGPIPE
00452 static RETSIGTYPE sigpipe (int);
00453 static RETSIGTYPE
00454 sigpipe(sig)
00455 int sig;
00456 {
00457
00458 }
00459 #endif
00460
00461 void
00462 rb_trap_exit()
00463 {
00464 #ifndef MACOS_UNUSE_SIGNAL
00465 if (trap_list[0].cmd) {
00466 VALUE trap_exit = trap_list[0].cmd;
00467
00468 trap_list[0].cmd = 0;
00469 rb_eval_cmd(trap_exit, rb_ary_new3(1, INT2FIX(0)), trap_list[0].safe);
00470 }
00471 #endif
00472 }
00473
00474 void
00475 rb_trap_exec()
00476 {
00477 #ifndef MACOS_UNUSE_SIGNAL
00478 int i;
00479
00480 for (i=0; i<NSIG; i++) {
00481 if (trap_pending_list[i]) {
00482 trap_pending_list[i] = 0;
00483 signal_exec(i);
00484 }
00485 }
00486 #endif
00487 rb_trap_pending = 0;
00488 }
00489
00490 struct trap_arg {
00491 #ifndef _WIN32
00492 # ifdef HAVE_SIGPROCMASK
00493 sigset_t mask;
00494 # else
00495 int mask;
00496 # endif
00497 #endif
00498 VALUE sig, cmd;
00499 };
00500
00501 # ifdef HAVE_SIGPROCMASK
00502 static sigset_t trap_last_mask;
00503 # else
00504 static int trap_last_mask;
00505 # endif
00506
00507 static RETSIGTYPE sigexit (int);
00508 static RETSIGTYPE
00509 sigexit(sig)
00510 int sig;
00511 {
00512 rb_thread_signal_exit();
00513 }
00514
00515 static VALUE
00516 trap(arg)
00517 struct trap_arg *arg;
00518 {
00519 sighandler_t func, oldfunc;
00520 VALUE command, oldcmd;
00521 int sig = -1;
00522 char *s;
00523
00524 func = sighandler;
00525 command = arg->cmd;
00526 if (NIL_P(command)) {
00527 func = SIG_IGN;
00528 }
00529 else if (TYPE(command) == T_STRING) {
00530 SafeStringValue(command);
00531 if (RSTRING(command)->len == 0) {
00532 func = SIG_IGN;
00533 }
00534 else if (RSTRING(command)->len == 7) {
00535 if (strncmp(RSTRING(command)->ptr, "SIG_IGN", 7) == 0) {
00536 func = SIG_IGN;
00537 }
00538 else if (strncmp(RSTRING(command)->ptr, "SIG_DFL", 7) == 0) {
00539 func = SIG_DFL;
00540 }
00541 else if (strncmp(RSTRING(command)->ptr, "DEFAULT", 7) == 0) {
00542 func = SIG_DFL;
00543 }
00544 }
00545 else if (RSTRING(command)->len == 6) {
00546 if (strncmp(RSTRING(command)->ptr, "IGNORE", 6) == 0) {
00547 func = SIG_IGN;
00548 }
00549 }
00550 else if (RSTRING(command)->len == 4) {
00551 if (strncmp(RSTRING(command)->ptr, "EXIT", 4) == 0) {
00552 func = sigexit;
00553 }
00554 }
00555 }
00556 if (func == SIG_IGN || func == SIG_DFL) {
00557 command = 0;
00558 }
00559
00560 switch (TYPE(arg->sig)) {
00561 case T_FIXNUM:
00562 sig = FIX2INT(arg->sig);
00563 break;
00564
00565 case T_SYMBOL:
00566 s = rb_id2name(SYM2ID(arg->sig));
00567 if (!s) rb_raise(rb_eArgError, "bad signal");
00568 goto str_signal;
00569
00570 case T_STRING:
00571 s = RSTRING(arg->sig)->ptr;
00572
00573 str_signal:
00574 if (strncmp("SIG", s, 3) == 0)
00575 s += 3;
00576 sig = signm2signo(s);
00577 if (sig == 0 && strcmp(s, "EXIT") != 0)
00578 rb_raise(rb_eArgError, "unsupported signal SIG%s", s);
00579 }
00580
00581 if (sig < 0 || sig > NSIG) {
00582 rb_raise(rb_eArgError, "invalid signal number (%d)", sig);
00583 }
00584 #if defined(HAVE_SETITIMER)
00585 if (sig == SIGVTALRM) {
00586 rb_raise(rb_eArgError, "SIGVTALRM reserved for Thread; can't set handler");
00587 }
00588 #endif
00589 if (func == SIG_DFL) {
00590 switch (sig) {
00591 case SIGINT:
00592 #ifdef SIGHUP
00593 case SIGHUP:
00594 #endif
00595 #ifdef SIGQUIT
00596 case SIGQUIT:
00597 #endif
00598 #ifdef SIGALRM
00599 case SIGALRM:
00600 #endif
00601 #ifdef SIGUSR1
00602 case SIGUSR1:
00603 #endif
00604 #ifdef SIGUSR2
00605 case SIGUSR2:
00606 #endif
00607 func = sighandler;
00608 break;
00609 #ifdef SIGBUS
00610 case SIGBUS:
00611 func = sigbus;
00612 break;
00613 #endif
00614 #ifdef SIGSEGV
00615 case SIGSEGV:
00616 func = sigsegv;
00617 break;
00618 #endif
00619 #ifdef SIGPIPE
00620 case SIGPIPE:
00621 func = sigpipe;
00622 break;
00623 #endif
00624 }
00625 }
00626 oldfunc = ruby_signal(sig, func);
00627 oldcmd = trap_list[sig].cmd;
00628 if (!oldcmd) {
00629 if (oldfunc == SIG_IGN) oldcmd = rb_str_new2("IGNORE");
00630 else if (oldfunc == sighandler) oldcmd = rb_str_new2("DEFAULT");
00631 else oldcmd = Qnil;
00632 }
00633
00634 trap_list[sig].cmd = command;
00635 trap_list[sig].safe = ruby_safe_level;
00636
00637 #ifndef _WIN32
00638 #ifdef HAVE_SIGPROCMASK
00639 sigdelset(&arg->mask, sig);
00640 #else
00641 arg->mask &= ~sigmask(sig);
00642 #endif
00643 #endif
00644 return oldcmd;
00645 }
00646
00647 #ifndef _WIN32
00648 static VALUE
00649 trap_ensure(arg)
00650 struct trap_arg *arg;
00651 {
00652
00653 #ifdef HAVE_SIGPROCMASK
00654 sigprocmask(SIG_SETMASK, &arg->mask, NULL);
00655 #else
00656 sigsetmask(arg->mask);
00657 #endif
00658 trap_last_mask = arg->mask;
00659 return 0;
00660 }
00661 #endif
00662
00663 void
00664 rb_trap_restore_mask()
00665 {
00666 #ifndef _WIN32
00667 # ifdef HAVE_SIGPROCMASK
00668 sigprocmask(SIG_SETMASK, &trap_last_mask, NULL);
00669 # else
00670 sigsetmask(trap_last_mask);
00671 # endif
00672 #endif
00673 }
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703 static VALUE
00704 sig_trap(argc, argv)
00705 int argc;
00706 VALUE *argv;
00707 {
00708 struct trap_arg arg;
00709
00710 rb_secure(2);
00711 if (argc == 0 || argc > 2) {
00712 rb_raise(rb_eArgError, "wrong number of arguments -- trap(sig, cmd)/trap(sig){...}");
00713 }
00714
00715 arg.sig = argv[0];
00716 if (argc == 1) {
00717 arg.cmd = rb_block_proc();
00718 }
00719 else if (argc == 2) {
00720 arg.cmd = argv[1];
00721 }
00722
00723 if (OBJ_TAINTED(arg.cmd)) {
00724 rb_raise(rb_eSecurityError, "Insecure: tainted signal trap");
00725 }
00726 #ifndef _WIN32
00727
00728 # ifdef HAVE_SIGPROCMASK
00729 sigfillset(&arg.mask);
00730 sigprocmask(SIG_BLOCK, &arg.mask, &arg.mask);
00731 # else
00732 arg.mask = sigblock(~0);
00733 # endif
00734
00735 return rb_ensure(trap, (VALUE)&arg, trap_ensure, (VALUE)&arg);
00736 #else
00737 return trap(&arg);
00738 #endif
00739 }
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750 static VALUE
00751 sig_list()
00752 {
00753 VALUE h = rb_hash_new();
00754 struct signals *sigs;
00755
00756 for (sigs = siglist; sigs->signm; sigs++) {
00757 rb_hash_aset(h, rb_str_new2(sigs->signm), INT2FIX(sigs->signo));
00758 }
00759 return h;
00760 }
00761
00762 static void
00763 install_sighandler(signum, handler)
00764 int signum;
00765 sighandler_t handler;
00766 {
00767 sighandler_t old;
00768
00769 old = ruby_signal(signum, handler);
00770 if (old != SIG_DFL) {
00771 ruby_signal(signum, old);
00772 }
00773 }
00774
00775 static void
00776 init_sigchld(sig)
00777 int sig;
00778 {
00779 sighandler_t oldfunc;
00780 #ifndef _WIN32
00781 # ifdef HAVE_SIGPROCMASK
00782 sigset_t mask;
00783 # else
00784 int mask;
00785 # endif
00786 #endif
00787
00788 #ifndef _WIN32
00789
00790 # ifdef HAVE_SIGPROCMASK
00791 sigfillset(&mask);
00792 sigprocmask(SIG_BLOCK, &mask, &mask);
00793 # else
00794 mask = sigblock(~0);
00795 # endif
00796 #endif
00797
00798 oldfunc = ruby_signal(sig, SIG_DFL);
00799 if (oldfunc != SIG_DFL && oldfunc != SIG_IGN) {
00800 ruby_signal(sig, oldfunc);
00801 } else {
00802 trap_list[sig].cmd = 0;
00803 }
00804
00805 #ifndef _WIN32
00806 #ifdef HAVE_SIGPROCMASK
00807 sigdelset(&mask, sig);
00808 sigprocmask(SIG_SETMASK, &mask, NULL);
00809 #else
00810 mask &= ~sigmask(sig);
00811 sigsetmask(mask);
00812 #endif
00813 trap_last_mask = mask;
00814 #endif
00815 }
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854 void
00855 Init_signal()
00856 {
00857 #ifndef MACOS_UNUSE_SIGNAL
00858 VALUE mSignal = rb_define_module("Signal");
00859
00860 rb_define_global_function("trap", sig_trap, -1);
00861 rb_define_module_function(mSignal, "trap", sig_trap, -1);
00862 rb_define_module_function(mSignal, "list", sig_list, 0);
00863
00864 install_sighandler(SIGINT, sighandler);
00865 #ifdef SIGHUP
00866 install_sighandler(SIGHUP, sighandler);
00867 #endif
00868 #ifdef SIGQUIT
00869 install_sighandler(SIGQUIT, sighandler);
00870 #endif
00871 #ifdef SIGALRM
00872 install_sighandler(SIGALRM, sighandler);
00873 #endif
00874 #ifdef SIGUSR1
00875 install_sighandler(SIGUSR1, sighandler);
00876 #endif
00877 #ifdef SIGUSR2
00878 install_sighandler(SIGUSR2, sighandler);
00879 #endif
00880
00881 #ifdef SIGBUS
00882 install_sighandler(SIGBUS, sigbus);
00883 #endif
00884 #ifdef SIGSEGV
00885 install_sighandler(SIGSEGV, sigsegv);
00886 #endif
00887 #ifdef SIGPIPE
00888 install_sighandler(SIGPIPE, sigpipe);
00889 #endif
00890
00891 #ifdef SIGCLD
00892 init_sigchld(SIGCLD);
00893 #endif
00894 #ifdef SIGCHLD
00895 init_sigchld(SIGCHLD);
00896 #endif
00897
00898 #endif
00899 }
00900