Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
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 @ferrous26 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 c…
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 c…
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 c…
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 c…
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 c…
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 c…
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 c…
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 c…
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 c…
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 c…
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 c…
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 c…
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 c…
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 c…
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 c…
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 c…
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 c…
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 c…
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 c…
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 c…
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 c…
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 c…
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 c…
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 c…
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 c…
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 c…
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 c…
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 c…
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 c…
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 c…
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 c…
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 c…
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 c…
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 c…
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 c…
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 c…
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 c…
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 c…
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 c…
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 c…
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 c…
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 c…
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 c…
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 c…
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.