Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 736 lines (658 sloc) 16.964 kb
9595725 update copyrights to 2011
Laurent Sansonetti authored
1 /*
2 * This file is covered by the Ruby license. See COPYING for more details.
7d7d3e8 Mark Rada Change ownership to The MacRuby Team and update copyrights
ferrous26 authored
3 *
4 * Copyright (C) 2012, The MacRuby Team. All rights reserved.
9595725 update copyrights to 2011
Laurent Sansonetti authored
5 * Copyright (C) 2007-2011, Apple Inc. All rights reserved.
6 * Copyright (C) 1993-2007 Yukihiro Matsumoto
7 * Copyright (C) 2000 Network Applied Communication Laboratory, Inc.
8 * Copyright (C) 2000 Information-technology Promotion Agency, Japan
9 */
9c1d230 committing experimental branch content
Laurent Sansonetti authored
10
153d145 don't install stupid handlers on some signals
Laurent Sansonetti authored
11 // TODO: rewrite me!
12
d0898dd include/ruby/macruby.h -> macruby_internal.h
Laurent Sansonetti authored
13 #include "macruby_internal.h"
9c1d230 committing experimental branch content
Laurent Sansonetti authored
14 #include "ruby/signal.h"
15 #include "ruby/node.h"
16 #include "id.h"
cb65416 the great schism, part I
Laurent Sansonetti authored
17 #include "vm.h"
9c1d230 committing experimental branch content
Laurent Sansonetti authored
18 #include <signal.h>
19 #include <stdio.h>
20
71a58c5 - Some beginning to signal handling. It is not yet complete, as we can'...
Thibault Martin-Lagardette authored
21 #define USE_DEFAULT_HANDLER (void (*)(int))-1
9c1d230 committing experimental branch content
Laurent Sansonetti authored
22
71a58c5 - Some beginning to signal handling. It is not yet complete, as we can'...
Thibault Martin-Lagardette authored
23 static RETSIGTYPE sighandler(int sig);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
24
25 static const struct signals {
26 const char *signm;
27 int signo;
28 } siglist [] = {
71a58c5 - Some beginning to signal handling. It is not yet complete, as we can'...
Thibault Martin-Lagardette authored
29 {"EXIT", 0},
30 {"HUP", SIGHUP},
31 {"INT", SIGINT},
32 {"QUIT", SIGQUIT},
33 {"ILL", SIGILL},
34 {"TRAP", SIGTRAP},
35 {"IOT", SIGIOT},
36 {"ABRT", SIGABRT},
37 {"EMT", SIGEMT},
38 {"FPE", SIGFPE},
39 {"KILL", SIGKILL},
40 {"BUS", SIGBUS},
41 {"SEGV", SIGSEGV},
42 {"SYS", SIGSYS},
43 {"PIPE", SIGPIPE},
44 {"ALRM", SIGALRM},
45 {"TERM", SIGTERM},
46 {"URG", SIGURG},
47 {"STOP", SIGSTOP},
48 {"TSTP", SIGTSTP},
49 {"CONT", SIGCONT},
50 {"CHLD", SIGCHLD},
51 {"CLD", SIGCHLD},
52 {"TTIN", SIGTTIN},
53 {"TTOU", SIGTTOU},
54 {"IO", SIGIO},
55 {"XCPU", SIGXCPU},
56 {"XFSZ", SIGXFSZ},
9c1d230 committing experimental branch content
Laurent Sansonetti authored
57 {"VTALRM", SIGVTALRM},
71a58c5 - Some beginning to signal handling. It is not yet complete, as we can'...
Thibault Martin-Lagardette authored
58 {"PROF", SIGPROF},
59 {"WINCH", SIGWINCH},
60 {"INFO", SIGINFO},
61 {"USR1", SIGUSR1},
62 {"USR2", SIGUSR2},
9c1d230 committing experimental branch content
Laurent Sansonetti authored
63 {NULL, 0}
64 };
65
71a58c5 - Some beginning to signal handling. It is not yet complete, as we can'...
Thibault Martin-Lagardette authored
66 static const struct trap_handlers {
67 const char *command;
68 VALUE new_cmd_value;
69 sighandler_t handler;
70 } gl_trap_handlers[] = {
71 {"SYSTEM_DEFAULT", 0, SIG_DFL},
72 {"SIG_IGN", 0, SIG_IGN},
73 {"IGNORE", 0, SIG_IGN},
74 {"", 0, SIG_IGN},
75 {"SIG_DFL", 0, USE_DEFAULT_HANDLER},
76 {"DEFAULT", 0, USE_DEFAULT_HANDLER},
77 {"EXIT", Qundef, sighandler},
78 {NULL, 0}
79 };
80
9c1d230 committing experimental branch content
Laurent Sansonetti authored
81 static int
82 signm2signo(const char *nm)
83 {
84 const struct signals *sigs;
85
86 for (sigs = siglist; sigs->signm; sigs++)
87 if (strcmp(sigs->signm, nm) == 0)
88 return sigs->signo;
89 return 0;
90 }
91
92 static const char*
93 signo2signm(int no)
94 {
95 const struct signals *sigs;
96
97 for (sigs = siglist; sigs->signm; sigs++)
98 if (sigs->signo == no)
99 return sigs->signm;
100 return 0;
101 }
102
103 const char *
104 ruby_signal_name(int no)
105 {
106 return signo2signm(no);
107 }
108
109 /*
110 * call-seq:
111 * SignalException.new(sig) => signal_exception
112 *
113 * Construct a new SignalException object. +sig+ should be a known
114 * signal name, or a signal number.
115 */
116
117 static VALUE
eab11cf ported to rb_objc_define_method()
Laurent Sansonetti authored
118 esignal_init(VALUE self, SEL sel, int argc, VALUE *argv)
9c1d230 committing experimental branch content
Laurent Sansonetti authored
119 {
120 int argnum = 1;
121 VALUE sig = Qnil;
122 int signo;
123 const char *signm;
124
125 if (argc > 0) {
126 sig = rb_check_to_integer(argv[0], "to_int");
127 if (!NIL_P(sig)) argnum = 2;
128 else sig = argv[0];
129 }
130 if (argc < 1 || argnum < argc) {
131 rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)",
132 argc, argnum);
133 }
134 if (argnum == 2) {
135 signo = NUM2INT(sig);
136 if (signo < 0 || signo > NSIG) {
137 rb_raise(rb_eArgError, "invalid signal number (%d)", signo);
138 }
139 if (argc > 1) {
140 sig = argv[1];
141 }
142 else {
143 signm = signo2signm(signo);
144 if (signm) {
145 sig = rb_sprintf("SIG%s", signm);
146 }
147 else {
148 sig = rb_sprintf("SIG%u", signo);
149 }
150 }
151 }
152 else {
153 signm = SYMBOL_P(sig) ? rb_sym2name(sig) : StringValuePtr(sig);
154 if (strncmp(signm, "SIG", 3) == 0) signm += 3;
155 signo = signm2signo(signm);
156 if (!signo) {
157 rb_raise(rb_eArgError, "unsupported name `SIG%s'", signm);
158 }
159 sig = rb_sprintf("SIG%s", signm);
160 }
70ea0b5 per-vm method cache + misc fixes/improvements
Laurent Sansonetti authored
161 rb_vm_call_super(self, selInitialize2, 1, &sig);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
162 rb_iv_set(self, "signo", INT2NUM(signo));
163
164 return self;
165 }
166
167 /*
168 * call-seq:
169 * signal_exception.signo => num
170 *
171 * Returns a signal number.
172 */
173
174 static VALUE
eab11cf ported to rb_objc_define_method()
Laurent Sansonetti authored
175 esignal_signo(VALUE self, SEL sel)
9c1d230 committing experimental branch content
Laurent Sansonetti authored
176 {
177 return rb_iv_get(self, "signo");
178 }
179
180 static VALUE
eab11cf ported to rb_objc_define_method()
Laurent Sansonetti authored
181 interrupt_init(VALUE self, SEL sel, int argc, VALUE *argv)
9c1d230 committing experimental branch content
Laurent Sansonetti authored
182 {
183 VALUE args[2];
184
185 args[0] = INT2FIX(SIGINT);
186 rb_scan_args(argc, argv, "01", &args[1]);
70ea0b5 per-vm method cache + misc fixes/improvements
Laurent Sansonetti authored
187 return rb_vm_call_super(self, selInitialize2, 2, args);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
188 }
189
190 void
191 ruby_default_signal(int sig)
192 {
193 #ifndef MACOS_UNUSE_SIGNAL
194 signal(sig, SIG_DFL);
195 raise(sig);
196 #endif
197 }
198
199 /*
200 * call-seq:
201 * Process.kill(signal, pid, ...) => fixnum
202 *
203 * Sends the given signal to the specified process id(s), or to the
204 * current process if _pid_ is zero. _signal_ may be an
205 * integer signal number or a POSIX signal name (either with or without
206 * a +SIG+ prefix). If _signal_ is negative (or starts
207 * with a minus sign), kills process groups instead of
208 * processes. Not all signals are available on all platforms.
209 *
210 * pid = fork do
211 * Signal.trap("HUP") { puts "Ouch!"; exit }
212 * # ... do some work ...
213 * end
214 * # ...
215 * Process.kill("HUP", pid)
216 * Process.wait
217 *
218 * <em>produces:</em>
219 *
220 * Ouch!
221 */
222
223 VALUE
e53e3cb ported process.c to the new runtime API
Laurent Sansonetti authored
224 rb_f_kill(VALUE self, SEL sel, int argc, VALUE *argv)
9c1d230 committing experimental branch content
Laurent Sansonetti authored
225 {
226 int negative = 0;
227 int sig;
228 int i;
71a58c5 - Some beginning to signal handling. It is not yet complete, as we can'...
Thibault Martin-Lagardette authored
229 int type;
230 const char *s = NULL;
9c1d230 committing experimental branch content
Laurent Sansonetti authored
231
232 rb_secure(2);
233 if (argc < 2)
234 rb_raise(rb_eArgError, "wrong number of arguments -- kill(sig, pid...)");
71a58c5 - Some beginning to signal handling. It is not yet complete, as we can'...
Thibault Martin-Lagardette authored
235
236 type = TYPE(argv[0]);
237 if (type == T_FIXNUM) {
9c1d230 committing experimental branch content
Laurent Sansonetti authored
238 sig = FIX2INT(argv[0]);
71a58c5 - Some beginning to signal handling. It is not yet complete, as we can'...
Thibault Martin-Lagardette authored
239 }
240 else {
241 if (type == T_SYMBOL) {
242 s = rb_sym2name(argv[0]);
243 if (!s)
244 rb_raise(rb_eArgError, "bad signal");
9c1d230 committing experimental branch content
Laurent Sansonetti authored
245 }
71a58c5 - Some beginning to signal handling. It is not yet complete, as we can'...
Thibault Martin-Lagardette authored
246 else if (type == T_STRING) {
247 s = RSTRING_PTR(argv[0]);
248 if (s[0] == '-') {
249 negative++;
250 s++;
251 }
252 }
253 else {
9c1d230 committing experimental branch content
Laurent Sansonetti authored
254 VALUE str;
255 str = rb_check_string_type(argv[0]);
256 if (!NIL_P(str)) {
257 s = RSTRING_PTR(str);
258 }
259 }
71a58c5 - Some beginning to signal handling. It is not yet complete, as we can'...
Thibault Martin-Lagardette authored
260 if (s == NULL)
261 rb_raise(rb_eArgError, "bad signal type %s", rb_obj_classname(argv[0]));
262
263 if (strncmp("SIG", s, 3) == 0)
264 s += 3;
265 if ((sig = signm2signo(s)) == 0)
266 rb_raise(rb_eArgError, "unsupported name `SIG%s'", s);
267 if (negative)
268 sig = -sig;
9c1d230 committing experimental branch content
Laurent Sansonetti authored
269 }
270
271 if (sig < 0) {
272 sig = -sig;
71a58c5 - Some beginning to signal handling. It is not yet complete, as we can'...
Thibault Martin-Lagardette authored
273 for (i = 1; i < argc; i++) {
9c1d230 committing experimental branch content
Laurent Sansonetti authored
274 if (killpg(NUM2PIDT(argv[i]), sig) < 0)
275 rb_sys_fail(0);
276 }
277 }
278 else {
71a58c5 - Some beginning to signal handling. It is not yet complete, as we can'...
Thibault Martin-Lagardette authored
279 for (i = 1; i < argc; i++) {
9c1d230 committing experimental branch content
Laurent Sansonetti authored
280 if (kill(NUM2PIDT(argv[i]), sig) < 0)
281 rb_sys_fail(0);
282 }
283 }
284 rb_thread_polling();
71a58c5 - Some beginning to signal handling. It is not yet complete, as we can'...
Thibault Martin-Lagardette authored
285 return INT2FIX(i - 1);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
286 }
287
288 VALUE
289 rb_get_trap_cmd(int sig)
290 {
71a58c5 - Some beginning to signal handling. It is not yet complete, as we can'...
Thibault Martin-Lagardette authored
291 return rb_vm_trap_cmd_for_signal(sig);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
292 }
293
71a58c5 - Some beginning to signal handling. It is not yet complete, as we can'...
Thibault Martin-Lagardette authored
294 sighandler_t
9c1d230 committing experimental branch content
Laurent Sansonetti authored
295 ruby_signal(int signum, sighandler_t handler)
296 {
71a58c5 - Some beginning to signal handling. It is not yet complete, as we can'...
Thibault Martin-Lagardette authored
297 struct sigaction sigact;
298 struct sigaction old;
9c1d230 committing experimental branch content
Laurent Sansonetti authored
299
300 sigemptyset(&sigact.sa_mask);
301 sigact.sa_handler = handler;
302 sigact.sa_flags = 0;
303
304 if (signum == SIGCHLD && handler == SIG_IGN)
305 sigact.sa_flags |= SA_NOCLDWAIT;
71a58c5 - Some beginning to signal handling. It is not yet complete, as we can'...
Thibault Martin-Lagardette authored
306 if (signum == SIGSEGV)
307 sigact.sa_flags |= SA_ONSTACK;
308 if (sigaction(signum, &sigact, &old) < 0) {
309 if (errno != 0 && errno != EINVAL) {
310 rb_bug("sigaction error.\n");
311 }
312 }
9c1d230 committing experimental branch content
Laurent Sansonetti authored
313 return old.sa_handler;
314 }
315
316 sighandler_t
317 posix_signal(int signum, sighandler_t handler)
318 {
319 return ruby_signal(signum, handler);
320 }
321
71a58c5 - Some beginning to signal handling. It is not yet complete, as we can'...
Thibault Martin-Lagardette authored
322 static void signal_exec(VALUE cmd, int level, int sig);
323 static void rb_signal_exec(int sig);
324
9c1d230 committing experimental branch content
Laurent Sansonetti authored
325 static RETSIGTYPE
326 sighandler(int sig)
327 {
71a58c5 - Some beginning to signal handling. It is not yet complete, as we can'...
Thibault Martin-Lagardette authored
328 int olderrno = errno;
329 rb_signal_exec(sig);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
330 ruby_signal(sig, sighandler);
71a58c5 - Some beginning to signal handling. It is not yet complete, as we can'...
Thibault Martin-Lagardette authored
331 errno = olderrno;
9c1d230 committing experimental branch content
Laurent Sansonetti authored
332 }
333
334 #include <pthread.h>
335
336 void
337 rb_disable_interrupt(void)
338 {
339 sigset_t mask;
340 sigfillset(&mask);
341 sigdelset(&mask, SIGVTALRM);
342 sigdelset(&mask, SIGSEGV);
343 pthread_sigmask(SIG_SETMASK, &mask, NULL);
344 }
345
346 void
347 rb_enable_interrupt(void)
348 {
349 sigset_t mask;
350 sigemptyset(&mask);
351 pthread_sigmask(SIG_SETMASK, &mask, NULL);
352 }
353
354 static RETSIGTYPE
355 sigpipe(int sig)
356 {
357 /* do nothing */
358 }
359
360 static void
71a58c5 - Some beginning to signal handling. It is not yet complete, as we can'...
Thibault Martin-Lagardette authored
361 signal_exec(VALUE cmd, int level, int sig)
9c1d230 committing experimental branch content
Laurent Sansonetti authored
362 {
71a58c5 - Some beginning to signal handling. It is not yet complete, as we can'...
Thibault Martin-Lagardette authored
363 VALUE signum = INT2NUM(sig);
364 rb_eval_cmd(cmd, rb_ary_new3(1, signum), level);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
365 }
366
367 void
368 rb_trap_exit(void)
369 {
7a4fd1b start cleaning up the public header files
Laurent Sansonetti authored
370 #if 0//ndef MACOS_UNUSE_SIGNAL
71a58c5 - Some beginning to signal handling. It is not yet complete, as we can'...
Thibault Martin-Lagardette authored
371 VALUE trap_exit;
372 int safe;
373
374 trap_exit = rb_vm_trap_cmd_for_signal(0);
375 if (trap_exit != (VALUE)NULL) {
376 safe = rb_vm_trap_level_for_signal(0);
377 rb_vm_set_trap_for_signal((VALUE)0, safe, 0);
378 signal_exec(trap_exit, safe, 0);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
379 }
380 #endif
381 }
382
383 static void
384 rb_signal_exec(int sig)
385 {
71a58c5 - Some beginning to signal handling. It is not yet complete, as we can'...
Thibault Martin-Lagardette authored
386 /* rb_vm_thread_t *t; */
387 /* VALUE exc; */
9c1d230 committing experimental branch content
Laurent Sansonetti authored
388 VALUE cmd = rb_get_trap_cmd(sig);
389
390 if (cmd == 0) {
391 switch (sig) {
392 case SIGINT:
393 rb_interrupt();
394 break;
395 case SIGHUP:
396 case SIGQUIT:
397 case SIGTERM:
398 case SIGALRM:
399 case SIGUSR1:
400 case SIGUSR2:
71a58c5 - Some beginning to signal handling. It is not yet complete, as we can'...
Thibault Martin-Lagardette authored
401 /* t = GetThreadPtr(rb_vm_main_thread()); */
402 /* exc = rb_exc_new2(rb_eSignal, ruby_signal_name(sig)); */
403 /* rb_vm_thread_raise(t, exc); */
404 /* rb_raise(rb_eSignal, "%s", signo2signm(sig)); */
9c1d230 committing experimental branch content
Laurent Sansonetti authored
405 break;
406 }
407 }
408 else if (cmd == Qundef) {
71a58c5 - Some beginning to signal handling. It is not yet complete, as we can'...
Thibault Martin-Lagardette authored
409 //rb_thread_signal_exit(th);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
410 }
411 else {
71a58c5 - Some beginning to signal handling. It is not yet complete, as we can'...
Thibault Martin-Lagardette authored
412 signal_exec(cmd, rb_vm_trap_level_for_signal(sig), sig);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
413 }
414 }
415
416 struct trap_arg {
417 int sig;
418 sighandler_t func;
419 VALUE cmd;
420 };
421
422 static sighandler_t
423 default_handler(int sig)
424 {
425 sighandler_t func;
426 switch (sig) {
427 case SIGINT:
428 case SIGHUP:
429 case SIGQUIT:
430 case SIGTERM:
431 case SIGALRM:
432 case SIGUSR1:
433 case SIGUSR2:
434 func = sighandler;
435 break;
436 case SIGPIPE:
437 func = sigpipe;
438 break;
439 default:
440 func = SIG_DFL;
441 break;
442 }
443
444 return func;
445 }
446
447 static sighandler_t
448 trap_handler(VALUE *cmd, int sig)
449 {
71a58c5 - Some beginning to signal handling. It is not yet complete, as we can'...
Thibault Martin-Lagardette authored
450 sighandler_t func = sighandler;
9c1d230 committing experimental branch content
Laurent Sansonetti authored
451 VALUE command;
452
453 if (NIL_P(*cmd)) {
454 func = SIG_IGN;
455 }
456 else {
457 command = rb_check_string_type(*cmd);
71a58c5 - Some beginning to signal handling. It is not yet complete, as we can'...
Thibault Martin-Lagardette authored
458 if (NIL_P(command) && SYMBOL_P(*cmd)) {
459 command = rb_id2str(SYM2ID(*cmd));
460 if (!command) rb_raise(rb_eArgError, "bad handler");
461 }
9c1d230 committing experimental branch content
Laurent Sansonetti authored
462 if (!NIL_P(command)) {
463 SafeStringValue(command); /* taint check */
71a58c5 - Some beginning to signal handling. It is not yet complete, as we can'...
Thibault Martin-Lagardette authored
464 *cmd = command;
465 for (int i = 0; gl_trap_handlers[i].command != NULL; i++) {
466 if (strcmp(gl_trap_handlers[i].command, RSTRING_PTR(command)) == 0) {
467 func = gl_trap_handlers[i].handler;
468 if (func == USE_DEFAULT_HANDLER) {
469 func = default_handler(sig);
470 }
471 *cmd = gl_trap_handlers[i].new_cmd_value;
472 break;
9c1d230 committing experimental branch content
Laurent Sansonetti authored
473 }
474 }
475 }
476 else {
71a58c5 - Some beginning to signal handling. It is not yet complete, as we can'...
Thibault Martin-Lagardette authored
477 /* func = sighandler; */
9c1d230 committing experimental branch content
Laurent Sansonetti authored
478 }
479 }
480
481 return func;
482 }
483
484 static int
485 trap_signm(VALUE vsig)
486 {
487 int sig = -1;
488 const char *s;
489
71a58c5 - Some beginning to signal handling. It is not yet complete, as we can'...
Thibault Martin-Lagardette authored
490 if (TYPE(vsig) == T_FIXNUM) {
9c1d230 committing experimental branch content
Laurent Sansonetti authored
491 sig = FIX2INT(vsig);
492 if (sig < 0 || sig >= NSIG) {
493 rb_raise(rb_eArgError, "invalid signal number (%d)", sig);
494 }
71a58c5 - Some beginning to signal handling. It is not yet complete, as we can'...
Thibault Martin-Lagardette authored
495 }
496 else {
497 if (TYPE(vsig) == T_SYMBOL) {
498 s = rb_sym2name(vsig);
499 if (s == NULL)
500 rb_raise(rb_eArgError, "bad signal");
501 }
502 else
503 s = StringValuePtr(vsig);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
504
505 if (strncmp("SIG", s, 3) == 0)
506 s += 3;
507 sig = signm2signo(s);
508 if (sig == 0 && strcmp(s, "EXIT") != 0)
509 rb_raise(rb_eArgError, "unsupported signal SIG%s", s);
510 }
511 return sig;
512 }
513
514 static VALUE
515 trap(struct trap_arg *arg)
516 {
71a58c5 - Some beginning to signal handling. It is not yet complete, as we can'...
Thibault Martin-Lagardette authored
517 sighandler_t oldfunc;
518 sighandler_t func = arg->func;
519 VALUE oldcmd;
520 VALUE command = arg->cmd;
9c1d230 committing experimental branch content
Laurent Sansonetti authored
521 int sig = arg->sig;
522
523 oldfunc = ruby_signal(sig, func);
71a58c5 - Some beginning to signal handling. It is not yet complete, as we can'...
Thibault Martin-Lagardette authored
524 oldcmd = rb_vm_trap_cmd_for_signal(sig);
525 if (oldcmd == 0) {
526 if (oldfunc == SIG_IGN)
527 oldcmd = rb_str_new2("IGNORE");
528 else if (oldfunc == sighandler)
529 oldcmd = rb_str_new2("DEFAULT");
530 else
531 oldcmd = Qnil;
9c1d230 committing experimental branch content
Laurent Sansonetti authored
532 }
71a58c5 - Some beginning to signal handling. It is not yet complete, as we can'...
Thibault Martin-Lagardette authored
533 else if (oldcmd == Qundef)
534 oldcmd = rb_str_new2("EXIT");
9c1d230 committing experimental branch content
Laurent Sansonetti authored
535
71a58c5 - Some beginning to signal handling. It is not yet complete, as we can'...
Thibault Martin-Lagardette authored
536 // Assign trap to signal
537 rb_vm_set_trap_for_signal(command, rb_safe_level(), sig);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
538
71a58c5 - Some beginning to signal handling. It is not yet complete, as we can'...
Thibault Martin-Lagardette authored
539 return oldcmd;
9c1d230 committing experimental branch content
Laurent Sansonetti authored
540 }
541
542 void
543 rb_trap_restore_mask(void)
544 {
545 }
546
547 /*
548 * call-seq:
549 * Signal.trap( signal, command ) => obj
550 * Signal.trap( signal ) {| | block } => obj
551 *
552 * Specifies the handling of signals. The first parameter is a signal
553 * name (a string such as ``SIGALRM'', ``SIGUSR1'', and so on) or a
554 * signal number. The characters ``SIG'' may be omitted from the
555 * signal name. The command or block specifies code to be run when the
556 * signal is raised.
557 * If the command is the string ``IGNORE'' or ``SIG_IGN'', the signal
558 * will be ignored.
559 * If the command is ``DEFAULT'' or ``SIG_DFL'', the Ruby's default handler
560 * will be invoked.
561 * If the command is ``EXIT'', the script will be terminated by the signal.
562 * If the command is ``SYSTEM_DEFAULT'', the operating system's default
563 * handler will be invoked.
564 * Otherwise, the given command or block will be run.
565 * The special signal name ``EXIT'' or signal number zero will be
566 * invoked just prior to program termination.
567 * trap returns the previous handler for the given signal.
568 *
569 * Signal.trap(0, proc { puts "Terminating: #{$$}" })
570 * Signal.trap("CLD") { puts "Child died" }
571 * fork && Process.wait
572 *
573 * produces:
574 * Terminating: 27461
575 * Child died
576 * Terminating: 27460
577 */
71a58c5 - Some beginning to signal handling. It is not yet complete, as we can'...
Thibault Martin-Lagardette authored
578
9c1d230 committing experimental branch content
Laurent Sansonetti authored
579 static VALUE
eab11cf ported to rb_objc_define_method()
Laurent Sansonetti authored
580 sig_trap(VALUE rcv, SEL sel, int argc, VALUE *argv)
9c1d230 committing experimental branch content
Laurent Sansonetti authored
581 {
582 struct trap_arg arg;
583
584 rb_secure(2);
585 if (argc == 0 || argc > 2) {
586 rb_raise(rb_eArgError, "wrong number of arguments -- trap(sig, cmd)/trap(sig){...}");
587 }
588
589 arg.sig = trap_signm(argv[0]);
590 if (argc == 1) {
591 arg.cmd = rb_block_proc();
592 arg.func = sighandler;
593 }
71a58c5 - Some beginning to signal handling. It is not yet complete, as we can'...
Thibault Martin-Lagardette authored
594 else {
9c1d230 committing experimental branch content
Laurent Sansonetti authored
595 arg.cmd = argv[1];
596 arg.func = trap_handler(&arg.cmd, arg.sig);
597 }
598
599 if (OBJ_TAINTED(arg.cmd)) {
600 rb_raise(rb_eSecurityError, "Insecure: tainted signal trap");
601 }
71a58c5 - Some beginning to signal handling. It is not yet complete, as we can'...
Thibault Martin-Lagardette authored
602
9c1d230 committing experimental branch content
Laurent Sansonetti authored
603 return trap(&arg);
604 }
605
606 /*
607 * call-seq:
608 * Signal.list => a_hash
609 *
610 * Returns a list of signal names mapped to the corresponding
611 * underlying signal numbers.
612 *
613 * Signal.list #=> {"ABRT"=>6, "ALRM"=>14, "BUS"=>7, "CHLD"=>17, "CLD"=>17, "CONT"=>18, "FPE"=>8, "HUP"=>1, "ILL"=>4, "INT"=>2, "IO"=>29, "IOT"=>6, "KILL"=>9, "PIPE"=>13, "POLL"=>29, "PROF"=>27, "PWR"=>30, "QUIT"=>3, "SEGV"=>11, "STOP"=>19, "SYS"=>31, "TERM"=>15, "TRAP"=>5, "TSTP"=>20, "TTIN"=>21, "TTOU"=>22, "URG"=>23, "USR1"=>10, "USR2"=>12, "VTALRM"=>26, "WINCH"=>28, "XCPU"=>24, "XFSZ"=>25}
614 */
615 static VALUE
eab11cf ported to rb_objc_define_method()
Laurent Sansonetti authored
616 sig_list(VALUE rcv, SEL sel)
9c1d230 committing experimental branch content
Laurent Sansonetti authored
617 {
618 VALUE h = rb_hash_new();
619 const struct signals *sigs;
620
621 for (sigs = siglist; sigs->signm; sigs++) {
622 rb_hash_aset(h, rb_str_new2(sigs->signm), INT2FIX(sigs->signo));
623 }
624 return h;
625 }
626
627 static void
628 install_sighandler(int signum, sighandler_t handler)
629 {
630 sighandler_t old;
631
632 old = ruby_signal(signum, handler);
633 if (old != SIG_DFL) {
634 ruby_signal(signum, old);
635 }
636 }
637
638 #if defined(SIGCLD) || defined(SIGCHLD)
639 static void
640 init_sigchld(int sig)
641 {
642 sighandler_t oldfunc;
643
644 oldfunc = ruby_signal(sig, SIG_DFL);
645 if (oldfunc != SIG_DFL && oldfunc != SIG_IGN) {
646 ruby_signal(sig, oldfunc);
647 } else {
71a58c5 - Some beginning to signal handling. It is not yet complete, as we can'...
Thibault Martin-Lagardette authored
648 rb_vm_set_trap_for_signal((VALUE)0, rb_safe_level(), sig);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
649 }
650 }
651 #endif
652
653 void
654 ruby_sig_finalize()
655 {
656 sighandler_t oldfunc;
657
658 oldfunc = ruby_signal(SIGINT, SIG_IGN);
659 if (oldfunc == sighandler) {
660 ruby_signal(SIGINT, SIG_DFL);
661 }
662 }
663
664 #ifdef RUBY_DEBUG_ENV
665 int ruby_enable_coredump = 0;
666 #endif
667
668 /*
669 * Many operating systems allow signals to be sent to running
670 * processes. Some signals have a defined effect on the process, while
671 * others may be trapped at the code level and acted upon. For
672 * example, your process may trap the USR1 signal and use it to toggle
673 * debugging, and may use TERM to initiate a controlled shutdown.
674 *
675 * pid = fork do
676 * Signal.trap("USR1") do
677 * $debug = !$debug
678 * puts "Debug now: #$debug"
679 * end
680 * Signal.trap("TERM") do
681 * puts "Terminating..."
682 * shutdown()
683 * end
684 * # . . . do some work . . .
685 * end
686 *
687 * Process.detach(pid)
688 *
689 * # Controlling program:
690 * Process.kill("USR1", pid)
691 * # ...
692 * Process.kill("USR1", pid)
693 * # ...
694 * Process.kill("TERM", pid)
695 *
696 * produces:
697 * Debug now: true
698 * Debug now: false
699 * Terminating...
700 *
701 * The list of available signal names and their interpretation is
702 * system dependent. Signal delivery semantics may also vary between
703 * systems; in particular signal delivery may not always be reliable.
704 */
705 void
706 Init_signal(void)
707 {
708 #ifndef MACOS_UNUSE_SIGNAL
709 VALUE mSignal = rb_define_module("Signal");
710
cbe906e introduce rb_objc_define_module_function() which mimics the ruby spec
Laurent Sansonetti authored
711 rb_objc_define_module_function(rb_mKernel, "trap", sig_trap, -1);
eab11cf ported to rb_objc_define_method()
Laurent Sansonetti authored
712 rb_objc_define_method(*(VALUE *)mSignal, "trap", sig_trap, -1);
713 rb_objc_define_method(*(VALUE *)mSignal, "list", sig_list, 0);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
714
eab11cf ported to rb_objc_define_method()
Laurent Sansonetti authored
715 rb_objc_define_method(rb_eSignal, "initialize", esignal_init, -1);
716 rb_objc_define_method(rb_eSignal, "signo", esignal_signo, 0);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
717 rb_alias(rb_eSignal, rb_intern("signm"), rb_intern("message"));
eab11cf ported to rb_objc_define_method()
Laurent Sansonetti authored
718 rb_objc_define_method(rb_eInterrupt, "initialize", interrupt_init, -1);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
719
71a58c5 - Some beginning to signal handling. It is not yet complete, as we can'...
Thibault Martin-Lagardette authored
720 /* install_sighandler(SIGINT, sighandler); */
721 /* install_sighandler(SIGHUP, sighandler); */
722 /* install_sighandler(SIGQUIT, sighandler); */
723 /* install_sighandler(SIGTERM, sighandler); */
724 /* install_sighandler(SIGALRM, sighandler); */
725 /* install_sighandler(SIGUSR1, sighandler); */
726 /* install_sighandler(SIGUSR2, sighandler); */
9c1d230 committing experimental branch content
Laurent Sansonetti authored
727
728 #ifdef RUBY_DEBUG_ENV
729 if (!ruby_enable_coredump)
730 #endif
731 install_sighandler(SIGPIPE, sigpipe);
732
733 init_sigchld(SIGCHLD);
71a58c5 - Some beginning to signal handling. It is not yet complete, as we can'...
Thibault Martin-Lagardette authored
734 #endif /* !MACOS_UNUSE_SIGNAL */
9c1d230 committing experimental branch content
Laurent Sansonetti authored
735 }
Something went wrong with that request. Please try again.