diff options
author | Xavier Leroy <xavier.leroy@inria.fr> | 1998-08-08 16:52:33 +0000 |
---|---|---|
committer | Xavier Leroy <xavier.leroy@inria.fr> | 1998-08-08 16:52:33 +0000 |
commit | c6b82c5c30ba710e5bf55729f09f12a9356ddcd6 (patch) | |
tree | c022d95cf48398fe52559d8c4f078c778a30ec26 | |
parent | 63be4e8d2bdb08ebfd3ac504b2bb30d02dd8cd18 (diff) |
Sys.signal renvoie l'ancien handler
git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@2039 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
-rw-r--r-- | asmrun/signals.c | 28 | ||||
-rw-r--r-- | byterun/signals.c | 22 | ||||
-rw-r--r-- | stdlib/sys.ml | 6 | ||||
-rw-r--r-- | stdlib/sys.mli | 6 |
4 files changed, 45 insertions, 17 deletions
diff --git a/asmrun/signals.c b/asmrun/signals.c index 1cfa8d7d3..3e8418e8e 100644 --- a/asmrun/signals.c +++ b/asmrun/signals.c @@ -25,6 +25,7 @@ #include "fail.h" #include "signals.h" #include "stack.h" +#include "sys.h" volatile int async_signal_mode = 0; volatile int pending_signal = 0; @@ -226,10 +227,11 @@ value install_signal_handler(value signal_number, value action) /* ML */ { int sig; - void (*act)(); + void (*act)(int signo), (*oldact)(int signo); #ifdef POSIX_SIGNALS - struct sigaction sigact; + struct sigaction sigact, oldsigact; #endif + value res; sig = Int_val(signal_number); if (sig < 0) sig = posix_signals[-sig-1]; @@ -255,15 +257,25 @@ value install_signal_handler(value signal_number, value action) /* ML */ act = handle_signal; break; } -#ifndef POSIX_SIGNALS - signal(sig, act); -#else +#ifdef POSIX_SIGNALS sigact.sa_handler = act; - sigact.sa_flags = 0; sigemptyset(&sigact.sa_mask); - sigaction(sig, &sigact, NULL); + sigact.sa_flags = 0; + if (sigaction(sig, &sigact, &oldsigact) == -1) sys_error(NO_ARG); + oldact = oldsigact.sa_handler; +#else + oldact = signal(sig, act); + if (oldact == SIG_ERR) sys_error(NO_ARG); #endif - return Val_unit; + if (oldact == handle_signal) { + res = alloc(1, 0); /* Signal_handle */ + Field(res, 0) = Field(signal_handlers, sig); + } + else if (oldact == SIG_IGN) + res = Val_int(1); /* Signal_ignore */ + else + res = Val_int(0); /* Signal_default */ + return res; } /* Machine- and OS-dependent handling of bound check trap */ diff --git a/byterun/signals.c b/byterun/signals.c index df01d68cb..67bb7d4bd 100644 --- a/byterun/signals.c +++ b/byterun/signals.c @@ -21,6 +21,7 @@ #include "mlvalues.h" #include "roots.h" #include "signals.h" +#include "sys.h" volatile int async_signal_mode = 0; volatile int pending_signal = 0; @@ -160,10 +161,11 @@ int posix_signals[] = { value install_signal_handler(value signal_number, value action) /* ML */ { int sig; - void (*act)(int signo); + void (*act)(int signo), (*oldact)(int signo); #ifdef POSIX_SIGNALS - struct sigaction sigact; + struct sigaction sigact, oldsigact; #endif + value res; sig = Int_val(signal_number); if (sig < 0) sig = posix_signals[-sig-1]; @@ -193,9 +195,19 @@ value install_signal_handler(value signal_number, value action) /* ML */ sigact.sa_handler = act; sigemptyset(&sigact.sa_mask); sigact.sa_flags = 0; - sigaction(sig, &sigact, NULL); + if (sigaction(sig, &sigact, &oldsigact) == -1) sys_error(NO_ARG); + oldact = oldsigact.sa_handler; #else - signal(sig, act); + oldact = signal(sig, act); + if (oldact == SIG_ERR) sys_error(NO_ARG); #endif - return Val_unit; + if (oldact == handle_signal) { + res = alloc(1, 0); /* Signal_handle */ + Field(res, 0) = Field(signal_handlers, sig); + } + else if (oldact == SIG_IGN) + res = Val_int(1); /* Signal_ignore */ + else + res = Val_int(0); /* Signal_default */ + return res; } diff --git a/stdlib/sys.ml b/stdlib/sys.ml index ae1494555..c2be9c9de 100644 --- a/stdlib/sys.ml +++ b/stdlib/sys.ml @@ -37,7 +37,8 @@ type signal_behavior = | Signal_ignore | Signal_handle of (int -> unit) -external signal: int -> signal_behavior -> unit = "install_signal_handler" +external signal: int -> signal_behavior -> signal_behavior + = "install_signal_handler" let sigabrt = -1 let sigalrm = -2 @@ -67,4 +68,5 @@ let catch_break on = if on then signal sigint (Signal_handle(fun _ -> raise Break)) else - signal sigint Signal_default + signal sigint Signal_default; + () diff --git a/stdlib/sys.mli b/stdlib/sys.mli index 2178df5da..1bdbb191b 100644 --- a/stdlib/sys.mli +++ b/stdlib/sys.mli @@ -65,9 +65,11 @@ type signal_behavior = - [Signal_handle f]: call function [f], giving it the signal number as argument. *) -external signal: int -> signal_behavior -> unit = "install_signal_handler" +external signal: int -> signal_behavior -> signal_behavior + = "install_signal_handler" (* Set the behavior of the system on receipt of a given signal. - The first argument is the signal number. *) + The first argument is the signal number. Return the behavior + previously associated with the signal. *) val sigabrt: int (* Abnormal termination *) val sigalrm: int (* Timeout *) |