aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias Andrée <maandree@kth.se>2017-11-12 14:05:45 +0100
committerMattias Andrée <maandree@kth.se>2017-11-12 14:05:45 +0100
commit83fab888366df693ff8718b15db9fc2f303e030f (patch)
tree45641f0dcdb0ecd8ed969424346877b7073b59ac
parentAdd libsimple.c and libsimple.h (diff)
downloadlibsimple-83fab888366df693ff8718b15db9fc2f303e030f.tar.gz
libsimple-83fab888366df693ff8718b15db9fc2f303e030f.tar.bz2
libsimple-83fab888366df693ff8718b15db9fc2f303e030f.tar.xz
More functions and add makefile
Signed-off-by: Mattias Andrée <maandree@kth.se>
-rw-r--r--Makefile10
-rw-r--r--libsimple.c619
-rw-r--r--libsimple.h841
3 files changed, 1401 insertions, 69 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..35e122e
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,10 @@
+.POSIX:
+
+all: libsimple.a
+libsimple.o: libsimple.h
+libsimple.a: libsimple.o
+
+clean:
+ -rm -r -- libsimple.o libsimple.a libsimple.so libsimple.so.*
+
+.PHONY: all clean
diff --git a/libsimple.c b/libsimple.c
index 9a58ba1..ac7432a 100644
--- a/libsimple.c
+++ b/libsimple.c
@@ -1,5 +1,6 @@
/* See LICENSE file for copyright and license details. */
#include "libsimple.h"
+#include <ifaddrs.h>
extern char *argv0;
@@ -441,11 +442,14 @@ vweprintf(const char *fmt, va_list ap)
va_end(ap2);
va_end(ap1);
- if (*end == ':') {
+ if (!*fmt) {
+ suffix1 = strerror(saved_errno);
+ suffix2 = "\n";
+ } else if (end[-1] == ':') {
suffix1 = " ";
suffix2 = strerror(saved_errno);
suffix3 = "\n";
- } else if (*end != '\n') {
+ } else if (end[-1] != '\n') {
suffix1 = "\n";
}
@@ -460,3 +464,614 @@ vweprintf(const char *fmt, va_list ap)
errno = saved_errno;
}
+
+
+
+int
+libsimple_sendfd(int sock, int fd)
+{
+ char buf[1];
+ struct iovec iov;
+ struct msghdr msg;
+ struct cmsghdr *cmsg;
+ char cms[CMSG_SPACE(sizeof(fd))];
+
+ buf[0] = 0;
+ iov.iov_base = buf;
+ iov.iov_len = 1;
+
+ memset(&msg, 0, sizeof(msg));
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ msg.msg_control = (caddr_t)cms;
+ msg.msg_controllen = CMSG_LEN(sizeof(fd));
+
+ cmsg = CMSG_FIRSTHDR(&msg);
+ cmsg->cmsg_len = CMSG_LEN(sizeof(fd));
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SCM_RIGHTS;
+ memcpy(CMSG_DATA(cmsg), &fd, sizeof(fd));
+
+ return -(sendmsg(sock, &msg, 0) != (ssize_t)iov.iov_len);
+}
+
+
+int
+libsimple_recvfd(int sock)
+{
+ int fd;
+ char buf[1];
+ struct iovec iov;
+ struct msghdr msg;
+ struct cmsghdr *cmsg;
+ char cms[CMSG_SPACE(sizeof(fd))];
+
+ iov.iov_base = buf;
+ iov.iov_len = 1;
+
+ memset(&msg, 0, sizeof(msg));
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+
+ msg.msg_control = (caddr_t)cms;
+ msg.msg_controllen = sizeof(cms);
+
+ switch (recvmsg(sock, &msg, 0)) {
+ case -1:
+ return -1;
+ case 0:
+ errno = ECONNRESET;
+ return -1;
+ default:
+ break;
+ }
+
+ cmsg = CMSG_FIRSTHDR(&msg);
+ memcpy(&fd, CMSG_DATA(cmsg), sizeof(fd));
+ return fd;
+}
+
+
+ssize_t
+libsimple_recvfrom_timestamped(int fd, void *restrict buf, size_t n, int flags, struct sockaddr *restrict addr,
+ socklen_t addrlen, struct timespec *restrict ts)
+{
+ struct iovec iov;
+ struct msghdr msg;
+ struct cmsghdr *cmsg;
+ char cms[CMSG_SPACE(sizeof(*ts))];
+ size_t r;
+
+ iov.iov_base = buf;
+ iov.iov_len = n;
+
+ memset(&msg, 0, sizeof(msg));
+ msg.msg_name = addr;
+ msg.msg_namelen = addrlen;
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+
+ msg.msg_control = (caddr_t)cms;
+ msg.msg_controllen = sizeof(cms);
+
+ switch ((r = recvmsg(fd, &msg, flags))) {
+ case -1:
+ return -1;
+ case 0:
+ errno = ECONNRESET;
+ return -1;
+ default:
+ break;
+ }
+
+ if (!ts)
+ return r;
+
+ cmsg = CMSG_FIRSTHDR(&msg);
+ if (cmsg &&
+ cmsg->cmsg_level == SOL_SOCKET &&
+ cmsg->cmsg_type == SCM_TIMESTAMPNS &&
+ cmsg->cmsg_len == CMSG_LEN(sizeof(*ts))) {
+ memcpy(ts, CMSG_DATA(cmsg), sizeof(*ts));
+ } else if (cmsg &&
+ cmsg->cmsg_level == SOL_SOCKET &&
+ cmsg->cmsg_type == SCM_TIMESTAMP &&
+ cmsg->cmsg_len == CMSG_LEN(sizeof(*ts))) {
+ memcpy(ts, CMSG_DATA(cmsg), sizeof(*ts));
+ ts->tv_nsec *= 1000;
+ } else {
+ memset(ts, 0, sizeof(*ts));
+ }
+
+ return r;
+}
+
+
+int
+libsimple_sumtimespec(struct timespec *sum, const struct timespec *augend, const struct timespec *addend)
+{
+ long int ns = augend->tv_nsec + addend->tv_nsec;
+ time_t s;
+ int ret = 0;
+
+ s = augend->tv_sec + addend->tv_sec;
+ if ((augend->tv_sec < 0) == (addend->tv_sec < 0)) {
+ if (augend->tv_sec >= 0 && augend->tv_sec > TIME_MAX - addend->tv_sec) {
+ s = TIME_MAX;
+ ns = 999999999L;
+ errno = ERANGE;
+ ret = -1;
+ } else if (augend->tv_sec < 0 && augend->tv_sec + addend->tv_sec < TIME_MIN) {
+ s = TIME_MIN;
+ ns = 0;
+ errno = ERANGE;
+ ret = -1;
+ }
+ }
+
+ if (ns < 0) {
+ if (s == TIME_MIN) {
+ ns = 0L;
+ errno = ERANGE;
+ ret = -1;
+ } else {
+ s -= 1;
+ ns += 1000000000L;
+ }
+ } else if (ns >= 1000000000L) {
+ if (s == TIME_MAX) {
+ ns = 999999999L;
+ errno = ERANGE;
+ ret = -1;
+ } else {
+ s += 1;
+ ns -= 1000000000L;
+ }
+ }
+
+ sum->tv_sec = s;
+ sum->tv_nsec = ns;
+ return ret;
+}
+
+
+int
+libsimple_difftimespec(struct timespec *diff, const struct timespec *minuend, const struct timespec *subtrahend)
+{
+ long int ns = minuend->tv_nsec - subtrahend->tv_nsec;
+ time_t s;
+ int ret = 0;
+
+ s = minuend->tv_sec - subtrahend->tv_sec;
+ if ((minuend->tv_sec <= 0) != (subtrahend->tv_sec <= 0)) {
+ if (minuend->tv_sec < 0 && minuend->tv_sec < TIME_MIN + subtrahend->tv_sec) {
+ s = TIME_MIN;
+ ns = 0;
+ errno = ERANGE;
+ ret = -1;
+ } else if (minuend->tv_sec >= 0 && minuend->tv_sec > TIME_MAX + subtrahend->tv_sec) {
+ s = TIME_MAX;
+ ns = 999999999L;
+ errno = ERANGE;
+ ret = -1;
+ }
+ }
+
+ if (ns < 0) {
+ if (s == TIME_MIN) {
+ ns = 0L;
+ errno = ERANGE;
+ ret = -1;
+ } else {
+ s -= 1;
+ ns += 1000000000L;
+ }
+ } else if (ns >= 1000000000L) {
+ if (s == TIME_MAX) {
+ ns = 999999999L;
+ errno = ERANGE;
+ ret = -1;
+ } else {
+ s += 1;
+ ns -= 1000000000L;
+ }
+ }
+
+ diff->tv_sec = s;
+ diff->tv_nsec = ns;
+ return ret;
+}
+
+
+int
+libsimple_multimespec(struct timespec *prod, const struct timespec *multiplicand, int multiplier)
+{
+ time_t s = multiplicand->tv_sec;
+ long long int ns = (long long int)(multiplicand->tv_nsec);
+ long long int xs;
+ int neg = (s < 0) ^ (multiplier < 0);
+
+ if (multiplier == 0 || multiplier == 1) {
+ prod->tv_sec = multiplier * multiplicand->tv_sec;
+ prod->tv_nsec = multiplier * multiplicand->tv_nsec;
+ return 0;
+ }
+
+ if (s < 0) {
+ if (TIME_MIN != -TIME_MAX && s == TIME_MIN)
+ goto overflow;
+ s = -s;
+ if (ns)
+ ns = 1000000000L - ns;
+ }
+ if (multiplier < 0)
+ multiplier = -multiplier;
+
+ ns *= multiplier;
+ xs /= 1000000000L;
+ ns %= 1000000000L;
+
+ if (s > TIME_MAX / multiplier)
+ goto overflow;
+ s *= multiplier;
+
+ if (s > TIME_MAX - (time_t)xs)
+ goto overflow;
+ s += (time_t)xs;
+
+ if (neg) {
+ s = -s;
+ if (ns) {
+ if (s == TIME_MIN)
+ goto overflow;
+ ns = 1000000000L - ns;
+ s -= 1;
+ }
+ }
+
+ prod->tv_sec = s;
+ prod->tv_nsec = ns;
+ return 0;
+
+overflow:
+ if (neg) {
+ prod->tv_sec = TIME_MIN;
+ prod->tv_nsec = 0;
+ } else {
+ prod->tv_sec = TIME_MAX;
+ prod->tv_nsec = 999999999L;
+ }
+ errno = ERANGE;
+ return -1;
+}
+
+
+int
+libsimple_sumtimeval(struct timeval *sum, const struct timeval *augend, const struct timeval *addend)
+{
+ struct timespec a, b, s;
+ int r;
+ libsimple_timeval2timespec(&a, augend);
+ libsimple_timeval2timespec(&b, addend);
+ r = libsimple_sumtimespec(&s, &a, &b);
+ if (r && errno != ERANGE)
+ return r;
+ return r | libsimple_timespec2timeval(sum, &s);
+}
+
+
+int
+libsimple_difftimeval(struct timeval *diff, const struct timeval *minuend, const struct timeval *subtrahend)
+{
+ struct timespec a, b, d;
+ int r;
+ libsimple_timeval2timespec(&a, minuend);
+ libsimple_timeval2timespec(&b, subtrahend);
+ r = libsimple_difftimespec(&d, &a, &b);
+ if (r && errno != ERANGE)
+ return r;
+ return r | libsimple_timespec2timeval(diff, &d);
+}
+
+
+int
+libsimple_multimeval(struct timeval *prod, const struct timeval *multiplicand, int multiplier)
+{
+ struct timespec a, p;
+ int r;
+ libsimple_timeval2timespec(&a, multiplicand);
+ r = libsimple_multimespec(&p, &a, multiplier);
+ if (r && errno != ERANGE)
+ return r;
+ return r | libsimple_timespec2timeval(prod, &p);
+}
+
+
+int
+libsimple_timespec2timeval(struct timeval *restrict tv, const struct timespec *restrict ts)
+{
+ tv->tv_sec = ts->tv_sec;
+ tv->tv_usec = ts->tv_nsec / 1000L;
+ if ((ts->tv_nsec % 1000L) >= 500L) {
+ if (++(tv->tv_usec) == 1000000L) {
+ tv->tv_usec = 0;
+ if (tv->tv_sec == TIME_MAX) {
+ tv->tv_usec = 999999L;
+ errno = EOVERFLOW;
+ return -1;
+ } else {
+ tv->tv_sec += 1;
+ }
+ }
+ }
+ return 0;
+}
+
+
+int
+libsimple_strtotimespec(struct timespec *restrict ts, const char *restrict s, char **restrict end)
+{
+ int neg = 0, bracket = 0;
+ time_t sec = 0;
+ long int nsec = 0;
+ long int mul = 100000000L;
+ const char *p;
+
+ if (end)
+ *end = (void *)s;
+
+ while (isspace(*s))
+ s++;
+
+ if (!isdigit(s) && *s != '+' && *s != '-' && *s != '.') {
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (*s == '-') {
+ neg = 1;
+ s++;
+ } else if (*s == '+') {
+ s++;
+ }
+
+ if (*s == '.') {
+ if (s[1] == '.' || s[1] == '(') {
+ if (!isdigit(s[2])) {
+ errno = EINVAL;
+ return -1;
+ }
+ } else if (!isdigit(s[1])) {
+ errno = EINVAL;
+ return -1;
+ }
+ }
+
+ for (; isdigit(*s); s++) {
+ if (sec < TIME_MIN / 10)
+ goto overflow;
+ sec *= 10;
+ if (sec < TIME_MIN + (*s & 15))
+ goto overflow;
+ sec -= *s & 15;
+ }
+
+ if (!neg) {
+ if (TIME_MIN != -TIME_MAX && sec == TIME_MIN)
+ goto overflow;
+ sec = -sec;
+ }
+
+ if (*s != '.') {
+ ts->tv_sec = sec;
+ ts->tv_nsec = 0;
+ if (end)
+ *end = (void *)s;
+ return 0;
+ }
+
+ for (s++; mul && isdigit(*s); s++) {
+ nsec += (*s & 15) * mul;
+ mul /= 10;
+ }
+
+ if (*s == '.' || *s == '(') {
+ bracket = *s++ == '(';
+ p = s;
+ if (!isdigit(*s)) {
+ errno = EINVAL;
+ return -1;
+ }
+ for (p = s; isdigit(*p); p++);
+ if (bracket) {
+ if (*p == ')') {
+ p++;
+ } else {
+ errno = EINVAL;
+ return -1;
+ }
+ }
+ if (end)
+ *end = (void *)p;
+ p = s;
+ while (mul) {
+ for (s = p; mul && isdigit(*s); s++) {
+ nsec += (*s & 15) * mul;
+ mul /= 10;
+ }
+ }
+ if (!isdigit(*s))
+ s = p;
+ if (*s >= '5') {
+ nsec += 1;
+ if (nsec == 1000000000L) {
+ if (sec == TIME_MAX)
+ goto overflow;
+ sec += 1;
+ nsec = 0;
+ }
+ }
+ } else {
+ if (isdigit(*s)) {
+ if (*s >= '5') {
+ nsec += 1;
+ if (nsec == 1000000000L) {
+ if (sec == TIME_MAX)
+ goto overflow;
+ sec += 1;
+ nsec = 0;
+ }
+ }
+ while (isdigit(*s))
+ s++;
+ }
+ if (end)
+ *end = (void *)s;
+ }
+
+ if (neg && nsec) {
+ if (sec == TIME_MIN)
+ goto overflow;
+ nsec = 1000000000L - nsec;
+ sec -= 1;
+ }
+
+ return 0;
+overflow:
+ if (neg) {
+ ts->tv_sec = TIME_MIN;
+ ts->tv_nsec = 0;
+ } else {
+ ts->tv_sec = TIME_MAX;
+ ts->tv_nsec = 999999999L;
+ }
+ errno = ERANGE;
+ return -1;
+}
+
+
+int
+libsimple_strtotimeval(struct timeval *restrict tv, const char *restrict s, char **restrict end)
+{
+ struct timespec ts;
+ int r = libsimple_strtotimespec(&ts, s, end);
+ if (r && errno != ERANGE)
+ return r;
+ return r | libsimple_timespec2timeval(tv, &ts);
+}
+
+
+char *
+libsimple_timespectostr(char *restrict buf, const struct timespec *restrict ts)
+{
+ time_t s = ts->tv_sec;
+ long int ns = ts->tv_nsec;
+ char sign[2] = "+";
+
+ if (!s) {
+ buf = malloc(INTSTRLEN(time_t) + sizeof("-.999999999"));
+ if (!buf)
+ return NULL;
+ }
+
+ if (ts->tv_nsec < 0 || ts->tv_nsec >= 1000000000L) {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ if (s == TIME_MIN && !ns) {
+ sprintf(buf, "%lli.000000000", (long long int)s);
+ return buf;
+ }
+
+ if (s < 0) {
+ s = -s;
+ *sign == '-';
+ if (ns) {
+ s -= 1;
+ ns = 1000000000L - ns;
+ }
+ }
+
+ sprintf(buf, "%s%lli.%09li", sign, (long long int)s, ns);
+ return buf;
+}
+
+
+char *
+libsimple_timevaltostr(char *restrict buf, const struct timeval *restrict tv)
+{
+ time_t s = tv->tv_sec;
+ long int us = tv->tv_usec;
+ char sign[2] = "+";
+
+ if (!s) {
+ buf = malloc(INTSTRLEN(time_t) + sizeof("-.999999"));
+ if (!buf)
+ return NULL;
+ }
+
+ if (tv->tv_usec < 0 || tv->tv_usec >= 1000000L) {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ if (s == TIME_MIN && !us) {
+ sprintf(buf, "%lli.000000", (long long int)s);
+ return buf;
+ }
+
+ if (s < 0) {
+ s = -s;
+ *sign == '-';
+ if (us) {
+ s -= 1;
+ us = 1000000L - us;
+ }
+ }
+
+ sprintf(buf, "%s%lli.%06li", sign, (long long int)s, us);
+ return buf;
+}
+
+
+void
+libsimple_doubletotimespec(struct timespec *ts, double d)
+{
+ double ns = (long long int)d;
+ long int nsi;
+ ns = d - ns;
+ ns *= (double)1000000000L;
+ nsi = (long int)ns;
+ if (2 * (ns - (double)nsi) >= 1) {
+ nsi += 1;
+ if (nsi == 1000000000L) {
+ nsi == 0;
+ d += 1;
+ }
+ }
+ ts->tv_sec = (time_t)d;
+ ts->tv_nsec = nsi;
+}
+
+
+void
+libsimple_doubletotimeval(struct timeval *tv, double d)
+{
+ double ns = (long long int)d;
+ long int nsi;
+ ns = d - ns;
+ ns *= (double)1000000L;
+ nsi = (long int)ns;
+ if (2 * (ns - (double)nsi) >= 1) {
+ nsi += 1;
+ if (nsi == 1000000L) {
+ nsi == 0;
+ d += 1;
+ }
+ }
+ tv->tv_sec = (time_t)d;
+ tv->tv_usec = nsi;
+}
diff --git a/libsimple.h b/libsimple.h
index 02fc912..893ba72 100644
--- a/libsimple.h
+++ b/libsimple.h
@@ -3,17 +3,40 @@
#define LIBSIMPLE_H
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <sys/mman.h>
+#include <sys/select.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <sys/un.h>
+#include <sys/wait.h>
+#include <aio.h>
#include <alloca.h>
+#include <ctype.h>
+#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
+#include <grp.h>
#include <inttypes.h>
#include <limits.h>
+#include <netdb.h>
+#include <poll.h>
+#include <pwd.h>
+#include <setjmp.h>
+#include <signal.h>
#include <stdarg.h>
+#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
+#include <time.h>
#include <unistd.h>
@@ -27,63 +50,523 @@
extern int libsimple_default_failure_exit;
-_LIBSIMPLE_GCC_ONLY(__attribute__((pure, nonnull, warn_unused_result)))
+#ifndef CLOCK_MONOTONIC_RAW
+# define CLOCK_MONOTONIC_RAW CLOCK_MONOTONIC
+#endif
+
+
+#ifdef AF_LOCAL
+# ifndef AF_UNIX
+# define AF_UNIX AF_LOCAL
+# endif
+# ifndef AF_FILE
+# define AF_FILE AF_LOCAL
+# endif
+#endif
+
+#ifdef AF_UNIX
+# ifndef AF_LOCAL
+# define AF_LOCAL AF_UNIX
+# endif
+# ifndef AF_FILE
+# define AF_FILE AF_UNIX
+# endif
+#endif
+
+#ifdef AF_FILE
+# ifndef AF_LOCAL
+# define AF_LOCAL AF_FILE
+# endif
+# ifndef AF_UNIX
+# define AF_UNIX AF_FILE
+# endif
+#endif
+
+#ifdef AF_NETLINK
+# ifndef AF_ROUTE
+# define AF_ROUTE AF_NETLINK
+# endif
+#endif
+
+#ifdef AF_ROUTE
+# ifndef AF_NETLINK
+# define AF_NETLINK AF_ROUTE
+# endif
+#endif
+
+#ifdef PF_LOCAL
+# ifndef PF_UNIX
+# define PF_UNIX PF_LOCAL
+# endif
+# ifndef PF_FILE
+# define PF_FILE PF_LOCAL
+# endif
+#endif
+
+#ifdef PF_UNIX
+# ifndef PF_LOCAL
+# define PF_LOCAL PF_UNIX
+# endif
+# ifndef PF_FILE
+# define PF_FILE PF_UNIX
+# endif
+#endif
+
+#ifdef PF_FILE
+# ifndef PF_LOCAL
+# define PF_LOCAL PF_FILE
+# endif
+# ifndef PF_UNIX
+# define PF_UNIX PF_FILE
+# endif
+#endif
+
+#ifdef PF_NETLINK
+# ifndef PF_ROUTE
+# define PF_ROUTE PF_NETLINK
+# endif
+#endif
+
+#ifdef PF_ROUTE
+# ifndef PF_NETLINK
+# define PF_NETLINK PF_ROUTE
+# endif
+#endif
+
+#if !defined(PF_UNIX) && defined(AF_UNIX)
+# define PF_UNIX AF_UNIX
+#endif
+#if !defined(PF_LOCAL) && defined(AF_LOCAL)
+# define PF_LOCAL AF_LOCAL
+#endif
+#if !defined(PF_FILE) && defined(AF_FILE)
+# define PF_FILE AF_FILE
+#endif
+#if !defined(PF_INET) && defined(AF_INET)
+# define PF_INET AF_INET
+#endif
+#if !defined(PF_INET6) && defined(AF_INET6)
+# define PF_INET6 AF_INET6
+#endif
+#if !defined(PF_NETLINK) && defined(AF_NETLINK)
+# define PF_NETLINK AF_NETLINK
+#endif
+#if !defined(PF_ROUTE) && defined(AF_ROUTE)
+# define PF_ROUTE AF_ROUTE
+#endif
+
+
+#ifndef MIN
+# define MIN(A, B) ((A) < (B) ? (A) : (B))
+#endif
+
+
+#ifndef MAX
+# define MAX(A, B) ((A) > (B) ? (A) : (B))
+#endif
+
+
+#ifndef MIN3
+# define MIN3(A, B, C) MIN(MIN((A), (B)), (C))
+#endif
+
+
+#ifndef MAX3
+# define MAX3(A, B, C) MAX(MAX((A), (B)), (C))
+#endif
+
+
+#ifndef ELEMSOF
+# define ELEMSOF(ARR) (sizeof(ARR) / (sizeof(*(ARR))))
+#endif
+
+
+#ifndef STRLEN
+# define STRLEN(STR) (sizeof(STR) - 1)
+#endif
+
+
+#ifndef INTSTRLEN
+# define INTSTRLEN(TYPE) ((sizeof(TYPE) == 1 ? 3 : 5 * (sizeof(TYPE) / 2)) + ((TYPE)-1 > 0))
+#endif
+
+
+#ifndef TYPE_MAX
+# define TYPE_MAX(TYPE) ((TYPE)(((1ULL << (8 * sizeof(TYPE) - 1)) - 1) << ((TYPE)-1 > 0) | 1))
+#endif
+
+
+#ifndef TYPE_MIN
+# define TYPE_MIN(TYPE) ((TYPE)((TYPE)-1 > 0 ? 0 : (TYPE)~0 < (TYPE)-1 ? (TYPE)~0 : (TYPE)(1ULL << (8 * sizeof(TYPE) - 1))))
+#endif
+
+
+#ifndef BLKCNT64_MAX
+# define BLKCNT64_MAX TYPE_MAX(blkcnt64_t)
+#endif
+
+#ifndef BLKCNT_MAX
+# define BLKCNT_MAX TYPE_MAX(blkcnt_t)
+#endif
+
+#ifndef BLKSIZE_MAX
+# define BLKSIZE_MAX TYPE_MAX(blksize_t)
+#endif
+
+#ifndef CC_MAX
+# define CC_MAX TYPE_MAX(cc_t)
+#endif
+
+#ifndef CLOCKID_MAX
+# define CLOCKID_MAX TYPE_MAX(clockid_t)
+#endif
+
+#ifndef CLOCK_MAX
+# define CLOCK_MAX TYPE_MAX(clock_t)
+#endif
+
+#ifndef DEV_MAX
+# define DEV_MAX TYPE_MAX(dev_t)
+#endif
+
+#ifndef FSBLKCNT64_MAX
+# define FSBLKCNT64_MAX TYPE_MAX(fsblkcnt64_t)
+#endif
+
+#ifndef FSBLKCNT_MAX
+# define FSBLKCNT_MAX TYPE_MAX(fsblkcnt_t)
+#endif
+
+#ifndef FSFILCNT64_MAX
+# define FSFILCNT64_MAX TYPE_MAX(fsfilcnt64_t)
+#endif
+
+#ifndef FSFILCNT_MAX
+# define FSFILCNT_MAX TYPE_MAX(fsfilcnt_t)
+#endif
+
+#ifndef FSID_MAX
+# define FSID_MAX TYPE_MAX(fsid_t)
+#endif
+
+#ifndef FSWORD_MAX
+# define FSWORD_MAX TYPE_MAX(fsword_t)
+#endif
+
+#ifndef GID_MAX
+# define GID_MAX TYPE_MAX(gid_t)
+#endif
+
+#ifndef ID_MAX
+# define ID_MAX TYPE_MAX(id_t)
+#endif
+
+#ifndef INO64_MAX
+# define INO64_MAX TYPE_MAX(ino64_t)
+#endif
+
+#ifndef INO_MAX
+# define INO_MAX TYPE_MAX(ino_t)
+#endif
+
+#ifndef KEY_MAX
+# define KEY_MAX TYPE_MAX(key_t)
+#endif
+
+#ifndef LOFF_MAX
+# define LOFF_MAX TYPE_MAX(loff_t)
+#endif
+
+#ifndef MODE_MAX
+# define MODE_MAX TYPE_MAX(mode_t)
+#endif
+
+#ifndef NLINK_MAX
+# define NLINK_MAX TYPE_MAX(nlink_t)
+#endif
+
+#ifndef OFF64_MAX
+# define OFF64_MAX TYPE_MAX(off64_t)
+#endif
+
+#ifndef OFF_MAX
+# define OFF_MAX TYPE_MAX(off_t)
+#endif
+
+#ifndef PID_MAX
+# define PID_MAX TYPE_MAX(pid_t)
+#endif
+
+#ifndef QUAD_MAX
+# define QUAD_MAX TYPE_MAX(quad_t)
+#endif
+
+#ifndef REGISTER_MAX
+# define REGISTER_MAX TYPE_MAX(register_t)
+#endif
+
+#ifndef RLIM64_MAX
+# define RLIM64_MAX TYPE_MAX(rlim64_t)
+#endif
+
+#ifndef RLIM_MAX
+# define RLIM_MAX TYPE_MAX(rlim_t)
+#endif
+
+#ifndef SOCKLEN_MAX
+# define SOCKLEN_MAX TYPE_MAX(socklen_t)
+#endif
+
+#ifndef SPEED_MAX
+# define SPEED_MAX TYPE_MAX(speed_t)
+#endif
+
+#ifndef SUSECONDS_MAX
+# define SUSECONDS_MAX TYPE_MAX(suseconds_t)
+#endif
+
+#ifndef TCFLAG_MAX
+# define TCFLAG_MAX TYPE_MAX(tcflag_t)
+#endif
+
+#ifndef TIMER_MAX
+# define TIMER_MAX TYPE_MAX(timer_t)
+#endif
+
+#ifndef TIME_MAX
+# define TIME_MAX TYPE_MAX(time_t)
+#endif
+
+#ifndef UID_MAX
+# define UID_MAX TYPE_MAX(uid_t)
+#endif
+
+#ifndef USECONDS_MAX
+# define USECONDS_MAX TYPE_MAX(useconds_t)
+#endif
+
+#ifndef U_QUAD_MAX
+# define U_QUAD_MAX TYPE_MAX(u_quad_t)
+#endif
+
+
+#ifndef BLKCNT64_MIN
+# define BLKCNT64_MIN TYPE_MIN(blkcnt64_t)
+#endif
+
+#ifndef BLKCNT_MIN
+# define BLKCNT_MIN TYPE_MIN(blkcnt_t)
+#endif
+
+#ifndef BLKSIZE_MIN
+# define BLKSIZE_MIN TYPE_MIN(blksize_t)
+#endif
+
+#ifndef CC_MIN
+# define CC_MIN TYPE_MIN(cc_t)
+#endif
+
+#ifndef CLOCKID_MIN
+# define CLOCKID_MIN TYPE_MIN(clockid_t)
+#endif
+
+#ifndef CLOCK_MIN
+# define CLOCK_MIN TYPE_MIN(clock_t)
+#endif
+
+#ifndef DEV_MIN
+# define DEV_MIN TYPE_MIN(dev_t)
+#endif
+
+#ifndef FSBLKCNT64_MIN
+# define FSBLKCNT64_MIN TYPE_MIN(fsblkcnt64_t)
+#endif
+
+#ifndef FSBLKCNT_MIN
+# define FSBLKCNT_MIN TYPE_MIN(fsblkcnt_t)
+#endif
+
+#ifndef FSFILCNT64_MIN
+# define FSFILCNT64_MIN TYPE_MIN(fsfilcnt64_t)
+#endif
+
+#ifndef FSFILCNT_MIN
+# define FSFILCNT_MIN TYPE_MIN(fsfilcnt_t)
+#endif
+
+#ifndef FSID_MIN
+# define FSID_MIN TYPE_MIN(fsid_t)
+#endif
+
+#ifndef FSWORD_MIN
+# define FSWORD_MIN TYPE_MIN(fsword_t)
+#endif
+
+#ifndef GID_MIN
+# define GID_MIN TYPE_MIN(gid_t)
+#endif
+
+#ifndef ID_MIN
+# define ID_MIN TYPE_MIN(id_t)
+#endif
+
+#ifndef INO64_MIN
+# define INO64_MIN TYPE_MIN(ino64_t)
+#endif
+
+#ifndef INO_MIN
+# define INO_MIN TYPE_MIN(ino_t)
+#endif
+
+#ifndef KEY_MIN
+# define KEY_MIN TYPE_MIN(key_t)
+#endif
+
+#ifndef LOFF_MIN
+# define LOFF_MIN TYPE_MIN(loff_t)
+#endif
+
+#ifndef MODE_MIN
+# define MODE_MIN TYPE_MIN(mode_t)
+#endif
+
+#ifndef NLINK_MIN
+# define NLINK_MIN TYPE_MIN(nlink_t)
+#endif
+
+#ifndef OFF64_MIN
+# define OFF64_MIN TYPE_MIN(off64_t)
+#endif
+
+#ifndef OFF_MIN
+# define OFF_MIN TYPE_MIN(off_t)
+#endif
+
+#ifndef PID_MIN
+# define PID_MIN TYPE_MIN(pid_t)
+#endif
+
+#ifndef QUAD_MIN
+# define QUAD_MIN TYPE_MIN(quad_t)
+#endif
+
+#ifndef REGISTER_MIN
+# define REGISTER_MIN TYPE_MIN(register_t)
+#endif
+
+#ifndef RLIM64_MIN
+# define RLIM64_MIN TYPE_MIN(rlim64_t)
+#endif
+
+#ifndef RLIM_MIN
+# define RLIM_MIN TYPE_MIN(rlim_t)
+#endif
+
+#ifndef SOCKLEN_MIN
+# define SOCKLEN_MIN TYPE_MIN(socklen_t)
+#endif
+
+#ifndef SPEED_MIN
+# define SPEED_MIN TYPE_MAX(speed_t)
+#endif
+
+#ifndef SUSECONDS_MIN
+# define SUSECONDS_MIN TYPE_MIN(suseconds_t)
+#endif
+
+#ifndef TCFLAG_MIN
+# define TCFLAG_MIN TYPE_MAX(tcflag_t)
+#endif
+
+#ifndef TIMER_MIN
+# define TIMER_MIN TYPE_MIN(timer_t)
+#endif
+
+#ifndef TIME_MIN
+# define TIME_MIN TYPE_MIN(time_t)
+#endif
+
+#ifndef UID_MIN
+# define UID_MIN TYPE_MIN(uid_t)
+#endif
+
+#ifndef USECONDS_MIN
+# define USECONDS_MIN TYPE_MIN(useconds_t)
+#endif
+
+#ifndef U_QUAD_MIN
+# define U_QUAD_MIN TYPE_MIN(u_quad_t)
+#endif
+
+
+#define LIBSIMPLE_INTERFACE 0x0001
+#define LIBSIMPLE_NO_HOSTNAME 0x0002
+
+
+#define FREE(PTR) (free(PTR), (PTR) = NULL, 0)
+
+
+#define CLOSE(FD) ((FD) >= 0 ? (close(FD), (FD) = -1, 0) : 0)
+
+
+
+_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __nonnull__, __warn_unused_result__)))
void *libsimple_rawmemchr(const void *, int);
#ifndef rawmemchr
# define rawmemchr libsimple_rawmemchr
#endif
-_LIBSIMPLE_GCC_ONLY(__attribute__((pure, nonnull, warn_unused_result)))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __nonnull__, __warn_unused_result__)))
void *libsimple_memrchr(const void *, int, size_t);
#ifndef memrchr
# define memrchr libsimple_memrchr
#endif
-_LIBSIMPLE_GCC_ONLY(__attribute__((pure, nonnull, warn_unused_result)))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __nonnull__, __warn_unused_result__)))
void *libsimple_rawmemrchr(const void *, int, size_t);
#ifndef rawmemrchr
# define rawmemrchr libsimple_rawmemrchr
#endif
-_LIBSIMPLE_GCC_ONLY(__attribute__((pure, nonnull, warn_unused_result)))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __nonnull__, __warn_unused_result__)))
char *libsimple_strchrnul(const char *, int);
#ifndef strchrnul
# define strchrnul libsimple_strchrnul
#endif
-_LIBSIMPLE_GCC_ONLY(__attribute__((pure, nonnull, warn_unused_result)))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __nonnull__, __warn_unused_result__)))
static inline char *libsimple_strend(const char *__s) { return strchr(__s, '\0'); }
#ifndef strend
# define strend libsimple_strend
#endif
-_LIBSIMPLE_GCC_ONLY(__attribute__((pure, nonnull, warn_unused_result)))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __nonnull__, __warn_unused_result__)))
static inline int libsimple_inchrset(int __c, const char *__s) { return __c && strchr(__s, __c); }
#ifndef inchrset
# define inchrset libsimple_inchrset
#endif
-_LIBSIMPLE_GCC_ONLY(__attribute__((nonnull, warn_unused_result)))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__, __warn_unused_result__)))
void *libsimple_memdup(const void *, size_t);
#ifndef memdup
# define memdup libsimple_memdup
#endif
-_LIBSIMPLE_GCC_ONLY(__attribute__((nonnull, warn_unused_result)))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__, __warn_unused_result__)))
char *libsimple_strndup(const char *, size_t);
#ifndef strndup
# define strndup libsimple_strndup
#endif
-_LIBSIMPLE_GCC_ONLY(__attribute__((warn_unused_result)))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__)))
static inline void *libsimple_mempcpy(void *__d, const void *__s, size_t __n)
{ return &((char *)memcpy(__d, __s, __n))[__n]; }
#ifndef mempcpy
@@ -142,21 +625,21 @@ static inline void *libsimple_mempcpy(void *__d, const void *__s, size_t __n)
* @param allow_modified_nul Whether Modified UTF-8 is allowed, which allows a two-byte encoding for NUL
* @return 1 if good, 0 on encoding error
*/
-_LIBSIMPLE_GCC_ONLY(__attribute__((pure, nonnull, warn_unused_result)))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __nonnull__, __warn_unused_result__)))
int libsimple_isutf8(const char *, int);
#ifndef isutf8
# define isutf8 libsimple_isutf8
#endif
-_LIBSIMPLE_GCC_ONLY(__attribute__((nonnull(1, 2), format(printf, 2, 3))))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__(1, 2), __format__(__printf__, 2, 3))))
int libsimple_asprintf(char **, const char *, ...);
#ifndef asprintf
# define asprintf libsimple_asprintf
#endif
-_LIBSIMPLE_GCC_ONLY(__attribute__((nonnull(1, 2))))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__(1, 2))))
int libsimple_vasprintf(char **, const char *, va_list);
#ifndef vasprintf
# define vasprintf libsimple_vasprintf
@@ -210,62 +693,70 @@ int libsimple_vasprintf(char **, const char *, va_list);
#endif
-_LIBSIMPLE_GCC_ONLY(__attribute__((pure, warn_unused_result)))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __warn_unused_result__)))
void *libsimple_memmem(const void *, size_t, const void *, size_t);
#ifndef memmem
# define memmem libsimple_memmem
#endif
-_LIBSIMPLE_GCC_ONLY(__attribute__((pure, warn_unused_result)))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __warn_unused_result__)))
int libsimple_memstarts(const void *, size_t, const void *, size_t);
#ifndef memstarts
# define memstarts libsimple_memstarts
#endif
-_LIBSIMPLE_GCC_ONLY(__attribute__((pure, warn_unused_result)))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __warn_unused_result__)))
int libsimple_memends(const void *, size_t, const void *, size_t);
#ifndef memends
# define memends libsimple_memends
#endif
-_LIBSIMPLE_GCC_ONLY(__attribute__((pure, nonnull, warn_unused_result)))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __nonnull__, __warn_unused_result__)))
int libsimple_strstarts(const char *, const char *);
#ifndef strstarts
# define strstarts libsimple_strstarts
#endif
-_LIBSIMPLE_GCC_ONLY(__attribute__((pure, nonnull, warn_unused_result)))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __nonnull__, __warn_unused_result__)))
int libsimple_strends(const char *, const char *);
#ifndef strends
# define strends libsimple_strends
#endif
-_LIBSIMPLE_GCC_ONLY(__attribute__((pure, nonnull, warn_unused_result)))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __nonnull__, __warn_unused_result__)))
char *libsimple_strcasestr(const char *, const char *);
#ifndef strcasestr
# define strcasestr libsimple_strcasestr
#endif
+_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __nonnull__, __warn_unused_result__)))
+static inline int streq(const char *__a, const char *__b) { return !strcmp(__a, __b); }
+
+
+_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __nonnull__, __warn_unused_result__)))
+static inline int strneq(const char *__a, const char *__b, size_t __n) { return !strncmp(__a, __b, __n); }
+
+
#define malloczn(CLEAR, ...) _libsimple_malloczn((CLEAR), __VA_ARGS__, (size_t)0)
#define mallocn(...) malloczn(0, __VA_ARGS__)
#define callocn(...) malloczn(1, __VA_ARGS__)
-_LIBSIMPLE_GCC_ONLY(__attribute__((warn_unused_result)))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__)))
void *libsimple_vmalloczn(int, size_t, va_list);
-_LIBSIMPLE_GCC_ONLY(__attribute__((warn_unused_result)))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__)))
static inline void *libsimple_vmallocn(size_t __n, va_list __ap) { return libsimple_vmalloczn(0, __n, __ap); }
-_LIBSIMPLE_GCC_ONLY(__attribute__((warn_unused_result)))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__)))
static inline void *libsimple_vcallocn(size_t __n, va_list __ap) { return libsimple_vmalloczn(1, __n, __ap); }
-_LIBSIMPLE_GCC_ONLY(__attribute__((warn_unused_result)))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__)))
static inline void *
libsimple_malloczn(int __clear, size_t __n, ...)
{
@@ -275,7 +766,7 @@ libsimple_malloczn(int __clear, size_t __n, ...)
va_end(__ap);
}
-_LIBSIMPLE_GCC_ONLY(__attribute__((warn_unused_result)))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__)))
static inline void *
libsimple_mallocn(size_t __n, ...)
{
@@ -285,7 +776,7 @@ libsimple_mallocn(size_t __n, ...)
va_end(__ap);
}
-_LIBSIMPLE_GCC_ONLY(__attribute__((warn_unused_result)))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__)))
static inline void *
libsimple_callocn(size_t __n, ...)
{
@@ -297,10 +788,10 @@ libsimple_callocn(size_t __n, ...)
#define reallocn(PTR, ...) _libsimple_reallocn((PTR), __VA_ARGS__, (size_t)0)
-_LIBSIMPLE_GCC_ONLY(__attribute__((warn_unused_result)))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__)))
void *libsimple_vreallocn(void *, size_t, va_list);
-_LIBSIMPLE_GCC_ONLY(__attribute__((warn_unused_result)))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__)))
static inline void *
libsimple_reallocn(void *__ptr, size_t __n, ...)
{
@@ -311,22 +802,22 @@ libsimple_reallocn(void *__ptr, size_t __n, ...)
}
-_LIBSIMPLE_GCC_ONLY(__attribute__((warn_unused_result, returns_nonnull)))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__, __returns_nonnull__)))
void *enmalloc(int, size_t);
-_LIBSIMPLE_GCC_ONLY(__attribute__((warn_unused_result, returns_nonnull)))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__, __returns_nonnull__)))
void *encalloc(int, size_t, size_t);
-_LIBSIMPLE_GCC_ONLY(__attribute__((warn_unused_result, returns_nonnull)))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__, __returns_nonnull__)))
void *enrealloc(int, void *, size_t);
-_LIBSIMPLE_GCC_ONLY(__attribute__((nonnull, warn_unused_result, returns_nonnull)))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__, __warn_unused_result__, __returns_nonnull__)))
char *enstrdup(int, const char *);
-_LIBSIMPLE_GCC_ONLY(__attribute__((nonnull, warn_unused_result, returns_nonnull)))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__, __warn_unused_result__, __returns_nonnull__)))
char *enstrndup(int, const char *, size_t);
-_LIBSIMPLE_GCC_ONLY(__attribute__((warn_unused_result, returns_nonnull)))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__, __returns_nonnull__)))
void *enmemdup(int, const void *, size_t);
#define enmalloczn(STATUS, CLEAR, ...) _libsimple_enmalloczn((STATUS), (CLEAR), __VA_ARGS__, (size_t)0)
@@ -334,19 +825,19 @@ void *enmemdup(int, const void *, size_t);
#define encallocn(STATUS, ...) _libsimple_encallocn((STATUS), (CLEAR), __VA_ARGS__, (size_t)0)
#define enreallocn(STATUS, PTR, ...) _libsimple_enreallocn((STATUS), (PTR), __VA_ARGS__, (size_t)0)
-_LIBSIMPLE_GCC_ONLY(__attribute__((warn_unused_result, returns_nonnull)))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__, __returns_nonnull__)))
void *libsimple_envmalloczn(int, int, size_t, va_list);
-_LIBSIMPLE_GCC_ONLY(__attribute__((warn_unused_result, returns_nonnull)))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__, __returns_nonnull__)))
void *libsimple_envreallocn(int, void *, size_t, va_list);
-_LIBSIMPLE_GCC_ONLY(__attribute__((warn_unused_result, returns_nonnull)))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__, __returns_nonnull__)))
static inline void *libsimple_envmallocn(int __st, size_t __n, va_list __ap) { return libsimple_envmalloczn(__st, 0, __n, __ap); }
-_LIBSIMPLE_GCC_ONLY(__attribute__((warn_unused_result, returns_nonnull)))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__, __returns_nonnull__)))
static inline void *libsimple_envcallocn(int __st, size_t __n, va_list __ap) { return libsimple_envmalloczn(__st, 1, __n, __ap); }
-_LIBSIMPLE_GCC_ONLY(__attribute__((warn_unused_result, returns_nonnull)))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__, __returns_nonnull__)))
static inline void *
libsimple_enmalloczn(int __status, int __clear, size_t __n, ...)
{
@@ -356,7 +847,7 @@ libsimple_enmalloczn(int __status, int __clear, size_t __n, ...)
va_end(__ap);
}
-_LIBSIMPLE_GCC_ONLY(__attribute__((warn_unused_result, returns_nonnull)))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__, __returns_nonnull__)))
static inline void *
libsimple_enmallocn(int __status, size_t __n, ...)
{
@@ -366,7 +857,7 @@ libsimple_enmallocn(int __status, size_t __n, ...)
va_end(__ap);
}
-_LIBSIMPLE_GCC_ONLY(__attribute__((warn_unused_result, returns_nonnull)))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__, __returns_nonnull__)))
static inline void *
libsimple_encallocn(int __status, size_t __n, ...)
{
@@ -376,7 +867,7 @@ libsimple_encallocn(int __status, size_t __n, ...)
va_end(__ap);
}
-_LIBSIMPLE_GCC_ONLY(__attribute__((warn_unused_result, returns_nonnull)))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__, __returns_nonnull__)))
static inline void *
libsimple_enreallocn(int __status, void *__ptr, size_t __n, ...)
{
@@ -387,22 +878,22 @@ libsimple_enreallocn(int __status, void *__ptr, size_t __n, ...)
}
-_LIBSIMPLE_GCC_ONLY(__attribute__((warn_unused_result, returns_nonnull)))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__, __returns_nonnull__)))
static inline void *emalloc(size_t __n) { return enmalloc(libsimple_default_failure_exit, __n); }
-_LIBSIMPLE_GCC_ONLY(__attribute__((warn_unused_result, returns_nonnull)))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__, __returns_nonnull__)))
static inline void *ecalloc(size_t __n, size_t __m) { return encalloc(libsimple_default_failure_exit, __n, __m); }
-_LIBSIMPLE_GCC_ONLY(__attribute__((warn_unused_result, returns_nonnull)))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__, __returns_nonnull__)))
static inline void *erealloc(void *__ptr, size_t __n) { return enrealloc(libsimple_default_failure_exit, __ptr, __n); }
-_LIBSIMPLE_GCC_ONLY(__attribute__((nonnull, warn_unused_result, returns_nonnull)))
+_LIBSIMPLE_GCC_ONLY(__attribute__((nonnull, __warn_unused_result__, __returns_nonnull__)))
static inline char *estrdup(const char *__s) { return enstrdup(libsimple_default_failure_exit, __s); }
-_LIBSIMPLE_GCC_ONLY(__attribute__((nonnull, warn_unused_result, returns_nonnull)))
+_LIBSIMPLE_GCC_ONLY(__attribute__((nonnull, __warn_unused_result__, __returns_nonnull__)))
static inline char *estrndup(const char *__s, size_t __n) { return enstrndup(libsimple_default_failure_exit, __s, __n); }
-_LIBSIMPLE_GCC_ONLY(__attribute__((warn_unused_result, returns_nonnull)))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__, __returns_nonnull__)))
static inline void *ememdup(const void *__s, size_t __n) { return enmemdup(libsimple_default_failure_exit, __s, __n); }
#define emalloczn(CLEAR, ...) enmalloczn(libsimple_default_failure_exit, (CLEAR), __VA_ARGS__)
@@ -410,23 +901,23 @@ static inline void *ememdup(const void *__s, size_t __n) { return enmemdup(libsi
#define ecallocn(...) encallocn(libsimple_default_failure_exit, __VA_ARGS__)
#define ereallocn(PTR, ...) enreallocn(libsimple_default_failure_exit, (PTR), __VA_ARGS__)
-_LIBSIMPLE_GCC_ONLY(__attribute__((warn_unused_result, returns_nonnull)))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__, __returns_nonnull__)))
static inline void *libsimple_evmalloczn(int __clear, size_t __n, va_list __ap)
{ return libsimple_envmalloczn(libsimple_default_failure_exit, __clear, __n, __ap); }
-_LIBSIMPLE_GCC_ONLY(__attribute__((warn_unused_result, returns_nonnull)))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__, __returns_nonnull__)))
static inline void *libsimple_evmallocn(size_t __n, va_list __ap)
{ return libsimple_envcallocn(libsimple_default_failure_exit, __n, __ap); }
-_LIBSIMPLE_GCC_ONLY(__attribute__((warn_unused_result, returns_nonnull)))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__, __returns_nonnull__)))
static inline void *libsimple_evcallocn(size_t __n, va_list __ap)
{ return libsimple_envmallocn(libsimple_default_failure_exit, __n, __ap); }
-_LIBSIMPLE_GCC_ONLY(__attribute__((warn_unused_result, returns_nonnull)))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__, __returns_nonnull__)))
static inline void *libsimple_evreallocn(void *__ptr, size_t __n, va_list __ap)
{ return libsimple_envreallocn(libsimple_default_failure_exit, __ptr, __n, __ap); }
-_LIBSIMPLE_GCC_ONLY(__attribute__((warn_unused_result, returns_nonnull)))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__, __returns_nonnull__)))
static inline void *
libsimple_emalloczn(int __c, size_t __n, ...)
{
@@ -436,7 +927,7 @@ libsimple_emalloczn(int __c, size_t __n, ...)
va_end(__ap);
}
-_LIBSIMPLE_GCC_ONLY(__attribute__((warn_unused_result, returns_nonnull)))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__, __returns_nonnull__)))
static inline void *
libsimple_emallocn(size_t __n, ...)
{
@@ -446,7 +937,7 @@ libsimple_emallocn(size_t __n, ...)
va_end(__ap);
}
-_LIBSIMPLE_GCC_ONLY(__attribute__((warn_unused_result, returns_nonnull)))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__, __returns_nonnull__)))
static inline void *
libsimple_ecallocn(size_t __n, ...)
{
@@ -456,7 +947,7 @@ libsimple_ecallocn(size_t __n, ...)
va_end(__ap);
}
-_LIBSIMPLE_GCC_ONLY(__attribute__((warn_unused_result, returns_nonnull)))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__, __returns_nonnull__)))
static inline void *
libsimple_ereallocn(void *__p, size_t __n, ...)
{
@@ -467,7 +958,13 @@ libsimple_ereallocn(void *__p, size_t __n, ...)
}
-_LIBSIMPLE_GCC_ONLY(__attribute__((nonnull)))
+/**
+ * Read an environment variable, but handle it as undefined if empty
+ *
+ * @param var The environment variable's name
+ * @return The environment variable's value, `NULL` if empty or not defined
+ */
+_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__)))
static inline char *
getenv_ne(const char *__name)
{
@@ -476,13 +973,13 @@ getenv_ne(const char *__name)
}
-_LIBSIMPLE_GCC_ONLY(__attribute__((nonnull)))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__)))
int vputenvf(const char *, va_list);
-_LIBSIMPLE_GCC_ONLY(__attribute__((nonnull)))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__)))
void envputenvf(int, const char *, va_list);
-_LIBSIMPLE_GCC_ONLY(__attribute__((nonnull, format(printf, 1, 2))))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__, __format__(__printf__, 1, 2))))
static inline int
putenvf(const char *__fmt, ...)
{
@@ -492,7 +989,7 @@ putenvf(const char *__fmt, ...)
va_end(__ap);
}
-_LIBSIMPLE_GCC_ONLY(__attribute__((nonnull, format(printf, 1, 2))))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__, __format__(__printf__, 1, 2))))
static inline void
eputenvf(const char *__fmt, ...)
{
@@ -502,14 +999,14 @@ eputenvf(const char *__fmt, ...)
va_end(__ap);
}
-_LIBSIMPLE_GCC_ONLY(__attribute__((nonnull)))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__)))
static inline void
evputenvf(const char *__fmt, va_list __ap)
{
envputenvf(libsimple_default_failure_exit, __fmt, __ap);
}
-_LIBSIMPLE_GCC_ONLY(__attribute__((nonnull, format(printf, 2, 3))))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__, __format__(__printf__, 2, 3))))
static inline void
enputenvf(int __status, const char *__fmt, ...)
{
@@ -521,10 +1018,10 @@ enputenvf(int __status, const char *__fmt, ...)
-_LIBSIMPLE_GCC_ONLY(__attribute__((nonnull(1))))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__(1))))
void vweprintf(const char *, va_list);
-_LIBSIMPLE_GCC_ONLY(__attribute__((nonnull(1), format(printf, 1, 2), noreturn)))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__(1), __format__(__printf__, 1, 2), __noreturn__)))
static inline void
eprintf(const char *__fmt, ...)
{
@@ -535,7 +1032,7 @@ eprintf(const char *__fmt, ...)
exit(libsimple_default_failure_exit);
}
-_LIBSIMPLE_GCC_ONLY(__attribute__((nonnull(1), noreturn)))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__(1), __noreturn__)))
static inline void
veprintf(const char *__fmt, va_list __ap)
{
@@ -543,7 +1040,7 @@ veprintf(const char *__fmt, va_list __ap)
exit(libsimple_default_failure_exit);
}
-_LIBSIMPLE_GCC_ONLY(__attribute__((nonnull(2), format(printf, 2, 3), noreturn)))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__(2), __format__(__printf__, 2, 3), __noreturn__)))
static inline void
enprintf(int __status, const char *__fmt, ...)
{
@@ -554,7 +1051,7 @@ enprintf(int __status, const char *__fmt, ...)
exit(__status);
}
-_LIBSIMPLE_GCC_ONLY(__attribute__((nonnull(2), noreturn)))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__(2), __noreturn__)))
static inline void
venprintf(int __status, const char *__fmt, va_list __ap)
{
@@ -562,7 +1059,7 @@ venprintf(int __status, const char *__fmt, va_list __ap)
exit(__status);
}
-_LIBSIMPLE_GCC_ONLY(__attribute__((nonnull(1), format(printf, 1, 2))))
+_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__(1), __format__(__printf__, 1, 2))))
static inline void
weprintf(const char *__fmt, ...)
{
@@ -573,4 +1070,214 @@ weprintf(const char *__fmt, ...)
}
+int libsimple_sendfd(int, int);
+#ifndef sendfd
+# define sendfd libsimple_sendfd
+#endif
+
+
+_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__)))
+int libsimple_recvfd(int);
+#ifndef recvfd
+# define recvfd libsimple_recvfd
+#endif
+
+
+
+_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__)))
+ssize_t libsimple_recvfrom_timestamped(int, void *restrict, size_t, int, struct sockaddr *restrict,
+ socklen_t, struct timespec *restrict);
+#ifndef recvfrom_timestamped
+# define recvfrom_timestamped libsimple_recvfrom_timestamped
+#endif
+
+
+_LIBSIMPLE_GCC_ONLY(__attribute__((__warn_unused_result__)))
+static inline ssize_t
+libsimple_recv_timestamped(int __fd, void *restrict __buf, size_t __n,
+ int __flags, struct timespec *restrict __ts)
+{
+ return libsimple_recvfrom_timestamped(__fd, __buf, __n, __flags, NULL, 0, __ts);
+}
+#ifndef recv_timestamped
+# define recv_timestamped libsimple_recv_timestamped
+#endif
+
+
+_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__)))
+int libsimple_sumtimespec(struct timespec *, const struct timespec *, const struct timespec *);
+#ifndef sumtimespec
+# define sumtimespec libsimple_sumtimespec
+#endif
+
+
+_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__)))
+int libsimple_difftimespec(struct timespec *, const struct timespec *, const struct timespec *);
+#ifndef difftimespec
+# define difftimespec libsimple_difftimespec
+#endif
+
+
+_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__)))
+int libsimple_multimespec(struct timespec *, const struct timespec *, int);
+#ifndef multimespec
+# define multimespec libsimple_multimespec
+#endif
+
+
+_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__, __warn_unused_result__)))
+static inline int
+libsimple_cmptimespec(const struct timespec *__a, const struct timespec *__b)
+{
+ if (__a->tv_sec != __b->tv_sec)
+ return __a->tv_sec < __b->tv_sec ? -1 : +1;
+ return __a->tv_nsec < __b->tv_nsec ? -1 : __a->tv_nsec > __b->tv_nsec;
+}
+#ifndef cmptimespec
+# define cmptimespec libsimple_cmptimespec
+#endif
+
+
+_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__)))
+int libsimple_sumtimeval(struct timeval *, const struct timeval *, const struct timeval *);
+#ifndef sumtimeval
+# define sumtimeval libsimple_sumtimeval
+#endif
+
+
+_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__)))
+int libsimple_difftimeval(struct timeval *, const struct timeval *, const struct timeval *);
+#ifndef difftimeval
+# define difftimeval libsimple_difftimeval
+#endif
+
+
+_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__)))
+int libsimple_multimeval(struct timeval *, const struct timeval *, int);
+#ifndef multimeval
+# define multimeval libsimple_multimeval
+#endif
+
+
+_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__, __warn_unused_result__)))
+static inline int
+libsimple_cmptimeval(const struct timeval *__a, const struct timeval *__b)
+{
+ if (__a->tv_sec != __b->tv_sec)
+ return __a->tv_sec < __b->tv_sec ? -1 : +1;
+ return __a->tv_usec < __b->tv_usec ? -1 : __a->tv_usec > __b->tv_usec;
+}
+#ifndef cmptimeval
+# define cmptimeval libsimple_cmptimeval
+#endif
+
+
+_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__)))
+static inline void
+libsimple_timeval2timespec(struct timespec *restrict __ts, const struct timeval *restrict __tv)
+{
+ __ts->tv_sec = __tv->tv_sec;
+ __ts->tv_nsec = __tv->tv_usec;
+ __ts->tv_nsec *= 1000L;
+}
+#ifndef timeval2timespec
+# define timeval2timespec libsimple_timeval2timespec
+#endif
+
+
+_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__)))
+int libsimple_timespec2timeval(struct timeval *restrict, const struct timespec *restrict);
+#ifndef timespec2timeval
+# define timespec2timeval libsimple_timespec2timeval
+#endif
+
+
+_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__(1, 2))))
+int libsimple_strtotimespec(struct timespec *restrict, const char *restrict, char **restrict);
+#ifndef strtotimespec
+# define strtotimespec libsimple_strtotimespec
+#endif
+
+
+_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__(1, 2))))
+int libsimple_strtotimeval(struct timeval *restrict, const char *restrict, char **restrict);
+#ifndef strtotimeval
+# define strtotimeval libsimple_strtotimeval
+#endif
+
+
+_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__(2))))
+char *libsimple_timespectostr(char *restrict, const struct timespec *restrict);
+#ifndef timespectostr
+# define timespectostr libsimple_timespectostr
+#endif
+
+
+_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__(2))))
+char *libsimple_timevaltostr(char *restrict, const struct timeval *restrict);
+#ifndef timevaltostr
+# define timevaltostr libsimple_timevaltostr
+#endif
+
+
+_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__)))
+static inline double
+libsimple_timespectodouble(const struct timespec *__ts)
+{
+ double __ret = (double)(__ts->tv_nsec);
+ __ret /= (double)1000000000L;
+ __ret += (double)(__ts->tv_sec);
+ return __ret;
+}
+#ifndef timespectodouble
+# define timespectodouble libsimple_timespectodouble
+#endif
+
+
+_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__)))
+static inline double
+libsimple_timevaltodouble(const struct timeval *__tv)
+{
+ double __ret = (double)(__tv->tv_usec);
+ __ret /= (double)1000000L;
+ __ret += (double)(__tv->tv_sec);
+ return __ret;
+}
+#ifndef timevaltodouble
+# define timevaltodouble libsimple_timevaltodouble
+#endif
+
+
+_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__)))
+void libsimple_doubletotimespec(struct timespec *, double);
+#ifndef doubletotimespec
+# define doubletotimespec libsimple_doubletotimespec
+#endif
+
+
+_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__)))
+void libsimple_doubletotimeval(struct timeval *, double);
+#ifndef doubletotimeval
+# define doubletotimeval libsimple_doubletotimeval
+#endif
+
+
+#define LIBSIMPLE_UNLIST(LIST, I, NP) libsimple_unlist((LIST), (I), (NP), sizeof(*(LIST)))
+#ifndef UNLIST
+# define UNLIST(LIST, I, NP) libsimple_unlist((LIST), (I), (NP), sizeof(*(LIST)))
+#endif
+
+
+_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__)))
+static inline void
+libsimple_unlist(void *__list, size_t __i, size_t *__np, size_t __width)
+{
+ char *__lst = __list;
+ memmove(&__lst[__i * __width], &__lst[(__i + 1) * __width], (--*__np - __i) * __width);
+}
+#ifndef unlist
+# define unlist libsimple_unlist
+#endif
+
+
#endif