summaryrefslogtreecommitdiffstats
path: root/signal.h
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2013-12-12 22:47:27 -0800
committerKaz Kylheku <kaz@kylheku.com>2013-12-12 22:47:27 -0800
commitb3f8bee89e3fa5713ff391e0172b8e1d4b92be25 (patch)
tree14d49b10503cd3e086d00c79df184e51d444fe6b /signal.h
parentccf6c78422c227778c5e6103413849803aa7b158 (diff)
downloadtxr-b3f8bee89e3fa5713ff391e0172b8e1d4b92be25.tar.gz
txr-b3f8bee89e3fa5713ff391e0172b8e1d4b92be25.tar.bz2
txr-b3f8bee89e3fa5713ff391e0172b8e1d4b92be25.zip
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 <signal.h> 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.
Diffstat (limited to 'signal.h')
-rw-r--r--signal.h93
1 files changed, 93 insertions, 0 deletions
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 <kaz@kylheku.com>
+ * 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);