PageRenderTime 48ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/signal.c

https://github.com/fizx/ruby
C | 1167 lines | 921 code | 103 blank | 143 comment | 131 complexity | d215db811d40271cf8e14f2e84dbd982 MD5 | raw file
Possible License(s): LGPL-2.1, AGPL-3.0, GPL-2.0, BSD-3-Clause
  1. /**********************************************************************
  2. signal.c -
  3. $Author$
  4. created at: Tue Dec 20 10:13:44 JST 1994
  5. Copyright (C) 1993-2007 Yukihiro Matsumoto
  6. Copyright (C) 2000 Network Applied Communication Laboratory, Inc.
  7. Copyright (C) 2000 Information-technology Promotion Agency, Japan
  8. **********************************************************************/
  9. #include "ruby/ruby.h"
  10. #include "vm_core.h"
  11. #include <signal.h>
  12. #include <stdio.h>
  13. #include <errno.h>
  14. #ifdef _WIN32
  15. typedef LONG rb_atomic_t;
  16. # define ATOMIC_TEST(var) InterlockedExchange(&(var), 0)
  17. # define ATOMIC_SET(var, val) InterlockedExchange(&(var), (val))
  18. # define ATOMIC_INC(var) InterlockedIncrement(&(var))
  19. # define ATOMIC_DEC(var) InterlockedDecrement(&(var))
  20. #else
  21. typedef int rb_atomic_t;
  22. # define ATOMIC_TEST(var) ((var) ? ((var) = 0, 1) : 0)
  23. # define ATOMIC_SET(var, val) ((var) = (val))
  24. # define ATOMIC_INC(var) (++(var))
  25. # define ATOMIC_DEC(var) (--(var))
  26. #endif
  27. #if defined(__BEOS__) || defined(__HAIKU__)
  28. #undef SIGBUS
  29. #endif
  30. #if defined HAVE_SIGPROCMASK || defined HAVE_SIGSETMASK
  31. #define USE_TRAP_MASK 1
  32. #else
  33. #define USE_TRAP_MASK 0
  34. #endif
  35. #ifndef NSIG
  36. # define NSIG (_SIGMAX + 1) /* For QNX */
  37. #endif
  38. static const struct signals {
  39. const char *signm;
  40. int signo;
  41. } siglist [] = {
  42. {"EXIT", 0},
  43. #ifdef SIGHUP
  44. {"HUP", SIGHUP},
  45. #endif
  46. {"INT", SIGINT},
  47. #ifdef SIGQUIT
  48. {"QUIT", SIGQUIT},
  49. #endif
  50. #ifdef SIGILL
  51. {"ILL", SIGILL},
  52. #endif
  53. #ifdef SIGTRAP
  54. {"TRAP", SIGTRAP},
  55. #endif
  56. #ifdef SIGIOT
  57. {"IOT", SIGIOT},
  58. #endif
  59. #ifdef SIGABRT
  60. {"ABRT", SIGABRT},
  61. #endif
  62. #ifdef SIGEMT
  63. {"EMT", SIGEMT},
  64. #endif
  65. #ifdef SIGFPE
  66. {"FPE", SIGFPE},
  67. #endif
  68. #ifdef SIGKILL
  69. {"KILL", SIGKILL},
  70. #endif
  71. #ifdef SIGBUS
  72. {"BUS", SIGBUS},
  73. #endif
  74. #ifdef SIGSEGV
  75. {"SEGV", SIGSEGV},
  76. #endif
  77. #ifdef SIGSYS
  78. {"SYS", SIGSYS},
  79. #endif
  80. #ifdef SIGPIPE
  81. {"PIPE", SIGPIPE},
  82. #endif
  83. #ifdef SIGALRM
  84. {"ALRM", SIGALRM},
  85. #endif
  86. #ifdef SIGTERM
  87. {"TERM", SIGTERM},
  88. #endif
  89. #ifdef SIGURG
  90. {"URG", SIGURG},
  91. #endif
  92. #ifdef SIGSTOP
  93. {"STOP", SIGSTOP},
  94. #endif
  95. #ifdef SIGTSTP
  96. {"TSTP", SIGTSTP},
  97. #endif
  98. #ifdef SIGCONT
  99. {"CONT", SIGCONT},
  100. #endif
  101. #ifdef SIGCHLD
  102. {"CHLD", SIGCHLD},
  103. #endif
  104. #ifdef SIGCLD
  105. {"CLD", SIGCLD},
  106. #else
  107. # ifdef SIGCHLD
  108. {"CLD", SIGCHLD},
  109. # endif
  110. #endif
  111. #ifdef SIGTTIN
  112. {"TTIN", SIGTTIN},
  113. #endif
  114. #ifdef SIGTTOU
  115. {"TTOU", SIGTTOU},
  116. #endif
  117. #ifdef SIGIO
  118. {"IO", SIGIO},
  119. #endif
  120. #ifdef SIGXCPU
  121. {"XCPU", SIGXCPU},
  122. #endif
  123. #ifdef SIGXFSZ
  124. {"XFSZ", SIGXFSZ},
  125. #endif
  126. #ifdef SIGVTALRM
  127. {"VTALRM", SIGVTALRM},
  128. #endif
  129. #ifdef SIGPROF
  130. {"PROF", SIGPROF},
  131. #endif
  132. #ifdef SIGWINCH
  133. {"WINCH", SIGWINCH},
  134. #endif
  135. #ifdef SIGUSR1
  136. {"USR1", SIGUSR1},
  137. #endif
  138. #ifdef SIGUSR2
  139. {"USR2", SIGUSR2},
  140. #endif
  141. #ifdef SIGLOST
  142. {"LOST", SIGLOST},
  143. #endif
  144. #ifdef SIGMSG
  145. {"MSG", SIGMSG},
  146. #endif
  147. #ifdef SIGPWR
  148. {"PWR", SIGPWR},
  149. #endif
  150. #ifdef SIGPOLL
  151. {"POLL", SIGPOLL},
  152. #endif
  153. #ifdef SIGDANGER
  154. {"DANGER", SIGDANGER},
  155. #endif
  156. #ifdef SIGMIGRATE
  157. {"MIGRATE", SIGMIGRATE},
  158. #endif
  159. #ifdef SIGPRE
  160. {"PRE", SIGPRE},
  161. #endif
  162. #ifdef SIGGRANT
  163. {"GRANT", SIGGRANT},
  164. #endif
  165. #ifdef SIGRETRACT
  166. {"RETRACT", SIGRETRACT},
  167. #endif
  168. #ifdef SIGSOUND
  169. {"SOUND", SIGSOUND},
  170. #endif
  171. #ifdef SIGINFO
  172. {"INFO", SIGINFO},
  173. #endif
  174. {NULL, 0}
  175. };
  176. static int
  177. signm2signo(const char *nm)
  178. {
  179. const struct signals *sigs;
  180. for (sigs = siglist; sigs->signm; sigs++)
  181. if (strcmp(sigs->signm, nm) == 0)
  182. return sigs->signo;
  183. return 0;
  184. }
  185. static const char*
  186. signo2signm(int no)
  187. {
  188. const struct signals *sigs;
  189. for (sigs = siglist; sigs->signm; sigs++)
  190. if (sigs->signo == no)
  191. return sigs->signm;
  192. return 0;
  193. }
  194. const char *
  195. ruby_signal_name(int no)
  196. {
  197. return signo2signm(no);
  198. }
  199. /*
  200. * call-seq:
  201. * SignalException.new(sig) => signal_exception
  202. *
  203. * Construct a new SignalException object. +sig+ should be a known
  204. * signal name, or a signal number.
  205. */
  206. static VALUE
  207. esignal_init(int argc, VALUE *argv, VALUE self)
  208. {
  209. int argnum = 1;
  210. VALUE sig = Qnil;
  211. int signo;
  212. const char *signm;
  213. if (argc > 0) {
  214. sig = rb_check_to_integer(argv[0], "to_int");
  215. if (!NIL_P(sig)) argnum = 2;
  216. else sig = argv[0];
  217. }
  218. if (argc < 1 || argnum < argc) {
  219. rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)",
  220. argc, argnum);
  221. }
  222. if (argnum == 2) {
  223. signo = NUM2INT(sig);
  224. if (signo < 0 || signo > NSIG) {
  225. rb_raise(rb_eArgError, "invalid signal number (%d)", signo);
  226. }
  227. if (argc > 1) {
  228. sig = argv[1];
  229. }
  230. else {
  231. signm = signo2signm(signo);
  232. if (signm) {
  233. sig = rb_sprintf("SIG%s", signm);
  234. }
  235. else {
  236. sig = rb_sprintf("SIG%u", signo);
  237. }
  238. }
  239. }
  240. else {
  241. signm = SYMBOL_P(sig) ? rb_id2name(SYM2ID(sig)) : StringValuePtr(sig);
  242. if (strncmp(signm, "SIG", 3) == 0) signm += 3;
  243. signo = signm2signo(signm);
  244. if (!signo) {
  245. rb_raise(rb_eArgError, "unsupported name `SIG%s'", signm);
  246. }
  247. sig = rb_sprintf("SIG%s", signm);
  248. }
  249. rb_call_super(1, &sig);
  250. rb_iv_set(self, "signo", INT2NUM(signo));
  251. return self;
  252. }
  253. /*
  254. * call-seq:
  255. * signal_exception.signo => num
  256. *
  257. * Returns a signal number.
  258. */
  259. static VALUE
  260. esignal_signo(VALUE self)
  261. {
  262. return rb_iv_get(self, "signo");
  263. }
  264. /* :nodoc: */
  265. static VALUE
  266. interrupt_init(int argc, VALUE *argv, VALUE self)
  267. {
  268. VALUE args[2];
  269. args[0] = INT2FIX(SIGINT);
  270. rb_scan_args(argc, argv, "01", &args[1]);
  271. return rb_call_super(2, args);
  272. }
  273. void
  274. ruby_default_signal(int sig)
  275. {
  276. signal(sig, SIG_DFL);
  277. raise(sig);
  278. }
  279. /*
  280. * call-seq:
  281. * Process.kill(signal, pid, ...) => fixnum
  282. *
  283. * Sends the given signal to the specified process id(s), or to the
  284. * current process if _pid_ is zero. _signal_ may be an
  285. * integer signal number or a POSIX signal name (either with or without
  286. * a +SIG+ prefix). If _signal_ is negative (or starts
  287. * with a minus sign), kills process groups instead of
  288. * processes. Not all signals are available on all platforms.
  289. *
  290. * pid = fork do
  291. * Signal.trap("HUP") { puts "Ouch!"; exit }
  292. * # ... do some work ...
  293. * end
  294. * # ...
  295. * Process.kill("HUP", pid)
  296. * Process.wait
  297. *
  298. * <em>produces:</em>
  299. *
  300. * Ouch!
  301. *
  302. * If _signal_ is an integer but wrong for signal,
  303. * <code>Errno::EINVAL</code> or +RangeError+ will be raised.
  304. * Otherwise unless _signal_ is a +String+ or a +Symbol+, and a known
  305. * signal name, +ArgumentError+ will be raised.
  306. *
  307. * Also, <code>Errno::ESRCH</code> or +RangeError+ for invalid _pid_,
  308. * <code>Errno::EPERM</code> when failed because of no privilege,
  309. * will be raised. In these cases, signals may have been sent to
  310. * preceding processes.
  311. */
  312. VALUE
  313. rb_f_kill(int argc, VALUE *argv)
  314. {
  315. #ifndef HAS_KILLPG
  316. #define killpg(pg, sig) kill(-(pg), sig)
  317. #endif
  318. int negative = 0;
  319. int sig;
  320. int i;
  321. const char *s;
  322. rb_secure(2);
  323. if (argc < 2)
  324. rb_raise(rb_eArgError, "wrong number of arguments -- kill(sig, pid...)");
  325. switch (TYPE(argv[0])) {
  326. case T_FIXNUM:
  327. sig = FIX2INT(argv[0]);
  328. break;
  329. case T_SYMBOL:
  330. s = rb_id2name(SYM2ID(argv[0]));
  331. if (!s) rb_raise(rb_eArgError, "bad signal");
  332. goto str_signal;
  333. case T_STRING:
  334. s = RSTRING_PTR(argv[0]);
  335. if (s[0] == '-') {
  336. negative++;
  337. s++;
  338. }
  339. str_signal:
  340. if (strncmp("SIG", s, 3) == 0)
  341. s += 3;
  342. if((sig = signm2signo(s)) == 0)
  343. rb_raise(rb_eArgError, "unsupported name `SIG%s'", s);
  344. if (negative)
  345. sig = -sig;
  346. break;
  347. default:
  348. {
  349. VALUE str;
  350. str = rb_check_string_type(argv[0]);
  351. if (!NIL_P(str)) {
  352. s = RSTRING_PTR(str);
  353. goto str_signal;
  354. }
  355. rb_raise(rb_eArgError, "bad signal type %s",
  356. rb_obj_classname(argv[0]));
  357. }
  358. break;
  359. }
  360. if (sig < 0) {
  361. sig = -sig;
  362. for (i=1; i<argc; i++) {
  363. if (killpg(NUM2PIDT(argv[i]), sig) < 0)
  364. rb_sys_fail(0);
  365. }
  366. }
  367. else {
  368. for (i=1; i<argc; i++) {
  369. if (kill(NUM2PIDT(argv[i]), sig) < 0)
  370. rb_sys_fail(0);
  371. }
  372. }
  373. rb_thread_polling();
  374. return INT2FIX(i-1);
  375. }
  376. static struct {
  377. rb_atomic_t cnt[RUBY_NSIG];
  378. rb_atomic_t size;
  379. } signal_buff;
  380. #ifdef __dietlibc__
  381. #define sighandler_t sh_t
  382. #endif
  383. #if defined(SIGSEGV) && defined(HAVE_SIGALTSTACK) && defined(SA_SIGINFO)
  384. #define USE_SIGALTSTACK
  385. #endif
  386. typedef RETSIGTYPE (*sighandler_t)(int);
  387. #ifdef USE_SIGALTSTACK
  388. typedef void ruby_sigaction_t(int, siginfo_t*, void*);
  389. #define SIGINFO_ARG , siginfo_t *info, void *ctx
  390. #else
  391. typedef RETSIGTYPE ruby_sigaction_t(int);
  392. #define SIGINFO_ARG
  393. #endif
  394. #ifdef POSIX_SIGNAL
  395. #ifdef USE_SIGALTSTACK
  396. #ifdef SIGSTKSZ
  397. #define ALT_STACK_SIZE (SIGSTKSZ*2)
  398. #else
  399. #define ALT_STACK_SIZE (4*1024)
  400. #endif
  401. /* alternate stack for SIGSEGV */
  402. static void
  403. register_sigaltstack(void)
  404. {
  405. static void *altstack = 0;
  406. stack_t newSS, oldSS;
  407. if (altstack) return;
  408. newSS.ss_sp = altstack = malloc(ALT_STACK_SIZE);
  409. if (newSS.ss_sp == NULL)
  410. /* should handle error */
  411. rb_bug("register_sigaltstack. malloc error\n");
  412. newSS.ss_size = ALT_STACK_SIZE;
  413. newSS.ss_flags = 0;
  414. sigaltstack(&newSS, &oldSS); /* ignore error. */
  415. }
  416. #endif
  417. static sighandler_t
  418. ruby_signal(int signum, sighandler_t handler)
  419. {
  420. struct sigaction sigact, old;
  421. #if 0
  422. rb_trap_accept_nativethreads[signum] = 0;
  423. #endif
  424. sigemptyset(&sigact.sa_mask);
  425. #ifdef SA_SIGINFO
  426. sigact.sa_sigaction = (ruby_sigaction_t*)handler;
  427. sigact.sa_flags = SA_SIGINFO;
  428. #else
  429. sigact.sa_handler = handler;
  430. sigact.sa_flags = 0;
  431. #endif
  432. #ifdef SA_NOCLDWAIT
  433. if (signum == SIGCHLD && handler == SIG_IGN)
  434. sigact.sa_flags |= SA_NOCLDWAIT;
  435. #endif
  436. #if defined(SA_ONSTACK) && defined(USE_SIGALTSTACK)
  437. if (signum == SIGSEGV)
  438. sigact.sa_flags |= SA_ONSTACK;
  439. #endif
  440. if (sigaction(signum, &sigact, &old) < 0) {
  441. if (errno != 0 && errno != EINVAL) {
  442. rb_bug_errno("sigaction", errno);
  443. }
  444. }
  445. return old.sa_handler;
  446. }
  447. sighandler_t
  448. posix_signal(int signum, sighandler_t handler)
  449. {
  450. return ruby_signal(signum, handler);
  451. }
  452. #else /* !POSIX_SIGNAL */
  453. #define ruby_signal(sig,handler) (/* rb_trap_accept_nativethreads[sig] = 0,*/ signal((sig),(handler)))
  454. #if 0 /* def HAVE_NATIVETHREAD */
  455. static sighandler_t
  456. ruby_nativethread_signal(int signum, sighandler_t handler)
  457. {
  458. sighandler_t old;
  459. old = signal(signum, handler);
  460. rb_trap_accept_nativethreads[signum] = 1;
  461. return old;
  462. }
  463. #endif
  464. #endif
  465. static RETSIGTYPE
  466. sighandler(int sig)
  467. {
  468. ATOMIC_INC(signal_buff.cnt[sig]);
  469. ATOMIC_INC(signal_buff.size);
  470. #if !defined(BSD_SIGNAL) && !defined(POSIX_SIGNAL)
  471. ruby_signal(sig, sighandler);
  472. #endif
  473. }
  474. int
  475. rb_signal_buff_size(void)
  476. {
  477. return signal_buff.size;
  478. }
  479. #if USE_TRAP_MASK
  480. # ifdef HAVE_SIGPROCMASK
  481. static sigset_t trap_last_mask;
  482. # else
  483. static int trap_last_mask;
  484. # endif
  485. #endif
  486. #if HAVE_PTHREAD_H
  487. #include <pthread.h>
  488. #endif
  489. void
  490. rb_disable_interrupt(void)
  491. {
  492. #if USE_TRAP_MASK
  493. sigset_t mask;
  494. sigfillset(&mask);
  495. sigdelset(&mask, SIGVTALRM);
  496. sigdelset(&mask, SIGSEGV);
  497. pthread_sigmask(SIG_SETMASK, &mask, NULL);
  498. #endif
  499. }
  500. void
  501. rb_enable_interrupt(void)
  502. {
  503. #if USE_TRAP_MASK
  504. sigset_t mask;
  505. sigemptyset(&mask);
  506. pthread_sigmask(SIG_SETMASK, &mask, NULL);
  507. #endif
  508. }
  509. int
  510. rb_get_next_signal(void)
  511. {
  512. int i, sig = 0;
  513. for (i=1; i<RUBY_NSIG; i++) {
  514. if (signal_buff.cnt[i] > 0) {
  515. rb_disable_interrupt();
  516. {
  517. ATOMIC_DEC(signal_buff.cnt[i]);
  518. ATOMIC_DEC(signal_buff.size);
  519. }
  520. rb_enable_interrupt();
  521. sig = i;
  522. break;
  523. }
  524. }
  525. return sig;
  526. }
  527. #ifdef SIGBUS
  528. static RETSIGTYPE
  529. sigbus(int sig)
  530. {
  531. rb_bug("Bus Error");
  532. }
  533. #endif
  534. #ifdef SIGSEGV
  535. static int segv_received = 0;
  536. static RETSIGTYPE
  537. sigsegv(int sig SIGINFO_ARG)
  538. {
  539. #ifdef USE_SIGALTSTACK
  540. int ruby_stack_overflowed_p(const rb_thread_t *, const void *);
  541. NORETURN(void ruby_thread_stack_overflow(rb_thread_t *th));
  542. rb_thread_t *th = GET_THREAD();
  543. if (ruby_stack_overflowed_p(th, info->si_addr)) {
  544. ruby_thread_stack_overflow(th);
  545. }
  546. #endif
  547. if (segv_received) {
  548. fprintf(stderr, "SEGV received in SEGV handler\n");
  549. exit(EXIT_FAILURE);
  550. }
  551. else {
  552. extern int ruby_disable_gc_stress;
  553. segv_received = 1;
  554. ruby_disable_gc_stress = 1;
  555. rb_bug("Segmentation fault");
  556. }
  557. }
  558. #endif
  559. #ifdef SIGPIPE
  560. static RETSIGTYPE
  561. sigpipe(int sig)
  562. {
  563. /* do nothing */
  564. }
  565. #endif
  566. static void
  567. signal_exec(VALUE cmd, int safe, int sig)
  568. {
  569. VALUE signum = INT2NUM(sig);
  570. rb_eval_cmd(cmd, rb_ary_new3(1, signum), safe);
  571. }
  572. void
  573. rb_trap_exit(void)
  574. {
  575. rb_vm_t *vm = GET_VM();
  576. VALUE trap_exit = vm->trap_list[0].cmd;
  577. if (trap_exit) {
  578. vm->trap_list[0].cmd = 0;
  579. signal_exec(trap_exit, vm->trap_list[0].safe, 0);
  580. }
  581. }
  582. void
  583. rb_signal_exec(rb_thread_t *th, int sig)
  584. {
  585. rb_vm_t *vm = GET_VM();
  586. VALUE cmd = vm->trap_list[sig].cmd;
  587. int safe = vm->trap_list[sig].safe;
  588. if (cmd == 0) {
  589. switch (sig) {
  590. case SIGINT:
  591. rb_interrupt();
  592. break;
  593. #ifdef SIGHUP
  594. case SIGHUP:
  595. #endif
  596. #ifdef SIGQUIT
  597. case SIGQUIT:
  598. #endif
  599. #ifdef SIGTERM
  600. case SIGTERM:
  601. #endif
  602. #ifdef SIGALRM
  603. case SIGALRM:
  604. #endif
  605. #ifdef SIGUSR1
  606. case SIGUSR1:
  607. #endif
  608. #ifdef SIGUSR2
  609. case SIGUSR2:
  610. #endif
  611. rb_threadptr_signal_raise(th, sig);
  612. break;
  613. }
  614. }
  615. else if (cmd == Qundef) {
  616. rb_threadptr_signal_exit(th);
  617. }
  618. else {
  619. signal_exec(cmd, safe, sig);
  620. }
  621. }
  622. struct trap_arg {
  623. #if USE_TRAP_MASK
  624. # ifdef HAVE_SIGPROCMASK
  625. sigset_t mask;
  626. # else
  627. int mask;
  628. # endif
  629. #endif
  630. int sig;
  631. sighandler_t func;
  632. VALUE cmd;
  633. };
  634. static sighandler_t
  635. default_handler(int sig)
  636. {
  637. sighandler_t func;
  638. switch (sig) {
  639. case SIGINT:
  640. #ifdef SIGHUP
  641. case SIGHUP:
  642. #endif
  643. #ifdef SIGQUIT
  644. case SIGQUIT:
  645. #endif
  646. #ifdef SIGTERM
  647. case SIGTERM:
  648. #endif
  649. #ifdef SIGALRM
  650. case SIGALRM:
  651. #endif
  652. #ifdef SIGUSR1
  653. case SIGUSR1:
  654. #endif
  655. #ifdef SIGUSR2
  656. case SIGUSR2:
  657. #endif
  658. func = sighandler;
  659. break;
  660. #ifdef SIGBUS
  661. case SIGBUS:
  662. func = sigbus;
  663. break;
  664. #endif
  665. #ifdef SIGSEGV
  666. case SIGSEGV:
  667. func = (sighandler_t)sigsegv;
  668. # ifdef USE_SIGALTSTACK
  669. register_sigaltstack();
  670. # endif
  671. break;
  672. #endif
  673. #ifdef SIGPIPE
  674. case SIGPIPE:
  675. func = sigpipe;
  676. break;
  677. #endif
  678. default:
  679. func = SIG_DFL;
  680. break;
  681. }
  682. return func;
  683. }
  684. static sighandler_t
  685. trap_handler(VALUE *cmd, int sig)
  686. {
  687. sighandler_t func = sighandler;
  688. VALUE command;
  689. if (NIL_P(*cmd)) {
  690. func = SIG_IGN;
  691. }
  692. else {
  693. command = rb_check_string_type(*cmd);
  694. if (NIL_P(command) && SYMBOL_P(*cmd)) {
  695. command = rb_id2str(SYM2ID(*cmd));
  696. if (!command) rb_raise(rb_eArgError, "bad handler");
  697. }
  698. if (!NIL_P(command)) {
  699. SafeStringValue(command); /* taint check */
  700. *cmd = command;
  701. switch (RSTRING_LEN(command)) {
  702. case 0:
  703. goto sig_ign;
  704. break;
  705. case 14:
  706. if (strncmp(RSTRING_PTR(command), "SYSTEM_DEFAULT", 14) == 0) {
  707. func = SIG_DFL;
  708. *cmd = 0;
  709. }
  710. break;
  711. case 7:
  712. if (strncmp(RSTRING_PTR(command), "SIG_IGN", 7) == 0) {
  713. sig_ign:
  714. func = SIG_IGN;
  715. *cmd = 0;
  716. }
  717. else if (strncmp(RSTRING_PTR(command), "SIG_DFL", 7) == 0) {
  718. sig_dfl:
  719. func = default_handler(sig);
  720. *cmd = 0;
  721. }
  722. else if (strncmp(RSTRING_PTR(command), "DEFAULT", 7) == 0) {
  723. goto sig_dfl;
  724. }
  725. break;
  726. case 6:
  727. if (strncmp(RSTRING_PTR(command), "IGNORE", 6) == 0) {
  728. goto sig_ign;
  729. }
  730. break;
  731. case 4:
  732. if (strncmp(RSTRING_PTR(command), "EXIT", 4) == 0) {
  733. *cmd = Qundef;
  734. }
  735. break;
  736. }
  737. }
  738. else {
  739. rb_proc_t *proc;
  740. GetProcPtr(*cmd, proc);
  741. }
  742. }
  743. return func;
  744. }
  745. static int
  746. trap_signm(VALUE vsig)
  747. {
  748. int sig = -1;
  749. const char *s;
  750. switch (TYPE(vsig)) {
  751. case T_FIXNUM:
  752. sig = FIX2INT(vsig);
  753. if (sig < 0 || sig >= NSIG) {
  754. rb_raise(rb_eArgError, "invalid signal number (%d)", sig);
  755. }
  756. break;
  757. case T_SYMBOL:
  758. s = rb_id2name(SYM2ID(vsig));
  759. if (!s) rb_raise(rb_eArgError, "bad signal");
  760. goto str_signal;
  761. default:
  762. s = StringValuePtr(vsig);
  763. str_signal:
  764. if (strncmp("SIG", s, 3) == 0)
  765. s += 3;
  766. sig = signm2signo(s);
  767. if (sig == 0 && strcmp(s, "EXIT") != 0)
  768. rb_raise(rb_eArgError, "unsupported signal SIG%s", s);
  769. }
  770. return sig;
  771. }
  772. static VALUE
  773. trap(struct trap_arg *arg)
  774. {
  775. sighandler_t oldfunc, func = arg->func;
  776. VALUE oldcmd, command = arg->cmd;
  777. int sig = arg->sig;
  778. rb_vm_t *vm = GET_VM();
  779. oldfunc = ruby_signal(sig, func);
  780. oldcmd = vm->trap_list[sig].cmd;
  781. switch (oldcmd) {
  782. case 0:
  783. if (oldfunc == SIG_IGN) oldcmd = rb_str_new2("IGNORE");
  784. else if (oldfunc == sighandler) oldcmd = rb_str_new2("DEFAULT");
  785. else oldcmd = Qnil;
  786. break;
  787. case Qundef:
  788. oldcmd = rb_str_new2("EXIT");
  789. break;
  790. }
  791. vm->trap_list[sig].cmd = command;
  792. vm->trap_list[sig].safe = rb_safe_level();
  793. /* enable at least specified signal. */
  794. #if USE_TRAP_MASK
  795. #ifdef HAVE_SIGPROCMASK
  796. sigdelset(&arg->mask, sig);
  797. #else
  798. arg->mask &= ~sigmask(sig);
  799. #endif
  800. #endif
  801. return oldcmd;
  802. }
  803. #if USE_TRAP_MASK
  804. static VALUE
  805. trap_ensure(struct trap_arg *arg)
  806. {
  807. /* enable interrupt */
  808. #ifdef HAVE_SIGPROCMASK
  809. sigprocmask(SIG_SETMASK, &arg->mask, NULL);
  810. #else
  811. sigsetmask(arg->mask);
  812. #endif
  813. trap_last_mask = arg->mask;
  814. return 0;
  815. }
  816. #endif
  817. void
  818. rb_trap_restore_mask(void)
  819. {
  820. #if USE_TRAP_MASK
  821. # ifdef HAVE_SIGPROCMASK
  822. sigprocmask(SIG_SETMASK, &trap_last_mask, NULL);
  823. # else
  824. sigsetmask(trap_last_mask);
  825. # endif
  826. #endif
  827. }
  828. /*
  829. * call-seq:
  830. * Signal.trap( signal, command ) => obj
  831. * Signal.trap( signal ) {| | block } => obj
  832. *
  833. * Specifies the handling of signals. The first parameter is a signal
  834. * name (a string such as ``SIGALRM'', ``SIGUSR1'', and so on) or a
  835. * signal number. The characters ``SIG'' may be omitted from the
  836. * signal name. The command or block specifies code to be run when the
  837. * signal is raised.
  838. * If the command is the string ``IGNORE'' or ``SIG_IGN'', the signal
  839. * will be ignored.
  840. * If the command is ``DEFAULT'' or ``SIG_DFL'', the Ruby's default handler
  841. * will be invoked.
  842. * If the command is ``EXIT'', the script will be terminated by the signal.
  843. * If the command is ``SYSTEM_DEFAULT'', the operating system's default
  844. * handler will be invoked.
  845. * Otherwise, the given command or block will be run.
  846. * The special signal name ``EXIT'' or signal number zero will be
  847. * invoked just prior to program termination.
  848. * trap returns the previous handler for the given signal.
  849. *
  850. * Signal.trap(0, proc { puts "Terminating: #{$$}" })
  851. * Signal.trap("CLD") { puts "Child died" }
  852. * fork && Process.wait
  853. *
  854. * produces:
  855. * Terminating: 27461
  856. * Child died
  857. * Terminating: 27460
  858. */
  859. static VALUE
  860. sig_trap(int argc, VALUE *argv)
  861. {
  862. struct trap_arg arg;
  863. rb_secure(2);
  864. if (argc < 1 || argc > 2) {
  865. rb_raise(rb_eArgError, "wrong number of arguments -- trap(sig, cmd)/trap(sig){...}");
  866. }
  867. arg.sig = trap_signm(argv[0]);
  868. if (argc == 1) {
  869. arg.cmd = rb_block_proc();
  870. arg.func = sighandler;
  871. }
  872. else {
  873. arg.cmd = argv[1];
  874. arg.func = trap_handler(&arg.cmd, arg.sig);
  875. }
  876. if (OBJ_TAINTED(arg.cmd)) {
  877. rb_raise(rb_eSecurityError, "Insecure: tainted signal trap");
  878. }
  879. #if USE_TRAP_MASK
  880. /* disable interrupt */
  881. # ifdef HAVE_SIGPROCMASK
  882. sigfillset(&arg.mask);
  883. sigprocmask(SIG_BLOCK, &arg.mask, &arg.mask);
  884. # else
  885. arg.mask = sigblock(~0);
  886. # endif
  887. return rb_ensure(trap, (VALUE)&arg, trap_ensure, (VALUE)&arg);
  888. #else
  889. return trap(&arg);
  890. #endif
  891. }
  892. /*
  893. * call-seq:
  894. * Signal.list => a_hash
  895. *
  896. * Returns a list of signal names mapped to the corresponding
  897. * underlying signal numbers.
  898. *
  899. * 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}
  900. */
  901. static VALUE
  902. sig_list(void)
  903. {
  904. VALUE h = rb_hash_new();
  905. const struct signals *sigs;
  906. for (sigs = siglist; sigs->signm; sigs++) {
  907. rb_hash_aset(h, rb_str_new2(sigs->signm), INT2FIX(sigs->signo));
  908. }
  909. return h;
  910. }
  911. static void
  912. install_sighandler(int signum, sighandler_t handler)
  913. {
  914. sighandler_t old;
  915. old = ruby_signal(signum, handler);
  916. if (old != SIG_DFL) {
  917. ruby_signal(signum, old);
  918. }
  919. }
  920. #if defined(SIGCLD) || defined(SIGCHLD)
  921. static void
  922. init_sigchld(int sig)
  923. {
  924. sighandler_t oldfunc;
  925. #if USE_TRAP_MASK
  926. # ifdef HAVE_SIGPROCMASK
  927. sigset_t mask;
  928. # else
  929. int mask;
  930. # endif
  931. #endif
  932. #if USE_TRAP_MASK
  933. /* disable interrupt */
  934. # ifdef HAVE_SIGPROCMASK
  935. sigfillset(&mask);
  936. sigprocmask(SIG_BLOCK, &mask, &mask);
  937. # else
  938. mask = sigblock(~0);
  939. # endif
  940. #endif
  941. oldfunc = ruby_signal(sig, SIG_DFL);
  942. if (oldfunc != SIG_DFL && oldfunc != SIG_IGN) {
  943. ruby_signal(sig, oldfunc);
  944. } else {
  945. GET_VM()->trap_list[sig].cmd = 0;
  946. }
  947. #if USE_TRAP_MASK
  948. #ifdef HAVE_SIGPROCMASK
  949. sigdelset(&mask, sig);
  950. sigprocmask(SIG_SETMASK, &mask, NULL);
  951. #else
  952. mask &= ~sigmask(sig);
  953. sigsetmask(mask);
  954. #endif
  955. trap_last_mask = mask;
  956. #endif
  957. }
  958. #endif
  959. void
  960. ruby_sig_finalize(void)
  961. {
  962. sighandler_t oldfunc;
  963. oldfunc = ruby_signal(SIGINT, SIG_IGN);
  964. if (oldfunc == sighandler) {
  965. ruby_signal(SIGINT, SIG_DFL);
  966. }
  967. }
  968. #ifdef RUBY_DEBUG_ENV
  969. int ruby_enable_coredump = 0;
  970. #endif
  971. /*
  972. * Many operating systems allow signals to be sent to running
  973. * processes. Some signals have a defined effect on the process, while
  974. * others may be trapped at the code level and acted upon. For
  975. * example, your process may trap the USR1 signal and use it to toggle
  976. * debugging, and may use TERM to initiate a controlled shutdown.
  977. *
  978. * pid = fork do
  979. * Signal.trap("USR1") do
  980. * $debug = !$debug
  981. * puts "Debug now: #$debug"
  982. * end
  983. * Signal.trap("TERM") do
  984. * puts "Terminating..."
  985. * shutdown()
  986. * end
  987. * # . . . do some work . . .
  988. * end
  989. *
  990. * Process.detach(pid)
  991. *
  992. * # Controlling program:
  993. * Process.kill("USR1", pid)
  994. * # ...
  995. * Process.kill("USR1", pid)
  996. * # ...
  997. * Process.kill("TERM", pid)
  998. *
  999. * produces:
  1000. * Debug now: true
  1001. * Debug now: false
  1002. * Terminating...
  1003. *
  1004. * The list of available signal names and their interpretation is
  1005. * system dependent. Signal delivery semantics may also vary between
  1006. * systems; in particular signal delivery may not always be reliable.
  1007. */
  1008. void
  1009. Init_signal(void)
  1010. {
  1011. VALUE mSignal = rb_define_module("Signal");
  1012. rb_define_global_function("trap", sig_trap, -1);
  1013. rb_define_module_function(mSignal, "trap", sig_trap, -1);
  1014. rb_define_module_function(mSignal, "list", sig_list, 0);
  1015. rb_define_method(rb_eSignal, "initialize", esignal_init, -1);
  1016. rb_define_method(rb_eSignal, "signo", esignal_signo, 0);
  1017. rb_alias(rb_eSignal, rb_intern("signm"), rb_intern("message"));
  1018. rb_define_method(rb_eInterrupt, "initialize", interrupt_init, -1);
  1019. install_sighandler(SIGINT, sighandler);
  1020. #ifdef SIGHUP
  1021. install_sighandler(SIGHUP, sighandler);
  1022. #endif
  1023. #ifdef SIGQUIT
  1024. install_sighandler(SIGQUIT, sighandler);
  1025. #endif
  1026. #ifdef SIGTERM
  1027. install_sighandler(SIGTERM, sighandler);
  1028. #endif
  1029. #ifdef SIGALRM
  1030. install_sighandler(SIGALRM, sighandler);
  1031. #endif
  1032. #ifdef SIGUSR1
  1033. install_sighandler(SIGUSR1, sighandler);
  1034. #endif
  1035. #ifdef SIGUSR2
  1036. install_sighandler(SIGUSR2, sighandler);
  1037. #endif
  1038. #ifdef RUBY_DEBUG_ENV
  1039. if (!ruby_enable_coredump)
  1040. #endif
  1041. {
  1042. #ifdef SIGBUS
  1043. install_sighandler(SIGBUS, sigbus);
  1044. #endif
  1045. #ifdef SIGSEGV
  1046. # ifdef USE_SIGALTSTACK
  1047. register_sigaltstack();
  1048. # endif
  1049. install_sighandler(SIGSEGV, (sighandler_t)sigsegv);
  1050. #endif
  1051. }
  1052. #ifdef SIGPIPE
  1053. install_sighandler(SIGPIPE, sigpipe);
  1054. #endif
  1055. #if defined(SIGCLD)
  1056. init_sigchld(SIGCLD);
  1057. #elif defined(SIGCHLD)
  1058. init_sigchld(SIGCHLD);
  1059. #endif
  1060. }