summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2017-12-21 11:18:28 +0000
committerLaurent Bercot <ska-skaware@skarnet.org>2017-12-21 11:18:28 +0000
commit2990ce9b390ec1e2bfa1c043c406878e8aff86dd (patch)
tree270e5e2bfa3cdb2fc795039fc45901d93290567e /src
parent933e986a9207d2b61c5119e18603b44b924e7226 (diff)
downloadskalibs-2990ce9b390ec1e2bfa1c043c406878e8aff86dd.tar.xz
Big 2.6.3.0 reorganization
- Add libposixplz, update headers - Add memmem and friends - Add textmessage to libunixonacid - Update some sysdeps tests
Diffstat (limited to 'src')
-rw-r--r--src/include/skalibs/bytestr.h11
-rw-r--r--src/include/skalibs/djbunix.h9
-rw-r--r--src/include/skalibs/environ.h7
-rw-r--r--src/include/skalibs/getpeereid.h9
-rw-r--r--src/include/skalibs/mininetstring.h5
-rw-r--r--src/include/skalibs/posixplz.h45
-rw-r--r--src/include/skalibs/setgroups.h12
-rw-r--r--src/include/skalibs/skalibs.h4
-rw-r--r--src/include/skalibs/skamisc.h1
-rw-r--r--src/include/skalibs/stddjb.h4
-rw-r--r--src/include/skalibs/textmessage.h96
-rw-r--r--src/include/skalibs/unixonacid.h1
-rw-r--r--src/include/skalibs/webipc.h2
-rw-r--r--src/libposixplz/doublefork.c (renamed from src/libstddjb/doublefork.c)1
-rw-r--r--src/libposixplz/execvep.c (renamed from src/libstddjb/execvep.c)2
-rw-r--r--src/libposixplz/getpeereid.c (renamed from src/libstddjb/getpeereid.c)6
-rw-r--r--src/libposixplz/memmem.c187
-rw-r--r--src/libposixplz/setgroups.c (renamed from src/libstddjb/setgroups.c)0
-rw-r--r--src/libposixplz/strnlen.c16
-rw-r--r--src/libposixplz/touch.c (renamed from src/libstddjb/touch.c)3
-rw-r--r--src/libstddjb/byte_search.c11
-rw-r--r--src/libstddjb/env_get.c2
-rw-r--r--src/libstddjb/pathexec.c2
-rw-r--r--src/libstddjb/pathexec_run.c1
-rw-r--r--src/libstddjb/siovec_search.c30
-rw-r--r--src/libstddjb/skagetlnmaxsep.c29
-rw-r--r--src/libstddjb/xexecvep.c1
-rw-r--r--src/libunixonacid/textmessage_handle.c20
-rw-r--r--src/libunixonacid/textmessage_put.c21
-rw-r--r--src/libunixonacid/textmessage_putv.c22
-rw-r--r--src/libunixonacid/textmessage_receive.c40
-rw-r--r--src/libunixonacid/textmessage_receiver_0.c10
-rw-r--r--src/libunixonacid/textmessage_receiver_free.c10
-rw-r--r--src/libunixonacid/textmessage_receiver_hasmsginbuf.c21
-rw-r--r--src/libunixonacid/textmessage_receiver_init.c14
-rw-r--r--src/libunixonacid/textmessage_receiver_zero.c5
-rw-r--r--src/libunixonacid/textmessage_sender_1.c7
-rw-r--r--src/libunixonacid/textmessage_sender_flush.c9
-rw-r--r--src/libunixonacid/textmessage_sender_getfd.c9
-rw-r--r--src/libunixonacid/textmessage_sender_timed_flush.c15
-rw-r--r--src/libunixonacid/textmessage_sender_x.c7
-rw-r--r--src/libunixonacid/textmessage_sender_zero.c5
-rw-r--r--src/libunixonacid/textmessage_timed_handle.c29
-rw-r--r--src/libunixonacid/textmessage_timed_receive.c29
-rw-r--r--src/sysdeps/tryarc4random.c16
-rw-r--r--src/sysdeps/tryarc4random_addrandom.c16
-rw-r--r--src/sysdeps/trygetpeereid.c20
-rw-r--r--src/sysdeps/trymemmem.c28
-rw-r--r--src/sysdeps/trynamespaces.c15
-rw-r--r--src/sysdeps/trystrcasestr.c6
-rw-r--r--src/sysdeps/trystrnlen.c3
51 files changed, 831 insertions, 43 deletions
diff --git a/src/include/skalibs/bytestr.h b/src/include/skalibs/bytestr.h
index 1f3942b..3a5c95e 100644
--- a/src/include/skalibs/bytestr.h
+++ b/src/include/skalibs/bytestr.h
@@ -3,27 +3,21 @@
#ifndef BYTESTR_H
#define BYTESTR_H
-#include <skalibs/config.h>
#include <skalibs/gccattributes.h>
/* for Alphas and other archs where char != 8bit */
#define T8(x) ((x) & 0xffU)
-#include <skalibs/sysdeps.h>
#include <string.h>
#include <strings.h>
+#include <skalibs/posixplz.h>
#define byte_copy(to, n, from) memmove(to, (from), n)
#define byte_copyr(to, n, from) memmove(to, (from), n)
#define byte_diff(a, n, b) memcmp(a, (b), n)
#define byte_zero(p, n) memset(p, 0, n)
#define str_len strlen
-
-#ifdef SKALIBS_HASSTRNLEN
-# define str_nlen strnlen
-#else
-# define str_nlen(s, max) byte_chr(s, (max), 0)
-#endif
+#define str_nlen strnlen
#define str_diff strcmp
#define str_diffn strncmp
@@ -36,6 +30,7 @@ extern size_t byte_rchr (char const *, size_t, int) gccattr_pure ;
extern size_t byte_in (char const *, size_t, char const *, size_t) gccattr_pure ;
#define byte_equal(s, n, t) (!memcmp(s, (t), n))
extern size_t byte_count (char const *, size_t, char) gccattr_pure ;
+extern size_t byte_search (char const *, size_t, char const *, size_t) ;
#define str_diffb(a, n, b) strncmp(a, (b), n)
extern size_t str_chr (char const *, int) gccattr_pure ;
diff --git a/src/include/skalibs/djbunix.h b/src/include/skalibs/djbunix.h
index 4dc534e..b095c82 100644
--- a/src/include/skalibs/djbunix.h
+++ b/src/include/skalibs/djbunix.h
@@ -9,7 +9,8 @@
#include <skalibs/gccattributes.h>
#include <skalibs/stralloc.h>
#include <skalibs/envalloc.h>
-#include <skalibs/env.h> /* compatibility */
+#include <skalibs/env.h> /* will disappear */
+#include <skalibs/posixplz.h>
#define DJBUNIX_FLAG_NB 0x01U
#define DJBUNIX_FLAG_COE 0x02U
@@ -56,7 +57,6 @@ extern int pathexec_env (char const *, char const *) ;
extern void pathexec_r (char const *const *, char const *const *, size_t, char const *, size_t) ;
extern void pathexec_r_name (char const *, char const *const *, char const *const *, size_t, char const *, size_t) ;
extern void pathexec_fromenv (char const *const *, char const *const *, size_t) ;
-extern void execvep (char const *, char const *const *, char const *const *, char const *) ;
extern void pathexec_run (char const *, char const *const *, char const *const *) ;
extern void pathexec0_run (char const *const *, char const *const *) ;
extern void pathexec (char const *const *) ;
@@ -89,11 +89,9 @@ extern unsigned int wait_reap (void) ;
extern int waitn (pid_t *, unsigned int) ;
extern int waitn_reap (pid_t *, unsigned int) ;
-extern pid_t doublefork (void) ;
-
extern int fd_chdir (int) ;
-#define absolutepath(sa, s) sarealpath(sa, s)
+#define absolutepath(sa, s) sarealpath(sa, s) /* will disappear */
extern int sarealpath (stralloc *, char const *) ;
extern int sarealpath_tmp (stralloc *, char const *, stralloc *) ;
extern int sabasename (stralloc *, char const *, size_t) ;
@@ -162,7 +160,6 @@ extern int rm_rf_in_tmp (stralloc *, size_t) ; /* caution ! */
extern int rmstar (char const *) ;
extern int rmstar_tmp (char const *, stralloc *) ;
-extern int touch (char const *) ;
extern int filecopy_unsafe (char const *, char const *, unsigned int) ;
extern int filecopy_suffix (char const *, char const *, unsigned int, char const *) ;
extern int hiercopy (char const *, char const *) ;
diff --git a/src/include/skalibs/environ.h b/src/include/skalibs/environ.h
index 6bf3041..0d4494b 100644
--- a/src/include/skalibs/environ.h
+++ b/src/include/skalibs/environ.h
@@ -1,8 +1,5 @@
/* ISC license. */
-#ifndef ENVIRON_H
-#define ENVIRON_H
+/* This header is being deprecated */
-extern char **environ ;
-
-#endif
+#include <skalibs/posixplz.h>
diff --git a/src/include/skalibs/getpeereid.h b/src/include/skalibs/getpeereid.h
index 4aa2898..0d4494b 100644
--- a/src/include/skalibs/getpeereid.h
+++ b/src/include/skalibs/getpeereid.h
@@ -1,10 +1,5 @@
/* ISC license. */
-#ifndef GETPEEREID_H
-#define GETPEEREID_H
+/* This header is being deprecated */
-#include <sys/types.h>
-
-extern int getpeereid (int, uid_t *, gid_t *) ;
-
-#endif
+#include <skalibs/posixplz.h>
diff --git a/src/include/skalibs/mininetstring.h b/src/include/skalibs/mininetstring.h
index 1997b18..9e88601 100644
--- a/src/include/skalibs/mininetstring.h
+++ b/src/include/skalibs/mininetstring.h
@@ -4,9 +4,10 @@
#define MININETSTRING_H
#include <stdint.h>
+#include <skalibs/gccattributes.h>
#include <skalibs/stralloc.h>
-extern int mininetstring_read (int, stralloc *, uint32_t *) ;
-extern int mininetstring_write (int, char const *, uint16_t, uint32_t *) ;
+extern int mininetstring_read (int, stralloc *, uint32_t *) gccattr_deprecated ;
+extern int mininetstring_write (int, char const *, uint16_t, uint32_t *) gccattr_deprecated ;
#endif
diff --git a/src/include/skalibs/posixplz.h b/src/include/skalibs/posixplz.h
new file mode 100644
index 0000000..72cffee
--- /dev/null
+++ b/src/include/skalibs/posixplz.h
@@ -0,0 +1,45 @@
+/* ISC license. */
+
+#ifndef SKALIBS_POSIXPLZ_H
+#define SKALIBS_POSIXPLZ_H
+
+#include <sys/types.h>
+#include <skalibs/gccattributes.h>
+
+
+ /*
+ Stuff that doesn't have its own POSIX header for some reason.
+ */
+
+extern char **environ ;
+
+
+ /*
+ Stuff that _is_ POSIX, but some OSes still don't have it.
+ openat() et al. should be here, but they're impossible to
+ emulate correctly, and I don't want an app using openat()
+ to think it has safe POSIX semantics when it doesn't :/
+ EPROTO et al. should be here, but ugh ifdef forests.
+ */
+
+extern size_t strnlen (char const *, size_t) gccattr_pure ;
+
+
+ /*
+ Non-POSIX functions that some OSes provide and others don't.
+ setgroups() isn't included because it's its own kind of broken.
+ */
+
+extern void *memmem (void const *, size_t, void const *, size_t) gccattr_pure ;
+extern int getpeereid (int, uid_t *, gid_t *) ;
+
+
+ /*
+ Functions that aren't standard at all, but honestly could be. :P
+ */
+
+extern void execvep (char const *, char const *const *, char const *const *, char const *) ;
+extern pid_t doublefork (void) ;
+extern int touch (char const *) ;
+
+#endif
diff --git a/src/include/skalibs/setgroups.h b/src/include/skalibs/setgroups.h
index 98998e0..19421e0 100644
--- a/src/include/skalibs/setgroups.h
+++ b/src/include/skalibs/setgroups.h
@@ -7,6 +7,13 @@
#ifdef SKALIBS_HASSETGROUPS
+ /*
+ setgroups() is defined by a lot of OSes.
+ However, they don't agree on what it should do:
+ some change the primary gid, others don't, etc. It's a mess.
+ Never use setgroups(). Use the functions below instead.
+ */
+
#include <unistd.h>
extern int setgroups_and_gid (gid_t, size_t, gid_t const *) ;
@@ -15,8 +22,11 @@ extern int skalibs_setgroups (size_t, gid_t const *) ;
#else
+ /* No setgroups() at all? not much we can do. */
+
#include <errno.h>
-#define setgroups(n, tab) (errno = ENOSYS, -1)
+
+#define setgroups_and_gid(g, n, tab) (errno = ENOSYS, -1)
#define setgroups_with_egid(n, tab) (errno = ENOSYS, -1)
#define skalibs_setgroups(n, tab) (errno = ENOSYS, -1)
diff --git a/src/include/skalibs/skalibs.h b/src/include/skalibs/skalibs.h
index e889461..2924e1c 100644
--- a/src/include/skalibs/skalibs.h
+++ b/src/include/skalibs/skalibs.h
@@ -4,11 +4,11 @@
#define SKALIBS_H
/*
- This header includes everything in skalibs,
- except skalibs/config.h and skalibs/sysdeps.h
+ This header includes everything in skalibs except skalibs/config.h
It's heavy!
*/
+#include <skalibs/posixplz.h>
#include <skalibs/stddjb.h>
#include <skalibs/stdcrypto.h>
#include <skalibs/random.h>
diff --git a/src/include/skalibs/skamisc.h b/src/include/skalibs/skamisc.h
index cf33ec2..15f7f02 100644
--- a/src/include/skalibs/skamisc.h
+++ b/src/include/skalibs/skamisc.h
@@ -12,6 +12,7 @@ extern stralloc satmp ;
extern int skagetln (buffer *, stralloc *, char) ;
extern int skagetln_nofill (buffer *, stralloc *, char) ;
extern int skagetlnsep (buffer *, stralloc *, char const *, size_t) ;
+extern int skagetlnmaxsep (buffer *, stralloc *, size_t, char const *, size_t) ;
extern int getlnmax (buffer *, char *, size_t, size_t *, char) ;
extern int getlnmaxsep (buffer *, char *, size_t, size_t *, char const *, size_t) ;
diff --git a/src/include/skalibs/stddjb.h b/src/include/skalibs/stddjb.h
index 50e07c5..87f72d0 100644
--- a/src/include/skalibs/stddjb.h
+++ b/src/include/skalibs/stddjb.h
@@ -29,17 +29,15 @@
#include <skalibs/djbunix.h>
#include <skalibs/envalloc.h>
#include <skalibs/env.h>
-#include <skalibs/environ.h>
#include <skalibs/fmtscan.h>
#include <skalibs/functypes.h>
#include <skalibs/gccattributes.h>
#include <skalibs/genalloc.h>
#include <skalibs/genwrite.h>
-#include <skalibs/getpeereid.h>
#include <skalibs/iobuffer.h>
#include <skalibs/iopause.h>
#include <skalibs/lolstdio.h>
-#include <skalibs/mininetstring.h>
+#include <skalibs/mininetstring.h> /* will disappear */
#include <skalibs/netstring.h>
#include <skalibs/nsig.h>
#include <skalibs/segfault.h>
diff --git a/src/include/skalibs/textmessage.h b/src/include/skalibs/textmessage.h
new file mode 100644
index 0000000..9904534
--- /dev/null
+++ b/src/include/skalibs/textmessage.h
@@ -0,0 +1,96 @@
+/* ISC license. */
+
+#ifndef SKALIBS_TEXTMESSAGE_H
+#define SKALIBS_TEXTMESSAGE_H
+
+#include <sys/uio.h>
+#include <stdint.h>
+#include <skalibs/gccattributes.h>
+#include <skalibs/allreadwrite.h>
+#include <skalibs/bufalloc.h>
+#include <skalibs/buffer.h>
+#include <skalibs/stralloc.h>
+#include <skalibs/tai.h>
+
+#define TEXTMESSAGE_MAXREADS 128
+
+
+ /* Sender */
+
+typedef struct textmessage_sender_s textmessage_sender_t, *textmessage_sender_t_ref ;
+struct textmessage_sender_s
+{
+ bufalloc out ;
+} ;
+#define TEXTMESSAGE_SENDER_ZERO { .out = BUFALLOC_ZERO }
+extern textmessage_sender_t const textmessage_sender_zero ;
+#define TEXTMESSAGE_SENDER_INIT(fd) { .out = BUFALLOC_INIT(&fd_write, (fd)) }
+
+#define textmessage_sender_init(ts, fd) bufalloc_init(&(ts)->out, &fd_write, fd)
+#define textmessage_sender_free(ts) bufalloc_free(&(ts)->out)
+#define textmessage_sender_fd(ts) bufalloc_fd(&(ts)->out)
+extern int textmessage_sender_getfd (textmessage_sender_t const *) gccattr_pure ;
+#define textmessage_sender_isempty(ts) bufalloc_isempty(&(ts)->out)
+
+extern int textmessage_put (textmessage_sender_t *, char const *, size_t) ;
+extern int textmessage_putv (textmessage_sender_t *, struct iovec const *, unsigned int) ;
+
+extern int textmessage_sender_flush (textmessage_sender_t *) ;
+extern int unixmessage_sender_timed_flush (textmessage_sender_t *, tain_t const *, tain_t *) ;
+#define textmessage_sender_timed_flush_g(ts, deadline) textmessage_sender_timed_flush(ts, (deadline), &STAMP)
+
+#define textmessage_send(ts, s, len) (textmessage_put(ts, s, len) && textmessage_sender_flush(ts))
+#define textmessage_sendv(ts, v, n) (textmessage_putv(ts, v, n) && textmessage_sender_flush(ts))
+#define textmessage_timed_send(ts, s, len, deadline, stamp) (textmessage_put(ts, s, len) && texxtmessage_sender_timed_flush(ts, deadline, stamp))
+#define textmessage_timed_sendv(ts, v, n, deadline, stamp) (textmessage_putv(ts, v, n) && texxtmessage_sender_timed_flush(ts, deadline, stamp))
+#define textmessage_timed_send_g(ts, s, len, deadline) textmessage_timed_send(ts, s, len, (deadline), &STAMP)
+#define textmessage_timed_sendv_g(ts, v, n, deadline) textmessage_timed_sendv(ts, v, n, (deadline), &STAMP)
+
+
+ /* Receiver */
+
+typedef struct textmessage_receiver_s textmessage_receiver_t, *textmessage_receiver_t_ref ;
+struct textmessage_receiver_s
+{
+ buffer in ;
+ stralloc indata ;
+ uint32_t wanted ;
+ uint32_t max ;
+} ;
+#define TEXTMESSAGE_RECEIVER_ZERO { .in = BUFFER_ZERO, .indata = STRALLOC_ZERO, .wanted = 0, .max = 0 }
+extern textmessage_receiver_t const textmessage_receiver_zero ;
+#define TEXTMESSAGE_RECEIVER_INIT(fd, buf, len, n) { .in = BUFFER_INIT(&buffer_read, (fd), buf, len), .indata = STRALLOC_ZERO, .wanted = 0, .max = n }
+
+extern int textmessage_receiver_init (textmessage_receiver_t *, int, char *, size_t, uint32_t) ;
+extern void textmessage_receiver_free (textmessage_receiver_t *) ;
+#define textmessage_receiver_fd(tr) buffer_fd(&(tr)->in)
+#define textmessage_receiver_isempty(tr) buffer_isempty(&(tr)->in)
+#define textmessage_receiver_isfull(tr) buffer_isfull(&(tr)->in)
+
+extern int textmessage_receiver_hasmsginbuf (textmessage_receiver_t const *) gccattr_pure ;
+
+extern int textmessage_receive (textmessage_receiver_t *, struct iovec *) ;
+extern int textmessage_timed_receive (textmessage_receiver_t *, struct iovec *, tain_t const *, tain_t *) ;
+#define textmessage_timed_receive_g(tr, s, max, deadline) textmessage_timed_receive(tr, s, max, (deadline), &STAMP)
+
+typedef int textmessage_handler_func_t (struct iovec const *, void *) ;
+typedef textmessage_handler_func_t *textmessage_handler_func_t_ref ;
+
+extern int textmessage_handle (textmessage_receiver_t *, textmessage_handler_func_t_ref, void *) ;
+extern int textmessage_timed_handle (textmessage_receiver_t *, textmessage_handler_func_t_ref, void *, tain_t const *, tain_t *) ;
+#define textmessage_timed_handle_g(tr, f, p, deadline) unixmessage_timed_handle(tr, f, p, (deadline), &STAMP)
+
+
+
+ /* Globals */
+
+extern textmessage_receiver_t textmessage_receiver_0_ ;
+#define textmessage_receiver_0 (&textmessage_receiver_0_)
+
+extern textmessage_sender_t textmessage_sender_1_ ;
+#define textmessage_sender_1 (&textmessage_sender_1_)
+
+extern textmessage_sender_t textmessage_sender_x_ ;
+#define textmessage_sender_x (&textmessage_sender_x_)
+
+#endif
diff --git a/src/include/skalibs/unixonacid.h b/src/include/skalibs/unixonacid.h
index 9ec3fe8..43bd695 100644
--- a/src/include/skalibs/unixonacid.h
+++ b/src/include/skalibs/unixonacid.h
@@ -5,6 +5,7 @@
#include <skalibs/unix-transactional.h>
#include <skalibs/unix-timed.h>
+#include <skalibs/textmessage.h>
#include <skalibs/unixmessage.h>
#include <skalibs/unixconnection.h>
#include <skalibs/kolbak.h>
diff --git a/src/include/skalibs/webipc.h b/src/include/skalibs/webipc.h
index 0ddd084..eba6f6b 100644
--- a/src/include/skalibs/webipc.h
+++ b/src/include/skalibs/webipc.h
@@ -13,7 +13,7 @@
#define IPCPATH_MAX 107
#include <sys/types.h>
-#include <skalibs/getpeereid.h>
+#include <skalibs/posixplz.h>
#include <skalibs/tai.h>
#include <skalibs/djbunix.h>
diff --git a/src/libstddjb/doublefork.c b/src/libposixplz/doublefork.c
index da512f8..6038a9f 100644
--- a/src/libstddjb/doublefork.c
+++ b/src/libposixplz/doublefork.c
@@ -6,6 +6,7 @@
#include <skalibs/uint64.h>
#include <skalibs/allreadwrite.h>
#include <skalibs/djbunix.h>
+#include <skalibs/posixplz.h>
pid_t doublefork ()
{
diff --git a/src/libstddjb/execvep.c b/src/libposixplz/execvep.c
index 3dae8bc..acdf11f 100644
--- a/src/libstddjb/execvep.c
+++ b/src/libposixplz/execvep.c
@@ -4,7 +4,7 @@
#include <string.h>
#include <errno.h>
#include <skalibs/bytestr.h>
-#include <skalibs/djbunix.h>
+#include <skalibs/posixplz.h>
void execvep (char const *file, char const *const *argv, char const *const *envp, char const *path)
{
diff --git a/src/libstddjb/getpeereid.c b/src/libposixplz/getpeereid.c
index 0d36abb..ae1142f 100644
--- a/src/libstddjb/getpeereid.c
+++ b/src/libposixplz/getpeereid.c
@@ -13,7 +13,7 @@
#include <skalibs/nonposix.h>
#include <sys/socket.h>
#include <sys/un.h>
-#include <skalibs/getpeereid.h>
+#include <skalibs/posixplz.h>
int getpeereid (int s, uid_t *u, gid_t *g)
{
@@ -34,7 +34,7 @@ int getpeereid (int s, uid_t *u, gid_t *g)
#include <skalibs/nonposix.h>
#include <ucred.h>
-#include <skalibs/getpeereid.h>
+#include <skalibs/posixplz.h>
int getpeereid (int s, uid_t *u, gid_t *g)
{
@@ -51,7 +51,7 @@ int getpeereid (int s, uid_t *u, gid_t *g)
/* can't find a real implementation, make a stub */
#include <errno.h>
-#include <skalibs/getpeereid.h>
+#include <skalibs/posixplz.h>
int getpeereid (int s, uid_t *uid, gid_t *gid)
{
diff --git a/src/libposixplz/memmem.c b/src/libposixplz/memmem.c
new file mode 100644
index 0000000..d107346
--- /dev/null
+++ b/src/libposixplz/memmem.c
@@ -0,0 +1,187 @@
+/* MIT license. See below. */
+
+#include <skalibs/sysdeps.h>
+
+#ifndef SKALIBS_HASMEMMEM
+
+/*
+ If the underlying platform does not provide memmem(), then the
+ following implementation is used. It comes from the musl libc,
+ which is MIT-licensed:
+
+----------------------------------------------------------------------
+Copyright © 2005-2017 Rich Felker, Szabolcs Nagy, Timo Teräs, Alexander Monakov
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+----------------------------------------------------------------------
+
+*/
+
+#include <string.h>
+#include <stdint.h>
+#include <skalibs/posixplz.h>
+
+static char *twobyte_memmem(const unsigned char *h, size_t k, const unsigned char *n)
+{
+ uint16_t nw = n[0]<<8 | n[1], hw = h[0]<<8 | h[1];
+ for (h+=2, k-=2; k; k--, hw = hw<<8 | *h++)
+ if (hw == nw) return (char *)h-2;
+ return hw == nw ? (char *)h-2 : 0;
+}
+
+static char *threebyte_memmem(const unsigned char *h, size_t k, const unsigned char *n)
+{
+ uint32_t nw = n[0]<<24 | n[1]<<16 | n[2]<<8;
+ uint32_t hw = h[0]<<24 | h[1]<<16 | h[2]<<8;
+ for (h+=3, k-=3; k; k--, hw = (hw|*h++)<<8)
+ if (hw == nw) return (char *)h-3;
+ return hw == nw ? (char *)h-3 : 0;
+}
+
+static char *fourbyte_memmem(const unsigned char *h, size_t k, const unsigned char *n)
+{
+ uint32_t nw = n[0]<<24 | n[1]<<16 | n[2]<<8 | n[3];
+ uint32_t hw = h[0]<<24 | h[1]<<16 | h[2]<<8 | h[3];
+ for (h+=4, k-=4; k; k--, hw = hw<<8 | *h++)
+ if (hw == nw) return (char *)h-4;
+ return hw == nw ? (char *)h-4 : 0;
+}
+
+#define MAX(a,b) ((a)>(b)?(a):(b))
+#define MIN(a,b) ((a)<(b)?(a):(b))
+
+#define BITOP(a,b,op) \
+ ((a)[(size_t)(b)/(8*sizeof *(a))] op (size_t)1<<((size_t)(b)%(8*sizeof *(a))))
+
+static char *twoway_memmem(const unsigned char *h, const unsigned char *z, const unsigned char *n, size_t l)
+{
+ size_t i, ip, jp, k, p, ms, p0, mem, mem0;
+ size_t byteset[32 / sizeof(size_t)] = { 0 };
+ size_t shift[256];
+
+ /* Computing length of needle and fill shift table */
+ for (i=0; i<l; i++)
+ BITOP(byteset, n[i], |=), shift[n[i]] = i+1;
+
+ /* Compute maximal suffix */
+ ip = -1; jp = 0; k = p = 1;
+ while (jp+k<l) {
+ if (n[ip+k] == n[jp+k]) {
+ if (k == p) {
+ jp += p;
+ k = 1;
+ } else k++;
+ } else if (n[ip+k] > n[jp+k]) {
+ jp += k;
+ k = 1;
+ p = jp - ip;
+ } else {
+ ip = jp++;
+ k = p = 1;
+ }
+ }
+ ms = ip;
+ p0 = p;
+
+ /* And with the opposite comparison */
+ ip = -1; jp = 0; k = p = 1;
+ while (jp+k<l) {
+ if (n[ip+k] == n[jp+k]) {
+ if (k == p) {
+ jp += p;
+ k = 1;
+ } else k++;
+ } else if (n[ip+k] < n[jp+k]) {
+ jp += k;
+ k = 1;
+ p = jp - ip;
+ } else {
+ ip = jp++;
+ k = p = 1;
+ }
+ }
+ if (ip+1 > ms+1) ms = ip;
+ else p = p0;
+
+ /* Periodic needle? */
+ if (memcmp(n, n+p, ms+1)) {
+ mem0 = 0;
+ p = MAX(ms, l-ms-1) + 1;
+ } else mem0 = l-p;
+ mem = 0;
+
+ /* Search loop */
+ for (;;) {
+ /* If remainder of haystack is shorter than needle, done */
+ if (z-h < l) return 0;
+
+ /* Check last byte first; advance by shift on mismatch */
+ if (BITOP(byteset, h[l-1], &)) {
+ k = l-shift[h[l-1]];
+ if (k) {
+ if (mem0 && mem && k < p) k = l-p;
+ h += k;
+ mem = 0;
+ continue;
+ }
+ } else {
+ h += l;
+ mem = 0;
+ continue;
+ }
+
+ /* Compare right half */
+ for (k=MAX(ms+1,mem); k<l && n[k] == h[k]; k++);
+ if (k < l) {
+ h += k-ms;
+ mem = 0;
+ continue;
+ }
+ /* Compare left half */
+ for (k=ms+1; k>mem && n[k-1] == h[k-1]; k--);
+ if (k <= mem) return (char *)h;
+ h += p;
+ mem = mem0;
+ }
+}
+
+void *memmem(const void *h0, size_t k, const void *n0, size_t l)
+{
+ const unsigned char *h = h0, *n = n0;
+
+ /* Return immediately on empty needle */
+ if (!l) return (void *)h;
+
+ /* Return immediately when needle is longer than haystack */
+ if (k<l) return 0;
+
+ /* Use faster algorithms for short needles */
+ h = memchr(h0, *n, k);
+ if (!h || l==1) return (void *)h;
+ k -= h - (const unsigned char *)h0;
+ if (k<l) return 0;
+ if (l==2) return twobyte_memmem(h, k, n);
+ if (l==3) return threebyte_memmem(h, k, n);
+ if (l==4) return fourbyte_memmem(h, k, n);
+
+ return twoway_memmem(h, h+k, n, l);
+}
+
+#endif
diff --git a/src/libstddjb/setgroups.c b/src/libposixplz/setgroups.c
index d064ed2..d064ed2 100644
--- a/src/libstddjb/setgroups.c
+++ b/src/libposixplz/setgroups.c
diff --git a/src/libposixplz/strnlen.c b/src/libposixplz/strnlen.c
new file mode 100644
index 0000000..1699771
--- /dev/null
+++ b/src/libposixplz/strnlen.c
@@ -0,0 +1,16 @@
+/* ISC license. */
+
+#include <skalibs/sysdeps.h>
+
+#ifndef SKALIBS_HASSTRNLEN
+
+#include <string.h>
+#include <skalibs/bytestr.h>
+#include <skalibs/posixplz.h>
+
+size_t strnlen (char const *s, size_t max)
+{
+ return byte_chr(s, max, 0) ;
+}
+
+#endif
diff --git a/src/libstddjb/touch.c b/src/libposixplz/touch.c
index dc0c3cf..c4419ec 100644
--- a/src/libstddjb/touch.c
+++ b/src/libposixplz/touch.c
@@ -8,6 +8,7 @@
#include <time.h>
#include <sys/stat.h>
#include <skalibs/djbunix.h>
+#include <skalibs/posixplz.h>
int touch (char const *file)
{
@@ -25,6 +26,7 @@ int touch (char const *file)
#include <skalibs/nonposix.h>
#include <sys/time.h>
#include <skalibs/djbunix.h>
+#include <skalibs/posixplz.h>
int touch (char const *file)
{
@@ -40,6 +42,7 @@ int touch (char const *file)
#include <sys/time.h>
#include <skalibs/djbunix.h>
+#include <skalibs/posixplz.h>
int touch (char const *file)
{
diff --git a/src/libstddjb/byte_search.c b/src/libstddjb/byte_search.c
new file mode 100644
index 0000000..286d806
--- /dev/null
+++ b/src/libstddjb/byte_search.c
@@ -0,0 +1,11 @@
+/* ISC license. */
+
+#include <string.h>
+#include <skalibs/posixplz.h>
+#include <skalibs/bytestr.h>
+
+size_t byte_search (char const *haystack, size_t hlen, char const *needle, size_t nlen)
+{
+ char *p = memmem(haystack, hlen, needle, nlen) ;
+ return p ? p - haystack : hlen + 1 - nlen ;
+}
diff --git a/src/libstddjb/env_get.c b/src/libstddjb/env_get.c
index 927955f..f523f45 100644
--- a/src/libstddjb/env_get.c
+++ b/src/libstddjb/env_get.c
@@ -1,7 +1,7 @@
/* ISC license. */
#include <skalibs/env.h>
-#include <skalibs/environ.h>
+#include <skalibs/posixplz.h>
char const *env_get (char const *s)
{
diff --git a/src/libstddjb/pathexec.c b/src/libstddjb/pathexec.c
index b7b088e..da8788c 100644
--- a/src/libstddjb/pathexec.c
+++ b/src/libstddjb/pathexec.c
@@ -4,7 +4,7 @@
#include <skalibs/env.h>
#include <skalibs/djbunix.h>
-#include <skalibs/environ.h>
+#include <skalibs/posixplz.h>
void pathexec (char const *const *argv)
{
diff --git a/src/libstddjb/pathexec_run.c b/src/libstddjb/pathexec_run.c
index 4d9b291..ff3211d 100644
--- a/src/libstddjb/pathexec_run.c
+++ b/src/libstddjb/pathexec_run.c
@@ -2,6 +2,7 @@
#include <skalibs/config.h>
#include <skalibs/env.h>
+#include <skalibs/posixplz.h>
#include <skalibs/djbunix.h>
void pathexec_run (char const *file, char const *const *argv, char const *const *envp)
diff --git a/src/libstddjb/siovec_search.c b/src/libstddjb/siovec_search.c
new file mode 100644
index 0000000..ef64e96
--- /dev/null
+++ b/src/libstddjb/siovec_search.c
@@ -0,0 +1,30 @@
+/* ISC license. */
+
+#include <string.h>
+#include <sys/uio.h>
+#include <skalibs/posixplz.h>
+#include <skalibs/siovec.h>
+
+size_t siovec_search (struct iovec const *v, unsigned int n, char const *needle, size_t nlen)
+{
+ size_t vlen = siovec_len(v, n) ;
+ size_t w = 0 ;
+ unsigned int i = 0 ;
+ for (; i < n ; i++)
+ {
+ char *p = memmem(v[i].iov_base, v[i].iov_len, needle, nlen) ;
+ if (p) return w + (p - (char *)v[i].iov_base) ;
+ if (i < n-1 && nlen > 1 && v[i].iov_len)
+ {
+ size_t prelen = v[i].iov_len < nlen ? v[i].iov_len : nlen ;
+ size_t postlen = vlen - w - v[i].iov_len < nlen ? vlen - w - v[i].iov_len : nlen ;
+ char buf[prelen + postlen - 2] ;
+ memcpy(buf, (char *)v[i].iov_base + v[i].iov_len - prelen + 1, prelen - 1) ;
+ siovec_gather(v + i + 1, n - 1 - i, buf + prelen - 1, postlen - 1) ;
+ p = memmem(buf, prelen + postlen - 2, needle, nlen) ;
+ if (p) return w + v[i].iov_len - prelen + 1 + (p - buf) ;
+ }
+ w += v[i].iov_len ;
+ }
+ return w ;
+}
diff --git a/src/libstddjb/skagetlnmaxsep.c b/src/libstddjb/skagetlnmaxsep.c
new file mode 100644
index 0000000..7742c06
--- /dev/null
+++ b/src/libstddjb/skagetlnmaxsep.c
@@ -0,0 +1,29 @@
+/* ISC license. */
+
+#include <sys/uio.h>
+#include <errno.h>
+#include <skalibs/buffer.h>
+#include <skalibs/siovec.h>
+#include <skalibs/stralloc.h>
+#include <skalibs/skamisc.h>
+
+int skagetlnmaxsep (buffer *b, stralloc *sa, size_t max, char const *sep, size_t seplen)
+{
+ size_t start = sa->len ;
+ for (;;)
+ {
+ struct iovec v[2] ;
+ size_t pos ;
+ int r ;
+ buffer_rpeek(b, v) ;
+ pos = siovec_bytein(v, 2, sep, seplen) ;
+ r = pos < buffer_len(b) ; pos += r ;
+ if (!stralloc_readyplus(sa, pos)) return -1 ;
+ buffer_getnofill(b, sa->s + sa->len, pos) ; sa->len += pos ;
+ if (r) return 1 ;
+ if (sa->len - start >= max) return (errno = EMSGSIZE, -1) ;
+ r = buffer_fill(b) ;
+ if (r < 0) return r ;
+ if (!r) return (sa->s && (sa->len > start)) ? (errno = EPIPE, -1) : 0 ;
+ }
+}
diff --git a/src/libstddjb/xexecvep.c b/src/libstddjb/xexecvep.c
index 294f959..17a3abf 100644
--- a/src/libstddjb/xexecvep.c
+++ b/src/libstddjb/xexecvep.c
@@ -1,6 +1,7 @@
/* ISC license. */
#include <errno.h>
+#include <skalibs/posixplz.h>
#include <skalibs/djbunix.h>
#include <skalibs/strerr2.h>
diff --git a/src/libunixonacid/textmessage_handle.c b/src/libunixonacid/textmessage_handle.c
new file mode 100644
index 0000000..bec62cb
--- /dev/null
+++ b/src/libunixonacid/textmessage_handle.c
@@ -0,0 +1,20 @@
+/* ISC license. */
+
+#include <sys/uio.h>
+#include <skalibs/textmessage.h>
+
+int textmessage_handle (textmessage_receiver_t *tr, textmessage_handler_func_t_ref f, void *p)
+{
+ unsigned int count = 0 ;
+ while (count < TEXTMESSAGE_MAXREADS || textmessage_receiver_hasmsginbuf(tr))
+ {
+ struct iovec v ;
+ int r = textmessage_receive(tr, &v) ;
+ if (r < 0) return -1 ;
+ if (!r) break ;
+ r = (*f)(&v, p) ;
+ if (r <= 0) return r-2 ;
+ count++ ;
+ }
+ return (int)count ;
+}
diff --git a/src/libunixonacid/textmessage_put.c b/src/libunixonacid/textmessage_put.c
new file mode 100644
index 0000000..a6eb6ca
--- /dev/null
+++ b/src/libunixonacid/textmessage_put.c
@@ -0,0 +1,21 @@
+/* ISC license. */
+
+#include <sys/uio.h>
+#include <errno.h>
+#include <stdint.h>
+#include <skalibs/uint32.h>
+#include <skalibs/bufalloc.h>
+#include <skalibs/textmessage.h>
+
+int textmessage_put (textmessage_sender_t *ts, char const *s, size_t len)
+{
+ char pack[4] ;
+ struct iovec v[2] =
+ {
+ { .iov_base = pack, .iov_len = 4 },
+ { .iov_base = (char *)s, .iov_len = len }
+ } ;
+ if (len > UINT32_MAX) return (errno = EINVAL, 0) ;
+ uint32_pack_big(pack, (uint32_t)len) ;
+ return bufalloc_putv(&ts->out, v, 2) ;
+}
diff --git a/src/libunixonacid/textmessage_putv.c b/src/libunixonacid/textmessage_putv.c
new file mode 100644
index 0000000..c144505
--- /dev/null
+++ b/src/libunixonacid/textmessage_putv.c
@@ -0,0 +1,22 @@
+/* ISC license. */
+
+#include <sys/uio.h>
+#include <errno.h>
+#include <stdint.h>
+#include <skalibs/uint32.h>
+#include <skalibs/bufalloc.h>
+#include <skalibs/siovec.h>
+#include <skalibs/textmessage.h>
+
+int textmessage_putv (textmessage_sender_t *ts, struct iovec const *v, unsigned int n)
+{
+ size_t len = siovec_len(v, n) ;
+ char pack[4] ;
+ struct iovec vv[n+1] ;
+ if (len > UINT32_MAX) return (errno = EINVAL, 0) ;
+ vv[0].iov_base = pack ;
+ vv[0].iov_len = 4 ;
+ for (unsigned int i = 0 ; i < n ; i++) vv[i+1] = v[i] ;
+ uint32_pack_big(pack, (uint32_t)len) ;
+ return bufalloc_putv(&ts->out, vv, n+1) ;
+}
diff --git a/src/libunixonacid/textmessage_receive.c b/src/libunixonacid/textmessage_receive.c
new file mode 100644
index 0000000..1411f9a
--- /dev/null
+++ b/src/libunixonacid/textmessage_receive.c
@@ -0,0 +1,40 @@
+/* ISC license. */
+
+#include <sys/uio.h>
+#include <stdint.h>
+#include <errno.h>
+#include <skalibs/uint32.h>
+#include <skalibs/allreadwrite.h>
+#include <skalibs/buffer.h>
+#include <skalibs/stralloc.h>
+#include <skalibs/textmessage.h>
+
+int textmessage_receive (textmessage_receiver_t *tr, struct iovec *v)
+{
+ if (tr->indata.len == tr->wanted)
+ {
+ uint32_t u ;
+ char pack[4] ;
+ if (buffer_len(&tr->in) < 4)
+ {
+ ssize_t r = sanitize_read(buffer_fill(&tr->in)) ;
+ if (r <= 0) return r ;
+ if (buffer_len(&tr->in) < 4) return (errno = EWOULDBLOCK, 0) ;
+ }
+ buffer_getnofill(&tr->in, pack, 4) ;
+ uint32_unpack_big(pack, &u) ;
+ if (u > tr->max) return (errno = EMSGSIZE, -1) ;
+ if (!stralloc_ready(&tr->indata, u)) return -1 ;
+ tr->wanted = u ;
+ tr->indata.len = 0 ;
+ }
+
+ {
+ int r = buffer_getall(&tr->in, tr->indata.s, tr->wanted, &tr->indata.len) ;
+ if (r <= 0) return r ;
+ }
+
+ v->iov_base = tr->indata.s ;
+ v->iov_len = tr->indata.len ;
+ return 1 ;
+}
diff --git a/src/libunixonacid/textmessage_receiver_0.c b/src/libunixonacid/textmessage_receiver_0.c
new file mode 100644
index 0000000..f21b396
--- /dev/null
+++ b/src/libunixonacid/textmessage_receiver_0.c
@@ -0,0 +1,10 @@
+/* ISC license. */
+
+/* MT-unsafe */
+
+#include <stdint.h>
+#include <skalibs/buffer.h>
+#include <skalibs/textmessage.h>
+
+static char buf[BUFFER_INSIZE] ;
+textmessage_receiver_t textmessage_receiver_0_ = TEXTMESSAGE_RECEIVER_INIT(0, buf, BUFFER_INSIZE, UINT32_MAX) ;
diff --git a/src/libunixonacid/textmessage_receiver_free.c b/src/libunixonacid/textmessage_receiver_free.c
new file mode 100644
index 0000000..037e23b
--- /dev/null
+++ b/src/libunixonacid/textmessage_receiver_free.c
@@ -0,0 +1,10 @@
+/* ISC license. */
+
+#include <skalibs/stralloc.h>
+#include <skalibs/textmessage.h>
+
+void textmessage_receiver_free (textmessage_receiver_t *ts)
+{
+ stralloc_free(&ts->indata) ;
+ *ts = textmessage_receiver_zero ;
+}
diff --git a/src/libunixonacid/textmessage_receiver_hasmsginbuf.c b/src/libunixonacid/textmessage_receiver_hasmsginbuf.c
new file mode 100644
index 0000000..d0cdcc3
--- /dev/null
+++ b/src/libunixonacid/textmessage_receiver_hasmsginbuf.c
@@ -0,0 +1,21 @@
+/* ISC license. */
+
+#include <stdint.h>
+#include <sys/uio.h>
+#include <skalibs/uint32.h>
+#include <skalibs/siovec.h>
+#include <skalibs/buffer.h>
+#include <skalibs/textmessage.h>
+
+int textmessage_receiver_hasmsginbuf (textmessage_receiver_t const *tr)
+{
+ size_t len = buffer_len(&tr->in) ;
+ uint32_t n ;
+ char pack[4] ;
+ struct iovec v[2] ;
+ if (len < 4) return 0 ;
+ buffer_rpeek(&tr->in, v) ;
+ siovec_gather(v, 2, pack, 4) ;
+ uint32_unpack_big(pack, &n) ;
+ return len - 4 >= n ;
+}
diff --git a/src/libunixonacid/textmessage_receiver_init.c b/src/libunixonacid/textmessage_receiver_init.c
new file mode 100644
index 0000000..8a29d68
--- /dev/null
+++ b/src/libunixonacid/textmessage_receiver_init.c
@@ -0,0 +1,14 @@
+/* ISC license. */
+
+#include <skalibs/buffer.h>
+#include <skalibs/stralloc.h>
+#include <skalibs/textmessage.h>
+
+int textmessage_receiver_init (textmessage_receiver_t *tr, int fd, char *buf, size_t buflen, uint32_t max)
+{
+ if (!buffer_init(&tr->in, &buffer_read, fd, buf, buflen)) return 0 ;
+ tr->indata = stralloc_zero ;
+ tr->wanted = 0 ;
+ tr->max = max ;
+ return 1 ;
+}
diff --git a/src/libunixonacid/textmessage_receiver_zero.c b/src/libunixonacid/textmessage_receiver_zero.c
new file mode 100644
index 0000000..1e852e5
--- /dev/null
+++ b/src/libunixonacid/textmessage_receiver_zero.c
@@ -0,0 +1,5 @@
+/* ISC license. */
+
+#include <skalibs/textmessage.h>
+
+textmessage_receiver_t const textmessage_receiver_zero = TEXTMESSAGE_RECEIVER_ZERO ;
diff --git a/src/libunixonacid/textmessage_sender_1.c b/src/libunixonacid/textmessage_sender_1.c
new file mode 100644
index 0000000..0be2ae9
--- /dev/null
+++ b/src/libunixonacid/textmessage_sender_1.c
@@ -0,0 +1,7 @@
+/* ISC license. */
+
+/* MT-unsafe */
+
+#include <skalibs/textmessage.h>
+
+textmessage_sender_t textmessage_sender_1_ = TEXTMESSAGE_SENDER_INIT(1) ;
diff --git a/src/libunixonacid/textmessage_sender_flush.c b/src/libunixonacid/textmessage_sender_flush.c
new file mode 100644
index 0000000..53bd407
--- /dev/null
+++ b/src/libunixonacid/textmessage_sender_flush.c
@@ -0,0 +1,9 @@
+/* ISC license. */
+
+#include <skalibs/bufalloc.h>
+#include <skalibs/textmessage.h>
+
+int textmessage_sender_flush (textmessage_sender_t *ts)
+{
+ return bufalloc_flush(&ts->out) ;
+}
diff --git a/src/libunixonacid/textmessage_sender_getfd.c b/src/libunixonacid/textmessage_sender_getfd.c
new file mode 100644
index 0000000..8a6ddf7
--- /dev/null
+++ b/src/libunixonacid/textmessage_sender_getfd.c
@@ -0,0 +1,9 @@
+/* ISC license. */
+
+#include <skalibs/bufalloc.h>
+#include <skalibs/textmessage.h>
+
+int textmessage_sender_getfd (textmessage_sender_t const *ts)
+{
+ return bufalloc_fd(&ts->out) ;
+}
diff --git a/src/libunixonacid/textmessage_sender_timed_flush.c b/src/libunixonacid/textmessage_sender_timed_flush.c
new file mode 100644
index 0000000..18eddd2
--- /dev/null
+++ b/src/libunixonacid/textmessage_sender_timed_flush.c
@@ -0,0 +1,15 @@
+/* ISC license. */
+
+#include <skalibs/functypes.h>
+#include <skalibs/unix-timed.h>
+#include <skalibs/textmessage.h>
+
+static int textmessage_sender_isnonempty (textmessage_sender_t *ts)
+{
+ return !textmessage_sender_isempty(ts) ;
+}
+
+int textmessage_sender_timed_flush (textmessage_sender_t *ts, tain_t const *deadline, tain_t *stamp)
+{
+ return timed_flush(ts, (initfunc_t_ref)&textmessage_sender_getfd, (initfunc_t_ref)&textmessage_sender_isnonempty, (initfunc_t_ref)&textmessage_sender_flush, deadline, stamp) ;
+}
diff --git a/src/libunixonacid/textmessage_sender_x.c b/src/libunixonacid/textmessage_sender_x.c
new file mode 100644
index 0000000..2f6c557
--- /dev/null
+++ b/src/libunixonacid/textmessage_sender_x.c
@@ -0,0 +1,7 @@
+/* ISC license. */
+
+/* MT-unsafe */
+
+#include <skalibs/textmessage.h>
+
+textmessage_sender_t textmessage_sender_x_ = TEXTMESSAGE_SENDER_ZERO ;
diff --git a/src/libunixonacid/textmessage_sender_zero.c b/src/libunixonacid/textmessage_sender_zero.c
new file mode 100644
index 0000000..fbb2921
--- /dev/null
+++ b/src/libunixonacid/textmessage_sender_zero.c
@@ -0,0 +1,5 @@
+/* ISC license. */
+
+#include <skalibs/textmessage.h>
+
+textmessage_sender_t const textmessage_sender_zero = TEXTMESSAGE_SENDER_ZERO ;
diff --git a/src/libunixonacid/textmessage_timed_handle.c b/src/libunixonacid/textmessage_timed_handle.c
new file mode 100644
index 0000000..f8cf2dd
--- /dev/null
+++ b/src/libunixonacid/textmessage_timed_handle.c
@@ -0,0 +1,29 @@
+/* ISC license. */
+
+#include <skalibs/functypes.h>
+#include <skalibs/unix-timed.h>
+#include <skalibs/textmessage.h>
+
+typedef struct textmessage_handler_blah_s textmessage_handler_blah_t, *textmessage_handler_blah_t_ref ;
+struct textmessage_handler_blah_s
+{
+ textmessage_receiver_t *tr ;
+ textmessage_handler_func_t_ref f ;
+ void *p ;
+} ;
+
+static int getfd (textmessage_handler_blah_t *blah)
+{
+ return textmessage_receiver_fd(blah->tr) ;
+}
+
+static ssize_t get (textmessage_handler_blah_t *blah)
+{
+ return textmessage_handle(blah->tr, blah->f, blah->p) ;
+}
+
+int textmessage_timed_handle (textmessage_receiver_t *tr, textmessage_handler_func_t_ref f, void *p, tain_t const *deadline, tain_t *stamp)
+{
+ textmessage_handler_blah_t blah = { .tr = tr, .f = f, .p = p } ;
+ return timed_get(&blah, (initfunc_t_ref)&getfd, (getfunc_t_ref)&get, deadline, stamp) ;
+}
diff --git a/src/libunixonacid/textmessage_timed_receive.c b/src/libunixonacid/textmessage_timed_receive.c
new file mode 100644
index 0000000..5c7a848
--- /dev/null
+++ b/src/libunixonacid/textmessage_timed_receive.c
@@ -0,0 +1,29 @@
+/* ISC license. */
+
+#include <sys/uio.h>
+#include <skalibs/functypes.h>
+#include <skalibs/unix-timed.h>
+#include <skalibs/textmessage.h>
+
+typedef struct textmessage_get_s textmessage_get_t, *textmessage_get_t_ref ;
+struct textmessage_get_s
+{
+ textmessage_receiver_t *tr ;
+ struct iovec *v ;
+} ;
+
+static int getfd (textmessage_get_t *g)
+{
+ return textmessage_receiver_fd(g->tr) ;
+}
+
+static ssize_t get (textmessage_get_t *g)
+{
+ return textmessage_receive(g->tr, g->v) ;
+}
+
+int textmessage_timed_receive (textmessage_receiver_t *tr, struct iovec *v, tain_t const *deadline, tain_t *stamp)
+{
+ textmessage_get_t g = { .tr = tr, .v = v } ;
+ return timed_get(&g, (initfunc_t_ref)&getfd, (getfunc_t_ref)&get, deadline, stamp) ;
+}
diff --git a/src/sysdeps/tryarc4random.c b/src/sysdeps/tryarc4random.c
index b2f596a..3593eaa 100644
--- a/src/sysdeps/tryarc4random.c
+++ b/src/sysdeps/tryarc4random.c
@@ -3,6 +3,22 @@
#undef _POSIX_C_SOURCE
#undef _XOPEN_SOURCE
+#ifndef __EXTENSIONS__
+#define __EXTENSIONS__
+#endif
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+#ifndef _BSD_SOURCE
+#define _BSD_SOURCE
+#endif
+#ifndef _NETBSD_SOURCE
+#define _NETBSD_SOURCE
+#endif
+#ifndef _INCOMPLETE_XOPEN_C063
+#define _INCOMPLETE_XOPEN_C063
+#endif
+
#include <stdlib.h>
int main (void)
diff --git a/src/sysdeps/tryarc4random_addrandom.c b/src/sysdeps/tryarc4random_addrandom.c
index 1d5f84f..beb2346 100644
--- a/src/sysdeps/tryarc4random_addrandom.c
+++ b/src/sysdeps/tryarc4random_addrandom.c
@@ -3,6 +3,22 @@
#undef _POSIX_C_SOURCE
#undef _XOPEN_SOURCE
+#ifndef __EXTENSIONS__
+#define __EXTENSIONS__
+#endif
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+#ifndef _BSD_SOURCE
+#define _BSD_SOURCE
+#endif
+#ifndef _NETBSD_SOURCE
+#define _NETBSD_SOURCE
+#endif
+#ifndef _INCOMPLETE_XOPEN_C063
+#define _INCOMPLETE_XOPEN_C063
+#endif
+
#include <stdlib.h>
int main (void)
diff --git a/src/sysdeps/trygetpeereid.c b/src/sysdeps/trygetpeereid.c
index 10a411a..87b5017 100644
--- a/src/sysdeps/trygetpeereid.c
+++ b/src/sysdeps/trygetpeereid.c
@@ -3,6 +3,22 @@
#undef _POSIX_C_SOURCE
#undef _XOPEN_SOURCE
+#ifndef __EXTENSIONS__
+#define __EXTENSIONS__
+#endif
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+#ifndef _BSD_SOURCE
+#define _BSD_SOURCE
+#endif
+#ifndef _NETBSD_SOURCE
+#define _NETBSD_SOURCE
+#endif
+#ifndef _INCOMPLETE_XOPEN_C063
+#define _INCOMPLETE_XOPEN_C063
+#endif
+
#include <sys/types.h>
#include <unistd.h>
@@ -10,6 +26,6 @@ int main (void)
{
uid_t uid ;
gid_t gid ;
- int s = 0 ;
- return getpeereid(s, &uid, &gid) ;
+ int fd = 0 ;
+ return getpeereid(fd, &uid, &gid) ;
}
diff --git a/src/sysdeps/trymemmem.c b/src/sysdeps/trymemmem.c
new file mode 100644
index 0000000..458ac25
--- /dev/null
+++ b/src/sysdeps/trymemmem.c
@@ -0,0 +1,28 @@
+/* ISC license. */
+
+#undef _POSIX_C_SOURCE
+#undef _XOPEN_SOURCE
+
+#ifndef __EXTENSIONS__
+#define __EXTENSIONS__
+#endif
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+#ifndef _BSD_SOURCE
+#define _BSD_SOURCE
+#endif
+#ifndef _NETBSD_SOURCE
+#define _NETBSD_SOURCE
+#endif
+#ifndef _INCOMPLETE_XOPEN_C063
+#define _INCOMPLETE_XOPEN_C063
+#endif
+
+#include <string.h>
+
+int main (void)
+{
+ memmem("blah", 4, "la", 2) ;
+ return 0 ;
+}
diff --git a/src/sysdeps/trynamespaces.c b/src/sysdeps/trynamespaces.c
index 01894be..b88f414 100644
--- a/src/sysdeps/trynamespaces.c
+++ b/src/sysdeps/trynamespaces.c
@@ -1,8 +1,23 @@
/* ISC license. */
+#undef _POSIX_C_SOURCE
+#undef _XOPEN_SOURCE
+
+#ifndef __EXTENSIONS__
+#define __EXTENSIONS__
+#endif
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
+#ifndef _BSD_SOURCE
+#define _BSD_SOURCE
+#endif
+#ifndef _NETBSD_SOURCE
+#define _NETBSD_SOURCE
+#endif
+#ifndef _INCOMPLETE_XOPEN_C063
+#define _INCOMPLETE_XOPEN_C063
+#endif
#include <sched.h>
diff --git a/src/sysdeps/trystrcasestr.c b/src/sysdeps/trystrcasestr.c
index f362202..3c4efc4 100644
--- a/src/sysdeps/trystrcasestr.c
+++ b/src/sysdeps/trystrcasestr.c
@@ -3,6 +3,9 @@
#undef _POSIX_C_SOURCE
#undef _XOPEN_SOURCE
+#ifndef __EXTENSIONS__
+#define __EXTENSIONS__
+#endif
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
@@ -12,6 +15,9 @@
#ifndef _NETBSD_SOURCE
#define _NETBSD_SOURCE
#endif
+#ifndef _INCOMPLETE_XOPEN_C063
+#define _INCOMPLETE_XOPEN_C063
+#endif
#include <string.h>
diff --git a/src/sysdeps/trystrnlen.c b/src/sysdeps/trystrnlen.c
index 7ebab53..0799dde 100644
--- a/src/sysdeps/trystrnlen.c
+++ b/src/sysdeps/trystrnlen.c
@@ -1,5 +1,8 @@
/* ISC license. */
+#undef _POSIX_C_SOURCE
+#undef _XOPEN_SOURCE
+
#include <string.h>
int main (void)