Import selfpipe code from skalibs 1.2.5

[andersk@mit.edu: Move code to new third/libstddjb directory]
This commit is contained in:
Quentin Smith
2012-02-26 15:58:37 -05:00
committed by Keith Winstein
parent 9a3ab83783
commit 77f3a9073f
24 changed files with 697 additions and 0 deletions
+15
View File
@@ -0,0 +1,15 @@
/*
* Copyright (c) 2011-2012 Laurent Bercot <ska-skaware@skarnet.org>
*
* 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.
*/
+25
View File
@@ -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
+11
View File
@@ -0,0 +1,11 @@
/* ISC license. */
#include <fcntl.h>
#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) ;
}
+15
View File
@@ -0,0 +1,15 @@
/* ISC license. */
#include <unistd.h>
#include <errno.h>
#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 ;
}
+13
View File
@@ -0,0 +1,13 @@
/* ISC license. */
#include <unistd.h>
#include <errno.h>
#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 ;
}
+13
View File
@@ -0,0 +1,13 @@
/* ISC license. */
#include <unistd.h>
#include <errno.h>
#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 ;
}
+61
View File
@@ -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
+15
View File
@@ -0,0 +1,15 @@
/* ISC license. */
#include <sys/types.h>
#include <fcntl.h>
#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) ;
}
+13
View File
@@ -0,0 +1,13 @@
/* ISC license. */
#ifndef NSIG_H
#include <signal.h>
#define SKALIBS_NSIG 64
#ifndef NSIG
# define NSIG SKALIBS_NSIG
#endif
#endif
+36
View File
@@ -0,0 +1,36 @@
/* ISC license. */
#include "sysdeps.h"
#ifdef HASPIPE2
# define _GNU_SOURCE
# include <fcntl.h>
#else
# include <errno.h>
#endif
#include <unistd.h>
#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
}
+15
View File
@@ -0,0 +1,15 @@
/* ISC license. */
#include <errno.h>
#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 ;
}
}
+28
View File
@@ -0,0 +1,28 @@
/* ISC license. */
/* MT-unsafe */
#ifndef SELFPIPE_INTERNAL_H
#define SELFPIPE_INTERNAL_H
#include <signal.h>
#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
+17
View File
@@ -0,0 +1,17 @@
/* ISC license. */
/* MT-unsafe */
#ifndef SELFPIPE_H
#define SELFPIPE_H
#include <signal.h>
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
+35
View File
@@ -0,0 +1,35 @@
/* ISC license. */
/* MT-unsafe */
#include <signal.h>
#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
+27
View File
@@ -0,0 +1,27 @@
/* ISC license. */
/* MT-unsafe */
#include <errno.h>
#include <signal.h>
#include "sysdeps.h"
#include "selfpipe-internal.h"
#include "selfpipe.h"
#ifdef HASSIGNALFD
# include <sys/signalfd.h>
#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 ;
}
+31
View File
@@ -0,0 +1,31 @@
/* ISC license. */
/* MT-unsafe */
#include <signal.h>
#include "sysdeps.h"
#include "selfpipe-internal.h"
sigset_t selfpipe_caught ;
#ifdef HASSIGNALFD
int selfpipe_fd = -1 ;
#else
#include <errno.h>
#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
+31
View File
@@ -0,0 +1,31 @@
/* ISC license. */
/* MT-unsafe */
#include "sysdeps.h"
#include "allreadwrite.h"
#include "selfpipe-internal.h"
#include "selfpipe.h"
#ifdef HASSIGNALFD
#include <sys/signalfd.h>
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
+51
View File
@@ -0,0 +1,51 @@
/* ISC license. */
/* MT-unsafe */
#include <errno.h>
#include <signal.h>
#include "sysdeps.h"
#include "selfpipe-internal.h"
#include "selfpipe.h"
#ifdef HASSIGNALFD
#include <sys/signalfd.h>
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
+64
View File
@@ -0,0 +1,64 @@
/* ISC license. */
/* MT-unsafe */
#include <errno.h>
#include <signal.h>
#include "sysdeps.h"
#include "selfpipe-internal.h"
#include "selfpipe.h"
#ifdef HASSIGNALFD
#include <sys/signalfd.h>
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
+54
View File
@@ -0,0 +1,54 @@
/* ISC license. */
/* MT-unsafe */
#include <errno.h>
#include <signal.h>
#include "sysdeps.h"
#include "selfpipe-internal.h"
#include "selfpipe.h"
#ifdef HASSIGNALFD
#include <sys/signalfd.h>
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
+61
View File
@@ -0,0 +1,61 @@
/* ISC license. */
#ifndef SIG_H
#define SIG_H
#include <signal.h>
#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
+17
View File
@@ -0,0 +1,17 @@
/* ISC license. */
/* MT-unsafe */
#include <signal.h>
#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) ;
}
}
+7
View File
@@ -0,0 +1,7 @@
/* ISC license. */
#include <signal.h>
#include "sig.h"
struct skasigaction const SKASIG_DFL = { SIG_DFL, 0 } ;
struct skasigaction const SKASIG_IGN = { SIG_IGN, 0 } ;
+42
View File
@@ -0,0 +1,42 @@
/* ISC license. */
#include <signal.h>
#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