summaryrefslogtreecommitdiffstats
path: root/usr/include/setjmp.h
diff options
context:
space:
mode:
Diffstat (limited to 'usr/include/setjmp.h')
-rw-r--r--usr/include/setjmp.h48
1 files changed, 48 insertions, 0 deletions
diff --git a/usr/include/setjmp.h b/usr/include/setjmp.h
new file mode 100644
index 0000000..5916cd8
--- /dev/null
+++ b/usr/include/setjmp.h
@@ -0,0 +1,48 @@
+/*
+ * setjmp.h
+ */
+
+#ifndef _SETJMP_H
+#define _SETJMP_H
+
+#include <klibc/extern.h>
+#include <klibc/compiler.h>
+#include <stddef.h>
+#include <signal.h>
+
+#include <klibc/archsetjmp.h>
+
+__extern int setjmp(jmp_buf);
+__extern __noreturn longjmp(jmp_buf, int);
+
+/*
+ Whose bright idea was it to add unrelated functionality to just about
+ the only function in the standard C library (setjmp) which cannot be
+ wrapped by an ordinary function wrapper? Anyway, the damage is done,
+ and therefore, this wrapper *must* be inline. However, gcc will
+ complain if this is an inline function for unknown reason, and
+ therefore sigsetjmp() needs to be a macro.
+*/
+
+struct __sigjmp_buf {
+ jmp_buf __jmpbuf;
+ sigset_t __sigs;
+ unsigned char __sigs_saved;
+};
+
+typedef struct __sigjmp_buf sigjmp_buf[1];
+
+#define sigsetjmp(__env, __save) \
+({ \
+ struct __sigjmp_buf *__e = (__env); \
+ if (__save) { \
+ sigprocmask(0, NULL, &__e->__sigs); \
+ __e->__sigs_saved = 1; \
+ } else \
+ __e->__sigs_saved = 0; \
+ setjmp(__e->__jmpbuf); \
+})
+
+__extern __noreturn siglongjmp(sigjmp_buf, int);
+
+#endif /* _SETJMP_H */