From 77f3a9073fe5d4c9948d0b5c997e224529b09c4a Mon Sep 17 00:00:00 2001 From: Quentin Smith Date: Sun, 26 Feb 2012 15:58:37 -0500 Subject: [PATCH] Import selfpipe code from skalibs 1.2.5 [andersk@mit.edu: Move code to new third/libstddjb directory] --- third/libstddjb/COPYING | 15 +++++++ third/libstddjb/allreadwrite.h | 25 +++++++++++ third/libstddjb/coe.c | 11 +++++ third/libstddjb/fd_close.c | 15 +++++++ third/libstddjb/fd_read.c | 13 ++++++ third/libstddjb/fd_write.c | 13 ++++++ third/libstddjb/gccattributes.h | 61 +++++++++++++++++++++++++++ third/libstddjb/ndelay_on.c | 15 +++++++ third/libstddjb/nsig.h | 13 ++++++ third/libstddjb/pipe_internal.c | 36 ++++++++++++++++ third/libstddjb/sanitize_read.c | 15 +++++++ third/libstddjb/selfpipe-internal.h | 28 +++++++++++++ third/libstddjb/selfpipe.h | 17 ++++++++ third/libstddjb/selfpipe_finish.c | 35 ++++++++++++++++ third/libstddjb/selfpipe_init.c | 27 ++++++++++++ third/libstddjb/selfpipe_internal.c | 31 ++++++++++++++ third/libstddjb/selfpipe_read.c | 31 ++++++++++++++ third/libstddjb/selfpipe_trap.c | 51 +++++++++++++++++++++++ third/libstddjb/selfpipe_trapset.c | 64 +++++++++++++++++++++++++++++ third/libstddjb/selfpipe_untrap.c | 54 ++++++++++++++++++++++++ third/libstddjb/sig.h | 61 +++++++++++++++++++++++++++ third/libstddjb/sig_restoreto.c | 17 ++++++++ third/libstddjb/skasig_dfl.c | 7 ++++ third/libstddjb/skasigaction.c | 42 +++++++++++++++++++ 24 files changed, 697 insertions(+) create mode 100644 third/libstddjb/COPYING create mode 100644 third/libstddjb/allreadwrite.h create mode 100644 third/libstddjb/coe.c create mode 100644 third/libstddjb/fd_close.c create mode 100644 third/libstddjb/fd_read.c create mode 100644 third/libstddjb/fd_write.c create mode 100644 third/libstddjb/gccattributes.h create mode 100644 third/libstddjb/ndelay_on.c create mode 100644 third/libstddjb/nsig.h create mode 100644 third/libstddjb/pipe_internal.c create mode 100644 third/libstddjb/sanitize_read.c create mode 100644 third/libstddjb/selfpipe-internal.h create mode 100644 third/libstddjb/selfpipe.h create mode 100644 third/libstddjb/selfpipe_finish.c create mode 100644 third/libstddjb/selfpipe_init.c create mode 100644 third/libstddjb/selfpipe_internal.c create mode 100644 third/libstddjb/selfpipe_read.c create mode 100644 third/libstddjb/selfpipe_trap.c create mode 100644 third/libstddjb/selfpipe_trapset.c create mode 100644 third/libstddjb/selfpipe_untrap.c create mode 100644 third/libstddjb/sig.h create mode 100644 third/libstddjb/sig_restoreto.c create mode 100644 third/libstddjb/skasig_dfl.c create mode 100644 third/libstddjb/skasigaction.c diff --git a/third/libstddjb/COPYING b/third/libstddjb/COPYING new file mode 100644 index 0000000..cc53e86 --- /dev/null +++ b/third/libstddjb/COPYING @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2011-2012 Laurent Bercot + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/third/libstddjb/allreadwrite.h b/third/libstddjb/allreadwrite.h new file mode 100644 index 0000000..e893f52 --- /dev/null +++ b/third/libstddjb/allreadwrite.h @@ -0,0 +1,25 @@ +/* ISC license. */ + +#ifndef ALLREADWRITE_H +#define ALLREADWRITE_H + +typedef int iofunc_t (int, char *, unsigned int) ; +typedef iofunc_t *iofunc_t_ref ; + +typedef unsigned int alliofunc_t (int, char *, unsigned int) ; +typedef alliofunc_t *alliofunc_t_ref ; + +extern int sanitize_read (int) ; +extern unsigned int allreadwrite (iofunc_t_ref, int, char *, unsigned int) ; + +extern int fd_read (int, char *, unsigned int) ; +extern int fd_write (int, char const *, unsigned int) ; + +extern int fd_recv (int, char *, unsigned int, unsigned int) ; +extern int fd_send (int, char const *, unsigned int, unsigned int) ; + +extern unsigned int allread (int, char *, unsigned int) ; +extern unsigned int allwrite (int, char const *, unsigned int) ; + + +#endif diff --git a/third/libstddjb/coe.c b/third/libstddjb/coe.c new file mode 100644 index 0000000..cee4fe9 --- /dev/null +++ b/third/libstddjb/coe.c @@ -0,0 +1,11 @@ +/* ISC license. */ + +#include +#include "djbunix.h" + +int coe (int fd) +{ + register int flags = fcntl(fd, F_GETFD, 0) ; + if (flags < 0) return -1 ; + return fcntl(fd, F_SETFD, flags | FD_CLOEXEC) ; +} diff --git a/third/libstddjb/fd_close.c b/third/libstddjb/fd_close.c new file mode 100644 index 0000000..8fa19e0 --- /dev/null +++ b/third/libstddjb/fd_close.c @@ -0,0 +1,15 @@ +/* ISC license. */ + +#include +#include +#include "djbunix.h" + +int fd_close (int fd) +{ + register unsigned int i = 0 ; +doit: + if (!close(fd)) return 0 ; + i++ ; + if (errno == EINTR) goto doit ; + return ((errno == EBADF) && (i > 1)) ? 0 : -1 ; +} diff --git a/third/libstddjb/fd_read.c b/third/libstddjb/fd_read.c new file mode 100644 index 0000000..3a90e6b --- /dev/null +++ b/third/libstddjb/fd_read.c @@ -0,0 +1,13 @@ +/* ISC license. */ + +#include +#include +#include "allreadwrite.h" + +int fd_read (int fd, char *buf, unsigned int len) +{ + register int r ; + do r = read(fd, buf, len) ; + while ((r == -1) && (errno == EINTR)) ; + return r ; +} diff --git a/third/libstddjb/fd_write.c b/third/libstddjb/fd_write.c new file mode 100644 index 0000000..780efac --- /dev/null +++ b/third/libstddjb/fd_write.c @@ -0,0 +1,13 @@ +/* ISC license. */ + +#include +#include +#include "allreadwrite.h" + +int fd_write (int fd, char const *buf, unsigned int len) +{ + register int r ; + do r = write(fd, buf, len) ; + while ((r == -1) && (errno == EINTR)) ; + return r ; +} diff --git a/third/libstddjb/gccattributes.h b/third/libstddjb/gccattributes.h new file mode 100644 index 0000000..0584480 --- /dev/null +++ b/third/libstddjb/gccattributes.h @@ -0,0 +1,61 @@ +/* ISC license. */ + +#ifndef GCCATTRIBUTES_H +#define GCCATTRIBUTES_H + +#ifdef __GNUC__ + +#define gccattr_noreturn __attribute__((__noreturn__)) +#define gccattr_noinline __attribute__((__noinline__)) +#define gccattr_inline __attribute__((__always_inline__)) +#define gccattr_const __attribute__((__const__)) +#define gccattr_unused __attribute__((__unused__)) +#define gccattr_used __attribute__((__used__)) +#define gccattr_weak __attribute__((__weak__)) +#define gccattr_aligned __attribute__((__aligned__)) + +# if (__GNUC__ >= 3) || ((__GNUC__ == 2) && (__GNUC_MINOR__ >= 96)) +#define gccattr_malloc __attribute__((__malloc__)) +#define gccattr_pure __attribute__((__pure__)) +# else +#define gccattr_malloc +#define gccattr_pure +# endif + +# if (__GNUC__ >= 3) +#define gccattr_deprecated __attribute__((__deprecated__)) +# else +#define gccattr_deprecated +# endif + +#else + +#define gccattr_noreturn +#define gccattr_noinline +#define gccattr_inline +#define gccattr_const +#define gccattr_unused +#define gccattr_used +#define gccattr_weak +#define gccattr_aligned +#define gccattr_malloc +#define gccattr_pure +#define gccattr_deprecated + +#endif + +#ifdef GCCATTR_COMPAT_0_22 +#define _a_noreturn gccattr_noreturn +#define _a_noinline gccattr_noinline +#define _a_inline gccattr_inline +#define _a_const gccattr_const +#define _a_unused gccattr_unused +#define _a_used gccattr_used +#define _a_weak gccattr_weak +#define _a_aligned gccattr_aligned +#define _a_malloc gccattr_malloc +#define _a_pure gccattr_pure +#define _a_deprecated gccattr_deprecated +#endif + +#endif diff --git a/third/libstddjb/ndelay_on.c b/third/libstddjb/ndelay_on.c new file mode 100644 index 0000000..4fc5148 --- /dev/null +++ b/third/libstddjb/ndelay_on.c @@ -0,0 +1,15 @@ +/* ISC license. */ + +#include +#include +#include "djbunix.h" + +#ifndef O_NONBLOCK +#define O_NONBLOCK O_NDELAY +#endif + +int ndelay_on (int fd) +{ + register int got = fcntl(fd, F_GETFL) ; + return (got == -1) ? -1 : fcntl(fd, F_SETFL, got | O_NONBLOCK) ; +} diff --git a/third/libstddjb/nsig.h b/third/libstddjb/nsig.h new file mode 100644 index 0000000..f6bd240 --- /dev/null +++ b/third/libstddjb/nsig.h @@ -0,0 +1,13 @@ +/* ISC license. */ + +#ifndef NSIG_H + +#include + +#define SKALIBS_NSIG 64 + +#ifndef NSIG +# define NSIG SKALIBS_NSIG +#endif + +#endif diff --git a/third/libstddjb/pipe_internal.c b/third/libstddjb/pipe_internal.c new file mode 100644 index 0000000..9e7aaf7 --- /dev/null +++ b/third/libstddjb/pipe_internal.c @@ -0,0 +1,36 @@ +/* ISC license. */ + +#include "sysdeps.h" +#ifdef HASPIPE2 +# define _GNU_SOURCE +# include +#else +# include +#endif + +#include +#include "djbunix.h" + +int pipe_internal (int *p, unsigned int flags) +{ +#ifdef HASPIPE2 + return pipe2(p, ((flags & DJBUNIX_FLAG_COE) ? O_CLOEXEC : 0) | ((flags & DJBUNIX_FLAG_NB) ? O_NONBLOCK : 0)) ; +#else + int pi[2] ; + if (pipe(pi) < 0) return -1 ; + if (flags & DJBUNIX_FLAG_COE) + if ((coe(pi[0]) < 0) || (coe(pi[1]) < 0)) goto err ; + if (flags & DJBUNIX_FLAG_NB) + if ((ndelay_on(pi[0]) < 0) || (ndelay_on(pi[1]) < 0)) goto err ; + p[0] = pi[0] ; p[1] = pi[1] ; + return 0 ; + err: + { + register int e = errno ; + fd_close(pi[1]) ; + fd_close(pi[0]) ; + errno = e ; + } + return -1 ; +#endif +} diff --git a/third/libstddjb/sanitize_read.c b/third/libstddjb/sanitize_read.c new file mode 100644 index 0000000..7d87d70 --- /dev/null +++ b/third/libstddjb/sanitize_read.c @@ -0,0 +1,15 @@ +/* ISC license. */ + +#include +#include "allreadwrite.h" +#include "error.h" + +int sanitize_read (int r) +{ + switch (r) + { + case -1 : return error_isagain(errno) ? (errno = 0, 0) : -1 ; + case 0 : return (errno = EPIPE, -1) ; + default : return r ; + } +} diff --git a/third/libstddjb/selfpipe-internal.h b/third/libstddjb/selfpipe-internal.h new file mode 100644 index 0000000..1f9d0f4 --- /dev/null +++ b/third/libstddjb/selfpipe-internal.h @@ -0,0 +1,28 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#ifndef SELFPIPE_INTERNAL_H +#define SELFPIPE_INTERNAL_H + +#include +#include "sysdeps.h" + +extern sigset_t selfpipe_caught ; + +#ifdef HASSIGNALFD + +extern int selfpipe_fd ; + +#else + +#include "sig.h" + +extern int selfpipe[2] ; +#define selfpipe_fd selfpipe[0] + +extern struct skasigaction const selfpipe_ssa ; + +#endif + +#endif diff --git a/third/libstddjb/selfpipe.h b/third/libstddjb/selfpipe.h new file mode 100644 index 0000000..c587f93 --- /dev/null +++ b/third/libstddjb/selfpipe.h @@ -0,0 +1,17 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#ifndef SELFPIPE_H +#define SELFPIPE_H + +#include + +extern int selfpipe_init (void) ; +extern int selfpipe_trap (int) ; +extern int selfpipe_untrap (int) ; +extern int selfpipe_trapset (sigset_t const *) ; +extern int selfpipe_read (void) ; +extern void selfpipe_finish (void) ; + +#endif diff --git a/third/libstddjb/selfpipe_finish.c b/third/libstddjb/selfpipe_finish.c new file mode 100644 index 0000000..af9a2da --- /dev/null +++ b/third/libstddjb/selfpipe_finish.c @@ -0,0 +1,35 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include +#include "sysdeps.h" +#include "djbunix.h" +#include "selfpipe-internal.h" +#include "selfpipe.h" + +#ifdef HASSIGNALFD + +void selfpipe_finish (void) +{ + sigprocmask(SIG_UNBLOCK, &selfpipe_caught, 0) ; + sigemptyset(&selfpipe_caught) ; + fd_close(selfpipe_fd) ; + selfpipe_fd = -1 ; +} + +#else + +#include "sig.h" +#include "nsig.h" + +void selfpipe_finish (void) +{ + sig_restoreto(&selfpipe_caught, NSIG) ; + sigemptyset(&selfpipe_caught) ; + fd_close(selfpipe[1]) ; + fd_close(selfpipe[0]) ; + selfpipe[0] = selfpipe[1] = -1 ; +} + +#endif diff --git a/third/libstddjb/selfpipe_init.c b/third/libstddjb/selfpipe_init.c new file mode 100644 index 0000000..81d6f4d --- /dev/null +++ b/third/libstddjb/selfpipe_init.c @@ -0,0 +1,27 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include +#include +#include "sysdeps.h" +#include "selfpipe-internal.h" +#include "selfpipe.h" + +#ifdef HASSIGNALFD +# include +#else +# include "djbunix.h" +#endif + +int selfpipe_init (void) +{ + if (selfpipe_fd >= 0) return (errno = EBUSY, -1) ; + sigemptyset(&selfpipe_caught) ; +#ifdef HASSIGNALFD + selfpipe_fd = signalfd(-1, &selfpipe_caught, SFD_NONBLOCK | SFD_CLOEXEC) ; +#else + if (pipenbcoe(selfpipe) < 0) return -1 ; +#endif + return selfpipe_fd ; +} diff --git a/third/libstddjb/selfpipe_internal.c b/third/libstddjb/selfpipe_internal.c new file mode 100644 index 0000000..a3e39f4 --- /dev/null +++ b/third/libstddjb/selfpipe_internal.c @@ -0,0 +1,31 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include +#include "sysdeps.h" +#include "selfpipe-internal.h" + +sigset_t selfpipe_caught ; + +#ifdef HASSIGNALFD + +int selfpipe_fd = -1 ; + +#else + +#include +#include "allreadwrite.h" +#include "djbunix.h" + +int selfpipe[2] = { -1, -1 } ; + +static void selfpipe_trigger (int s) +{ + char c = (char)s ; + fd_write(selfpipe[1], &c, 1) ; +} + +struct skasigaction const selfpipe_ssa = { &selfpipe_trigger, SKASA_NOCLDSTOP | SKASA_MASKALL } ; + +#endif diff --git a/third/libstddjb/selfpipe_read.c b/third/libstddjb/selfpipe_read.c new file mode 100644 index 0000000..dc34368 --- /dev/null +++ b/third/libstddjb/selfpipe_read.c @@ -0,0 +1,31 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include "sysdeps.h" +#include "allreadwrite.h" +#include "selfpipe-internal.h" +#include "selfpipe.h" + +#ifdef HASSIGNALFD + +#include + +int selfpipe_read (void) +{ + struct signalfd_siginfo buf ; + register int r = sanitize_read(fd_read(selfpipe_fd, (char *)&buf, sizeof(struct signalfd_siginfo))) ; + return (r <= 0) ? r : (int)buf.ssi_signo ; +} + +#else + +int selfpipe_read (void) +{ + char c ; + register int r = sanitize_read((fd_read(selfpipe_fd, &c, 1))) ; + return (r <= 0) ? r : (int)c ; +} + +#endif + diff --git a/third/libstddjb/selfpipe_trap.c b/third/libstddjb/selfpipe_trap.c new file mode 100644 index 0000000..2f3db3a --- /dev/null +++ b/third/libstddjb/selfpipe_trap.c @@ -0,0 +1,51 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include +#include +#include "sysdeps.h" +#include "selfpipe-internal.h" +#include "selfpipe.h" + +#ifdef HASSIGNALFD + +#include + +int selfpipe_trap (int sig) +{ + sigset_t ss = selfpipe_caught ; + sigset_t old ; + if (selfpipe_fd < 0) return (errno = EBADF, -1) ; + if ((sigaddset(&ss, sig) < 0) || (sigprocmask(SIG_BLOCK, &ss, &old) < 0)) + return -1 ; + if (signalfd(selfpipe_fd, &ss, SFD_NONBLOCK | SFD_CLOEXEC) < 0) + { + int e = errno ; + sigprocmask(SIG_SETMASK, &old, 0) ; + errno = e ; + return -1 ; + } + selfpipe_caught = ss ; + return 0 ; +} + +#else + +#include "sig.h" + +int selfpipe_trap (int sig) +{ + if (selfpipe_fd < 0) return (errno = EBADF, -1) ; + if (sig_catcha(sig, &selfpipe_ssa) < 0) return -1 ; + if (sigaddset(&selfpipe_caught, sig) < 0) + { + int e = errno ; + sig_restore(sig) ; + errno = e ; + return -1 ; + } + return 0 ; +} + +#endif diff --git a/third/libstddjb/selfpipe_trapset.c b/third/libstddjb/selfpipe_trapset.c new file mode 100644 index 0000000..4b97e29 --- /dev/null +++ b/third/libstddjb/selfpipe_trapset.c @@ -0,0 +1,64 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include +#include +#include "sysdeps.h" +#include "selfpipe-internal.h" +#include "selfpipe.h" + +#ifdef HASSIGNALFD + +#include + +int selfpipe_trapset (sigset_t const *set) +{ + sigset_t old ; + if (selfpipe_fd < 0) return (errno = EBADF, -1) ; + if (sigprocmask(SIG_SETMASK, set, &old) < 0) return -1 ; + if (signalfd(selfpipe_fd, set, SFD_NONBLOCK | SFD_CLOEXEC) < 0) + { + int e = errno ; + sigprocmask(SIG_SETMASK, &old, 0) ; + errno = e ; + return -1 ; + } + selfpipe_caught = *set ; + return 0 ; +} + +#else + +#include "sig.h" +#include "nsig.h" + +int selfpipe_trapset (sigset_t const *set) +{ + unsigned int i = 1 ; + if (selfpipe_fd < 0) return (errno = EBADF, -1) ; + for (; i <= NSIG ; i++) + { + register int h = sigismember(set, i) ; + if (h < 0) continue ; + if (h) + { + if (sig_catcha(i, &selfpipe_ssa) < 0) break ; + } + else if (sigismember(&selfpipe_caught, i)) + { + if (sig_restore(i) < 0) break ; + } + } + if (i <= NSIG) + { + int e = errno ; + sig_restoreto(set, i) ; + errno = e ; + return -1 ; + } + selfpipe_caught = *set ; + return 0 ; +} + +#endif diff --git a/third/libstddjb/selfpipe_untrap.c b/third/libstddjb/selfpipe_untrap.c new file mode 100644 index 0000000..994ab9f --- /dev/null +++ b/third/libstddjb/selfpipe_untrap.c @@ -0,0 +1,54 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include +#include +#include "sysdeps.h" +#include "selfpipe-internal.h" +#include "selfpipe.h" + +#ifdef HASSIGNALFD + +#include + +int selfpipe_untrap (int sig) +{ + sigset_t ss = selfpipe_caught ; + sigset_t blah ; + register int r = sigismember(&selfpipe_caught, sig) ; + if (selfpipe_fd < 0) return (errno = EBADF, -1) ; + if (r < 0) return -1 ; + if (!r) return (errno = EINVAL, -1) ; + if ((sigdelset(&ss, sig) < 0) + || (signalfd(selfpipe_fd, &ss, SFD_NONBLOCK | SFD_CLOEXEC) < 0)) + return -1 ; + sigemptyset(&blah) ; + sigaddset(&blah, sig) ; + if (sigprocmask(SIG_UNBLOCK, &blah, 0) < 0) + { + int e = errno ; + signalfd(selfpipe_fd, &selfpipe_caught, SFD_NONBLOCK | SFD_CLOEXEC) ; + errno = e ; + return -1 ; + } + selfpipe_caught = ss ; + return 0 ; +} + +#else + +#include "sig.h" + +int selfpipe_untrap (int sig) +{ + register int r = sigismember(&selfpipe_caught, sig) ; + if (selfpipe_fd < 0) return (errno = EBADF, -1) ; + if (r < 0) return -1 ; + if (!r) return (errno = EINVAL, -1) ; + if (sig_restore(sig) < 0) return -1 ; + sigdelset(&selfpipe_caught, sig) ; + return 0 ; +} + +#endif diff --git a/third/libstddjb/sig.h b/third/libstddjb/sig.h new file mode 100644 index 0000000..dab64bd --- /dev/null +++ b/third/libstddjb/sig.h @@ -0,0 +1,61 @@ +/* ISC license. */ + +#ifndef SIG_H +#define SIG_H + +#include +#include "gccattributes.h" + +extern int sig_alarm gccattr_deprecated ; +extern int sig_child gccattr_deprecated ; +extern int sig_stop gccattr_deprecated ; +extern int sig_cont gccattr_deprecated ; +extern int sig_hangup gccattr_deprecated ; +extern int sig_int gccattr_deprecated ; +extern int sig_kill gccattr_deprecated ; +extern int sig_pipe gccattr_deprecated ; +extern int sig_term gccattr_deprecated ; +extern int sig_usr1 gccattr_deprecated ; +extern int sig_usr2 gccattr_deprecated ; +extern int sig_quit gccattr_deprecated ; +extern int sig_abort gccattr_deprecated ; + + +typedef void skasighandler_t (int) ; +typedef skasighandler_t *skasighandler_t_ref ; + +struct skasigaction +{ + skasighandler_t_ref handler ; + unsigned int flags : 2 ; +} ; + +#define SKASA_MASKALL 0x01 +#define SKASA_NOCLDSTOP 0x02 + +extern struct skasigaction const SKASIG_DFL ; +extern struct skasigaction const SKASIG_IGN ; +extern int skasigaction (int, struct skasigaction const *, struct skasigaction *) ; + +#define sig_catcha(sig, ac) skasigaction(sig, (ac), 0) +#define sig_restore(sig) skasigaction((sig), &SKASIG_DFL, 0) + +extern void sig_restoreto (sigset_t const *, unsigned int) ; +extern int sig_catch (int, skasighandler_t_ref) ; +#define sig_ignore(sig) sig_catcha((sig), &SKASIG_IGN) +#define sig_uncatch(sig) sig_restore(sig) + +#define SIGSTACKSIZE 16 +extern int sig_pusha (int, struct skasigaction const *) ; +extern int sig_pop (int) ; +extern int sig_push (int, skasighandler_t_ref) ; + +extern void sig_block (int) ; +extern void sig_blockset (sigset_t const *) ; +extern void sig_unblock (int) ; +extern void sig_blocknone (void) ; +extern void sig_pause (void) ; +extern void sig_shield (void) ; +extern void sig_unshield (void) ; + +#endif diff --git a/third/libstddjb/sig_restoreto.c b/third/libstddjb/sig_restoreto.c new file mode 100644 index 0000000..088fa68 --- /dev/null +++ b/third/libstddjb/sig_restoreto.c @@ -0,0 +1,17 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include +#include "sig.h" + +void sig_restoreto (sigset_t const *set, unsigned int n) +{ + register unsigned int i = 1 ; + for (; i <= n ; i++) + { + register int h = sigismember(set, i) ; + if (h < 0) continue ; + if (h) sig_restore(i) ; + } +} diff --git a/third/libstddjb/skasig_dfl.c b/third/libstddjb/skasig_dfl.c new file mode 100644 index 0000000..b2790c6 --- /dev/null +++ b/third/libstddjb/skasig_dfl.c @@ -0,0 +1,7 @@ +/* ISC license. */ + +#include +#include "sig.h" + +struct skasigaction const SKASIG_DFL = { SIG_DFL, 0 } ; +struct skasigaction const SKASIG_IGN = { SIG_IGN, 0 } ; diff --git a/third/libstddjb/skasigaction.c b/third/libstddjb/skasigaction.c new file mode 100644 index 0000000..9fc8ab9 --- /dev/null +++ b/third/libstddjb/skasigaction.c @@ -0,0 +1,42 @@ +/* ISC license. */ + +#include +#include "sysdeps.h" +#include "sig.h" + +#ifdef HASSIGACTION + +int skasigaction (int sig, struct skasigaction const *new, struct skasigaction *old) +{ + struct sigaction sanew, saold ; + if (((new->flags & SKASA_MASKALL) ? sigfillset(&sanew.sa_mask) : sigemptyset(&sanew.sa_mask)) == -1) return -1 ; + sanew.sa_handler = new->handler ; + sanew.sa_flags = (new->flags & SKASA_NOCLDSTOP) ? SA_NOCLDSTOP : 0 ; + if (sigaction(sig, &sanew, &saold) == -1) return -1 ; + if (old) + { + register int r = sigismember(&saold.sa_mask, (sig == SIGTERM) ? SIGPIPE : SIGTERM) ; + if (r == -1) return -1 ; + old->flags = 0 ; + if (r) old->flags |= SKASA_MASKALL ; + if (saold.sa_flags & SA_NOCLDSTOP) old->flags |= SKASA_NOCLDSTOP ; + old->handler = saold.sa_handler ; + } + return 0 ; +} + +#else + +int skasigaction (int sig, struct skasigaction const *new, struct skasigaction *old) +{ + skasighandler_t_ref haold = signal(sig, new->handler) ; + if (haold == SIG_ERR) return -1 ; + if (old) + { + old->handler = haold ; + old->flags = 0 ; + } + return 0 ; +} + +#endif