From b3f8bee89e3fa5713ff391e0172b8e1d4b92be25 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Thu, 12 Dec 2013 22:47:27 -0800 Subject: First cut at signal handling support. * Makefile (OBJS-y): Include signal.o if have_posix_sigs is "y". * configure (have_posix_sigs): New variable, set by detecting POSIX signal stuff. * dep.mk: Regenerated. * arith.c, debug.c, eval.c, filter.c, hash.c, match.c, parser.y, parser.l, rand.c, regex.c, syslog.c, txr.c, utf8.c: Include new signal.h header, now required by unwind, and the system header. * eval.c (exit_wrap): New function. (eval_init): New functions registered as intrinsics: exit_wrap, set_sig_handler, get_sig_handler, sig_check. * gc.c (release): Unused functions removed. * gc.h (release): Declaration removed. * lib.c (init): Call sig_init. * stream.c (set_putc, se_getc, se_fflush): New static functions. (stdio_put_char_callback, stdio_get_char_callback, stdio_put_byte, stdio_flush, stdio_get_byte): Use new functions to enable signals when blocked on I/O. (tail_strategy): Allow signals across sleep. (pipev_close): Allow signals across waitpid. (se_pclose): New static function. (pipe_close): Use new function to enable signals across pclose. * unwind.c (uw_unwind_to_exit_point): use extended_longjmp instead of longjmp. * unwind.h (struct uw_block, struct uw_catch): jb member changes from jmp_buf to extended_jmp_buf. (uw_block_begin, uw_simple_catch_begin, uw_catch_begin): Use extended_setjmp instead of setjmp. * signal.c: New file. * signal.h: New file. --- signal.h | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 signal.h (limited to 'signal.h') diff --git a/signal.h b/signal.h new file mode 100644 index 00000000..111c6265 --- /dev/null +++ b/signal.h @@ -0,0 +1,93 @@ +/* Copyright 2013-2014 + * Kaz Kylheku + * Vancouver, Canada + * All rights reserved. + * + * BSD License: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + + +#if HAVE_POSIX_SIGS + +#define sig_save_enable \ + do { \ + int sig_save = async_sig_enabled; \ + async_sig_enabled = 1; \ + if (!sig_save) \ + sig_check(); \ + { \ + typedef void v_o_i_d + +#define sig_restore_enable \ + do { } while (0); \ + } \ + async_sig_enabled = sig_save; \ + } while(0) + +#define sig_save_disable \ + do { \ + int sig_save = async_sig_enabled; \ + async_sig_enabled = 1; \ + { \ + typedef void v_o_i_d + +#define sig_restore_disable \ + do { } while (0); \ + } \ + async_sig_enabled = sig_save; \ + if (sig_save) \ + sig_check(); \ + } while(0) + +typedef struct { + jmp_buf jb; + sig_atomic_t se; + int rv; +} extended_jmp_buf; + +#define extended_setjmp(EJB) \ + (sigsetjmp((EJB).jb, 1) \ + ? (async_sig_enabled = (EJB).se, (EJB).rv) \ + : ((EJB).se = async_sig_enabled, 0)) + +#define extended_longjmp(EJB, ARG) \ + ((EJB).rv = (ARG), longjmp((EJB).jb, 1)) + +#else + +#define sig_save_enable do { +#define sig_save_disable do { + +#define sig_restore_enable do { } while (0); } while (0) +#define sig_restore_disable do { } while (0); } while (0) + +tyedef jmp_buf extended_jmp_buf; +#define extended_setjmp(EJB) setjmp(EJB) +#define extended_longjmp(EJB, ARG) longjmp(EJB, ARG) + +#endif + +extern volatile sig_atomic_t async_sig_enabled; + +void sig_init(void); +val set_sig_handler(val signo, val lambda); +val get_sig_handler(val signo); +val sig_check(void); -- cgit v1.2.3