summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorXavier Leroy <xavier.leroy@inria.fr>1998-08-08 16:52:33 +0000
committerXavier Leroy <xavier.leroy@inria.fr>1998-08-08 16:52:33 +0000
commitc6b82c5c30ba710e5bf55729f09f12a9356ddcd6 (patch)
treec022d95cf48398fe52559d8c4f078c778a30ec26
parent63be4e8d2bdb08ebfd3ac504b2bb30d02dd8cd18 (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.c28
-rw-r--r--byterun/signals.c22
-rw-r--r--stdlib/sys.ml6
-rw-r--r--stdlib/sys.mli6
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 *)