* __scm.h (scm_asyncs_pending_p): Removed.
[bpt/guile.git] / libguile / scmsigs.c
CommitLineData
e4b265d8 1/* Copyright (C) 1995,1996,1997,1998,1999,2000,2001 Free Software Foundation, Inc.
adb2c53b 2 *
0f2d19dd
JB
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2, or (at your option)
6 * any later version.
adb2c53b 7 *
0f2d19dd
JB
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
adb2c53b 12 *
0f2d19dd
JB
13 * You should have received a copy of the GNU General Public License
14 * along with this software; see the file COPYING. If not, write to
82892bed
JB
15 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
16 * Boston, MA 02111-1307 USA
0f2d19dd
JB
17 *
18 * As a special exception, the Free Software Foundation gives permission
19 * for additional uses of the text contained in its release of GUILE.
20 *
21 * The exception is that, if you link the GUILE library with other files
22 * to produce an executable, this does not by itself cause the
23 * resulting executable to be covered by the GNU General Public License.
24 * Your use of that executable is in no way restricted on account of
25 * linking the GUILE library code into it.
26 *
27 * This exception does not however invalidate any other reasons why
28 * the executable file might be covered by the GNU General Public License.
29 *
30 * This exception applies only to the code released by the
31 * Free Software Foundation under the name GUILE. If you copy
32 * code from other Free Software Foundation releases into a copy of
33 * GUILE, as the General Public License permits, the exception does
34 * not apply to the code that you add in this way. To avoid misleading
35 * anyone as to the status of such modified files, you must delete
36 * this exception notice from them.
37 *
38 * If you write modifications of your own for GUILE, it is your choice
39 * whether to permit this exception to apply to your modifications.
82892bed 40 * If you do not wish that, delete this exception notice. */
1bbd0b84 41
1bbd0b84 42
0f2d19dd
JB
43\f
44
0f2d19dd 45#include <signal.h>
e6e2e95a
MD
46#include <errno.h>
47
a0599745 48#include "libguile/_scm.h"
0f2d19dd 49
a0599745
MD
50#include "libguile/async.h"
51#include "libguile/eval.h"
fdc28395 52#include "libguile/root.h"
a0599745 53#include "libguile/vectors.h"
1bbd0b84 54
a0599745
MD
55#include "libguile/validate.h"
56#include "libguile/scmsigs.h"
20e6290e 57
0f2d19dd
JB
58#ifdef HAVE_UNISTD_H
59#include <unistd.h>
60#endif
61
1bed8c28
GH
62#ifdef HAVE_SYS_TIME_H
63#include <sys/time.h>
64#endif
65
b74f4728
JB
66/* The thread system has its own sleep and usleep functions. */
67#ifndef USE_THREADS
68
69#if defined(MISSING_SLEEP_DECL)
70int sleep ();
71#endif
72
73#if defined(HAVE_USLEEP) && defined(MISSING_USLEEP_DECL)
74int usleep ();
ce874f2d 75#endif
b74f4728 76
0935d604 77#endif
0f2d19dd 78
82893676
MG
79#ifdef __MINGW32__
80#include <windows.h>
81#define alarm(sec) (0)
82/* This weird comma expression is because Sleep is void under Windows. */
83#define sleep(sec) (Sleep ((sec) * 1000), 0)
ed618cc9 84#define usleep(usec) (Sleep ((usec) / 1000), 0)
82893676
MG
85#define kill(pid, sig) raise (sig)
86#endif
87
0f2d19dd
JB
88\f
89
e1a191a8 90/* SIGRETTYPE is the type that signal handlers return. See <signal.h> */
0f2d19dd
JB
91
92#ifdef RETSIGTYPE
e1a191a8 93# define SIGRETTYPE RETSIGTYPE
0f2d19dd 94#else
e1a191a8
GH
95# ifdef STDC_HEADERS
96# define SIGRETTYPE void
97# else
98# define SIGRETTYPE int
99# endif
0f2d19dd
JB
100#endif
101
102\f
103
e1a191a8
GH
104/* take_signal is installed as the C signal handler whenever a Scheme
105 handler is set. when a signal arrives, take_signal marks the corresponding
106 element of got_signal and marks signal_async. the thunk in signal_async
107 (sys_deliver_signals) will be run at the next opportunity, outside a
108 critical section. sys_deliver_signals runs each Scheme handler for
109 which got_signal is set. */
0f2d19dd 110
e1a191a8 111static SCM signal_async;
0f2d19dd 112
e1a191a8 113static char got_signal[NSIG];
0f2d19dd 114
e1a191a8
GH
115/* a Scheme vector of handler procedures. */
116static SCM *signal_handlers;
0f2d19dd 117
e1a191a8
GH
118/* saves the original C handlers, when a new handler is installed.
119 set to SIG_ERR if the original handler is installed. */
120#ifdef HAVE_SIGACTION
121static struct sigaction orig_handlers[NSIG];
122#else
da6e81b6 123static SIGRETTYPE (*orig_handlers[NSIG])(int);
0f2d19dd
JB
124#endif
125
e1a191a8
GH
126static SIGRETTYPE
127take_signal (int signum)
128{
e1a191a8 129 got_signal[signum] = 1;
7123fc3b 130 scm_system_async_mark_from_signal_handler (signal_async);
e1a191a8 131}
0f2d19dd 132
e1a191a8
GH
133static SCM
134sys_deliver_signals (void)
135{
136 int i;
137
138 for (i = 0; i < NSIG; i++)
139 {
140 if (got_signal[i])
141 {
cc0b3312
GH
142 /* The flag is reset before calling the handler in case the
143 handler doesn't return. If the handler doesn't return
144 but leaves other signals flagged, they their handlers
145 will be applied some time later when the async is checked
146 again. It would probably be better to reset the flags
147 after doing a longjmp. */
e1a191a8
GH
148 got_signal[i] = 0;
149#ifndef HAVE_SIGACTION
150 signal (i, take_signal);
151#endif
fdc28395 152 scm_call_1 (SCM_VELTS (*signal_handlers)[i], SCM_MAKINUM (i));
e1a191a8
GH
153 }
154 }
155 return SCM_UNSPECIFIED;
0f2d19dd
JB
156}
157
e1a191a8 158/* user interface for installation of signal handlers. */
adb2c53b 159SCM_DEFINE (scm_sigaction, "sigaction", 1, 2, 0,
1bbd0b84 160 (SCM signum, SCM handler, SCM flags),
0d172d3f 161 "Install or report the signal handler for a specified signal.\n\n"
b380b885
MD
162 "@var{signum} is the signal number, which can be specified using the value\n"
163 "of variables such as @code{SIGINT}.\n\n"
164 "If @var{action} is omitted, @code{sigaction} returns a pair: the\n"
165 "CAR is the current\n"
166 "signal hander, which will be either an integer with the value @code{SIG_DFL}\n"
167 "(default action) or @code{SIG_IGN} (ignore), or the Scheme procedure which\n"
168 "handles the signal, or @code{#f} if a non-Scheme procedure handles the\n"
169 "signal. The CDR contains the current @code{sigaction} flags for the handler.\n\n"
170 "If @var{action} is provided, it is installed as the new handler for\n"
171 "@var{signum}. @var{action} can be a Scheme procedure taking one\n"
172 "argument, or the value of @code{SIG_DFL} (default action) or\n"
173 "@code{SIG_IGN} (ignore), or @code{#f} to restore whatever signal handler\n"
174 "was installed before @code{sigaction} was first used. Flags can\n"
175 "optionally be specified for the new handler (@code{SA_RESTART} will\n"
0d172d3f 176 "always be added if it's available and the system is using restartable\n"
b380b885
MD
177 "system calls.) The return value is a pair with information about the\n"
178 "old handler as described above.\n\n"
179 "This interface does not provide access to the \"signal blocking\"\n"
180 "facility. Maybe this is not needed, since the thread support may\n"
181 "provide solutions to the problem of consistent access to data\n"
182 "structures.")
1bbd0b84 183#define FUNC_NAME s_scm_sigaction
e1a191a8
GH
184{
185 int csig;
186#ifdef HAVE_SIGACTION
187 struct sigaction action;
188 struct sigaction old_action;
189#else
af68e5e5 190 SIGRETTYPE (* chandler) (int) = SIG_DFL;
e1a191a8
GH
191 SIGRETTYPE (* old_chandler) (int);
192#endif
193 int query_only = 0;
194 int save_handler = 0;
34d19ef6 195
e1a191a8
GH
196 SCM old_handler;
197
34d19ef6 198 SCM_VALIDATE_INUM_COPY (1, signum, csig);
7ee92fce
GH
199#if defined(HAVE_SIGACTION)
200#if defined(SA_RESTART) && defined(HAVE_RESTARTABLE_SYSCALLS)
201 /* don't allow SA_RESTART to be omitted if HAVE_RESTARTABLE_SYSCALLS
202 is defined, since libguile would be likely to produce spurious
203 EINTR errors. */
e1a191a8
GH
204 action.sa_flags = SA_RESTART;
205#else
206 action.sa_flags = 0;
207#endif
208 if (!SCM_UNBNDP (flags))
209 {
34d19ef6 210 SCM_VALIDATE_INUM (3, flags);
e1a191a8
GH
211 action.sa_flags |= SCM_INUM (flags);
212 }
213 sigemptyset (&action.sa_mask);
214#endif
215 SCM_DEFER_INTS;
34d19ef6 216 old_handler = SCM_VELTS(*signal_handlers)[csig];
e1a191a8
GH
217 if (SCM_UNBNDP (handler))
218 query_only = 1;
9a09deb1 219 else if (SCM_EQ_P (scm_integer_p (handler), SCM_BOOL_T))
e1a191a8 220 {
e4b265d8
DH
221 if (SCM_NUM2LONG (2, handler) == (long) SIG_DFL
222 || SCM_NUM2LONG (2, handler) == (long) SIG_IGN)
e1a191a8
GH
223 {
224#ifdef HAVE_SIGACTION
225 action.sa_handler = (SIGRETTYPE (*) (int)) SCM_INUM (handler);
226#else
227 chandler = (SIGRETTYPE (*) (int)) SCM_INUM (handler);
228#endif
34d19ef6 229 SCM_VECTOR_SET (*signal_handlers, csig, SCM_BOOL_F);
e1a191a8
GH
230 }
231 else
1bbd0b84 232 SCM_OUT_OF_RANGE (2, handler);
e1a191a8
GH
233 }
234 else if (SCM_FALSEP (handler))
235 {
236 /* restore the default handler. */
237#ifdef HAVE_SIGACTION
238 if (orig_handlers[csig].sa_handler == SIG_ERR)
239 query_only = 1;
240 else
241 {
242 action = orig_handlers[csig];
243 orig_handlers[csig].sa_handler = SIG_ERR;
34d19ef6
HWN
244 SCM_VECTOR_SET (*signal_handlers, csig, SCM_BOOL_F);
245
e1a191a8
GH
246 }
247#else
248 if (orig_handlers[csig] == SIG_ERR)
249 query_only = 1;
250 else
251 {
252 chandler = orig_handlers[csig];
253 orig_handlers[csig] = SIG_ERR;
34d19ef6 254 SCM_VECTOR_SET (*signal_handlers, csig, SCM_BOOL_F);
e1a191a8
GH
255 }
256#endif
adb2c53b 257 }
e1a191a8
GH
258 else
259 {
34d19ef6 260 SCM_VALIDATE_NIM (2, handler);
e1a191a8
GH
261#ifdef HAVE_SIGACTION
262 action.sa_handler = take_signal;
263 if (orig_handlers[csig].sa_handler == SIG_ERR)
264 save_handler = 1;
265#else
266 chandler = take_signal;
267 if (orig_handlers[csig] == SIG_ERR)
268 save_handler = 1;
269#endif
34d19ef6 270 SCM_VECTOR_SET (*signal_handlers, csig, handler);
e1a191a8 271 }
adb2c53b 272
0d172d3f
MV
273 /* XXX - Silently ignore setting handlers for `program error signals'
274 because they can't currently be handled by Scheme code.
275 */
276
277 switch (csig)
278 {
279 /* This list of program error signals is from the GNU Libc
280 Reference Manual */
281 case SIGFPE:
282 case SIGILL:
283 case SIGSEGV:
82893676 284#ifdef SIGBUS
0d172d3f 285 case SIGBUS:
82893676 286#endif
0d172d3f 287 case SIGABRT:
6732de1b 288#if defined(SIGIOT) && (SIGIOT != SIGABRT)
0d172d3f
MV
289 case SIGIOT:
290#endif
82893676 291#ifdef SIGTRAP
0d172d3f 292 case SIGTRAP:
82893676 293#endif
0d172d3f
MV
294#ifdef SIGEMT
295 case SIGEMT:
296#endif
adb2c53b 297#ifdef SIGSYS
0d172d3f 298 case SIGSYS:
adb2c53b 299#endif
0d172d3f
MV
300 query_only = 1;
301 }
302
e1a191a8
GH
303#ifdef HAVE_SIGACTION
304 if (query_only)
305 {
306 if (sigaction (csig, 0, &old_action) == -1)
1bbd0b84 307 SCM_SYSERROR;
e1a191a8
GH
308 }
309 else
310 {
311 if (sigaction (csig, &action , &old_action) == -1)
1bbd0b84 312 SCM_SYSERROR;
e1a191a8
GH
313 if (save_handler)
314 orig_handlers[csig] = old_action;
315 }
316 if (old_action.sa_handler == SIG_DFL || old_action.sa_handler == SIG_IGN)
7ee92fce 317 old_handler = scm_long2num ((long) old_action.sa_handler);
e1a191a8
GH
318 SCM_ALLOW_INTS;
319 return scm_cons (old_handler, SCM_MAKINUM (old_action.sa_flags));
320#else
321 if (query_only)
322 {
323 if ((old_chandler = signal (csig, SIG_IGN)) == SIG_ERR)
1bbd0b84 324 SCM_SYSERROR;
e1a191a8 325 if (signal (csig, old_chandler) == SIG_ERR)
1bbd0b84 326 SCM_SYSERROR;
e1a191a8
GH
327 }
328 else
329 {
330 if ((old_chandler = signal (csig, chandler)) == SIG_ERR)
1bbd0b84 331 SCM_SYSERROR;
e1a191a8
GH
332 if (save_handler)
333 orig_handlers[csig] = old_chandler;
334 }
335 if (old_chandler == SIG_DFL || old_chandler == SIG_IGN)
da6e81b6 336 old_handler = scm_long2num ((long) old_chandler);
e1a191a8
GH
337 SCM_ALLOW_INTS;
338 return scm_cons (old_handler, SCM_MAKINUM (0));
0f2d19dd 339#endif
e1a191a8 340}
1bbd0b84 341#undef FUNC_NAME
e1a191a8 342
adb2c53b 343SCM_DEFINE (scm_restore_signals, "restore-signals", 0, 0, 0,
1bbd0b84 344 (void),
b380b885
MD
345 "Return all signal handlers to the values they had before any call to\n"
346 "@code{sigaction} was made. The return value is unspecified.")
1bbd0b84 347#define FUNC_NAME s_scm_restore_signals
e1a191a8
GH
348{
349 int i;
e1a191a8
GH
350 for (i = 0; i < NSIG; i++)
351 {
352#ifdef HAVE_SIGACTION
353 if (orig_handlers[i].sa_handler != SIG_ERR)
354 {
355 if (sigaction (i, &orig_handlers[i], NULL) == -1)
1bbd0b84 356 SCM_SYSERROR;
e1a191a8 357 orig_handlers[i].sa_handler = SIG_ERR;
34d19ef6 358 SCM_VECTOR_SET (*signal_handlers, i, SCM_BOOL_F);
e1a191a8
GH
359 }
360#else
361 if (orig_handlers[i] != SIG_ERR)
362 {
363 if (signal (i, orig_handlers[i]) == SIG_ERR)
1bbd0b84 364 SCM_SYSERROR;
e1a191a8 365 orig_handlers[i] = SIG_ERR;
34d19ef6 366 SCM_VECTOR_SET (*signal_handlers, i, SCM_BOOL_F);
e1a191a8
GH
367 }
368#endif
369 }
370 return SCM_UNSPECIFIED;
371}
1bbd0b84 372#undef FUNC_NAME
0f2d19dd 373
adb2c53b 374SCM_DEFINE (scm_alarm, "alarm", 1, 0, 0,
1bbd0b84 375 (SCM i),
b380b885
MD
376 "Set a timer to raise a @code{SIGALRM} signal after the specified\n"
377 "number of seconds (an integer). It's advisable to install a signal\n"
378 "handler for\n"
379 "@code{SIGALRM} beforehand, since the default action is to terminate\n"
380 "the process.\n\n"
381 "The return value indicates the time remaining for the previous alarm,\n"
382 "if any. The new value replaces the previous alarm. If there was\n"
383 "no previous alarm, the return value is zero.")
1bbd0b84 384#define FUNC_NAME s_scm_alarm
0f2d19dd
JB
385{
386 unsigned int j;
34d19ef6 387 SCM_VALIDATE_INUM (1, i);
e1a191a8 388 j = alarm (SCM_INUM (i));
0f2d19dd
JB
389 return SCM_MAKINUM (j);
390}
1bbd0b84 391#undef FUNC_NAME
0f2d19dd 392
53f8a0d2
RB
393#ifdef HAVE_SETITIMER
394SCM_DEFINE (scm_setitimer, "setitimer", 5, 0, 0,
395 (SCM which_timer,
396 SCM interval_seconds, SCM interval_microseconds,
397 SCM value_seconds, SCM value_microseconds),
398 "Set the timer specified by @var{which_timer} according to the given\n"
399 "@var{interval_seconds}, @var{interval_microseconds},\n"
400 "@var{value_seconds}, and @var{value_microseconds} values.\n"
401 "\n"
402 "Return information about the timer's previous setting."
403 "\n"
404 "Errors are handled as described in the guile info pages under ``POSIX\n"
405 "Interface Conventions''.\n"
406 "\n"
9401323e 407 "The timers available are: @code{ITIMER_REAL}, @code{ITIMER_VIRTUAL},\n"
53f8a0d2
RB
408 "and @code{ITIMER_PROF}.\n"
409 "\n"
410 "The return value will be a list of two cons pairs representing the\n"
411 "current state of the given timer. The first pair is the seconds and\n"
412 "microseconds of the timer @code{it_interval}, and the second pair is\n"
9401323e 413 "the seconds and microseconds of the timer @code{it_value}.")
53f8a0d2
RB
414#define FUNC_NAME s_scm_setitimer
415{
416 int rv;
417 int c_which_timer;
418 struct itimerval new_timer;
419 struct itimerval old_timer;
420
421 c_which_timer = SCM_NUM2INT(1, which_timer);
422 new_timer.it_interval.tv_sec = SCM_NUM2LONG(2, interval_seconds);
423 new_timer.it_interval.tv_usec = SCM_NUM2LONG(3, interval_microseconds);
424 new_timer.it_value.tv_sec = SCM_NUM2LONG(4, value_seconds);
425 new_timer.it_value.tv_usec = SCM_NUM2LONG(5, value_microseconds);
426
427 SCM_SYSCALL(rv = setitimer(c_which_timer, &new_timer, &old_timer));
428
429 if(rv != 0)
430 SCM_SYSERROR;
431
432 return scm_list_2(scm_cons(scm_long2num(old_timer.it_interval.tv_sec),
433 scm_long2num(old_timer.it_interval.tv_usec)),
434 scm_cons(scm_long2num(old_timer.it_value.tv_sec),
435 scm_long2num(old_timer.it_value.tv_usec)));
436}
437#undef FUNC_NAME
438#endif /* HAVE_SETITIMER */
439
440#ifdef HAVE_GETITIMER
441SCM_DEFINE (scm_getitimer, "getitimer", 1, 0, 0,
442 (SCM which_timer),
443 "Return information about the timer specified by @var{which_timer}"
444 "\n"
445 "Errors are handled as described in the guile info pages under ``POSIX\n"
446 "Interface Conventions''.\n"
447 "\n"
9401323e 448 "The timers available are: @code{ITIMER_REAL}, @code{ITIMER_VIRTUAL},\n"
53f8a0d2
RB
449 "and @code{ITIMER_PROF}.\n"
450 "\n"
451 "The return value will be a list of two cons pairs representing the\n"
452 "current state of the given timer. The first pair is the seconds and\n"
453 "microseconds of the timer @code{it_interval}, and the second pair is\n"
9401323e 454 "the seconds and microseconds of the timer @code{it_value}.")
53f8a0d2
RB
455#define FUNC_NAME s_scm_getitimer
456{
457 int rv;
458 int c_which_timer;
459 struct itimerval old_timer;
460
461 c_which_timer = SCM_NUM2INT(1, which_timer);
462
463 SCM_SYSCALL(rv = getitimer(c_which_timer, &old_timer));
464
465 if(rv != 0)
466 SCM_SYSERROR;
467
468 return scm_list_2(scm_cons(scm_long2num(old_timer.it_interval.tv_sec),
469 scm_long2num(old_timer.it_interval.tv_usec)),
470 scm_cons(scm_long2num(old_timer.it_value.tv_sec),
471 scm_long2num(old_timer.it_value.tv_usec)));
472}
473#undef FUNC_NAME
474#endif /* HAVE_GETITIMER */
475
0e958795 476#ifdef HAVE_PAUSE
adb2c53b 477SCM_DEFINE (scm_pause, "pause", 0, 0, 0,
1bbd0b84 478 (),
b380b885
MD
479 "Pause the current process (thread?) until a signal arrives whose\n"
480 "action is to either terminate the current process or invoke a\n"
481 "handler procedure. The return value is unspecified.")
1bbd0b84 482#define FUNC_NAME s_scm_pause
0f2d19dd
JB
483{
484 pause ();
485 return SCM_UNSPECIFIED;
486}
1bbd0b84 487#undef FUNC_NAME
0e958795 488#endif
0f2d19dd 489
adb2c53b 490SCM_DEFINE (scm_sleep, "sleep", 1, 0, 0,
1bbd0b84 491 (SCM i),
b380b885
MD
492 "Wait for the given number of seconds (an integer) or until a signal\n"
493 "arrives. The return value is zero if the time elapses or the number\n"
494 "of seconds remaining otherwise.")
1bbd0b84 495#define FUNC_NAME s_scm_sleep
0f2d19dd 496{
b74f4728 497 unsigned long j;
34d19ef6 498 SCM_VALIDATE_INUM_MIN (1, i,0);
b74f4728
JB
499#ifdef USE_THREADS
500 j = scm_thread_sleep (SCM_INUM(i));
501#else
e1a191a8 502 j = sleep (SCM_INUM(i));
b74f4728
JB
503#endif
504 return scm_ulong2num (j);
0f2d19dd 505}
1bbd0b84 506#undef FUNC_NAME
0f2d19dd 507
ed618cc9 508#if defined(USE_THREADS) || defined(HAVE_USLEEP) || defined(__MINGW32__)
adb2c53b 509SCM_DEFINE (scm_usleep, "usleep", 1, 0, 0,
1bbd0b84 510 (SCM i),
5352393c
MG
511 "Sleep for I microseconds. @code{usleep} is not available on\n"
512 "all platforms.")
1bbd0b84 513#define FUNC_NAME s_scm_usleep
ce874f2d 514{
34d19ef6 515 SCM_VALIDATE_INUM_MIN (1, i,0);
b74f4728
JB
516
517#ifdef USE_THREADS
518 /* If we have threads, we use the thread system's sleep function. */
519 {
520 unsigned long j = scm_thread_usleep (SCM_INUM (i));
521 return scm_ulong2num (j);
522 }
523#else
0935d604
MD
524#ifdef USLEEP_RETURNS_VOID
525 usleep (SCM_INUM (i));
526 return SCM_INUM0;
527#else
b74f4728
JB
528 {
529 int j = usleep (SCM_INUM (i));
530 return SCM_MAKINUM (j);
531 }
0935d604 532#endif
ce874f2d 533#endif
b74f4728 534}
1bbd0b84 535#undef FUNC_NAME
ed618cc9 536#endif /* USE_THREADS || HAVE_USLEEP || __MINGW32__ */
ce874f2d 537
adb2c53b 538SCM_DEFINE (scm_raise, "raise", 1, 0, 0,
1bbd0b84 539 (SCM sig),
b380b885
MD
540 "Sends a specified signal @var{sig} to the current process, where\n"
541 "@var{sig} is as described for the kill procedure.")
1bbd0b84 542#define FUNC_NAME s_scm_raise
0f2d19dd 543{
34d19ef6 544 SCM_VALIDATE_INUM (1, sig);
e1a191a8
GH
545 SCM_DEFER_INTS;
546 if (kill (getpid (), (int) SCM_INUM (sig)) != 0)
1bbd0b84 547 SCM_SYSERROR;
e1a191a8
GH
548 SCM_ALLOW_INTS;
549 return SCM_UNSPECIFIED;
0f2d19dd 550}
1bbd0b84 551#undef FUNC_NAME
0f2d19dd
JB
552
553\f
0f2d19dd 554
e1a191a8
GH
555void
556scm_init_scmsigs ()
0f2d19dd 557{
e1a191a8
GH
558 SCM thunk;
559 int i;
560
561 signal_handlers =
86d31dfe
MV
562 SCM_VARIABLE_LOC (scm_c_define ("signal-handlers",
563 scm_c_make_vector (NSIG, SCM_BOOL_F)));
9a441ddb
MV
564 /* XXX - use scm_c_make_gsubr here instead of `define'? */
565 thunk = scm_c_define_gsubr ("%deliver-signals", 0, 0, 0,
566 sys_deliver_signals);
e1a191a8
GH
567 signal_async = scm_system_async (thunk);
568
569 for (i = 0; i < NSIG; i++)
570 {
571 got_signal[i] = 0;
572#ifdef HAVE_SIGACTION
573 orig_handlers[i].sa_handler = SIG_ERR;
840ae05d 574
e1a191a8
GH
575#else
576 orig_handlers[i] = SIG_ERR;
0f2d19dd 577#endif
840ae05d 578
08b8c694 579#ifdef HAVE_RESTARTABLE_SYSCALLS
7ee92fce 580 /* If HAVE_RESTARTABLE_SYSCALLS is defined, it's important that
adb2c53b 581 signals really are restartable. don't rely on the same
7ee92fce
GH
582 run-time that configure got: reset the default for every signal.
583 */
584#ifdef HAVE_SIGINTERRUPT
585 siginterrupt (i, 0);
de881428 586#elif defined(SA_RESTART)
840ae05d
JB
587 {
588 struct sigaction action;
589
590 sigaction (i, NULL, &action);
591 if (!(action.sa_flags & SA_RESTART))
592 {
3efb80f2 593 action.sa_flags |= SA_RESTART;
840ae05d
JB
594 sigaction (i, &action, NULL);
595 }
596 }
7ee92fce
GH
597#endif
598 /* if neither siginterrupt nor SA_RESTART are available we may
599 as well assume that signals are always restartable. */
840ae05d 600#endif
e1a191a8 601 }
1cc91f1b 602
86d31dfe
MV
603 scm_c_define ("NSIG", scm_long2num (NSIG));
604 scm_c_define ("SIG_IGN", scm_long2num ((long) SIG_IGN));
605 scm_c_define ("SIG_DFL", scm_long2num ((long) SIG_DFL));
e1a191a8 606#ifdef SA_NOCLDSTOP
86d31dfe 607 scm_c_define ("SA_NOCLDSTOP", scm_long2num (SA_NOCLDSTOP));
0f2d19dd 608#endif
e1a191a8 609#ifdef SA_RESTART
86d31dfe 610 scm_c_define ("SA_RESTART", scm_long2num (SA_RESTART));
0f2d19dd 611#endif
1cc91f1b 612
53f8a0d2
RB
613#if defined(HAVE_SETITIMER) || defined(HAVE_GETITIMER)
614 /* Stuff needed by setitimer and getitimer. */
615 scm_c_define ("ITIMER_REAL", SCM_MAKINUM (ITIMER_REAL));
616 scm_c_define ("ITIMER_VIRTUAL", SCM_MAKINUM (ITIMER_VIRTUAL));
617 scm_c_define ("ITIMER_PROF", SCM_MAKINUM (ITIMER_PROF));
618#endif /* defined(HAVE_SETITIMER) || defined(HAVE_GETITIMER) */
619
a0599745 620#include "libguile/scmsigs.x"
0f2d19dd
JB
621}
622
89e00824
ML
623
624/*
625 Local Variables:
626 c-file-style: "gnu"
627 End:
628*/