Sys.Signals module for a Variant type of signals (and a set_signal function that...
[ocaml.git] / otherlibs / unix / signals.c
blobc388b139367fbb5d060d9cb6b2da2a88310e2b97
1 /***********************************************************************/
2 /* */
3 /* Objective Caml */
4 /* */
5 /* Xavier Leroy, projet Cristal, INRIA Rocquencourt */
6 /* */
7 /* Copyright 1998 Institut National de Recherche en Informatique et */
8 /* en Automatique. All rights reserved. This file is distributed */
9 /* under the terms of the GNU Library General Public License, with */
10 /* the special exception on linking described in file ../../LICENSE. */
11 /* */
12 /***********************************************************************/
14 /* $Id$ */
16 #include <errno.h>
17 #include <signal.h>
19 #include <alloc.h>
20 #include <fail.h>
21 #include <memory.h>
22 #include <mlvalues.h>
23 #include <signals.h>
24 #include "unixsupport.h"
26 #ifndef NSIG
27 #define NSIG 64
28 #endif
30 #ifdef POSIX_SIGNALS
32 static void decode_sigset(value vset, sigset_t * set)
34 sigemptyset(set);
35 while (vset != Val_int(0)) {
36 int sig = caml_convert_signal_number(Int_val(Field(vset, 0)));
37 sigaddset(set, sig);
38 vset = Field(vset, 1);
42 static value encode_sigset(sigset_t * set)
44 value res = Val_int(0);
45 int i;
47 Begin_root(res)
48 for (i = 1; i < NSIG; i++)
49 if (sigismember(set, i) > 0) {
50 value newcons = alloc_small(2, 0);
51 Field(newcons, 0) = Val_int(caml_rev_convert_signal_number(i));
52 Field(newcons, 1) = res;
53 res = newcons;
55 End_roots();
56 return res;
59 static int sigprocmask_cmd[3] = { SIG_SETMASK, SIG_BLOCK, SIG_UNBLOCK };
61 CAMLprim value unix_sigprocmask(value vaction, value vset)
63 int how;
64 sigset_t set, oldset;
65 int retcode;
67 how = sigprocmask_cmd[Int_val(vaction)];
68 decode_sigset(vset, &set);
69 enter_blocking_section();
70 retcode = sigprocmask(how, &set, &oldset);
71 leave_blocking_section();
72 if (retcode == -1) uerror("sigprocmask", Nothing);
73 return encode_sigset(&oldset);
76 CAMLprim value unix_sigpending(value unit)
78 sigset_t pending;
79 if (sigpending(&pending) == -1) uerror("sigpending", Nothing);
80 return encode_sigset(&pending);
83 CAMLprim value unix_sigsuspend(value vset)
85 sigset_t set;
86 int retcode;
87 decode_sigset(vset, &set);
88 enter_blocking_section();
89 retcode = sigsuspend(&set);
90 leave_blocking_section();
91 if (retcode == -1 && errno != EINTR) uerror("sigsuspend", Nothing);
92 return Val_unit;
95 #else
97 CAMLprim value unix_sigprocmask(value vaction, value vset)
98 { invalid_argument("Unix.sigprocmask not available"); }
100 CAMLprim value unix_sigpending(value unit)
101 { invalid_argument("Unix.sigpending not available"); }
103 CAMLprim value unix_sigsuspend(value vset)
104 { invalid_argument("Unix.sigsuspend not available"); }
106 #endif