diff options
Diffstat (limited to 'src')
853 files changed, 19363 insertions, 0 deletions
diff --git a/src/etc/leapsecs.dat b/src/etc/leapsecs.dat Binary files differnew file mode 100644 index 0000000..86a9a90 --- /dev/null +++ b/src/etc/leapsecs.dat diff --git a/src/headers/error-addrinuse b/src/headers/error-addrinuse new file mode 100644 index 0000000..6f1e4fe --- /dev/null +++ b/src/headers/error-addrinuse @@ -0,0 +1,3 @@ + +/* BSD sucks */ +#define error_isalready(e) (((e) == EALREADY) || ((e) == EINPROGRESS) || ((e) == EADDRINUSE)) diff --git a/src/headers/error-already b/src/headers/error-already new file mode 100644 index 0000000..ac6b8a7 --- /dev/null +++ b/src/headers/error-already @@ -0,0 +1 @@ +#define error_isalready(e) (((e) == EALREADY) || ((e) == EINPROGRESS)) diff --git a/src/headers/error-footer b/src/headers/error-footer new file mode 100644 index 0000000..ddd5dae --- /dev/null +++ b/src/headers/error-footer @@ -0,0 +1,2 @@ + +#endif diff --git a/src/headers/error-header b/src/headers/error-header new file mode 100644 index 0000000..b891b6b --- /dev/null +++ b/src/headers/error-header @@ -0,0 +1,12 @@ +/* ISC license. */ + +#ifndef ERROR_H +#define ERROR_H + +#include <errno.h> +#include <skalibs/gccattributes.h> + +extern char const *error_str (int) gccattr_const ; +extern int error_temp (int) gccattr_const ; + +#define error_isagain(e) (((e) == EAGAIN) || ((e) == EWOULDBLOCK)) diff --git a/src/headers/error-proto b/src/headers/error-proto new file mode 100644 index 0000000..fd0c01d --- /dev/null +++ b/src/headers/error-proto @@ -0,0 +1,3 @@ + +/* Did I ever mention that BSD sucks ? */ +#define EPROTO EPROTOTYPE diff --git a/src/headers/gidstuff-16 b/src/headers/gidstuff-16 new file mode 100644 index 0000000..491de89 --- /dev/null +++ b/src/headers/gidstuff-16 @@ -0,0 +1,7 @@ +#include <skalibs/uint16.h> + +#define GID_FMT UINT16_FMT +#define gid_fmt(s, u) uint16_fmt(s, u) +#define gid_scan(s, u) uint16_scan(s, u) +#define gid_fmtlist(s, tab, n) uint16_fmtlist(s, tab, n) +#define gid_scanlist(tab, max, s, num) uint16_scanlist(tab, max, s, num) diff --git a/src/headers/gidstuff-32 b/src/headers/gidstuff-32 new file mode 100644 index 0000000..a8ed0e8 --- /dev/null +++ b/src/headers/gidstuff-32 @@ -0,0 +1,7 @@ +#include <skalibs/uint32.h> + +#define GID_FMT UINT32_FMT +#define gid_fmt(s, u) uint32_fmt(s, u) +#define gid_scan(s, u) uint32_scan(s, u) +#define gid_fmtlist(s, tab, n) uint32_fmtlist(s, tab, n) +#define gid_scanlist(tab, max, s, num) uint32_scanlist(tab, max, s, num) diff --git a/src/headers/gidstuff-64 b/src/headers/gidstuff-64 new file mode 100644 index 0000000..3d441e6 --- /dev/null +++ b/src/headers/gidstuff-64 @@ -0,0 +1,7 @@ +#include <skalibs/uint64.h> + +#define GID_FMT UINT64_FMT +#define gid_fmt(s, u) uint64_fmt(s, u) +#define gid_scan(s, u) uint64_scan(s, u) +#define gid_fmtlist(s, tab, n) uint64_fmtlist(s, tab, n) +#define gid_scanlist(tab, max, s, num) uint64_scanlist(tab, max, s, num) diff --git a/src/headers/gidstuff-footer b/src/headers/gidstuff-footer new file mode 100644 index 0000000..ddd5dae --- /dev/null +++ b/src/headers/gidstuff-footer @@ -0,0 +1,2 @@ + +#endif diff --git a/src/headers/gidstuff-header b/src/headers/gidstuff-header new file mode 100644 index 0000000..73bf86b --- /dev/null +++ b/src/headers/gidstuff-header @@ -0,0 +1,5 @@ +/* ISC license. */ + +#ifndef GIDSTUFF_H +#define GIDSTUFF_H + diff --git a/src/headers/ip46-footer b/src/headers/ip46-footer new file mode 100644 index 0000000..4340daf --- /dev/null +++ b/src/headers/ip46-footer @@ -0,0 +1,10 @@ + +#define ip46_from_ip(i, s, h) ((h) ? ip46_from_ip6(i, s) : ip46_from_ip4(i, s)) + +#define socket_recvnb46_g(fd, buf, len, i, port, deadline) socket_recvnb46(fd, buf, len, i, port, (deadline), &STAMP) +#define socket_sendnb46_g(fd, buf, len, i, port, deadline) socket_sendnb46(fd, buf, len, i, port, (deadline), &STAMP) + +extern int socket_deadlineconnstamp46 (int, ip46_t const *, uint16, tain_t const *, tain_t *) ; +#define socket_deadlineconnstamp46_g(fd, ip, port, deadline) socket_deadlineconnstamp46(fd, ip, port, (deadline), &STAMP) + +#endif diff --git a/src/headers/ip46-header b/src/headers/ip46-header new file mode 100644 index 0000000..4f0cf8c --- /dev/null +++ b/src/headers/ip46-header @@ -0,0 +1,34 @@ +/* ISC license. */ + +#ifndef IP46_H +#define IP46_H + +#include <errno.h> +#include <skalibs/uint16.h> +#include <skalibs/bytestr.h> +#include <skalibs/fmtscan.h> +#include <skalibs/tai.h> +#include <skalibs/socket.h> + +#define IP46_FMT IP6_FMT +#define IP4_ANY "\0\0\0" +#define IP6_ANY "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" +#define IP4_LOCAL "\177\0\0\1" +#define IP6_LOCAL "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1" + +typedef struct ip46full_s ip46full_t, *ip46full_t_ref ; + +struct ip46full_s +{ + char ip[16] ; + unsigned int is6: 1 ; +} ; +#define IP46FULL_ZERO { .ip = IP6_ANY, .is6 = 0 } + +#define ip46full_is6(i) ((i)->is6) +#define ip46full_fmt(s, i) ((i)->is6 ? ip6_fmt(s, (i)->ip) : ip4_fmt(s, (i)->ip)) +extern unsigned int ip46full_scan (char const *, ip46full_t_ref) ; +extern unsigned int ip46full_scanlist (ip46full_t_ref, unsigned int, char const *, unsigned int *) ; +#define ip46full_from_ip4(i, ip4) (byte_copy((i)->ip, 4, ip4), byte_zero((i)->ip + 4, 12), (i)->is6 = 0) +#define ip46full_from_ip6(i, ip6) (byte_copy((i)->ip, 16, ip6), (i)->is6 = 1) + diff --git a/src/headers/ip46-with b/src/headers/ip46-with new file mode 100644 index 0000000..0cd3d19 --- /dev/null +++ b/src/headers/ip46-with @@ -0,0 +1,24 @@ +typedef ip46full_t ip46_t, *ip46_t_ref ; +#define IP46_ZERO IP46FULL_ZERO + +#define SKALIBS_IPV6_ENABLED +#define SKALIBS_IP_SIZE 16 +#define ip46_is6(i) ip46full_is6(i) +#define ip46_fmt(s, i) ip46full_fmt(s, i) +#define ip46_scan(s, i) ip46full_scan(s, i) +#define ip46_scanlist(out, max, s, num) ip46full_scanlist(out, max, s, num) +#define ip46_from_ip4(i, ip4) (ip46full_from_ip4(i, ip4), 1) +#define ip46_from_ip6(i, ip6) (ip46full_from_ip6(i, ip6), 1) + +#define socket_connect46(s, i, port) ((i)->is6 ? socket_connect6(s, (i)->ip, port) : socket_connect4(s, (i)->ip, port)) +#define socket_bind46(s, i, port) ((i)->is6 ? socket_bind6(s, (i)->ip, port) : socket_bind4(s, (i)->ip, port)) +#define socket_bind46_reuse(s, i, port) ((i)->is6 ? socket_bind6_reuse(s, (i)->ip, port) : socket_bind4_reuse(s, (i)->ip, port)) +#define socket_tcp46(h) ((h) ? socket_tcp6() : socket_tcp4()) +#define socket_udp46(h) ((h) ? socket_udp6() : socket_udp4()) +#define socket_recv46(fd, s, len, i, port) ((i)->is6 ? socket_recv6(fd, s, len, (i)->ip, port) : socket_recv4(fd, s, len, (i)->ip, port)) +#define socket_send46(fd, s, len, i, port) ((i)->is6 ? socket_send6(fd, s, len, (i)->ip, port) : socket_send4(fd, s, len, (i)->ip, port)) +extern int socket_local46 (int, ip46_t_ref, uint16 *) ; +extern int socket_remote46 (int, ip46_t_ref, uint16 *) ; + +#define socket_recvnb46(fd, buf, len, i, port, deadline, stamp) ((i)->is6 ? socket_recvnb6(fd, buf, len, (i)->ip, port, deadline, stamp) : socket_recvnb4(fd, buf, len, (i)->ip, port, deadline, stamp)) +#define socket_sendnb46(fd, buf, len, i, port, deadline, stamp) ((i)->is6 ? socket_sendnb6(fd, buf, len, (i)->ip, port, deadline, stamp) : socket_sendnb4(fd, buf, len, (i)->ip, port, deadline, stamp)) diff --git a/src/headers/ip46-without b/src/headers/ip46-without new file mode 100644 index 0000000..7887482 --- /dev/null +++ b/src/headers/ip46-without @@ -0,0 +1,28 @@ +typedef struct ip46_s ip46_t, *ip46_t_ref ; +struct ip46_s +{ + char ip[4] ; +} ; +#define IP46_ZERO { .ip = "\0\0\0" } + +#undef SKALIBS_IPV6_ENABLED +#define SKALIBS_IP_SIZE 4 +#define ip46_is6(ip) 0 +#define ip46_fmt(s, i) ip4_fmt(s, (i)->ip) +#define ip46_scan(s, i) ip4_scan(s, (i)->ip) +#define ip46_scanlist(out, max, s, num) ip4_scanlist((out)->ip, max, s, num) +#define ip46_from_ip4(i, ip4) (byte_copy((i)->ip, 4, ip4), 1) +#define ip46_from_ip6(i, ip6) (errno = ENOSYS, 0) + +#define socket_connect46(s, i, port) socket_connect4(s, (i)->ip, port) +#define socket_bind46(s, i, port) socket_bind4(s, (i)->ip, port) +#define socket_bind46_reuse(s, i, port) socket_bind4_reuse(s, (i)->ip, port) +#define socket_tcp46(h) socket_tcp4() +#define socket_udp46(h) socket_udp4() +#define socket_recv46(fd, s, len, i, port) socket_recv4(fd, s, len, (i)->ip, port) +#define socket_send46(fd, s, len, i, port) socket_send4(fd, s, len, (i)->ip, port) +#define socket_local46(fd, i, port) socket_local4(fd, (i)->ip, port) +#define socket_remote46(fd, i, port) socket_remote4(fd, (i)->ip, port) + +#define socket_recvnb46(fd, buf, len, i, port, deadline, stamp) socket_recvnb4(fd, buf, len, (i)->ip, port, deadline, stamp) +#define socket_sendnb46(fd, buf, len, i, port, deadline, stamp) socket_sendnb4(fd, buf, len, (i)->ip, port, deadline, stamp) diff --git a/src/headers/setgroups-footer b/src/headers/setgroups-footer new file mode 100644 index 0000000..ddd5dae --- /dev/null +++ b/src/headers/setgroups-footer @@ -0,0 +1,2 @@ + +#endif diff --git a/src/headers/setgroups-header b/src/headers/setgroups-header new file mode 100644 index 0000000..0b8697a --- /dev/null +++ b/src/headers/setgroups-header @@ -0,0 +1,5 @@ +/* ISC license. */ + +#ifndef SETGROUPS_H +#define SETGROUPS_H + diff --git a/src/headers/setgroups-stub b/src/headers/setgroups-stub new file mode 100644 index 0000000..3c54861 --- /dev/null +++ b/src/headers/setgroups-stub @@ -0,0 +1,2 @@ +#include <errno.h> +#define setgroups(n, s) (errno = ENOSYS, -1) diff --git a/src/headers/uint-16 b/src/headers/uint-16 new file mode 100644 index 0000000..85434db --- /dev/null +++ b/src/headers/uint-16 @@ -0,0 +1,34 @@ +#include <skalibs/uint16.h> + +#define UINT_PACK 2 +#define uint_pack uint16_pack +#define uint_pack_big uint16_pack_big +#define uint_unpack(s, u) uint16_unpack(s, (uint16 *)(char *)(u)) +#define uint_unpack_big(s, u) uint16_unpack_big(s, (uint16 *)(char *)(u)) + +#define uint_reverse uint16_reverse +#define uint_big_endian uint16_big_endian +#define uint_little_endian uint16_little_endian + +#define UINT_FMT UINT16_FMT +#define UINT_OFMT UINT16_OFMT +#define UINT_XFMT UINT16_XFMT +#define UINT_BFMT UINT16_BFMT + +#define uint_fmt_base uint16_fmt_base +#define uint0_fmt_base uint160_fmt_base +#define uint_fmt uint16_fmt +#define uint0_fmt uint160_fmt +#define uint_ofmt uint16_ofmt +#define uint0_ofmt uint160_ofmt +#define uint_xfmt uint16_xfmt +#define uint0_xfmt uint160_xfmt +#define uint_bfmt uint16_bfmt +#define uint0_bfmt uint160_bfmt + +#define uint_fmtlist(s, tab, n) uint16_fmtlist(s, tab, n) + +#define uint_scan_base(s, u, b) uint16_scan_base(s, (uint16 *)(char *)(u), b) +#define uint0_scan_base(s, u, b) uint160_scan_base(s, (uint16 *)(char *)(u), b) + +#define uint_scanlist(tab, max, s, num) uint16_scanlist(tab, max, s, num) diff --git a/src/headers/uint-32 b/src/headers/uint-32 new file mode 100644 index 0000000..32c6600 --- /dev/null +++ b/src/headers/uint-32 @@ -0,0 +1,34 @@ +#include <skalibs/uint32.h> + +#define UINT_PACK 4 +#define uint_pack uint32_pack +#define uint_pack_big uint32_pack_big +#define uint_unpack(s, u) uint32_unpack(s, (uint32 *)(char *)(u)) +#define uint_unpack_big(s, u) uint32_unpack_big(s, (uint32 *)(char *)(u)) + +#define uint_reverse uint32_reverse +#define uint_big_endian uint32_big_endian +#define uint_little_endian uint32_little_endian + +#define UINT_FMT UINT32_FMT +#define UINT_OFMT UINT32_OFMT +#define UINT_XFMT UINT32_XFMT +#define UINT_BFMT UINT32_BFMT + +#define uint_fmt_base uint32_fmt_base +#define uint0_fmt_base uint320_fmt_base +#define uint_fmt uint32_fmt +#define uint0_fmt uint320_fmt +#define uint_ofmt uint32_ofmt +#define uint0_ofmt uint320_ofmt +#define uint_xfmt uint32_xfmt +#define uint0_xfmt uint320_xfmt +#define uint_bfmt uint32_bfmt +#define uint0_bfmt uint320_bfmt + +#define uint_fmtlist(s, tab, n) uint32_fmtlist(s, tab, n) + +#define uint_scan_base(s, u, b) uint32_scan_base(s, (uint32 *)(char *)(u), b) +#define uint0_scan_base(s, u, b) uint320_scan_base(s, (uint32 *)(char *)(u), b) + +#define uint_scanlist(tab, max, s, num) uint32_scanlist(tab, max, s, num) diff --git a/src/headers/uint-64 b/src/headers/uint-64 new file mode 100644 index 0000000..31926d9 --- /dev/null +++ b/src/headers/uint-64 @@ -0,0 +1,34 @@ +#include <skalibs/uint64.h> + +#define UINT_PACK 8 +#define uint_pack uint64_pack +#define uint_pack_big uint64_pack_big +#define uint_unpack(s, u) uint64_unpack(s, (uint64 *)(char *)(u)) +#define uint_unpack_big(s, u) uint64_unpack_big(s, (uint64 *)(char *)(u)) + +#define uint_reverse uint64_reverse +#define uint_big_endian uint64_big_endian +#define uint_little_endian uint64_little_endian + +#define UINT_FMT UINT64_FMT +#define UINT_OFMT UINT64_OFMT +#define UINT_XFMT UINT64_XFMT +#define UINT_BFMT UINT64_BFMT + +#define uint_fmt_base uint64_fmt_base +#define uint0_fmt_base uint640_fmt_base +#define uint_fmt uint64_fmt +#define uint0_fmt uint640_fmt +#define uint_ofmt uint64_ofmt +#define uint0_ofmt uint640_ofmt +#define uint_xfmt uint64_xfmt +#define uint0_xfmt uint640_xfmt +#define uint_bfmt uint64_bfmt +#define uint0_bfmt uint640_bfmt + +#define uint_fmtlist(s, tab, n) uint64_fmtlist(s, tab, n) + +#define uint_scan_base(s, u, b) uint64_scan_base(s, (uint64 *)(char *)(u), b) +#define uint0_scan_base(s, u, b) uint640_scan_base(s, (uint64 *)(char *)(u), b) + +#define uint_scanlist(tab, max, s, num) uint64_scanlist(tab, max, s, num) diff --git a/src/headers/uint-footer b/src/headers/uint-footer new file mode 100644 index 0000000..68bbaf7 --- /dev/null +++ b/src/headers/uint-footer @@ -0,0 +1,10 @@ +#define uint_scan(s, u) uint_scan_base(s, (u), 10) +#define uint0_scan(s, u) uint0_scan_base(s, (u), 10) +#define uint_oscan(s, u) uint_scan_base(s, (u), 8) +#define uint0_oscan(s, u) uint0_scan_base(s, (u), 8) +#define uint_xscan(s, u) uint_scan_base(s, (u), 16) +#define uint0_xscan(s, u) uint0_scan_base(s, (u), 16) +#define uint_bscan(s, u) uint_scan_base(s, (u), 2) +#define uint0_bscan(s, u) uint0_scan_base(s, (u), 2) + +#endif diff --git a/src/headers/uint-header b/src/headers/uint-header new file mode 100644 index 0000000..8136b0c --- /dev/null +++ b/src/headers/uint-header @@ -0,0 +1,5 @@ +/* ISC license. */ + +#ifndef UINT_H +#define UINT_H + diff --git a/src/headers/uint16-bendian b/src/headers/uint16-bendian new file mode 100644 index 0000000..e1d0427 --- /dev/null +++ b/src/headers/uint16-bendian @@ -0,0 +1,3 @@ +#define uint16_little_endian(s, n) uint16_reverse((s), (n)) +#define uint16_big_endian(s, n) + diff --git a/src/headers/uint16-footer b/src/headers/uint16-footer new file mode 100644 index 0000000..5602571 --- /dev/null +++ b/src/headers/uint16-footer @@ -0,0 +1,40 @@ + +extern void uint16_pack (char *, uint16) ; +extern void uint16_pack_big (char *, uint16) ; +extern void uint16_unpack (char const *, uint16 *) ; +extern void uint16_unpack_big (char const *, uint16 *) ; +extern void uint16_reverse (char *, unsigned int) ; + +#define UINT16_FMT 6 +#define UINT16_OFMT 7 +#define UINT16_XFMT 5 +#define UINT16_BFMT 17 + +#define uint16_fmt_base(s, u, b) uint64_fmt_base(s, (uint64)(uint16)(u), b) +#define uint160_fmt_base(s, u, n, b) uint640_fmt_base(s, (uint64)(uint16)(u), n, b) + +#define uint16_fmt(s, u) uint64_fmt(s, (uint64)(uint16)(u)) +#define uint160_fmt(s, u, n) uint64_fmt(s, (uint64)(uint16)(u), n) +#define uint16_ofmt(s, o) uint64_ofmt(s, (uint64)(uint16)(o)) +#define uint160_ofmt(s, o, n) uint64_ofmt(s, (uint64)(uint16)(o), n) +#define uint16_xfmt(s, x) uint64_xfmt(s, (uint64)(uint16)(x)) +#define uint160_xfmt(s, x, n) uint64_xfmt(s, (uint64)(uint16)(x), n) +#define uint16_bfmt(s, b) uint64_bfmt(s, (uint64)(uint16)(b)) +#define uint160_bfmt(s, b, n) uint64_bfmt(s, (uint64)(uint16)(b), n) + +extern unsigned int uint16_fmtlist (char *, uint16 const *, unsigned int) ; + +extern unsigned int uint16_scan_base (char const *, uint16 *, unsigned char) ; +extern unsigned int uint160_scan_base (char const *, uint16 *, unsigned char) ; +#define uint16_scan(s, u) uint16_scan_base(s, (u), 10) +#define uint160_scan(s, u) uint160_scan_base(s, (u), 10) +#define uint16_oscan(s, u) uint16_scan_base(s, (u), 8) +#define uint160_oscan(s, u) uint160_scan_base(s, (u), 8) +#define uint16_xscan(s, u) uint16_scan_base(s, (u), 16) +#define uint160_xscan(s, u) uint160_scan_base(s, (u), 16) +#define uint16_bscan(s, u) uint16_scan_base(s, (u), 2) +#define uint160_bscan(s, u) uint160_scan_base(s, (u), 2) + +extern unsigned int uint16_scanlist (uint16 *, unsigned int, char const *, unsigned int *) ; + +#endif diff --git a/src/headers/uint16-header b/src/headers/uint16-header new file mode 100644 index 0000000..a8058c6 --- /dev/null +++ b/src/headers/uint16-header @@ -0,0 +1,9 @@ +/* ISC license. */ + +#ifndef UINT16_H +#define UINT16_H + +#include <stdint.h> +#include <skalibs/uint64.h> + +typedef uint16_t uint16 ; diff --git a/src/headers/uint16-lendian b/src/headers/uint16-lendian new file mode 100644 index 0000000..a9f9945 --- /dev/null +++ b/src/headers/uint16-lendian @@ -0,0 +1,3 @@ +#define uint16_little_endian(s, n) +#define uint16_big_endian(s, n) uint16_reverse((s), (n)) + diff --git a/src/headers/uint32-bendian b/src/headers/uint32-bendian new file mode 100644 index 0000000..27903c7 --- /dev/null +++ b/src/headers/uint32-bendian @@ -0,0 +1,3 @@ +#define uint32_little_endian(s, n) uint32_reverse((s), (n)) +#define uint32_big_endian(s, n) + diff --git a/src/headers/uint32-footer b/src/headers/uint32-footer new file mode 100644 index 0000000..7cfe7ba --- /dev/null +++ b/src/headers/uint32-footer @@ -0,0 +1,39 @@ +extern void uint32_pack (char *, uint32) ; +extern void uint32_pack_big (char *, uint32) ; +extern void uint32_unpack (char const *, uint32 *) ; +extern void uint32_unpack_big (char const *, uint32 *) ; +extern void uint32_reverse (char *, unsigned int) ; + +#define UINT32_FMT 11 +#define UINT32_OFMT 13 +#define UINT32_XFMT 9 +#define UINT32_BFMT 33 + +#define uint32_fmt_base(s, u, b) uint64_fmt_base(s, (uint64)(uint32)(u), b) +#define uint320_fmt_base(s, u, n, b) uint640_fmt_base(s, (uint64)(uint32)(u), n, b) + +#define uint32_fmt(s, u) uint64_fmt(s, (uint64)(uint32)(u)) +#define uint320_fmt(s, u, n) uint640_fmt(s, (uint64)(uint32)(u), n) +#define uint32_ofmt(s, o) uint64_ofmt(s, (uint64)(uint32)(o)) +#define uint320_ofmt(s, o, n) uint640_ofmt(s, (uint64)(uint32)(o), n) +#define uint32_xfmt(s, x) uint64_xfmt(s, (uint64)(uint32)(x)) +#define uint320_xfmt(s, x, n) uint640_xfmt(s, (uint64)(uint32)(x), n) +#define uint32_bfmt(s, b) uint64_bfmt(s, (uint64)(uint32)(b)) +#define uint320_bfmt(s, b, n) uint640_bfmt(s, (uint64)(uint32)(b), n) + +extern unsigned int uint32_fmtlist (char *, uint32 const *, unsigned int) ; + +extern unsigned int uint32_scan_base (char const *, uint32 *, unsigned char) ; +extern unsigned int uint320_scan_base (char const *, uint32 *, unsigned char) ; +#define uint32_scan(s, u) uint32_scan_base(s, (u), 10) +#define uint320_scan(s, u) uint320_scan_base(s, (u), 10) +#define uint32_oscan(s, u) uint32_scan_base(s, (u), 8) +#define uint320_oscan(s, u) uint320_scan_base(s, (u), 8) +#define uint32_xscan(s, u) uint32_scan_base(s, (u), 16) +#define uint320_xscan(s, u) uint320_scan_base(s, (u), 16) +#define uint32_bscan(s, u) uint32_scan_base(s, (u), 2) +#define uint320_bscan(s, u) uint320_scan_base(s, (u), 2) + +extern unsigned int uint32_scanlist (uint32 *, unsigned int, char const *, unsigned int *) ; + +#endif diff --git a/src/headers/uint32-header b/src/headers/uint32-header new file mode 100644 index 0000000..f71267f --- /dev/null +++ b/src/headers/uint32-header @@ -0,0 +1,9 @@ +/* ISC license. */ + +#ifndef UINT32_H +#define UINT32_H + +#include <stdint.h> +#include <skalibs/uint64.h> + +typedef uint32_t uint32 ; diff --git a/src/headers/uint32-inttypesh b/src/headers/uint32-inttypesh new file mode 100644 index 0000000..47a8910 --- /dev/null +++ b/src/headers/uint32-inttypesh @@ -0,0 +1,3 @@ +#include <inttypes.h> +typedef uint32_t uint32 ; + diff --git a/src/headers/uint32-lendian b/src/headers/uint32-lendian new file mode 100644 index 0000000..f88c111 --- /dev/null +++ b/src/headers/uint32-lendian @@ -0,0 +1,3 @@ +#define uint32_little_endian(s, n) +#define uint32_big_endian(s, n) uint32_reverse((s), (n)) + diff --git a/src/headers/uint32-noulong32 b/src/headers/uint32-noulong32 new file mode 100644 index 0000000..4705047 --- /dev/null +++ b/src/headers/uint32-noulong32 @@ -0,0 +1,2 @@ +typedef unsigned int uint32 ; + diff --git a/src/headers/uint32-stdinth b/src/headers/uint32-stdinth new file mode 100644 index 0000000..dc9eb42 --- /dev/null +++ b/src/headers/uint32-stdinth @@ -0,0 +1,3 @@ +#include <stdint.h> +typedef uint32_t uint32 ; + diff --git a/src/headers/uint32-ulong32 b/src/headers/uint32-ulong32 new file mode 100644 index 0000000..87119a5 --- /dev/null +++ b/src/headers/uint32-ulong32 @@ -0,0 +1,2 @@ +typedef unsigned long uint32 ; + diff --git a/src/headers/uint64-bendian b/src/headers/uint64-bendian new file mode 100644 index 0000000..2485bec --- /dev/null +++ b/src/headers/uint64-bendian @@ -0,0 +1,3 @@ +#define uint64_little_endian(s, n) uint64_reverse((s), (n)) +#define uint64_big_endian(s, n) + diff --git a/src/headers/uint64-footer b/src/headers/uint64-footer new file mode 100644 index 0000000..df620a5 --- /dev/null +++ b/src/headers/uint64-footer @@ -0,0 +1,39 @@ +extern void uint64_pack (char *, uint64) ; +extern void uint64_pack_big (char *, uint64) ; +extern void uint64_unpack (char const *, uint64 *) ; +extern void uint64_unpack_big (char const *, uint64 *) ; +extern void uint64_reverse (char *, unsigned int) ; + +#define UINT64_FMT 21 +#define UINT64_OFMT 25 +#define UINT64_XFMT 17 +#define UINT64_BFMT 65 + +extern unsigned int uint64_fmt_base (char *, uint64, unsigned char) ; +extern unsigned int uint640_fmt_base (char *, uint64, unsigned int, unsigned char) ; + +#define uint64_fmt(s, u) uint64_fmt_base(s, (u), 10) +#define uint640_fmt(s, u, n) uint640_fmt_base(s, u, (n), 10) +#define uint64_ofmt(s, u) uint64_fmt_base(s, (u), 8) +#define uint640_ofmt(s, u, n) uint640_fmt_base(s, u, (n), 8) +#define uint64_xfmt(s, u) uint64_fmt_base(s, (u), 16) +#define uint640_xfmt(s, u, n) uint640_fmt_base(s, u, (n), 16) +#define uint64_bfmt(s, u) uint64_fmt_base(s, (u), 2) +#define uint640_bfmt(s, u, n) uint640_fmt_base(s, u, (n), 2) + +extern unsigned int uint64_fmtlist (char *, uint64 const *, unsigned int) ; + +extern unsigned int uint64_scan_base (char const *, uint64 *, unsigned char) ; +extern unsigned int uint640_scan_base (char const *, uint64 *, unsigned char) ; +#define uint64_scan(s, u) uint64_scan_base(s, (u), 10) +#define uint640_scan(s, u) uint640_scan_base(s, (u), 10) +#define uint64_oscan(s, u) uint64_scan_base(s, (u), 8) +#define uint640_oscan(s, u) uint640_scan_base(s, (u), 8) +#define uint64_xscan(s, u) uint64_scan_base(s, (u), 16) +#define uint640_xscan(s, u) uint640_scan_base(s, (u), 16) +#define uint64_bscan(s, u) uint64_scan_base(s, (u), 2) +#define uint640_bscan(s, u) uint640_scan_base(s, (u), 2) + +extern unsigned int uint64_scanlist (uint64 *, unsigned int, char const *, unsigned int *) ; + +#endif diff --git a/src/headers/uint64-header b/src/headers/uint64-header new file mode 100644 index 0000000..f0f10e6 --- /dev/null +++ b/src/headers/uint64-header @@ -0,0 +1,5 @@ +/* ISC license. */ + +#ifndef UINT64_H +#define UINT64_H + diff --git a/src/headers/uint64-lendian b/src/headers/uint64-lendian new file mode 100644 index 0000000..ffdb4de --- /dev/null +++ b/src/headers/uint64-lendian @@ -0,0 +1,3 @@ +#define uint64_little_endian(s, n) +#define uint64_big_endian(s, n) uint64_reverse((s), (n)) + diff --git a/src/headers/uint64-noulong64 b/src/headers/uint64-noulong64 new file mode 100644 index 0000000..c72ebef --- /dev/null +++ b/src/headers/uint64-noulong64 @@ -0,0 +1,2 @@ +typedef unsigned long long uint64 ; + diff --git a/src/headers/uint64-stdinth b/src/headers/uint64-stdinth new file mode 100644 index 0000000..9c43f44 --- /dev/null +++ b/src/headers/uint64-stdinth @@ -0,0 +1,3 @@ +#include <stdint.h> + +typedef uint64_t uint64 ; diff --git a/src/headers/uint64-ulong64 b/src/headers/uint64-ulong64 new file mode 100644 index 0000000..d9313d4 --- /dev/null +++ b/src/headers/uint64-ulong64 @@ -0,0 +1 @@ +typedef unsigned long uint64 ; diff --git a/src/headers/ulong-32 b/src/headers/ulong-32 new file mode 100644 index 0000000..b1b3326 --- /dev/null +++ b/src/headers/ulong-32 @@ -0,0 +1,32 @@ +#include <skalibs/uint32.h> + +#define ULONG_PACK 4 +#define ulong_pack uint32_pack +#define ulong_pack_big uint32_pack_big +#define ulong_unpack(s, u) uint32_unpack(s, (uint32 *)(char *)(u)) +#define ulong_unpack_big(s, u) uint32_unpack_big(s, (uint32 *)(char *)(u)) + +#define ulong_reverse uint32_reverse +#define ulong_big_endian uint32_big_endian +#define ulong_little_endian uint32_little_endian + +#define ULONG_FMT UINT32_FMT +#define ULONG_OFMT UINT32_OFMT +#define ULONG_XFMT UINT32_XFMT +#define ULONG_BFMT UINT32_BFMT + +#define ulong_fmt uint32_fmt +#define ulong0_fmt uint320_fmt +#define ulong_ofmt uint32_ofmt +#define ulong0_ofmt uint320_ofmt +#define ulong_xfmt uint32_xfmt +#define ulong0_xfmt uint320_xfmt +#define ulong_bfmt uint32_bfmt +#define ulong0_bfmt uint320_bfmt + +#define ulong_fmtlist(s, tab, n) uint32_fmtlist(s, tab, n) + +#define ulong_scan_base(s, u, b) uint32_scan_base(s, (uint32 *)(char *)(u), b) +#define ulong0_scan_base(s, u, b) uint320_scan_base(s, (uint32 *)(char *)(u), b) + +#define ulong_scanlist(tab, max, s, num) uint32_scanlist(tab, max, s, num) diff --git a/src/headers/ulong-64 b/src/headers/ulong-64 new file mode 100644 index 0000000..016fd1f --- /dev/null +++ b/src/headers/ulong-64 @@ -0,0 +1,32 @@ +#include <skalibs/uint64.h> + +#define ULONG_PACK 8 +#define ulong_pack uint64_pack +#define ulong_pack_big uint64_pack_big +#define ulong_unpack(s, u) uint64_unpack(s, (uint64 *)(char *)(u)) +#define ulong_unpack_big(s, u) uint64_unpack_big(s, (uint64 *)(char *)(u)) + +#define ulong_reverse uint64_reverse +#define ulong_big_endian uint64_big_endian +#define ulong_little_endian uint64_little_endian + +#define ULONG_FMT UINT64_FMT +#define ULONG_OFMT UINT64_OFMT +#define ULONG_XFMT UINT64_XFMT +#define ULONG_BFMT UINT64_BFMT + +#define ulong_fmt uint64_fmt +#define ulong0_fmt uint640_fmt +#define ulong_ofmt uint64_ofmt +#define ulong0_ofmt uint640_ofmt +#define ulong_xfmt uint64_xfmt +#define ulong0_xfmt uint640_xfmt +#define ulong_bfmt uint64_bfmt +#define ulong0_bfmt uint640_bfmt + +#define ulong_fmtlist(s, tab, n) uint64_fmtlist(s, tab, n) + +#define ulong_scan_base(s, u, b) uint64_scan_base(s, (uint64 *)(char *)(u), b) +#define ulong0_scan_base(s, u, b) uint640_scan_base(s, (uint64 *)(char *)(u), b) + +#define ulong_scanlist(tab, max, s, num) uint64_scanlist(tab, max, s, num) diff --git a/src/headers/ulong-footer b/src/headers/ulong-footer new file mode 100644 index 0000000..0607872 --- /dev/null +++ b/src/headers/ulong-footer @@ -0,0 +1,10 @@ +#define ulong_scan(s, u) ulong_scan_base(s, (u), 10) +#define ulong0_scan(s, u) ulong0_scan_base(s, (u), 10) +#define ulong_oscan(s, u) ulong_scan_base(s, (u), 8) +#define ulong0_oscan(s, u) ulong0_scan_base(s, (u), 8) +#define ulong_xscan(s, u) ulong_scan_base(s, (u), 16) +#define ulong0_xscan(s, u) ulong0_scan_base(s, (u), 16) +#define ulong_bscan(s, u) ulong_scan_base(s, (u), 2) +#define ulong0_bscan(s, u) ulong0_scan_base(s, (u), 2) + +#endif diff --git a/src/headers/ulong-header b/src/headers/ulong-header new file mode 100644 index 0000000..98e6f37 --- /dev/null +++ b/src/headers/ulong-header @@ -0,0 +1,5 @@ +/* ISC license. */ + +#ifndef ULONG_H +#define ULONG_H + diff --git a/src/headers/ushort-16 b/src/headers/ushort-16 new file mode 100644 index 0000000..0e210c6 --- /dev/null +++ b/src/headers/ushort-16 @@ -0,0 +1,34 @@ +#include <skalibs/uint16.h> + +#define USHORT_PACK 2 +#define ushort_pack uint16_pack +#define ushort_pack_big uint16_pack_big +#define ushort_unpack(s, u) uint16_unpack(s, (uint16 *)(char *)(u)) +#define ushort_unpack_big(s, u) uint16_unpack_big(s, (uint16 *)(char *)(u)) + +#define ushort_reverse uint16_reverse +#define ushort_big_endian uint16_big_endian +#define ushort_little_endian uint16_little_endian + +#define USHORT_FMT UINT16_FMT +#define USHORT_OFMT UINT16_OFMT +#define USHORT_XFMT UINT16_XFMT +#define USHORT_BFMT UINT16_BFMT + +#define ushort_fmt_base uint16_fmt_base +#define ushort0_fmt_base uint160_fmt_base +#define ushort_fmt uint16_fmt +#define ushort0_fmt uint160_fmt +#define ushort_ofmt uint16_ofmt +#define ushort0_ofmt uint160_ofmt +#define ushort_xfmt uint16_xfmt +#define ushort0_xfmt uint160_xfmt +#define ushort_bfmt uint16_bfmt +#define ushort0_bfmt uint160_bfmt + +#define ushort_fmtlist(s, tab, n) uint16_fmtlist(s, tab, n) + +#define ushort_scan_base(s, u, b) uint16_scan_base(s, (uint16 *)(char *)(u), b) +#define ushort0_scan_base(s, u, b) uint160_scan_base(s, (uint16 *)(char *)(u), b) + +#define ushort_scanlist(tab, max, s, num) uint16_scanlist(tab, max, s, num) diff --git a/src/headers/ushort-32 b/src/headers/ushort-32 new file mode 100644 index 0000000..b41aef4 --- /dev/null +++ b/src/headers/ushort-32 @@ -0,0 +1,34 @@ +#include <skalibs/uint32.h> + +#define USHORT_PACK 4 +#define ushort_pack uint32_pack +#define ushort_pack_big uint32_pack_big +#define ushort_unpack(s, u) uint32_unpack(s, (uint32 *)(char *)(u)) +#define ushort_unpack_big(s, u) uint32_unpack_big(s, (uint32 *)(char *)(u)) + +#define ushort_reverse uint32_reverse +#define ushort_big_endian uint32_big_endian +#define ushort_little_endian uint32_little_endian + +#define USHORT_FMT UINT32_FMT +#define USHORT_OFMT UINT32_OFMT +#define USHORT_XFMT UINT32_XFMT +#define USHORT_BFMT UINT32_BFMT + +#define ushort_fmt_base uint32_fmt_base +#define ushort0_fmt_base uint320_fmt_base +#define ushort_fmt uint32_fmt +#define ushort0_fmt uint320_fmt +#define ushort_ofmt uint32_ofmt +#define ushort0_ofmt uint320_ofmt +#define ushort_xfmt uint32_xfmt +#define ushort0_xfmt uint320_xfmt +#define ushort_bfmt uint32_bfmt +#define ushort0_bfmt uint320_bfmt + +#define ushort_fmtlist(s, tab, n) uint32_fmtlist(s, tab, n) + +#define ushort_scan_base(s, u, b) uint32_scan_base(s, (uint32 *)(char *)(u), b) +#define ushort0_scan_base(s, u, b) uint320_scan_base(s, (uint32 *)(char *)(u), b) + +#define ushort_scanlist(tab, max, s, num) uint32_scanlist(tab, max, s, num) diff --git a/src/headers/ushort-footer b/src/headers/ushort-footer new file mode 100644 index 0000000..db56f73 --- /dev/null +++ b/src/headers/ushort-footer @@ -0,0 +1,10 @@ +#define ushort_scan(s, u) ushort_scan_base(s, (u), 10) +#define ushort0_scan(s, u) ushort0_scan_base(s, (u), 10) +#define ushort_oscan(s, u) ushort_scan_base(s, (u), 8) +#define ushort0_oscan(s, u) ushort0_scan_base(s, (u), 8) +#define ushort_xscan(s, u) ushort_scan_base(s, (u), 16) +#define ushort0_xscan(s, u) ushort0_scan_base(s, (u), 16) +#define ushort_bscan(s, u) ushort_scan_base(s, (u), 2) +#define ushort0_bscan(s, u) ushort0_scan_base(s, (u), 2) + +#endif diff --git a/src/headers/ushort-header b/src/headers/ushort-header new file mode 100644 index 0000000..66b7f9a --- /dev/null +++ b/src/headers/ushort-header @@ -0,0 +1,5 @@ +/* ISC license. */ + +#ifndef USHORT_H +#define USHORT_H + diff --git a/src/include/skalibs/alloc.h b/src/include/skalibs/alloc.h new file mode 100644 index 0000000..707d5c1 --- /dev/null +++ b/src/include/skalibs/alloc.h @@ -0,0 +1,16 @@ +/* ISC license. */ + +#ifndef ALLOC_H +#define ALLOC_H + +#include <skalibs/gccattributes.h> + +typedef char aligned_char gccattr_aligned ; +typedef aligned_char *aligned_char_ref, **aligned_char_ref_ref ; + +extern aligned_char_ref alloc (unsigned int) ; +extern void alloc_free (void *) ; +#define alloc_re(p, old, new) alloc_realloc(p, new) +extern int alloc_realloc (aligned_char_ref_ref, unsigned int) ; + +#endif diff --git a/src/include/skalibs/allreadwrite.h b/src/include/skalibs/allreadwrite.h new file mode 100644 index 0000000..6b2a0cf --- /dev/null +++ b/src/include/skalibs/allreadwrite.h @@ -0,0 +1,27 @@ +/* ISC license. */ + +#ifndef ALLREADWRITE_H +#define ALLREADWRITE_H + +#include <sys/types.h> +#include <sys/uio.h> +#include <skalibs/functypes.h> + +extern int sanitize_read (int) ; +extern int unsanitize_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) ; + +extern int fd_readv (int, struct iovec const *, unsigned int) ; +extern int fd_writev (int, struct iovec const *, unsigned int) ; + +#endif diff --git a/src/include/skalibs/avlnode.h b/src/include/skalibs/avlnode.h new file mode 100644 index 0000000..4d13d15 --- /dev/null +++ b/src/include/skalibs/avlnode.h @@ -0,0 +1,44 @@ +/* ISC license. */ + +#ifndef AVLNODE_H +#define AVLNODE_H + +#include <skalibs/gccattributes.h> +#include <skalibs/functypes.h> + + +#define AVLNODE_MAXDEPTH 49 /* enough for 2^32 nodes in the worst case */ + +typedef int avliterfunc_t (unsigned int, unsigned int, void *) ; +typedef avliterfunc_t *avliterfunc_t_ref ; + +typedef struct avlnode_s avlnode, *avlnode_ref ; +struct avlnode_s +{ + unsigned int data ; + unsigned int child[2] ; + signed char balance : 2 ; +} ; + +#define AVLNODE_ZERO { .data = 0, .child = { (unsigned int)-1, (unsigned int)-1 }, .balance = 0 } +extern avlnode const avlnode_zero ; + +extern unsigned int avlnode_searchnode (avlnode const *, unsigned int, unsigned int, void const *, dtokfunc_t_ref, cmpfunc_t_ref, void *) ; +extern int avlnode_search (avlnode const *, unsigned int, unsigned int, void const *, unsigned int *, dtokfunc_t_ref, cmpfunc_t_ref, void *) ; +extern unsigned int avlnode_height (avlnode const *, unsigned int, unsigned int) gccattr_pure ; + +extern unsigned int avlnode_extremenode (avlnode const *, unsigned int, unsigned int, int) gccattr_pure ; +#define avlnode_minnode(s, max, r) avlnode_extremenode(s, max, (r), 0) +#define avlnode_maxnode(s, max, r) avlnode_extremenode(s, max, (r), 1) + +extern int avlnode_extreme (avlnode const *, unsigned int, unsigned int, int, unsigned int *) ; +#define avlnode_min(s, max, r, data) avlnode_extreme(s, max, (r), 0, data) +#define avlnode_max(s, max, r, data) avlnode_extreme(s, max, (r), 1, data) + +extern unsigned int avlnode_insertnode (avlnode_ref, unsigned int, unsigned int, unsigned int, dtokfunc_t_ref, cmpfunc_t_ref, void *) ; +extern unsigned int avlnode_delete (avlnode_ref, unsigned int, unsigned int *, void const *, dtokfunc_t_ref, cmpfunc_t_ref, void *) ; +#define avlnode_deletenode(s, max, r, i, dtok, f, p) avlnode_delete(s, max, r, (*(dtok))((s)[i].data), dtok, f, p) + +extern int avlnode_iter (avlnode_ref, unsigned int, unsigned int, avliterfunc_t_ref, void *) ; + +#endif diff --git a/src/include/skalibs/avltree.h b/src/include/skalibs/avltree.h new file mode 100644 index 0000000..cefd116 --- /dev/null +++ b/src/include/skalibs/avltree.h @@ -0,0 +1,55 @@ +/* ISC license. */ + +#ifndef AVLTREE_H +#define AVLTREE_H + +#include <skalibs/functypes.h> +#include <skalibs/gensetdyn.h> +#include <skalibs/avlnode.h> + +typedef struct avltree_s avltree, *avltree_ref ; +struct avltree_s +{ + gensetdyn x ; + unsigned int root ; + dtokfunc_t_ref dtok ; + cmpfunc_t_ref kcmp ; + void *external ; +} ; + +#define AVLTREE_ZERO { .x = GENSETDYN_ZERO, .root = (unsigned int)-1, .dtok = 0, .kcmp = 0, .external = 0 } +extern avltree const avltree_zero ; +#define avltree_len(t) gensetdyn_n(&(t)->x) +#define avltree_totalsize(t) ((t)->x.storage.len) +#define avltree_nodes(t) ((avlnode_ref)(t)->x.storage.s) +#define avltree_data(t, i) (avltree_nodes(t)[i].data) +#define avltree_root(t) ((t)->root) +#define avltree_setroot(t, r) ((t)->root = (r)) + +extern void avltree_free (avltree_ref) ; +extern void avltree_init (avltree_ref, unsigned int, unsigned int, unsigned int, dtokfunc_t_ref, cmpfunc_t_ref, void *) ; +#define AVLTREE_INIT(b, num, den, dtk, f, p) { .x = GENSETDYN_INIT(avlnode, (b), num, den), .root = (unsigned int)-1, .dtok = (dtk), .kcmp = (f), .external = (p) } + +#define avltree_searchnode(t, k) avlnode_searchnode(avltree_nodes(t), avltree_totalsize(t), avltree_root(t), k, (t)->dtok, (t)->kcmp, (t)->external) +#define avltree_search(t, k, data) avlnode_search(avltree_nodes(t), avltree_totalsize(t), avltree_root(t), k, (data), (t)->dtok, (t)->kcmp, (t)->external) + +#define avltree_height(t) avlnode_height(avltree_nodes(t), avltree_totalsize(t), avltree_root(t)) + +#define avltree_extremenode(t, h) avlnode_extremenode(avltree_nodes(t), avltree_totalsize(t), avltree_root(t), h) +#define avltree_minnode(t) avltree_extremenode((t), 0) +#define avltree_maxnode(t) avltree_extremenode((t), 1) + +#define avltree_extreme(t, h, data) avlnode_extreme(avltree_nodes(t), avltree_totalsize(t), avltree_root(t), (h), data) +#define avltree_min(t, data) avltree_extreme((t), 0, data) +#define avltree_max(t, data) avltree_extreme((t), 1, data) + +extern int avltree_newnode (avltree_ref, unsigned int, unsigned int *) ; +#define avltree_insertnode(t, i) avltree_setroot(t, avlnode_insertnode(avltree_nodes(t), avltree_totalsize(t), avltree_root(t), i, (t)->dtok, (t)->kcmp, (t)->external)) +extern int avltree_insert (avltree_ref, unsigned int) ; + +#define avltree_deletenode(t, i) avltree_delete(t, (*(t)->dtok)(avltree_data(t, i))) +extern int avltree_delete (avltree_ref, void const *) ; + +#define avltree_iter(t, f, p) avlnode_iter(avltree_nodes(t), avltree_totalsize(t), avltree_root(t), f, p) + +#endif diff --git a/src/include/skalibs/avltreen.h b/src/include/skalibs/avltreen.h new file mode 100644 index 0000000..8151e9d --- /dev/null +++ b/src/include/skalibs/avltreen.h @@ -0,0 +1,87 @@ +/* ISC license. */ + +#ifndef AVLTREEN_H +#define AVLTREEN_H + +#include <skalibs/functypes.h> +#include <skalibs/genset.h> +#include <skalibs/avlnode.h> + + + /* avltreen: just the structure. Storage and freelist are outside. */ + +typedef struct avltreen_s avltreen, *avltreen_ref ; +struct avltreen_s +{ + genset x ; + unsigned int root ; + dtokfunc_t_ref dtok ; + cmpfunc_t_ref kcmp ; + void *external ; +} ; + +#define AVLTREEN_ZERO { .x = GENSET_ZERO, .root = (unsigned int)-1, .dtok = 0, .kcmp = 0, .external = 0 } +#define avltreen_totalsize(t) ((t)->x.max) +#define avltreen_len(t) genset_n(&(t)->x) +#define avltreen_nodes(t) ((avlnode_ref)(t)->x.storage) +#define avltreen_data(t, i) (avltreen_nodes(t)[i].data) +#define avltreen_root(t) ((t)->root) +#define avltreen_setroot(t, r) ((t)->root = (r)) +extern void avltreen_init (avltreen_ref, avlnode_ref, unsigned int *, unsigned int, dtokfunc_t_ref, cmpfunc_t_ref, void *) ; + +#define avltreen_searchnode(t, k) avlnode_searchnode(avltreen_nodes(t), avltreen_totalsize(t), avltreen_root(t), (k), (t)->dtok, (t)->kcmp, (t)->external) +#define avltreen_search(t, k, data) avlnode_search(avltreen_nodes(t), avltreen_totalsize(t), avltreen_root(t), k, (data), (t)->dtok, (t)->kcmp, (t)->external) + +#define avltreen_height(t) avlnode_height(avltreen_nodes(t), avltreen_totalsize(t), avltreen_root(t)) + +#define avltreen_extremenode(t, h) avlnode_extremenode(avltreen_nodes(t), avltreen_totalsize(t), avltreen_root(t), h) +#define avltreen_minnode(t) avltreen_extremenode((t), 0) +#define avltreen_maxnode(t) avltreen_extremenode((t), 1) + +#define avltreen_extreme(t, h, data) avlnode_extreme(avltreen_nodes(t), avltreen_totalsize(t), avltreen_root(t), (h), data) +#define avltreen_min(t, data) avltreen_extreme((t), 0, data) +#define avltreen_max(t, data) avltreen_extreme((t), 1, data) + +extern unsigned int avltreen_newnode (avltreen_ref, unsigned int) ; +#define avltreen_insertnode(t, i) avltreen_setroot(t, avlnode_insertnode(avltreen_nodes(t), avltreen_totalsize(t), avltreen_root(t), i, (t)->dtok, (t)->kcmp, (t)->external)) +extern int avltreen_insert (avltreen_ref, unsigned int) ; + +#define avltreen_deletenode(t, i) avltreen_delete(t, avltreen_data(t, i)) +extern int avltreen_delete (avltreen_ref, void const *) ; + +#define avltreen_iter(t, f, p) avlnode_iter(avltreen_nodes(t), avltreen_totalsize(t), avltreen_root(t), f, p) + + + /* avltreeb: everything in one place. Stack or BSS, or heap if you insist */ + +#define AVLTREEB_TYPE(size) struct { avlnode storage[size] ; unsigned int freelist[size] ; avltreen info ; } +#define avltreeb_init(t, size, dtk, f, p) avltreen_init(&(t)->info, (t)->storage, (t)->freelist, size, dtk, f, p) +#define avltreeb_totalsize(t) avltreen_totalsize(&(t)->info) +#define avltreeb_len(t) avltreen_len(&(t)->info) +#define avltreeb_nodes(t) ((avlnode_ref)(t)->storage) +#define avltreeb_data(t, i) (avltreeb_nodes(t)[i].data) +#define avltreeb_root(t) ((t)->info.root) +#define avltreeb_setroot(t, r) ((t)->info.root = (r)) + +#define avltreeb_searchnode(t, k) avlnode_searchnode(avltreeb_nodes(t), avltreeb_totalsize(t), avltreeb_root(t), (k), (t)->info.dtok, (t)->info.kcmp, (t)->info.external) +#define avltreeb_search(t, k, data) avlnode_search(avltreeb_nodes(t), avltreeb_totalsize(t), avltreeb_root(t), k, (data), (t)->info.dtok, (t)->info.kcmp, (t)->info.external) +#define avltreeb_height(t) avlnode_height(avltreeb_nodes(t), avltreeb_totalsize(t), avltreeb_root(t)) + +#define avltreeb_extremenode(t, h) avlnode_extremenode(avltreeb_nodes(t), avltreeb_totalsize(t), avltreeb_root(t), h) +#define avltreeb_minnode(t) avltreeb_extremenode((t), 0) +#define avltreeb_maxnode(t) avltreeb_extremenode((t), 1) + +#define avltreeb_extreme(t, h, data) avlnode_extremenode(avltreeb_nodes(t), avltreeb_totalsize(t), avltreeb_root(t), h, data) +#define avltreeb_min(t, data) avltreeb_extreme((t), 0, data) +#define avltreeb_max(t, data) avltreeb_extreme((t), 1, data) + +#define avltreeb_newnode(t, d) avltreen_newnode(&(t)->info, d) +#define avltreeb_insertnode(t, i) avltreeb_setroot(t, avlnode_insertnode(avltreeb_nodes(t), avltreeb_totalsize(t), avltreeb_root(t), (i), (t)->info.dtok, (t)->info.kcmp, (t)->info.external)) +#define avltreeb_insert(t, d) avltreen_insert(&(t)->info, d) + +#define avltreeb_deletenode(t, i) avltreeb_delete(t, avltreeb_data(t, i)) +#define avltreeb_delete(t, k) avltreen_delete(&(t)->info, k) + +#define avltreeb_iter(t, f, p) avlnode_iter(avltreeb_nodes(t), avltreeb_totalsize(t), avltreeb_root(t), f, p) + +#endif diff --git a/src/include/skalibs/biguint.h b/src/include/skalibs/biguint.h new file mode 100644 index 0000000..94e99a9 --- /dev/null +++ b/src/include/skalibs/biguint.h @@ -0,0 +1,46 @@ +/* ISC license. */ + +#ifndef BIGUINT_H +#define BIGUINT_H + +#include <skalibs/gccattributes.h> +#include <skalibs/uint32.h> + +extern void bu_pack (char *, uint32 const *, unsigned int) ; +extern void bu_unpack (char const *, uint32 *, unsigned int) ; +extern void bu_pack_big (char *, uint32 const *, unsigned int) ; +extern void bu_unpack_big (char const *, uint32 *, unsigned int) ; +extern unsigned int bu_fmt (char *, uint32 const *, unsigned int) ; +extern unsigned int bu_scanlen (char const *, unsigned int *) ; +extern int bu_scan (char const *, unsigned int, uint32 *, unsigned int, unsigned int) ; + +extern unsigned int bu_len (uint32 const *, unsigned int) gccattr_pure ; +extern void bu_zero (uint32 *, unsigned int) ; +extern int bu_copy (uint32 *, unsigned int, uint32 const *, unsigned int) ; +extern int bu_cmp (uint32 const *, unsigned int, uint32 const *, unsigned int) gccattr_pure ; + +#define bu_add(c, cn, a, an, b, bn) bu_addc(c, cn, a, an, b, (bn), 0) +extern int bu_addc (uint32 *, unsigned int, uint32 const *, unsigned int, uint32 const *, unsigned int, int) ; +#define bu_sub(c, cn, a, an, b, bn) bu_subc(c, cn, a, an, b, (bn), 0) +extern int bu_subc (uint32 *, unsigned int, uint32 const *, unsigned int, uint32 const *, unsigned int, int) ; +extern int bu_mul (uint32 *, unsigned int, uint32 const *, unsigned int, uint32 const *, unsigned int) ; +extern int bu_div (uint32 const *, unsigned int, uint32 const *, unsigned int, uint32 *, unsigned int, uint32 *, unsigned int) ; +extern int bu_mod (uint32 *, unsigned int, uint32 const *, unsigned int) ; +extern int bu_gcd (uint32 *, unsigned int, uint32 const *, unsigned int, uint32 const *, unsigned int) ; + +#define bu_slb(a, n) bu_slbc(a, n, 0) +extern int bu_slbc (uint32 *, unsigned int, int) ; +#define bu_srb(a, n) bu_srbc(a, n, 0) +extern int bu_srbc (uint32 *, unsigned int, int) ; + +extern int bu_addmod (uint32 *, unsigned int, uint32 const *, unsigned int, uint32 const *, unsigned int, uint32 const *, unsigned int) ; +extern int bu_submod (uint32 *, unsigned int, uint32 const *, unsigned int, uint32 const *, unsigned int, uint32 const *, unsigned int) ; +extern int bu_invmod (uint32 *, unsigned int, uint32 const *, unsigned int) ; +extern int bu_divmod (uint32 *, unsigned int, uint32 const *, unsigned int, uint32 const *, unsigned int, uint32 const *, unsigned int) ; + +extern void bu_scan_internal (char const *, unsigned int, uint32 *) ; +extern void bu_copy_internal (uint32 *, uint32 const *, unsigned int) ; +extern void bu_div_internal (uint32 *, unsigned int, uint32 const *, unsigned int, uint32 *, unsigned int) ; +extern void bu_divmod_internal (uint32 *, uint32 *, uint32 const *, unsigned int) ; + +#endif diff --git a/src/include/skalibs/bitarray.h b/src/include/skalibs/bitarray.h new file mode 100644 index 0000000..7cf79b3 --- /dev/null +++ b/src/include/skalibs/bitarray.h @@ -0,0 +1,33 @@ +/* ISC license. */ + +#ifndef BITARRAY_H +#define BITARRAY_H + +#include <skalibs/gccattributes.h> + +#define bitarray_div8(n) ((n) ? 1U + (((n) - 1) >> 3) : 0U) + +extern void bitarray_clearsetn (unsigned char *, unsigned int, unsigned int, int) ; +#define bitarray_clearn(s, start, len) bitarray_clearsetn(s, start, (len), 0) +#define bitarray_setn(s, start, len) bitarray_clearsetn(s, start, (len), 1) + +#define bitarray_peek(s, n) (((s)[(n)>>3] & (1U<<((n)&7))) ? 1 : 0) +#define bitarray_isset(b, n) bitarray_peek(b, n) +#define bitarray_clear(s, n) ((s)[(n)>>3] &= ~(1U << ((n) & 7))) +#define bitarray_set(s, n) ((s)[(n)>>3] |= 1U << ((n) & 7)) +#define bitarray_poke(s, n, h) ((h) ? bitarray_set(s, n) : bitarray_clear(s, n)) + +extern int bitarray_testandpoke (unsigned char *, unsigned int, int) ; +#define bitarray_testandclear(b, n) bitarray_testandpoke(b, n, 0) +#define bitarray_testandset(b, n) bitarray_testandpoke(b, n, 1) + +extern unsigned int bitarray_firstclear (unsigned char const *, unsigned int) gccattr_pure ; +extern unsigned int bitarray_firstset (unsigned char const *, unsigned int) gccattr_pure ; +#define bitarray_first(s, n, h) ((h) ? bitarray_firstset(s, n) : bitarray_firstclear(s, n)) + +extern void bitarray_not (unsigned char *, unsigned int, unsigned int) ; +extern void bitarray_and (unsigned char *, unsigned char const *, unsigned char const *, unsigned int) ; +extern void bitarray_or (unsigned char *, unsigned char const *, unsigned char const *, unsigned int) ; +extern void bitarray_xor (unsigned char *, unsigned char const *, unsigned char const *, unsigned int) ; + +#endif diff --git a/src/include/skalibs/bufalloc.h b/src/include/skalibs/bufalloc.h new file mode 100644 index 0000000..c2779b6 --- /dev/null +++ b/src/include/skalibs/bufalloc.h @@ -0,0 +1,36 @@ +/* ISC license. */ + +#ifndef BUFALLOC_H +#define BUFALLOC_H + +#include <skalibs/gccattributes.h> +#include <skalibs/stralloc.h> + +typedef struct bufalloc bufalloc, *bufalloc_ref ; +struct bufalloc +{ + stralloc x ; + unsigned int p ; + int fd ; + int (*op) (int, char const *, unsigned int) ; +} ; + +#define BUFALLOC_ZERO { .x = STRALLOC_ZERO, .p = 0, .fd = -1, .op = 0 } +#define BUFALLOC_INIT(f, d) { .x = STRALLOC_ZERO, .p = 0, .fd = (d), .op = (f) } +extern void bufalloc_init (bufalloc_ref, int (*)(int, char const *, unsigned int), int) ; +#define bufalloc_shrink(ba) stralloc_shrink(&(ba)->x) +#define bufalloc_free(ba) stralloc_free(&(ba)->x) +#define bufalloc_put(ba, s, n) stralloc_catb(&(ba)->x, s, n) +#define bufalloc_puts(ba, s) stralloc_cats(&(ba)->x, s) +#define bufalloc_putv(ba, v, n) stralloc_catv(&(ba)->x, v, n) +#define bufalloc_fd(ba) ((ba)->fd) +extern int bufalloc_getfd (bufalloc const *) gccattr_pure ; +extern int bufalloc_flush (bufalloc_ref) ; +extern void bufalloc_clean (bufalloc_ref) ; +#define bufalloc_len(ba) ((ba)->x.len - (ba)->p) +extern unsigned int bufalloc_getlen (bufalloc const *) gccattr_pure ; +#define bufalloc_isempty(ba) ((ba)->x.len == (ba)->p) + +extern bufalloc_ref bufalloc_1, bufalloc_2 ; + +#endif diff --git a/src/include/skalibs/buffer.h b/src/include/skalibs/buffer.h new file mode 100644 index 0000000..3064c51 --- /dev/null +++ b/src/include/skalibs/buffer.h @@ -0,0 +1,134 @@ +/* ISC license. */ + +#ifndef BUFFER_H +#define BUFFER_H + +#include <skalibs/gccattributes.h> +#include <skalibs/bytestr.h> +#include <skalibs/cbuffer.h> +#include <skalibs/diuint.h> +#include <skalibs/siovec.h> + +typedef int buffer_io_func_t (int, siovec_t const *, unsigned int, void *) ; +typedef buffer_io_func_t *buffer_io_func_t_ref ; + +typedef struct buffer_s buffer, buffer_t, *buffer_ref, *buffer_t_ref ; +struct buffer_s +{ + buffer_io_func_t *op ; + int fd ; + cbuffer_t c ; + void *aux ; +} ; +#define BUFFER_ZERO { .op = 0, .fd = -1, .c = CBUFFER_ZERO, .aux = 0 } + + + /* + Circular buffers need to be 1 char bigger than the storage space, + so that the head == tail case is nonambiguous (empty). + */ + +#define BUFFER_INSIZE 8193 +#define BUFFER_OUTSIZE 8193 +#define BUFFER_ERRSIZE 1025 +#define BUFFER_INSIZE_SMALL 513 +#define BUFFER_OUTSIZE_SMALL 513 + +#define BUFFER_INIT_AUX(f, d, buf, len, data) { .op = (f), .fd = (d), .c = CBUFFER_INIT(buf, len), .aux = (data) } +#define BUFFER_INIT(f, d, buf, len) BUFFER_INIT_AUX(f, d, buf, (len), 0) +extern int buffer_init_aux (buffer *, buffer_io_func_t *, int, char *, unsigned int, void *) ; +#define buffer_init(b, f, d, buf, len) buffer_init_aux(b, f, d, buf, len, 0) + + + /* Writing */ + +extern int buffer_flush (buffer *) ; + +#define buffer_putnoflush(b, s, len) cbuffer_put(&(b)->c, s, len) +#define buffer_putvnoflush(b, v, n) cbuffer_putv(&(b)->c, v, n) +#define buffer_putsnoflush(b, s) buffer_putnoflush(b, (s), str_len(s)) + +extern int buffer_putallnoflush (buffer *, char const *, unsigned int) ; +extern int buffer_putvallnoflush (buffer *, siovec_t const *, unsigned int) ; +#define buffer_putsallnoflush(b, s) buffer_putallnoflush(b, (s), str_len(s)) + +extern int buffer_putall (buffer *, char const *, unsigned int, unsigned int *) ; +extern int buffer_putvall (buffer *, siovec_t const *, unsigned int, diuint *) ; +#define buffer_putsall(b, s, w) buffer_putall(b, s, str_len(s), w) + +#define buffer_putallflush(b, s, len, w) (buffer_putall(b, s, len, w) && buffer_flush(b)) +#define buffer_putvallflush(b, v, n, w) (buffer_putvall(b, v, n, w) && buffer_flush(b)) +#define buffer_putsallflush(b, s, w) buffer_putallflush(b, s, str_len(s), w) + +extern int buffer_put (buffer *, char const *, unsigned int) ; +extern int buffer_putv (buffer *, siovec_t const *, unsigned int) ; +#define buffer_puts(b, s) buffer_put(b, (s), str_len(s)) + +extern int buffer_putflush (buffer *, char const *, unsigned int) ; +extern int buffer_putvflush (buffer *, siovec_t const *, unsigned int) ; +#define buffer_putsflush(b, s) buffer_putflush(b, (s), str_len(s)) + +#define buffer_unput(b, n) cbuffer_unput(&(b)->c, n) +#define buffer_wpeek(b, v) cbuffer_wpeek(&(b)->c, v) +#define buffer_wseek(b, n) cbuffer_wseek(&(b)->c, n) +extern buffer_io_func_t buffer_write ; + + + /* Reading */ + +extern int buffer_fill (buffer *) ; + +#define buffer_getnofill(b, s, len) cbuffer_get(&(b)->c, s, len) +#define buffer_getvnofill(b, v, n) cbuffer_getv(&(b)->c, v, n) + +extern int buffer_getallnofill (buffer *, char *, unsigned int) ; +extern int buffer_getvallnofill (buffer *, siovec_t const *, unsigned int) ; + +extern int buffer_getall (buffer *, char *, unsigned int, unsigned int *) ; +extern int buffer_getvall (buffer *, siovec_t const *, unsigned int, diuint *) ; + +extern int buffer_get (buffer *, char *, unsigned int) ; +extern int buffer_getv (buffer *, siovec_t const *, unsigned int) ; + +#define buffer_unget(b, n) cbuffer_unget(&(b)->c, n) +#define buffer_rpeek(b, n) cbuffer_rpeek(&(b)->c, n) +#define buffer_rseek(b, n) cbuffer_rseek(&(b)->c, n) +extern buffer_io_func_t buffer_read ; + + + /* Utility */ + +#define buffer_len(b) cbuffer_len(&(b)->c) +extern unsigned int buffer_getlen (buffer const *) gccattr_pure ; +#define buffer_available(b) cbuffer_available(&(b)->c) +#define buffer_isempty(b) cbuffer_isempty(&(b)->c) +#define buffer_isfull(b) cbuffer_isfull(&(b)->c) +#define buffer_fd(b) ((b)->fd) +extern int buffer_getfd (buffer const *) gccattr_pure ; +#define buffer_isreadable(b) (!buffer_isfull(b)) +#define buffer_iswritable(b) (!buffer_isempty(b)) + + + /* Globals */ + +extern buffer_io_func_t buffer_flush1read ; + +extern buffer buffer_0_ ; +#define buffer_0 (&buffer_0_) + +extern buffer buffer_0small_ ; +#define buffer_0small (&buffer_0small_) + +extern buffer buffer_0f1_ ; +#define buffer_0f1 (&buffer_0f1_) + +extern buffer buffer_1_ ; +#define buffer_1 (&buffer_1_) + +extern buffer buffer_1small_ ; +#define buffer_1small (&buffer_1small_) + +extern buffer buffer_2_ ; +#define buffer_2 (&buffer_2_) + +#endif diff --git a/src/include/skalibs/bytestr.h b/src/include/skalibs/bytestr.h new file mode 100644 index 0000000..52e9bd6 --- /dev/null +++ b/src/include/skalibs/bytestr.h @@ -0,0 +1,65 @@ +/* ISC license. */ + +#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) + +#ifndef SKALIBS_FLAG_REPLACE_LIBC + +#include <sys/types.h> +#include <string.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(s) strlen(s) +#define str_diff(a, b) strcmp(a, b) +#define str_diffn(a, b, n) strncmp(a, b, n) +#define str_copy(to, from) strlen(strcpy(to, from)) + +#else + +extern void byte_copy (char *, unsigned int, char const *) ; +extern void byte_copyr (char *, unsigned int, char const *) ; +extern int byte_diff (char const *, unsigned int, char const *) gccattr_pure ; +extern void byte_zero (void *, unsigned int) ; +extern unsigned int str_len (char const *) gccattr_pure ; +extern int str_diff (char const *, char const *) gccattr_pure ; +extern int str_diffn (char const *, char const *, unsigned int) gccattr_pure ; +extern unsigned int str_copy (char *, char const *) ; + +#endif + + +extern unsigned int byte_chr (char const *, unsigned int, int) gccattr_pure ; +extern unsigned int byte_rchr (char const *, unsigned int, int) gccattr_pure ; +extern unsigned int byte_in (char const *, unsigned int, char const *, unsigned int) gccattr_pure ; +#define byte_equal(s, n, t) (!byte_diff((s), (n), (t))) +extern unsigned int byte_count (char const *, unsigned int, char) gccattr_pure ; + +#define str_diffb(a, n, b) str_diffn(a, (b), n) +extern unsigned int str_chr (char const *, int) gccattr_pure ; +extern unsigned int str_rchr (char const *, int) gccattr_pure ; +extern int str_start (char const *, char const *) gccattr_pure ; +#define str_equal(s, t) (!str_diff(s, t)) +extern unsigned int str_strn (char const *, unsigned int, char const *, unsigned int) gccattr_pure ; + +extern void case_lowers (char *) ; +extern void case_lowerb (char *, unsigned int) ; +extern void case_uppers (char *) ; +extern void case_upperb (char *, unsigned int) ; +#define case_equals(a, b) (!case_diffs(a, b)) +#define case_equalb(a, n, b) (!case_diffb(a, n, b)) +extern int case_diffs (char const *, char const *) gccattr_pure ; +extern int case_diffb (char const *, unsigned int, char const *) gccattr_pure ; +#define case_starts(s, t) case_startb(s, str_len(s), t) +extern int case_startb (char const *, unsigned int, char const *) gccattr_pure ; +extern unsigned int case_str (char const *, char const *) gccattr_pure ; + +#endif diff --git a/src/include/skalibs/cbuffer.h b/src/include/skalibs/cbuffer.h new file mode 100644 index 0000000..a80e3af --- /dev/null +++ b/src/include/skalibs/cbuffer.h @@ -0,0 +1,62 @@ +/* ISC license. */ + +#ifndef CBUFFER_H +#define CBUFFER_H + +#include <skalibs/gccattributes.h> +#include <skalibs/bytestr.h> +#include <skalibs/diuint.h> +#include <skalibs/siovec.h> + +typedef struct cbuffer_s cbuffer_t, *cbuffer_t_ref ; +struct cbuffer_s +{ + char *x ; + unsigned int a ; /* total length */ + unsigned int p ; /* head */ + unsigned int n ; /* tail */ +} ; +#define CBUFFER_ZERO { .x = 0, .a = 0, .p = 0, .n = 0 } + + /* + Circular buffers need to be 1 char bigger than the storage space, + so that the head == tail case is nonambiguous (empty). + */ + +#define CBUFFER_INIT(buf, len) { .x = (buf), .a = (len), .p = 0, .n = 0 } +extern int cbuffer_init (cbuffer_t *, char *, unsigned int) ; + + + /* Writing */ + +extern unsigned int cbuffer_put (cbuffer_t *, char const *, unsigned int) ; +extern unsigned int cbuffer_putv (cbuffer_t *, siovec_t const *, unsigned int) ; +#define cbuffer_puts(b, s) cbuffer_put(b, (s), str_len(s)) + +#define cbuffer_UNPUT(b, w) ((b)->n = ((b)->a + (b)->n - w) % (b)->a, w) ; +extern unsigned int cbuffer_unput (cbuffer_t *, unsigned int) ; +extern void cbuffer_wpeek (cbuffer_t *, siovec_t *) ; +#define cbuffer_WSEEK(b, w) ((b)->n = ((b)->n + (w)) % (b)->a, w) +extern unsigned int cbuffer_wseek (cbuffer_t *, unsigned int) ; + + + /* Reading */ + +extern unsigned int cbuffer_get (cbuffer_t *, char *, unsigned int) ; +extern unsigned int cbuffer_getv (cbuffer_t *, siovec_t const *, unsigned int) ; + +#define cbuffer_UNGET(b, n) ((b)->p = ((b)->a + (b)->p - n) % (b)->a, n) ; +extern unsigned int cbuffer_unget (cbuffer_t *, unsigned int) ; +extern void cbuffer_rpeek (cbuffer_t *, siovec_t *) ; +#define cbuffer_RSEEK(b, n) ((b)->p = ((b)->p + (n)) % (b)->a, n) +extern unsigned int cbuffer_rseek (cbuffer_t *, unsigned int) ; + + + /* Utility */ + +#define cbuffer_len(b) ((unsigned int)(((b)->a - (b)->p + (b)->n) % (b)->a)) +#define cbuffer_available(b) ((unsigned int)(((b)->a - (b)->n + (b)->p - 1) % (b)->a)) +#define cbuffer_isempty(b) (!cbuffer_len(b)) +#define cbuffer_isfull(b) (!cbuffer_available(b)) + +#endif diff --git a/src/include/skalibs/cdb.h b/src/include/skalibs/cdb.h new file mode 100644 index 0000000..9e9aae0 --- /dev/null +++ b/src/include/skalibs/cdb.h @@ -0,0 +1,51 @@ +/* ISC license. */ + +#ifndef CDB_H +#define CDB_H + +#include <skalibs/gccattributes.h> +#include <skalibs/uint32.h> + +#define CDB_HASHSTART 5381 +extern uint32 cdb_hashadd (uint32, unsigned char) gccattr_const ; +extern uint32 cdb_hash (char const *, unsigned int) gccattr_pure ; + +typedef struct cdb cdb_t, *cdb_t_ref ; +struct cdb +{ + char *map ; /* 0 if no map */ + int fd ; /* -1 if uninitted, negative if mapped, nonnegative if nomapped */ + uint32 size ; /* initialized if map is nonzero */ + uint32 loop ; /* number of hash slots searched under this key */ + uint32 khash ; /* initialized if loop is nonzero */ + uint32 kpos ; /* initialized if loop is nonzero */ + uint32 hpos ; /* initialized if loop is nonzero */ + uint32 hslots ; /* initialized if loop is nonzero */ + uint32 dpos ; /* initialized if cdb_findnext() returns 1 */ + uint32 dlen ; /* initialized if cdb_findnext() returns 1 */ +} ; + +#define CDB_ZERO { .map = 0, .fd = -1, .size = 0, .loop = 0, .khash = 0, .kpos = 0, .hpos = 0, .hslots = 0, .dpos = 0, .dlen = 0 } +extern struct cdb const cdb_zero ; + +extern void cdb_free (struct cdb *) ; + +#define cdb_init(c, fd) (cdb_init_map(c, (fd), 1) ? 0 : -1) +extern int cdb_init_map (struct cdb *, int fd, int) ; +extern int cdb_mapfile (struct cdb *, char const *) ; +extern int cdb_read (struct cdb *, char *, unsigned int, uint32) ; +#define cdb_findstart(c) ((c)->loop = 0) +extern int cdb_findnext (struct cdb *, char const *, unsigned int) ; +#define cdb_find(c, s, len) (cdb_findstart(c), cdb_findnext(c, s, len)) + +#define cdb_datapos(c) ((c)->dpos) +#define cdb_datalen(c) ((c)->dlen) +#define cdb_keypos(c) ((c)->kpos) +#define cdb_keylen(c) ((c)->dpos - (c)->kpos) + +#define cdb_traverse_init(c, kpos) (*(kpos) = 2048) +#define cdb_firstkey(c, kpos) (cdb_traverse_init(c, kpos), cdb_nextkey(c, kpos)) +extern int cdb_nextkey (struct cdb *, uint32 *) ; +extern int cdb_successor (struct cdb *, char const *, unsigned int) ; + +#endif diff --git a/src/include/skalibs/cdb_make.h b/src/include/skalibs/cdb_make.h new file mode 100644 index 0000000..d0a949b --- /dev/null +++ b/src/include/skalibs/cdb_make.h @@ -0,0 +1,27 @@ +/* ISC license. */ + +#ifndef CDB_MAKE_H +#define CDB_MAKE_H + +#include <skalibs/uint32.h> +#include <skalibs/diuint32.h> +#include <skalibs/genalloc.h> +#include <skalibs/buffer.h> + +typedef struct cdb_make cdb_make, *cdb_make_ref ; +struct cdb_make +{ + char buf[BUFFER_OUTSIZE] ; + genalloc hplist ; /* diuint32 */ + buffer b ; + uint32 pos ; + int fd ; +} ; + +#define CDB_MAKE_ZERO { .buf = "", .hplist = GENALLOC_ZERO, .b = BUFFER_INIT(&buffer_write, -1, 0, 0), .pos = 2048, .fd = -1 } + +extern int cdb_make_start (struct cdb_make *, int) ; +extern int cdb_make_add (struct cdb_make *, char const *, unsigned int, char const *, unsigned int) ; +extern int cdb_make_finish (struct cdb_make *) ; + +#endif diff --git a/src/include/skalibs/datastruct.h b/src/include/skalibs/datastruct.h new file mode 100644 index 0000000..1c7d816 --- /dev/null +++ b/src/include/skalibs/datastruct.h @@ -0,0 +1,12 @@ +/* ISC license. */ + +#ifndef DATASTRUCT_H +#define DATASTRUCT_H + +#include <skalibs/genset.h> +#include <skalibs/gensetdyn.h> +#include <skalibs/avlnode.h> +#include <skalibs/avltree.h> +#include <skalibs/avltreen.h> + +#endif diff --git a/src/include/skalibs/direntry.h b/src/include/skalibs/direntry.h new file mode 100644 index 0000000..3150e51 --- /dev/null +++ b/src/include/skalibs/direntry.h @@ -0,0 +1,13 @@ +/* ISC license. */ + +#ifndef DIRENTRY_H +#define DIRENTRY_H + +#include <sys/types.h> +#include <dirent.h> + +typedef struct dirent direntry, direntry_t, *direntry_ref, *direntry_t_ref ; + +extern int dir_close (DIR *) ; + +#endif diff --git a/src/include/skalibs/diuint.h b/src/include/skalibs/diuint.h new file mode 100644 index 0000000..1c13bd8 --- /dev/null +++ b/src/include/skalibs/diuint.h @@ -0,0 +1,15 @@ +/* ISC license. */ + +#ifndef DIUINT_H +#define DIUINT_H + +typedef struct diuint diuint, *diuint_ref ; +struct diuint +{ + unsigned int left ; + unsigned int right ; +} ; + +#define DIUINT_ZERO { .left = 0, .right = 0 } + +#endif diff --git a/src/include/skalibs/diuint32.h b/src/include/skalibs/diuint32.h new file mode 100644 index 0000000..cd8ae75 --- /dev/null +++ b/src/include/skalibs/diuint32.h @@ -0,0 +1,17 @@ +/* ISC license. */ + +#ifndef DIUINT32_H +#define DIUINT32_H + +#include <skalibs/uint32.h> + +typedef struct diuint32 diuint32, *diuint32_ref ; +struct diuint32 +{ + uint32 left ; + uint32 right ; +} ; + +#define DIUINT32_ZERO { .left = 0, .right = 0 } + +#endif diff --git a/src/include/skalibs/djbtime.h b/src/include/skalibs/djbtime.h new file mode 100644 index 0000000..60a1d0b --- /dev/null +++ b/src/include/skalibs/djbtime.h @@ -0,0 +1,70 @@ +/* ISC license. */ + +#ifndef DJBTIME_H +#define DJBTIME_H + +#include <time.h> +#include <skalibs/config.h> +#include <skalibs/uint32.h> +#include <skalibs/uint64.h> +#include <skalibs/tai.h> + + +/* UTC <--> TAI conversions */ +/* sysclock can be either TAI-10 or UTC */ + +extern int utc_from_tai (uint64 *, tai_t const *) ; +extern int tai_from_utc (tai_t *, uint64) ; +extern int utc_from_sysclock (uint64 *) ; +extern int sysclock_from_utc (uint64 *) ; + + +/* NTP internal format */ + +#define NTP_OFFSET 2208988800UL +extern int ntp_from_tain (uint64 *, tain_t const *) ; +extern int tain_from_ntp (tain_t *, uint64) ; + + +/* localtime handling - replaces caltimedate functions */ +/* ltm64 can be either TAI-10 or UTC depending on --enable-right-tz */ +/* normally ltm64 is the same as sysclock, but we allow it to be different */ +/* for instance for musl TAI-10 systems */ + +typedef struct localtmn_s localtmn_t, *localtmn_t_ref ; +struct localtmn_s +{ + struct tm tm ; + uint32 nano ; +} ; + +extern int ltm64_from_tai (uint64 *, tai_t const *) ; +extern int tai_from_ltm64 (tai_t *, uint64) ; +extern int ltm64_from_utc (uint64 *) ; +extern int utc_from_ltm64 (uint64 *) ; +extern int ltm64_from_sysclock (uint64 *) ; +extern int sysclock_from_ltm64 (uint64 *) ; + +extern int localtm_from_ltm64 (struct tm *, uint64, int) ; +extern int ltm64_from_localtm (uint64 *, struct tm const *) ; +extern int localtm_from_sysclock (struct tm *, uint64, int) ; +extern int sysclock_from_localtm (uint64 *, struct tm const *) ; +extern int localtm_from_utc (struct tm *, uint64, int) ; +extern int utc_from_localtm (uint64 *, struct tm const *) ; +extern int localtm_from_tai (struct tm *, tai_t const *, int) ; +extern int tai_from_localtm (tai_t *, struct tm const *) ; + +extern int localtmn_from_tain (localtmn_t_ref, tain_t const *, int) ; +extern int tain_from_localtmn (tain_t *, localtmn_t const *) ; +extern int localtmn_from_sysclock (localtmn_t_ref, tain_t const *, int) ; +extern int sysclock_from_localtmn (tain_t *, localtmn_t const *) ; + +#define LOCALTM_FMT 21 +extern unsigned int localtm_fmt (char *, struct tm const *) ; +extern unsigned int localtm_scan (char const *, struct tm *) ; + +#define LOCALTMN_FMT 31 +extern unsigned int localtmn_fmt (char *, localtmn_t const *) ; +extern unsigned int localtmn_scan (char const *, localtmn_t_ref) ; + +#endif diff --git a/src/include/skalibs/djbunix.h b/src/include/skalibs/djbunix.h new file mode 100644 index 0000000..b5f5db4 --- /dev/null +++ b/src/include/skalibs/djbunix.h @@ -0,0 +1,149 @@ +/* ISC license. */ + +#ifndef DJBUNIX_H +#define DJBUNIX_H + +#include <sys/types.h> +#include <sys/uio.h> +#include <sys/wait.h> +#include <sys/stat.h> +#include <unistd.h> +#include <skalibs/gccattributes.h> +#include <skalibs/uint64.h> +#include <skalibs/stralloc.h> +#include <skalibs/envalloc.h> +#include <skalibs/env.h> /* compatibility */ + +#define DJBUNIX_FLAG_NB 0x01U +#define DJBUNIX_FLAG_COE 0x02U + +extern int coe (int) ; +extern int uncoe (int) ; +extern int ndelay_on (int) ; +extern int ndelay_off (int) ; +extern int pipe_internal (int *, unsigned int) ; +#define pipenb(p) pipe_internal(p, DJBUNIX_FLAG_NB) +#define pipecoe(p) pipe_internal(p, DJBUNIX_FLAG_COE) +#define pipenbcoe(p) pipe_internal(p, DJBUNIX_FLAG_NB|DJBUNIX_FLAG_COE) +extern int fd_copy (int, int) ; +extern int fd_copy2 (int, int, int, int) ; +extern int fd_move (int, int) ; +extern int fd_move2 (int, int, int, int) ; +extern int fd_close (int) ; +extern int fd_chmod (int, unsigned int) ; +extern int fd_chown (int, unsigned int, unsigned int) ; +extern int fd_sync (int) ; +extern int fd_cat (int, int) ; +extern unsigned int fd_catn (int, int, unsigned int) ; +extern int fd_ensure_open (int, int) ; +#define fd_sanitize() (fd_ensure_open(0, 0) && fd_ensure_open(1, 1)) +extern int lock_ex (int) ; +extern int lock_exnb (int) ; +extern int lock_sh (int) ; +extern int lock_shnb (int) ; +extern int lock_un (int) ; +extern int open2 (char const *, unsigned int) ; +extern int open3 (char const *, unsigned int, unsigned int) ; +extern int open_read (char const *) ; +extern int open_readb (char const *) ; +extern int open_excl (char const *) ; +extern int open_append (char const *) ; +extern int open_create (char const *) ; +extern int open_trunc (char const *) ; +extern int open_write (char const *) ; +extern int socket_internal (int, int, int, unsigned int) ; +extern int socketpair_internal (int, int, int, unsigned int, int *) ; + +extern int pathexec_env (char const *, char const *) ; +extern void pathexec_r (char const *const *, char const *const *, unsigned int, char const *, unsigned int) ; +extern void pathexec_r_name (char const *, char const *const *, char const *const *, unsigned int, char const *, unsigned int) ; +extern void pathexec_fromenv (char const *const *, char const *const *, unsigned int) ; +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 *) ; +extern void pathexec0 (char const *const *) ; + +#define prot_gid(gid) setgid(gid) +#define prot_uid(uid) setuid(uid) +extern int prot_readgroups (char const *, gid_t *, unsigned int) ; +extern int prot_grps (char const *) ; +extern int prot_setuidgid (char const *) ; + +extern long seek_cur (int) ; +extern int seek_set (int, long) ; +extern int seek_end (int) ; +extern int seek_trunc (int, long) ; +#define seek_begin(fd) (seek_set((fd), 0)) + +extern pid_t wait_nointr (int *) ; +extern pid_t waitpid_nointr (pid_t, int *, int) ; +#define wait_pid(pid, wstat) waitpid_nointr(pid, (wstat), 0) +#define wait_nohang(wstat) waitpid_nointr(-1, (wstat), WNOHANG) +extern pid_t wait_pid_nohang (pid_t, int *) ; +extern int wait_pids_nohang (pid_t const *, unsigned int, int *) ; +#define wait_status(w) (WIFSIGNALED(w) ? 126 : WEXITSTATUS(w)) +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) +/* extern char *realpath (char const *, char *) ; */ +extern char *realpath_tmp (char const *, char *, stralloc *) ; +extern int sarealpath (stralloc *, char const *) ; +extern int sarealpath_tmp (stralloc *, char const *, stralloc *) ; +/* extern char *basename (char *) ; */ +extern int sabasename (stralloc *, char const *, unsigned int) ; +/* extern char *dirname (char *) ; */ +extern int sadirname (stralloc *, char const *, unsigned int) ; +extern int sagetcwd (stralloc *) ; +extern int sareadlink (stralloc *, char const *) ; +extern int sagethostname (stralloc *) ; + +extern int slurp (stralloc *, int) ; +extern int openslurpclose (stralloc *, char const *) ; +extern int openreadclose (char const *, stralloc *, unsigned int) ; +extern int openreadnclose (char const *, char *, unsigned int) ; +extern int openreadfileclose (char const *, stralloc *, unsigned int) ; + +#define openwritenclose_unsafe(f, s, n) openwritenclose_unsafe_internal(f, s, (n), 0, 0, 0) +#define openwritenclose_unsafe_sync(f, s, n) openwritenclose_unsafe_internal(f, s, (n), 0, 0, 1) +#define openwritenclose_unsafe_devino(f, s, n, dev, ino) openwritenclose_unsafe_internal(f, s, n, dev, (ino), 0) +#define openwritenclose_unsafe_devino_sync(f, s, n, dev, ino) openwritenclose_unsafe_internal(f, s, n, dev, (ino), 1) +extern int openwritenclose_unsafe_internal (char const *, char const *, unsigned int, uint64 *, uint64 *, int) ; + +#define openwritenclose_suffix(f, s, n, t) openwritenclose_suffix_internal(f, s, n, 0, 0, 0, t) +#define openwritenclose_suffix_sync(f, s, n, t) openwritenclose_suffix_internal(f, s, n, 0, 0, 1, t) +#define openwritenclose_suffix_devino(f, s, n, t, dev, ino) openwritenclose_suffix_internal(f, s, n, dev, (ino), 0, t) +#define openwritenclose_suffix_devino_sync(f, s, n, t, dev, ino) openwritenclose_suffix_internal(f, s, n, dev, (ino), 1, t) +extern int openwritenclose_suffix_internal (char const *, char const *, unsigned int, uint64 *, uint64 *, int, char const *) ; + +extern int rm_rf (char const *) ; +extern int rm_rf_tmp (char const *, stralloc *) ; +extern int rm_rf_in_tmp (stralloc *, unsigned int) ; /* caution ! */ +extern int rmstar (char const *) ; +extern int rmstar_tmp (char const *, stralloc *) ; + + + /* Simple spawn functions. 0 for no communication, 1 for a child/parent pipe. */ + +extern pid_t child_spawn0 (char const *, char const *const *, char const *const *) ; +extern pid_t child_spawn1 (char const *, char const *const *, char const *const *, int *, int) ; + + + /* + Unified function to fork a child with communication canals. + * uses posix_spawn() if available, else uses fork+exec + * requests n (the last arg) communication fds between parent and child + * if n=1, the fd is a Unix socket. If more canals are needed, you can + pass them through that socket. + * if n>=2, the fds are pipes, parent reads on even and writes on odd. + */ + +extern pid_t child_spawn (char const *, char const *const *, char const *const *, int *, unsigned int) ; + +#endif diff --git a/src/include/skalibs/env.h b/src/include/skalibs/env.h new file mode 100644 index 0000000..ccb3aac --- /dev/null +++ b/src/include/skalibs/env.h @@ -0,0 +1,26 @@ +/* ISC license. */ + +#ifndef ENV_H +#define ENV_H + +#include <skalibs/gccattributes.h> +#include <skalibs/stralloc.h> + +extern unsigned int env_len (char const *const *) gccattr_pure ; +extern char const *env_get (char const *) gccattr_pure ; +extern char const *env_get2 (char const *const *, char const *) gccattr_pure ; +extern char const *ucspi_get (char const *) gccattr_pure ; +extern int env_addmodif (stralloc *, char const *, char const *) ; +extern int env_make (char const **, unsigned int, char const *, unsigned int) ; +extern unsigned int env_merge (char const **, unsigned int, char const *const *, unsigned int, char const *, unsigned int) ; +extern int env_string (stralloc *, char const *const *, unsigned int) ; + +#define SKALIBS_ENVDIR_VERBATIM 0x01 +#define SKALIBS_ENVDIR_NOCHOMP 0x02 +extern int envdir_internal (char const *, stralloc *, unsigned int, char) ; +#define envdir(path, sa) envdir_internal(path, (sa), 0, '\n') +#define envdir_leaveblanks(path, sa) envdir_internal(path, (sa), SKALIBS_ENVDIR_NOCHOMP, '\n') +#define envdir_verbatim_chomp(path, sa) envdir_internal(path, (sa), SKALIBS_ENVDIR_VERBATIM, '\n') +#define envdir_verbatim(path, sa) envdir_internal(path, (sa), SKALIBS_ENVDIR_VERBATIM|SKALIBS_ENVDIR_NOCHOMP, '\n') + +#endif diff --git a/src/include/skalibs/envalloc.h b/src/include/skalibs/envalloc.h new file mode 100644 index 0000000..1ebcd6b --- /dev/null +++ b/src/include/skalibs/envalloc.h @@ -0,0 +1,15 @@ +/* ISC license. */ + +#ifndef ENVALLOC_H +#define ENVALLOC_H + +#include <skalibs/genalloc.h> + +#define ENVALLOC_ZERO GENALLOC_ZERO + +extern int envalloc_make (genalloc *, unsigned int, char const *, unsigned int) ; +extern int envalloc_uniq (genalloc *, char) ; +extern int envalloc_merge (genalloc *, char const *const *, unsigned int, char const *, unsigned int) ; +extern int envalloc_0 (genalloc *) ; + +#endif diff --git a/src/include/skalibs/environ.h b/src/include/skalibs/environ.h new file mode 100644 index 0000000..6bf3041 --- /dev/null +++ b/src/include/skalibs/environ.h @@ -0,0 +1,8 @@ +/* ISC license. */ + +#ifndef ENVIRON_H +#define ENVIRON_H + +extern char **environ ; + +#endif diff --git a/src/include/skalibs/fmtscan.h b/src/include/skalibs/fmtscan.h new file mode 100644 index 0000000..ccfd160 --- /dev/null +++ b/src/include/skalibs/fmtscan.h @@ -0,0 +1,53 @@ +/* ISC license. */ + +#ifndef FMTSCAN_H +#define FMTSCAN_H + +#include <skalibs/gccattributes.h> +#include <skalibs/uint32.h> + + + /* fmt */ + + +extern unsigned char fmtscan_asc (unsigned char) gccattr_const ; + +extern unsigned int str_fmt (char *, char const *) ; +extern unsigned int strn_fmt (char *, char const *, unsigned int) ; + +#define IP4_FMT 20 +extern unsigned int ip4_fmt (char *, char const *) ; +extern unsigned int ip4_fmtu32 (char *, uint32) ; + +extern unsigned int ucharn_fmt (char *, char const *, unsigned int) ; +extern unsigned int ucharn_fmt_little (char *, char const *, unsigned int) ; + +#define IP6_FMT 40 +extern unsigned int ip6_fmt (char *, char const *) ; + +#define short_fmt(s, u) long_fmt((s), (long)(u)) +#define int_fmt(s, u) long_fmt((s), (long)(u)) +extern unsigned int long_fmt (char *, long) ; + + + /* scan */ + + +extern unsigned char fmtscan_num (unsigned char, unsigned char) gccattr_const ; + +extern unsigned int ip4_scan (char const *, char *) ; +extern unsigned int ip4_scanu32 (char const *, uint32 *) ; +extern unsigned int ip4_scanlist_u32 (uint32 *, unsigned int, char const *, unsigned int *) ; +extern unsigned int ip4_scanlist (char *, unsigned int, char const *, unsigned int *) ; +extern unsigned int ip6_scan (char const *, char *) ; +extern unsigned int ip6_scanlist (char *, unsigned int, char const *, unsigned int *) ; + +extern unsigned int ucharn_scan (char const *, char *, unsigned int) ; +extern unsigned int ucharn_scan_little (char const *, char *, unsigned int) ; +extern unsigned int ucharn_findlen (char const *) gccattr_pure ; + +extern unsigned int short_scan (char const *, short *) ; +extern unsigned int int_scan (char const *, int *) ; +extern unsigned int long_scan (char const *, long *) ; + +#endif diff --git a/src/include/skalibs/functypes.h b/src/include/skalibs/functypes.h new file mode 100644 index 0000000..15cdbcc --- /dev/null +++ b/src/include/skalibs/functypes.h @@ -0,0 +1,33 @@ +/* ISC license. */ + +#ifndef FUNCTYPES_H +#define FUNCTYPES_H + +typedef int uintcmpfunc_t (unsigned int, unsigned int, void *) ; +typedef uintcmpfunc_t *uintcmpfunc_t_ref ; + +typedef int cmpfunc_t (void const *, void const *, void *) ; +typedef cmpfunc_t *cmpfunc_t_ref ; + +typedef void *dtokfunc_t (unsigned int, void *) ; +typedef dtokfunc_t *dtokfunc_t_ref ; + +typedef int iterfunc_t (char *, void *) ; +typedef iterfunc_t *iterfunc_t_ref ; + +typedef void freefunc_t (void *) ; +typedef freefunc_t *freefunc_t_ref ; + +typedef int initfunc_t (void *) ; +typedef initfunc_t *initfunc_t_ref ; + +typedef unsigned int uinitfunc_t (void *) ; +typedef uinitfunc_t *uinitfunc_t_ref ; + +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 ; + +#endif diff --git a/src/include/skalibs/gccattributes.h b/src/include/skalibs/gccattributes.h new file mode 100644 index 0000000..0584480 --- /dev/null +++ b/src/include/skalibs/gccattributes.h @@ -0,0 +1,61 @@ +/* ISC license. */ + +#ifndef GCCATTRIBUTES_H +#define GCCATTRIBUTES_H + +#ifdef __GNUC__ + +#define gccattr_noreturn __attribute__((__noreturn__)) +#define gccattr_noinline __attribute__((__noinline__)) +#define gccattr_inline __attribute__((__always_inline__)) +#define gccattr_const __attribute__((__const__)) +#define gccattr_unused __attribute__((__unused__)) +#define gccattr_used __attribute__((__used__)) +#define gccattr_weak __attribute__((__weak__)) +#define gccattr_aligned __attribute__((__aligned__)) + +# if (__GNUC__ >= 3) || ((__GNUC__ == 2) && (__GNUC_MINOR__ >= 96)) +#define gccattr_malloc __attribute__((__malloc__)) +#define gccattr_pure __attribute__((__pure__)) +# else +#define gccattr_malloc +#define gccattr_pure +# endif + +# if (__GNUC__ >= 3) +#define gccattr_deprecated __attribute__((__deprecated__)) +# else +#define gccattr_deprecated +# endif + +#else + +#define gccattr_noreturn +#define gccattr_noinline +#define gccattr_inline +#define gccattr_const +#define gccattr_unused +#define gccattr_used +#define gccattr_weak +#define gccattr_aligned +#define gccattr_malloc +#define gccattr_pure +#define gccattr_deprecated + +#endif + +#ifdef GCCATTR_COMPAT_0_22 +#define _a_noreturn gccattr_noreturn +#define _a_noinline gccattr_noinline +#define _a_inline gccattr_inline +#define _a_const gccattr_const +#define _a_unused gccattr_unused +#define _a_used gccattr_used +#define _a_weak gccattr_weak +#define _a_aligned gccattr_aligned +#define _a_malloc gccattr_malloc +#define _a_pure gccattr_pure +#define _a_deprecated gccattr_deprecated +#endif + +#endif diff --git a/src/include/skalibs/genalloc.h b/src/include/skalibs/genalloc.h new file mode 100644 index 0000000..1aa0613 --- /dev/null +++ b/src/include/skalibs/genalloc.h @@ -0,0 +1,35 @@ +/* ISC license. */ + +#ifndef GENALLOC_H +#define GENALLOC_H + +#include <skalibs/stralloc.h> +#include <skalibs/functypes.h> + +typedef stralloc genalloc, *genalloc_ref ; + +#define GENALLOC_ZERO STRALLOC_ZERO +#define genalloc_zero stralloc_zero + +#define genalloc_s(type, g) ((type *)((g)->s)) +#define genalloc_len(type, g) ((g)->len/sizeof(type)) +#define genalloc_setlen(type, g, n) ((g)->len = (n)*sizeof(type)) + +#define genalloc_ready(type, g, n) stralloc_ready((g), (n)*sizeof(type)) +#define genalloc_ready_tuned(type, g, n, base, fracnum, fracden) stralloc_ready_tuned((g), (n)*sizeof(type), base, fracnum, fracden) +#define genalloc_readyplus(type, g, n) stralloc_readyplus((g), (n)*sizeof(type)) +#define genalloc_free(type, g) stralloc_free(g) +#define genalloc_shrink(type, g) stralloc_shrink(g) +#define genalloc_catb(type, g, s, n) stralloc_catb((g), (char const *)(s), (n)*sizeof(type)) +#define genalloc_copyb(type, g, s, n) stralloc_copyb((g), (char const *)(s), (n)*sizeof(type)) +#define genalloc_copy(type, g1, g2) stralloc_copy((g1), g2) +#define genalloc_cat(type, g1, g2) stralloc_cat((g1), g2) +#define genalloc_append(type, g, p) stralloc_catb((g), (char const *)(p), sizeof(type)) +#define genalloc_reverse(type, g) stralloc_reverse_blocks((g), sizeof(type)) +#define genalloc_insertb(type, g, offset, s, n) stralloc_insertb((g), (offset)*sizeof(type), (char const *)(s), (n)*sizeof(type)) +#define genalloc_insert(type, g1, offset, g2) stralloc_insert((g1), (offset)*sizeof(type), (g2)) + +#define genalloc_deepfree(type, g, f) genalloc_deepfree_size(g, (freefunc_t_ref)(f), sizeof(type)) +extern void genalloc_deepfree_size (genalloc *, freefunc_t_ref, unsigned int) ; + +#endif diff --git a/src/include/skalibs/genset.h b/src/include/skalibs/genset.h new file mode 100644 index 0000000..5eb47d7 --- /dev/null +++ b/src/include/skalibs/genset.h @@ -0,0 +1,37 @@ +/* ISC license. */ + +#ifndef GENSET_H +#define GENSET_H + +#include <skalibs/functypes.h> + +typedef struct genset_s genset, *genset_ref ; +struct genset_s +{ + char *storage ; + unsigned int *freelist ; + unsigned int esize ; + unsigned int max ; + unsigned int sp ; +} ; + +#define GENSET_ZERO { .storage = 0, .freelist = 0, .esize = 1, .max = 0, .sp = 0 } +extern void genset_init (genset_ref, void *, unsigned int *, unsigned int, unsigned int) ; +#define GENSET_init(g, type, storage, fl, size) genset_init(g, storage, fl, sizeof(type), size) + +#define genset_p(type, g, i) ((type *)((g)->storage + (i) * (g)->esize)) +extern unsigned int genset_new (genset_ref) ; +extern int genset_delete (genset_ref, unsigned int) ; +#define genset_n(g) ((g)->max - (g)->sp) +extern unsigned int genset_iter (genset_ref, iterfunc_t_ref, void *) ; + + +#define GENSETB_TYPE(type, size) struct { type storage[size] ; unsigned int freelist[size] ; genset info ; } +#define GENSETB_init(type, g, size) GENSET_init(&(g)->info, type, (g)->storage, (g)->freelist, size) +#define gensetb_p(type, g, i) genset_p(type, &(g)->info, i) +#define gensetb_new(g) genset_new(&(g)->info) +#define gensetb_delete(g, i) genset_delete(&(g)->info, i) +#define gensetb_n(g) genset_n(&(g)->info) +#define gensetb_iter(g, f, p) genset_iter(&(g)->info, f, p) + +#endif diff --git a/src/include/skalibs/gensetdyn.h b/src/include/skalibs/gensetdyn.h new file mode 100644 index 0000000..4fe396b --- /dev/null +++ b/src/include/skalibs/gensetdyn.h @@ -0,0 +1,40 @@ +/* ISC license. */ + +#ifndef GENSETDYN_H +#define GENSETDYN_H + +#include <skalibs/stralloc.h> +#include <skalibs/genalloc.h> +#include <skalibs/functypes.h> + +typedef struct gensetdyn_s gensetdyn, *gensetdyn_ref ; +struct gensetdyn_s +{ + stralloc storage ; + genalloc freelist ; /* array of unsigned int */ + unsigned int esize ; + unsigned int base ; + unsigned int fracnum ; + unsigned int fracden ; +} ; + +#define GENSETDYN_ZERO { .storage = STRALLOC_ZERO, .freelist = GENALLOC_ZERO, .esize = 1, .base = 0, .fracnum = 0, .fracden = 1 } +extern gensetdyn const gensetdyn_zero ; + +#define GENSETDYN_INIT(type, b, num, den) { .storage = STRALLOC_ZERO, .freelist = GENALLOC_ZERO, .esize = sizeof(type), .base = (b), .fracnum = (num), .fracden = (den) } +extern void gensetdyn_init (gensetdyn_ref, unsigned int, unsigned int, unsigned int, unsigned int) ; + +#define gensetdyn_n(g) ((g)->storage.len - genalloc_len(unsigned int, &(g)->freelist)) +extern int gensetdyn_ready (gensetdyn_ref, unsigned int) ; +#define gensetdyn_readyplus(x, n) gensetdyn_ready(x, gensetdyn_n(x) + (n)) +extern void gensetdyn_free (gensetdyn_ref) ; + +extern int gensetdyn_new (gensetdyn_ref, unsigned int *) ; +extern int gensetdyn_delete (gensetdyn_ref, unsigned int) ; + +#define gensetdyn_p(g, i) ((g)->storage.s + (i) * (g)->esize) +#define GENSETDYN_P(type, g, i) ((type *)gensetdyn_p(g, i)) + +extern unsigned int gensetdyn_iter (gensetdyn_ref, iterfunc_t_ref, void *) ; + +#endif diff --git a/src/include/skalibs/genwrite.h b/src/include/skalibs/genwrite.h new file mode 100644 index 0000000..9ae0fb9 --- /dev/null +++ b/src/include/skalibs/genwrite.h @@ -0,0 +1,35 @@ +/* ISC license. */ + +#ifndef GENWRITE_H +#define GENWRITE_H + +typedef int genwrite_put_func_t (void *, char const *, unsigned int) ; +typedef genwrite_put_func_t *genwrite_put_func_t_ref ; + +typedef int genwrite_flush_func_t (void *) ; +typedef genwrite_flush_func_t *genwrite_flush_func_t_ref ; + +typedef struct genwrite_s genwrite_t, *genwrite_t_ref ; +struct genwrite_s +{ + genwrite_put_func_t_ref put ; + genwrite_flush_func_t_ref flush ; + void *target ; +} ; +#define GENWRITE_ZERO { .put = 0, .flush = 0, .target = 0 } + +extern genwrite_put_func_t genwrite_put_stralloc ; +extern genwrite_flush_func_t genwrite_flush_stralloc ; +extern genwrite_put_func_t genwrite_put_buffer ; +extern genwrite_flush_func_t genwrite_flush_buffer ; +extern genwrite_put_func_t genwrite_put_bufalloc ; +extern genwrite_flush_func_t genwrite_flush_bufalloc ; + +#define GENWRITE_STRALLOC_INIT(sa) { .put = &genwrite_put_stralloc, .flush = &genwrite_flush_stralloc, .target = (sa) } +#define GENWRITE_BUFFER_INIT(b) { .put = &genwrite_put_buffer, .flush = &genwrite_flush_buffer, .target = (b) } +#define GENWRITE_BUFALLOC_INIT(ba) { .put = &genwrite_put_bufalloc, .flush = &genwrite_flush_bufalloc, .target = (ba) } + +extern genwrite_t genwrite_stdout ; +extern genwrite_t genwrite_stderr ; + +#endif diff --git a/src/include/skalibs/getpeereid.h b/src/include/skalibs/getpeereid.h new file mode 100644 index 0000000..4aa2898 --- /dev/null +++ b/src/include/skalibs/getpeereid.h @@ -0,0 +1,10 @@ +/* ISC license. */ + +#ifndef GETPEEREID_H +#define GETPEEREID_H + +#include <sys/types.h> + +extern int getpeereid (int, uid_t *, gid_t *) ; + +#endif diff --git a/src/include/skalibs/iobuffer.h b/src/include/skalibs/iobuffer.h new file mode 100644 index 0000000..c1864cf --- /dev/null +++ b/src/include/skalibs/iobuffer.h @@ -0,0 +1,117 @@ +/* ISC license. */ + +#ifndef IOBUFFER_H +#define IOBUFFER_H + +#define IOBUFFER_SIZE 65536U + + /* iobufferu */ + +#include <skalibs/buffer.h> +#include <skalibs/djbunix.h> + +#define IOBUFFERU_SIZE (IOBUFFER_SIZE+1) + +typedef struct iobufferu_s iobufferu, *iobufferu_ref ; +struct iobufferu_s +{ + buffer b[2] ; + char *buf ; +} ; + +extern int iobufferu_init (iobufferu_ref, int, int) ; +extern int iobufferu_fill (iobufferu_ref) ; +extern int iobufferu_flush (iobufferu_ref) ; +extern void iobufferu_finish (iobufferu_ref) ; + +#define iobufferu_len(u) buffer_len(&(u)->b[0]) +#define iobufferu_available(u) buffer_available(&(u)->b[1]) +#define iobufferu_isempty(u) buffer_isempty(&(u)->b[0]) +#define iobufferu_isfull(u) buffer_isfull(&(u)->b[1]) +#define iobufferu_fd(u, h) buffer_fd((u)->b[h]) +#define iobufferu_isreadable(u) iobufferu_available(u) +#define iobufferu_iswritable(u) iobufferu_len(u) +#define iobufferu_nonblock(u, h) ndelay_on(iobufferu_fd(u, h)) +#define iobufferu_block(u, h) ndelay_off(iobufferu_fd(u, h)) +#define iobufferu_nbstate(u, h, j) (j ? iobufferu_nonblock(u, h) : iobufferu_block(u, h)) + + + /* iobufferk */ + +#define IOBUFFERK_SIZE IOBUFFER_SIZE + +typedef struct iobufferk_s iobufferk, *iobufferk_ref ; +struct iobufferk_s +{ + int fd[2] ; + int p[2] ; + unsigned int n ; + unsigned int type : 2 ; + unsigned int nb : 2 ; +} ; + +typedef int iobufferk_io_func_t (iobufferk_ref) ; +typedef iobufferk_io_func_t *iobufferk_io_func_t_ref ; +typedef void iobufferk_finish_func_t (iobufferk_ref) ; +typedef iobufferk_finish_func_t *iobufferk_finish_func_t_ref ; + +extern iobufferk_io_func_t iobufferk_nosys ; +extern iobufferk_io_func_t iobufferk_isworking ; + +extern int iobufferk_init (iobufferk_ref, int, int) ; +extern iobufferk_io_func_t_ref const iobufferk_fill_f[4] ; +extern iobufferk_io_func_t_ref const iobufferk_flush_f[4] ; +extern iobufferk_finish_func_t_ref const iobufferk_finish_f[4] ; + +#define iobufferk_fill(k) (*iobufferk_fill_f[(k)->type])(k) +#define iobufferk_flush(k) (*iobufferk_flush_f[(k)->type])(k) +#define iobufferk_finish(k) (*iobufferk_finish_f[(k)->type])(k) +#define iobufferk_len(k) ((k)->n) +#define iobufferk_available(k) (IOBUFFERK_SIZE - (k)->n) +#define iobufferk_isempty(k) (!iobufferk_len(k)) +#define iobufferk_isfull(k) (!iobufferk_available(k)) +#define iobufferk_fd(k, h) ((k)->fd[h]) +#define iobufferk_isreadable(k) iobufferk_available(k) +#define iobufferk_iswritable(k) iobufferk_len(k) +#define iobufferk_nonblock(k, h) ((k)->nb |= (1 << (h)), 0) +#define iobufferk_block(k, h) ((k)->nb &= (3 - (1 << (h))), 0) +#define iobufferk_nbstate(k, h, j) (j ? iobufferk_nonblock(k, h) : iobufferk_block(k, h)) + + + /* iobuffer */ + +typedef union iobufferku_u iobufferku, *iobufferku_ref ; +union iobufferku_u +{ + iobufferk k ; + iobufferu u ; +} ; + +typedef struct iobuffer_s iobuffer, *iobuffer_ref ; +struct iobuffer_s +{ + iobufferku x ; + unsigned int isk : 1 ; +} ; + +extern int iobuffer_ufromk (iobufferu_ref, iobufferk_ref) ; +extern int iobuffer_kfromu (iobufferk_ref, iobufferu_ref) ; +extern int iobuffer_salvage (iobuffer_ref) ; + +extern int iobuffer_init (iobuffer_ref, int, int) ; +extern int iobuffer_fill (iobuffer_ref) ; +extern int iobuffer_flush (iobuffer_ref) ; + +#define iobuffer_finish(b) ((b)->isk ? iobufferk_finish(&(b)->x.k) : iobufferu_finish(&(b)->x.u)) +#define iobuffer_len(b) ((b)->isk ? iobufferk_len(&(b)->x.k) : iobufferu_len(&(b)->x.u)) +#define iobuffer_available(b) ((b)->isk ? iobufferk_available(&(b)->x.k) : iobufferu_available(&(b)->x.u)) +#define iobuffer_isempty(b) ((b)->isk ? iobufferk_isempty(&(b)->x.k) : iobufferu_isempty(&(b)->x.u)) +#define iobuffer_isfull(b) ((b)->isk ? iobufferk_isfull(&(b)->x.k) : iobufferu_isfull(&(b)->x.u)) +#define iobuffer_fd(b, h) ((b)->isk ? iobufferk_fd(&(b)->x.k, h) : iobufferu_fd(&(b)->x.u, h)) +#define iobuffer_isreadable(b) ((b)->isk ? iobufferk_isreadable(&(b)->x.k) : iobufferu_isreadable(&(b)->x.u)) +#define iobuffer_iswritable(b) ((b)->isk ? iobufferk_iswritable(&(b)->x.k) : iobufferu_iswritable(&(b)->x.u)) +#define iobuffer_nonblock(b, h) ((b)->isk ? iobufferk_nonblock(&(b)->x.k, h) : iobufferu_nonblock(&(b)->x.u, h)) +#define iobuffer_block(b, h) ((b)->isk ? iobufferk_block(&(b)->x.k, h) : iobufferu_block(&(b)->x.u, h)) +#define iobuffer_nbstate(b, h, j) ((b)->isk ? iobufferk_nbstate(&(b)->x.k, h, j) : iobufferu_nbstate(&(b)->x.u, h, j)) + +#endif diff --git a/src/include/skalibs/iopause.h b/src/include/skalibs/iopause.h new file mode 100644 index 0000000..d8f5e1c --- /dev/null +++ b/src/include/skalibs/iopause.h @@ -0,0 +1,32 @@ +/* ISC license. */ + +#ifndef IOPAUSE_H +#define IOPAUSE_H + +#include <sys/types.h> +#include <poll.h> +#include <skalibs/tai.h> + +typedef struct pollfd iopause_fd, *iopause_fd_ref ; + +#define IOPAUSE_READ (POLLIN|POLLHUP) +#define IOPAUSE_WRITE POLLOUT +#define IOPAUSE_EXCEPT (POLLERR|POLLHUP|POLLNVAL) + +typedef int iopause_func_t (iopause_fd *, unsigned int, tain_t const *, tain_t const *) ; +typedef iopause_func_t *iopause_func_t_ref ; + +extern iopause_func_t iopause_select ; +extern iopause_func_t iopause_poll ; +extern iopause_func_t iopause_ppoll ; + +extern iopause_func_t_ref const iopause_ ; +#define iopause (*iopause_) + +extern int iopause_stamp (iopause_fd *, unsigned int, tain_t const *, tain_t *) ; +#define iopause_g(x, n, deadline) iopause_stamp(x, n, (deadline), &STAMP) + +extern void deepsleepuntil (tain_t const *, tain_t *) ; +#define deepsleepuntil_g(deadline) deepsleepuntil((deadline), &STAMP) + +#endif diff --git a/src/include/skalibs/kolbak.h b/src/include/skalibs/kolbak.h new file mode 100644 index 0000000..86a2170 --- /dev/null +++ b/src/include/skalibs/kolbak.h @@ -0,0 +1,32 @@ +/* ISC license. */ + +#ifndef KOLBAK_H +#define KOLBAK_H + +#include <skalibs/unixmessage.h> + +typedef struct kolbak_closure_s kolbak_closure_t, *kolbak_closure_t_ref ; +struct kolbak_closure_s +{ + unixmessage_handler_func_t_ref f ; + void *data ; +} ; +#define KOLBAK_CLOSURE_ZERO { .f = 0, .data = 0 } + +typedef struct kolbak_queue_s kolbak_queue_t, *kolbak_queue_t_ref ; +struct kolbak_queue_s +{ + kolbak_closure_t *x ; + unsigned int n ; + unsigned int head ; + unsigned int tail ; +} ; +#define KOLBAK_QUEUE_ZERO { .x = 0, .n = 0, .head = 0, .tail = 0 } +#define KOLBAK_QUEUE_INIT(s, len) { .x = (s), .n = (len), .head = 0, .tail = 0 } + +extern int kolbak_queue_init (kolbak_queue_t *, kolbak_closure_t *, unsigned int) ; +extern int kolbak_enqueue (kolbak_queue_t *, unixmessage_handler_func_t_ref, void *) ; +extern int kolbak_unenqueue (kolbak_queue_t *) ; +extern int kolbak_call (unixmessage_t const *, kolbak_queue_t *) ; + +#endif diff --git a/src/include/skalibs/lolstdio.h b/src/include/skalibs/lolstdio.h new file mode 100644 index 0000000..ec66da2 --- /dev/null +++ b/src/include/skalibs/lolstdio.h @@ -0,0 +1,30 @@ +/* ISC license. */ + +#ifndef LOLSTDIO_H +#define LOLSTDIO_H + +#include <stdarg.h> +#include <skalibs/buffer.h> +#include <skalibs/bufalloc.h> +#include <skalibs/strerr2.h> + +#ifdef DEBUG +# define LOLDEBUG(...) do \ + { \ + buffer_puts(buffer_2, PROG) ; \ + buffer_puts(buffer_2, ": debug: ") ; \ + bprintf(buffer_2, __VA_ARGS__) ; \ + buffer_putflush(buffer_2, "\n", 1) ; \ + } while (0) +#else +# define LOLDEBUG(...) +#endif + +extern int vbprintf (buffer *, char const *, va_list) ; +extern int bprintf (buffer *, char const *, ...) ; +extern int lolprintf (char const *, ...) ; + +extern int vbaprintf (bufalloc *, char const *, va_list) ; +extern int baprintf (bufalloc *, char const *, ...) ; + +#endif diff --git a/src/include/skalibs/md5.h b/src/include/skalibs/md5.h new file mode 100644 index 0000000..00e43cc --- /dev/null +++ b/src/include/skalibs/md5.h @@ -0,0 +1,21 @@ +/* ISC license. */ + +#ifndef MD5_H +#define MD5_H + +#include <skalibs/uint32.h> + +typedef struct MD5Schedule MD5Schedule, *MD5Schedule_ref ; +struct MD5Schedule +{ + uint32 buf[4] ; + uint32 bits[2] ; + unsigned char in[64] ; +} ; + +#define MD5_INIT() { .buf = { 0x67452301UL, 0xefcdab89UL, 0x98badcfeUL, 0x10325476UL }, .bits = { 0, 0 }, .in = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" } +extern void md5_init (MD5Schedule_ref) ; +extern void md5_update (MD5Schedule_ref, char const *, unsigned int) ; +extern void md5_final (MD5Schedule_ref, char * /* 16 chars */) ; + +#endif diff --git a/src/include/skalibs/mininetstring.h b/src/include/skalibs/mininetstring.h new file mode 100644 index 0000000..c275fb2 --- /dev/null +++ b/src/include/skalibs/mininetstring.h @@ -0,0 +1,13 @@ +/* ISC license. */ + +#ifndef MININETSTRING_H +#define MININETSTRING_H + +#include <skalibs/uint16.h> +#include <skalibs/uint32.h> +#include <skalibs/stralloc.h> + +extern int mininetstring_read (int, stralloc *, uint32 *) ; +extern int mininetstring_write (int, char const *, uint16, uint32 *) ; + +#endif diff --git a/src/include/skalibs/netstring.h b/src/include/skalibs/netstring.h new file mode 100644 index 0000000..ee5cd85 --- /dev/null +++ b/src/include/skalibs/netstring.h @@ -0,0 +1,24 @@ +/* ISC license. */ + +#ifndef NETSTRING_H +#define NETSTRING_H + +#include <skalibs/buffer.h> +#include <skalibs/siovec.h> +#include <skalibs/stralloc.h> + +extern int netstring_appendb (stralloc *, char const *, unsigned int) ; +#define netstring_appends(sa, s) netstring_appendb((sa), (s), str_len(s)) +#define netstring_append(to, from) netstring_appendb((to), (from)->s, (from)->len) +extern int netstring_appendv (stralloc *, siovec_t const *, unsigned int) ; + +extern int netstring_encode (stralloc *, char const *, unsigned int) ; +extern int netstring_decode (stralloc *, char const *, unsigned int) ; + +extern int netstring_okeof (buffer *, unsigned int) ; +extern int netstring_get (buffer *, stralloc *, unsigned int *) ; +extern int netstring_put (buffer *, char const *, unsigned int, unsigned int *) ; +#define netstring_putba(ba, s, n) netstring_appendb(&(ba)->x, s, n) +#define netstring_putbav(ba, v, n) netstring_appendv(&(ba)->x, v, n) + +#endif diff --git a/src/include/skalibs/nonposix.h b/src/include/skalibs/nonposix.h new file mode 100644 index 0000000..26af211 --- /dev/null +++ b/src/include/skalibs/nonposix.h @@ -0,0 +1,58 @@ +/* ISC license. */ + +#ifndef NONPOSIX_H +#define NONPOSIX_H + + + /* Drop all pretense of standardness: some libc headers are *more* + broken when you define standard feature test macros than when + you don't (I'm looking at you, FreeBSD). */ + +#undef _POSIX_C_SOURCE +#undef _XOPEN_SOURCE + + + /* Solaris: the socket API is not POSIX unless you enable this */ + +#ifndef _XPG4_2 +#define _XPG4_2 +#endif +#ifndef _XPG6 +#define _XPG6 +#endif + + + /* Solaris: for settimeofday() and similar. Notice how you + have to define by hand a macro with double underscores. */ + +#ifndef __EXTENSIONS__ +#define __EXTENSIONS__ +#endif + + + /* GNU: most extensions are unavailable unless you enable this */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif +#ifndef _BSD_SOURCE +#define _BSD_SOURCE +#endif + + + /* NetBSD: of course they had to have their own macros. */ + +#ifndef _NETBSD_SOURCE +#define _NETBSD_SOURCE +#endif +#ifndef _INCOMPLETE_XOPEN_C063 +#define _INCOMPLETE_XOPEN_C063 +#endif + + + /* old versions of BSD: system headers are not self-contained, + starting with sys/types.h is the usual workaround */ + +#include <sys/types.h> + +#endif diff --git a/src/include/skalibs/nsig.h b/src/include/skalibs/nsig.h new file mode 100644 index 0000000..f6bd240 --- /dev/null +++ b/src/include/skalibs/nsig.h @@ -0,0 +1,13 @@ +/* ISC license. */ + +#ifndef NSIG_H + +#include <signal.h> + +#define SKALIBS_NSIG 64 + +#ifndef NSIG +# define NSIG SKALIBS_NSIG +#endif + +#endif diff --git a/src/include/skalibs/random.h b/src/include/skalibs/random.h new file mode 100644 index 0000000..90aa0c0 --- /dev/null +++ b/src/include/skalibs/random.h @@ -0,0 +1,33 @@ +/* ISC license. */ + +/* MT-unsafe functions only. Use rrandom for MT-safety. */ + +#ifndef RANDOM_H +#define RANDOM_H + +#include <skalibs/gccattributes.h> +#include <skalibs/stralloc.h> + +extern int badrandom_init (void) ; +extern unsigned char badrandom_char (void) ; +extern unsigned int badrandom_int (unsigned int) ; +extern unsigned int badrandom_string (char *, unsigned int) ; +extern void badrandom_finish (void) ; + +extern int goodrandom_init (void) ; +extern unsigned char goodrandom_char (void) ; +extern unsigned int goodrandom_int (unsigned int) ; +extern unsigned int goodrandom_string (char *, unsigned int) ; +extern void goodrandom_finish (void) ; + +#define random_init badrandom_init +#define random_char badrandom_char +#define random_int badrandom_int +#define random_string badrandom_string +#define random_finish badrandom_finish + +extern int random_name (char *, unsigned int) ; +extern int random_sauniquename (stralloc *, unsigned int) ; +extern void random_unsort (char *, unsigned int, unsigned int) ; + +#endif diff --git a/src/include/skalibs/randomegd.h b/src/include/skalibs/randomegd.h new file mode 100644 index 0000000..28d4faa --- /dev/null +++ b/src/include/skalibs/randomegd.h @@ -0,0 +1,10 @@ +/* ISC license. */ + +#ifndef RANDOMEGD_H +#define RANDOMEGD_H + +extern int randomegd_open (char const *) ; +extern unsigned int randomegd_readb (int, char *, unsigned int) ; +extern unsigned int randomegd_readnb (int, char *, unsigned int) ; + +#endif diff --git a/src/include/skalibs/rc4.h b/src/include/skalibs/rc4.h new file mode 100644 index 0000000..16683ce --- /dev/null +++ b/src/include/skalibs/rc4.h @@ -0,0 +1,19 @@ +/* ISC license. */ + +#ifndef RC4_H +#define RC4_H + +#define RC4_THROWAWAY 128 + +typedef struct RC4Schedule RC4Schedule, *RC4Schedule_ref ; + +struct RC4Schedule +{ + unsigned char tab[256] ; + unsigned char x, y ; +} ; + +extern void rc4_init (RC4Schedule_ref, char const *, unsigned int) ; +extern void rc4 (RC4Schedule_ref, char const *, char *, unsigned int) ; + +#endif diff --git a/src/include/skalibs/rrandom.h b/src/include/skalibs/rrandom.h new file mode 100644 index 0000000..7f6a2aa --- /dev/null +++ b/src/include/skalibs/rrandom.h @@ -0,0 +1,36 @@ +/* ISC license. */ + +#ifndef RRANDOM_H +#define RRANDOM_H + +#include <skalibs/unirandom.h> + +typedef struct rrandominfo rrandominfo, *rrandominfo_ref, **rrandominfo_ref_ref ; +struct rrandominfo +{ + unirandom it ; + unsigned int ok ; +} ; + +#define RRANDOMINFO_ZERO { .it = UNIRANDOM_ZERO, .ok = 3 } + +typedef struct rrandom rrandom, *rrandom_ref, **rrandom_ref_ref ; +struct rrandom +{ + rrandominfo tries[3] ; + unsigned int n ; +} ; + +#define RRANDOM_ZERO { .tries = { RRANDOMINFO_ZERO, RRANDOMINFO_ZERO, RRANDOMINFO_ZERO }, .n = 0 } + +extern int rrandom_add (rrandom_ref, int (*) (unirandom_ref)) ; +extern int rrandom_finish (rrandom_ref) ; + +extern unsigned int rrandom_read (rrandom_ref, char *, unsigned int, unsigned int (*) (unirandom_ref, char *, unsigned int)) ; +extern unsigned int rrandom_readint (rrandom_ref, unsigned int, unsigned int (*) (unirandom_ref, char *, unsigned int)) ; +#define rrandom_readb(z, s, n) rrandom_read((z), (s), (n), &unirandom_readb) +#define rrandom_readnb(z, s, n) rrandom_read((z), (s), (n), &unirandom_readnb) + +extern unsigned int rrandom_name (rrandom_ref, char *, unsigned int, int) ; + +#endif diff --git a/src/include/skalibs/segfault.h b/src/include/skalibs/segfault.h new file mode 100644 index 0000000..732ad4f --- /dev/null +++ b/src/include/skalibs/segfault.h @@ -0,0 +1,11 @@ +/* ISC license. */ + +#ifndef SEGFAULT_H +#define SEGFAULT_H + +extern int sigsegv (void) ; +extern int sigfpe (void) ; + +#define segfault() sigsegv() + +#endif diff --git a/src/include/skalibs/selfpipe.h b/src/include/skalibs/selfpipe.h new file mode 100644 index 0000000..c587f93 --- /dev/null +++ b/src/include/skalibs/selfpipe.h @@ -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 diff --git a/src/include/skalibs/sgetopt.h b/src/include/skalibs/sgetopt.h new file mode 100644 index 0000000..367edf3 --- /dev/null +++ b/src/include/skalibs/sgetopt.h @@ -0,0 +1,46 @@ +/* ISC license. */ + +#ifndef SGETOPT_H +#define SGETOPT_H + + + /* reentrant */ + +typedef struct subgetopt_s subgetopt_t, *subgetopt_t_ref ; +struct subgetopt_s +{ + int ind ; + int err ; + int problem ; + char const *arg ; + unsigned int pos ; + char const *prog ; +} ; + +#define SUBGETOPT_ZERO { .ind = 1, .err = 1, .problem = 0, .arg = 0, .pos = 0, .prog = 0 } + +extern int subgetopt_r (int, char const *const *, char const *, subgetopt_t_ref) ; + + + /* non-reentrant */ + +extern int sgetopt_r (int, char const *const *, char const *, subgetopt_t_ref) ; + +extern subgetopt_t subgetopt_here ; + +#define subgetopt(argc, argv, opts) subgetopt_r((argc), (argv), (opts), &subgetopt_here) +#define sgetopt(argc, argv, opts) sgetopt_r((argc), (argv), (opts), &subgetopt_here) +#define sgetopt_prog() (subgetopt_here.prog = PROG) + +/* define SUBGETOPT_SHORT if you don't mind potential name conflicts */ + +#ifdef SUBGETOPT_SHORT +# define getopt sgetopt +# define optarg subgetopt_here.arg +# define optind subgetopt_here.ind +# define opterr subgetopt_here.err +# define optopt subgetopt_here.problem +# define opteof (-1) +#endif + +#endif diff --git a/src/include/skalibs/sha1.h b/src/include/skalibs/sha1.h new file mode 100644 index 0000000..03cdaf0 --- /dev/null +++ b/src/include/skalibs/sha1.h @@ -0,0 +1,22 @@ +/* ISC license. */ + +#ifndef SHA1_H +#define SHA1_H + +#include <skalibs/uint32.h> + +typedef struct SHA1Schedule SHA1Schedule, *SHA1Schedule_ref ; +struct SHA1Schedule +{ + uint32 buf[5] ; + uint32 bits[2] ; + uint32 in[16] ; + unsigned int b ; +} ; + +#define SHA1_INIT() { .buf = { 0x67452301UL, 0xefcdab89UL, 0x98badcfeUL, 0x10325476UL, 0xc3d2e1f0UL }, .bits = { 0, 0 }, .in = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, .b = 0 } +extern void sha1_init (SHA1Schedule_ref) ; +extern void sha1_update (SHA1Schedule_ref, char const *, unsigned int) ; +extern void sha1_final (SHA1Schedule_ref, char * /* 20 chars */) ; + +#endif diff --git a/src/include/skalibs/sha256.h b/src/include/skalibs/sha256.h new file mode 100644 index 0000000..8f28c38 --- /dev/null +++ b/src/include/skalibs/sha256.h @@ -0,0 +1,29 @@ +/* ISC license. */ + +/* SHA256 routines */ +/* Written by David Madore (<URL: http://www.madore.org/~david/ >) */ +/* Adapted by Laurent Bercot. */ +/* This version last modified 2010-01-08 */ + +/* Note: these routines do not depend on endianness. */ + +#ifndef SHA256_H +#define SHA256_H + +#include <skalibs/uint32.h> + +typedef struct SHA256Schedule_s SHA256Schedule, *SHA256Schedule_ref ; +struct SHA256Schedule_s +{ + uint32 buf[8] ; /* The eight chaining variables */ + uint32 bits[2] ; /* Count number of message bits */ + uint32 in[16] ; /* Data being fed in */ + unsigned int b ; /* Our position within the 512 bits (always between 0 and 63) */ +} ; + +#define SHA256_INIT() { .buf = { 0x6a09e667UL, 0xbb67ae85UL, 0x3c6ef372UL, 0xa54ff53aUL, 0x510e527fUL, 0x9b05688cUL, 0x1f83d9abUL, 0x5be0cd19UL }, .bits = { 0, 0 }, .in = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, .b = 0 } +extern void sha256_init (SHA256Schedule_ref) ; +extern void sha256_update (SHA256Schedule_ref, char const *, unsigned int) ; +extern void sha256_final (SHA256Schedule_ref, char *digest) ; + +#endif diff --git a/src/include/skalibs/sig.h b/src/include/skalibs/sig.h new file mode 100644 index 0000000..a463b63 --- /dev/null +++ b/src/include/skalibs/sig.h @@ -0,0 +1,61 @@ +/* ISC license. */ + +#ifndef SIG_H +#define SIG_H + +#include <signal.h> +#include <skalibs/gccattributes.h> + +extern int sig_alarm gccattr_deprecated ; +extern int sig_child gccattr_deprecated ; +extern int sig_stop gccattr_deprecated ; +extern int sig_cont gccattr_deprecated ; +extern int sig_hangup gccattr_deprecated ; +extern int sig_int gccattr_deprecated ; +extern int sig_kill gccattr_deprecated ; +extern int sig_pipe gccattr_deprecated ; +extern int sig_term gccattr_deprecated ; +extern int sig_usr1 gccattr_deprecated ; +extern int sig_usr2 gccattr_deprecated ; +extern int sig_quit gccattr_deprecated ; +extern int sig_abort gccattr_deprecated ; + + +typedef void skasighandler_t (int) ; +typedef skasighandler_t *skasighandler_t_ref ; + +struct skasigaction +{ + skasighandler_t_ref handler ; + unsigned int flags : 2 ; +} ; + +#define SKASA_MASKALL 0x01 +#define SKASA_NOCLDSTOP 0x02 + +extern struct skasigaction const SKASIG_DFL ; +extern struct skasigaction const SKASIG_IGN ; +extern int skasigaction (int, struct skasigaction const *, struct skasigaction *) ; + +#define sig_catcha(sig, ac) skasigaction(sig, (ac), 0) +#define sig_restore(sig) skasigaction((sig), &SKASIG_DFL, 0) + +extern void sig_restoreto (sigset_t const *, unsigned int) ; +extern int sig_catch (int, skasighandler_t_ref) ; +#define sig_ignore(sig) sig_catcha((sig), &SKASIG_IGN) +#define sig_uncatch(sig) sig_restore(sig) + +#define SIGSTACKSIZE 16 +extern int sig_pusha (int, struct skasigaction const *) ; +extern int sig_pop (int) ; +extern int sig_push (int, skasighandler_t_ref) ; + +extern void sig_block (int) ; +extern void sig_blockset (sigset_t const *) ; +extern void sig_unblock (int) ; +extern void sig_blocknone (void) ; +extern void sig_pause (void) ; +extern void sig_shield (void) ; +extern void sig_unshield (void) ; + +#endif diff --git a/src/include/skalibs/siovec.h b/src/include/skalibs/siovec.h new file mode 100644 index 0000000..8c8161f --- /dev/null +++ b/src/include/skalibs/siovec.h @@ -0,0 +1,29 @@ +/* ISC license. */ + +#ifndef SIOVEC_H +#define SIOVEC_H + +#include <sys/types.h> +#include <sys/uio.h> +#include <skalibs/gccattributes.h> + +typedef struct siovec_s siovec_t, *siovec_t_ref ; +struct siovec_s +{ + char *s ; + unsigned int len ; +} ; + +extern unsigned int siovec_len (siovec_t const *, unsigned int) gccattr_pure ; +extern unsigned int siovec_gather (siovec_t const *, unsigned int, char *, unsigned int) ; +extern unsigned int siovec_scatter (siovec_t const *, unsigned int, char const *, unsigned int) ; +extern unsigned int siovec_deal (siovec_t const *, unsigned int, siovec_t const *, unsigned int) ; +extern unsigned int siovec_seek (siovec_t *, unsigned int, unsigned int) ; + +extern void siovec_from_iovec (siovec_t *, struct iovec const *, unsigned int) ; +extern void iovec_from_siovec (struct iovec *, siovec_t const *, unsigned int) ; + +extern unsigned int siovec_bytechr (siovec_t const *, unsigned int, char) ; +extern unsigned int siovec_bytein (siovec_t const *, unsigned int, char const *, unsigned int) ; + +#endif diff --git a/src/include/skalibs/skaclient.h b/src/include/skalibs/skaclient.h new file mode 100644 index 0000000..a057d50 --- /dev/null +++ b/src/include/skalibs/skaclient.h @@ -0,0 +1,115 @@ +/* ISC license. */ + +#ifndef SKACLIENT_H +#define SKACLIENT_H + +#include <sys/types.h> +#include <skalibs/kolbak.h> +#include <skalibs/siovec.h> +#include <skalibs/tai.h> +#include <skalibs/uint32.h> +#include <skalibs/unixmessage.h> + + + /* Server part */ + +extern int skaclient_server_ack (unixmessage_t const *, unixmessage_sender_t *, unixmessage_sender_t *, char const *, unsigned int, char const *, unsigned int) ; +extern int skaclient_server_bidi_ack (unixmessage_t const *, unixmessage_sender_t *, unixmessage_sender_t *, unixmessage_receiver_t *, char *, unsigned int, char *, unsigned int, char const *, unsigned int, char const *, unsigned int) ; +extern int skaclient_server_init (unixmessage_receiver_t *, char *, unsigned int, char *, unsigned int, unixmessage_sender_t *, unixmessage_sender_t *, char const *, unsigned int, char const *, unsigned int, tain_t const *, tain_t *) ; +#define skaclient_server_init_g(in, mainbuf, mainlen, auxbuf, auxlen, out, asyncout, before, beforelen, after, afterlen, deadline) skaclient_server_init(in, mainbuf, mainlen, auxbuf, auxlen, out, asyncout, before, beforelen, after, afterlen, (deadline), &STAMP) + + + /* Client part: the rest of this file */ + +#define SKACLIENT_KOLBAK_SIZE 64 +#define SKACLIENT_OPTION_WAITPID 0x00000001U + +#define skaclient_buffer_type(bufsn, auxbufsn, bufan, auxbufan, qlen) struct { char bufs[bufsn] ; char auxbufs[auxbufsn] ; char bufa[bufan] ; char auxbufa[auxbufan] ; kolbak_closure_t q[qlen] ; } +typedef skaclient_buffer_type(UNIXMESSAGE_BUFSIZE, UNIXMESSAGE_AUXBUFSIZE, UNIXMESSAGE_BUFSIZE, UNIXMESSAGE_AUXBUFSIZE, SKACLIENT_KOLBAK_SIZE) skaclient_buffer_t, *skaclient_buffer_t_ref ; + + + /* Callback data for init */ + +typedef struct skaclient_cbdata_s skaclient_cbdata_t, *skaclient_cbdata_t_ref ; +struct skaclient_cbdata_s +{ + unixmessage_receiver_t *asyncin ; + unixmessage_sender_t *asyncout ; + char const *after ; + unsigned int afterlen ; +} ; + + + /* User structure */ + +typedef struct skaclient_s skaclient_t, *skaclient_t_ref ; +struct skaclient_s +{ + unixmessage_receiver_t syncin ; + unixmessage_sender_t syncout ; + kolbak_queue_t kq ; + unixmessage_receiver_t asyncin ; + unixmessage_sender_t asyncout ; + pid_t pid ; + uint32 options ; +} ; +#define SKACLIENT_ZERO { .syncin = UNIXMESSAGE_RECEIVER_ZERO, .syncout = UNIXMESSAGE_SENDER_ZERO, .kq = KOLBAK_QUEUE_ZERO, .asyncin = UNIXMESSAGE_RECEIVER_ZERO, .asyncout = UNIXMESSAGE_SENDER_ZERO, .pid = 0, .options = 0 } +extern skaclient_t const skaclient_zero ; + +extern void skaclient_end (skaclient_t *) ; + +extern int skaclient_start_async (skaclient_t *, char *, unsigned int, char *, unsigned int, char *, unsigned int, char *, unsigned int, kolbak_closure_t *, unsigned int, char const *, char const *, unsigned int, char const *, unsigned int, skaclient_cbdata_t *) ; +#define skaclient_start_async_b(a, sb, path, before, beforelen, after, afterlen, blah) skaclient_start_async(a, (sb)->bufs, sizeof((sb)->bufs), (sb)->auxbufs, sizeof((sb)->auxbufs), (sb)->bufa, sizeof((sb)->bufa), (sb)->auxbufa, sizeof((sb)->auxbufa), (sb)->q, sizeof((sb)->q), path, before, beforelen, after, afterlen, blah) +extern int skaclient_startf_async (skaclient_t *, char *, unsigned int, char *, unsigned int, char *, unsigned int, char *, unsigned int, kolbak_closure_t *, unsigned int, char const *, char const *const *, char const *const *, uint32, char const *, unsigned int, char const *, unsigned int, skaclient_cbdata_t *) ; +#define skaclient_startf_async_b(a, sb, prog, argv, envp, options, before, beforelen, after, afterlen, blah) skaclient_startf_async(a, (sb)->bufs, sizeof((sb)->bufs), (sb)->auxbufs, sizeof((sb)->auxbufs), (sb)->bufa, sizeof((sb)->bufa), (sb)->auxbufa, sizeof((sb)->auxbufa), (sb)->q, sizeof((sb)->q), prog, argv, envp, options, before, beforelen, after, afterlen, blah) + +extern int skaclient_start (skaclient_t *, char *, unsigned int, char *, unsigned int, char *, unsigned int, char *, unsigned int, kolbak_closure_t *, unsigned int, char const *, char const *, unsigned int, char const *, unsigned int, tain_t const *, tain_t *) ; +#define skaclient_start_b(a, sb, path, before, beforelen, after, afterlen, deadline, stamp) skaclient_start((a, (sb)->bufs, sizeof((sb)->bufs), (sb)->auxbufs, sizeof((sb)->auxbufs), (sb)->bufa, sizeof((sb)->bufa), (sb)->auxbufa, sizeof((sb)->auxbufa), (sb)->q, sizeof((sb)->q), path, before, beforelen, after, afterlen, deadline, stamp) +#define skaclient_start_g(a, bufs, bufsn, auxbufs, auxbufsn, bufa, bufan, auxbufa, auxbufan, q, qlen, path, before, beforelen, after, afterlen, deadline) skaclient_start(a, bufs, bufsn, auxbufs, auxbufsn, bufa, bufan, auxbufa, auxbufan, q, qlen, path, before, beforelen, after, afterlen, (deadline), &STAMP) +#define skaclient_start_b_g(a, sb, path, before, beforelen, after, afterlen, deadline) skaclient_start_b(a, sb, path, before, beforelen, after, afterlen, (deadline), &STAMP) + +extern int skaclient_startf (skaclient_t *, char *, unsigned int, char *, unsigned int, char *, unsigned int, char *, unsigned int, kolbak_closure_t *, unsigned int, char const *, char const *const *, char const *const *, uint32, char const *, unsigned int, char const *, unsigned int, tain_t const *, tain_t *) ; +#define skaclient_startf_b(a, sb, prog, argv, envp, before, beforelen, after, afterlen, deadline, stamp) skaclient_start((a, (sb)->bufs, sizeof((sb)->bufs), (sb)->auxbufs, sizeof((sb)->auxbufs), (sb)->bufa, sizeof((sb)->bufa), (sb)->auxbufa, sizeof((sb)->auxbufa), (sb)->q, sizeof((sb)->q), prog, argv, envp, before, beforelen, after, afterlen, deadline, stamp) +#define skaclient_startf_g(a, bufs, bufsn, auxbufs, auxbufsn, bufa, bufan, auxbufa, auxbufan, q, qlen, prog, argv, envp, options, before, beforelen, after, afterlen, deadline) skaclient_startf(a, bufs, bufsn, auxbufs, auxbufsn, bufa, bufan, auxbufa, auxbufan, q, qlen, prog, argv, envp, options, before, beforelen, after, afterlen, (deadline), &STAMP) +#define skaclient_startf_b_g(a, sb, prog, argv, envp, options, before, beforelen, after, afterlen, deadline) skaclient_startf_b(a, sb, prog, argv, envp, options, before, beforelen, after, afterlen, (deadline), &STAMP) + +extern int skaclient_putmsg_and_close (skaclient_t *, unixmessage_t const *, unsigned char const *, unixmessage_handler_func_t *, void *) ; +#define skaclient_putmsg(a, m, cb, result) skaclient_putmsg_and_close(a, m, unixmessage_bits_closenone, cb, result) +extern int skaclient_putmsgv_and_close (skaclient_t *, unixmessage_v_t const *, unsigned char const *, unixmessage_handler_func_t *, void *) ; +#define skaclient_putmsgv(a, m, cb, result) skaclient_putmsgv_and_close(a, m, unixmessage_bits_closenone, cb, result) + +extern int skaclient_put (skaclient_t *, char const *, unsigned int, unixmessage_handler_func_t *, void *) ; +extern int skaclient_putv (skaclient_t *, siovec_t const *, unsigned int, unixmessage_handler_func_t *, void *) ; + +extern int skaclient_sendmsg_and_close (skaclient_t *, unixmessage_t const *, unsigned char const *, unixmessage_handler_func_t *, void *, tain_t const *, tain_t *) ; +#define skaclient_sendmsg_and_close_g(a, m, bits, cb, result, deadline) skaclient_sendmsg_and_close(a, m, bits, cb, result, (deadline), &STAMP) +#define skaclient_sendmsg(a, m, cb, result, deadline, stamp) skaclient_sendmsg_and_close(a, m, unixmessage_bits_closenone, cb, result, deadline, stamp) +#define skaclient_sendmsg_g(a, m, cb, result, deadline) skaclient_sendmsg(a, m, cb, result, (deadline), &STAMP) + +extern int skaclient_sendmsgv_and_close (skaclient_t *, unixmessage_v_t const *, unsigned char const *, unixmessage_handler_func_t *, void *, tain_t const *, tain_t *) ; +#define skaclient_sendmsgv_and_close_g(a, m, bits, cb, result, deadline) skaclient_sendmsgv_and_close(a, m, bits, cb, result, (deadline), &STAMP) +#define skaclient_sendmsgv(a, m, cb, result, deadline, stamp) skaclient_sendmsgv_and_close(a, m, unixmessage_bits_closenone, cb, result, deadline, stamp) +#define skaclient_sendmsgv_g(a, m, cb, result, deadline) skaclient_sendmsgv(a, m, cb, result, (deadline), &STAMP) + +extern int skaclient_send (skaclient_t *, char const *, unsigned int, unixmessage_handler_func_t *, void *, tain_t const *, tain_t *) ; +#define skaclient_send_g(a, s, len, cb, result, deadline) skaclient_send(a, s, len, cb, result, (deadline), &STAMP) +extern int skaclient_sendv (skaclient_t *, siovec_t const *, unsigned int, unixmessage_handler_func_t *, void *, tain_t const *, tain_t *) ; +#define skaclient_sendv_g(a, v, vlen, cb, result, deadline) skaclient_sendv(a, v, vlen, cb, result, (deadline), &STAMP) + +#define skaclient_sfd(a) unixmessage_receiver_fd(&(a)->syncin) +#define skaclient_flush(a) unixmessage_sender_flush(&(a)->syncout) +#define skaclient_timed_flush(a, deadline, stamp) unixmessage_sender_timed_flush(&(a)->syncout, deadline, stamp) +#define skaclient_timed_flush_g(a, deadline) skaclient_timed_flush(a, (deadline), &STAMP) + +#define skaclient_supdate(a) unixmessage_handle(&(a)->syncin, (unixmessage_handler_func_t *)&kolbak_call, &(a)->kq) +#define skaclient_timed_supdate(a, deadline, stamp) unixmessage_timed_handle(&(a)->syncin, (unixmessage_handler_func_t *)&kolbak_call, &(a)->kq, deadline, stamp) +#define skaclient_timed_supdate_g(a, deadline) skaclient_timed_supdate(a, (deadline), &STAMP) + +#define skaclient_fd(a) skaclient_afd(a) +#define skaclient_afd(a) unixmessage_receiver_fd(&(a)->asyncin) +#define skaclient_update(a, f, p) skaclient_aupdate(a, f, p) +#define skaclient_aupdate(a, f, p) unixmessage_handle(&(a)->asyncin, f, p) + +extern unixmessage_handler_func_t skaclient_default_cb ; + +#endif diff --git a/src/include/skalibs/skalibs.h b/src/include/skalibs/skalibs.h new file mode 100644 index 0000000..e889461 --- /dev/null +++ b/src/include/skalibs/skalibs.h @@ -0,0 +1,19 @@ +/* ISC license. */ + +#ifndef SKALIBS_H +#define SKALIBS_H + +/* + This header includes everything in skalibs, + except skalibs/config.h and skalibs/sysdeps.h + It's heavy! +*/ + +#include <skalibs/stddjb.h> +#include <skalibs/stdcrypto.h> +#include <skalibs/random.h> +#include <skalibs/datastruct.h> +#include <skalibs/biguint.h> +#include <skalibs/unixonacid.h> + +#endif diff --git a/src/include/skalibs/skamisc.h b/src/include/skalibs/skamisc.h new file mode 100644 index 0000000..bdc4869 --- /dev/null +++ b/src/include/skalibs/skamisc.h @@ -0,0 +1,29 @@ +/* ISC license. */ + +#ifndef SKAMISC_H +#define SKAMISC_H + +#include <skalibs/buffer.h> +#include <skalibs/stralloc.h> + +extern stralloc satmp ; + +extern int skagetln (buffer *, stralloc *, char) ; +extern int skagetlnsep (buffer *, stralloc *, char const *, unsigned int) ; +extern int getlnmax (buffer *, char *, unsigned int, unsigned int *, char) ; +extern int getlnmaxsep (buffer *, char *, unsigned int, unsigned int *, char const *, unsigned int) ; + +extern int sauniquename (stralloc *) ; + +extern int string_quote (stralloc *, char const *, unsigned int) ; +extern int string_quote_nodelim (stralloc *, char const *, unsigned int) ; +extern int string_quote_nodelim_mustquote (stralloc *, char const *, unsigned int, char const *, unsigned int) ; +extern int string_unquote (char *, unsigned int *, char const *, unsigned int, unsigned int *) ; +extern int string_unquote_nodelim (char *, char const *, unsigned int) ; +extern int string_unquote_withdelim (char *, unsigned int *, char const *, unsigned int, unsigned int *, char const *, unsigned int) ; + +extern int string_format (stralloc *, char const *, char const *, char const *const *) ; + +#define skaoffsetof(n, s, field) do { s sofoftmp ; *(n) = (unsigned char *)&sofoftmp->field - (unsigned char *)&sofoftmp ; } while (0) + +#endif diff --git a/src/include/skalibs/socket.h b/src/include/skalibs/socket.h new file mode 100644 index 0000000..91be2f5 --- /dev/null +++ b/src/include/skalibs/socket.h @@ -0,0 +1,122 @@ +/* ISC license. */ + +#ifndef SOCKET_H +#define SOCKET_H + +#include <skalibs/gccattributes.h> +#include <skalibs/uint16.h> +#include <skalibs/uint32.h> +#include <skalibs/tai.h> +#include <skalibs/djbunix.h> +#include <skalibs/webipc.h> + +typedef int socket_io_func_t (int, char *, unsigned int, char *, uint16 *) ; +typedef socket_io_func_t *socket_io_func_t_ref ; + + + /* INET and INET6 domain socket operations */ + +#define socket_tcp() socket_tcp4() +#define socket_tcp_b() socket_tcp4_b() +#define socket_tcp_nb() socket_tcp4_nb() +#define socket_tcp_coe() socket_tcp4_coe() +#define socket_tcp_nbcoe() socket_tcp4_nbcoe() + +#define socket_tcp4() socket_tcp4_nb() +#define socket_tcp4_b() socket_tcp4_internal(0) +#define socket_tcp4_nb() socket_tcp4_internal(DJBUNIX_FLAG_NB) +#define socket_tcp4_coe() socket_tcp4_internal(DJBUNIX_FLAG_COE) +#define socket_tcp4_nbcoe() socket_tcp4_internal(DJBUNIX_FLAG_NB|DJBUNIX_FLAG_COE) +extern int socket_tcp4_internal (unsigned int) ; + +#define socket_tcp6() socket_tcp6_nb() +#define socket_tcp6_b() socket_tcp6_internal(0) +#define socket_tcp6_nb() socket_tcp6_internal(DJBUNIX_FLAG_NB) +#define socket_tcp6_coe() socket_tcp6_internal(DJBUNIX_FLAG_COE) +#define socket_tcp6_nbcoe() socket_tcp6_internal(DJBUNIX_FLAG_NB|DJBUNIX_FLAG_COE) +extern int socket_tcp6_internal (unsigned int) ; + +#define socket_udp() socket_udp4() +#define socket_udp_b() socket_udp4_b() +#define socket_udp_nb() socket_udp4_nb() +#define socket_udp_coe() socket_udp4_coe() +#define socket_udp_nbcoe() socket_udp4_nbcoe() + +#define socket_udp4() socket_udp4_nb() +#define socket_udp4_b() socket_udp4_internal(0) +#define socket_udp4_nb() socket_udp4_internal(DJBUNIX_FLAG_NB) +#define socket_udp4_coe() socket_udp4_internal(DJBUNIX_FLAG_COE) +#define socket_udp4_nbcoe() socket_udp4_internal(DJBUNIX_FLAG_NB|DJBUNIX_FLAG_COE) +extern int socket_udp4_internal (unsigned int) ; + +#define socket_udp6() socket_udp6_nb() +#define socket_udp6_b() socket_udp6_internal(0) +#define socket_udp6_nb() socket_udp6_internal(DJBUNIX_FLAG_NB) +#define socket_udp6_coe() socket_udp6_internal(DJBUNIX_FLAG_COE) +#define socket_udp6_nbcoe() socket_udp6_internal(DJBUNIX_FLAG_NB|DJBUNIX_FLAG_COE) +extern int socket_udp6_internal (unsigned int) ; + +extern int socket_waitconn (int, tain_t const *, tain_t *) ; +#define socket_waitconn_g(fd, deadline) socket_waitconn(fd, (deadline), &STAMP) +extern int socket_deadlineconnstamp4 (int, char const *, uint16, tain_t const *, tain_t *) ; +#define socket_deadlineconnstamp(s, ip, port, deadline, stamp) socket_deadlineconnstamp4(s, ip, port, deadline, stamp) +#define socket_deadlineconnstamp4_g(fd, ip, port, deadline) socket_deadlineconnstamp4(fd, ip, port, (deadline), &STAMP) +extern int socket_deadlineconnstamp4_u32 (int, uint32, uint16, tain_t const *, tain_t *) ; +#define socket_deadlineconnstamp4_u32_g(fd, ip, port, deadline) socket_deadlineconnstamp4_u32(fd, ip, port, (deadline), &STAMP) + +extern int socket_timeoutconn (int, char const *, uint16, unsigned int) ; +extern int socket_connect4 (int, char const *, uint16) ; +extern int socket_connect4_u32 (int, uint32, uint16) ; +extern int socket_connected (int) gccattr_const ; +extern int socket_bind4 (int, char const *, uint16) ; +extern int socket_bind4_reuse (int, char const *, uint16) ; +#define socket_listen(fd, b) ipc_listen(fd, b) + +extern int socket_connect6 (int, char const *, uint16) ; +extern int socket_deadlineconnstamp6 (int, char const *, uint16, tain_t const *, tain_t *) ; +#define socket_deadlineconnstamp6_g(fd, ip6, port, deadline) socket_deadlineconnstamp6(fd, ip6, port, (deadline), &STAMP) +extern int socket_bind6 (int, char const *, uint16) ; +extern int socket_bind6_reuse (int, char const *, uint16) ; + +#define socket_accept4(s, ip, port) socket_accept4_internal(s, ip, (port), 0) +#define socket_accept4_nb(s, ip, port) socket_accept4_internal(s, ip, (port), DJBUNIX_FLAG_NB) +#define socket_accept4_coe(s, ip, port) socket_accept4_internal(s, ip, (port), DJBUNIX_FLAG_COE) +#define socket_accept4_nbcoe(s, ip, port) socket_accept4_internal(s, ip, (port), DJBUNIX_FLAG_NB|DJBUNIX_FLAG_COE) +extern int socket_accept4_internal (int, char *, uint16 *, unsigned int) ; +extern socket_io_func_t socket_recv4 ; +extern int socket_send4 (int, char const *, unsigned int, char const *, uint16) ; +extern socket_io_func_t socket_ioloop_send4 ; +extern int socket_local4 (int, char *, uint16 *) ; +extern int socket_remote4 (int, char *, uint16 *) ; + +#define socket_accept6(s, ip6, port) socket_accept6_internal(s, ip6, (port), 0) +#define socket_accept6_nb(s, ip6, port) socket_accept6_internal(s, ip6, (port), DJBUNIX_FLAG_NB) +#define socket_accept6_coe(s, ip6, port) socket_accept6_internal(s, ip6, (port), DJBUNIX_FLAG_COE) +#define socket_accept6_nbcoe(s, ip6, port) socket_accept6_internal(s, ip6, (port), DJBUNIX_FLAG_NB|DJBUNIX_FLAG_COE) +extern int socket_accept6_internal (int, char *, uint16 *, unsigned int) ; +extern socket_io_func_t socket_recv6 ; +extern int socket_send6 (int, char const *, unsigned int, char const *, uint16) ; +extern socket_io_func_t socket_ioloop_send6 ; +extern int socket_local6 (int, char *, uint16 *) ; +extern int socket_remote6 (int, char *, uint16 *) ; + +extern int socket_ipoptionskill (int) ; +extern int socket_tcpnodelay (int) ; +extern void socket_tryreservein (int, unsigned int) ; + + + /* Timed send and recv operations (for dgram sockets) */ + +extern int socket_ioloop (int, char *, unsigned int, char *, uint16 *, socket_io_func_t_ref, int, tain_t const *, tain_t *) ; + +#define socket_sendnb4(fd, buf, len, ip4, port, deadline, stamp) socket_ioloop(fd, buf, len, (char *)ip4, &(port), &socket_ioloop_send4, 1, deadline, stamp) +#define socket_sendnb4_g(fd, buf, len, ip4, port, deadline) socket_sendnb4(fd, buf, len, ip4, port, (deadline), &STAMP) +#define socket_recvnb4(fd, buf, len, ip4, port, deadline, stamp) socket_ioloop(fd, buf, len, ip4, port, &socket_recv4, 0, deadline, stamp) +#define socket_recvnb4_g(fd, buf, len, ip4, port, deadline) socket_recvnb4(fd, buf, len, ip4, port, (deadline), &STAMP) + +#define socket_sendnb6(fd, buf, len, ip6, port, deadline, stamp) socket_ioloop(fd, buf, len, (char *)ip6, &(port), &socket_ioloop_send6, 1, deadline, stamp) +#define socket_sendnb6_g(fd, buf, len, ip6, port, deadline) socket_sendnb6(fd, buf, len, ip6, port, (deadline), &STAMP) +#define socket_recvnb6(fd, buf, len, ip6, port, deadline, stamp) socket_ioloop(fd, buf, len, ip6, port, &socket_recv6, 0, deadline, stamp) +#define socket_recvnb6_g(fd, buf, len, ip6, port, deadline) socket_recvnb6(fd, buf, len, ip6, port, (deadline), &STAMP) + +#endif diff --git a/src/include/skalibs/stdcrypto.h b/src/include/skalibs/stdcrypto.h new file mode 100644 index 0000000..bd6751b --- /dev/null +++ b/src/include/skalibs/stdcrypto.h @@ -0,0 +1,11 @@ +/* ISC license. */ + +#ifndef STDCRYPTO_H +#define STDCRYPTO_H + +#include <skalibs/rc4.h> +#include <skalibs/md5.h> +#include <skalibs/sha1.h> +#include <skalibs/sha256.h> + +#endif diff --git a/src/include/skalibs/stddjb.h b/src/include/skalibs/stddjb.h new file mode 100644 index 0000000..e265003 --- /dev/null +++ b/src/include/skalibs/stddjb.h @@ -0,0 +1,60 @@ +/* ISC license. */ + +#ifndef STDDJB_H +#define STDDJB_H + +#include <skalibs/config.h> +#include <skalibs/uint16.h> +#include <skalibs/uint32.h> +#include <skalibs/uint64.h> +#include <skalibs/ushort.h> +#include <skalibs/uint.h> +#include <skalibs/ulong.h> +#include <skalibs/error.h> +#include <skalibs/gidstuff.h> +#include <skalibs/ip46.h> +#include <skalibs/setgroups.h> + +#include <skalibs/alloc.h> +#include <skalibs/allreadwrite.h> +#include <skalibs/bitarray.h> +#include <skalibs/bufalloc.h> +#include <skalibs/buffer.h> +#include <skalibs/bytestr.h> +#include <skalibs/cbuffer.h> +#include <skalibs/cdb.h> +#include <skalibs/cdb_make.h> +#include <skalibs/direntry.h> +#include <skalibs/diuint32.h> +#include <skalibs/diuint.h> +#include <skalibs/djbtime.h> +#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/netstring.h> +#include <skalibs/nsig.h> +#include <skalibs/segfault.h> +#include <skalibs/selfpipe.h> +#include <skalibs/sgetopt.h> +#include <skalibs/sig.h> +#include <skalibs/siovec.h> +#include <skalibs/skamisc.h> +#include <skalibs/socket.h> +#include <skalibs/stralloc.h> +#include <skalibs/strerr.h> +#include <skalibs/strerr2.h> +#include <skalibs/tai.h> +#include <skalibs/webipc.h> + +#endif diff --git a/src/include/skalibs/stralloc.h b/src/include/skalibs/stralloc.h new file mode 100644 index 0000000..2d762d4 --- /dev/null +++ b/src/include/skalibs/stralloc.h @@ -0,0 +1,40 @@ +/* ISC license. */ + +#ifndef STRALLOC_H +#define STRALLOC_H + +#include <skalibs/bytestr.h> +#include <skalibs/siovec.h> + +typedef struct stralloc_s stralloc, *stralloc_ref ; +struct stralloc_s +{ + char *s ; + unsigned int len ; + unsigned int a ; +} ; + +#define STRALLOC_ZERO { .s = 0, .len = 0, .a = 0 } +extern stralloc const stralloc_zero ; + +extern int stralloc_ready_tuned (stralloc *, unsigned int, unsigned int, unsigned int, unsigned int) ; +#define stralloc_ready(sa, n) stralloc_ready_tuned(sa, (n), 8, 1, 8) +#define stralloc_readyplus(sa, n) stralloc_ready(sa, (sa)->len + (n)) +extern void stralloc_free (stralloc *) ; +extern int stralloc_shrink (stralloc *) ; +extern int stralloc_copyb (stralloc *, char const *, unsigned int) ; +extern int stralloc_catb (stralloc *, char const *, unsigned int) ; +extern int stralloc_catv (stralloc *, siovec_t const *, unsigned int) ; +#define stralloc_copys(sa, s) stralloc_copyb(sa, (s), str_len(s)) +#define stralloc_cats(sa, s) stralloc_catb(sa, (s), str_len(s)) +#define stralloc_copy(sa1, sa2) stralloc_copyb(sa1, (sa2)->s, (sa2)->len) +#define stralloc_cat(sa1, sa2) stralloc_catb(sa1, (sa2)->s, (sa2)->len) +extern int stralloc_append (stralloc *, char) ; +extern void stralloc_reverse (stralloc *) ; +extern void stralloc_reverse_blocks (stralloc *, unsigned int) ; +#define stralloc_0(sa) stralloc_catb(sa, "", 1) +extern int stralloc_insertb (stralloc *, unsigned int, char const *, unsigned int) ; +#define stralloc_inserts(sa, offset, s) stralloc_insertb(sa, offset, (s), str_len(s)) +#define stralloc_insert(sa1, offset, sa2) stralloc_insertb(sa1, offset, (sa2)->s, (sa2)->len) + +#endif diff --git a/src/include/skalibs/strerr.h b/src/include/skalibs/strerr.h new file mode 100644 index 0000000..64665b5 --- /dev/null +++ b/src/include/skalibs/strerr.h @@ -0,0 +1,139 @@ +/* ISC license. */ + +#ifndef STRERR_H +#define STRERR_H + +#include <skalibs/gccattributes.h> + +extern void strerr_warn (char const *, char const *, char const *, char const *, char const *, char const *, char const *, char const *, char const *, char const *, char const *) ; +extern void strerr_die (int, char const *, char const *, char const *, char const *, char const *, char const *, char const *, char const *, char const *, char const *, char const *) gccattr_noreturn ; +extern void strerr_warnsys (char const *, char const *, char const *, char const *, char const *, char const *, char const *, char const *, char const *, char const *) ; +extern void strerr_diesys (int, char const *, char const *, char const *, char const *, char const *, char const *, char const *, char const *, char const *, char const *) gccattr_noreturn ; + +#define strerr_warn10(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, se) \ +strerr_warn(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, se) +#define strerr_warn9(x1, x2, x3, x4, x5, x6, x7, x8, x9, se) \ +strerr_warn(x1, x2, x3, x4, x5, x6, x7, x8, x9, 0, se) +#define strerr_warn8(x1, x2, x3, x4, x5, x6, x7, x8, se) \ +strerr_warn(x1, x2, x3, x4, x5, x6, x7, x8, 0, 0, se) +#define strerr_warn7(x1, x2, x3, x4, x5, x6, x7, se) \ +strerr_warn(x1, x2, x3, x4, x5, x6, x7, 0, 0, 0, se) +#define strerr_warn6(x1, x2, x3, x4, x5, x6, se) \ +strerr_warn(x1, x2, x3, x4, x5, x6, 0, 0, 0, 0, se) +#define strerr_warn5(x1, x2, x3, x4, x5, se) \ +strerr_warn(x1, x2, x3, x4, x5, 0, 0, 0, 0, 0, se) +#define strerr_warn4(x1, x2, x3, x4, se) \ +strerr_warn(x1, x2, x3, x4, 0, 0, 0, 0, 0, 0, se) +#define strerr_warn3(x1, x2, x3, se) \ +strerr_warn(x1, x2, x3, 0, 0, 0, 0, 0, 0, 0, se) +#define strerr_warn2(x1, x2, se) \ +strerr_warn(x1, x2, 0, 0, 0, 0, 0, 0, 0, 0, se) +#define strerr_warn1(x1, se) \ +strerr_warn(x1, 0, 0, 0, 0, 0, 0, 0, 0, 0, se) + +#define strerr_warn10sys(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10) \ +strerr_warnsys(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10) +#define strerr_warn9sys(x1, x2, x3, x4, x5, x6, x7, x8, x9) \ +strerr_warnsys(x1, x2, x3, x4, x5, x6, x7, x8, (x9), 0) +#define strerr_warn8sys(x1, x2, x3, x4, x5, x6, x7, x8) \ +strerr_warnsys(x1, x2, x3, x4, x5, x6, x7, (x8), 0, 0) +#define strerr_warn7sys(x1, x2, x3, x4, x5, x6, x7) \ +strerr_warnsys(x1, x2, x3, x4, x5, x6, (x7), 0, 0, 0) +#define strerr_warn6sys(x1, x2, x3, x4, x5, x6) \ +strerr_warnsys(x1, x2, x3, x4, x5, (x6), 0, 0, 0, 0) +#define strerr_warn5sys(x1, x2, x3, x4, x5) \ +strerr_warnsys(x1, x2, x3, x4, (x5), 0, 0, 0, 0, 0) +#define strerr_warn4sys(x1, x2, x3, x4) \ +strerr_warnsys(x1, x2, x3, (x4), 0, 0, 0, 0, 0, 0) +#define strerr_warn3sys(x1, x2, x3) \ +strerr_warnsys(x1, x2, (x3), 0, 0, 0, 0, 0, 0, 0) +#define strerr_warn2sys(x1, x2) \ +strerr_warnsys(x1, (x2), 0, 0, 0, 0, 0, 0, 0, 0) +#define strerr_warn1sys(x1) \ +strerr_warnsys((x1), 0, 0, 0, 0, 0, 0, 0, 0, 0) + +#define strerr_warn10x(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10) \ +strerr_warn(x1, x2, x3, x4, x5, x6, x7, x8, x9, (x10), 0) +#define strerr_warn9x(x1, x2, x3, x4, x5, x6, x7, x8, x9) \ +strerr_warn(x1, x2, x3, x4, x5, x6, x7, x8, (x9), 0, 0) +#define strerr_warn8x(x1, x2, x3, x4, x5, x6, x7, x8) \ +strerr_warn(x1, x2, x3, x4, x5, x6, x7, (x8), 0, 0, 0) +#define strerr_warn7x(x1, x2, x3, x4, x5, x6, x7) \ +strerr_warn(x1, x2, x3, x4, x5, x6, (x7), 0, 0, 0, 0) +#define strerr_warn6x(x1, x2, x3, x4, x5, x6) \ +strerr_warn(x1, x2, x3, x4, x5, (x6), 0, 0, 0, 0, 0) +#define strerr_warn5x(x1, x2, x3, x4, x5) \ +strerr_warn(x1, x2, x3, x4, (x5), 0, 0, 0, 0, 0, 0) +#define strerr_warn4x(x1, x2, x3, x4) \ +strerr_warn(x1, x2, x3, (x4), 0, 0, 0, 0, 0, 0, 0) +#define strerr_warn3x(x1, x2, x3) \ +strerr_warn(x1, x2, (x3), 0, 0, 0, 0, 0, 0, 0, 0) +#define strerr_warn2x(x1, x2) \ +strerr_warn(x1, (x2), 0, 0, 0, 0, 0, 0, 0, 0, 0) +#define strerr_warn1x(x1) \ +strerr_warn((x1), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + +#define strerr_die10(e, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, se) \ +strerr_die(e, x1, x2, x3, x4, x5 , x6, x7, x8, x9, x10, se) +#define strerr_die9(e, x1, x2, x3, x4, x5, x6, x7, x8, x9, se) \ +strerr_die(e, x1, x2, x3, x4, x5, x6, x7, x8, x9, 0, se) +#define strerr_die8(e, x1, x2, x3, x4, x5, x6, x7, x8, se) \ +strerr_die(e, x1, x2, x3, x4, x5, x6, x7, x8, 0, 0, se) +#define strerr_die7(e, x1, x2, x3, x4, x5, x6, x7, se) \ +strerr_die(e, x1, x2, x3, x4, x5, x6, x7, 0, 0, 0, se) +#define strerr_die6(e, x1, x2, x3, x4, x5, x6, se) \ +strerr_die(e, x1, x2, x3, x4, x5, x6, 0, 0, 0, 0, se) +#define strerr_die5(e, x1, x2, x3, x4, x5, se) \ +strerr_die(e, x1, x2, x3, x4, x5, 0, 0, 0, 0, 0, se) +#define strerr_die4(e, x1, x2, x3, x4, se) \ +strerr_die(e, x1, x2, x3, x4, 0, 0, 0, 0, 0, 0, se) +#define strerr_die3(e, x1, x2, x3, se) \ +strerr_die(e, x1, x2, x3, 0, 0, 0, 0, 0, 0, 0, se) +#define strerr_die2(e, x1, x2, se) \ +strerr_die(e, x1, x2, 0, 0, 0, 0, 0, 0, 0, 0, se) +#define strerr_die1(e, x1, se) \ +strerr_die(e, x1, 0, 0, 0, 0, 0, 0, 0, 0, 0, se) + +#define strerr_die10sys(e, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10) \ +strerr_diesys(e, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10) +#define strerr_die9sys(e, x1, x2, x3, x4, x5, x6, x7, x8, x9) \ +strerr_diesys(e, x1, x2, x3, x4, x5, x6, x7, x8, (x9), 0) +#define strerr_die8sys(e, x1, x2, x3, x4, x5, x6, x7, x8) \ +strerr_diesys(e, x1, x2, x3, x4, x5, x6, x7, (x8), 0, 0) +#define strerr_die7sys(e, x1, x2, x3, x4, x5, x6, x7) \ +strerr_diesys(e, x1, x2, x3, x4, x5, x6, (x7), 0, 0, 0) +#define strerr_die6sys(e, x1, x2, x3, x4, x5, x6) \ +strerr_diesys(e, x1, x2, x3, x4, x5, (x6), 0, 0, 0, 0) +#define strerr_die5sys(e, x1, x2, x3, x4, x5) \ +strerr_diesys(e, x1, x2, x3, x4, (x5), 0, 0, 0, 0, 0) +#define strerr_die4sys(e, x1, x2, x3, x4) \ +strerr_diesys(e, x1, x2, x3, (x4), 0, 0, 0, 0, 0, 0) +#define strerr_die3sys(e, x1, x2, x3) \ +strerr_diesys(e, x1, x2, (x3), 0, 0, 0, 0, 0, 0, 0) +#define strerr_die2sys(e, x1, x2) \ +strerr_diesys(e, x1, (x2), 0, 0, 0, 0, 0, 0, 0, 0) +#define strerr_die1sys(e, x1) \ +strerr_diesys(e, (x1), 0, 0, 0, 0, 0, 0, 0, 0, 0) + +#define strerr_die10x(e, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10) \ +strerr_die(e, x1, x2, x3, x4, x5, x6, x7, x8, x9, (x10), 0) +#define strerr_die9x(e, x1, x2, x3, x4, x5, x6, x7, x8, x9) \ +strerr_die(e, x1, x2, x3, x4, x5, x6, x7, x8, (x9), 0, 0) +#define strerr_die8x(e, x1, x2, x3, x4, x5, x6, x7, x8) \ +strerr_die(e, x1, x2, x3, x4, x5, x6, x7, (x8), 0, 0, 0) +#define strerr_die7x(e, x1, x2, x3, x4, x5, x6, x7) \ +strerr_die(e, x1, x2, x3, x4, x5, x6, (x7), 0, 0, 0, 0) +#define strerr_die6x(e, x1, x2, x3, x4, x5, x6) \ +strerr_die(e, x1, x2, x3, x4, x5, (x6), 0, 0, 0, 0, 0) +#define strerr_die5x(e, x1, x2, x3, x4, x5) \ +strerr_die(e, x1, x2, x3, x4, (x5), 0, 0, 0, 0, 0, 0) +#define strerr_die4x(e, x1, x2, x3, x4) \ +strerr_die(e, x1, x2, x3, (x4), 0, 0, 0, 0, 0, 0, 0) +#define strerr_die3x(e, x1, x2, x3) \ +strerr_die(e, x1, x2, (x3), 0, 0, 0, 0, 0, 0, 0, 0) +#define strerr_die2x(e, x1, x2) \ +strerr_die(e, x1, (x2), 0, 0, 0, 0, 0, 0, 0, 0, 0) +#define strerr_die1x(e, x1) \ +strerr_die(e, (x1), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + +#endif diff --git a/src/include/skalibs/strerr2.h b/src/include/skalibs/strerr2.h new file mode 100644 index 0000000..fa7cc02 --- /dev/null +++ b/src/include/skalibs/strerr2.h @@ -0,0 +1,267 @@ +/* ISC license. */ + +#ifndef STRERR2_H +#define STRERR2_H + +#include <skalibs/strerr.h> + +extern char const *PROG ; + + +#define strerr_warnw1x(x1) \ +strerr_warn3x(PROG, ": warning: ", (x1)) +#define strerr_warnw2x(x1, x2) \ +strerr_warn4x(PROG, ": warning: ", (x1), x2) +#define strerr_warnw3x(x1, x2, x3) \ +strerr_warn5x(PROG, ": warning: ", (x1), x2, x3) +#define strerr_warnw4x(x1, x2, x3, x4) \ +strerr_warn6x(PROG, ": warning: ", (x1), x2, x3, x4) +#define strerr_warnw5x(x1, x2, x3, x4, x5) \ +strerr_warn7x(PROG, ": warning: ", (x1), x2, x3, x4, x5) +#define strerr_warnw6x(x1, x2, x3, x4, x5, x6) \ +strerr_warn8x(PROG, ": warning: ", (x1), x2, x3, x4, x5, x6) +#define strerr_warnw7x(x1, x2, x3, x4, x5, x6, x7) \ +strerr_warn9x(PROG, ": warning: ", (x1), x2, x3, x4, x5, x6, x7) +#define strerr_warnw8x(x1, x2, x3, x4, x5, x6, x7, x8) \ +strerr_warn10x(PROG, ": warning: ", (x1), x2, x3, x4, x5, x6, x7, x8) + +#define strerr_warnw1sys(x1) \ +strerr_warn4sys(PROG, ": warning: ", (x1), ": ") +#define strerr_warnw2sys(x1, x2) \ +strerr_warn5sys(PROG, ": warning: ", (x1), (x2), ": ") +#define strerr_warnw3sys(x1, x2, x3) \ +strerr_warn6sys(PROG, ": warning: ", (x1), x2, (x3), ": ") +#define strerr_warnw4sys(x1, x2, x3, x4) \ +strerr_warn7sys(PROG, ": warning: ", (x1), x2, x3, (x4), ": ") +#define strerr_warnw5sys(x1, x2, x3, x4, x5) \ +strerr_warn8sys(PROG, ": warning: ", (x1), x2, x3, x4, (x5), ": ") +#define strerr_warnw6sys(x1, x2, x3, x4, x5, x6) \ +strerr_warn9sys(PROG, ": warning: ", (x1), x2, x3, x4, x5, (x6), ": ") +#define strerr_warnw7sys(x1, x2, x3, x4, x5, x6, x7) \ +strerr_warn10sys(PROG, ": warning: ", (x1), x2, x3, x4, x5, x6, (x7), ": ") + +#define strerr_diew1x(e, x1) \ +strerr_die3x(e, PROG, ": warning: ", x1) +#define strerr_diew2x(e, x1, x2) \ +strerr_die4x(e, PROG, ": warning: ", x1, x2) +#define strerr_diew3x(e, x1, x2, x3) \ +strerr_die5x(e, PROG, ": warning: ", x1, x2, x3) +#define strerr_diew4x(e, x1, x2, x3, x4) \ +strerr_die6x(e, PROG, ": warning: ", x1, x2, x3, x4) +#define strerr_diew5x(e, x1, x2, x3, x4, x5) \ +strerr_die7x(e, PROG, ": warning: ", x1, x2, x3, x4, x5) +#define strerr_diew6x(e, x1, x2, x3, x4, x5, x6) \ +strerr_die8x(e, PROG, ": warning: ", x1, x2, x3, x4, x5, x6) +#define strerr_diew7x(e, x1, x2, x3, x4, x5, x6, x7) \ +strerr_die9x(e, PROG, ": warning: ", x1, x2, x3, x4, x5, x6, x7) +#define strerr_diew8x(e, x1, x2, x3, x4, x5, x6, x7, x8) \ +strerr_die10x(e, PROG, ": warning: ", x1, x2, x3, x4, x5, x6, x7, x8) + +#define strerr_diew1sys(e, x1) \ +strerr_die4sys(e, PROG, ": warning: ", (x1), ": ") +#define strerr_diew2sys(e, x1, x2) \ +strerr_die5sys(e, PROG, ": warning: ", x1, (x2), ": ") +#define strerr_diew3sys(e, x1, x2, x3) \ +strerr_die6sys(e, PROG, ": warning: ", x1, x2, (x3), ": ") +#define strerr_diew4sys(e, x1, x2, x3, x4) \ +strerr_die7sys(e, PROG, ": warning: ", x1, x2, x3, (x4), ": ") +#define strerr_diew5sys(e, x1, x2, x3, x4, x5) \ +strerr_die8sys(e, PROG, ": warning: ", x1, x2, x3, x4, (x5), ": ") +#define strerr_diew6sys(e, x1, x2, x3, x4, x5, x6) \ +strerr_die9sys(e, PROG, ": warning: ", x1, x2, x3, x4, x5, (x6), ": ") +#define strerr_diew7sys(e, x1, x2, x3, x4, x5, x6, x7) \ +strerr_die10sys(e, PROG, ": warning: ", x1, x2, x3, x4, x5, x6, (x7), ": ") + +#define strerr_dief1x(e, x1) \ +strerr_die3x(e, PROG, ": fatal: ", x1) +#define strerr_dief2x(e, x1, x2) \ +strerr_die4x(e, PROG, ": fatal: ", x1, x2) +#define strerr_dief3x(e, x1, x2, x3) \ +strerr_die5x(e, PROG, ": fatal: ", x1, x2, x3) +#define strerr_dief4x(e, x1, x2, x3, x4) \ +strerr_die6x(e, PROG, ": fatal: ", x1, x2, x3, x4) +#define strerr_dief5x(e, x1, x2, x3, x4, x5) \ +strerr_die7x(e, PROG, ": fatal: ", x1, x2, x3, x4, x5) +#define strerr_dief6x(e, x1, x2, x3, x4, x5, x6) \ +strerr_die8x(e, PROG, ": fatal: ", x1, x2, x3, x4, x5, x6) +#define strerr_dief7x(e, x1, x2, x3, x4, x5, x6, x7) \ +strerr_die9x(e, PROG, ": fatal: ", x1, x2, x3, x4, x5, x6, x7) +#define strerr_dief8x(e, x1, x2, x3, x4, x5, x6, x7, x8) \ +strerr_die10x(e, PROG, ": fatal: ", x1, x2, x3, x4, x5, x6, x7, x8) + +#define strerr_dief1sys(e, x1) \ +strerr_die4sys(e, PROG, ": fatal: ", (x1), ": ") +#define strerr_dief2sys(e, x1, x2) \ +strerr_die5sys(e, PROG, ": fatal: ", x1, (x2), ": ") +#define strerr_dief3sys(e, x1, x2, x3) \ +strerr_die6sys(e, PROG, ": fatal: ", x1, x2, (x3), ": ") +#define strerr_dief4sys(e, x1, x2, x3, x4) \ +strerr_die7sys(e, PROG, ": fatal: ", x1, x2, x3, (x4), ": ") +#define strerr_dief5sys(e, x1, x2, x3, x4, x5) \ +strerr_die8sys(e, PROG, ": fatal: ", x1, x2, x3, x4, (x5), ": ") +#define strerr_dief6sys(e, x1, x2, x3, x4, x5, x6) \ +strerr_die9sys(e, PROG, ": fatal: ", x1, x2, x3, x4, x5, (x6), ": ") +#define strerr_dief7sys(e, x1, x2, x3, x4, x5, x6, x7) \ +strerr_die10sys(e, PROG, ": fatal: ", x1, x2, x3, x4, x5, x6, (x7), ": ") + +#define strerr_diefu1x(e, x1) \ +strerr_die4x(e, PROG, ": fatal: ", "unable to ", x1) +#define strerr_diefu2x(e, x1, x2) \ +strerr_die5x(e, PROG, ": fatal: ", "unable to ", x1, x2) +#define strerr_diefu3x(e, x1, x2, x3) \ +strerr_die6x(e, PROG, ": fatal: ", "unable to ", x1, x2, x3) +#define strerr_diefu4x(e, x1, x2, x3, x4) \ +strerr_die7x(e, PROG, ": fatal: ", "unable to ", x1, x2, x3, x4) +#define strerr_diefu5x(e, x1, x2, x3, x4, x5) \ +strerr_die8x(e, PROG, ": fatal: ", "unable to ", x1, x2, x3, x4, x5) +#define strerr_diefu6x(e, x1, x2, x3, x4, x5, x6) \ +strerr_die9x(e, PROG, ": fatal: ", "unable to ", x1, x2, x3, x4, x5, x6) +#define strerr_diefu7x(e, x1, x2, x3, x4, x5, x6, x7) \ +strerr_die10x(e, PROG, ": fatal: ", "unable to ", x1, x2, x3, x4, x5, x6, x7) + +#define strerr_diefu1sys(e, x1) \ +strerr_die5sys(e, PROG, ": fatal: ", "unable to ", (x1), ": ") +#define strerr_diefu2sys(e, x1, x2) \ +strerr_die6sys(e, PROG, ": fatal: ", "unable to ", x1, (x2), ": ") +#define strerr_diefu3sys(e, x1, x2, x3) \ +strerr_die7sys(e, PROG, ": fatal: ", "unable to ", x1, x2, (x3), ": ") +#define strerr_diefu4sys(e, x1, x2, x3, x4) \ +strerr_die8sys(e, PROG, ": fatal: ", "unable to ", x1, x2, x3, (x4), ": ") +#define strerr_diefu5sys(e, x1, x2, x3, x4, x5) \ +strerr_die9sys(e, PROG, ": fatal: ", "unable to ", x1, x2, x3, x4, (x5), ": ") +#define strerr_diefu6sys(e, x1, x2, x3, x4, x5, x6) \ +strerr_die10sys(e, PROG, ": fatal: ", "unable to ", x1, x2, x3, x4, x5, (x6), ": ") + +#define strerr_warnwu1x(x1) \ +strerr_warn4x(PROG, ": warning: ", "unable to ", (x1)) +#define strerr_warnwu2x(x1, x2) \ +strerr_warn5x(PROG, ": warning: ", "unable to ", (x1), x2) +#define strerr_warnwu3x(x1, x2, x3) \ +strerr_warn6x(PROG, ": warning: ", "unable to ", (x1), x2, x3) +#define strerr_warnwu4x(x1, x2, x3, x4) \ +strerr_warn7x(PROG, ": warning: ", "unable to ", (x1), x2, x3, x4) +#define strerr_warnwu5x(x1, x2, x3, x4, x5) \ +strerr_warn8x(PROG, ": warning: ", "unable to ", (x1), x2, x3, x4, x5) +#define strerr_warnwu6x(x1, x2, x3, x4, x5, x6) \ +strerr_warn9x(PROG, ": warning: ", "unable to ", (x1), x2, x3, x4, x5, x6) +#define strerr_warnwu7x(x1, x2, x3, x4, x5, x6, x7) \ +strerr_warn10x(PROG, ": warning: ", "unable to ", (x1), x2, x3, x4, x5, x6, x7) + +#define strerr_warnwu1sys(x1) \ +strerr_warn5sys(PROG, ": warning: ", "unable to ", (x1), ": ") +#define strerr_warnwu2sys(x1, x2) \ +strerr_warn6sys(PROG, ": warning: ", "unable to ", (x1), (x2), ": ") +#define strerr_warnwu3sys(x1, x2, x3) \ +strerr_warn7sys(PROG, ": warning: ", "unable to ", (x1), x2, (x3), ": ") +#define strerr_warnwu4sys(x1, x2, x3, x4) \ +strerr_warn8sys(PROG, ": warning: ", "unable to ", (x1), x2, x3, (x4), ": ") +#define strerr_warnwu5sys(x1, x2, x3, x4, x5) \ +strerr_warn9sys(PROG, ": warning: ", "unable to ", (x1), x2, x3, x4, (x5), ": ") +#define strerr_warnwu6sys(x1, x2, x3, x4, x5, x6) \ +strerr_warn10sys(PROG, ": warning: ", "unable to ", (x1), x2, x3, x4, x5, (x6), ": ") + +#define strerr_diewu1x(e, x1) \ +strerr_die4x(e, PROG, ": warning: ", "unable to ", x1) +#define strerr_diewu2x(e, x1, x2) \ +strerr_die5x(e, PROG, ": warning: ", "unable to ", x1, x2) +#define strerr_diewu3x(e, x1, x2, x3) \ +strerr_die6x(e, PROG, ": warning: ", "unable to ", x1, x2, x3) +#define strerr_diewu4x(e, x1, x2, x3, x4) \ +strerr_die7x(e, PROG, ": warning: ", "unable to ", x1, x2, x3, x4) +#define strerr_diewu5x(e, x1, x2, x3, x4, x5) \ +strerr_die8x(e, PROG, ": warning: ", "unable to ", x1, x2, x3, x4, x5) +#define strerr_diewu6x(e, x1, x2, x3, x4, x5, x6) \ +strerr_die9x(e, PROG, ": warning: ", "unable to ", x1, x2, x3, x4, x5, x6) +#define strerr_diewu7x(e, x1, x2, x3, x4, x5, x6, x7) \ +strerr_die10x(e, PROG, ": warning: ", "unable to ", x1, x2, x3, x4, x5, x6, x7) + +#define strerr_diewu1sys(e, x1) \ +strerr_die5sys(e, PROG, ": warning: ", "unable to ", (x1), ": ") +#define strerr_diewu2sys(e, x1, x2) \ +strerr_die6sys(e, PROG, ": warning: ", "unable to ", x1, (x2), ": ") +#define strerr_diewu3sys(e, x1, x2, x3) \ +strerr_die7sys(e, PROG, ": warning: ", "unable to ", x1, x2, (x3), ": ") +#define strerr_diewu4sys(e, x1, x2, x3, x4) \ +strerr_die8sys(e, PROG, ": warning: ", "unable to ", x1, x2, x3, (x4), ": ") +#define strerr_diewu5sys(e, x1, x2, x3, x4, x5) \ +strerr_die9sys(e, PROG, ": warning: ", "unable to ", x1, x2, x3, x4, (x5), ": ") +#define strerr_diewu6sys(e, x1, x2, x3, x4, x5, x6) \ +strerr_die10sys(e, PROG, ": warning: ", "unable to ", x1, x2, x3, x4, x5, (x6), ": ") + +#define strerr_dieusage(e, u) \ +strerr_die3x(e, PROG, ": usage: ", u) + +#define strerr_dienotset(e, x) \ +strerr_dief2x(e, (x), " not set") + +#define strerr_dieinvalid(e, x) \ +strerr_dief2x(e, "invalid $", x) + +#define strerr_dieexec(e, x) \ +strerr_diefu2sys(e, "exec ", x) + +#define strerr_warni1x(x1) \ +strerr_warn3x(PROG, ": info: ", (x1)) +#define strerr_warni2x(x1, x2) \ +strerr_warn4x(PROG, ": info: ", (x1), x2) +#define strerr_warni3x(x1, x2, x3) \ +strerr_warn5x(PROG, ": info: ", (x1), x2, x3) +#define strerr_warni4x(x1, x2, x3, x4) \ +strerr_warn6x(PROG, ": info: ", (x1), x2, x3, x4) +#define strerr_warni5x(x1, x2, x3, x4, x5) \ +strerr_warn7x(PROG, ": info: ", (x1), x2, x3, x4, x5) +#define strerr_warni6x(x1, x2, x3, x4, x5, x6) \ +strerr_warn8x(PROG, ": info: ", (x1), x2, x3, x4, x5, x6) +#define strerr_warni7x(x1, x2, x3, x4, x5, x6, x7) \ +strerr_warn9x(PROG, ": info: ", (x1), x2, x3, x4, x5, x6, x7) +#define strerr_warni8x(x1, x2, x3, x4, x5, x6, x7, x8) \ +strerr_warn10x(PROG, ": info: ", (x1), x2, x3, x4, x5, x6, x7, x8) + +#define strerr_warni1sys(x1) \ +strerr_warn4sys(PROG, ": info: ", (x1), ": ") +#define strerr_warni2sys(x1, x2) \ +strerr_warn5sys(PROG, ": info: ", (x1), (x2), ": ") +#define strerr_warni3sys(x1, x2, x3) \ +strerr_warn6sys(PROG, ": info: ", (x1), x2, (x3), ": ") +#define strerr_warni4sys(x1, x2, x3, x4) \ +strerr_warn7sys(PROG, ": info: ", (x1), x2, x3, (x4), ": ") +#define strerr_warni5sys(x1, x2, x3, x4, x5) \ +strerr_warn8sys(PROG, ": info: ", (x1), x2, x3, x4, (x5), ": ") +#define strerr_warni6sys(x1, x2, x3, x4, x5, x6) \ +strerr_warn9sys(PROG, ": info: ", (x1), x2, x3, x4, x5, (x6), ": ") +#define strerr_warni7sys(x1, x2, x3, x4, x5, x6, x7) \ +strerr_warn10sys(PROG, ": info: ", (x1), x2, x3, x4, x5, x6, (x7), ": ") + +#define strerr_warnt1x(x1) \ +strerr_warn3x(PROG, ": tracing: ", (x1)) +#define strerr_warnt2x(x1, x2) \ +strerr_warn4x(PROG, ": tracing: ", (x1), x2) +#define strerr_warnt3x(x1, x2, x3) \ +strerr_warn5x(PROG, ": tracing: ", (x1), x2, x3) +#define strerr_warnt4x(x1, x2, x3, x4) \ +strerr_warn6x(PROG, ": tracing: ", (x1), x2, x3, x4) +#define strerr_warnt5x(x1, x2, x3, x4, x5) \ +strerr_warn7x(PROG, ": tracing: ", (x1), x2, x3, x4, x5) +#define strerr_warnt6x(x1, x2, x3, x4, x5, x6) \ +strerr_warn8x(PROG, ": tracing: ", (x1), x2, x3, x4, x5, x6) +#define strerr_warnt7x(x1, x2, x3, x4, x5, x6, x7) \ +strerr_warn9x(PROG, ": tracing: ", (x1), x2, x3, x4, x5, x6, x7) +#define strerr_warnt8x(x1, x2, x3, x4, x5, x6, x7, x8) \ +strerr_warn10x(PROG, ": tracing: ", (x1), x2, x3, x4, x5, x6, x7, x8) + +#define strerr_warnt1sys(x1) \ +strerr_warn4sys(PROG, ": tracing: ", (x1), ": ") +#define strerr_warnt2sys(x1, x2) \ +strerr_warn5sys(PROG, ": tracing: ", (x1), (x2), ": ") +#define strerr_warnt3sys(x1, x2, x3) \ +strerr_warn6sys(PROG, ": tracing: ", (x1), x2, (x3), ": ") +#define strerr_warnt4sys(x1, x2, x3, x4) \ +strerr_warn7sys(PROG, ": tracing: ", (x1), x2, x3, (x4), ": ") +#define strerr_warnt5sys(x1, x2, x3, x4, x5) \ +strerr_warn8sys(PROG, ": tracing: ", (x1), x2, x3, x4, (x5), ": ") +#define strerr_warnt6sys(x1, x2, x3, x4, x5, x6) \ +strerr_warn9sys(PROG, ": tracing: ", (x1), x2, x3, x4, x5, (x6), ": ") +#define strerr_warnt7sys(x1, x2, x3, x4, x5, x6, x7) \ +strerr_warn10sys(PROG, ": tracing: ", (x1), x2, x3, x4, x5, x6, (x7), ": ") + +#endif diff --git a/src/include/skalibs/surf.h b/src/include/skalibs/surf.h new file mode 100644 index 0000000..6422903 --- /dev/null +++ b/src/include/skalibs/surf.h @@ -0,0 +1,29 @@ +/* ISC license. */ + +#ifndef SKALIBS_SURF_H +#define SKALIBS_SURF_H + +#include <skalibs/uint32.h> + +typedef struct SURFSchedule SURFSchedule, *SURFSchedule_ref, **SURFSchedule_ref_ref ; +struct SURFSchedule +{ + uint32 seed[32] ; + uint32 in[12] ; + char out[32] ; + unsigned int pos ; +} ; + +#define SURFSCHEDULE_ZERO { .seed = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, .in = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, .out = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", .pos = 32 } + +extern void surf_sinit (SURFSchedule_ref, char const *) ; /* 160 chars */ +extern void surf (SURFSchedule_ref, char *, unsigned int) ; + + + /* The following functions need libstdcrypto.a */ + +extern void surf_makeseed (char *) ; /* fills 160 chars */ +extern void surf_init (SURFSchedule_ref) ; +extern void surf_autoinit (SURFSchedule_ref, char *, unsigned int) ; + +#endif diff --git a/src/include/skalibs/tai.h b/src/include/skalibs/tai.h new file mode 100644 index 0000000..cce5670 --- /dev/null +++ b/src/include/skalibs/tai.h @@ -0,0 +1,140 @@ +/* ISC license. */ + +#ifndef TAI_H +#define TAI_H + +#include <sys/types.h> +#include <time.h> +#include <sys/time.h> +#include <skalibs/gccattributes.h> +#include <skalibs/uint32.h> +#include <skalibs/uint64.h> + +typedef struct tai_s tai_t, *tai_t_ref ; +struct tai_s +{ + uint64 x ; +} ; + + +#define TAI_ZERO { .x = 0 } +#define TAI_MAGIC ((uint64)4611686018427387904ULL) +#define TAI_EPOCH { .x = TAI_MAGIC + 10UL } +#define TAI_INFINITE_RELATIVE { .x = ((uint64)1 << 60) } +#define TAI_INFINITE { .x = TAI_MAGIC + ((uint64)1 << 61) } + +#define tai_sec(t) ((t)->x) +#define tai_u64(t, u) ((void)((t)->x = (u))) +#define tai_unix(t, u) tai_u64(t, (TAI_MAGIC + (u))) +#define tai_uint(t, u) tai_u64(t, (uint64)(u)) + +extern int tai_relative_from_timeval (tai_t *, struct timeval const *) ; +extern int tai_from_timeval (tai_t *, struct timeval const *) ; +extern int timeval_from_tai_relative (struct timeval *, tai_t const *) ; +extern int timeval_from_tai (struct timeval *, tai_t const *) ; + +extern int tai_relative_from_timespec (tai_t *, struct timespec const *) ; +extern int tai_from_timespec (tai_t *, struct timespec const *) ; +extern int timespec_from_tai_relative (struct timespec *, tai_t const *) ; +extern int timespec_from_tai (struct timespec *, tai_t const *) ; + +extern int tai_now (tai_t *) ; +extern int tai_from_sysclock (tai_t *, uint64) ; +extern int sysclock_from_tai (uint64 *, tai_t const *) ; + +#define tai_approx(t) ((double)(tai_sec(t))) + +extern void tai_add (tai_t *, tai_t const *, tai_t const *) ; +extern void tai_sub (tai_t *, tai_t const *, tai_t const *) ; +#define tai_less(t,u) (tai_sec(t) < tai_sec(u)) + +#define TAI_PACK 8 +extern void tai_pack (char *, tai_t const *) ; +extern void tai_unpack (char const *, tai_t *) ; +extern void tai_pack_little (char *, tai_t const *) ; +extern void tai_unpack_little (char const *, tai_t *) ; + +typedef struct tain_s tain_t, *tain_t_ref ; +struct tain_s +{ + tai_t sec ; + uint32 nano ; /* 0..999999999U */ +} ; + +#define TAIN_ZERO { .sec = TAI_ZERO, .nano = 0 } +#define TAIN_EPOCH { .sec = TAI_EPOCH, .nano = 0 } +#define TAIN_INFINITE { .sec = TAI_INFINITE, .nano = 0 } +#define TAIN_INFINITE_RELATIVE { .sec = TAI_INFINITE_RELATIVE, .nano = 0 } +#define TAIN_NANO500 { .sec = TAI_ZERO, .nano = 500 } + +extern tain_t STAMP ; /* the global process wallclock */ +extern tain_t const tain_infinite_relative ; +extern tain_t const tain_nano500 ; + +#define tain_sec(a) ((a)->sec) +#define tain_secp(a) (&(a)->sec) +#define tain_nano(a) ((a)->nano) + +extern int tain_relative_from_timeval (tain_t *, struct timeval const *) ; +extern int tain_from_timeval (tain_t *, struct timeval const *) ; +extern int timeval_from_tain_relative (struct timeval *, tain_t const *) ; +extern int timeval_from_tain (struct timeval *, tain_t const *) ; + +extern int tain_relative_from_timespec (tain_t *, struct timespec const *) ; +extern int tain_from_timespec (tain_t *, struct timespec const *) ; +extern int timespec_from_tain_relative (struct timespec *, tain_t const *) ; +extern int timespec_from_tain (struct timespec *, tain_t const *) ; + +extern int sysclock_get (tain_t *) ; +extern int tain_sysclock (tain_t *) ; +#define tain_sysclock_g() tain_sysclock(&STAMP) +extern int tain_clockmon_init (tain_t *) ; +extern int tain_clockmon (tain_t *, tain_t const *) ; +#define tain_clockmon_g(offset) tain_clockmon(&STAMP, (offset)) +extern int tain_init (void) ; +extern int tain_now (tain_t *) ; +#define tain_now_g() tain_now(&STAMP) +#define tain_copynow(t) (*(t) = STAMP) + +extern int sysclock_set (tain_t const *) ; +extern int tain_setnow (tain_t const *) ; + +extern double tain_approx (tain_t const *) gccattr_pure ; +extern double tain_frac (tain_t const *) gccattr_pure ; + +extern int tain_from_millisecs (tain_t *, int) ; +extern int tain_to_millisecs (tain_t const *) gccattr_pure ; + +extern void tain_add (tain_t *, tain_t const *, tain_t const *) ; +#define tain_add_g(deadline, tto) tain_add(deadline, &STAMP, tto) +extern void tain_addsec (tain_t *, tain_t const *, int) ; +#define tain_addsec_g(deadline, n) tain_addsec(deadline, &STAMP, n) +extern void tain_sub (tain_t *, tain_t const *, tain_t const *) ; +extern void tain_half (tain_t *, tain_t const *) ; +extern int tain_less (tain_t const *, tain_t const *) gccattr_pure ; +#define tain_future(deadline) tain_less(&STAMP, (deadline)) + +#define TAIN_PACK 12 +extern void tain_pack (char *, tain_t const *) ; +extern void tain_unpack (char const *, tain_t *) ; +extern void tain_pack_little (char *, tain_t const *) ; +extern void tain_unpack_little (char const *, tain_t *) ; + +#define TAIN_FMT 25 +extern unsigned int tain_fmt (char *, tain_t const *) ; +extern unsigned int tain_scan (char const *, tain_t *) ; + +#define TAIN_FMTFRAC 19 +extern unsigned int tain_fmtfrac (char *, tain_t const *) ; + +#define tain_uint(a, u) tain_ulong(a, u) +extern void tain_ulong (tain_t *, unsigned long) ; + +#define TIMESTAMP (1 + (TAIN_PACK << 1)) +extern unsigned int timestamp_fmt (char *, tain_t const *) ; +extern unsigned int timestamp_scan (char const *, tain_t *) ; +extern int timestamp_r (char *, tain_t *) ; +extern int timestamp (char *) ; +#define timestamp_g(s) timestamp_fmt((s), &STAMP) + +#endif diff --git a/src/include/skalibs/unirandom.h b/src/include/skalibs/unirandom.h new file mode 100644 index 0000000..fc87886 --- /dev/null +++ b/src/include/skalibs/unirandom.h @@ -0,0 +1,57 @@ +/* ISC license. */ + +#ifndef UNIRANDOM_H +#define UNIRANDOM_H + +#include <skalibs/buffer.h> +#include <skalibs/surf.h> + +#define RANDOMBUF_BUFSIZE 257 + +struct randombuf_s +{ + char buf[RANDOMBUF_BUFSIZE] ; + buffer b ; + unsigned int nb : 1 ; +} ; +#define RANDOMBUF_ZERO { .buf = "", .b = BUFFER_INIT(0, -1, 0, 0), .nb = 0 } + +struct randomegd_s +{ + int fd ; +} ; + +union unirandominfo +{ + SURFSchedule surf_ctx ; + struct randombuf_s device ; + struct randomegd_s egd ; +} ; + +#define UNIRANDOMINFO_ZERO { .surf_ctx = SURFSCHEDULE_ZERO } + +typedef struct unirandom unirandom, *unirandom_ref, **unirandom_ref_ref ; +struct unirandom +{ + unsigned int (*readb) (union unirandominfo *, char *, unsigned int) ; + unsigned int (*readnb) (union unirandominfo *, char *, unsigned int) ; + int (*init) (union unirandominfo *) ; + int (*finish) (union unirandominfo *) ; + union unirandominfo data ; + unsigned int initted : 1 ; +} ; + +#define UNIRANDOM_ZERO { .readb = 0, .readnb = 0, .init = 0, .finish = 0, .data = UNIRANDOMINFO_ZERO, .initted = 0 } + +extern int unirandom_register_devrandom (unirandom_ref) ; +extern int unirandom_register_devurandom (unirandom_ref) ; +extern int unirandom_register_hasegd (unirandom_ref) ; +extern int unirandom_register_surf (unirandom_ref) ; + +extern int unirandom_init (unirandom_ref) ; +extern unsigned int unirandom_readb (unirandom_ref, char *, unsigned int) ; +extern unsigned int unirandom_readnb (unirandom_ref, char *, unsigned int) ; +extern int unirandom_finish (unirandom_ref) ; + + +#endif diff --git a/src/include/skalibs/unirandomdev.h b/src/include/skalibs/unirandomdev.h new file mode 100644 index 0000000..589a1c1 --- /dev/null +++ b/src/include/skalibs/unirandomdev.h @@ -0,0 +1,19 @@ +/* ISC license. */ + +#ifndef UNIRANDOMDEV_H +#define UNIRANDOMDEV_H + +#include <skalibs/unirandom.h> + +extern int unirandomdev_sinit (union unirandominfo *, char const *) ; +extern unsigned int unirandomdev_readb (union unirandominfo *, char *, unsigned int) ; +extern unsigned int unirandomdev_readnb (union unirandominfo *, char *, unsigned int) ; +extern int unirandomdev_finish (union unirandominfo *) ; + +extern int unidevrandom_init (union unirandominfo *) ; +extern int unidevurandom_init (union unirandominfo *) ; + +#define UNIRANDOM_REGISTER_DEVRANDOM() { .readb = &unirandomdev_readb, .readnb = &unirandomdev_readnb, .init = &unidevrandom_init, .finish = &unirandomdev_finish, .data = UNIRANDOMINFO_ZERO, .initted = 0 } +#define UNIRANDOM_REGISTER_DEVURANDOM() { .readb = &unirandomdev_readb, .readnb = &unirandomdev_readnb, .init = &unidevurandom_init, .finish = &unirandomdev_finish, .data = UNIRANDOMINFO_ZERO, .initted = 0 } + +#endif diff --git a/src/include/skalibs/unirandomegd.h b/src/include/skalibs/unirandomegd.h new file mode 100644 index 0000000..11bb464 --- /dev/null +++ b/src/include/skalibs/unirandomegd.h @@ -0,0 +1,17 @@ +/* ISC license. */ + +#ifndef UNIRANDOMEGD_H +#define UNIRANDOMEGD_H + +#include <skalibs/unirandom.h> + +extern int unirandomegd_sinit (union unirandominfo *, char const *) ; +extern unsigned int unirandomegd_readb (union unirandominfo *, char *, unsigned int) ; +extern unsigned int unirandomegd_readnb (union unirandominfo *, char *, unsigned int) ; +extern int unirandomegd_finish (union unirandominfo *) ; + +extern int unihasegd_init (union unirandominfo *) ; + +#define UNIRANDOM_REGISTER_HASEGD() { .readb = &unirandomegd_readb, .readnb = &unirandomegd_readnb, .init = &unihasegd_init, .finish = &unirandomegd_finish, .data = UNIRANDOMINFO_ZERO, .initted = 0 } + +#endif diff --git a/src/include/skalibs/unisurf.h b/src/include/skalibs/unisurf.h new file mode 100644 index 0000000..5c95c82 --- /dev/null +++ b/src/include/skalibs/unisurf.h @@ -0,0 +1,16 @@ +/* ISC license. */ + +#ifndef UNISURF_H +#define UNISURF_H + +#include <skalibs/unirandom.h> + +extern int unisurf_sinit (union unirandominfo *, char const *) ; +extern unsigned int unisurf_read (union unirandominfo *, char *, unsigned int) ; +extern int unisurf_finish (union unirandominfo *) ; + +extern int unisurf_init (union unirandominfo *) ; + +#define UNIRANDOM_REGISTER_SURF() { .readb = &unisurf_read, .readnb = &unisurf_read, .init = &unisurf_init, .finish = &unisurf_finish, .data = UNIRANDOMINFO_ZERO, .initted = 0 } + +#endif diff --git a/src/include/skalibs/unix-timed.h b/src/include/skalibs/unix-timed.h new file mode 100644 index 0000000..f5a25b6 --- /dev/null +++ b/src/include/skalibs/unix-timed.h @@ -0,0 +1,36 @@ +/* ISC license. */ + +#ifndef UNIX_TIMED_H +#define UNIX_TIMED_H + +#include <skalibs/bufalloc.h> +#include <skalibs/buffer.h> +#include <skalibs/functypes.h> +#include <skalibs/stralloc.h> +#include <skalibs/tai.h> + + /* Timed "blocking" operations (the fd must still be non-blocking) */ + + +extern int timed_flush (void *, initfunc_t_ref, initfunc_t_ref, initfunc_t_ref, tain_t const *, tain_t *) ; +#define timed_flush_g(b, getfd, isnonempty, flush, deadline) timed_flush(b, getfd, isnonempty, flush, (deadline_), &STAMP) +extern int timed_get (void *, initfunc_t_ref, initfunc_t_ref, tain_t const *, tain_t *) ; +#define timed_get_g (b, getfd, get, deadline) timed_get(b, getfd, get, (deadline), &STAMP) + +extern int buffer_timed_fill (buffer *, tain_t const *, tain_t *) ; +#define buffer_timed_fill_g(b, deadline) buffer_timed_fill(b, (deadline), &STAMP) +extern int bufalloc_timed_flush (bufalloc *, tain_t const *, tain_t *) ; +#define bufalloc_timed_flush_g(ba, deadline) bufalloc_timed_flush(ba, (deadline), &STAMP) +extern int buffer_timed_flush (buffer *, tain_t const *, tain_t *) ; +#define buffer_timed_flush_g(b, deadline) buffer_timed_flush(b, (deadline), &STAMP) +extern unsigned int buffer_timed_get (buffer *, char *, unsigned int, tain_t const *, tain_t *) ; +#define buffer_timed_get_g(b, buf, buflen, deadline) buffer_timed_get(b, buf, buflen, (deadline), &STAMP) + +extern int timed_getln (buffer_ref, stralloc *, char, tain_t const *, tain_t *) ; +#define timed_getln_g(b, sa, sep, deadline) timed_getln(b, sa, sep, (deadline), &STAMP) +extern int timed_getlnmax (buffer_ref, char *, unsigned int, unsigned int *, char, tain_t const *, tain_t *) ; +#define timed_getlnmax_g(b, max, maxlen, len, sep, deadline) timed_getlnmax(b, max, maxlen, len, sep, (deadline), &STAMP) +extern int netstring_timed_get (buffer *, stralloc *, tain_t const *, tain_t *) ; +#define netstring_timed_get_g(b, sa, deadline) netstring_timed_get(b, sa, (deadline), &STAMP) + +#endif diff --git a/src/include/skalibs/unix-transactional.h b/src/include/skalibs/unix-transactional.h new file mode 100644 index 0000000..e1545e0 --- /dev/null +++ b/src/include/skalibs/unix-transactional.h @@ -0,0 +1,59 @@ +/* ISC license. */ + +#ifndef UNIX_TRANSACTIONAL_H +#define UNIX_TRANSACTIONAL_H + +#include <skalibs/uint64.h> +#include <skalibs/stralloc.h> + + /* Transactional/reliable filesystem operations */ + +extern int open2_at (int, char const *, int) ; +extern int open3_at (int, char const *, int, unsigned int) ; + +extern int opengetlnclose (char const *, stralloc *, int) ; + +extern int open_readat (int, char const *) ; +extern int open_readatb (int, char const *) ; +extern int open_writeat (int, char const *) ; +extern int open_writeatb (int, char const *) ; +extern int open_truncat (int, char const *) ; +extern int open_truncatb (int, char const *) ; +extern int open_appendat (int, char const *) ; +extern int open_appendatb (int, char const *) ; + +extern unsigned int openreadnclose_at (int, char const *, char *, unsigned int) ; +extern int openslurpclose_at (int, char const *, stralloc *) ; +extern int opengetlnclose_at (int, char const *, stralloc *, int) ; + +extern int openwritenclose (char const *, char const *, unsigned int) ; +extern int openwritenclose_devino (char const *, char const *, unsigned int, uint64 *, uint64 *) ; +extern int openwritenclose_tmp (char const *, char const *, unsigned int, stralloc *) ; +extern int openwritenclose_devino_tmp (char const *, char const *, unsigned int, uint64 *, uint64 *, stralloc *) ; +extern unsigned int openwritenclose_at (int, char const *, char const *, unsigned int) ; + +extern int mkdir_unique (stralloc *, char const *, unsigned int) ; + +typedef struct dirdescriptor_s dirdescriptor_t, *dirdescriptor_t_ref ; +struct dirdescriptor_s +{ + int fd ; + char const *lnkfn ; + stralloc new ; +} ; + +#define DIRDESCRIPTOR_ZERO { .fd = 0, .lnkfn = 0, .new = STRALLOC_ZERO } + +extern int dd_open_read (dirdescriptor_t_ref, char const *) ; +extern int dd_open_write (dirdescriptor_t_ref, char const *, unsigned int) ; +extern int dd_close (dirdescriptor_t_ref) ; /* after dd_open_read */ +extern void dd_cancel (dirdescriptor_t_ref) ; /* after dd_open_write */ +extern int dd_commit (dirdescriptor_t_ref) ; /* after dd_open_write */ +extern int dd_commit_devino (dirdescriptor_t_ref, uint64 *, uint64 *) ; /* after dd_open_write */ + +#define dd_openreadnclose(blah, file, s, len) openreadnclose_at((blah)->fd, file, s, len) +#define dd_openslurpclose(blah, file, sa) openslurpclose_at((blah)->fd, file, sa) +#define dd_opengetlnclose(blah, file, sa, sep) opengetlnclose_at((blah)->fd, file, sa, sep) +#define dd_openwritenclose(blah, file, s, len) openwritenclose_at((blah)->fd, file, s, len) + +#endif diff --git a/src/include/skalibs/unixmessage.h b/src/include/skalibs/unixmessage.h new file mode 100644 index 0000000..69d6717 --- /dev/null +++ b/src/include/skalibs/unixmessage.h @@ -0,0 +1,103 @@ +/* ISC license. */ + +#ifndef UNIXMESSAGE_H +#define UNIXMESSAGE_H + +#include <skalibs/buffer.h> +#include <skalibs/cbuffer.h> +#include <skalibs/gccattributes.h> +#include <skalibs/genalloc.h> +#include <skalibs/siovec.h> +#include <skalibs/stralloc.h> +#include <skalibs/tai.h> + +typedef struct unixmessage_s unixmessage_t, *unixmessage_t_ref ; +struct unixmessage_s +{ + char *s ; + unsigned int len ; + int *fds ; + unsigned int nfds ; +} ; +#define UNIXMESSAGE_ZERO { .s = 0, .len = 0, .fds = 0, .nfds = 0 } +extern unixmessage_t const unixmessage_zero ; + +typedef struct unixmessage_v_s unixmessage_v_t, *unixmessage_v_t_ref ; +struct unixmessage_v_s +{ + siovec_t *v ; + unsigned int vlen ; + int *fds ; + unsigned int nfds ; +} ; +#define UNIXMESSAGE_V_ZERO { .v = 0, .vlen = 0, .fds = 0, .nfds = 0 } +extern unixmessage_v_t const unixmessage_v_zero ; + + +#define UNIXMESSAGE_BUFSIZE 2049 +#define UNIXMESSAGE_AUXBUFSIZE 2049 +#define UNIXMESSAGE_MAXFDS 256 +#define UNIXMESSAGE_MAXREADS 32 + +typedef struct unixmessage_sender_s unixmessage_sender_t, *unixmessage_sender_t_ref ; +struct unixmessage_sender_s +{ + int fd ; + stralloc data ; + genalloc fds ; /* int */ + genalloc offsets ; /* diuint */ + unsigned int head ; +} ; +#define UNIXMESSAGE_SENDER_ZERO UNIXMESSAGE_SENDER_INIT(-1) +#define UNIXMESSAGE_SENDER_INIT(s) { .fd = (s), .data = STRALLOC_ZERO, .fds = GENALLOC_ZERO, .offsets = GENALLOC_ZERO, .head = 0 } + +extern unixmessage_sender_t const unixmessage_sender_zero ; +extern void unixmessage_sender_init (unixmessage_sender_t *, int) ; +extern void unixmessage_sender_free (unixmessage_sender_t *) ; +#define unixmessage_sender_fd(b) ((b)->fd) +extern int unixmessage_sender_getfd (unixmessage_sender_t const *) gccattr_pure ; + +extern int unixmessage_put_and_close (unixmessage_sender_t *, unixmessage_t const *, unsigned char const *) ; +#define unixmessage_put(b, m) unixmessage_put_and_close(b, m, unixmessage_bits_closenone) +extern int unixmessage_putv_and_close (unixmessage_sender_t *, unixmessage_v_t const *, unsigned char const *) ; +#define unixmessage_putv(b, m) unixmessage_putv_and_close(b, m, unixmessage_bits_closenone) + +extern unsigned char const *const unixmessage_bits_closenone ; +extern unsigned char const *const unixmessage_bits_closeall ; + +extern int unixmessage_sender_flush (unixmessage_sender_t *) ; +extern int unixmessage_sender_timed_flush (unixmessage_sender_t *, tain_t const *, tain_t *) ; +#define unixmessage_sender_timed_flush_g(sender, deadline) unixmessage_sender_timed_flush(sender, (deadline), &STAMP) + + +typedef struct unixmessage_receiver_s unixmessage_receiver_t, *unixmessage_receiver_t_ref ; +struct unixmessage_receiver_s +{ + buffer mainb ; + cbuffer_t auxb ; + unsigned int mainlen ; + unsigned int auxlen ; + stralloc data ; + int fds[UNIXMESSAGE_MAXFDS] ; + unsigned int auxw ; +} ; +#define UNIXMESSAGE_RECEIVER_ZERO { .mainb = BUFFER_ZERO, .auxb = CBUFFER_ZERO, .mainlen = 0, .auxlen = 0, .data = STRALLOC_ZERO, .fds = { -1 }, .auxw = 0 } + +extern int unixmessage_receiver_init (unixmessage_receiver_t *, int, char *, unsigned int, char *, unsigned int) ; +extern void unixmessage_receiver_free (unixmessage_receiver_t *) ; +#define unixmessage_receiver_fd(b) buffer_fd(&(b)->mainb) + +extern int unixmessage_receive (unixmessage_receiver_t *, unixmessage_t *) ; +extern int unixmessage_timed_receive (unixmessage_receiver_t *, unixmessage_t *, tain_t const *, tain_t *) ; +#define unixmessage_timed_receive_g(receiver, msg, deadline) unixmessage_timed_receive(receiver, msg, (deadline), &STAMP) + +extern buffer_io_func_t unixmessage_read ; + +typedef int unixmessage_handler_func_t (unixmessage_t const *, void *) ; +typedef unixmessage_handler_func_t *unixmessage_handler_func_t_ref ; + +extern int unixmessage_handle (unixmessage_receiver_t *, unixmessage_handler_func_t *, void *) ; +extern int unixmessage_timed_handle (unixmessage_receiver_t *, unixmessage_handler_func_t *, void *, tain_t const *, tain_t *) ; +#define unixmessage_timed_handle_g(b, f, p, deadline) unixmessage_timed_handle(b, f, p, (deadline), &STAMP) + +#endif diff --git a/src/include/skalibs/unixonacid.h b/src/include/skalibs/unixonacid.h new file mode 100644 index 0000000..a150e39 --- /dev/null +++ b/src/include/skalibs/unixonacid.h @@ -0,0 +1,12 @@ +/* ISC license. */ + +#ifndef UNIXONACID_H +#define UNIXONACID_H + +#include <skalibs/unix-transactional.h> +#include <skalibs/unix-timed.h> +#include <skalibs/unixmessage.h> +#include <skalibs/kolbak.h> +#include <skalibs/skaclient.h> + +#endif diff --git a/src/include/skalibs/webipc.h b/src/include/skalibs/webipc.h new file mode 100644 index 0000000..6b2c1fe --- /dev/null +++ b/src/include/skalibs/webipc.h @@ -0,0 +1,60 @@ +/* ISC license. */ + +#ifndef WEBIPC_H +#define WEBIPC_H + + /* + UNIX domain socket functions. + "web" stands for William E. Baxter, the original author, who kindly + permitted me to modify and release his code as a part of skalibs. + It has nothing to do with the World Wide Web. + */ + +#define IPCPATH_MAX 107 + +#include <skalibs/tai.h> +#include <skalibs/djbunix.h> + +#define ipc_stream() ipc_stream_nb() +#define ipc_stream_b() ipc_stream_internal(0) +#define ipc_stream_nb() ipc_stream_internal(DJBUNIX_FLAG_NB) +#define ipc_stream_coe() ipc_stream_internal(DJBUNIX_FLAG_COE) +#define ipc_stream_nbcoe() ipc_stream_internal(DJBUNIX_FLAG_NB|DJBUNIX_FLAG_COE) +extern int ipc_stream_internal (unsigned int) ; + +#define ipc_datagram() ipc_datagram_nb() +#define ipc_datagram_b() ipc_datagram_internal(0) +#define ipc_datagram_nb() ipc_datagram_internal(DJBUNIX_FLAG_NB) +#define ipc_datagram_coe() ipc_datagram_internal(DJBUNIX_FLAG_COE) +#define ipc_datagram_nbcoe() ipc_datagram_internal(DJBUNIX_FLAG_NB|DJBUNIX_FLAG_COE) +extern int ipc_datagram_internal (unsigned int) ; + +#define ipc_pair(sv) ipc_pair_nb(sv) +#define ipc_pair_b(sv) ipc_pair_internal((sv), 0) +#define ipc_pair_nb(sv) ipc_pair_internal((sv), DJBUNIX_FLAG_NB) +#define ipc_pair_coe(sv) ipc_pair_internal((sv), DJBUNIX_FLAG_COE) +#define ipc_pair_nbcoe(sv) ipc_pair_internal((sv), DJBUNIX_FLAG_NB|DJBUNIX_FLAG_COE) +extern int ipc_pair_internal (int *, unsigned int) ; + +extern int ipc_bind (int, char const *) ; +extern int ipc_bind_reuse (int, char const *) ; +extern int ipc_listen (int, int) ; + +#define ipc_accept(s, path, len, trunc) ipc_accept_internal(s, path, len, (trunc), 0) +#define ipc_accept_nb(s, path, len, trunc) ipc_accept_internal(s, path, len, (trunc), DJBUNIX_FLAG_NB) +#define ipc_accept_coe(s, path, len, trunc) ipc_accept_internal(s, path, len, (trunc), DJBUNIX_FLAG_COE) +#define ipc_accept_nbcoe(s, path, len, trunc) ipc_accept_internal(s, path, len, (trunc), DJBUNIX_FLAG_NB|DJBUNIX_FLAG_COE) +extern int ipc_accept_internal (int, char *, unsigned int, int *, unsigned int) ; + +extern int ipc_eid (int, unsigned int *, unsigned int *) ; +extern int ipc_local (int, char *, unsigned int, int *) ; + +extern int ipc_connect (int, char const *) ; +extern int ipc_connected (int) ; +extern int ipc_timed_connect (int, char const *, tain_t const *, tain_t *) ; +#define ipc_timed_connect_g(fd, path, deadline) ipc_timed_connect(fd, path, (deadline), &STAMP) + +extern int ipc_send (int, char const *, unsigned int, char const *) ; +extern int ipc_recv (int, char *, unsigned int, char *) ; + +#endif diff --git a/src/libbiguint/bu_addc.c b/src/libbiguint/bu_addc.c new file mode 100644 index 0000000..0a57531 --- /dev/null +++ b/src/libbiguint/bu_addc.c @@ -0,0 +1,22 @@ +/* ISC license. */ + +/* OpenBSD needs that for EOVERFLOW. wtfbsdseriously */ +#define _BSD_SOURCE + +#include <errno.h> +#include <skalibs/uint32.h> +#include <skalibs/biguint.h> + +int bu_addc (uint32 *c, unsigned int cn, uint32 const *a, unsigned int an, uint32 const *b, unsigned int bn, register int carry) +{ + register unsigned int i = 0 ; + for (; i < cn ; i++) + { + register uint32 ai = (i < an) ? a[i] : 0 ; + register uint32 bi = (i < bn) ? b[i] : 0 ; + register uint32 ci = ai + bi + carry ; + carry = (carry || bi) && (ci < ai) ; + c[i] = ci ; + } + return carry ? (errno = EOVERFLOW, 0) : 1 ; +} diff --git a/src/libbiguint/bu_addmod.c b/src/libbiguint/bu_addmod.c new file mode 100644 index 0000000..c997897 --- /dev/null +++ b/src/libbiguint/bu_addmod.c @@ -0,0 +1,11 @@ +/* ISC license. */ + +#include <skalibs/uint32.h> +#include <skalibs/biguint.h> + +int bu_addmod (uint32 *c, unsigned int cn, uint32 const *a, unsigned int an, uint32 const *b, unsigned int bn, uint32 const *m, unsigned int mn) +{ + if (!bu_add(c, cn, a, an, b, bn)) return 0 ; + if (bu_cmp(c, cn, m, mn) >= 0) bu_sub(c, cn, c, cn, m, mn) ; + return 1 ; +} diff --git a/src/libbiguint/bu_cmp.c b/src/libbiguint/bu_cmp.c new file mode 100644 index 0000000..a6bfaeb --- /dev/null +++ b/src/libbiguint/bu_cmp.c @@ -0,0 +1,18 @@ +/* ISC license. */ + +#include <skalibs/uint32.h> +#include <skalibs/biguint.h> + +int bu_cmp (register uint32 const *a, register unsigned int an, register uint32 const *b, register unsigned int bn) +{ + an = bu_len(a, an) ; + bn = bu_len(b, bn) ; + if (an < bn) return -1 ; + if (an > bn) return 1 ; + while (bn--) + { + if (a[bn] < b[bn]) return -1 ; + if (a[bn] > b[bn]) return 1 ; + } + return 0 ; +} diff --git a/src/libbiguint/bu_copy.c b/src/libbiguint/bu_copy.c new file mode 100644 index 0000000..1358aca --- /dev/null +++ b/src/libbiguint/bu_copy.c @@ -0,0 +1,21 @@ +/* ISC license. */ + +/* OpenBSD needs that for EOVERFLOW. wtfbsdseriously */ +#define _BSD_SOURCE + +#include <errno.h> +#include <skalibs/uint32.h> +#include <skalibs/biguint.h> + +int bu_copy (uint32 *b, unsigned int bn, uint32 const *a, unsigned int an) +{ + register unsigned int alen = bu_len(a, an) ; + if (bn < alen) + { + bu_copy_internal(b, a, bn) ; + return (errno = EOVERFLOW, 0) ; + } + bu_copy_internal(b, a, alen) ; + bu_zero(b + alen, bn - alen) ; + return 1 ; +} diff --git a/src/libbiguint/bu_copy_internal.c b/src/libbiguint/bu_copy_internal.c new file mode 100644 index 0000000..919929b --- /dev/null +++ b/src/libbiguint/bu_copy_internal.c @@ -0,0 +1,9 @@ +/* ISC license. */ + +#include <skalibs/uint32.h> +#include <skalibs/biguint.h> + +void bu_copy_internal (register uint32 *b, register uint32 const *a, register unsigned int n) +{ + while (n--) b[n] = a[n] ; +} diff --git a/src/libbiguint/bu_div.c b/src/libbiguint/bu_div.c new file mode 100644 index 0000000..c7718e2 --- /dev/null +++ b/src/libbiguint/bu_div.c @@ -0,0 +1,23 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/uint32.h> +#include <skalibs/biguint.h> + +int bu_div (uint32 const *a, unsigned int an, uint32 const *b, unsigned int bn, uint32 *q, unsigned int qn, uint32 *r, unsigned int rn) +{ + unsigned int alen = bu_len(a, an) ; + unsigned int blen = bu_len(b, bn) ; + if (!blen) return (errno = EDOM, 0) ; + else + { + uint32 qq[alen] ; + uint32 rr[alen] ; + register int qh, rh ; + bu_copy_internal(rr, a, alen) ; + bu_div_internal(rr, alen, b, blen, qq, alen) ; + qh = bu_copy(q, qn, qq, alen) ; + rh = bu_copy(r, rn, rr, alen) ; + return qh && rh ; + } +} diff --git a/src/libbiguint/bu_div_internal.c b/src/libbiguint/bu_div_internal.c new file mode 100644 index 0000000..d1be789 --- /dev/null +++ b/src/libbiguint/bu_div_internal.c @@ -0,0 +1,46 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/uint32.h> +#include <skalibs/biguint.h> + +/* + q = a/b, a = a mod b. Assumes b != 0 and qn >= alen - blen + 1. +*/ + +void bu_div_internal (uint32 *a, unsigned int an, uint32 const *b, unsigned int bn, uint32 *q, unsigned int qn) +{ + unsigned int alen = bu_len(a, an) ; + unsigned int blen = bu_len(b, bn) ; + bu_zero(q, qn) ; + if (alen < blen) return ; + { + uint32 bb[alen + 1] ; + unsigned int i = 1 + ((alen - blen) << 5) ; + bu_zero(bb, alen - blen) ; + bu_copy_internal(bb + alen - blen, b, blen) ; + bb[alen] = 0 ; + + while (bu_cmp(a, alen, bb, alen+1) >= 0) + { + bu_slb(bb + alen - blen, blen + 1) ; + i++ ; + } + while (i && (bu_cmp(a, alen, bb, alen+1) < 0)) + { + bu_srb(bb, alen + 1) ; + i-- ; + } + + while (i--) + { + bu_slb(q, alen - blen + 1) ; + if (bu_cmp(a, alen, bb, alen) >= 0) + { + bu_sub(a, alen, a, alen, bb, alen) ; + q[0] |= 1 ; + } + bu_srb(bb, alen) ; + } + } +} diff --git a/src/libbiguint/bu_divmod.c b/src/libbiguint/bu_divmod.c new file mode 100644 index 0000000..5d5802f --- /dev/null +++ b/src/libbiguint/bu_divmod.c @@ -0,0 +1,32 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/uint32.h> +#include <skalibs/biguint.h> + +/* + q = y/x mod m. +*/ + +int bu_divmod (uint32 *q, unsigned int qn, uint32 const *y, unsigned int yn, uint32 const *x, unsigned int xn, uint32 const *m, unsigned int mn) +{ + unsigned int ylen = bu_len(y, yn) ; + unsigned int xlen = bu_len(x, xn) ; + unsigned int mlen = bu_len(m, mn) ; + unsigned int n = ylen ; + if (n < xlen) n = xlen ; + if (n < mlen) n = mlen ; + if (!n) return (errno = EDOM, 0) ; + { + uint32 yy[n] ; + uint32 xx[n] ; + uint32 mm[n] ; + bu_gcd(xx, n, x, xlen, m, mlen) ; + if ((xx[0] != 1) || (bu_len(xx, n) != 1)) return (errno = EDOM, 0) ; + bu_copy_internal(yy, y, ylen) ; bu_zero(yy+ylen, n-ylen) ; + bu_copy_internal(xx, x, xlen) ; bu_zero(xx+xlen, n-xlen) ; + bu_copy_internal(mm, m, mlen) ; bu_zero(mm+mlen, n-mlen) ; + bu_divmod_internal(yy, xx, mm, n) ; + return bu_copy(q, qn, yy, n) ; + } +} diff --git a/src/libbiguint/bu_divmod_internal.c b/src/libbiguint/bu_divmod_internal.c new file mode 100644 index 0000000..46d3335 --- /dev/null +++ b/src/libbiguint/bu_divmod_internal.c @@ -0,0 +1,37 @@ +/* ISC license. */ + +#include <skalibs/uint32.h> +#include <skalibs/biguint.h> + +/* + u = u/a mod m. a and m must be relatively prime - otherwise, infinite loop. + a is not immutable. + Original idea: see http://research.sun.com/techrep/2001/abstract-95.html +*/ + +void bu_divmod_internal (register uint32 *u, register uint32 *a, register uint32 const *m, unsigned int n) +{ + uint32 bb[n] ; register uint32 *b = bb ; + uint32 vv[n] ; register uint32 *v = vv ; + bu_copy_internal(b, m, n) ; + bu_zero(v, n) ; + + /*** XXX: this iterates like mad, should probably be optimized more */ + for (;;) + { + while (!(a[0] & 1)) + { + bu_srb(a, n) ; + if (u[0] & 1) bu_add(u, n, u, n, m, n) ; + bu_srb(u, n) ; + } + if ((a[0] == 1) && (bu_len(a, n) == 1)) break ; + if (bu_cmp(a, n, b, n) < 0) + { + register uint32 *t = a ; a = b ; b = t ; + t = u ; u = v ; v = t ; + } + bu_add(a, n, a, n, b, n) ; + bu_add(u, n, u, n, v, n) ; + } +} diff --git a/src/libbiguint/bu_fmt.c b/src/libbiguint/bu_fmt.c new file mode 100644 index 0000000..31fa706 --- /dev/null +++ b/src/libbiguint/bu_fmt.c @@ -0,0 +1,19 @@ +/* ISC license. */ + +#include <skalibs/uint32.h> +#include <skalibs/bytestr.h> +#include <skalibs/biguint.h> + +unsigned int bu_fmt (char *s, uint32 const *x, unsigned int n) +{ + unsigned int len = 0 ; + while (n--) + { + char fmt[8] ; + unsigned int i = uint32_xfmt(fmt, x[n]) ; + byte_copy(s+len, 8-i, "00000000") ; + byte_copy(s+len+8-i, i, fmt) ; + len += 8 ; + } + return len ; +} diff --git a/src/libbiguint/bu_gcd.c b/src/libbiguint/bu_gcd.c new file mode 100644 index 0000000..d6c5791 --- /dev/null +++ b/src/libbiguint/bu_gcd.c @@ -0,0 +1,33 @@ +/* ISC license. */ + +#include <skalibs/uint32.h> +#include <skalibs/biguint.h> + +int bu_gcd (uint32 *r, unsigned int rn, uint32 const *a, unsigned int an, uint32 const *b, unsigned int bn) +{ + if (bu_cmp(a, an, b, bn) < 0) + { + register uint32 const *t = a ; + register unsigned int tn = an ; + a = b ; an = bn ; + b = t ; bn = tn ; + } + { + uint32 trash[an] ; + uint32 aa[an] ; + uint32 bb[an] ; + uint32 *aaa = aa, *bbb = bb ; + bu_copy_internal(aa, a, an) ; + bu_copy_internal(bb, b, bn) ; + bu_zero(bb+bn, an-bn) ; + + while (bu_len(bbb, an)) + { + register uint32 *ttt = aaa ; + bu_div_internal(aaa, an, bbb, an, trash, an) ; + aaa = bbb ; + bbb = ttt ; + } + return bu_copy(r, rn, aaa, an) ; + } +} diff --git a/src/libbiguint/bu_invmod.c b/src/libbiguint/bu_invmod.c new file mode 100644 index 0000000..ff209e7 --- /dev/null +++ b/src/libbiguint/bu_invmod.c @@ -0,0 +1,12 @@ +/* ISC license. */ + +#include <skalibs/uint32.h> +#include <skalibs/biguint.h> + +/* x^-1 mod m. */ + +int bu_invmod (uint32 *x, unsigned int xn, uint32 const *m, unsigned int mn) +{ + uint32 const one = 1 ; + return bu_divmod(x, xn, &one, 1, x, xn, m, mn) ; +} diff --git a/src/libbiguint/bu_len.c b/src/libbiguint/bu_len.c new file mode 100644 index 0000000..0f6ec10 --- /dev/null +++ b/src/libbiguint/bu_len.c @@ -0,0 +1,10 @@ +/* ISC license. */ + +#include <skalibs/uint32.h> +#include <skalibs/biguint.h> + +unsigned int bu_len (register uint32 const *a, register unsigned int n) +{ + while (n--) if (a[n]) return n+1 ; + return 0 ; +} diff --git a/src/libbiguint/bu_mod.c b/src/libbiguint/bu_mod.c new file mode 100644 index 0000000..2050320 --- /dev/null +++ b/src/libbiguint/bu_mod.c @@ -0,0 +1,10 @@ +/* ISC license. */ + +#include <skalibs/uint32.h> +#include <skalibs/biguint.h> + +int bu_mod (uint32 *a, unsigned int an, uint32 const *b, unsigned int bn) +{ + uint32 q[an] ; + return bu_div(a, an, b, bn, q, an, a, an) ; +} diff --git a/src/libbiguint/bu_mul.c b/src/libbiguint/bu_mul.c new file mode 100644 index 0000000..184d652 --- /dev/null +++ b/src/libbiguint/bu_mul.c @@ -0,0 +1,32 @@ +/* ISC license. */ + +#include <skalibs/uint32.h> +#include <skalibs/uint64.h> +#include <skalibs/biguint.h> + + /* No Karatsuba. Keep it simple, stupid. */ + +int bu_mul (uint32 *x, unsigned int xn, uint32 const *a, unsigned int an, uint32 const *b, unsigned int bn) +{ + unsigned int alen = bu_len(a, an) ; + unsigned int blen = bu_len(b, bn) ; + uint32 c[alen + blen] ; + register unsigned int i = 0 ; + bu_zero(c, alen + blen) ; + for (; i < alen ; i++) + { + register uint32 carry = 0 ; + register unsigned int j = 0 ; + for (; j < blen ; j++) + { + register uint64 t = a[i] ; + t *= b[j] ; + t += c[i+j] ; + t += carry ; + c[i+j] = (uint32)t ; + carry = (uint32)(t >> 32) ; + } + c[i+j] += carry ; + } + return bu_copy(x, xn, c, alen+blen) ; +} diff --git a/src/libbiguint/bu_mulmod.c b/src/libbiguint/bu_mulmod.c new file mode 100644 index 0000000..18e5a1c --- /dev/null +++ b/src/libbiguint/bu_mulmod.c @@ -0,0 +1,16 @@ +/* ISC license. */ + +#include <skalibs/uint32.h> +#include <skalibs/biguint.h> + + /* Nope, no Montgomery either. */ + +int bu_mulmod (uint32 *c, unsigned int cn, uint32 const *a, unsigned int an, uint32 const *b, unsigned int bn, uint32 const *m, unsigned int mn) +{ + unsigned int alen = bu_len(a, an) ; + unsigned int blen = bu_len(b, bn) ; + uint32 x[alen+blen] ; + if (!bu_mul(x, alen+blen, a, alen, b, blen)) return 0 ; + if (!bu_mod(x, alen+blen, m, mn)) return 0 ; + return bu_copy(c, cn, x, mn) ; +} diff --git a/src/libbiguint/bu_pack.c b/src/libbiguint/bu_pack.c new file mode 100644 index 0000000..0145b9f --- /dev/null +++ b/src/libbiguint/bu_pack.c @@ -0,0 +1,9 @@ +/* ISC license. */ + +#include <skalibs/uint32.h> +#include <skalibs/biguint.h> + +void bu_pack (char *s, uint32 const *a, register unsigned int n) +{ + while (n--) uint32_pack(s + (n<<2), a[n]) ; +} diff --git a/src/libbiguint/bu_pack_big.c b/src/libbiguint/bu_pack_big.c new file mode 100644 index 0000000..8340fd7 --- /dev/null +++ b/src/libbiguint/bu_pack_big.c @@ -0,0 +1,10 @@ +/* ISC license. */ + +#include <skalibs/uint32.h> +#include <skalibs/biguint.h> + +void bu_pack_big (char *s, uint32 const *a, unsigned int n) +{ + register unsigned int i = 0 ; + for (; i < n ; i++) uint32_pack_big(s + (i<<2), a[n-1-i]) ; +} diff --git a/src/libbiguint/bu_scan.c b/src/libbiguint/bu_scan.c new file mode 100644 index 0000000..a34ed99 --- /dev/null +++ b/src/libbiguint/bu_scan.c @@ -0,0 +1,18 @@ +/* ISC license. */ + +/* OpenBSD needs that for EOVERFLOW. wtfbsdseriously */ +#define _BSD_SOURCE + +#include <errno.h> +#include <skalibs/uint32.h> +#include <skalibs/bitarray.h> +#include <skalibs/biguint.h> + +int bu_scan (char const *s, unsigned int len, uint32 *x, unsigned int xn, unsigned int zeron) +{ + register unsigned int n = bitarray_div8(zeron) ; + if (xn < n) return (errno = EOVERFLOW, 0) ; + bu_scan_internal(s, len, x) ; + bu_zero(x + n, xn - n) ; + return 1 ; +} diff --git a/src/libbiguint/bu_scan_internal.c b/src/libbiguint/bu_scan_internal.c new file mode 100644 index 0000000..696880a --- /dev/null +++ b/src/libbiguint/bu_scan_internal.c @@ -0,0 +1,21 @@ +/* ISC license. */ + +#include <skalibs/uint32.h> +#include <skalibs/bytestr.h> +#include <skalibs/biguint.h> + +void bu_scan_internal (char const *s, unsigned int len, uint32 *x) +{ + char fmt[9] = "\0\0\0\0\0\0\0\0" ; + unsigned int i = 0 ; + if (len & 7) + { + byte_copy(fmt, len & 7, s) ; + uint32_xscan(fmt, x + (len >> 3)) ; + } + for (; i < (len >> 3) ; i++) + { + byte_copy(fmt, 8, s + len - 8 - (i << 3)) ; + uint32_xscan(fmt, x + i) ; + } +} diff --git a/src/libbiguint/bu_scanlen.c b/src/libbiguint/bu_scanlen.c new file mode 100644 index 0000000..88c6aee --- /dev/null +++ b/src/libbiguint/bu_scanlen.c @@ -0,0 +1,12 @@ +/* ISC license. */ + +#include <skalibs/fmtscan.h> +#include <skalibs/biguint.h> + +unsigned int bu_scanlen (char const *s, unsigned int *zeron) +{ + unsigned int n = ucharn_findlen(s) ; + *zeron = n ; + while (*s == '0') { s++ ; (*zeron)-- ; } + return n ; +} diff --git a/src/libbiguint/bu_slbc.c b/src/libbiguint/bu_slbc.c new file mode 100644 index 0000000..081c599 --- /dev/null +++ b/src/libbiguint/bu_slbc.c @@ -0,0 +1,17 @@ +/* ISC license. */ + +#include <skalibs/uint32.h> +#include <skalibs/biguint.h> + +int bu_slbc (register uint32 *a, register unsigned int n, register int carry) +{ + register unsigned int i = 0 ; + carry = !!carry ; + for (; i < n ; i++) + { + register int c = a[i] >> 31 ; + a[i] = (a[i] << 1) | carry ; + carry = c ; + } + return carry ; +} diff --git a/src/libbiguint/bu_srbc.c b/src/libbiguint/bu_srbc.c new file mode 100644 index 0000000..87196b1 --- /dev/null +++ b/src/libbiguint/bu_srbc.c @@ -0,0 +1,15 @@ +/* ISC license. */ + +#include <skalibs/uint32.h> +#include <skalibs/biguint.h> + +int bu_srbc (register uint32 *a, register unsigned int n, register int carry) +{ + while (n--) + { + register int c = a[n] & 1 ; + a[n] = (a[n] >> 1) | (carry ? 0x80000000UL : 0) ; + carry = c ; + } + return carry ; +} diff --git a/src/libbiguint/bu_subc.c b/src/libbiguint/bu_subc.c new file mode 100644 index 0000000..c26adca --- /dev/null +++ b/src/libbiguint/bu_subc.c @@ -0,0 +1,22 @@ +/* ISC license. */ + +/* OpenBSD needs that for EOVERFLOW. wtfbsdseriously */ +#define _BSD_SOURCE + +#include <errno.h> +#include <skalibs/uint32.h> +#include <skalibs/biguint.h> + +int bu_subc (uint32 *c, unsigned int cn, uint32 const *a, unsigned int an, uint32 const *b, unsigned int bn, register int carry) +{ + register unsigned int i = 0 ; + for (; i < cn ; i++) + { + register uint32 ai = (i < an) ? a[i] : 0 ; + register uint32 bi = (i < bn) ? b[i] : 0 ; + register uint32 ci = ai - bi - carry ; + carry = (carry || bi) && (ci > ai) ; + c[i] = ci ; + } + return carry ? (errno = EOVERFLOW, 0) : 1 ; +} diff --git a/src/libbiguint/bu_submod.c b/src/libbiguint/bu_submod.c new file mode 100644 index 0000000..f988a50 --- /dev/null +++ b/src/libbiguint/bu_submod.c @@ -0,0 +1,12 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/uint32.h> +#include <skalibs/biguint.h> + +int bu_submod (uint32 *c, unsigned int cn, uint32 const *a, unsigned int an, uint32 const *b, unsigned int bn, uint32 const *m, unsigned int mn) +{ + if (!bu_sub(c, cn, a, an, b, bn) && bu_add(c, cn, c, cn, m, mn)) + return (errno = EDOM, 0) ; + return (errno = 0, 1) ; +} diff --git a/src/libbiguint/bu_unpack.c b/src/libbiguint/bu_unpack.c new file mode 100644 index 0000000..d4f4130 --- /dev/null +++ b/src/libbiguint/bu_unpack.c @@ -0,0 +1,9 @@ +/* ISC license. */ + +#include <skalibs/uint32.h> +#include <skalibs/biguint.h> + +void bu_unpack (char const *s, uint32 *a, register unsigned int n) +{ + while (n--) uint32_unpack(s + (n<<2), a + n) ; +} diff --git a/src/libbiguint/bu_unpack_big.c b/src/libbiguint/bu_unpack_big.c new file mode 100644 index 0000000..ef79029 --- /dev/null +++ b/src/libbiguint/bu_unpack_big.c @@ -0,0 +1,10 @@ +/* ISC license. */ + +#include <skalibs/uint32.h> +#include <skalibs/biguint.h> + +void bu_unpack_big (char const *s, uint32 *a, unsigned int n) +{ + register unsigned int i = 0 ; + for (; i < n ; i++) uint32_unpack_big(s + (i<<2), a + n - 1 - i) ; +} diff --git a/src/libbiguint/bu_zero.c b/src/libbiguint/bu_zero.c new file mode 100644 index 0000000..07efd69 --- /dev/null +++ b/src/libbiguint/bu_zero.c @@ -0,0 +1,9 @@ +/* ISC license. */ + +#include <skalibs/uint32.h> +#include <skalibs/biguint.h> + +void bu_zero (register uint32 *z, register unsigned int n) +{ + while (n--) z[n] = 0 ; +} diff --git a/src/libdatastruct/avlnode-internal.h b/src/libdatastruct/avlnode-internal.h new file mode 100644 index 0000000..0342695 --- /dev/null +++ b/src/libdatastruct/avlnode-internal.h @@ -0,0 +1,15 @@ +/* ISC license. */ + +#ifndef AVLNODE_INTERNAL_H +#define AVLNODE_INTERNAL_H + +#include <skalibs/avlnode.h> + +#define avlnode_ufroms(c) ((c) > 0) +#define avlnode_sfromu(h) ((h) ? 1 : -1) + +extern unsigned int avlnode_rotate (avlnode_ref, unsigned int, unsigned int, int) ; +extern unsigned int avlnode_doublerotate (avlnode_ref, unsigned int, unsigned int, int) ; +#define avlnode_rotate_maydouble(s, max, r, h, isdouble) ((isdouble) ? avlnode_doublerotate(s, max, r, h) : avlnode_rotate(s, max, r, h)) + +#endif diff --git a/src/libdatastruct/avlnode_delete.c b/src/libdatastruct/avlnode_delete.c new file mode 100644 index 0000000..b0f9dd0 --- /dev/null +++ b/src/libdatastruct/avlnode_delete.c @@ -0,0 +1,72 @@ +/* ISC license. */ + +#include <skalibs/functypes.h> +#include <skalibs/avlnode.h> +#include "avlnode-internal.h" + +unsigned int avlnode_delete (avlnode_ref s, unsigned int max, unsigned int *root, void const *k, dtokfunc_t_ref dtok, cmpfunc_t_ref f, void *p) +{ + unsigned int stack[AVLNODE_MAXDEPTH] ; + int spin[AVLNODE_MAXDEPTH] ; + unsigned int sp = 0 ; + unsigned int r = *root ; + unsigned int itodel ; + + for (; r < max ; sp++) + { + register int c = (*f)(k, (*dtok)(s[r].data, p), p) ; + if (!c) break ; + spin[sp] = avlnode_ufroms(c) ; + stack[sp] = r ; + r = s[r].child[spin[sp]] ; + } + if (r >= max) return max ; + itodel = r ; + + if ((s[r].child[0] < max) || (s[r].child[1] < max)) + { + int subspin = s[r].child[1] < max ; + stack[sp] = r ; + spin[sp++] = subspin ; + r = s[r].child[subspin] ; + for (; r < max ; sp++) + { + stack[sp] = r ; + spin[sp] = !subspin ; + r = s[r].child[!subspin] ; + } + r = stack[--sp] ; + s[itodel].data = s[r].data ; + itodel = s[r].child[subspin] ; + if (itodel < max) + { + s[r].data = s[itodel].data ; + stack[sp] = r ; + spin[sp++] = subspin ; + } + else itodel = r ; + } + + r = max ; + while (sp--) + { + s[stack[sp]].child[spin[sp]] = r ; + r = stack[sp] ; + if (!s[r].balance) goto easyfix ; + else if (spin[sp] == avlnode_ufroms(s[r].balance)) s[r].balance = 0 ; + else if (!s[s[r].child[!spin[sp]]].balance) goto hardfix ; + else r = avlnode_rotate_maydouble(s, max, r, spin[sp], spin[sp] == avlnode_ufroms(s[s[r].child[!spin[sp]]].balance)) ; + } + *root = r ; + return itodel ; + + easyfix: + s[r].balance = -avlnode_sfromu(spin[sp]) ; + return itodel ; + + hardfix: + r = avlnode_rotate(s, max, r, spin[sp]) ; + if (!sp--) *root = r ; + else s[stack[sp]].child[spin[sp]] = r ; + return itodel ; +} diff --git a/src/libdatastruct/avlnode_doublerotate.c b/src/libdatastruct/avlnode_doublerotate.c new file mode 100644 index 0000000..da1f31b --- /dev/null +++ b/src/libdatastruct/avlnode_doublerotate.c @@ -0,0 +1,19 @@ +/* ISC license. */ + +#include <skalibs/avlnode.h> +#include "avlnode-internal.h" + +unsigned int avlnode_doublerotate (avlnode_ref s, unsigned int max, unsigned int i, int h) +{ + register unsigned int j = s[i].child[!h] ; + register unsigned int k = s[j].child[h] ; + s[i].child[!h] = s[k].child[h] ; + s[j].child[h] = s[k].child[!h] ; + s[k].child[!h] = j ; + s[k].child[h] = i ; + s[h ? i : j].balance = (s[k].balance < 0) ; + s[h ? j : i].balance = -(s[k].balance > 0) ; + s[k].balance = 0 ; + (void)max ; + return k ; +} diff --git a/src/libdatastruct/avlnode_extreme.c b/src/libdatastruct/avlnode_extreme.c new file mode 100644 index 0000000..42d991d --- /dev/null +++ b/src/libdatastruct/avlnode_extreme.c @@ -0,0 +1,12 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/avlnode.h> + +int avlnode_extreme (avlnode const *s, unsigned int max, unsigned int r, int h, unsigned int *k) +{ + register unsigned int i = avlnode_extremenode(s, max, r, h) ; + if (i >= max) return (errno = ESRCH, 0) ; + *k = s[i].data ; + return 1 ; +} diff --git a/src/libdatastruct/avlnode_extremenode.c b/src/libdatastruct/avlnode_extremenode.c new file mode 100644 index 0000000..57a8e59 --- /dev/null +++ b/src/libdatastruct/avlnode_extremenode.c @@ -0,0 +1,10 @@ +/* ISC license. */ + +#include <skalibs/avlnode.h> + +unsigned int avlnode_extremenode (avlnode const *s, unsigned int max, unsigned int r, int h) +{ + register unsigned int oldr = r ; + for (; r < max ; oldr = r, r = s[r].child[h]) ; + return oldr ; +} diff --git a/src/libdatastruct/avlnode_height.c b/src/libdatastruct/avlnode_height.c new file mode 100644 index 0000000..e78448e --- /dev/null +++ b/src/libdatastruct/avlnode_height.c @@ -0,0 +1,15 @@ +/* ISC license. */ + +#include <skalibs/avlnode.h> + +unsigned int avlnode_height (avlnode const *s, unsigned int max, unsigned int r) +{ + if (r >= max) return 0 ; + else if (s[r].balance) return 1 + avlnode_height(s, max, s[r].child[s[r].balance > 0]) ; + else + { + unsigned int h1 = avlnode_height(s, max, s[r].child[0]) ; + unsigned int h2 = avlnode_height(s, max, s[r].child[1]) ; + return 1 + ((h1 > h2) ? h1 : h2) ; + } +} diff --git a/src/libdatastruct/avlnode_insertnode.c b/src/libdatastruct/avlnode_insertnode.c new file mode 100644 index 0000000..c69b34e --- /dev/null +++ b/src/libdatastruct/avlnode_insertnode.c @@ -0,0 +1,42 @@ +/* ISC license. */ + +#include <skalibs/functypes.h> +#include <skalibs/avlnode.h> +#include "avlnode-internal.h" + +unsigned int avlnode_insertnode (avlnode_ref s, unsigned int max, unsigned int r, unsigned int i, dtokfunc_t_ref dtok, cmpfunc_t_ref f, void *p) +{ + unsigned int stack[AVLNODE_MAXDEPTH] ; + int spin[AVLNODE_MAXDEPTH] ; + unsigned int sp = 0 ; + + { + register void const *k = (*dtok)(s[i].data, p) ; + for (; r < max ; sp++) + { + spin[sp] = avlnode_ufroms((*f)(k, (*dtok)(s[r].data, p), p)) ; + stack[sp] = r ; + r = s[r].child[spin[sp]] ; + } + } + r = i ; + while (sp--) + { + s[stack[sp]].child[spin[sp]] = r ; + r = stack[sp] ; + if (s[r].balance) goto lastfix ; + s[r].balance = avlnode_sfromu(spin[sp]) ; + } + return r ; + + lastfix: + if (avlnode_ufroms(s[r].balance) != spin[sp]) + { + s[r].balance = 0 ; + return stack[0] ; + } + r = avlnode_rotate_maydouble(s, max, r, !spin[sp], spin[sp] != spin[sp+1]) ; + if (!sp--) return r ; + s[stack[sp]].child[spin[sp]] = r ; + return stack[0] ; +} diff --git a/src/libdatastruct/avlnode_iter.c b/src/libdatastruct/avlnode_iter.c new file mode 100644 index 0000000..9e1d698 --- /dev/null +++ b/src/libdatastruct/avlnode_iter.c @@ -0,0 +1,26 @@ +/* ISC license. */ + +#include <skalibs/avlnode.h> + +struct avlnode_iter_s +{ + avlnode_ref s ; + unsigned int max ; + avliterfunc_t_ref f ; + void *p ; +} ; + +static int avlnode_iter_rec (struct avlnode_iter_s const *blah, unsigned int r, unsigned int h) +{ + return (r < blah->max) ? + avlnode_iter_rec(blah, blah->s[r].child[0], h+1) + && (*blah->f)(blah->s[r].data, h, blah->p) + && avlnode_iter_rec(blah, blah->s[r].child[1], h+1) + : 1 ; +} + +int avlnode_iter (avlnode_ref s, unsigned int max, unsigned int r, avliterfunc_t_ref f, void *p) +{ + struct avlnode_iter_s blah = { s, max, f, p } ; + return avlnode_iter_rec(&blah, r, 0) ; +} diff --git a/src/libdatastruct/avlnode_rotate.c b/src/libdatastruct/avlnode_rotate.c new file mode 100644 index 0000000..fe06994 --- /dev/null +++ b/src/libdatastruct/avlnode_rotate.c @@ -0,0 +1,15 @@ +/* ISC license. */ + +#include <skalibs/avlnode.h> +#include "avlnode-internal.h" + +unsigned int avlnode_rotate (avlnode_ref s, unsigned int max, unsigned int i, int h) +{ + register unsigned int j = s[i].child[!h] ; + s[i].child[!h] = s[j].child[h] ; + s[j].child[h] = i ; + if (s[j].balance * avlnode_sfromu(h) < 0) s[i].balance = s[j].balance = 0 ; + else s[j].balance = avlnode_sfromu(h) ; + (void)max ; + return j ; +} diff --git a/src/libdatastruct/avlnode_search.c b/src/libdatastruct/avlnode_search.c new file mode 100644 index 0000000..e12b0a4 --- /dev/null +++ b/src/libdatastruct/avlnode_search.c @@ -0,0 +1,12 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/avlnode.h> + +int avlnode_search (avlnode const *s, unsigned int max, unsigned int r, void const *k, unsigned int *data, dtokfunc_t_ref dtok, cmpfunc_t_ref f, void *p) +{ + register unsigned int i = avlnode_searchnode(s, max, r, k, dtok, f, p) ; + if (i >= max) return (errno = ESRCH, 0) ; + *data = s[i].data ; + return 1 ; +} diff --git a/src/libdatastruct/avlnode_searchnode.c b/src/libdatastruct/avlnode_searchnode.c new file mode 100644 index 0000000..4ab015c --- /dev/null +++ b/src/libdatastruct/avlnode_searchnode.c @@ -0,0 +1,16 @@ +/* ISC license. */ + +#include <skalibs/functypes.h> +#include <skalibs/avlnode.h> +#include "avlnode-internal.h" + +unsigned int avlnode_searchnode (avlnode const *s, unsigned int max, unsigned int r, void const *k, dtokfunc_t_ref dtok, cmpfunc_t_ref f, void *p) +{ + while (r < max) + { + register int h = (*f)(k, (*dtok)(s[r].data, p), p) ; + if (!h) break ; + r = s[r].child[avlnode_ufroms(h)] ; + } + return r ; +} diff --git a/src/libdatastruct/avlnode_zero.c b/src/libdatastruct/avlnode_zero.c new file mode 100644 index 0000000..caf4adb --- /dev/null +++ b/src/libdatastruct/avlnode_zero.c @@ -0,0 +1,5 @@ +/* ISC license. */ + +#include <skalibs/avlnode.h> + +avlnode const avlnode_zero = AVLNODE_ZERO ; diff --git a/src/libdatastruct/avltree_delete.c b/src/libdatastruct/avltree_delete.c new file mode 100644 index 0000000..5127f01 --- /dev/null +++ b/src/libdatastruct/avltree_delete.c @@ -0,0 +1,16 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/gensetdyn.h> +#include <skalibs/avlnode.h> +#include <skalibs/avltree.h> + +int avltree_delete (avltree_ref t, void const *k) +{ + unsigned int r = avltree_root(t) ; + unsigned int i = avlnode_delete(avltree_nodes(t), avltree_totalsize(t), &r, k, t->dtok, t->kcmp, t->external) ; + if (i >= avltree_totalsize(t)) return (errno = ESRCH, 0) ; + avltree_setroot(t, r) ; + if (!gensetdyn_delete(&t->x, i)) return 0 ; + return 1 ; +} diff --git a/src/libdatastruct/avltree_free.c b/src/libdatastruct/avltree_free.c new file mode 100644 index 0000000..14198fe --- /dev/null +++ b/src/libdatastruct/avltree_free.c @@ -0,0 +1,10 @@ +/* ISC license. */ + +#include <skalibs/gensetdyn.h> +#include <skalibs/avltree.h> + +void avltree_free (avltree_ref t) +{ + gensetdyn_free(&t->x) ; + *t = avltree_zero ; +} diff --git a/src/libdatastruct/avltree_init.c b/src/libdatastruct/avltree_init.c new file mode 100644 index 0000000..290ff64 --- /dev/null +++ b/src/libdatastruct/avltree_init.c @@ -0,0 +1,16 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/functypes.h> +#include <skalibs/gensetdyn.h> +#include <skalibs/avlnode.h> +#include <skalibs/avltree.h> + +void avltree_init (avltree_ref t, unsigned int base, unsigned int fracnum, unsigned int fracden, dtokfunc_t_ref dtok, cmpfunc_t_ref f, void *p) +{ + gensetdyn_init(&t->x, sizeof(avlnode), base, fracnum, fracden) ; + t->root = (unsigned int)-1 ; + t->dtok = dtok ; + t->kcmp = f ; + t->external = p ; +} diff --git a/src/libdatastruct/avltree_insert.c b/src/libdatastruct/avltree_insert.c new file mode 100644 index 0000000..308990a --- /dev/null +++ b/src/libdatastruct/avltree_insert.c @@ -0,0 +1,11 @@ +/* ISC license. */ + +#include <skalibs/avltree.h> + +int avltree_insert (avltree_ref t, unsigned int d) +{ + unsigned int i ; + if (!avltree_newnode(t, d, &i)) return 0 ; + avltree_insertnode(t, i) ; + return 1 ; +} diff --git a/src/libdatastruct/avltree_newnode.c b/src/libdatastruct/avltree_newnode.c new file mode 100644 index 0000000..dc972a0 --- /dev/null +++ b/src/libdatastruct/avltree_newnode.c @@ -0,0 +1,18 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/gensetdyn.h> +#include <skalibs/avlnode.h> +#include <skalibs/avltree.h> + +int avltree_newnode (avltree_ref t, unsigned int data, unsigned int *i) +{ + if (!gensetdyn_new(&t->x, i)) return 0 ; + { + register avlnode_ref s = avltree_nodes(t) ; + s[*i].data = data ; + s[*i].child[0] = s[*i].child[1] = (unsigned int)-1 ; + s[*i].balance = 0 ; + } + return 1 ; +} diff --git a/src/libdatastruct/avltree_zero.c b/src/libdatastruct/avltree_zero.c new file mode 100644 index 0000000..400828a --- /dev/null +++ b/src/libdatastruct/avltree_zero.c @@ -0,0 +1,5 @@ +/* ISC license. */ + +#include <skalibs/avltree.h> + +avltree const avltree_zero = AVLTREE_ZERO ; diff --git a/src/libdatastruct/avltreen_delete.c b/src/libdatastruct/avltreen_delete.c new file mode 100644 index 0000000..bfe85c5 --- /dev/null +++ b/src/libdatastruct/avltreen_delete.c @@ -0,0 +1,16 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/genset.h> +#include <skalibs/avlnode.h> +#include <skalibs/avltreen.h> + +int avltreen_delete (avltreen_ref t, void const *k) +{ + unsigned int r = avltreen_root(t) ; + unsigned int i = avlnode_delete(avltreen_nodes(t), avltreen_totalsize(t), &r, k, t->dtok, t->kcmp, t->external) ; + if (i >= avltreen_totalsize(t)) return (errno = ESRCH, 0) ; + avltreen_setroot(t, r) ; + if (!genset_delete(&t->x, i)) return 0 ; + return 1 ; +} diff --git a/src/libdatastruct/avltreen_init.c b/src/libdatastruct/avltreen_init.c new file mode 100644 index 0000000..5e141b1 --- /dev/null +++ b/src/libdatastruct/avltreen_init.c @@ -0,0 +1,15 @@ +/* ISC license. */ + +#include <skalibs/functypes.h> +#include <skalibs/genset.h> +#include <skalibs/avlnode.h> +#include <skalibs/avltreen.h> + +void avltreen_init (avltreen_ref t, avlnode_ref storage, unsigned int *freelist, unsigned int size, dtokfunc_t_ref dtok, cmpfunc_t_ref f, void *p) +{ + GENSET_init(&t->x, avlnode, storage, freelist, size) ; + t->root = size ; + t->dtok = dtok ; + t->kcmp = f ; + t->external = p ; +} diff --git a/src/libdatastruct/avltreen_insert.c b/src/libdatastruct/avltreen_insert.c new file mode 100644 index 0000000..795216d --- /dev/null +++ b/src/libdatastruct/avltreen_insert.c @@ -0,0 +1,11 @@ +/* ISC license. */ + +#include <skalibs/avltreen.h> + +int avltreen_insert (avltreen_ref t, unsigned int d) +{ + unsigned int i = avltreen_newnode(t, d) ; + if (i >= avltreen_totalsize(t)) return 0 ; + avltreen_insertnode(t, i) ; + return 1 ; +} diff --git a/src/libdatastruct/avltreen_newnode.c b/src/libdatastruct/avltreen_newnode.c new file mode 100644 index 0000000..335025c --- /dev/null +++ b/src/libdatastruct/avltreen_newnode.c @@ -0,0 +1,18 @@ +/* ISC license. */ + +#include <skalibs/genset.h> +#include <skalibs/avlnode.h> +#include <skalibs/avltreen.h> + +unsigned int avltreen_newnode (avltreen_ref t, unsigned int d) +{ + register unsigned int i = genset_new(&t->x) ; + if (i < avltreen_totalsize(t)) + { + register avlnode_ref s = avltreen_nodes(t) ; + s[i].data = d ; + s[i].child[0] = s[i].child[1] = avltreen_totalsize(t) ; + s[i].balance = 0 ; + } + return i ; +} diff --git a/src/libdatastruct/genset.c b/src/libdatastruct/genset.c new file mode 100644 index 0000000..8d750b7 --- /dev/null +++ b/src/libdatastruct/genset.c @@ -0,0 +1,27 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/genset.h> + +void genset_init (genset_ref x, void *storage, unsigned int *freelist, unsigned int esize, unsigned int max) +{ + register unsigned int i = 0 ; + x->storage = (char *)storage ; + x->freelist = freelist ; + x->esize = esize ; + x->max = max ; + x->sp = max ; + for (; i < max ; i++) freelist[i] = max - 1 - i ; +} + +unsigned int genset_new (genset_ref x) +{ + return x->sp ? x->freelist[--x->sp] : (errno = ENOSPC, x->max) ; +} + +int genset_delete (genset_ref x, unsigned int i) +{ + if ((i >= x->max) || (x->sp >= x->max)) return (errno = EINVAL, 0) ; + x->freelist[x->sp++] = i ; + return 1 ; +} diff --git a/src/libdatastruct/genset_iter.c b/src/libdatastruct/genset_iter.c new file mode 100644 index 0000000..cc6e863 --- /dev/null +++ b/src/libdatastruct/genset_iter.c @@ -0,0 +1,19 @@ +/* ISC license. */ + +#include <skalibs/bitarray.h> +#include <skalibs/functypes.h> +#include <skalibs/genset.h> + +unsigned int genset_iter (genset_ref g, iterfunc_t_ref f, void *stuff) +{ + unsigned char bits[bitarray_div8(g->max)] ; + unsigned int i = 0, j = 0, n = 0, m = genset_n(g) ; + bitarray_setn(bits, 0, g->max) ; + for (; i < g->sp ; i++) bitarray_clear(bits, g->freelist[i]) ; + for (i = 0 ; (i < g->max) && (j < m) ; i++) if (bitarray_peek(bits, i)) + { + j++ ; + if ((*f)(g->storage + i * g->esize, stuff)) n++ ; + } + return n ; +} diff --git a/src/libdatastruct/gensetdyn_delete.c b/src/libdatastruct/gensetdyn_delete.c new file mode 100644 index 0000000..58aec05 --- /dev/null +++ b/src/libdatastruct/gensetdyn_delete.c @@ -0,0 +1,11 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/genalloc.h> +#include <skalibs/gensetdyn.h> + +int gensetdyn_delete (gensetdyn_ref g, unsigned int i) +{ + return (i >= g->storage.len) ? (errno = EINVAL, 0) : + genalloc_catb(unsigned int, &g->freelist, &i, 1) ; +} diff --git a/src/libdatastruct/gensetdyn_free.c b/src/libdatastruct/gensetdyn_free.c new file mode 100644 index 0000000..c0a4366 --- /dev/null +++ b/src/libdatastruct/gensetdyn_free.c @@ -0,0 +1,12 @@ +/* ISC license. */ + +#include <skalibs/stralloc.h> +#include <skalibs/genalloc.h> +#include <skalibs/gensetdyn.h> + +void gensetdyn_free (gensetdyn_ref g) +{ + stralloc_free(&g->storage) ; + genalloc_free(unsigned int, &g->freelist) ; + *g = gensetdyn_zero ; +} diff --git a/src/libdatastruct/gensetdyn_init.c b/src/libdatastruct/gensetdyn_init.c new file mode 100644 index 0000000..cff6ff5 --- /dev/null +++ b/src/libdatastruct/gensetdyn_init.c @@ -0,0 +1,15 @@ +/* ISC license. */ + +#include <skalibs/stralloc.h> +#include <skalibs/genalloc.h> +#include <skalibs/gensetdyn.h> + +void gensetdyn_init (gensetdyn_ref g, unsigned int esize, unsigned int base, unsigned int fracnum, unsigned int fracden) +{ + g->storage = stralloc_zero ; + g->freelist = genalloc_zero ; + g->esize = esize ; + g->base = base ; + g->fracnum = fracnum ; + g->fracden = fracden ; +} diff --git a/src/libdatastruct/gensetdyn_iter.c b/src/libdatastruct/gensetdyn_iter.c new file mode 100644 index 0000000..216d42b --- /dev/null +++ b/src/libdatastruct/gensetdyn_iter.c @@ -0,0 +1,26 @@ +/* ISC license. */ + +#include <skalibs/bitarray.h> +#include <skalibs/functypes.h> +#include <skalibs/gensetdyn.h> + +unsigned int gensetdyn_iter (gensetdyn_ref g, iterfunc_t_ref f, void *stuff) +{ + /* + XXX: we may be called by a freeing function, so we cannot alloc - + XXX: so pray that the bitarray fits in the stack. + */ + unsigned char bits[bitarray_div8(g->storage.len)] ; + unsigned int i = 0, j = 0, n = 0, m = gensetdyn_n(g) ; + register unsigned int *fl = genalloc_s(unsigned int, &g->freelist) ; + register unsigned int sp = genalloc_len(unsigned int, &g->freelist) ; + bitarray_setn(bits, 0, g->storage.len) ; + + for (; i < sp ; i++) bitarray_clear(bits, fl[i]) ; + for (i = 0 ; (i < g->storage.len) && (j < m) ; i++) if (bitarray_peek(bits, i)) + { + j++ ; + if ((*f)(gensetdyn_p(g, i), stuff)) n++ ; + } + return n ; +} diff --git a/src/libdatastruct/gensetdyn_new.c b/src/libdatastruct/gensetdyn_new.c new file mode 100644 index 0000000..6a49189 --- /dev/null +++ b/src/libdatastruct/gensetdyn_new.c @@ -0,0 +1,14 @@ +/* ISC license. */ + +#include <skalibs/genalloc.h> +#include <skalibs/gensetdyn.h> + +int gensetdyn_new (gensetdyn_ref g, unsigned int *i) +{ + register unsigned int n ; + if (!genalloc_len(unsigned int, &g->freelist) && !gensetdyn_readyplus(g, 1)) return 0 ; + n = genalloc_len(unsigned int, &g->freelist) ; + *i = genalloc_s(unsigned int, &g->freelist)[n-1] ; + genalloc_setlen(unsigned int, &g->freelist, n-1) ; + return 1 ; +} diff --git a/src/libdatastruct/gensetdyn_ready.c b/src/libdatastruct/gensetdyn_ready.c new file mode 100644 index 0000000..d1cfd9f --- /dev/null +++ b/src/libdatastruct/gensetdyn_ready.c @@ -0,0 +1,26 @@ +/* ISC license. */ + +#include <skalibs/stralloc.h> +#include <skalibs/genalloc.h> +#include <skalibs/gensetdyn.h> + +int gensetdyn_ready (gensetdyn_ref g, unsigned int n) +{ + int wasnull = !g->storage.s ; + unsigned int i = g->storage.len ; + if (n < i) return 1 ; + n += g->base + (n * g->fracnum) / g->fracden ; + if (!stralloc_ready_tuned(&g->storage, n * g->esize, 0, 0, 1)) return 0 ; + if (!genalloc_ready(unsigned int, &g->freelist, n)) + { + if (wasnull) stralloc_free(&g->storage) ; + return 0 ; + } + for (; i < n ; i++) + { + unsigned int j = n - 1 - i + g->storage.len ; + genalloc_catb(unsigned int, &g->freelist, &j, 1) ; + } + g->storage.len = n ; + return 1 ; +} diff --git a/src/libdatastruct/gensetdyn_zero.c b/src/libdatastruct/gensetdyn_zero.c new file mode 100644 index 0000000..e3ab04a --- /dev/null +++ b/src/libdatastruct/gensetdyn_zero.c @@ -0,0 +1,5 @@ +/* ISC license. */ + +#include <skalibs/gensetdyn.h> + +gensetdyn const gensetdyn_zero = GENSETDYN_ZERO ; diff --git a/src/librandom/badrandom_char.c b/src/librandom/badrandom_char.c new file mode 100644 index 0000000..c0ca1de --- /dev/null +++ b/src/librandom/badrandom_char.c @@ -0,0 +1,13 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include "random-internal.h" +#include <skalibs/random.h> + +unsigned char badrandom_char (void) +{ + unsigned char x ; + badrandom_string((char *)&x, 1) ; + return x ; +} diff --git a/src/librandom/badrandom_finish.c b/src/librandom/badrandom_finish.c new file mode 100644 index 0000000..e0791ee --- /dev/null +++ b/src/librandom/badrandom_finish.c @@ -0,0 +1,12 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include <skalibs/rrandom.h> +#include "random-internal.h" +#include <skalibs/random.h> + +void badrandom_finish (void) +{ + rrandom_finish(&badrandom_here) ; +} diff --git a/src/librandom/badrandom_here.c b/src/librandom/badrandom_here.c new file mode 100644 index 0000000..c7d2992 --- /dev/null +++ b/src/librandom/badrandom_here.c @@ -0,0 +1,40 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include <skalibs/sysdeps.h> +#include <skalibs/config.h> +#include <skalibs/unisurf.h> +#include "random-internal.h" + +#ifdef SKALIBS_EGD + +# include <skalibs/unirandomegd.h> + +# ifdef SKALIBS_HASDEVURANDOM + +# include <skalibs/unirandomdev.h> + +rrandom badrandom_here = { { { UNIRANDOM_REGISTER_DEVURANDOM(), 3 }, { UNIRANDOM_REGISTER_HASEGD(), 3 }, { UNIRANDOM_REGISTER_SURF(), 3 } }, 3 } ; + +# else + +rrandom badrandom_here = { { { UNIRANDOM_REGISTER_HASEGD(), 3 }, { UNIRANDOM_REGISTER_SURF(), 3 }, { UNIRANDOM_ZERO, 3 } }, 2 } ; + +# endif + +#else + +# ifdef SKALIBS_HASDEVURANDOM + +# include <skalibs/unirandomdev.h> + +rrandom badrandom_here = { { { UNIRANDOM_REGISTER_DEVURANDOM(), 3 }, { UNIRANDOM_REGISTER_SURF(), 3 }, { UNIRANDOM_ZERO, 3 } }, 2 } ; + +# else + +rrandom badrandom_here = { { { UNIRANDOM_REGISTER_SURF(), 3 }, { UNIRANDOM_ZERO, 3 }, { UNIRANDOM_ZERO, 3 } }, 1 } ; + +# endif + +#endif diff --git a/src/librandom/badrandom_init.c b/src/librandom/badrandom_init.c new file mode 100644 index 0000000..a6eb7e3 --- /dev/null +++ b/src/librandom/badrandom_init.c @@ -0,0 +1,10 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include <skalibs/random.h> + +int badrandom_init (void) +{ + return 1 ; +} diff --git a/src/librandom/badrandom_int.c b/src/librandom/badrandom_int.c new file mode 100644 index 0000000..ae12db5 --- /dev/null +++ b/src/librandom/badrandom_int.c @@ -0,0 +1,12 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include <skalibs/rrandom.h> +#include "random-internal.h" +#include <skalibs/random.h> + +unsigned int badrandom_int (unsigned int n) +{ + return rrandom_readint(&badrandom_here, n, &unirandom_readnb) ; +} diff --git a/src/librandom/badrandom_string.c b/src/librandom/badrandom_string.c new file mode 100644 index 0000000..ec20f5b --- /dev/null +++ b/src/librandom/badrandom_string.c @@ -0,0 +1,12 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include <skalibs/rrandom.h> +#include "random-internal.h" +#include <skalibs/random.h> + +unsigned int badrandom_string (char *s, unsigned int n) +{ + return rrandom_readnb(&badrandom_here, s, n) ; +} diff --git a/src/librandom/goodrandom_char.c b/src/librandom/goodrandom_char.c new file mode 100644 index 0000000..8fbf5e8 --- /dev/null +++ b/src/librandom/goodrandom_char.c @@ -0,0 +1,13 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include "random-internal.h" +#include <skalibs/random.h> + +unsigned char goodrandom_char (void) +{ + unsigned char x ; + goodrandom_string((char *)&x, 1) ; + return x ; +} diff --git a/src/librandom/goodrandom_finish.c b/src/librandom/goodrandom_finish.c new file mode 100644 index 0000000..a764030 --- /dev/null +++ b/src/librandom/goodrandom_finish.c @@ -0,0 +1,12 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include "random-internal.h" +#include <skalibs/rrandom.h> +#include <skalibs/random.h> + +void goodrandom_finish (void) +{ + rrandom_finish(&goodrandom_here) ; +} diff --git a/src/librandom/goodrandom_here.c b/src/librandom/goodrandom_here.c new file mode 100644 index 0000000..8275ab2 --- /dev/null +++ b/src/librandom/goodrandom_here.c @@ -0,0 +1,40 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include <skalibs/sysdeps.h> +#include <skalibs/config.h> +#include <skalibs/unisurf.h> +#include "random-internal.h" + +#ifdef SKALIBS_EGD + +# include <skalibs/unirandomegd.h> + +# ifdef SKALIBS_HASDEVRANDOM + +# include <skalibs/unirandomdev.h> + +rrandom goodrandom_here = { { { UNIRANDOM_REGISTER_DEVRANDOM(), 3 }, { UNIRANDOM_REGISTER_HASEGD(), 3 }, { UNIRANDOM_REGISTER_SURF(), 3 } }, 3 } ; + +# else + +rrandom goodrandom_here = { { { UNIRANDOM_REGISTER_HASEGD(), 3 }, { UNIRANDOM_REGISTER_SURF(), 3 }, { UNIRANDOM_ZERO, 3 } }, 2 } ; + +# endif + +#else + +# ifdef SKALIBS_HASDEVRANDOM + +# include <skalibs/unirandomdev.h> + +rrandom goodrandom_here = { { { UNIRANDOM_REGISTER_DEVRANDOM(), 3 }, { UNIRANDOM_REGISTER_SURF(), 3 }, { UNIRANDOM_ZERO, 3 } }, 2 } ; + +# else + +rrandom goodrandom_here = { { { UNIRANDOM_REGISTER_SURF(), 3 }, { UNIRANDOM_ZERO, 3 }, { UNIRANDOM_ZERO, 3 } }, 1 } ; + +# endif + +#endif diff --git a/src/librandom/goodrandom_init.c b/src/librandom/goodrandom_init.c new file mode 100644 index 0000000..dea6225 --- /dev/null +++ b/src/librandom/goodrandom_init.c @@ -0,0 +1,10 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include <skalibs/random.h> + +int goodrandom_init (void) +{ + return 1 ; +} diff --git a/src/librandom/goodrandom_int.c b/src/librandom/goodrandom_int.c new file mode 100644 index 0000000..11ef2e1 --- /dev/null +++ b/src/librandom/goodrandom_int.c @@ -0,0 +1,12 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include <skalibs/rrandom.h> +#include "random-internal.h" +#include <skalibs/random.h> + +unsigned int goodrandom_int (unsigned int n) +{ + return rrandom_readint(&goodrandom_here, n, &unirandom_readb) ; +} diff --git a/src/librandom/goodrandom_string.c b/src/librandom/goodrandom_string.c new file mode 100644 index 0000000..556c41c --- /dev/null +++ b/src/librandom/goodrandom_string.c @@ -0,0 +1,12 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include <skalibs/rrandom.h> +#include "random-internal.h" +#include <skalibs/random.h> + +unsigned int goodrandom_string (char *s, unsigned int n) +{ + return rrandom_readb(&goodrandom_here, s, n) ; +} diff --git a/src/librandom/random-internal.h b/src/librandom/random-internal.h new file mode 100644 index 0000000..37b534e --- /dev/null +++ b/src/librandom/random-internal.h @@ -0,0 +1,20 @@ +/* ISC license. */ + +#ifndef RANDOM_INTERNAL_H +#define RANDOM_INTERNAL_H + +#include <skalibs/gccattributes.h> +#include <skalibs/surf.h> +#include <skalibs/unirandom.h> +#include <skalibs/rrandom.h> + +extern void unirandom_register (unirandom_ref, int (*) (union unirandominfo *), int (*) (union unirandominfo *), unsigned int (*) (union unirandominfo *, char *, unsigned int), unsigned int (*) (union unirandominfo *, char *, unsigned int)) ; + +extern unsigned int random_mask2 (unsigned int) gccattr_const ; +extern unsigned int random_nchars (unsigned int) gccattr_const ; + +extern SURFSchedule surf_here ; +extern rrandom goodrandom_here ; +extern rrandom badrandom_here ; + +#endif diff --git a/src/librandom/random_mask2.c b/src/librandom/random_mask2.c new file mode 100644 index 0000000..ab8c8e7 --- /dev/null +++ b/src/librandom/random_mask2.c @@ -0,0 +1,35 @@ +/* ISC license. */ + +#include <skalibs/sysdeps.h> +#include "random-internal.h" + +unsigned int random_mask2 (register unsigned int n) +{ + for (;;) + { + register unsigned int m = n | (n >> 1) ; + if (m == n) return n ; + n = m ; + } +} + +unsigned int random_nchars (register unsigned int n) +{ + return n <= 0xff ? 1 : +#if SKALIBS_SIZEOFUINT == 2 + 2 +#else + n <= 0xffff ? 2 : + n <= 0xffffffUL ? 3 : +# if SKALIBS_SIZEOFUINT == 4 + 4 +# else + n <= 0xffffffffUL ? 4 : + n <= 0xffffffffffULL ? 5 : + n <= 0xffffffffffffULL ? 6 : + n <= 0xffffffffffffffULL ? 7 : + 8 +# endif +#endif + ; +} diff --git a/src/librandom/random_name.c b/src/librandom/random_name.c new file mode 100644 index 0000000..8736699 --- /dev/null +++ b/src/librandom/random_name.c @@ -0,0 +1,13 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include "random-internal.h" +#include <skalibs/random.h> + +int random_name (char *s, unsigned int n) +{ + register unsigned int r = rrandom_name(&badrandom_here, s, n, 1) ; + if (r < n) return -1 ; + return n ; +} diff --git a/src/librandom/random_sauniquename.c b/src/librandom/random_sauniquename.c new file mode 100644 index 0000000..7c902ef --- /dev/null +++ b/src/librandom/random_sauniquename.c @@ -0,0 +1,25 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include <skalibs/stralloc.h> +#include <skalibs/skamisc.h> +#include <skalibs/random.h> + +int random_sauniquename (stralloc *sa, unsigned int n) +{ + unsigned int base = sa->len ; + int wasnull = !sa->s ; + register int r ; + if (sauniquename(sa) == -1) return -1 ; + if (!stralloc_readyplus(sa, n+1)) goto err ; + stralloc_catb(sa, ":", 1) ; + r = random_name(sa->s + sa->len, n) ; + if (r == -1) goto err ; + sa->len += r ; + return r ; + +err: + if (wasnull) stralloc_free(sa) ; else sa->len = base ; + return -1 ; +} diff --git a/src/librandom/random_unsort.c b/src/librandom/random_unsort.c new file mode 100644 index 0000000..289ef96 --- /dev/null +++ b/src/librandom/random_unsort.c @@ -0,0 +1,17 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/bytestr.h> +#include <skalibs/random.h> + +void random_unsort (char *s, unsigned int n, unsigned int chunksize) +{ + char tmp[chunksize] ; + while (n--) + { + register unsigned int i = badrandom_int(n+1) ; + byte_copy(tmp, chunksize, s + i * chunksize) ; + byte_copy(s + i * chunksize, chunksize, s + n * chunksize) ; + byte_copy(s + n * chunksize, chunksize, tmp) ; + } +} diff --git a/src/librandom/randomegd_open.c b/src/librandom/randomegd_open.c new file mode 100644 index 0000000..7c43f0d --- /dev/null +++ b/src/librandom/randomegd_open.c @@ -0,0 +1,20 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/djbunix.h> +#include <skalibs/webipc.h> +#include <skalibs/randomegd.h> + +int randomegd_open (char const *path) +{ + int s = ipc_stream() ; + if (s < 0) return -1 ; + if (ipc_connect(s, path) == -1) + { + register int e = errno ; + fd_close(s) ; + errno = e ; + return -1 ; + } + return s ; +} diff --git a/src/librandom/randomegd_readb.c b/src/librandom/randomegd_readb.c new file mode 100644 index 0000000..614f7a8 --- /dev/null +++ b/src/librandom/randomegd_readb.c @@ -0,0 +1,27 @@ +/* ISC license. */ + +#include <skalibs/allreadwrite.h> +#include <skalibs/randomegd.h> + +unsigned int randomegd_readb (int s, char *x, unsigned int n) +{ + unsigned int w = 0 ; + unsigned int i = 0 ; + for (; i < (n / 255) ; i++) + { + char const c[2] = { 0x02, 0xFF } ; + register unsigned int wtmp ; + if (allwrite(s, c, 2) < 2) return w ; + wtmp = allread(s, x + w, 255) ; + w += wtmp ; + if (wtmp < 255) return w ; + } + if (w < n) + { + char c[2] = "\002" ; + c[1] = n - w ; + if (allwrite(s, c, 2) < 2) return w ; + w += allread(s, x + w, c[1]) ; + } + return w ; +} diff --git a/src/librandom/randomegd_readnb.c b/src/librandom/randomegd_readnb.c new file mode 100644 index 0000000..29165c4 --- /dev/null +++ b/src/librandom/randomegd_readnb.c @@ -0,0 +1,28 @@ +/* ISC license. */ + +#include <skalibs/allreadwrite.h> +#include <skalibs/randomegd.h> + +unsigned int randomegd_readnb (int s, char *x, unsigned int n) +{ + unsigned int w = 0 ; + while ((n - w) >= 255) + { + char c[2] = { 0x01, 0xFF } ; + register unsigned char wtmp ; + if (allwrite(s, c, 2) < 2) return w ; + if (sanitize_read(fd_read(s, c+1, 1)) < 1) return w ; + wtmp = allread(s, x + w, c[1]) ; + w += wtmp ; + if ((wtmp < (unsigned char)c[1]) || ((unsigned char)c[1] < 0xFF)) return w ; + } + if (w < n) + { + char c[2] = "\001" ; + c[1] = n - w ; + if (allwrite(s, c, 2) < 2) return w ; + if (sanitize_read(fd_read(s, c+1, 1)) < 1) return w ; + w += allread(s, x + w, c[1]) ; + } + return w ; +} diff --git a/src/librandom/rrandom_add.c b/src/librandom/rrandom_add.c new file mode 100644 index 0000000..c22a43c --- /dev/null +++ b/src/librandom/rrandom_add.c @@ -0,0 +1,13 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/unirandom.h> +#include <skalibs/rrandom.h> + +int rrandom_add (rrandom_ref z, int (*f) (unirandom_ref)) +{ + if (z->n >= 3) return (errno = EBUSY, 0) ; + if (!(*f)(&z->tries[z->n].it)) return 0 ; + z->tries[z->n++].ok = 3 ; + return 1 ; +} diff --git a/src/librandom/rrandom_finish.c b/src/librandom/rrandom_finish.c new file mode 100644 index 0000000..a3cb24b --- /dev/null +++ b/src/librandom/rrandom_finish.c @@ -0,0 +1,14 @@ +/* ISC license. */ + +#include <skalibs/unirandom.h> +#include <skalibs/rrandom.h> + +int rrandom_finish (rrandom_ref z) +{ + rrandom zero = RRANDOM_ZERO ; + unsigned int i = z->n ; + int e = 1 ; + while (i--) e &= unirandom_finish(&z->tries[i].it) ; + if (e) *z = zero ; + return e ; +} diff --git a/src/librandom/rrandom_name.c b/src/librandom/rrandom_name.c new file mode 100644 index 0000000..5e77e83 --- /dev/null +++ b/src/librandom/rrandom_name.c @@ -0,0 +1,13 @@ +/* ISC license. */ + +#include <skalibs/unirandom.h> +#include <skalibs/rrandom.h> + +unsigned int rrandom_name (rrandom_ref z, char *s, unsigned int n, int nb) +{ + static char const *oklist = "ABCDEFGHIJKLMNOPQRSTUVWXYZghijklmnopqrstuvwxyz-_0123456789abcdef" ; + register unsigned int r = rrandom_read(z, s, n, nb ? &unirandom_readnb : &unirandom_readb) ; + register unsigned int i = 0 ; + for (; i < r ; i++) s[i] = oklist[s[i] & 63] ; + return r ; +} diff --git a/src/librandom/rrandom_read.c b/src/librandom/rrandom_read.c new file mode 100644 index 0000000..57ff920 --- /dev/null +++ b/src/librandom/rrandom_read.c @@ -0,0 +1,21 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/allreadwrite.h> +#include <skalibs/error.h> +#include <skalibs/unirandom.h> +#include <skalibs/rrandom.h> + +unsigned int rrandom_read (rrandom_ref z, char *s, unsigned int n, unsigned int (*f) (unirandom_ref, char *, unsigned int)) +{ + unsigned int i = 0 ; + for (; i < 3 ; i++) + { + int r ; + if (!z->tries[i].ok) continue ; + r = sanitize_read((*f)(&z->tries[i].it, s, n)) ; + if (r > 0) return r ; + z->tries[i].ok = error_temp(errno) ? z->tries[i].ok - 1 : 0 ; + } + return (errno = ENOENT, 0) ; +} diff --git a/src/librandom/rrandom_readint.c b/src/librandom/rrandom_readint.c new file mode 100644 index 0000000..e4f677c --- /dev/null +++ b/src/librandom/rrandom_readint.c @@ -0,0 +1,24 @@ +/* ISC license. */ + +#include <skalibs/uint.h> +#include <skalibs/unirandom.h> +#include "random-internal.h" +#include <skalibs/rrandom.h> + +unsigned int rrandom_readint (rrandom_ref z, unsigned int n, unsigned int (*f) (unirandom_ref, char *, unsigned int)) +{ + if (!n) return 0 ; + else + { + unsigned int i = n, nchars = random_nchars(n), m = random_mask2(n-1) ; + char tmp[UINT_PACK] ; + while (i >= n) + { + if (rrandom_read(z, tmp, nchars, f) < nchars) return 0 ; + byte_zero(tmp + nchars, UINT_PACK - nchars) ; + uint_unpack(tmp, &i) ; + i &= m ; + } + return i ; + } +} diff --git a/src/librandom/surf.c b/src/librandom/surf.c new file mode 100644 index 0000000..1687df9 --- /dev/null +++ b/src/librandom/surf.c @@ -0,0 +1,54 @@ +/* ISC license. */ + +#include <skalibs/uint32.h> +#include <skalibs/bytestr.h> +#include <skalibs/surf.h> + +#define ROTATE(x, b) (((x) << (b)) | ((x) >> (32 - (b)))) +#define MUSH(i, b) x = t[i] += (((x ^ ctx->seed[i]) + sum) ^ ROTATE(x, b)) + +static void surfit (SURFSchedule_ref ctx) +{ + uint32 t[12] ; + uint32 z[8] ; + uint32 x ; + uint32 sum = 0 ; + unsigned int i = 0, loop = 0 ; ; + + if (!++ctx->in[0] && !++ctx->in[1] && !++ctx->in[2]) ++ctx->in[3] ; + for (; i < 12 ; i++) t[i] = ctx->in[i] ^ ctx->seed[12+i] ; + for (i = 0 ; i < 8 ; i++) z[i] = ctx->seed[24+i] ; + x = t[11] ; + for (; loop < 2 ; loop++) + { + for (i = 0 ; i < 16 ; i++) + { + sum += 0x9e3779b9 ; + MUSH(0, 5) ; MUSH(1, 7) ; MUSH(2, 9) ; MUSH(3, 13) ; + MUSH(4, 5) ; MUSH(5, 7) ; MUSH(6, 9) ; MUSH(7, 13) ; + MUSH(8, 5) ; MUSH(9, 7) ; MUSH(10, 9) ; MUSH(11, 13) ; + } + for (i = 0 ; i < 8 ; i++) z[i] ^= t[i+4] ; + } + for (i = 0 ; i < 8 ; i++) uint32_pack(ctx->out + (i<<2), z[i]) ; +} + +void surf (SURFSchedule_ref ctx, char *s, unsigned int n) +{ + { + register unsigned int i = 32 - ctx->pos ; + if (n < i) i = n ; + byte_copy(s, i, ctx->out + ctx->pos) ; + s += i ; n -= i ; ctx->pos += i ; + } + while (n > 32) + { + surfit(ctx) ; + byte_copy(s, 32, ctx->out) ; + s += 32 ; n -= 32 ; + } + if (!n) return ; + surfit(ctx) ; + byte_copy(s, n, ctx->out) ; + ctx->pos = n ; +} diff --git a/src/librandom/surf_autoinit.c b/src/librandom/surf_autoinit.c new file mode 100644 index 0000000..920612b --- /dev/null +++ b/src/librandom/surf_autoinit.c @@ -0,0 +1,10 @@ +/* ISC license. */ + +#include <skalibs/surf.h> + +void surf_autoinit (SURFSchedule_ref ctx, char *s, unsigned int n) +{ + if (!ctx->in[0] && !ctx->in[1] && !ctx->in[2] && !ctx->in[3]) + surf_init(ctx) ; + surf(ctx, s, n) ; +} diff --git a/src/librandom/surf_here.c b/src/librandom/surf_here.c new file mode 100644 index 0000000..ebbdffb --- /dev/null +++ b/src/librandom/surf_here.c @@ -0,0 +1,8 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include <skalibs/surf.h> +#include "random-internal.h" + +SURFSchedule surf_here = SURFSCHEDULE_ZERO ; diff --git a/src/librandom/surf_init.c b/src/librandom/surf_init.c new file mode 100644 index 0000000..3662fa8 --- /dev/null +++ b/src/librandom/surf_init.c @@ -0,0 +1,10 @@ +/* ISC license. */ + +#include <skalibs/surf.h> + +void surf_init (SURFSchedule_ref ctx) +{ + char s[160] ; + surf_makeseed(s) ; + surf_sinit(ctx, s) ; +} diff --git a/src/librandom/surf_makeseed.c b/src/librandom/surf_makeseed.c new file mode 100644 index 0000000..adae9a4 --- /dev/null +++ b/src/librandom/surf_makeseed.c @@ -0,0 +1,35 @@ +/* ISC license. */ + +#include <unistd.h> +#include <skalibs/uint32.h> +#include <skalibs/tai.h> +#include <skalibs/sha1.h> +#include <skalibs/surf.h> + +void surf_makeseed (char *s) +{ + SHA1Schedule bak = SHA1_INIT() ; + { + tain_t now ; + char tmp[20 + TAIN_PACK] ; + uint32 x = getpid() ; + uint32_pack(tmp, x) ; + x = getppid() ; + uint32_pack(tmp + 4, x) ; + tain_now(&now) ; + tain_pack(tmp + 8, &now) ; + sha1_update(&bak, tmp, 8 + TAIN_PACK) ; + sha1_final(&bak, tmp) ; + sha1_init(&bak) ; + sha1_update(&bak, tmp, 20) ; + } + { + char i = 0 ; + for (; i < 8 ; i++) + { + SHA1Schedule ctx = bak ; + sha1_update(&ctx, &i, 1) ; + sha1_final(&ctx, s + 20*i) ; + } + } +} diff --git a/src/librandom/surf_sinit.c b/src/librandom/surf_sinit.c new file mode 100644 index 0000000..ae7f480 --- /dev/null +++ b/src/librandom/surf_sinit.c @@ -0,0 +1,13 @@ +/* ISC license. */ + +#include <skalibs/uint32.h> +#include <skalibs/surf.h> + +void surf_sinit (SURFSchedule_ref ctx, char const *s) +{ + SURFSchedule zero = SURFSCHEDULE_ZERO ; + register unsigned int i = 4 ; + *ctx = zero ; + for (; i < 12 ; i++) uint32_unpack(s + (i<<2) - 16, ctx->in + i) ; + for (i = 0 ; i < 32 ; i++) uint32_unpack(s + 32 + (i<<2), ctx->seed + i) ; +} diff --git a/src/librandom/unidevrandom.c b/src/librandom/unidevrandom.c new file mode 100644 index 0000000..fb7b6b8 --- /dev/null +++ b/src/librandom/unidevrandom.c @@ -0,0 +1,38 @@ +/* ISC license. */ + +#include <skalibs/sysdeps.h> +#include <skalibs/unirandomdev.h> +#include <skalibs/unirandom.h> + +#ifdef SKALIBS_HASDEVRANDOM + +#include "random-internal.h" + +int unidevrandom_init (union unirandominfo *u) +{ + return unirandomdev_sinit(u, "/dev/random") ; +} + +int unirandom_register_devrandom (unirandom *u) +{ + unirandom_register(u, &unidevrandom_init, &unirandomdev_finish, &unirandomdev_readb, &unirandomdev_readnb) ; + return 1 ; +} + +#else + +#include <errno.h> + +int unidevrandom_init (union unirandominfo *u) +{ + (void)u ; + return (errno = ENOSYS, 0) ; +} + +int unirandom_register_devrandom (unirandom *u) +{ + (void)u ; + return (errno = ENOSYS, 0) ; +} + +#endif diff --git a/src/librandom/unidevurandom.c b/src/librandom/unidevurandom.c new file mode 100644 index 0000000..d601ea0 --- /dev/null +++ b/src/librandom/unidevurandom.c @@ -0,0 +1,38 @@ +/* ISC license. */ + +#include <skalibs/sysdeps.h> +#include <skalibs/unirandomdev.h> +#include <skalibs/unirandom.h> + +#ifdef SKALIBS_HASDEVURANDOM + +#include "random-internal.h" + +int unidevurandom_init (union unirandominfo *u) +{ + return unirandomdev_sinit(u, "/dev/urandom") ; +} + +int unirandom_register_devurandom (unirandom *u) +{ + unirandom_register(u, &unidevurandom_init, &unirandomdev_finish, &unirandomdev_readb, &unirandomdev_readnb) ; + return 1 ; +} + +#else + +#include <errno.h> + +int unidevurandom_init (union unirandominfo *u) +{ + (void)u ; + return (errno = ENOSYS, 0) ; +} + +int unirandom_register_devurandom (unirandom *u) +{ + (void)u ; + return (errno = ENOSYS, 0) ; +} + +#endif diff --git a/src/librandom/unihasegd.c b/src/librandom/unihasegd.c new file mode 100644 index 0000000..ab263c7 --- /dev/null +++ b/src/librandom/unihasegd.c @@ -0,0 +1,38 @@ +/* ISC license. */ + +#include <skalibs/config.h> +#include <skalibs/unirandomegd.h> +#include <skalibs/unirandom.h> + +#ifdef SKALIBS_EGD + +#include "random-internal.h" + +int unihasegd_init (union unirandominfo *u) +{ + return unirandomegd_sinit(u, SKALIBS_EGD) ; +} + +int unirandom_register_hasegd (unirandom *u) +{ + unirandom_register(u, &unihasegd_init, &unirandomegd_finish, &unirandomegd_readb, &unirandomegd_readnb) ; + return 1 ; +} + +#else + +#include <errno.h> + +int unihasegd_init (union unirandominfo *u) +{ + (void)u ; + return (errno = ENOSYS, 0) ; +} + +int unirandom_register_hasegd (unirandom *u) +{ + (void)u ; + return (errno = ENOSYS, 0) ; +} + +#endif diff --git a/src/librandom/unirandom_finish.c b/src/librandom/unirandom_finish.c new file mode 100644 index 0000000..14c4411 --- /dev/null +++ b/src/librandom/unirandom_finish.c @@ -0,0 +1,12 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/unirandom.h> + +int unirandom_finish (unirandom_ref u) +{ + if (!u->initted) return 1 ; + if (!(*u->finish)(&u->data)) return 0 ; + u->initted = 0 ; + return 1 ; +} diff --git a/src/librandom/unirandom_init.c b/src/librandom/unirandom_init.c new file mode 100644 index 0000000..711a4ac --- /dev/null +++ b/src/librandom/unirandom_init.c @@ -0,0 +1,12 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/unirandom.h> + +int unirandom_init (unirandom_ref u) +{ + if (u->initted) return 1 ; + if (!(*u->init)(&u->data)) return 0 ; + u->initted = 1 ; + return 1 ; +} diff --git a/src/librandom/unirandom_readb.c b/src/librandom/unirandom_readb.c new file mode 100644 index 0000000..cbe45a6 --- /dev/null +++ b/src/librandom/unirandom_readb.c @@ -0,0 +1,10 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/unirandom.h> + +unsigned int unirandom_readb (unirandom_ref u, char *s, unsigned int n) +{ + if (!u->initted && !unirandom_init(u)) return 0 ; + return (*u->readb)(&u->data, s, n) ; +} diff --git a/src/librandom/unirandom_readnb.c b/src/librandom/unirandom_readnb.c new file mode 100644 index 0000000..f0cc38e --- /dev/null +++ b/src/librandom/unirandom_readnb.c @@ -0,0 +1,10 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/unirandom.h> + +unsigned int unirandom_readnb (unirandom_ref u, char *s, unsigned int n) +{ + if (!u->initted && !unirandom_init(u)) return 0 ; + return (*u->readnb)(&u->data, s, n) ; +} diff --git a/src/librandom/unirandom_register.c b/src/librandom/unirandom_register.c new file mode 100644 index 0000000..35f7411 --- /dev/null +++ b/src/librandom/unirandom_register.c @@ -0,0 +1,16 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/unirandom.h> +#include "random-internal.h" + +void unirandom_register (unirandom_ref u, int (*init) (union unirandominfo *), int (*finish) (union unirandominfo *), unsigned int (*readb) (union unirandominfo *, char *, unsigned int), unsigned int (*readnb) (union unirandominfo *, char *, unsigned int)) +{ + unirandom zero = UNIRANDOM_ZERO ; + *u = zero ; + u->init = init ; + u->finish = finish ; + u->readb = readb ; + u->readnb = readnb ; + u->initted = 0 ; +} diff --git a/src/librandom/unirandomdev.c b/src/librandom/unirandomdev.c new file mode 100644 index 0000000..4a22514 --- /dev/null +++ b/src/librandom/unirandomdev.c @@ -0,0 +1,50 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/buffer.h> +#include <skalibs/djbunix.h> +#include <skalibs/unirandom.h> +#include <skalibs/unirandomdev.h> + +int unirandomdev_sinit (union unirandominfo *u, char const *file) +{ + register int fd = open_read(file) ; + if (fd < 0) return 0 ; + if (coe(fd) < 0) + { + register int e = errno ; + fd_close(fd) ; + errno = e ; + return 0 ; + } + buffer_init(&u->device.b, &buffer_read, fd, u->device.buf, RANDOMBUF_BUFSIZE) ; + u->device.nb = 1 ; + return 1 ; +} + +int unirandomdev_finish (union unirandominfo *u) +{ + return fd_close(buffer_fd(&u->device.b)) < 0 ; +} + +static unsigned int unirandomdev_read (union unirandominfo *u, char *s, unsigned int n, unsigned int h) +{ + unsigned int w = 0 ; + if (u->device.nb != h) + { + if ((h ? ndelay_on(buffer_fd(&u->device.b)) : ndelay_off(buffer_fd(&u->device.b))) < 0) return 0 ; + u->device.nb = h ; + } + buffer_getall(&u->device.b, s, n, &w) ; + return w ; +} + +unsigned int unirandomdev_readb (union unirandominfo *u, char *s, unsigned int n) +{ + return unirandomdev_read(u, s, n, 0) ; +} + +unsigned int unirandomdev_readnb (union unirandominfo *u, char *s, unsigned int n) +{ + return unirandomdev_read(u, s, n, 1) ; +} diff --git a/src/librandom/unirandomegd.c b/src/librandom/unirandomegd.c new file mode 100644 index 0000000..a340f06 --- /dev/null +++ b/src/librandom/unirandomegd.c @@ -0,0 +1,37 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/djbunix.h> +#include <skalibs/randomegd.h> +#include <skalibs/unirandom.h> +#include <skalibs/unirandomegd.h> + +int unirandomegd_sinit (union unirandominfo *u, char const *path) +{ + register int s = randomegd_open(path) ; + if (s == -1) return 0 ; + if (coe(s) == -1) + { + register int e = errno ; + fd_close(s) ; + errno = e ; + return 0 ; + } + u->egd.fd = s ; + return 1 ; +} + +int unirandomegd_finish (union unirandominfo *u) +{ + return !fd_close(u->egd.fd) ; +} + +unsigned int unirandomegd_readb (union unirandominfo *u, char *s, unsigned int n) +{ + return randomegd_readb(u->egd.fd, s, n) ; +} + +unsigned int unirandomegd_readnb (union unirandominfo *u, char *s, unsigned int n) +{ + return randomegd_readnb(u->egd.fd, s, n) ; +} diff --git a/src/librandom/unisurf.c b/src/librandom/unisurf.c new file mode 100644 index 0000000..334d044 --- /dev/null +++ b/src/librandom/unisurf.c @@ -0,0 +1,23 @@ +/* ISC license. */ + +#include <skalibs/surf.h> +#include <skalibs/unirandom.h> +#include <skalibs/unisurf.h> + +int unisurf_sinit (union unirandominfo *u, char const *s) +{ + surf_sinit(&u->surf_ctx, s) ; + return 1 ; +} + +int unisurf_finish (union unirandominfo *u) +{ + (void)u ; + return 1 ; +} + +unsigned int unisurf_read (union unirandominfo *u, char *s, unsigned int n) +{ + surf(&u->surf_ctx, s, n) ; + return n ; +} diff --git a/src/librandom/unisurf_init.c b/src/librandom/unisurf_init.c new file mode 100644 index 0000000..d5a1f73 --- /dev/null +++ b/src/librandom/unisurf_init.c @@ -0,0 +1,18 @@ +/* ISC license. */ + +#include <skalibs/surf.h> +#include "random-internal.h" +#include <skalibs/unirandom.h> +#include <skalibs/unisurf.h> + +int unisurf_init (union unirandominfo *u) +{ + surf_init(&u->surf_ctx) ; + return 1 ; +} + +int unirandom_register_surf (unirandom *u) +{ + unirandom_register(u, &unisurf_init, &unisurf_finish, &unisurf_read, &unisurf_read) ; + return 1 ; +} diff --git a/src/libstdcrypto/INCLUDE b/src/libstdcrypto/INCLUDE new file mode 100644 index 0000000..563254f --- /dev/null +++ b/src/libstdcrypto/INCLUDE @@ -0,0 +1,5 @@ +rc4.h +md5.h +sha1.h +sha256.h +stdcrypto.h diff --git a/src/libstdcrypto/Makefile b/src/libstdcrypto/Makefile new file mode 100644 index 0000000..8c0d22f --- /dev/null +++ b/src/libstdcrypto/Makefile @@ -0,0 +1,7 @@ +it: EXPORT- .done + +EXPORT-: gen-EXPORT + exec ./gen-EXPORT > EXPORT- + +.done: gen-Makefile + ./gen-Makefile > Makefile.real && make -f Makefile.real && : > .done diff --git a/src/libstdcrypto/md5-internal.h b/src/libstdcrypto/md5-internal.h new file mode 100644 index 0000000..374528a --- /dev/null +++ b/src/libstdcrypto/md5-internal.h @@ -0,0 +1,11 @@ +/* ISC license. */ + +#ifndef MD5_INTERNAL_H +#define MD5_INTERNAL_H + +#include <skalibs/uint32.h> +#include <skalibs/md5.h> + +extern void md5_transform (uint32 * /* 4 uint32s */, uint32 const * /* 16 uint32s */) ; + +#endif diff --git a/src/libstdcrypto/md5_final.c b/src/libstdcrypto/md5_final.c new file mode 100644 index 0000000..834d57c --- /dev/null +++ b/src/libstdcrypto/md5_final.c @@ -0,0 +1,30 @@ +/* ISC license. */ + +#include <skalibs/uint32.h> +#include <skalibs/bytestr.h> +#include <skalibs/md5.h> +#include "md5-internal.h" + +void md5_final (MD5Schedule_ref ctx, char *digest /* 16 chars */) +{ + register unsigned int count = (ctx->bits[0] >> 3) & 0x3F ; + register unsigned char *p = ctx->in + count ; + *p++ = 0x80; + count = 63 - count ; + if (count < 8) + { + byte_zero(p, count) ; + uint32_little_endian((char *)ctx->in, 16) ; + md5_transform(ctx->buf, (uint32 *)ctx->in) ; + byte_zero(ctx->in, 56) ; + } + else byte_zero(p, count - 8) ; + uint32_little_endian((char *)ctx->in, 14) ; + + byte_copy(ctx->in + 56, 4, (char *)&ctx->bits[0]) ; + byte_copy(ctx->in + 60, 4, (char *)&ctx->bits[1]) ; + + md5_transform(ctx->buf, (uint32 *)ctx->in) ; + uint32_little_endian((char *)ctx->buf, 4) ; + byte_copy(digest, 16, (char *)ctx->buf) ; +} diff --git a/src/libstdcrypto/md5_init.c b/src/libstdcrypto/md5_init.c new file mode 100644 index 0000000..cb2f611 --- /dev/null +++ b/src/libstdcrypto/md5_init.c @@ -0,0 +1,13 @@ +/* ISC license. */ + +#include <skalibs/md5.h> + +void md5_init (MD5Schedule_ref ctx) +{ + ctx->buf[0] = 0x67452301UL ; + ctx->buf[1] = 0xefcdab89UL ; + ctx->buf[2] = 0x98badcfeUL ; + ctx->buf[3] = 0x10325476UL ; + ctx->bits[0] = 0 ; + ctx->bits[1] = 0 ; +} diff --git a/src/libstdcrypto/md5_transform.c b/src/libstdcrypto/md5_transform.c new file mode 100644 index 0000000..2449b58 --- /dev/null +++ b/src/libstdcrypto/md5_transform.c @@ -0,0 +1,91 @@ +/* ISC license. */ + +#include <skalibs/uint32.h> +#include "md5-internal.h" + +/* #define F1(x, y, z) (x & y | ~x & z) */ +#define F1(x, y, z) (z ^ (x & (y ^ z))) +#define F2(x, y, z) F1(z, x, y) +#define F3(x, y, z) (x ^ y ^ z) +#define F4(x, y, z) (y ^ (x | ~z)) + +#define MD5STEP(f, w, x, y, z, data, s) \ + ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x ) + +void md5_transform (uint32 *buf /* 4 uint32s */, uint32 const *in /* 16 uint32s */) +{ + register uint32 a = buf[0], b = buf[1], c = buf[2], d = buf[3] ; + + MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7) ; + MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12) ; + MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17) ; + MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22) ; + MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7) ; + MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12) ; + MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17) ; + MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22) ; + MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7) ; + MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12) ; + MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17) ; + MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22) ; + MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7) ; + MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12) ; + MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17) ; + MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22) ; + + MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5) ; + MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9) ; + MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14) ; + MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20) ; + MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5) ; + MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9) ; + MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14) ; + MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20) ; + MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5) ; + MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9) ; + MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14) ; + MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20) ; + MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5) ; + MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9) ; + MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14) ; + MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20) ; + + MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4) ; + MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11) ; + MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16) ; + MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23) ; + MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4) ; + MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11) ; + MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16) ; + MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23) ; + MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4) ; + MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11) ; + MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16) ; + MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23) ; + MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4) ; + MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11) ; + MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16) ; + MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23) ; + + MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6) ; + MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10) ; + MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15) ; + MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21) ; + MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6) ; + MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10) ; + MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15) ; + MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21) ; + MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6) ; + MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10) ; + MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15) ; + MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21) ; + MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6) ; + MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10) ; + MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15) ; + MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21) ; + + buf[0] += a ; + buf[1] += b ; + buf[2] += c ; + buf[3] += d ; +} diff --git a/src/libstdcrypto/md5_update.c b/src/libstdcrypto/md5_update.c new file mode 100644 index 0000000..63fdea3 --- /dev/null +++ b/src/libstdcrypto/md5_update.c @@ -0,0 +1,37 @@ +/* ISC license. */ + +#include <skalibs/uint32.h> +#include <skalibs/bytestr.h> +#include <skalibs/md5.h> +#include "md5-internal.h" + +void md5_update (MD5Schedule_ref ctx, char const *s, unsigned int len) +{ + register uint32 t = ctx->bits[0] ; + if ((ctx->bits[0] = t + (len << 3)) < t) + ctx->bits[1]++ ; + ctx->bits[1] += len >> 29 ; + t = (t >> 3) & 0x3f ; + if (t) + { + unsigned char *p = ctx->in + t ; + t = 64 - t ; + if (len < t) + { + byte_copy((char *)p, len, s) ; + return ; + } + byte_copy((char *)p, t, s) ; + uint32_little_endian((char *)ctx->in, 16) ; + md5_transform(ctx->buf, (uint32 *)ctx->in) ; + s += t ; len -= t ; + } + while (len >= 64) + { + byte_copy((char *)ctx->in, 64, s) ; + uint32_little_endian((char *)ctx->in, 16) ; + md5_transform(ctx->buf, (uint32 *)ctx->in) ; + s += 64 ; len -= 64 ; + } + byte_copy((char *)ctx->in, len, s) ; +} diff --git a/src/libstdcrypto/rc4.c b/src/libstdcrypto/rc4.c new file mode 100644 index 0000000..7ead2c6 --- /dev/null +++ b/src/libstdcrypto/rc4.c @@ -0,0 +1,20 @@ +/* ISC license. */ +/* Thanks to Thomas Pornin <pornin@bolet.org> */ + +#include <skalibs/bytestr.h> +#include <skalibs/rc4.h> + +void rc4 (RC4Schedule_ref r, char const *in, char *out, unsigned int n) +{ + register unsigned int i = 0 ; + for (; i < n ; i++) + { + register unsigned char t ; + r->x = T8(r->x + 1) ; + t = r->tab[r->x] ; + r->y = T8(r->y + t) ; + r->tab[r->x] = r->tab[r->y] ; + r->tab[r->y] = t ; + out[i] = (unsigned char)in[i] ^ T8(r->tab[r->x] + r->tab[r->y]) ; + } +} diff --git a/src/libstdcrypto/rc4_init.c b/src/libstdcrypto/rc4_init.c new file mode 100644 index 0000000..d6f8c20 --- /dev/null +++ b/src/libstdcrypto/rc4_init.c @@ -0,0 +1,26 @@ +/* ISC license. */ +/* Thanks to Thomas Pornin <pornin@bolet.org> */ + +#include <skalibs/bytestr.h> +#include <skalibs/rc4.h> + +void rc4_init (RC4Schedule_ref r, char const *key, unsigned int ksize) +{ + register unsigned int i = 0, j = 0 ; + register unsigned char c = 0; + + r->x = r->y = 0 ; + for (; i < 256 ; i++) r->tab[i] = i ; + for (i = 0 ; i < 256 ; i++) + { + unsigned char t = r->tab[i] ; + c = T8(c + (unsigned char)key[j] + t) ; + r->tab[i] = r->tab[c] ; + r->tab[c] = t ; + if (++j == ksize) j = 0 ; + } + { + char tmp[RC4_THROWAWAY] ; + rc4(r, tmp, tmp, RC4_THROWAWAY) ; + } +} diff --git a/src/libstdcrypto/sha1-internal.h b/src/libstdcrypto/sha1-internal.h new file mode 100644 index 0000000..eae3947 --- /dev/null +++ b/src/libstdcrypto/sha1-internal.h @@ -0,0 +1,12 @@ +/* ISC license. */ + +#ifndef SHA1_INTERNAL_H +#define SHA1_INTERNAL_H + +#include <skalibs/uint32.h> +#include <skalibs/sha1.h> + +extern void sha1_feed (SHA1Schedule_ref, unsigned char) ; +extern void sha1_transform (uint32 * /* 5 uint32s */, uint32 const * /* 16 uint32s */) ; + +#endif diff --git a/src/libstdcrypto/sha1_feed.c b/src/libstdcrypto/sha1_feed.c new file mode 100644 index 0000000..208cebd --- /dev/null +++ b/src/libstdcrypto/sha1_feed.c @@ -0,0 +1,24 @@ +/* ISC license. */ + +#include <skalibs/uint32.h> +#include <skalibs/bytestr.h> +#include <skalibs/sha1.h> +#include "sha1-internal.h" + +void sha1_feed (SHA1Schedule_ref ctx, unsigned char inb) +{ + register uint32 tmp ; + + ctx->in[ctx->b>>2] <<= 8 ; + ctx->in[ctx->b>>2] |= T8(inb) ; + if (++ctx->b >= 64) + { + register unsigned int i = 0 ; + sha1_transform(ctx->buf, ctx->in) ; + ctx->b = 0 ; + for (i = 0 ; i < 16 ; i++) ctx->in[i] = 0 ; + } + tmp = ctx->bits[0] ; + ctx->bits[0] += 8 ; + if (tmp > ctx->bits[0]) ctx->bits[1]++ ; +} diff --git a/src/libstdcrypto/sha1_final.c b/src/libstdcrypto/sha1_final.c new file mode 100644 index 0000000..4af2efb --- /dev/null +++ b/src/libstdcrypto/sha1_final.c @@ -0,0 +1,18 @@ +/* ISC license. */ + +#include <skalibs/uint32.h> +#include <skalibs/sha1.h> +#include "sha1-internal.h" + +void sha1_final (SHA1Schedule_ref ctx, char *digest) +{ + char pack[8] ; + register unsigned int i = 0 ; + uint32_pack_big(pack, ctx->bits[1]) ; + uint32_pack_big(pack+4, ctx->bits[0]) ; + sha1_feed(ctx, 0x80) ; + while (ctx->b != 56) sha1_feed(ctx, 0) ; + sha1_update(ctx, pack, 8) ; + for (; i < 5 ; i++) + uint32_pack_big(digest + (i<<2), ctx->buf[i]) ; +} diff --git a/src/libstdcrypto/sha1_init.c b/src/libstdcrypto/sha1_init.c new file mode 100644 index 0000000..bdcb5fd --- /dev/null +++ b/src/libstdcrypto/sha1_init.c @@ -0,0 +1,16 @@ +/* ISC license. */ + +#include <skalibs/sha1.h> + +void sha1_init (SHA1Schedule_ref ctx) +{ + register unsigned int i = 0 ; + ctx->buf[0] = 0x67452301UL ; + ctx->buf[1] = 0xefcdab89UL ; + ctx->buf[2] = 0x98badcfeUL ; + ctx->buf[3] = 0x10325476UL ; + ctx->buf[4] = 0xc3d2e1f0UL ; + ctx->bits[0] = ctx->bits[1] = 0 ; + for (; i < 16 ; i++) ctx->in[i] = 0 ; + ctx->b = 0 ; +} diff --git a/src/libstdcrypto/sha1_transform.c b/src/libstdcrypto/sha1_transform.c new file mode 100644 index 0000000..bd6e624 --- /dev/null +++ b/src/libstdcrypto/sha1_transform.c @@ -0,0 +1,42 @@ +/* ISC license. */ + +#include <skalibs/uint32.h> +#include "sha1-internal.h" + +#define F1(x, y, z) ((x & y) | ((~x) & z)) +#define F2(x, y, z) (x ^ y ^ z) +#define F3(x, y, z) ((x & y) | (x & z) | (y & z)) +#define F4(x, y, z) (x ^ y ^ z) + +#define SHA1STEP(f, data) \ +{ \ + register uint32 tmp = e + f(b, c, d) + data + ((a<<5) | (a>>27)); \ + e = d ; \ + d = c ; \ + c = (b<<30) | (b>>2) ; \ + b = a ; \ + a = tmp ; \ +} + +void sha1_transform (uint32 *buf, uint32 const *in) +{ + register uint32 a = buf[0], b = buf[1], c = buf[2], d = buf[3], e = buf[4] ; + uint32 w[80] ; + register unsigned int i = 0 ; + + for (; i < 16 ; i++) w[i] = in[i] ; + for (; i < 80 ; i++) + { + w[i] = w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16] ; + w[i] = (w[i]<<1) | (w[i]>>31) ; + } + for (i = 0 ; i < 20 ; i++) + SHA1STEP(F1, w[i] + 0x5a827999UL) ; + for (; i < 40 ; i++) + SHA1STEP(F2, w[i] + 0x6ed9eba1UL) ; + for (; i < 60 ; i++) + SHA1STEP(F3, w[i] + 0x8f1bbcdcUL) ; + for (; i < 80 ; i++) + SHA1STEP(F4, w[i] + 0xca62c1d6UL) ; + buf[0] += a ; buf[1] += b ; buf[2] += c ; buf[3] += d ; buf[4] += e ; +} diff --git a/src/libstdcrypto/sha1_update.c b/src/libstdcrypto/sha1_update.c new file mode 100644 index 0000000..1b3c4de --- /dev/null +++ b/src/libstdcrypto/sha1_update.c @@ -0,0 +1,10 @@ +/* ISC license. */ + +#include <skalibs/sha1.h> +#include "sha1-internal.h" + +void sha1_update (SHA1Schedule_ref ctx, char const *buf, unsigned int len) +{ + register unsigned int i = 0 ; + for (; i < len ; i++) sha1_feed(ctx, (unsigned char)buf[i]) ; +} diff --git a/src/libstdcrypto/sha256-internal.h b/src/libstdcrypto/sha256-internal.h new file mode 100644 index 0000000..377e6ef --- /dev/null +++ b/src/libstdcrypto/sha256-internal.h @@ -0,0 +1,12 @@ +/* ISC license. */ + +#ifndef SHA256_INTERNAL_H +#define SHA256_INTERNAL_H + +#include <skalibs/uint32.h> +#include <skalibs/sha256.h> + +extern void sha256_feed (SHA256Schedule_ref, unsigned char) ; +extern void sha256_transform (uint32 *, uint32 const *) ; + +#endif diff --git a/src/libstdcrypto/sha256_feed.c b/src/libstdcrypto/sha256_feed.c new file mode 100644 index 0000000..5533d75 --- /dev/null +++ b/src/libstdcrypto/sha256_feed.c @@ -0,0 +1,23 @@ +/* ISC license. */ + +#include <skalibs/uint32.h> +#include <skalibs/bytestr.h> +#include <skalibs/sha256.h> +#include "sha256-internal.h" + +void sha256_feed (SHA256Schedule_ref ctx, unsigned char inb) +{ + register uint32 tmp ; + ctx->in[ctx->b>>2] <<= 8 ; + ctx->in[ctx->b>>2] |= T8(inb) ; + if (++ctx->b >= 64) + { + register unsigned int i = 0 ; + sha256_transform(ctx->buf, ctx->in) ; + ctx->b = 0 ; + for (; i < 16 ; i++) ctx->in[i] = 0 ; + } + tmp = ctx->bits[0] ; + ctx->bits[0] += 8 ; + if (tmp > ctx->bits[0]) ctx->bits[1]++ ; +} diff --git a/src/libstdcrypto/sha256_final.c b/src/libstdcrypto/sha256_final.c new file mode 100644 index 0000000..58b938a --- /dev/null +++ b/src/libstdcrypto/sha256_final.c @@ -0,0 +1,31 @@ +/* ISC license. */ + +#include <skalibs/bytestr.h> +#include <skalibs/uint32.h> +#include <skalibs/sha256.h> +#include "sha256-internal.h" + +void sha256_final (SHA256Schedule_ref ctx, char *digest) +{ + register unsigned int i = 0 ; + register unsigned char *p = (unsigned char *)digest ; + uint32 bits[2] = { ctx->bits[0], ctx->bits[1] } ; + + sha256_feed(ctx, 0x80) ; + while (ctx->b != 56) sha256_feed(ctx, 0) ; + sha256_feed(ctx, T8(bits[1]>>24)) ; + sha256_feed(ctx, T8(bits[1]>>16)) ; + sha256_feed(ctx, T8(bits[1]>>8)) ; + sha256_feed(ctx, T8(bits[1])) ; + sha256_feed(ctx, T8(bits[0]>>24)) ; + sha256_feed(ctx, T8(bits[0]>>16)) ; + sha256_feed(ctx, T8(bits[0]>>8)) ; + sha256_feed(ctx, T8(bits[0])) ; + for (; i < 8 ; i++) + { + *p++ = T8(ctx->buf[i]>>24) ; + *p++ = T8(ctx->buf[i]>>16) ; + *p++ = T8(ctx->buf[i]>>8) ; + *p++ = T8(ctx->buf[i]) ; + } +} diff --git a/src/libstdcrypto/sha256_init.c b/src/libstdcrypto/sha256_init.c new file mode 100644 index 0000000..e8a9ae1 --- /dev/null +++ b/src/libstdcrypto/sha256_init.c @@ -0,0 +1,9 @@ +/* ISC license. */ + +#include <skalibs/sha256.h> + +void sha256_init (SHA256Schedule_ref ctx) +{ + SHA256Schedule empty = SHA256_INIT() ; + *ctx = empty ; +} diff --git a/src/libstdcrypto/sha256_transform.c b/src/libstdcrypto/sha256_transform.c new file mode 100644 index 0000000..e61775c --- /dev/null +++ b/src/libstdcrypto/sha256_transform.c @@ -0,0 +1,53 @@ +/* ISC license. */ + +#include <skalibs/uint32.h> +#include "sha256-internal.h" + +#define F1(x, y, z) ((x & y) | ((~x) & z)) +#define F2(x, y, z) ((x & y) | (x & z) | (y & z)) + +#define ROTR(x,n) (((x)>>(n)) | ((x)<<(32-(n)))) +#define CAPITALSIGMA0(x) (ROTR(x,2)^ROTR(x,13)^ROTR(x,22)) +#define CAPITALSIGMA1(x) (ROTR(x,6)^ROTR(x,11)^ROTR(x,25)) +#define SMALLSIGMA0(x) (ROTR(x,7)^ROTR(x,18)^((x)>>3)) +#define SMALLSIGMA1(x) (ROTR(x,17)^ROTR(x,19)^((x)>>10)) + +static uint32 const sha256_constants[64] = +{ + 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, + 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, + 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL, + 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL, + 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, + 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, + 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, + 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL, + 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL, + 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, + 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, + 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, + 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL, + 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL, + 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, + 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL +} ; + +void sha256_transform (uint32 *buf, uint32 const *in) +{ + uint32 w[64] ; + unsigned int i = 0 ; + register uint32 a = buf[0], b = buf[1], c = buf[2], d = buf[3], e = buf[4], f = buf[5], g = buf[6], h = buf[7] ; + + for (; i < 16 ; i++) w[i] = in[i] ; + for (; i < 64 ; i++) + w[i] = SMALLSIGMA1(w[i-2]) + w[i-7] + SMALLSIGMA0(w[i-15]) + w[i-16] ; + for (i = 0 ; i < 64 ; i++) + { + uint32 temp1 = h + CAPITALSIGMA1(e) + F1(e, f, g) + sha256_constants[i] + w[i] ; + uint32 temp2 = CAPITALSIGMA0(a) + F2(a, b, c) ; + h = g ; g = f ; f = e ; e = d + temp1 ; + d = c ; c = b ; b = a ; a = temp1 + temp2 ; + } + buf[0] += a ; buf[1] += b ; buf[2] += c ; buf[3] += d ; + buf[4] += e ; buf[5] += f ; buf[6] += g ; buf[7] += h ; +} diff --git a/src/libstdcrypto/sha256_update.c b/src/libstdcrypto/sha256_update.c new file mode 100644 index 0000000..c87644e --- /dev/null +++ b/src/libstdcrypto/sha256_update.c @@ -0,0 +1,10 @@ +/* ISC license. */ + +#include <skalibs/sha256.h> +#include "sha256-internal.h" + +void sha256_update (SHA256Schedule_ref ctx, char const *buf, unsigned int len) +{ + register unsigned int i = 0 ; + for (; i < len ; i++) sha256_feed(ctx, (unsigned char)buf[i]) ; +} diff --git a/src/libstddjb/absolutepath.c b/src/libstddjb/absolutepath.c new file mode 100644 index 0000000..9a7a19f --- /dev/null +++ b/src/libstddjb/absolutepath.c @@ -0,0 +1,12 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include <skalibs/stralloc.h> +#include <skalibs/skamisc.h> +#include <skalibs/djbunix.h> + +int sarealpath (stralloc *sa, char const *path) +{ + return sarealpath_tmp(sa, path, &satmp) ; +} diff --git a/src/libstddjb/absolutepath_tmp.c b/src/libstddjb/absolutepath_tmp.c new file mode 100644 index 0000000..79a613a --- /dev/null +++ b/src/libstddjb/absolutepath_tmp.c @@ -0,0 +1,62 @@ +/* ISC license. */ + +#include <unistd.h> +#include <errno.h> +#include <skalibs/bytestr.h> +#include <skalibs/stralloc.h> +#include <skalibs/djbunix.h> + +int sarealpath_tmp (stralloc *sa, char const *path, stralloc *tmp) +{ + unsigned int tmpbase = tmp->len ; + unsigned int base = sa->len ; + unsigned int loop = 48 ; + int fdhere ; + int wasnull = !sa->s ; + + if (!path) return (errno = EINVAL, -1) ; + if (!stralloc_cats(sa, path)) return -1 ; + fdhere = open_read(".") ; + if (fdhere == -1) + { + if (wasnull) stralloc_free(sa) ; else sa->len = base ; + return -1 ; + } + + do + { + tmp->len = tmpbase ; + if (!loop--) { errno = ELOOP ; goto err ; } + if (!sadirname(tmp, sa->s + base, sa->len - base) + || !stralloc_0(tmp) + || (chdir(tmp->s + tmpbase) == -1)) + goto err ; + tmp->len = tmpbase ; + if (!sabasename(tmp, sa->s + base, sa->len - base) + || !stralloc_0(tmp)) goto err ; + sa->len = base ; + } + while (sareadlink(sa, tmp->s + tmpbase) >= 0) ; + + if ((errno != EINVAL) + || (sagetcwd(sa) == -1) + || ((sa->len > base + 1) && !stralloc_catb(sa, "/", 1)) + || ((--tmp->len > tmpbase) && (tmp->s[tmpbase] != '/') && !stralloc_catb(sa, tmp->s + tmpbase, tmp->len - tmpbase))) + goto err ; + + tmp->len = tmpbase ; + fd_chdir(fdhere) ; + fd_close(fdhere) ; + return 0 ; + +err: + { + register int e = errno ; + tmp->len = tmpbase ; + fd_chdir(fdhere) ; + fd_close(fdhere) ; + if (wasnull) stralloc_free(sa) ; else sa->len = base ; + errno = e ; + } + return -1 ; +} diff --git a/src/libstddjb/alloc-internal.h b/src/libstddjb/alloc-internal.h new file mode 100644 index 0000000..918b5df --- /dev/null +++ b/src/libstddjb/alloc-internal.h @@ -0,0 +1,21 @@ +/* ISC license. */ + +#ifndef ALLOC_0_H +#define ALLOC_0_H + +#include <skalibs/sysdeps.h> +#include <skalibs/alloc.h> + +#ifdef SKALIBS_HASMALLOC0 + +#include <stdlib.h> + +#define alloc_0 (aligned_char_ref)malloc(0) + +#else + +extern aligned_char_ref alloc_0 ; + +#endif + +#endif diff --git a/src/libstddjb/alloc.c b/src/libstddjb/alloc.c new file mode 100644 index 0000000..e3f89dd --- /dev/null +++ b/src/libstddjb/alloc.c @@ -0,0 +1,49 @@ +/* ISC license. */ + +#include <errno.h> +#include <stdlib.h> +#include <skalibs/sysdeps.h> +#include <skalibs/alloc.h> +#include "alloc-internal.h" + +#ifdef DEBUG_ALLOC +# include "buffer.h" +# include "strerr2.h" +# include "lolstdio.h" +# define PLM(...) (bprintf(buffer_2, "%s: debug_alloc: ", PROG), bprintf(buffer_2, __VA_ARGS__), buffer_putflush(buffer_2, "\n", 1)) +#endif + +aligned_char_ref alloc (unsigned int n) +{ + register aligned_char_ref p = n ? (aligned_char_ref)malloc(n) : (aligned_char_ref)alloc_0 ; +#ifdef DEBUG_ALLOC + static unsigned int counter = 0 ; + PLM("alloc(%u): %p. Allocated: %u", n, p, ++counter) ; +#endif + return p ; +} + +void alloc_free (void *p) +{ + register int e = errno ; +#ifdef DEBUG_ALLOC + static unsigned int counter = 0 ; + PLM("alloc_free(%p). Freed: %u", p, ++counter) ; +#endif +#ifndef SKALIBS_HASMALLOC0 + if (p != alloc_0) +#endif + free(p) ; + errno = e ; +} + +int alloc_realloc (aligned_char_ref *x, unsigned int n) +{ + aligned_char_ref y = n ? (aligned_char_ref)realloc(*x, n) : (free(*x), alloc_0) ; +#ifdef DEBUG_ALLOC + PLM("alloc_realloc(&%p) -> new address = %p", *x, y) ; +#endif + if (!y) return 0 ; + *x = y ; + return 1 ; +} diff --git a/src/libstddjb/alloc_0.c b/src/libstddjb/alloc_0.c new file mode 100644 index 0000000..2175262 --- /dev/null +++ b/src/libstddjb/alloc_0.c @@ -0,0 +1,13 @@ +/* ISC license. */ + +#include <skalibs/sysdeps.h> +#include <skalibs/alloc.h> +#include "alloc-internal.h" + +#ifndef SKALIBS_HASMALLOC0 + +#define ALIGNMENT 16 +static union { unsigned char blah[ALIGNMENT] ; long double ld ; } const zeroblock ; +aligned_char_ref alloc_0 = (aligned_char_ref)(&zeroblock) ; + +#endif diff --git a/src/libstddjb/allread.c b/src/libstddjb/allread.c new file mode 100644 index 0000000..9f3d3bc --- /dev/null +++ b/src/libstddjb/allread.c @@ -0,0 +1,8 @@ +/* ISC license. */ + +#include <skalibs/allreadwrite.h> + +unsigned int allread (int fd, char *buf, unsigned int len) +{ + return allreadwrite(&fd_read, fd, buf, len) ; +} diff --git a/src/libstddjb/allreadwrite.c b/src/libstddjb/allreadwrite.c new file mode 100644 index 0000000..7e7867b --- /dev/null +++ b/src/libstddjb/allreadwrite.c @@ -0,0 +1,19 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/allreadwrite.h> + +unsigned int allreadwrite (iofunc_t_ref op, int fd, register char *buf, register unsigned int len) +{ + register unsigned int written = 0 ; + while (len) + { + register int w = (*op)(fd, buf, len) ; + if (!w) errno = EPIPE ; + if (w <= 0) break ; + written += w ; + buf += w ; + len -= w ; + } + return written ; +} diff --git a/src/libstddjb/allwrite.c b/src/libstddjb/allwrite.c new file mode 100644 index 0000000..61c8ad7 --- /dev/null +++ b/src/libstddjb/allwrite.c @@ -0,0 +1,8 @@ +/* ISC license. */ + +#include <skalibs/allreadwrite.h> + +unsigned int allwrite (int fd, char const *buf, unsigned int len) +{ + return allreadwrite((iofunc_t_ref)&fd_write, fd, (char *)buf, len) ; +} diff --git a/src/libstddjb/baprintf.c b/src/libstddjb/baprintf.c new file mode 100644 index 0000000..63ea5a7 --- /dev/null +++ b/src/libstddjb/baprintf.c @@ -0,0 +1,15 @@ +/* ISC license. */ + +#include <stdarg.h> +#include <skalibs/bufalloc.h> +#include <skalibs/lolstdio.h> + +int baprintf (bufalloc *ba, char const *format, ...) +{ + va_list args ; + int r ; + va_start(args, format) ; + r = vbaprintf(ba, format, args) ; + va_end(args) ; + return r ; +} diff --git a/src/libstddjb/basename.c b/src/libstddjb/basename.c new file mode 100644 index 0000000..4eb4080 --- /dev/null +++ b/src/libstddjb/basename.c @@ -0,0 +1,19 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include <skalibs/bytestr.h> +#include <skalibs/stralloc.h> +#include <skalibs/djbunix.h> + +char *basename (char *s) +{ + static stralloc basename_sa = STRALLOC_ZERO ; + static char dot0[2] = "." ; + char *dot = dot0 ; + if (!s) return dot ; + basename_sa.len = 0 ; + if (!sabasename(&basename_sa, s, str_len(s))) return 0 ; + if (!stralloc_0(&basename_sa)) return 0 ; + return basename_sa.s ; +} diff --git a/src/libstddjb/bitarray_and.c b/src/libstddjb/bitarray_and.c new file mode 100644 index 0000000..d2f491e --- /dev/null +++ b/src/libstddjb/bitarray_and.c @@ -0,0 +1,10 @@ +/* ISC license. */ + +#include <skalibs/bitarray.h> + +void bitarray_and (unsigned char *c, unsigned char const *a, unsigned char const *b, unsigned int n) +{ + unsigned int len = bitarray_div8(n) ; + register unsigned int i = 0 ; + for (; i < len ; i++) c[i] = a[i] & b[i] ; +} diff --git a/src/libstddjb/bitarray_clearsetn.c b/src/libstddjb/bitarray_clearsetn.c new file mode 100644 index 0000000..b3f46f1 --- /dev/null +++ b/src/libstddjb/bitarray_clearsetn.c @@ -0,0 +1,24 @@ +/* ISC license. */ + +#include <skalibs/bitarray.h> + +void bitarray_clearsetn (register unsigned char *s, register unsigned int a, register unsigned int b, register int h) +{ + if (!b) return ; + b += a ; + if ((a >> 3) == ((b-1) >> 3)) + { + register unsigned char mask = ((1 << (a & 7)) - 1) ^ ((1 << (b & 7)) - 1) ; + if (h) s[a>>3] |= mask ; else s[a>>3] &= ~mask ; + } + else + { + register unsigned char mask = ~((1 << (a & 7)) - 1) ; + register unsigned int i = (a>>3) + 1 ; + if (h) s[a>>3] |= mask ; else s[a>>3] &= ~mask ; + mask = h ? 0xff : 0x00 ; + for (; i < b>>3 ; i++) s[i] = mask ; + mask = (1 << (b & 7)) - 1 ; + if (h) s[b>>3] |= mask ; else s[b>>3] &= ~mask ; + } +} diff --git a/src/libstddjb/bitarray_firstclear.c b/src/libstddjb/bitarray_firstclear.c new file mode 100644 index 0000000..80b6fbb --- /dev/null +++ b/src/libstddjb/bitarray_firstclear.c @@ -0,0 +1,14 @@ +/* ISC license. */ + +#include <skalibs/bitarray.h> + +unsigned int bitarray_firstclear (register unsigned char const *s, unsigned int max) +{ + unsigned int n = bitarray_div8(max) ; + register unsigned int i = 0 ; + for (; i < n ; i++) if (s[i] != 0xffU) break ; + if (i == n) return max ; + i <<= 3 ; + while ((i < max) && bitarray_peek(s, i)) i++ ; + return i ; +} diff --git a/src/libstddjb/bitarray_firstset.c b/src/libstddjb/bitarray_firstset.c new file mode 100644 index 0000000..de3d27e --- /dev/null +++ b/src/libstddjb/bitarray_firstset.c @@ -0,0 +1,14 @@ +/* ISC license. */ + +#include <skalibs/bitarray.h> + +unsigned int bitarray_firstset (register unsigned char const *s, unsigned int max) +{ + unsigned int n = bitarray_div8(max) ; + register unsigned int i = 0 ; + for (; i < n ; i++) if (s[i]) break ; + if (i == n) return max ; + i <<= 3 ; + while ((i < max) && !bitarray_peek(s, i)) i++ ; + return i ; +} diff --git a/src/libstddjb/bitarray_not.c b/src/libstddjb/bitarray_not.c new file mode 100644 index 0000000..4bd95ad --- /dev/null +++ b/src/libstddjb/bitarray_not.c @@ -0,0 +1,18 @@ +/* ISC license. */ + +#include <skalibs/bitarray.h> + +void bitarray_not (register unsigned char *s, register unsigned int a, register unsigned int b) +{ + if (!b) return ; + b += a ; + if ((a >> 3) == ((b-1) >> 3)) + s[a>>3] ^= ((1 << (a & 7)) - 1) ^ ((a << (b & 7)) - 1) ; + else + { + register unsigned int i = (a>>3) + 1 ; + s[a>>3] ^= ~((1 << (a & 7)) - 1) ; + for (; i < (b>>3) - 1 ; i++) s[i] = ~s[i] ; + s[b>>3] ^= (1 << (b & 7)) - 1 ; + } +} diff --git a/src/libstddjb/bitarray_or.c b/src/libstddjb/bitarray_or.c new file mode 100644 index 0000000..9e9e6b3 --- /dev/null +++ b/src/libstddjb/bitarray_or.c @@ -0,0 +1,10 @@ +/* ISC license. */ + +#include <skalibs/bitarray.h> + +void bitarray_or (unsigned char *c, unsigned char const *a, unsigned char const *b, unsigned int n) +{ + unsigned int len = bitarray_div8(n) ; + register unsigned int i = 0 ; + for (; i < len ; i++) c[i] = a[i] | b[i] ; +} diff --git a/src/libstddjb/bitarray_testandpoke.c b/src/libstddjb/bitarray_testandpoke.c new file mode 100644 index 0000000..5075f1d --- /dev/null +++ b/src/libstddjb/bitarray_testandpoke.c @@ -0,0 +1,11 @@ +/* ISC license. */ + +#include <skalibs/bitarray.h> + +int bitarray_testandpoke (register unsigned char *s, register unsigned int n, register int h) +{ + register unsigned char mask = 1 << (n & 7) ; + register unsigned char c = s[n>>3] ; + s[n>>3] = h ? c | mask : c & ~mask ; + return (c & mask) ? 1 : 0 ; +} diff --git a/src/libstddjb/bitarray_xor.c b/src/libstddjb/bitarray_xor.c new file mode 100644 index 0000000..8b16f25 --- /dev/null +++ b/src/libstddjb/bitarray_xor.c @@ -0,0 +1,10 @@ +/* ISC license. */ + +#include <skalibs/bitarray.h> + +void bitarray_xor (unsigned char *c, unsigned char const *a, unsigned char const *b, unsigned int n) +{ + unsigned int len = bitarray_div8(n) ; + register unsigned int i = 0 ; + for (; i < len ; i++) c[i] = a[i] ^ b[i] ; +} diff --git a/src/libstddjb/bprintf.c b/src/libstddjb/bprintf.c new file mode 100644 index 0000000..56617ad --- /dev/null +++ b/src/libstddjb/bprintf.c @@ -0,0 +1,15 @@ +/* ISC license. */ + +#include <stdarg.h> +#include <skalibs/buffer.h> +#include <skalibs/lolstdio.h> + +int bprintf (buffer *b, char const *format, ...) +{ + va_list args ; + int r ; + va_start(args, format) ; + r = vbprintf(b, format, args) ; + va_end(args) ; + return r ; +} diff --git a/src/libstddjb/bufalloc_1.c b/src/libstddjb/bufalloc_1.c new file mode 100644 index 0000000..6e636ca --- /dev/null +++ b/src/libstddjb/bufalloc_1.c @@ -0,0 +1,9 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include <skalibs/allreadwrite.h> +#include <skalibs/bufalloc.h> + +static bufalloc b = BUFALLOC_INIT(&fd_write, 1) ; +bufalloc_ref bufalloc_1 = &b ; diff --git a/src/libstddjb/bufalloc_2.c b/src/libstddjb/bufalloc_2.c new file mode 100644 index 0000000..bcf97da --- /dev/null +++ b/src/libstddjb/bufalloc_2.c @@ -0,0 +1,9 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include <skalibs/allreadwrite.h> +#include <skalibs/bufalloc.h> + +static bufalloc b = BUFALLOC_INIT(&fd_write, 2) ; +bufalloc_ref bufalloc_2 = &b ; diff --git a/src/libstddjb/bufalloc_clean.c b/src/libstddjb/bufalloc_clean.c new file mode 100644 index 0000000..28bd35e --- /dev/null +++ b/src/libstddjb/bufalloc_clean.c @@ -0,0 +1,14 @@ +/* ISC license. */ + +#include <skalibs/bytestr.h> +#include <skalibs/bufalloc.h> + +void bufalloc_clean (register bufalloc_ref ba) +{ + if (ba->p) + { + byte_copy(ba->x.s, ba->x.len - ba->p, ba->x.s + ba->p) ; + ba->x.len -= ba->p ; + ba->p = 0 ; + } +} diff --git a/src/libstddjb/bufalloc_flush.c b/src/libstddjb/bufalloc_flush.c new file mode 100644 index 0000000..49b2eb1 --- /dev/null +++ b/src/libstddjb/bufalloc_flush.c @@ -0,0 +1,11 @@ +/* ISC license. */ + +#include <skalibs/allreadwrite.h> +#include <skalibs/bufalloc.h> + +int bufalloc_flush (bufalloc_ref ba) +{ + ba->p += allreadwrite((iofunc_t_ref)ba->op, ba->fd, ba->x.s + ba->p, ba->x.len - ba->p) ; + bufalloc_clean(ba) ; + return !ba->x.len ; +} diff --git a/src/libstddjb/bufalloc_getfd.c b/src/libstddjb/bufalloc_getfd.c new file mode 100644 index 0000000..d24ab88 --- /dev/null +++ b/src/libstddjb/bufalloc_getfd.c @@ -0,0 +1,8 @@ +/* ISC license. */ + +#include <skalibs/bufalloc.h> + +int bufalloc_getfd (bufalloc const *ba) +{ + return bufalloc_fd(ba) ; +} diff --git a/src/libstddjb/bufalloc_getlen.c b/src/libstddjb/bufalloc_getlen.c new file mode 100644 index 0000000..696e41d --- /dev/null +++ b/src/libstddjb/bufalloc_getlen.c @@ -0,0 +1,8 @@ +/* ISC license. */ + +#include <skalibs/bufalloc.h> + +unsigned int bufalloc_getlen (bufalloc const *ba) +{ + return bufalloc_len(ba) ; +} diff --git a/src/libstddjb/bufalloc_init.c b/src/libstddjb/bufalloc_init.c new file mode 100644 index 0000000..ddb6b6b --- /dev/null +++ b/src/libstddjb/bufalloc_init.c @@ -0,0 +1,12 @@ +/* ISC license. */ + +#include <skalibs/stralloc.h> +#include <skalibs/bufalloc.h> + +void bufalloc_init (bufalloc_ref ba, int (*op)(int, char const *, unsigned int), int fd) +{ + ba->x.len = 0 ; + ba->op = op ; + ba->fd = fd ; + ba->p = 0 ; +} diff --git a/src/libstddjb/buffer_0.c b/src/libstddjb/buffer_0.c new file mode 100644 index 0000000..50dc6dc --- /dev/null +++ b/src/libstddjb/buffer_0.c @@ -0,0 +1,8 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include <skalibs/buffer.h> + +static char buf[BUFFER_INSIZE] ; +buffer buffer_0_ = BUFFER_INIT(&buffer_read, 0, buf, BUFFER_INSIZE) ; diff --git a/src/libstddjb/buffer_0f1.c b/src/libstddjb/buffer_0f1.c new file mode 100644 index 0000000..685577c --- /dev/null +++ b/src/libstddjb/buffer_0f1.c @@ -0,0 +1,8 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include <skalibs/buffer.h> + +static char buf[BUFFER_INSIZE] ; +buffer buffer_0f1_ = BUFFER_INIT(&buffer_flush1read, 0, buf, BUFFER_INSIZE) ; diff --git a/src/libstddjb/buffer_0small.c b/src/libstddjb/buffer_0small.c new file mode 100644 index 0000000..849edec --- /dev/null +++ b/src/libstddjb/buffer_0small.c @@ -0,0 +1,8 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include <skalibs/buffer.h> + +static char buf[BUFFER_INSIZE_SMALL] ; +buffer buffer_0small_ = BUFFER_INIT(&buffer_read, 0, buf, BUFFER_INSIZE_SMALL) ; diff --git a/src/libstddjb/buffer_1.c b/src/libstddjb/buffer_1.c new file mode 100644 index 0000000..088d421 --- /dev/null +++ b/src/libstddjb/buffer_1.c @@ -0,0 +1,8 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include <skalibs/buffer.h> + +static char buf[BUFFER_OUTSIZE] ; +buffer buffer_1_ = BUFFER_INIT(&buffer_write, 1, buf, BUFFER_OUTSIZE) ; diff --git a/src/libstddjb/buffer_1small.c b/src/libstddjb/buffer_1small.c new file mode 100644 index 0000000..6e9cfa2 --- /dev/null +++ b/src/libstddjb/buffer_1small.c @@ -0,0 +1,8 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include <skalibs/buffer.h> + +static char buf[BUFFER_OUTSIZE_SMALL] ; +buffer buffer_1small_ = BUFFER_INIT(&buffer_write, 1, buf, BUFFER_OUTSIZE_SMALL) ; diff --git a/src/libstddjb/buffer_2.c b/src/libstddjb/buffer_2.c new file mode 100644 index 0000000..9bc4e3f --- /dev/null +++ b/src/libstddjb/buffer_2.c @@ -0,0 +1,8 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include <skalibs/buffer.h> + +static char buf[BUFFER_ERRSIZE] ; +buffer buffer_2_ = BUFFER_INIT(&buffer_write, 2, buf, BUFFER_ERRSIZE) ; diff --git a/src/libstddjb/buffer_fill.c b/src/libstddjb/buffer_fill.c new file mode 100644 index 0000000..c158abe --- /dev/null +++ b/src/libstddjb/buffer_fill.c @@ -0,0 +1,17 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/buffer.h> +#include <skalibs/cbuffer.h> + +int buffer_fill (buffer *b) +{ + siovec_t v[2] ; + register int r ; + if (buffer_isfull(b)) return (errno = ENOBUFS, -1) ; + buffer_wpeek(b, v) ; + r = (*b->op)(b->fd, v, 2, b->aux) ; + if (r <= 0) return r ; + cbuffer_WSEEK(&b->c, r) ; + return r ; +} diff --git a/src/libstddjb/buffer_flush.c b/src/libstddjb/buffer_flush.c new file mode 100644 index 0000000..ca6ca6b --- /dev/null +++ b/src/libstddjb/buffer_flush.c @@ -0,0 +1,20 @@ +/* ISC license. */ + +#include <skalibs/buffer.h> +#include <skalibs/cbuffer.h> +#include <skalibs/siovec.h> + +int buffer_flush (buffer *b) +{ + for (;;) + { + siovec_t v[2] ; + register int r ; + buffer_rpeek(b, v) ; + if (!v[0].len && !v[1].len) break ; + r = (*b->op)(b->fd, v, 2, b->aux) ; + if (r <= 0) return 0 ; + cbuffer_RSEEK(&b->c, r) ; + } + return 1 ; +} diff --git a/src/libstddjb/buffer_flush1read.c b/src/libstddjb/buffer_flush1read.c new file mode 100644 index 0000000..9dcdf81 --- /dev/null +++ b/src/libstddjb/buffer_flush1read.c @@ -0,0 +1,10 @@ +/* ISC license. */ + +#include <skalibs/buffer.h> +#include <skalibs/siovec.h> + +int buffer_flush1read (int fd, siovec_t const *v, unsigned int n, void *aux) +{ + if (!buffer_flush(buffer_1)) return -1 ; + return buffer_read(fd, v, n, aux) ; +} diff --git a/src/libstddjb/buffer_get.c b/src/libstddjb/buffer_get.c new file mode 100644 index 0000000..dcfa8e7 --- /dev/null +++ b/src/libstddjb/buffer_get.c @@ -0,0 +1,12 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/buffer.h> + +int buffer_get (buffer *b, char *s, unsigned int len) +{ + unsigned int w = 0 ; + register int r = buffer_getall(b, s, len, &w) ; + return r == -1 ? errno == EPIPE ? (errno = 0, 0) : -1 : + !r ? (errno = EWOULDBLOCK, -1) : (int)w ; +} diff --git a/src/libstddjb/buffer_getall.c b/src/libstddjb/buffer_getall.c new file mode 100644 index 0000000..34db9df --- /dev/null +++ b/src/libstddjb/buffer_getall.c @@ -0,0 +1,18 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/allreadwrite.h> +#include <skalibs/buffer.h> + +int buffer_getall (buffer_ref b, char *buf, unsigned int len, unsigned int *w) +{ + if (*w > len) return (errno = EINVAL, -1) ; + *w += buffer_getnofill(b, buf + *w, len - *w) ; + while (*w < len) + { + register int r = sanitize_read(buffer_fill(b)) ; + if (r <= 0) return r ; + *w += buffer_getnofill(b, buf + *w, len - *w) ; + } + return 1 ; +} diff --git a/src/libstddjb/buffer_getallnf.c b/src/libstddjb/buffer_getallnf.c new file mode 100644 index 0000000..8a97a31 --- /dev/null +++ b/src/libstddjb/buffer_getallnf.c @@ -0,0 +1,15 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/buffer.h> + +int buffer_getallnofill (buffer_ref b, char *s, unsigned int len) +{ + register unsigned int r = buffer_getnofill(b, s, len) ; + if (r < len) + { + buffer_unget(b, r) ; + return (errno = ENOBUFS, 0) ; + } + return 1 ; +} diff --git a/src/libstddjb/buffer_getfd.c b/src/libstddjb/buffer_getfd.c new file mode 100644 index 0000000..224beec --- /dev/null +++ b/src/libstddjb/buffer_getfd.c @@ -0,0 +1,8 @@ +/* ISC license. */ + +#include <skalibs/buffer.h> + +int buffer_getfd (buffer const *b) +{ + return buffer_fd(b) ; +} diff --git a/src/libstddjb/buffer_getlen.c b/src/libstddjb/buffer_getlen.c new file mode 100644 index 0000000..73289a7 --- /dev/null +++ b/src/libstddjb/buffer_getlen.c @@ -0,0 +1,8 @@ +/* ISC license. */ + +#include <skalibs/buffer.h> + +unsigned int buffer_getlen (buffer const *b) +{ + return buffer_len(b) ; +} diff --git a/src/libstddjb/buffer_getv.c b/src/libstddjb/buffer_getv.c new file mode 100644 index 0000000..0f8f848 --- /dev/null +++ b/src/libstddjb/buffer_getv.c @@ -0,0 +1,15 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/buffer.h> +#include <skalibs/diuint.h> +#include <skalibs/siovec.h> + +int buffer_getv (buffer *b, siovec_t const *v, unsigned int n) +{ + diuint w = DIUINT_ZERO ; + register int r = buffer_getvall(b, v, n, &w) ; + return r == -1 ? errno == EPIPE ? (errno = 0, 0) : -1 : + !r ? (errno = EWOULDBLOCK, -1) : + (int)(siovec_len(v, w.left) + w.right) ; +} diff --git a/src/libstddjb/buffer_getvall.c b/src/libstddjb/buffer_getvall.c new file mode 100644 index 0000000..b6eeb46 --- /dev/null +++ b/src/libstddjb/buffer_getvall.c @@ -0,0 +1,18 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/buffer.h> +#include <skalibs/diuint.h> +#include <skalibs/siovec.h> + +int buffer_getvall (buffer *b, siovec_t const *v, unsigned int n, diuint *w) +{ + if (w->left > n || (w->left == n && w->right) || w->right >= v[w->left].len) + return (errno = EINVAL, -1) ; + for (; w->left < n ; w->left++, w->right = 0) + { + register int r = buffer_getall(b, v[w->left].s, v[w->left].len, &w->right) ; + if (r <= 0) return r ; + } + return 1 ; +} diff --git a/src/libstddjb/buffer_getvallnf.c b/src/libstddjb/buffer_getvallnf.c new file mode 100644 index 0000000..2f4b82d --- /dev/null +++ b/src/libstddjb/buffer_getvallnf.c @@ -0,0 +1,16 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/buffer.h> +#include <skalibs/siovec.h> + +int buffer_getvallnofill (buffer_ref b, siovec_t const *v, unsigned int n) +{ + register unsigned int r = buffer_getvnofill(b, v, n) ; + if (r < siovec_len(v, n)) + { + buffer_unget(b, r) ; + return (errno = ENOBUFS, 0) ; + } + return 1 ; +} diff --git a/src/libstddjb/buffer_init.c b/src/libstddjb/buffer_init.c new file mode 100644 index 0000000..09d4910 --- /dev/null +++ b/src/libstddjb/buffer_init.c @@ -0,0 +1,13 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/buffer.h> + +int buffer_init_aux (buffer *b, buffer_io_func_t *op, int fd, char *s, unsigned int len, void *aux) +{ + if (!cbuffer_init(&b->c, s, len)) return 0 ; + b->fd = fd ; + b->op = op ; + b->aux = aux ; + return 1 ; +} diff --git a/src/libstddjb/buffer_put.c b/src/libstddjb/buffer_put.c new file mode 100644 index 0000000..56baaa7 --- /dev/null +++ b/src/libstddjb/buffer_put.c @@ -0,0 +1,10 @@ +/* ISC license. */ + +#include <skalibs/buffer.h> + +int buffer_put (buffer *b, char const *s, unsigned int len) +{ + unsigned int w = 0 ; + if (!buffer_putall(b, s, len, &w)) return -1 ; + return (int)w ; +} diff --git a/src/libstddjb/buffer_putall.c b/src/libstddjb/buffer_putall.c new file mode 100644 index 0000000..16facc2 --- /dev/null +++ b/src/libstddjb/buffer_putall.c @@ -0,0 +1,16 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/buffer.h> + +int buffer_putall (buffer *b, char const *s, unsigned int len, unsigned int *written) +{ + if (*written > len) return (errno = EINVAL, 0) ; + for (;;) + { + *written += buffer_putnoflush(b, s + *written, len - *written) ; + if (*written >= len) return 1 ; + buffer_flush(b) ; + if (buffer_isfull(b)) return 0 ; + } +} diff --git a/src/libstddjb/buffer_putallnf.c b/src/libstddjb/buffer_putallnf.c new file mode 100644 index 0000000..1cf3c5e --- /dev/null +++ b/src/libstddjb/buffer_putallnf.c @@ -0,0 +1,15 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/buffer.h> + +int buffer_putallnoflush (buffer *b, char const *s, unsigned int len) +{ + register unsigned int r = buffer_putnoflush(b, s, len) ; + if (r < len) + { + buffer_unput(b, r) ; + return (errno = ENOBUFS, 0) ; + } + return 1 ; +} diff --git a/src/libstddjb/buffer_putflush.c b/src/libstddjb/buffer_putflush.c new file mode 100644 index 0000000..609d88b --- /dev/null +++ b/src/libstddjb/buffer_putflush.c @@ -0,0 +1,11 @@ +/* ISC license. */ + +#include <skalibs/buffer.h> + +int buffer_putflush (buffer *b, char const *s, unsigned int len) +{ + int r = buffer_put(b, s, len) ; + if (r < 0) return -1 ; + if (!buffer_flush(b)) return -1 ; + return r ; +} diff --git a/src/libstddjb/buffer_putv.c b/src/libstddjb/buffer_putv.c new file mode 100644 index 0000000..a1530d2 --- /dev/null +++ b/src/libstddjb/buffer_putv.c @@ -0,0 +1,12 @@ +/* ISC license. */ + +#include <skalibs/buffer.h> +#include <skalibs/diuint.h> +#include <skalibs/siovec.h> + +int buffer_putv (buffer *b, siovec_t const *v, unsigned int n) +{ + diuint w = DIUINT_ZERO ; + if (!buffer_putvall(b, v, n, &w)) return -1 ; + return (int)(siovec_len(v, w.left) + w.right) ; +} diff --git a/src/libstddjb/buffer_putvall.c b/src/libstddjb/buffer_putvall.c new file mode 100644 index 0000000..d6297c1 --- /dev/null +++ b/src/libstddjb/buffer_putvall.c @@ -0,0 +1,15 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/buffer.h> +#include <skalibs/diuint.h> +#include <skalibs/siovec.h> + +int buffer_putvall (buffer *b, siovec_t const *v, unsigned int n, diuint *w) +{ + if (w->left > n || (w->left == n && w->right) || w->right >= v[w->left].len) + return (errno = EINVAL, 0) ; + for (; w->left < n ; w->left++, w->right = 0) + if (!buffer_putall(b, v[w->left].s, v[w->left].len, &w->right)) return 0 ; + return 1 ; +} diff --git a/src/libstddjb/buffer_putvallnf.c b/src/libstddjb/buffer_putvallnf.c new file mode 100644 index 0000000..cada660 --- /dev/null +++ b/src/libstddjb/buffer_putvallnf.c @@ -0,0 +1,15 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/buffer.h> + +int buffer_putvallnoflush (buffer *b, siovec_t const *v, unsigned int n) +{ + register unsigned int r = buffer_putvnoflush(b, v, n) ; + if (r < siovec_len(v, n)) + { + buffer_unput(b, r) ; + return (errno = ENOBUFS, 0) ; + } + return 1 ; +} diff --git a/src/libstddjb/buffer_putvflush.c b/src/libstddjb/buffer_putvflush.c new file mode 100644 index 0000000..46f9e03 --- /dev/null +++ b/src/libstddjb/buffer_putvflush.c @@ -0,0 +1,12 @@ +/* ISC license. */ + +#include <skalibs/buffer.h> +#include <skalibs/siovec.h> + +int buffer_putvflush (buffer *b, siovec_t const *v, unsigned int n) +{ + int r = buffer_putv(b, v, n) ; + if (r < 0) return -1 ; + if (!buffer_flush(b)) return -1 ; + return r ; +} diff --git a/src/libstddjb/buffer_read.c b/src/libstddjb/buffer_read.c new file mode 100644 index 0000000..150bc15 --- /dev/null +++ b/src/libstddjb/buffer_read.c @@ -0,0 +1,15 @@ +/* ISC license. */ + +#include <sys/types.h> +#include <sys/uio.h> +#include <skalibs/allreadwrite.h> +#include <skalibs/buffer.h> +#include <skalibs/siovec.h> + +int buffer_read (int fd, siovec_t const *v, unsigned int n, void *aux) +{ + struct iovec iov[n] ; + iovec_from_siovec(iov, v, n) ; + (void)aux ; + return fd_readv(fd, iov, n) ; +} diff --git a/src/libstddjb/buffer_write.c b/src/libstddjb/buffer_write.c new file mode 100644 index 0000000..40ffd46 --- /dev/null +++ b/src/libstddjb/buffer_write.c @@ -0,0 +1,15 @@ +/* ISC license. */ + +#include <sys/types.h> +#include <sys/uio.h> +#include <skalibs/allreadwrite.h> +#include <skalibs/buffer.h> +#include <skalibs/siovec.h> + +int buffer_write (int fd, siovec_t const *v, unsigned int n, void *aux) +{ + struct iovec iov[n] ; + iovec_from_siovec(iov, v, n) ; + (void)aux ; + return fd_writev(fd, iov, n) ; +} diff --git a/src/libstddjb/byte_chr.c b/src/libstddjb/byte_chr.c new file mode 100644 index 0000000..e9caef5 --- /dev/null +++ b/src/libstddjb/byte_chr.c @@ -0,0 +1,33 @@ +/* ISC license. */ + +#include <skalibs/config.h> +#include <skalibs/bytestr.h> + +#ifndef SKALIBS_FLAG_REPLACE_LIBC + +#include <string.h> + +unsigned int byte_chr (char const *s, unsigned int n, int c) +{ + register void *p = memchr(s, c, n) ; + return p ? (unsigned int)((char *)p - s) : n ; +} + +#else + +unsigned int byte_chr (char const *s, unsigned int n, int c) +{ + register char ch = c ; + register char const *t = s ; + + for (;;) + { + if (!n) break; if (*t == ch) break; ++t; --n; + if (!n) break; if (*t == ch) break; ++t; --n; + if (!n) break; if (*t == ch) break; ++t; --n; + if (!n) break; if (*t == ch) break; ++t; --n; + } + return t - s ; +} + +#endif diff --git a/src/libstddjb/byte_copy.c b/src/libstddjb/byte_copy.c new file mode 100644 index 0000000..410fb95 --- /dev/null +++ b/src/libstddjb/byte_copy.c @@ -0,0 +1,14 @@ +/* ISC license. */ + +#include <skalibs/config.h> + +#ifdef SKALIBS_FLAG_REPLACE_LIBC + +#include <skalibs/bytestr.h> + +void byte_copy (register char *to, register unsigned int n, register char const *from) +{ + while (n--) *to++ = *from++ ; +} + +#endif diff --git a/src/libstddjb/byte_count.c b/src/libstddjb/byte_count.c new file mode 100644 index 0000000..5e3f8af --- /dev/null +++ b/src/libstddjb/byte_count.c @@ -0,0 +1,10 @@ +/* ISC license. */ + +#include <skalibs/bytestr.h> + +unsigned int byte_count (register char const *s, register unsigned int len, register char b) +{ + register unsigned int n = 0 ; + while (len--) if (*s++ == b) n++ ; + return n ; +} diff --git a/src/libstddjb/byte_cr.c b/src/libstddjb/byte_cr.c new file mode 100644 index 0000000..d81e7cf --- /dev/null +++ b/src/libstddjb/byte_cr.c @@ -0,0 +1,22 @@ +/* ISC license. */ + +#include <skalibs/config.h> + +#ifdef SKALIBS_FLAG_REPLACE_LIBC + +#include <skalibs/bytestr.h> + +void byte_copyr (register char *to, register unsigned int n, register char const *from) +{ + to += n ; + from += n ; + for (;;) + { + if (!n) return; *--to = *--from; --n; + if (!n) return; *--to = *--from; --n; + if (!n) return; *--to = *--from; --n; + if (!n) return; *--to = *--from; --n; + } +} + +#endif diff --git a/src/libstddjb/byte_diff.c b/src/libstddjb/byte_diff.c new file mode 100644 index 0000000..9e7f107 --- /dev/null +++ b/src/libstddjb/byte_diff.c @@ -0,0 +1,22 @@ +/* ISC license. */ + +#include <skalibs/config.h> + +#ifdef SKALIBS_FLAG_REPLACE_LIBC + +#include <skalibs/bytestr.h> + +int byte_diff (register char const *s, register unsigned int n, register char const *t) +{ + for (;;) + { + if (!n) return 0; if (*s != *t) break; ++s; ++t; --n; + if (!n) return 0; if (*s != *t) break; ++s; ++t; --n; + if (!n) return 0; if (*s != *t) break; ++s; ++t; --n; + if (!n) return 0; if (*s != *t) break; ++s; ++t; --n; + } + return ((int)(unsigned int)(unsigned char) *s) + - ((int)(unsigned int)(unsigned char) *t) ; +} + +#endif diff --git a/src/libstddjb/byte_in.c b/src/libstddjb/byte_in.c new file mode 100644 index 0000000..60625c5 --- /dev/null +++ b/src/libstddjb/byte_in.c @@ -0,0 +1,14 @@ +/* ISC license. */ + +#include <skalibs/bytestr.h> + +unsigned int byte_in (char const *s, register unsigned int n, register char const *sep, register unsigned int len) +{ + register char const *t = s ; + while (n--) + { + if (byte_chr(sep, len, *t) < len) break ; + ++t ; + } + return t - s ; +} diff --git a/src/libstddjb/byte_rchr.c b/src/libstddjb/byte_rchr.c new file mode 100644 index 0000000..3564c36 --- /dev/null +++ b/src/libstddjb/byte_rchr.c @@ -0,0 +1,12 @@ +/* ISC license. */ + +#include <skalibs/bytestr.h> + +unsigned int byte_rchr (register char const *s, unsigned int n, int c) +{ + register unsigned int i = n ; + register char ch = c ; + s += n ; + while (i--) if (*--s == ch) return i ; + return n ; +} diff --git a/src/libstddjb/byte_zero.c b/src/libstddjb/byte_zero.c new file mode 100644 index 0000000..6751210 --- /dev/null +++ b/src/libstddjb/byte_zero.c @@ -0,0 +1,15 @@ +/* ISC license. */ + +#include <skalibs/config.h> + +#ifdef SKALIBS_FLAG_REPLACE_LIBC + +#include <skalibs/bytestr.h> + +void byte_zero (void *p, register unsigned int n) +{ + register char *s = (char *)p ; + while (n--) *s++ = 0 ; +} + +#endif diff --git a/src/libstddjb/case_diffb.c b/src/libstddjb/case_diffb.c new file mode 100644 index 0000000..1931c0f --- /dev/null +++ b/src/libstddjb/case_diffb.c @@ -0,0 +1,18 @@ +/* ISC license. */ + +#include <skalibs/bytestr.h> + +int case_diffb (char const *s, unsigned int len, char const *t) +{ + register unsigned char x = 0, y = 0 ; + unsigned char const d = 'a' - 'A' ; + + while (len-- && (x == y)) + { + x = *s++ ; + if (('a' <= x) && (x <= 'z')) x -= d ; + y = *t++ ; + if (('a' <= y) && (y <= 'z')) y -= d ; + } + return (int)(x - y) ; +} diff --git a/src/libstddjb/case_diffs.c b/src/libstddjb/case_diffs.c new file mode 100644 index 0000000..2731408 --- /dev/null +++ b/src/libstddjb/case_diffs.c @@ -0,0 +1,18 @@ +/* ISC license. */ + +#include <skalibs/bytestr.h> + +int case_diffs (char const *s, char const *t) +{ + register unsigned char x = 1, y = 1 ; + unsigned char const d = 'a' - 'A' ; + + while (x && (x == y)) + { + x = *s++ ; + if (('a' <= x) && (x <= 'z')) x -= d ; + y = *t++ ; + if (('a' <= y) && (y <= 'z')) y -= d ; + } + return (int)(x - y) ; +} diff --git a/src/libstddjb/case_lowerb.c b/src/libstddjb/case_lowerb.c new file mode 100644 index 0000000..9f51ed5 --- /dev/null +++ b/src/libstddjb/case_lowerb.c @@ -0,0 +1,13 @@ +/* ISC license. */ + +#include <skalibs/bytestr.h> + +void case_lowerb (register char *s, unsigned int len) +{ + register unsigned char const d = 'a' - 'A' ; + while (len--) + { + if (('A' <= *s) && (*s <= 'Z')) *s += d ; + ++s ; + } +} diff --git a/src/libstddjb/case_lowers.c b/src/libstddjb/case_lowers.c new file mode 100644 index 0000000..5999786 --- /dev/null +++ b/src/libstddjb/case_lowers.c @@ -0,0 +1,13 @@ +/* ISC license. */ + +#include <skalibs/bytestr.h> + +void case_lowers (register char *s) +{ + register unsigned char const d = 'a' - 'A' ; + while (*s) + { + if (('A' <= *s) && (*s <= 'Z')) *s += d ; + ++s ; + } +} diff --git a/src/libstddjb/case_startb.c b/src/libstddjb/case_startb.c new file mode 100644 index 0000000..cae0fb4 --- /dev/null +++ b/src/libstddjb/case_startb.c @@ -0,0 +1,9 @@ +/* ISC license. */ + +#include <skalibs/bytestr.h> + +int case_startb (register char const *s, unsigned int slen, register char const *t) +{ + register unsigned int tlen = str_len(t) ; + return slen < tlen ? 0 : !case_diffb(s, tlen, t) ; +} diff --git a/src/libstddjb/case_str.c b/src/libstddjb/case_str.c new file mode 100644 index 0000000..14409c3 --- /dev/null +++ b/src/libstddjb/case_str.c @@ -0,0 +1,32 @@ +/* ISC license. */ + +#include <skalibs/config.h> +#include <skalibs/sysdeps.h> + +#if defined(SKALIBS_HASSTRCASESTR) && !defined(SKALIBS_FLAG_REPLACE_LIBC) + +#include <skalibs/nonposix.h> +#include <string.h> +#include <skalibs/bytestr.h> + +unsigned int case_str (char const *haystack, char const *needle) +{ + register char *p = strcasestr(haystack, needle) ; + return p ? p - haystack : str_len(haystack) ; +} + +#else + +#include <skalibs/bytestr.h> + +unsigned int case_str (char const *haystack, char const *needle) +{ + unsigned int nlen = str_len(needle) ; + register char const *p = haystack ; + if (!nlen) return 0 ; + for (; *p ; p++) + if (!case_diffb(p, nlen, needle)) return p - haystack ; + return str_len(haystack) ; +} + +#endif diff --git a/src/libstddjb/case_upperb.c b/src/libstddjb/case_upperb.c new file mode 100644 index 0000000..54ceab4 --- /dev/null +++ b/src/libstddjb/case_upperb.c @@ -0,0 +1,13 @@ +/* ISC license. */ + +#include <skalibs/bytestr.h> + +void case_upperb (register char *s, unsigned int len) +{ + register unsigned char const d = 'a' - 'A' ; + while (len--) + { + if (('a' <= *s) && (*s <= 'z')) *s -= d ; + ++s ; + } +} diff --git a/src/libstddjb/case_uppers.c b/src/libstddjb/case_uppers.c new file mode 100644 index 0000000..cf2875a --- /dev/null +++ b/src/libstddjb/case_uppers.c @@ -0,0 +1,13 @@ +/* ISC license. */ + +#include <skalibs/bytestr.h> + +void case_uppers (register char *s) +{ + register unsigned char const d = 'a' - 'A' ; + while (*s) + { + if (('a' <= *s) && (*s <= 'z')) *s -= d ; + ++s ; + } +} diff --git a/src/libstddjb/cbuffer_get.c b/src/libstddjb/cbuffer_get.c new file mode 100644 index 0000000..544cbb2 --- /dev/null +++ b/src/libstddjb/cbuffer_get.c @@ -0,0 +1,11 @@ +/* ISC license. */ + +#include <skalibs/cbuffer.h> +#include <skalibs/siovec.h> + +unsigned int cbuffer_get (cbuffer_t *b, char *s, unsigned int len) +{ + siovec_t v[2] ; + cbuffer_rpeek(b, v) ; + return cbuffer_RSEEK(b, siovec_gather(v, 2, s, len)) ; +} diff --git a/src/libstddjb/cbuffer_getv.c b/src/libstddjb/cbuffer_getv.c new file mode 100644 index 0000000..3db638f --- /dev/null +++ b/src/libstddjb/cbuffer_getv.c @@ -0,0 +1,11 @@ +/* ISC license. */ + +#include <skalibs/cbuffer.h> +#include <skalibs/siovec.h> + +unsigned int cbuffer_getv (cbuffer_t *b, siovec_t const *v, unsigned int n) +{ + siovec_t vsrc[2] ; + cbuffer_rpeek(b, vsrc) ; + return cbuffer_RSEEK(b, siovec_deal(v, n, vsrc, 2)) ; +} diff --git a/src/libstddjb/cbuffer_init.c b/src/libstddjb/cbuffer_init.c new file mode 100644 index 0000000..eba4765 --- /dev/null +++ b/src/libstddjb/cbuffer_init.c @@ -0,0 +1,13 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/cbuffer.h> + +int cbuffer_init (cbuffer_t *b, char *s, unsigned int len) +{ + if (len < 2) return (errno = EINVAL, 0) ; + b->x = s ; + b->a = len ; + b->p = b->n = 0 ; + return 1 ; +} diff --git a/src/libstddjb/cbuffer_put.c b/src/libstddjb/cbuffer_put.c new file mode 100644 index 0000000..12f513e --- /dev/null +++ b/src/libstddjb/cbuffer_put.c @@ -0,0 +1,11 @@ +/* ISC license. */ + +#include <skalibs/cbuffer.h> +#include <skalibs/siovec.h> + +unsigned int cbuffer_put (cbuffer_t *b, char const *s, unsigned int len) +{ + siovec_t v[2] ; + cbuffer_wpeek(b, v) ; + return cbuffer_WSEEK(b, siovec_scatter(v, 2, s, len)) ; +} diff --git a/src/libstddjb/cbuffer_putv.c b/src/libstddjb/cbuffer_putv.c new file mode 100644 index 0000000..66bed05 --- /dev/null +++ b/src/libstddjb/cbuffer_putv.c @@ -0,0 +1,11 @@ +/* ISC license. */ + +#include <skalibs/cbuffer.h> +#include <skalibs/siovec.h> + +unsigned int cbuffer_putv (cbuffer_t *b, siovec_t const *v, unsigned int n) +{ + siovec_t vdest[2] ; + cbuffer_wpeek(b, vdest) ; + return cbuffer_WSEEK(b, siovec_deal(vdest, 2, v, n)) ; +} diff --git a/src/libstddjb/cbuffer_rpeek.c b/src/libstddjb/cbuffer_rpeek.c new file mode 100644 index 0000000..22a1ef5 --- /dev/null +++ b/src/libstddjb/cbuffer_rpeek.c @@ -0,0 +1,21 @@ +/* ISC license. */ + +#include <skalibs/cbuffer.h> +#include <skalibs/siovec.h> + +void cbuffer_rpeek (cbuffer_t *b, siovec_t *v) +{ + v[0].s = b->x + b->p ; + if (b->n >= b->p) + { + v[0].len = b->n - b->p ; + v[1].s = 0 ; + v[1].len = 0 ; + } + else + { + v[0].len = b->a - b->p ; + v[1].s = b->x ; + v[1].len = b->n ; + } +} diff --git a/src/libstddjb/cbuffer_rseek.c b/src/libstddjb/cbuffer_rseek.c new file mode 100644 index 0000000..4a98511 --- /dev/null +++ b/src/libstddjb/cbuffer_rseek.c @@ -0,0 +1,10 @@ +/* ISC license. */ + +#include <skalibs/cbuffer.h> + +unsigned int cbuffer_rseek (cbuffer_t *b, unsigned int len) +{ + register unsigned int max = cbuffer_len(b) ; + if (len > max) len = max ; + return cbuffer_RSEEK(b, len) ; +} diff --git a/src/libstddjb/cbuffer_unget.c b/src/libstddjb/cbuffer_unget.c new file mode 100644 index 0000000..d1591e6 --- /dev/null +++ b/src/libstddjb/cbuffer_unget.c @@ -0,0 +1,10 @@ +/* ISC license. */ + +#include <skalibs/cbuffer.h> + +unsigned int cbuffer_unget (cbuffer_t *b, unsigned int len) +{ + register unsigned int max = cbuffer_available(b) ; + if (len > max) len = max ; + return cbuffer_UNGET(b, len) ; +} diff --git a/src/libstddjb/cbuffer_unput.c b/src/libstddjb/cbuffer_unput.c new file mode 100644 index 0000000..8221ca0 --- /dev/null +++ b/src/libstddjb/cbuffer_unput.c @@ -0,0 +1,10 @@ +/* ISC license. */ + +#include <skalibs/cbuffer.h> + +unsigned int cbuffer_unput (cbuffer_t *b, unsigned int len) +{ + register unsigned int max = cbuffer_len(b) ; + if (len > max) len = max ; + return cbuffer_UNPUT(b, len) ; +} diff --git a/src/libstddjb/cbuffer_wpeek.c b/src/libstddjb/cbuffer_wpeek.c new file mode 100644 index 0000000..a2c6a63 --- /dev/null +++ b/src/libstddjb/cbuffer_wpeek.c @@ -0,0 +1,22 @@ +/* ISC license. */ + +#include <skalibs/cbuffer.h> +#include <skalibs/siovec.h> + +void cbuffer_wpeek (cbuffer_t *b, siovec_t *v) +{ + unsigned int last = (b->a - 1 + b->p) % b->a ; + v[0].s = b->x + b->n ; + if (last >= b->n) + { + v[0].len = last - b->n ; + v[1].s = 0 ; + v[1].len = 0 ; + } + else + { + v[0].len = b->a - b->n ; + v[1].s = b->x ; + v[1].len = last ; + } +} diff --git a/src/libstddjb/cbuffer_wseek.c b/src/libstddjb/cbuffer_wseek.c new file mode 100644 index 0000000..6b90ab6 --- /dev/null +++ b/src/libstddjb/cbuffer_wseek.c @@ -0,0 +1,10 @@ +/* ISC license. */ + +#include <skalibs/cbuffer.h> + +unsigned int cbuffer_wseek (cbuffer_t *b, unsigned int len) +{ + register unsigned int max = cbuffer_available(b) ; + if (len > max) len = max ; + return cbuffer_WSEEK(b, len) ; +} diff --git a/src/libstddjb/cdb_findnext.c b/src/libstddjb/cdb_findnext.c new file mode 100644 index 0000000..2559bc2 --- /dev/null +++ b/src/libstddjb/cdb_findnext.c @@ -0,0 +1,67 @@ +/* ISC license. */ + +#include <skalibs/bytestr.h> +#include <skalibs/uint32.h> +#include <skalibs/cdb.h> + +static int match (struct cdb *c, char const *key, unsigned int len, uint32 pos) +{ + char buf[1024] ; + while (len > 0) + { + register unsigned int n = 1024 ; + if (n > len) n = len ; + if (cdb_read(c, buf, n, pos) < 0) return -1 ; + if (byte_diff(buf, n, key)) return 0 ; + pos += n ; key += n ; len -= n ; + } + return 1 ; +} + +int cdb_findnext (struct cdb *c, char const *key, unsigned int len) +{ + char buf[8] ; + uint32 pos ; + uint32 u ; + + if (!c->loop) + { + u = cdb_hash(key, len) ; + if (cdb_read(c, buf, 8, (u << 3) & 2047) < 0) return -1 ; + uint32_unpack(buf + 4, &c->hslots) ; + if (!c->hslots) return 0 ; + uint32_unpack(buf, &c->hpos) ; + c->khash = u ; + u >>= 8 ; + u %= c->hslots ; + u <<= 3 ; + c->kpos = c->hpos + u ; + } + + while (c->loop < c->hslots) + { + if (cdb_read(c, buf, 8, c->kpos) < 0) return -1 ; + uint32_unpack(buf + 4, &pos) ; + if (!pos) return 0 ; + c->loop++ ; + c->kpos += 8 ; + if (c->kpos == c->hpos + (c->hslots << 3)) c->kpos = c->hpos ; + uint32_unpack(buf, &u) ; + if (u == c->khash) + { + if (cdb_read(c, buf, 8, pos) < 0) return -1 ; + uint32_unpack(buf, &u) ; + if (u == len) + switch (match(c, key, len, pos + 8)) + { + case -1: + return -1 ; + case 1: + uint32_unpack(buf + 4, &c->dlen) ; + c->dpos = pos + 8 + len ; + return 1 ; + } + } + } + return 0 ; +} diff --git a/src/libstddjb/cdb_free.c b/src/libstddjb/cdb_free.c new file mode 100644 index 0000000..dcf9675 --- /dev/null +++ b/src/libstddjb/cdb_free.c @@ -0,0 +1,11 @@ +/* ISC license. */ + +#include <sys/types.h> +#include <sys/mman.h> +#include <skalibs/cdb.h> + +extern void cdb_free (struct cdb *c) +{ + if (c->map) munmap(c->map, c->size) ; + *c = cdb_zero ; +} diff --git a/src/libstddjb/cdb_hash.c b/src/libstddjb/cdb_hash.c new file mode 100644 index 0000000..9eedf54 --- /dev/null +++ b/src/libstddjb/cdb_hash.c @@ -0,0 +1,17 @@ +/* ISC license. */ + +#include <skalibs/uint32.h> +#include <skalibs/cdb.h> + +uint32 cdb_hashadd (uint32 h, unsigned char c) +{ + h += (h << 5) ; + return h ^ c ; +} + +uint32 cdb_hash (char const *buf, unsigned int len) +{ + uint32 h = CDB_HASHSTART ; + while (len--) h = cdb_hashadd(h, *buf++) ; + return h ; +} diff --git a/src/libstddjb/cdb_init_map.c b/src/libstddjb/cdb_init_map.c new file mode 100644 index 0000000..bf8eb9d --- /dev/null +++ b/src/libstddjb/cdb_init_map.c @@ -0,0 +1,23 @@ +/* ISC license. */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/mman.h> +#include <skalibs/cdb.h> + +int cdb_init_map (struct cdb *c, int fd, int domap) +{ + if (domap) + { + struct stat st ; + char *map ; + if (fstat(fd, &st) < 0) return 0 ; + map = mmap(0, st.st_size, PROT_READ, MAP_SHARED, fd, 0) ; + if (map == MAP_FAILED) return 0 ; + c->fd = -fd-2 ; + c->map = map ; + c->size = st.st_size ; + } + else c->fd = fd ; + return 1 ; +} diff --git a/src/libstddjb/cdb_make.c b/src/libstddjb/cdb_make.c new file mode 100644 index 0000000..0ec3423 --- /dev/null +++ b/src/libstddjb/cdb_make.c @@ -0,0 +1,145 @@ +/* ISC license. */ + +#include <unistd.h> +#include <errno.h> +#include <skalibs/uint32.h> +#include <skalibs/diuint32.h> +#include <skalibs/genalloc.h> +#include <skalibs/buffer.h> +#include <skalibs/djbunix.h> +#include <skalibs/cdb.h> +#include <skalibs/cdb_make.h> + +static void cdb_make_free (struct cdb_make *c) +{ + struct cdb_make zero = CDB_MAKE_ZERO ; + genalloc_free(diuint32, &c->hplist) ; + *c = zero ; +} + +int cdb_make_start (struct cdb_make *c, int fd) +{ + c->hplist = genalloc_zero ; + c->fd = fd ; + c->pos = 2048 ; + buffer_init(&c->b, &buffer_write, fd, c->buf, BUFFER_OUTSIZE) ; + return seek_set(fd, c->pos) ; +} + +static int posplus (struct cdb_make *c, uint32 len) +{ + register uint32 newpos = c->pos + len ; + if (newpos < len) return (errno = ENOMEM, 0) ; + c->pos = newpos ; + return 1 ; +} + +static int cdb_make_addend (struct cdb_make *c, unsigned int keylen, unsigned int datalen, uint32 h) +{ + diuint32 blah = { h, c->pos } ; + if (!genalloc_append(diuint32, &c->hplist, &blah) || !posplus(c, 8) || !posplus(c, keylen) || !posplus(c, datalen)) + { + cdb_make_free(c) ; + return -1 ; + } + return 0 ; +} + +static int cdb_make_addbegin (struct cdb_make *c, unsigned int keylen, unsigned int datalen) +{ + char buf[8] ; + if ((keylen > 0xffffffff) || (datalen > 0xffffffff)) + { + errno = ENOMEM ; + goto err ; + } + uint32_pack(buf, keylen) ; + uint32_pack(buf + 4, datalen) ; + if (buffer_put(&c->b, buf, 8) < 0) goto err ; + return 0 ; +err: + cdb_make_free(c) ; + return -1 ; +} + +int cdb_make_add (struct cdb_make *c, char const *key, unsigned int keylen, char const *data, unsigned int datalen) +{ + if ((cdb_make_addbegin(c, keylen, datalen) < 0) + || (buffer_put(&c->b, key, keylen) < 0) + || (buffer_put(&c->b, data, datalen) < 0) + || (cdb_make_addend(c, keylen, datalen, cdb_hash(key, keylen)) < 0)) + return -1 ; + return 0 ; +} + +int cdb_make_finish (struct cdb_make *c) +{ + uint32 count[256] ; + uint32 start[256] ; + char final[2048] ; + unsigned int size = 1 ; + unsigned int n = genalloc_len(diuint32, &c->hplist) ; + register unsigned int i = 0 ; + register diuint32 *hp = genalloc_s(diuint32, &c->hplist) ; + + for ( ; i < 256 ; i++) count[i] = 0 ; + for (i = 0 ; i < n ; i++) ++count[hp[i].left & 255] ; + + { + register uint32 u = 0 ; + for (i = 0 ; i < 256 ; i++) start[i] = u += count[i] ; /* bounded by n */ + for (i = 0 ; i < 256 ; i++) + { + u = count[i] << 1 ; + if (u > size) size = u ; + } + size += n ; /* no overflow possible up to now */ + u = 0xffffffffUL ; u /= sizeof(diuint32) ; + if (size > u) return (errno = ENOMEM, -1) ; + } + i = n ; + { + diuint32 split[size] ; + while (i--) split[--start[hp[i].left & 255]] = hp[i] ; + genalloc_free(diuint32, &c->hplist) ; + hp = split + n ; + + for (i = 0 ; i < 256 ; ++i) + { + char buf[8] ; + register uint32 k = count[i] ; + register uint32 len = k << 1 ; /* no overflow possible */ + register diuint32 *p = split + start[i] ; + register unsigned int j = 0 ; + + uint32_pack(final + (i << 3), c->pos) ; + uint32_pack(final + (i << 3) + 4, len) ; + + for ( ; j < len ; j++) hp[j].left = hp[j].right = 0 ; + for (j = 0 ; j < k ; j++) + { + register uint32 where = (p->left >> 8) % len ; + while (hp[where].right) if (++where == len) where = 0 ; + hp[where] = *p++ ; + } + + for (j = 0 ; j < len ; j++) + { + uint32_pack(buf, hp[j].left) ; + uint32_pack(buf + 4, hp[j].right) ; + if (buffer_put(&c->b, buf, 8) < 0) goto err0 ; + if (!posplus(c, 8)) goto err0 ; + } + } + } + + if (!buffer_flush(&c->b)) goto err0 ; + if (seek_begin(c->fd) == -1) goto err0 ; + if (buffer_putflush(&c->b, final, 2048) < 0) goto err0 ; + cdb_make_free(c) ; + return 0 ; + +err0: + cdb_make_free(c) ; + return -1 ; +} diff --git a/src/libstddjb/cdb_mapfile.c b/src/libstddjb/cdb_mapfile.c new file mode 100644 index 0000000..f26ad3c --- /dev/null +++ b/src/libstddjb/cdb_mapfile.c @@ -0,0 +1,20 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/djbunix.h> +#include <skalibs/cdb.h> + +int cdb_mapfile (struct cdb *c, char const *file) +{ + int fd = open_readb(file) ; + if (fd < 0) return 0 ; + if (!cdb_init_map(c, fd, 1)) + { + register int e = errno ; + fd_close(fd) ; + errno = e ; + return 0 ; + } + fd_close(fd) ; + return 1 ; +} diff --git a/src/libstddjb/cdb_nextkey.c b/src/libstddjb/cdb_nextkey.c new file mode 100644 index 0000000..28925fe --- /dev/null +++ b/src/libstddjb/cdb_nextkey.c @@ -0,0 +1,23 @@ +/* ISC license. */ + +#include <skalibs/uint32.h> +#include <skalibs/cdb.h> + +int cdb_nextkey (struct cdb *c, uint32 *kpos) +{ + char buf[8] ; + uint32 eod, klen ; + if (cdb_read(c, buf, 4, 0) < 0) return -1 ; + uint32_unpack(buf, &eod) ; + if (eod < 8 || eod - 8 < *kpos) return 0 ; + c->kpos = *kpos + 8 ; + if (c->kpos < *kpos) return -1 ; /* wraparound */ + cdb_findstart(c) ; + c->hslots = 1 ; + if (cdb_read(c, buf, 8, *kpos) < 0) return -1 ; + uint32_unpack(buf, &klen) ; + uint32_unpack(buf + 4, &c->dlen) ; + c->dpos = c->kpos + klen ; + *kpos += 8 + klen + c->dlen ; + return 1 ; +} diff --git a/src/libstddjb/cdb_read.c b/src/libstddjb/cdb_read.c new file mode 100644 index 0000000..76fbd63 --- /dev/null +++ b/src/libstddjb/cdb_read.c @@ -0,0 +1,24 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/error.h> +#include <skalibs/bytestr.h> +#include <skalibs/allreadwrite.h> +#include <skalibs/uint32.h> +#include <skalibs/djbunix.h> +#include <skalibs/cdb.h> + +int cdb_read (struct cdb *c, char *buf, unsigned int len, uint32 pos) +{ + if (c->map) + { + if ((pos > c->size) || (c->size - pos < len)) return (errno = EPROTO, -1) ; + byte_copy(buf, len, c->map + pos) ; + } + else + { + if (seek_set(c->fd, pos) < 0) return -1 ; + if (allread(c->fd, buf, len) < len) return -1 ; + } + return 0 ; +} diff --git a/src/libstddjb/cdb_successor.c b/src/libstddjb/cdb_successor.c new file mode 100644 index 0000000..5660692 --- /dev/null +++ b/src/libstddjb/cdb_successor.c @@ -0,0 +1,17 @@ +/* ISC license. */ + +#include <skalibs/uint32.h> +#include <skalibs/cdb.h> + +int cdb_successor (struct cdb *c, char const *key, unsigned int klen) +{ + uint32 kpos ; + if (key) + { + register int r = cdb_find(c, key, klen) ; + if (r < 1) return r ; + kpos = c->dpos + c->dlen ; + } + else cdb_traverse_init(c, &kpos) ; + return cdb_nextkey(c, &kpos) ; +} diff --git a/src/libstddjb/cdb_zero.c b/src/libstddjb/cdb_zero.c new file mode 100644 index 0000000..ce70444 --- /dev/null +++ b/src/libstddjb/cdb_zero.c @@ -0,0 +1,5 @@ +/* ISC license. */ + +#include <skalibs/cdb.h> + +struct cdb const cdb_zero = CDB_ZERO ; diff --git a/src/libstddjb/child_spawn.c b/src/libstddjb/child_spawn.c new file mode 100644 index 0000000..aa937fd --- /dev/null +++ b/src/libstddjb/child_spawn.c @@ -0,0 +1,228 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include <skalibs/sysdeps.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <sys/wait.h> +#include <unistd.h> +#include <errno.h> +#include <signal.h> +#include <skalibs/allreadwrite.h> +#include <skalibs/bytestr.h> +#include <skalibs/env.h> +#include <skalibs/djbunix.h> +#include <skalibs/uint.h> +#include <skalibs/webipc.h> + +#ifdef SKALIBS_HASPOSIXSPAWN + +#include <stdlib.h> +#include <spawn.h> +#include <skalibs/config.h> + +#else + +#include <skalibs/sig.h> +#include <skalibs/strerr2.h> + +#endif + +#define NOFDVAR "SKALIBS_CHILD_SPAWN_FDS" + + + /* + If n = 0 : child's stdin and stdout are the same as the parent's + If n = 1 : Unix socket between parent and child. + Additional canals, if needed, may be fd-passed through it. + If n >= 2 : pipes between parent and child. + Parent reads on even ones, writes on odd ones. + */ + +pid_t child_spawn (char const *prog, char const *const *argv, char const *const *envp, int *fds, unsigned int n) +{ +#ifdef SKALIBS_HASPOSIXSPAWN + posix_spawn_file_actions_t actions ; + posix_spawnattr_t attr ; +#endif + int p[n ? n : 1][2] ; + int syncpipe[2] ; + pid_t pid ; + int e ; + unsigned int m = sizeof(NOFDVAR) ; + unsigned int i ; + char modifs[m + 1 + n * UINT_FMT] ; + byte_copy(modifs, sizeof(NOFDVAR), NOFDVAR "=") ; + if (n == 1) + { + if (ipc_pair_b(p[0]) < 0) return 0 ; + } + else if (n >= 2) + { + for (i = 0 ; i < n ; i++) if (pipe(p[i]) < 0) { e = errno ; goto errp ; } + } + if (pipe(syncpipe) < 0) { e = errno ; goto errp ; } + if (coe(syncpipe[1]) < 0) { e = errno ; goto errsp ; } + for (i = 0 ; i < n ; i++) + if ((ndelay_on(p[i][i & 1]) < 0) || (coe(p[i][i & 1]) < 0)) + { + e = errno ; goto errsp ; + } + for (i = 2 ; i < n ; i++) + { + m += uint_fmt(modifs + m, p[i][!(i & 1)]) ; + if (i+1 < n) modifs[m++] = ',' ; + } + modifs[m++] = 0 ; + +#ifdef SKALIBS_HASPOSIXSPAWN + + e = posix_spawnattr_init(&attr) ; + if (e) goto errsp ; + { + sigset_t set ; + sigemptyset(&set) ; + e = posix_spawnattr_setsigmask(&attr, &set) ; + } + if (e) goto errattr ; + e = posix_spawn_file_actions_init(&actions) ; + if (e) goto errattr ; + e = posix_spawn_file_actions_addclose(&actions, syncpipe[0]) ; + if (e) goto erractions ; + switch (n) + { + case 0 : + break ; + case 1 : + e = posix_spawn_file_actions_adddup2(&actions, p[0][1], 1) ; + if (e) goto erractions ; + e = posix_spawn_file_actions_addclose(&actions, p[0][1]) ; + if (e) goto erractions ; + e = posix_spawn_file_actions_adddup2(&actions, 1, 0) ; + if (e) goto erractions ; + break ; + default : + e = posix_spawn_file_actions_adddup2(&actions, p[1][0], 0) ; + if (e) goto erractions ; + e = posix_spawn_file_actions_addclose(&actions, p[1][0]) ; + if (e) goto erractions ; + e = posix_spawn_file_actions_adddup2(&actions, p[0][1], 1) ; + if (e) goto erractions ; + e = posix_spawn_file_actions_addclose(&actions, p[0][1]) ; + if (e) goto erractions ; + break ; + } + { + int haspath = !!env_get("PATH") ; + unsigned int envlen = env_len(envp) ; + char const *newenv[envlen + 2] ; + if (!env_merge(newenv, envlen+2, envp, envlen, modifs, m)) goto errsp ; + if (!haspath && (setenv("PATH", SKALIBS_DEFAULTPATH, 0) < 0)) + { + e = errno ; goto erractions ; + } + e = posix_spawnp(&pid, prog, &actions, &attr, (char *const *)argv, (char *const *)newenv) ; + if (!haspath) unsetenv("PATH") ; + if (e) goto erractions ; + } + + posix_spawn_file_actions_destroy(&actions) ; + posix_spawnattr_destroy(&attr) ; + +#else + + pid = fork() ; + if (pid < 0) { e = errno ; goto errsp ; } + else if (!pid) + { + unsigned int len = str_len(PROG) ; + char name[len + 9] ; + byte_copy(name, len, PROG) ; + byte_copy(name + len, 9, " (child)") ; + PROG = name ; + fd_close(syncpipe[0]) ; + switch (n) + { + case 0 : + { + int fd = open2("/dev/null", O_RDONLY) ; + if (fd < 0) goto syncdie ; + if (fd_move(0, fd) < 0) goto syncdie ; + fd = open2("/dev/null", O_WRONLY) ; + if (fd < 0) goto syncdie ; + if (fd_move(1, fd) < 0) goto syncdie ; + break ; + } + case 1 : + if (fd_move(1, p[0][1]) < 0) goto syncdie ; + if (fd_copy(0, 1) < 0) goto syncdie ; + break ; + default : + if (fd_move2(0, p[1][0], 1, p[0][1]) < 0) goto syncdie ; + break ; + } + sig_blocknone() ; + pathexec_r_name(prog, argv, envp, env_len(envp), modifs, m) ; + + syncdie: + { + char c = errno ; + fd_write(syncpipe[1], &c, 1) ; + } + _exit(127) ; + } + +#endif + + fd_close(syncpipe[1]) ; + { + char c ; + syncpipe[1] = fd_read(syncpipe[0], &c, 1) ; + if (syncpipe[1]) + { + if (syncpipe[1] < 0) e = errno ; + else + { + kill(pid, SIGKILL) ; + e = c ; + } + wait_pid(pid, &syncpipe[1]) ; + goto errsp0 ; + } + } + if (waitpid_nointr(pid, &e, WNOHANG)) + { + e = WEXITSTATUS(e) == 127 ? EIO : 0 ; + goto errsp0 ; + } + + fd_close(syncpipe[0]) ; + for (i = n ; i ; i--) + { + fd_close(p[i-1][i & 1]) ; + fds[i-1] = p[i-1][!(i & 1)] ; + } + return pid ; + +#ifdef SKALIBS_HASPOSIXSPAWN + erractions: + posix_spawn_file_actions_destroy(&actions) ; + errattr: + posix_spawnattr_destroy(&attr) ; +#endif + errsp: + fd_close(syncpipe[1]) ; + errsp0: + fd_close(syncpipe[0]) ; + i = n ; + errp: + while (i--) + { + fd_close(p[i][1]) ; + fd_close(p[i][0]) ; + } + errno = e ; + return 0 ; +} diff --git a/src/libstddjb/child_spawn0.c b/src/libstddjb/child_spawn0.c new file mode 100644 index 0000000..b96b2ef --- /dev/null +++ b/src/libstddjb/child_spawn0.c @@ -0,0 +1,73 @@ +/* ISC license. */ + +#include <skalibs/sysdeps.h> +#include <sys/types.h> +#include <errno.h> + +#ifdef SKALIBS_HASPOSIXSPAWN + +#include <spawn.h> +#include <stdlib.h> +#include <skalibs/config.h> +#include <skalibs/env.h> + +pid_t child_spawn0 (char const *prog, char const *const *argv, char const *const *envp) +{ + pid_t pid ; + int e ; + int haspath = !!env_get("PATH") ; + if (!haspath && (setenv("PATH", SKALIBS_DEFAULTPATH, 0) < 0)) return 0 ; + e = posix_spawnp(&pid, prog, 0, 0, (char *const *)argv, (char *const *)envp) ; + if (!haspath) unsetenv("PATH") ; + return e ? (errno = e, 0) : pid ; +} + +#else + +#include <unistd.h> +#include <skalibs/allreadwrite.h> +#include <skalibs/djbunix.h> + +pid_t child_spawn0 (char const *prog, char const *const *argv, char const *const *envp) +{ + int e ; + int p[2] ; + pid_t pid ; + if (pipecoe(p) < 0) return 0 ; + pid = fork() ; + if (pid < 0) + { + e = errno ; + fd_close(p[1]) ; + fd_close(p[0]) ; + errno = e ; + return 0 ; + } + if (pid) + { + fd_close(p[0]) ; + pathexec_run(prog, argv, envp) ; + e = errno ; + fd_write(p[1], (char *)&e, sizeof(e)) ; + _exit(127) ; + } + fd_close(p[1]) ; + p[1] = fd_read(p[0], (char *)&e, sizeof(e)) ; + if (p[1] < 0) + { + e = errno ; + fd_close(p[0]) ; + errno = e ; + return 0 ; + } + fd_close(p[0]) ; + if (p[1] == sizeof(e)) + { + wait_pid(pid, &p[0]) ; + errno = e ; + return 0 ; + } + return pid ; +} + +#endif diff --git a/src/libstddjb/child_spawn1.c b/src/libstddjb/child_spawn1.c new file mode 100644 index 0000000..bb51ab9 --- /dev/null +++ b/src/libstddjb/child_spawn1.c @@ -0,0 +1,115 @@ +/* ISC license. */ + +#include <skalibs/sysdeps.h> +#include <sys/types.h> +#include <unistd.h> +#include <errno.h> +#include <skalibs/djbunix.h> + +#ifdef SKALIBS_HASPOSIXSPAWN + +#include <spawn.h> +#include <stdlib.h> +#include <skalibs/config.h> +#include <skalibs/env.h> + +pid_t child_spawn1 (char const *prog, char const *const *argv, char const *const *envp, int *fd, int to) +{ + posix_spawn_file_actions_t actions ; + int e ; + int p[2] ; + pid_t pid ; + int haspath = !!env_get("PATH") ; + if (pipe(p) < 0) return 0 ; + to = !!to ; + e = posix_spawn_file_actions_init(&actions) ; + if (e) goto err ; + e = posix_spawn_file_actions_addclose(&actions, p[!to]) ; + if (e) goto erractions ; + e = posix_spawn_file_actions_adddup2(&actions, p[to], to) ; + if (e) goto erractions ; + if (!haspath && (setenv("PATH", SKALIBS_DEFAULTPATH, 0) < 0)) { e = errno ; goto erractions ; } + e = posix_spawnp(&pid, prog, &actions, 0, (char *const *)argv, (char *const *)envp) ; + if (!haspath) unsetenv("PATH") ; + posix_spawn_file_actions_destroy(&actions) ; + fd_close(p[to]) ; + if (e) goto errp ; + *fd = p[!to] ; + return pid ; + + erractions: + posix_spawn_file_actions_destroy(&actions) ; + err: + fd_close(p[to]) ; + errp: + fd_close(p[!to]) ; + errno = e ; + return 0 ; +} + +#else + +#include <skalibs/allreadwrite.h> + +pid_t child_spawn1 (char const *prog, char const *const *argv, char const *const *envp, int *fd, int to) +{ + int e ; + int syncp[2] ; + int p[2] ; + pid_t pid ; + if (pipe(p) < 0) return 0 ; + if (pipecoe(syncp) < 0) + { + e = errno ; + fd_close(p[1]) ; + fd_close(p[0]) ; + errno = e ; + return 0 ; + } + to = !!to ; + pid = fork() ; + if (pid < 0) + { + e = errno ; + fd_close(syncp[1]) ; + fd_close(syncp[0]) ; + fd_close(p[1]) ; + fd_close(p[0]) ; + errno = e ; + return 0 ; + } + if (pid) + { + fd_close(syncp[0]) ; + fd_close(p[!to]) ; + if (fd_move(to, p[to]) < 0) goto err ; + pathexec_run(prog, argv, envp) ; +err: + e = errno ; + fd_write(syncp[1], (char *)&e, sizeof(e)) ; + _exit(127) ; + } + fd_close(syncp[1]) ; + fd_close(p[to]) ; + syncp[1] = fd_read(syncp[0], (char *)&e, sizeof(e)) ; + if (syncp[1] < 0) + { + e = errno ; + fd_close(syncp[0]) ; + fd_close(p[!to]) ; + errno = e ; + return 0 ; + } + fd_close(syncp[0]) ; + if (syncp[1] == sizeof(e)) + { + fd_close(p[!to]) ; + wait_pid(pid, &syncp[1]) ; + errno = e ; + return 0 ; + } + *fd = p[!to] ; + return pid ; +} + +#endif diff --git a/src/libstddjb/coe.c b/src/libstddjb/coe.c new file mode 100644 index 0000000..a12f9cb --- /dev/null +++ b/src/libstddjb/coe.c @@ -0,0 +1,11 @@ +/* ISC license. */ + +#include <fcntl.h> +#include <skalibs/djbunix.h> + +int coe (int fd) +{ + register int flags = fcntl(fd, F_GETFD, 0) ; + if (flags < 0) return -1 ; + return fcntl(fd, F_SETFD, flags | FD_CLOEXEC) ; +} diff --git a/src/libstddjb/deepsleepuntil.c b/src/libstddjb/deepsleepuntil.c new file mode 100644 index 0000000..77ac080 --- /dev/null +++ b/src/libstddjb/deepsleepuntil.c @@ -0,0 +1,10 @@ +/* ISC license. */ + +#include <skalibs/tai.h> +#include <skalibs/iopause.h> + +void deepsleepuntil (tain_t const *deadline, tain_t *stamp) +{ + iopause_fd x ; + while (tain_less(stamp, deadline)) iopause_stamp(&x, 0, deadline, stamp) ; +} diff --git a/src/libstddjb/dir_close.c b/src/libstddjb/dir_close.c new file mode 100644 index 0000000..0af6f0e --- /dev/null +++ b/src/libstddjb/dir_close.c @@ -0,0 +1,14 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/direntry.h> + +int dir_close (DIR *dir) +{ + register unsigned int done = 0 ; +doit: + done++ ; + if (!closedir(dir)) return 0 ; + if (errno == EINTR) goto doit ; + return ((errno == EBADF) && (done > 1)) ? 0 : -1 ; +} diff --git a/src/libstddjb/dirname.c b/src/libstddjb/dirname.c new file mode 100644 index 0000000..1def443 --- /dev/null +++ b/src/libstddjb/dirname.c @@ -0,0 +1,19 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include <skalibs/bytestr.h> +#include <skalibs/stralloc.h> +#include <skalibs/djbunix.h> + +char *dirname (char *s) +{ + static stralloc dirname_sa = STRALLOC_ZERO ; + static char dot0[2] = "." ; + char *dot = dot0 ; + if (!s) return dot ; + dirname_sa.len = 0 ; + if (!sadirname(&dirname_sa, s, str_len(s))) return 0 ; + if (!stralloc_0(&dirname_sa)) return 0 ; + return dirname_sa.s ; +} diff --git a/src/libstddjb/djbtime-internal.h b/src/libstddjb/djbtime-internal.h new file mode 100644 index 0000000..26ffc81 --- /dev/null +++ b/src/libstddjb/djbtime-internal.h @@ -0,0 +1,23 @@ +/* ISC license. */ + +#ifndef DJBTIME_INTERNAL_H +#define DJBTIME_INTERNAL_H + +#include <skalibs/uint64.h> + + +/* Leap second handling, for UTC <--> TAI conversions */ + +#define LEAPSECS_MAX 39 +#define LEAPSECS_FILE SKALIBS_ETC "/leapsecs.dat" +extern uint64 *leapsecs_here ; + +extern int leapsecs_init_r (char const *, uint64 *) ; +#define leapsecs_init() leapsecs_init_r(LEAPSECS_FILE, leapsecs_here) +extern int leapsecs_add_r (uint64 *, char const *, uint64 *, int) ; +#define leapsecs_add(t, h) leapsecs_add_r(t, LEAPSECS_FILE, leapsecs_here, h) +extern int leapsecs_sub_r (uint64 *, char const *, uint64 *) ; +#define leapsecs_sub(t) leapsecs_sub_r((t), LEAPSECS_FILE, leapsecs_here) + + +#endif diff --git a/src/libstddjb/doublefork.c b/src/libstddjb/doublefork.c new file mode 100644 index 0000000..5a1f7b1 --- /dev/null +++ b/src/libstddjb/doublefork.c @@ -0,0 +1,53 @@ +/* ISC license. */ + +#include <sys/types.h> +#include <sys/wait.h> +#include <unistd.h> +#include <errno.h> +#include <skalibs/uint64.h> +#include <skalibs/allreadwrite.h> +#include <skalibs/djbunix.h> + +pid_t doublefork () +{ + char pack[8] ; + int fd[2] ; + pid_t child ; + if (pipe(fd) == -1) return -1 ; + child = fork() ; + switch (child) + { + case -1: + { + register int e = errno ; + fd_close(fd[1]) ; + fd_close(fd[0]) ; + errno = e ; + return -1 ; + } + case 0: + { + pid_t pid ; + fd_close(fd[0]) ; + pid = fork() ; + switch (pid) + { + case -1: _exit(errno) ; + case 0: fd_close(fd[1]) ; return 0 ; + } + uint64_pack_big(pack, (uint64)pid) ; + _exit((allwrite(fd[1], pack, 8) < 8) ? errno : 0) ; + } + } + fd_close(fd[1]) ; + { + uint64 grandchild = 0 ; + int wstat ; + if (allread(fd[0], pack, 8) < 8) grandchild = 1 ; + fd_close(fd[0]) ; + wait_pid(child, &wstat) ; + if (grandchild) return (errno = WIFSIGNALED(wstat) ? EINTR : WEXITSTATUS(wstat), -1) ; + uint64_unpack_big(pack, &grandchild) ; + return (pid_t)grandchild ; + } +} diff --git a/src/libstddjb/env_addmodif.c b/src/libstddjb/env_addmodif.c new file mode 100644 index 0000000..4c34479 --- /dev/null +++ b/src/libstddjb/env_addmodif.c @@ -0,0 +1,18 @@ +/* ISC license. */ + +#include <skalibs/stralloc.h> +#include <skalibs/env.h> + +int env_addmodif (stralloc *sa, char const *s, char const *t) +{ + unsigned int oldlen = sa->len ; + if (!s) return 1 ; + if (!stralloc_cats(sa, s)) return 0 ; + if ((t && (!stralloc_catb(sa, "=", 1) || !stralloc_cats(sa, t))) + || !stralloc_0(sa)) + { + sa->len = oldlen ; + return 0 ; + } + return 1 ; +} diff --git a/src/libstddjb/env_get.c b/src/libstddjb/env_get.c new file mode 100644 index 0000000..927955f --- /dev/null +++ b/src/libstddjb/env_get.c @@ -0,0 +1,9 @@ +/* ISC license. */ + +#include <skalibs/env.h> +#include <skalibs/environ.h> + +char const *env_get (char const *s) +{ + return env_get2((char const **)environ, s) ; +} diff --git a/src/libstddjb/env_get2.c b/src/libstddjb/env_get2.c new file mode 100644 index 0000000..612cf6a --- /dev/null +++ b/src/libstddjb/env_get2.c @@ -0,0 +1,18 @@ +/* ISC license. */ + +#include <skalibs/bytestr.h> +#include <skalibs/env.h> + +char const *env_get2 (char const *const *envp, char const *s) +{ + unsigned int i ; + unsigned int len ; + + if (!s) return 0 ; + len = str_len(s) ; + for (i = 0 ; envp[i] ; ++i) + if (str_start(envp[i], s) + && (envp[i][len] == '=')) + return envp[i] + len + 1 ; + return 0 ; +} diff --git a/src/libstddjb/env_len.c b/src/libstddjb/env_len.c new file mode 100644 index 0000000..7e0bea8 --- /dev/null +++ b/src/libstddjb/env_len.c @@ -0,0 +1,10 @@ +/* ISC license. */ + +#include <skalibs/env.h> + +unsigned int env_len (register char const *const *e) +{ + register unsigned int i = 0 ; + while (*e++) i++ ; + return i ; +} diff --git a/src/libstddjb/env_make.c b/src/libstddjb/env_make.c new file mode 100644 index 0000000..dd5139f --- /dev/null +++ b/src/libstddjb/env_make.c @@ -0,0 +1,16 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/bytestr.h> +#include <skalibs/env.h> + +int env_make (char const **v, unsigned int argc, char const *s, unsigned int len) +{ + while (argc--) + { + register unsigned int n = str_len(s) + 1 ; + if (n > len) return (errno = EINVAL, 0) ; + *v++ = s ; s += n ; len -= n ; + } + return 1 ; +} diff --git a/src/libstddjb/env_merge.c b/src/libstddjb/env_merge.c new file mode 100644 index 0000000..2a0e5bd --- /dev/null +++ b/src/libstddjb/env_merge.c @@ -0,0 +1,25 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/bytestr.h> +#include <skalibs/env.h> + +unsigned int env_merge (char const **v, unsigned int vmax, char const *const *envp, unsigned int envlen, char const *modifs, unsigned int modiflen) +{ + unsigned int n = byte_count(modifs, modiflen, '\0') ; + unsigned int vlen = envlen ; + register unsigned int i = 0 ; + if (envlen + n + 1 > vmax) return (errno = ENAMETOOLONG, 0) ; + for (; i < envlen ; i++) v[i] = envp[i] ; + for (i = 0 ; i < modiflen ; i += str_len(modifs + i) + 1) + { + unsigned int split = str_chr(modifs + i, '=') ; + register unsigned int j = 0 ; + for (; j < vlen ; j++) + if (!byte_diff(modifs + i, split, v[j]) && (v[j][split] == '=')) break ; + if (j < vlen) v[j] = v[--vlen] ; + if (modifs[i + split]) v[vlen++] = modifs + i ; + } + v[vlen++] = 0 ; + return vlen ; +} diff --git a/src/libstddjb/env_string.c b/src/libstddjb/env_string.c new file mode 100644 index 0000000..7f97859 --- /dev/null +++ b/src/libstddjb/env_string.c @@ -0,0 +1,19 @@ +/* ISC license. */ + +#include <skalibs/stralloc.h> +#include <skalibs/env.h> + +int env_string (stralloc *sa, char const *const *envp, unsigned int envlen) +{ + unsigned int salen = sa->len ; + register unsigned int i = 0 ; + for (; i < envlen ; i++) + { + if (!stralloc_cats(sa, envp[i]) || !stralloc_0(sa)) + { + sa->len = salen ; + return 0 ; + } + } + return 1 ; +} diff --git a/src/libstddjb/envalloc_0.c b/src/libstddjb/envalloc_0.c new file mode 100644 index 0000000..114f69e --- /dev/null +++ b/src/libstddjb/envalloc_0.c @@ -0,0 +1,10 @@ +/* ISC license. */ + +#include <skalibs/genalloc.h> +#include <skalibs/envalloc.h> + +int envalloc_0 (genalloc *v) +{ + char const *z = 0 ; + return genalloc_append(char const *, v, &z) ; +} diff --git a/src/libstddjb/envalloc_make.c b/src/libstddjb/envalloc_make.c new file mode 100644 index 0000000..1cc44b9 --- /dev/null +++ b/src/libstddjb/envalloc_make.c @@ -0,0 +1,18 @@ +/* ISC license. */ + +#include <skalibs/env.h> +#include <skalibs/genalloc.h> +#include <skalibs/envalloc.h> + +int envalloc_make (genalloc *v, unsigned int argc, char const *s, unsigned int len) +{ + int wasnull = !v->s ; + if (!genalloc_readyplus(char const *, v, argc+1)) return 0 ; + if (!env_make(genalloc_s(char const *, v) + genalloc_len(char const *, v), argc, s, len)) + { + if (wasnull) genalloc_free(char const *, v) ; + return 0 ; + } + genalloc_setlen(char const *, v, genalloc_len(char const *, v) + argc) ; + return 1 ; +} diff --git a/src/libstddjb/envalloc_merge.c b/src/libstddjb/envalloc_merge.c new file mode 100644 index 0000000..9134b84 --- /dev/null +++ b/src/libstddjb/envalloc_merge.c @@ -0,0 +1,15 @@ +/* ISC license. */ + +#include <skalibs/bytestr.h> +#include <skalibs/env.h> +#include <skalibs/genalloc.h> +#include <skalibs/envalloc.h> + +int envalloc_merge (genalloc *v, char const *const *envp, unsigned int envlen, char const *modifs, unsigned int modiflen) +{ + unsigned int n = envlen + 1 + byte_count(modifs, modiflen, '\0') ; + if (!genalloc_readyplus(char const *, v, n)) return 0 ; + n = env_merge(genalloc_s(char const *, v) + genalloc_len(char const *, v), n, envp, envlen, modifs, modiflen) ; + genalloc_setlen(char const *, v, genalloc_len(char const *, v) + n) ; + return 1 ; +} diff --git a/src/libstddjb/envalloc_uniq.c b/src/libstddjb/envalloc_uniq.c new file mode 100644 index 0000000..181128a --- /dev/null +++ b/src/libstddjb/envalloc_uniq.c @@ -0,0 +1,31 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/bytestr.h> +#include <skalibs/genalloc.h> +#include <skalibs/envalloc.h> + +int envalloc_uniq (genalloc *v, char delim) +{ + unsigned int m = 0 ; + register unsigned int i = 0 ; + for (; i < genalloc_len(char const *, v) ; i++) + { + register unsigned int j = i+1 ; + char const *s = genalloc_s(char const *, v)[i] ; + unsigned int n = str_chr(s, delim) ; + if (delim && !s[n]) return (errno = EINVAL, -1) ; + for (; j < genalloc_len(char const *, v) ; j++) + { + register char const **p = genalloc_s(char const *, v) ; + if (!str_diffn(s, p[j], n)) + { + register unsigned int len = genalloc_len(char const *, v) - 1 ; + genalloc_setlen(char const *, v, len) ; + p[j] = p[len] ; + m++ ; + } + } + } + return (int)m ; +} diff --git a/src/libstddjb/envdir.c b/src/libstddjb/envdir.c new file mode 100644 index 0000000..7866c7a --- /dev/null +++ b/src/libstddjb/envdir.c @@ -0,0 +1,84 @@ +/* ISC license. */ + +#include <unistd.h> +#include <errno.h> +#include <skalibs/bytestr.h> +#include <skalibs/env.h> +#include <skalibs/direntry.h> +#include <skalibs/stralloc.h> +#include <skalibs/djbunix.h> + +#define MAXVARSIZE 4095 + +int envdir_internal (char const *path, stralloc *modifs, unsigned int options, char nullis) +{ + char buf[MAXVARSIZE + 1] ; + unsigned int n = 0 ; + unsigned int pathlen = str_len(path) ; + unsigned int modifbase = modifs->len ; + int wasnull = !modifs->s ; + DIR *dir ; + if (!nullis) return (errno = EINVAL, -1) ; + dir = opendir(path) ; + if (!dir) return -1 ; + for (;;) + { + direntry *d ; + unsigned int len ; + register int r ; + errno = 0 ; + d = readdir(dir) ; + if (!d) break ; + if (d->d_name[0] == '.') continue ; + len = str_len(d->d_name) ; + if (str_chr(d->d_name, '=') < len) continue ; + { + char tmp[pathlen + len + 2] ; + byte_copy(tmp, pathlen, path) ; + tmp[pathlen] = '/' ; + byte_copy(tmp + pathlen + 1, len + 1, d->d_name) ; + r = openreadnclose(tmp, buf, MAXVARSIZE) ; + } + if (r < 0) + { + if (errno == ENOENT) errno = EIDRM ; + goto err ; + } + else if (r > 0) + { + if (options & SKALIBS_ENVDIR_VERBATIM) + { + if (!(options & SKALIBS_ENVDIR_NOCHOMP) && (buf[r-1] == '\n')) r-- ; + } + else + { + r = byte_chr(buf, r, '\n') ; + if (!(options & SKALIBS_ENVDIR_NOCHOMP)) + { + while (r--) if ((buf[r] != ' ') && (buf[r] != '\t') && (buf[r] != '\r')) break ; + r++ ; + } + } + { + register unsigned int i = 0 ; + for (; i < (unsigned int)r ; i++) if (!buf[i]) buf[i] = nullis ; + } + buf[r++] = 0 ; + if (!env_addmodif(modifs, d->d_name, buf)) goto err ; + } + else if (!env_addmodif(modifs, d->d_name, 0)) goto err ; + n++ ; + } + if (errno) goto err ; + dir_close(dir) ; + return n ; + + err: + { + register int e = errno ; + dir_close(dir) ; + if (wasnull) stralloc_free(modifs) ; else modifs->len = modifbase ; + errno = e ; + return -1 ; + } +} diff --git a/src/libstddjb/error_str.c b/src/libstddjb/error_str.c new file mode 100644 index 0000000..6aca43f --- /dev/null +++ b/src/libstddjb/error_str.c @@ -0,0 +1,277 @@ +/* ISC license. */ + +#include <skalibs/config.h> +#include <skalibs/error.h> + +#ifndef SKALIBS_FLAG_REPLACE_LIBC + +#include <string.h> + +char const *error_str (register int i) +{ + return (char const *)strerror(i) ; +} + +#else + +#include <errno.h> + +#define X(e, s) case e : return s ; +#define Y(e, s) if (i == e) return s ; + +char const *error_str (register int i) +{ + Y(EWOULDBLOCK, "input/output would block") + Y(EAGAIN, "temporary failure") + Y(EINVAL, "invalid argument") + + switch (i) + { + X(0, "no error") + X(EINTR, "interrupted system call") + X(ENOMEM, "out of memory") + X(ENOENT, "file does not exist") + X(ETXTBSY, "text busy") + X(EIO, "input/output error") + X(EEXIST, "file already exists") + X(ETIMEDOUT, "timed out") + X(EINPROGRESS, "operation in progress") + X(EPIPE, "broken pipe") + X(EPERM, "permission denied") + X(EACCES, "access denied") + X(ENODEV, "device not configured") + X(EPROTO, "protocol error") + X(EISDIR, "is a directory") + X(ECONNREFUSED, "connection refused") + X(ENOTDIR, "not a directory") + X(ENOTSOCK, "not a socket") + X(EDOM, "input out of range") + X(ENOBUFS, "out of buffer space") + +#ifdef ESRCH + X(ESRCH, "no such process") +#endif +#ifdef E2BIG + X(E2BIG, "argument list too long") +#endif +#ifdef ENOEXEC + X(ENOEXEC, "exec format error") +#endif +#ifdef EBADF + X(EBADF, "file descriptor not open") +#endif +#ifdef ECHILD + X(ECHILD, "no child processes") +#endif +#ifdef EDEADLK + X(EDEADLK, "operation would cause deadlock") +#endif +#ifdef EFAULT + X(EFAULT, "bad address") +#endif +#ifdef ENOTBLK + X(ENOTBLK, "not a block device") +#endif +#ifdef EBUSY + X(EBUSY, "device busy") +#endif +#ifdef EXDEV + X(EXDEV, "cross-device link") +#endif +#ifdef ENFILE + X(ENFILE, "system cannot open more files") +#endif +#ifdef EMFILE + X(EMFILE, "process cannot open more files") +#endif +#ifdef ENOTTY + X(ENOTTY, "not a tty") +#endif +#ifdef EFBIG + X(EFBIG, "file too big") +#endif +#ifdef ENOSPC + X(ENOSPC, "out of disk space") +#endif +#ifdef ESPIPE + X(ESPIPE, "unseekable descriptor") +#endif +#ifdef EROFS + X(EROFS, "read-only file system") +#endif +#ifdef EMLINK + X(EMLINK, "too many links") +#endif +#ifdef ERANGE + X(ERANGE, "output out of range") +#endif +#ifdef EALREADY + X(EALREADY, "operation already in progress") +#endif +#ifdef EDESTADDRREQ + X(EDESTADDRREQ, "destination address required") +#endif +#ifdef EMSGSIZE + X(EMSGSIZE, "message too long") +#endif +#ifdef EPROTOTYPE + X(EPROTOTYPE, "incorrect protocol type") +#endif +#ifdef ENOPROTOOPT + X(ENOPROTOOPT, "protocol not available") +#endif +#ifdef EPROTONOSUPPORT + X(EPROTONOSUPPORT, "protocol not supported") +#endif +#ifdef ESOCKTNOSUPPORT + X(ESOCKTNOSUPPORT, "socket type not supported") +#endif +#ifdef EOPNOTSUPP + X(EOPNOTSUPP, "operation not supported") +#endif +#ifdef EPFNOSUPPORT + X(EPFNOSUPPORT, "protocol family not supported") +#endif +#ifdef EAFNOSUPPORT + X(EAFNOSUPPORT, "address family not supported") +#endif +#ifdef EADDRINUSE + X(EADDRINUSE, "address already used") +#endif +#ifdef EADDRNOTAVAIL + X(EADDRNOTAVAIL, "address not available") +#endif +#ifdef ENETDOWN + X(ENETDOWN, "network down") +#endif +#ifdef ENETUNREACH + X(ENETUNREACH, "network unreachable") +#endif +#ifdef ENETRESET + X(ENETRESET, "network reset") +#endif +#ifdef ECONNABORTED + X(ECONNABORTED, "connection aborted") +#endif +#ifdef ECONNRESET + X(ECONNRESET, "connection reset") +#endif +#ifdef EISCONN + X(EISCONN, "already connected") +#endif +#ifdef ENOTCONN + X(ENOTCONN, "not connected") +#endif +#ifdef ESHUTDOWN + X(ESHUTDOWN, "socket shut down") +#endif +#ifdef ETOOMANYREFS + X(ETOOMANYREFS, "too many references") +#endif +#ifdef ELOOP + X(ELOOP, "symbolic link loop") +#endif +#ifdef ENAMETOOLONG + X(ENAMETOOLONG, "file name too long") +#endif +#ifdef EHOSTDOWN + X(EHOSTDOWN, "host down") +#endif +#ifdef EHOSTUNREACH + X(EHOSTUNREACH, "host unreachable") +#endif +#ifdef ENOTEMPTY + X(ENOTEMPTY, "directory not empty") +#endif +#ifdef EPROCLIM + X(EPROCLIM, "too many processes") +#endif +#ifdef EUSERS + X(EUSERS, "too many users") +#endif +#ifdef EDQUOT + X(EDQUOT, "disk quota exceeded") +#endif +#ifdef ESTALE + X(ESTALE, "stale NFS file handle") +#endif +#ifdef EREMOTE + X(EREMOTE, "too many levels of remote in path") +#endif +#ifdef EBADRPC + X(EBADRPC, "RPC structure is bad") +#endif +#ifdef ERPCMISMATCH + X(ERPCMISMATCH, "RPC version mismatch") +#endif +#ifdef EPROGUNAVAIL + X(EPROGUNAVAIL, "RPC program unavailable") +#endif +#ifdef EPROGMISMATCH + X(EPROGMISMATCH, "program version mismatch") +#endif +#ifdef EPROCUNAVAIL + X(EPROCUNAVAIL, "bad procedure for program") +#endif +#ifdef ENOLCK + X(ENOLCK, "no locks available") +#endif +#ifdef ENOSYS + X(ENOSYS, "system call not available") +#endif +#ifdef EFTYPE + X(EFTYPE, "bad file type") +#endif +#ifdef EAUTH + X(EAUTH, "authentication error") +#endif +#ifdef ENEEDAUTH + X(ENEEDAUTH, "not authenticated") +#endif +#ifdef ENOSTR + X(ENOSTR, "not a stream device") +#endif +#ifdef ETIME + X(ETIME, "timer expired") +#endif +#ifdef ENOSR + X(ENOSR, "out of stream resources") +#endif +#ifdef ENOMSG + X(ENOMSG, "no message of desired type") +#endif +#ifdef EBADMSG + X(EBADMSG, "bad message type") +#endif +#ifdef EIDRM + X(EIDRM, "identifier removed") +#endif +#ifdef ENONET + X(ENONET, "machine not on network") +#endif +#ifdef ERREMOTE + X(ERREMOTE, "object not local") +#endif +#ifdef ENOLINK + X(ENOLINK, "link severed") +#endif +#ifdef EADV + X(EADV, "advertise error") +#endif +#ifdef ESRMNT + X(ESRMNT, "srmount error") +#endif +#ifdef ECOMM + X(ECOMM, "communication error") +#endif +#ifdef EMULTIHOP + X(EMULTIHOP, "multihop attempted") +#endif +#ifdef EREMCHG + X(EREMCHG, "remote address changed") +#endif + default : return "unknown error" ; + } +} + +#endif diff --git a/src/libstddjb/error_temp.c b/src/libstddjb/error_temp.c new file mode 100644 index 0000000..48a54f5 --- /dev/null +++ b/src/libstddjb/error_temp.c @@ -0,0 +1,78 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/error.h> + +int error_temp (register int e) +{ + if (error_isagain(e)) return 1 ; + switch (e) + { + case 0 : + case EINTR : + case ENOMEM : + case ETXTBSY : + case EIO : + case ETIMEDOUT : + case ENOBUFS : +#ifdef EDEADLK + case EDEADLK : +#endif +#ifdef EBUSY + case EBUSY : +#endif +#ifdef ENFILE + case ENFILE : +#endif +#ifdef EFBIG + case EFBIG : +#endif +#ifdef ENOSPC + case ENOSPC : +#endif +#ifdef ENETDOWN + case ENETDOWN : +#endif +#ifdef ENETUNREACH + case ENETUNREACH : +#endif +#ifdef ENETRESET + case ENETRESET : +#endif +#ifdef ECONNABORTED + case ECONNABORTED : +#endif +#ifdef ECONNRESET + case ECONNRESET : +#endif +#ifdef ETOOMANYREFS + case ETOOMANYREFS : +#endif +#ifdef ECONNREFUSED + case ECONNREFUSED : +#endif +#ifdef EHOSTDOWN + case EHOSTDOWN : +#endif +#ifdef EHOSTUNREACH + case EHOSTUNREACH : +#endif +#ifdef EPROCLIM + case EPROCLIM : +#endif +#ifdef EUSERS + case EUSERS : +#endif +#ifdef EDQUOT + case EDQUOT : +#endif +#ifdef ESTALE + case ESTALE : +#endif +#ifdef ENOLCK + case ENOLCK : +#endif + return 1 ; + default : return 0 ; + } +} diff --git a/src/libstddjb/execvep.c b/src/libstddjb/execvep.c new file mode 100644 index 0000000..1639236 --- /dev/null +++ b/src/libstddjb/execvep.c @@ -0,0 +1,38 @@ +/* ISC license. */ + +#include <unistd.h> +#include <errno.h> +#include <skalibs/bytestr.h> +#include <skalibs/djbunix.h> + +void execvep (char const *file, char const *const *argv, char const *const *envp, char const *path) +{ + if (!path) errno = EINVAL ; + else if (file[str_chr(file, '/')]) + execve(file, (char *const *)argv, (char *const *)envp) ; /* execve prototype sucks */ + else + { + unsigned int pathlen = str_len(path) + 1 ; + unsigned int filelen = str_len(file) ; + int savederrno = 0 ; + while (pathlen) + { + unsigned int split = byte_chr(path, pathlen - 1, ':') ; + if (split) + { + char tmp[split + 2 + filelen] ; + byte_copy(tmp, split, path) ; + tmp[split] = '/' ; + byte_copy(tmp + split + 1, filelen + 1, file) ; + execve(tmp, (char *const *)argv, (char *const *)envp) ; + if (errno != ENOENT) + { + savederrno = errno ; + if ((errno != EACCES) && (errno != EPERM) && (errno != EISDIR)) break ; + } + } + path += split+1 ; pathlen -= split+1 ; + } + if (savederrno) errno = savederrno ; + } +} diff --git a/src/libstddjb/fd_cat.c b/src/libstddjb/fd_cat.c new file mode 100644 index 0000000..5682f02 --- /dev/null +++ b/src/libstddjb/fd_cat.c @@ -0,0 +1,25 @@ +/* ISC license. */ + +#include <skalibs/iobuffer.h> +#include <skalibs/djbunix.h> + +int fd_cat (int from, int to) +{ + iobuffer b ; + unsigned int n = 0 ; + if (!iobuffer_init(&b, from, to)) return -1 ; + for (;;) + { + register int r = iobuffer_fill(&b) ; + if (r < 0) goto err ; + else if (!r) break ; + if (!iobuffer_flush(&b)) goto err ; + n += r ; + } + iobuffer_finish(&b) ; + return n ; + + err: + iobuffer_finish(&b) ; + return -1 ; +} diff --git a/src/libstddjb/fd_catn.c b/src/libstddjb/fd_catn.c new file mode 100644 index 0000000..ca78546 --- /dev/null +++ b/src/libstddjb/fd_catn.c @@ -0,0 +1,42 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/allreadwrite.h> +#include <skalibs/iobuffer.h> +#include <skalibs/djbunix.h> + +unsigned int fd_catn (int from, int to, unsigned int n) +{ + unsigned int w = 0 ; + if (n >= IOBUFFER_SIZE) + { + iobuffer b ; + if (!iobuffer_init(&b, from, to)) return 0 ; + while (n >= IOBUFFER_SIZE) + { + register int r = iobuffer_fill(&b) ; + if (r <= 0) + { + iobuffer_finish(&b) ; + if (!r) errno = EPIPE ; + return w ; + } + if (!iobuffer_flush(&b)) + { + iobuffer_finish(&b) ; + return w ; + } + n -= r ; w += r ; + } + iobuffer_finish(&b) ; + } + + { + char buf[n] ; + unsigned int r = allread(from, buf, n) ; + unsigned int v = 0 ; + if (r) v = allwrite(to, buf, r) ; + w += v ; + } + return w ; +} diff --git a/src/libstddjb/fd_chdir.c b/src/libstddjb/fd_chdir.c new file mode 100644 index 0000000..e09656e --- /dev/null +++ b/src/libstddjb/fd_chdir.c @@ -0,0 +1,14 @@ +/* ISC license. */ + +#include <unistd.h> +#include <errno.h> +#include <skalibs/djbunix.h> + +int fd_chdir (int d) +{ + register int r ; + do + r = fchdir(d) ; + while ((r == -1) && (errno == EINTR)) ; + return r ; +} diff --git a/src/libstddjb/fd_chmod.c b/src/libstddjb/fd_chmod.c new file mode 100644 index 0000000..a70c537 --- /dev/null +++ b/src/libstddjb/fd_chmod.c @@ -0,0 +1,17 @@ +/* ISC license. */ + + /* OpenBSD manages to bork the fchmod declaration */ +#include <skalibs/nonposix.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <errno.h> +#include <skalibs/djbunix.h> + +int fd_chmod (int fd, unsigned int mode) +{ + register int r ; + do + r = fchmod(fd, (mode_t)mode) ; + while ((r == -1) && (errno == EINTR)) ; + return r ; +} diff --git a/src/libstddjb/fd_chown.c b/src/libstddjb/fd_chown.c new file mode 100644 index 0000000..8aa36c8 --- /dev/null +++ b/src/libstddjb/fd_chown.c @@ -0,0 +1,15 @@ +/* ISC license. */ + +#include <sys/types.h> +#include <unistd.h> +#include <errno.h> +#include <skalibs/djbunix.h> + +int fd_chown (int fd, unsigned int uid, unsigned int gid) +{ + register int r ; + do + r = fchown(fd, (uid_t)uid, (gid_t)gid) ; + while ((r == -1) && (errno == EINTR)) ; + return r ; +} diff --git a/src/libstddjb/fd_close.c b/src/libstddjb/fd_close.c new file mode 100644 index 0000000..8b107f6 --- /dev/null +++ b/src/libstddjb/fd_close.c @@ -0,0 +1,15 @@ +/* ISC license. */ + +#include <unistd.h> +#include <errno.h> +#include <skalibs/djbunix.h> + +int fd_close (int fd) +{ + register unsigned int i = 0 ; +doit: + if (!close(fd)) return 0 ; + i++ ; + if (errno == EINTR) goto doit ; + return ((errno == EBADF) && (i > 1)) ? 0 : -1 ; +} diff --git a/src/libstddjb/fd_copy.c b/src/libstddjb/fd_copy.c new file mode 100644 index 0000000..b051eaf --- /dev/null +++ b/src/libstddjb/fd_copy.c @@ -0,0 +1,15 @@ +/* ISC license. */ + +#include <unistd.h> +#include <errno.h> +#include <skalibs/djbunix.h> + +int fd_copy (int to, int from) +{ + register int r ; + if (to == from) return (errno = EINVAL, -1) ; + do + r = dup2(from, to) ; + while ((r == -1) && (errno == EINTR)) ; + return r ; +} diff --git a/src/libstddjb/fd_copy2.c b/src/libstddjb/fd_copy2.c new file mode 100644 index 0000000..5537329 --- /dev/null +++ b/src/libstddjb/fd_copy2.c @@ -0,0 +1,17 @@ +/* ISC license. */ + +#include <unistd.h> +#include <errno.h> +#include <skalibs/djbunix.h> + +int fd_copy2 (int to1, int from1, int to2, int from2) +{ + if ((to1 == from2) || (to2 == from1)) return (errno = EINVAL, -1) ; + if (fd_copy(to1, from1) == -1) return -1 ; + if (fd_copy(to2, from2) == -1) + { + if (to1 != from1) fd_close(to1) ; + return -1 ; + } + return 0 ; +} diff --git a/src/libstddjb/fd_ensure_open.c b/src/libstddjb/fd_ensure_open.c new file mode 100644 index 0000000..b399af2 --- /dev/null +++ b/src/libstddjb/fd_ensure_open.c @@ -0,0 +1,25 @@ +/* ISC license. */ + +#include <errno.h> +#include <fcntl.h> +#include <skalibs/djbunix.h> + +int fd_ensure_open (int fd, int w) +{ + int dummy ; + if (fcntl(fd, F_GETFD, &dummy) < 0) + { + int newfd ; + if (errno != EBADF) return 0 ; + newfd = open2("/dev/null", w ? O_WRONLY : O_RDONLY) ; + if (newfd < 0) return 0 ; + if (fd_move(fd, newfd) < 0) + { + register int e = errno ; + fd_close(newfd) ; + errno = e ; + return 0 ; + } + } + return 1 ; +} diff --git a/src/libstddjb/fd_move.c b/src/libstddjb/fd_move.c new file mode 100644 index 0000000..d79f8ac --- /dev/null +++ b/src/libstddjb/fd_move.c @@ -0,0 +1,15 @@ +/* ISC license. */ + +#include <unistd.h> +#include <errno.h> +#include <skalibs/djbunix.h> + +int fd_move (int to, int from) +{ + register int r ; + if (to == from) return 0 ; + do + r = dup2(from, to) ; + while ((r == -1) && (errno == EINTR)) ; + return (r == -1) ? -1 : fd_close(from) ; +} diff --git a/src/libstddjb/fd_move2.c b/src/libstddjb/fd_move2.c new file mode 100644 index 0000000..7894e2f --- /dev/null +++ b/src/libstddjb/fd_move2.c @@ -0,0 +1,37 @@ +/* ISC license. */ + +#include <unistd.h> +#include <errno.h> +#include <skalibs/djbunix.h> + +int fd_move2 (int to1, int from1, int to2, int from2) +{ + register int tmp = from2 ; + if (to1 == from1) return fd_move(to2, from2) ; + if (to2 == from2) return fd_move(to1, from1) ; + if (from1 == from2) return (to1 == to2) ? fd_move(to1, from1) : (errno = EINVAL, -1) ; + if (to1 == to2) return (errno = EINVAL, -1) ; + if (from2 == to1) + { + tmp = dup(from2) ; + if (tmp == -1) return -1 ; + } + if (fd_copy(to1, from1) == -1) + { + register int e = errno ; + if (from2 != tmp) fd_close(tmp) ; + errno = e ; + return -1 ; + } + if (fd_copy(to2, tmp) == -1) + { + register int e = errno ; + fd_close(to1) ; + if (from2 != tmp) fd_move(from2, tmp) ; + errno = e ; + return -1 ; + } + if (from1 != to2) fd_close(from1) ; + fd_close(tmp) ; + return 0 ; +} diff --git a/src/libstddjb/fd_read.c b/src/libstddjb/fd_read.c new file mode 100644 index 0000000..22a296b --- /dev/null +++ b/src/libstddjb/fd_read.c @@ -0,0 +1,13 @@ +/* ISC license. */ + +#include <unistd.h> +#include <errno.h> +#include <skalibs/allreadwrite.h> + +int fd_read (int fd, char *buf, unsigned int len) +{ + register int r ; + do r = read(fd, buf, len) ; + while ((r == -1) && (errno == EINTR)) ; + return r ; +} diff --git a/src/libstddjb/fd_readv.c b/src/libstddjb/fd_readv.c new file mode 100644 index 0000000..c97d7ab --- /dev/null +++ b/src/libstddjb/fd_readv.c @@ -0,0 +1,14 @@ +/* ISC license. */ + +#include <sys/types.h> +#include <sys/uio.h> +#include <errno.h> +#include <skalibs/allreadwrite.h> + +int fd_readv (int fd, struct iovec const *v, unsigned int vlen) +{ + register int r ; + do r = readv(fd, v, vlen) ; + while ((r == -1) && (errno == EINTR)) ; + return r ; +} diff --git a/src/libstddjb/fd_recv.c b/src/libstddjb/fd_recv.c new file mode 100644 index 0000000..592dc8e --- /dev/null +++ b/src/libstddjb/fd_recv.c @@ -0,0 +1,14 @@ +/* ISC license. */ + +#include <sys/types.h> +#include <sys/socket.h> +#include <errno.h> +#include <skalibs/allreadwrite.h> + +int fd_recv (int fd, char *buf, unsigned int len, unsigned int flags) +{ + register int r ; + do r = recv(fd, buf, len, (int)flags) ; + while ((r == -1) && (errno == EINTR)) ; + return r ; +} diff --git a/src/libstddjb/fd_select.c b/src/libstddjb/fd_select.c new file mode 100644 index 0000000..846485d --- /dev/null +++ b/src/libstddjb/fd_select.c @@ -0,0 +1,14 @@ +/* ISC license. */ + +#include <sys/types.h> +#include <errno.h> +#include <sys/select.h> + +int fd_select (int n, fd_set *rfds, fd_set *wfds, fd_set *xfds, struct timeval *tv) +{ + register int r ; + do + r = select(n, rfds, wfds, xfds, tv) ; + while ((r == -1) && (errno == EINTR)) ; + return r ; +} diff --git a/src/libstddjb/fd_send.c b/src/libstddjb/fd_send.c new file mode 100644 index 0000000..cdc3dd2 --- /dev/null +++ b/src/libstddjb/fd_send.c @@ -0,0 +1,14 @@ +/* ISC license. */ + +#include <sys/types.h> +#include <sys/socket.h> +#include <errno.h> +#include <skalibs/allreadwrite.h> + +int fd_send (int fd, char const *buf, unsigned int len, unsigned int flags) +{ + register int r ; + do r = send(fd, buf, len, (int)flags) ; + while ((r == -1) && (errno == EINTR)) ; + return r ; +} diff --git a/src/libstddjb/fd_sync.c b/src/libstddjb/fd_sync.c new file mode 100644 index 0000000..db54136 --- /dev/null +++ b/src/libstddjb/fd_sync.c @@ -0,0 +1,14 @@ +/* ISC license. */ + +#include <unistd.h> +#include <errno.h> +#include <skalibs/djbunix.h> + +int fd_sync (int fd) +{ + register int r ; + do + r = fsync(fd) ; + while ((r == -1) && (errno == EINTR)) ; + return r ; +} diff --git a/src/libstddjb/fd_write.c b/src/libstddjb/fd_write.c new file mode 100644 index 0000000..636bce9 --- /dev/null +++ b/src/libstddjb/fd_write.c @@ -0,0 +1,13 @@ +/* ISC license. */ + +#include <unistd.h> +#include <errno.h> +#include <skalibs/allreadwrite.h> + +int fd_write (int fd, char const *buf, unsigned int len) +{ + register int r ; + do r = write(fd, buf, len) ; + while ((r == -1) && (errno == EINTR)) ; + return r ; +} diff --git a/src/libstddjb/fd_writev.c b/src/libstddjb/fd_writev.c new file mode 100644 index 0000000..d48d7f1 --- /dev/null +++ b/src/libstddjb/fd_writev.c @@ -0,0 +1,14 @@ +/* ISC license. */ + +#include <sys/types.h> +#include <sys/uio.h> +#include <errno.h> +#include <skalibs/allreadwrite.h> + +int fd_writev (int fd, struct iovec const *v, unsigned int vlen) +{ + register int r ; + do r = writev(fd, v, vlen) ; + while ((r == -1) && (errno == EINTR)) ; + return r ; +} diff --git a/src/libstddjb/fmtscan-internal.h b/src/libstddjb/fmtscan-internal.h new file mode 100644 index 0000000..b1cac3e --- /dev/null +++ b/src/libstddjb/fmtscan-internal.h @@ -0,0 +1,105 @@ +/* ISC license. */ + +#ifndef FMTSCAN_INTERNAL_H +#define FMTSCAN_INTERNAL_H + +#include <errno.h> +#include <limits.h> +#include <skalibs/bytestr.h> +#include <skalibs/fmtscan.h> + +#define SCANB(bits) \ +unsigned int uint##bits##_scan_base (char const *s, uint##bits *u, unsigned char base) \ +{ \ + static uint##bits const max = (uint##bits)(-1) ; \ + uint##bits result = 0 ; \ + unsigned int pos = 0 ; \ + for (;; pos++) \ + { \ + register unsigned char c = fmtscan_num(s[pos], base) ; \ + if ((c >= base) || (result > ((max - c) / base))) break ; \ + result = result * base + c ; \ + } \ + if (pos) *u = result ; \ + return pos ; \ +} \ + +#define SCANB0(bits) \ +unsigned int uint##bits##0_scan_base (char const *s, uint##bits *u, unsigned char base) \ +{ \ + register unsigned int pos = uint##bits##_scan_base(s, u, base) ; \ + if (!pos) return (errno = EINVAL, 0) ; \ + if (!s[pos]) return pos ; \ + errno = (fmtscan_num(s[pos], base) < base) ? EDOM : EINVAL ; \ + return 0 ; \ +} \ + +#define SCANS(type, cstname) \ +unsigned int type##_scan (char const *s, type *n) \ +{ \ + unsigned type tmp ; \ + register unsigned int r = 0 ; \ + register unsigned int sign = 0 ; \ + if (*s == '-') \ + { \ + r = 1 + u##type##_scan(s+1, &tmp) ; \ + if (r == 1) return 0 ; \ + if (tmp == 0) *n = 0 ; \ + else \ + { \ + if (tmp-1 > -(cstname##_MIN+1)) \ + { \ + tmp /= 10 ; \ + r-- ; \ + } \ + *n = cstname##_MIN + (-(cstname##_MIN+1) - (tmp-1)) ; \ + } \ + return r ; \ + } \ + if (*s == '+') (s++, sign++) ; \ + r = u##type##_scan(s, &tmp) ; \ + if (!r) return 0 ; \ + r += sign ; \ + if (tmp > cstname##_MAX) \ + { \ + tmp /= 10 ; \ + r-- ; \ + } \ + *n = tmp ; \ + return r ; \ +} \ + +#define SCANL(bits) \ +unsigned int uint##bits##_scanlist (uint##bits *tab, unsigned int max, char const *s, unsigned int *num) \ +{ \ + unsigned int i = 0, len = 0 ; \ + for (; s[len] && (i < max) ; i++) \ + { \ + register unsigned int w = uint##bits##_scan(s + len, tab + i) ; \ + if (!w) break ; \ + len += w ; \ + while (byte_chr(",:; \t\r\n", 7, s[len]) < 7) len++ ; \ + } \ + *num = i ; \ + return len ; \ +} \ + +#define FMTL(bits) \ +unsigned int uint##bits##_fmtlist (char *s, uint##bits const *tab, unsigned int n) \ +{ \ + unsigned int i = 0, len = 0 ; \ + for (; i < n ; i++) \ + { \ + register unsigned int w = uint##bits##_fmt(s, tab[i]) ; \ + len += w ; \ + if (s) \ + { \ + s += w ; \ + if (i < n-1) { *s++ = ',' ; len++ ; } \ + } \ + } \ + return len ; \ +} \ + + +#endif diff --git a/src/libstddjb/fmtscan_asc.c b/src/libstddjb/fmtscan_asc.c new file mode 100644 index 0000000..c33c0ec --- /dev/null +++ b/src/libstddjb/fmtscan_asc.c @@ -0,0 +1,9 @@ +/* ISC license. */ + +#include <skalibs/fmtscan.h> + +unsigned char fmtscan_asc (unsigned char c) +{ + static char const *tab = "0123456789abcdefghijklmnopqrstuvwxyz" ; + return (c >= 36) ? 0 : tab[c] ; +} diff --git a/src/libstddjb/fmtscan_num.c b/src/libstddjb/fmtscan_num.c new file mode 100644 index 0000000..094eb2a --- /dev/null +++ b/src/libstddjb/fmtscan_num.c @@ -0,0 +1,16 @@ +/* ISC license. */ + +#include <skalibs/fmtscan.h> + +unsigned char fmtscan_num (register unsigned char c, unsigned char n) +{ + return + ((c < '0') || (n > 36)) ? n : + (n <= 10) ? (c - '0' <= n) ? c - '0' : n : + (c - '0' <= 9) ? c - '0' : + (c < 'A') ? n : + (c - 'A' < n - 10) ? c - 'A' + 10 : + (c < 'a') ? n : + (c - 'a' < n - 10) ? c - 'a' + 10 : + n ; +} diff --git a/src/libstddjb/genalloc_deepfree.c b/src/libstddjb/genalloc_deepfree.c new file mode 100644 index 0000000..cda800a --- /dev/null +++ b/src/libstddjb/genalloc_deepfree.c @@ -0,0 +1,12 @@ +/* ISC license. */ + +#include <skalibs/stralloc.h> +#include <skalibs/genalloc.h> + +void genalloc_deepfree_size (genalloc *g, freefunc_t_ref f, unsigned int size) +{ + unsigned int len = g->len / size ; + register unsigned int i = 0 ; + for (; i < len ; i++) (*f)(g->s + i * size) ; + stralloc_free(g) ; +} diff --git a/src/libstddjb/genwrite_flush_bufalloc.c b/src/libstddjb/genwrite_flush_bufalloc.c new file mode 100644 index 0000000..6383246 --- /dev/null +++ b/src/libstddjb/genwrite_flush_bufalloc.c @@ -0,0 +1,10 @@ +/* ISC license. */ + +#include <skalibs/bufalloc.h> +#include <skalibs/genwrite.h> + +int genwrite_flush_bufalloc (void *target) +{ + register bufalloc *ba = target ; + return bufalloc_flush(ba) ; +} diff --git a/src/libstddjb/genwrite_flush_buffer.c b/src/libstddjb/genwrite_flush_buffer.c new file mode 100644 index 0000000..d30f3e6 --- /dev/null +++ b/src/libstddjb/genwrite_flush_buffer.c @@ -0,0 +1,10 @@ +/* ISC license. */ + +#include <skalibs/buffer.h> +#include <skalibs/genwrite.h> + +int genwrite_flush_buffer (void *target) +{ + register buffer *b = target ; + return buffer_flush(b) ; +} diff --git a/src/libstddjb/genwrite_flush_stralloc.c b/src/libstddjb/genwrite_flush_stralloc.c new file mode 100644 index 0000000..f623941 --- /dev/null +++ b/src/libstddjb/genwrite_flush_stralloc.c @@ -0,0 +1,9 @@ +/* ISC license. */ + +#include <skalibs/genwrite.h> + +int genwrite_flush_stralloc (void *target) +{ + (void)target ; + return 1 ; +} diff --git a/src/libstddjb/genwrite_put_bufalloc.c b/src/libstddjb/genwrite_put_bufalloc.c new file mode 100644 index 0000000..6aabe1c --- /dev/null +++ b/src/libstddjb/genwrite_put_bufalloc.c @@ -0,0 +1,10 @@ +/* ISC license. */ + +#include <skalibs/bufalloc.h> +#include <skalibs/genwrite.h> + +int genwrite_put_bufalloc (void *target, char const *s, unsigned int len) +{ + register bufalloc *ba = target ; + return bufalloc_put(ba, s, len) ? (int)len : -1 ; +} diff --git a/src/libstddjb/genwrite_put_buffer.c b/src/libstddjb/genwrite_put_buffer.c new file mode 100644 index 0000000..1c85725 --- /dev/null +++ b/src/libstddjb/genwrite_put_buffer.c @@ -0,0 +1,10 @@ +/* ISC license. */ + +#include <skalibs/buffer.h> +#include <skalibs/genwrite.h> + +int genwrite_put_buffer (void *target, char const *s, unsigned int len) +{ + register buffer *b = target ; + return buffer_put(b, s, len) ; +} diff --git a/src/libstddjb/genwrite_put_stralloc.c b/src/libstddjb/genwrite_put_stralloc.c new file mode 100644 index 0000000..2a8a8e8 --- /dev/null +++ b/src/libstddjb/genwrite_put_stralloc.c @@ -0,0 +1,10 @@ +/* ISC license. */ + +#include <skalibs/stralloc.h> +#include <skalibs/genwrite.h> + +int genwrite_put_stralloc (void *target, char const *s, unsigned int len) +{ + register stralloc *sa = target ; + return stralloc_catb(sa, s, len) ? (int)len : -1 ; +} diff --git a/src/libstddjb/genwrite_stderr.c b/src/libstddjb/genwrite_stderr.c new file mode 100644 index 0000000..1d6bae3 --- /dev/null +++ b/src/libstddjb/genwrite_stderr.c @@ -0,0 +1,6 @@ +/* ISC license. */ + +#include <skalibs/buffer.h> +#include <skalibs/genwrite.h> + +genwrite_t genwrite_stderr = GENWRITE_BUFFER_INIT(buffer_2) ; diff --git a/src/libstddjb/genwrite_stdout.c b/src/libstddjb/genwrite_stdout.c new file mode 100644 index 0000000..4fec080 --- /dev/null +++ b/src/libstddjb/genwrite_stdout.c @@ -0,0 +1,6 @@ +/* ISC license. */ + +#include <skalibs/buffer.h> +#include <skalibs/genwrite.h> + +genwrite_t genwrite_stdout = GENWRITE_BUFFER_INIT(buffer_1) ; diff --git a/src/libstddjb/getlnmax.c b/src/libstddjb/getlnmax.c new file mode 100644 index 0000000..e3fde8f --- /dev/null +++ b/src/libstddjb/getlnmax.c @@ -0,0 +1,28 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/bytestr.h> +#include <skalibs/buffer.h> +#include <skalibs/skamisc.h> + +int getlnmax (buffer *b, char *d, unsigned int max, unsigned int *w, char sep) +{ + if (max < *w) return (errno = EINVAL, -1) ; + for (;;) + { + siovec_t v[2] ; + unsigned int len = buffer_len(b) ; + unsigned int pos ; + int r ; + buffer_rpeek(b, v) ; + if (len > max - *w) len = max - *w ; + pos = siovec_bytechr(v, 2, sep) ; + if (pos > len) pos = len ; + r = pos < len ; + buffer_getnofill(b, d + *w, pos + r) ; *w += pos ; + if (*w >= max) return (errno = ERANGE, -1) ; + if (r) return 1 ; + r = buffer_fill(b) ; + if (r <= 0) return r ; + } +} diff --git a/src/libstddjb/getlnmaxsep.c b/src/libstddjb/getlnmaxsep.c new file mode 100644 index 0000000..2bde443 --- /dev/null +++ b/src/libstddjb/getlnmaxsep.c @@ -0,0 +1,28 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/bytestr.h> +#include <skalibs/buffer.h> +#include <skalibs/skamisc.h> + +int getlnmaxsep (buffer *b, char *d, unsigned int max, unsigned int *w, char const *sep, unsigned int seplen) +{ + if (max < *w) return (errno = EINVAL, -1) ; + for (;;) + { + siovec_t v[2] ; + unsigned int len = buffer_len(b) ; + unsigned int pos ; + int r ; + buffer_rpeek(b, v) ; + if (len > max - *w) len = max - *w ; + pos = siovec_bytein(v, 2, sep, seplen) ; + if (pos > len) pos = len ; + r = pos < len ; + buffer_getnofill(b, d + *w, pos + r) ; *w += pos ; + if (*w >= max) return (errno = ERANGE, -1) ; + if (r) return 1 ; + r = buffer_fill(b) ; + if (r <= 0) return r ; + } +} diff --git a/src/libstddjb/getpeereid.c b/src/libstddjb/getpeereid.c new file mode 100644 index 0000000..bf70aca --- /dev/null +++ b/src/libstddjb/getpeereid.c @@ -0,0 +1,68 @@ +/* ISC license. */ + +#include <skalibs/sysdeps.h> + +#ifdef SKALIBS_HASGETPEEREID +/* syscall exists - do nothing */ + +#else + +#ifdef SKALIBS_HASSOPEERCRED +/* implementation with SO_PEERCRED */ + +#include <skalibs/nonposix.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/un.h> +#include <skalibs/getpeereid.h> + +int getpeereid (int s, uid_t *u, gid_t *g) +{ + struct ucred blah ; + unsigned int len = sizeof(blah) ; + + if (getsockopt(s, SOL_SOCKET, SO_PEERCRED, &blah, &len) == -1) + return -1 ; + *u = blah.uid ; + *g = blah.gid ; + return 0 ; +} + +#else + +#ifdef SKALIBS_HASGETPEERUCRED +/* implementation with getpeerucred() */ + +#include <skalibs/nonposix.h> +#include <sys/types.h> +#include <ucred.h> + +int getpeereid (int s, uid_t *u, gid_t *g) +{ + ucred_t *cred ; + if (getpeerucred(s, &cred) == -1) return -1 ; + *u = ucred_geteuid(cred) ; + *g = ucred_getegid(cred) ; + ucred_free(cred) ; + return 0 ; +} + +#else + +/* can't find a real implementation, make a stub */ + +#include <sys/types.h> +#include <errno.h> +#include <skalibs/getpeereid.h> + +int getpeereid (int s, uid_t *uid, gid_t *gid) +{ + (void)s ; + *uid = *gid = -1 ; + errno = ENOSYS ; + return -1 ; +} + +#endif +#endif +#endif diff --git a/src/libstddjb/int_scan.c b/src/libstddjb/int_scan.c new file mode 100644 index 0000000..2547a04 --- /dev/null +++ b/src/libstddjb/int_scan.c @@ -0,0 +1,6 @@ +/* ISC license. */ + +#include <skalibs/uint.h> +#include "fmtscan-internal.h" + +SCANS(int, INT) diff --git a/src/libstddjb/iobuffer_fill.c b/src/libstddjb/iobuffer_fill.c new file mode 100644 index 0000000..991dffc --- /dev/null +++ b/src/libstddjb/iobuffer_fill.c @@ -0,0 +1,14 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/iobuffer.h> + +int iobuffer_fill (iobuffer_ref b) +{ + if (b->isk) + { + register int r = iobufferk_fill(&b->x.k) ; + if (r >= 0 || errno != ENOSYS || !iobuffer_salvage(b)) return r ; + } + return iobufferu_fill(&b->x.u) ; +} diff --git a/src/libstddjb/iobuffer_flush.c b/src/libstddjb/iobuffer_flush.c new file mode 100644 index 0000000..543744b --- /dev/null +++ b/src/libstddjb/iobuffer_flush.c @@ -0,0 +1,14 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/iobuffer.h> + +int iobuffer_flush (iobuffer_ref b) +{ + if (b->isk) + { + if (iobufferk_flush(&b->x.k)) return 1 ; + if (errno != ENOSYS || !iobuffer_salvage(b)) return 0 ; + } + return iobufferu_flush(&b->x.u) ; +} diff --git a/src/libstddjb/iobuffer_init.c b/src/libstddjb/iobuffer_init.c new file mode 100644 index 0000000..561379a --- /dev/null +++ b/src/libstddjb/iobuffer_init.c @@ -0,0 +1,17 @@ +/* ISC license. */ + +#include <skalibs/iobuffer.h> + +int iobuffer_init (iobuffer_ref b, int fdin, int fdout) +{ + if (!iobufferk_init(&b->x.k, fdin, fdout)) goto user ; + if (!iobufferk_isworking(&b->x.k)) goto fk ; + b->isk = 1 ; + return 1 ; + fk: + iobufferk_finish(&b->x.k) ; + user: + if (!iobufferu_init(&b->x.u, fdin, fdout)) return 0 ; + b->isk = 0 ; + return 1 ; +} diff --git a/src/libstddjb/iobuffer_kfromu.c b/src/libstddjb/iobuffer_kfromu.c new file mode 100644 index 0000000..28785e6 --- /dev/null +++ b/src/libstddjb/iobuffer_kfromu.c @@ -0,0 +1,41 @@ +/* ISC license. */ + +#include <skalibs/sysdeps.h> + +#ifdef SKALIBS_HASSPLICE + +#include <skalibs/nonposix.h> +#include <fcntl.h> +#include <sys/uio.h> +#include <skalibs/buffer.h> +#include <skalibs/iobuffer.h> +#include <skalibs/siovec.h> + +int iobuffer_kfromu (iobufferk_ref k, iobufferu_ref u) +{ + struct iovec iov[2] ; + siovec_t v[2] ; + int r ; + buffer_rpeek(&u->b[0], v) ; + iovec_from_siovec(iov, v, 2) ; + r = vmsplice(k->p[1], iov, 2, 0) ; + if (r < 0) return 0 ; + k->n += r ; + buffer_rseek(&u->b[0], (unsigned int)r) ; + u->b[1].c.p = u->b[0].c.p ; + return iobufferu_isempty(u) ; +} + +#else + +#include <errno.h> +#include <skalibs/iobuffer.h> + +int iobuffer_kfromu (iobufferk_ref k, iobufferu_ref u) +{ + (void)k ; + (void)u ; + return (errno = ENOSYS, 0) ; +} + +#endif diff --git a/src/libstddjb/iobuffer_salvage.c b/src/libstddjb/iobuffer_salvage.c new file mode 100644 index 0000000..b434568 --- /dev/null +++ b/src/libstddjb/iobuffer_salvage.c @@ -0,0 +1,19 @@ +/* ISC license. */ + +#include <skalibs/iobuffer.h> + +int iobuffer_salvage (iobuffer_ref b) +{ + iobufferu u ; + if (!b->isk) return 1 ; + if (!iobufferu_init(&u, b->x.k.fd[0], b->x.k.fd[1])) return 0 ; + if (!iobuffer_ufromk(&u, &b->x.k)) goto err ; + iobufferk_finish(&b->x.k) ; + b->x.u = u ; + b->isk = 0 ; + return 1 ; + +err: + iobufferu_finish(&u) ; + return 0 ; +} diff --git a/src/libstddjb/iobuffer_ufromk.c b/src/libstddjb/iobuffer_ufromk.c new file mode 100644 index 0000000..efb0368 --- /dev/null +++ b/src/libstddjb/iobuffer_ufromk.c @@ -0,0 +1,39 @@ +/* ISC license. */ + +#include <skalibs/sysdeps.h> + +#ifdef SKALIBS_HASSPLICE + +#include <skalibs/iobuffer.h> + +int iobuffer_ufromk (iobufferu_ref u, iobufferk_ref k) +{ + int in = u->b[0].fd ; + u->b[0].fd = k->p[0] ; + while (k->n) + { + register int r = iobufferu_fill(u) ; + if (r <= 0) goto err ; + k->n -= r ; + } + u->b[0].fd = in ; + return 1 ; + + err: + u->b[0].fd = in ; + return 0 ; +} + +#else + +#include <errno.h> +#include <skalibs/iobuffer.h> + +int iobuffer_ufromk (iobufferu_ref u, iobufferk_ref k) +{ + (void)u ; + (void)k ; + return (errno = ENOSYS, 0) ; +} + +#endif diff --git a/src/libstddjb/iobufferk_fill.c b/src/libstddjb/iobufferk_fill.c new file mode 100644 index 0000000..50ac403 --- /dev/null +++ b/src/libstddjb/iobufferk_fill.c @@ -0,0 +1,49 @@ +/* ISC license. */ + +#include <skalibs/sysdeps.h> + +#ifdef SKALIBS_HASSPLICE + +#include <skalibs/nonposix.h> +#include <fcntl.h> +#include <errno.h> +#include <skalibs/iobuffer.h> + +static int iobufferk_tee (iobufferk_ref k) +{ + register int r = tee(k->fd[0], k->fd[1], IOBUFFERK_SIZE - k->n, k->nb & 1 ? SPLICE_F_NONBLOCK : 0) ; + if (r > 0) k->n += r ; + return r ; +} + +static int iobufferk_splice (iobufferk_ref k) +{ + register int r = splice(k->fd[0], 0, k->fd[1], 0, IOBUFFERK_SIZE, k->nb ? SPLICE_F_NONBLOCK : 0) ; + if (r > 0) k->n += r ; + if ((r < 0) && (errno == EINVAL)) errno = ENOSYS ; + return r ; +} + +static int iobufferk_fill_3 (iobufferk_ref k) +{ + register int r = splice(k->fd[0], 0, k->p[1], 0, IOBUFFERK_SIZE - k->n, k->nb & 1 ? SPLICE_F_NONBLOCK : 0) ; + if (r > 0) k->n += r ; + if ((r < 0) && (errno == EINVAL)) errno = ENOSYS ; + return r ; +} + +iobufferk_io_func_t_ref const iobufferk_fill_f[4] = +{ + &iobufferk_tee, &iobufferk_splice, &iobufferk_splice, &iobufferk_fill_3 +} ; + +#else + +#include <skalibs/iobuffer.h> + +iobufferk_io_func_t_ref const iobufferk_fill_f[4] = +{ + &iobufferk_nosys, &iobufferk_nosys, &iobufferk_nosys, &iobufferk_nosys +} ; + +#endif diff --git a/src/libstddjb/iobufferk_finish.c b/src/libstddjb/iobufferk_finish.c new file mode 100644 index 0000000..ef20d57 --- /dev/null +++ b/src/libstddjb/iobufferk_finish.c @@ -0,0 +1,50 @@ +/* ISC license. */ + +#include <skalibs/sysdeps.h> + +#ifdef SKALIBS_HASSPLICE + +#include <errno.h> +#include <skalibs/djbunix.h> +#include <skalibs/iobuffer.h> + +static void iobufferk_nop (iobufferk_ref k) +{ + (void)k ; +} + +static void iobufferk_finish_0 (iobufferk_ref k) +{ + register int e = errno ; + fd_close(k->p[1]) ; + errno = e ; +} + +static void iobufferk_finish_3 (iobufferk_ref k) +{ + register int e = errno ; + fd_close(k->p[1]) ; + fd_close(k->p[0]) ; + errno = e ; +} + +iobufferk_finish_func_t_ref const iobufferk_finish_f[4] = +{ + &iobufferk_finish_0, &iobufferk_nop, &iobufferk_nop, &iobufferk_finish_3 +} ; + +#else + +#include <skalibs/iobuffer.h> + +static void iobufferk_nop (iobufferk_ref k) +{ + (void)k ; +} + +iobufferk_finish_func_t_ref const iobufferk_finish_f[4] = +{ + &iobufferk_nop, &iobufferk_nop, &iobufferk_nop, &iobufferk_nop +} ; + +#endif diff --git a/src/libstddjb/iobufferk_flush.c b/src/libstddjb/iobufferk_flush.c new file mode 100644 index 0000000..fb51e32 --- /dev/null +++ b/src/libstddjb/iobufferk_flush.c @@ -0,0 +1,61 @@ +/* ISC license. */ + +#include <skalibs/sysdeps.h> + +#ifdef SKALIBS_HASSPLICE + +#include <skalibs/nonposix.h> +#include <fcntl.h> +#include <errno.h> +#include <skalibs/iobuffer.h> + +static int iobufferk_flush_0 (iobufferk_ref k) +{ + while (k->n) + { + register int r = splice(k->fd[0], 0, k->p[1], 0, k->n, 0) ; + if (r < 0) return 0 ; + else if (!r) break ; + k->n -= r ; + } + return 1 ; +} + +static int fakeflush (iobufferk_ref k) +{ + k->n = 0 ; + return 1 ; +} + +static int iobufferk_flush_3 (iobufferk_ref k) +{ + while (k->n) + { + register int r = splice(k->p[0], 0, k->fd[1], 0, k->n, SPLICE_F_MORE | (k->nb & 2 ? SPLICE_F_NONBLOCK : 0)) ; + if (r < 0) + { + if (errno == EINVAL) errno = ENOSYS ; + return 0 ; + } + else if (!r) return (errno = EPIPE, 0) ; + k->n -= r ; + } + return 1 ; +} + +iobufferk_io_func_t_ref const iobufferk_flush_f[4] = +{ + &iobufferk_flush_0, &fakeflush, &fakeflush, &iobufferk_flush_3 +} ; + +#else + +#include <errno.h> +#include <skalibs/iobuffer.h> + +iobufferk_io_func_t_ref const iobufferk_flush_f[4] = +{ + &iobufferk_nosys, &iobufferk_nosys, &iobufferk_nosys, &iobufferk_nosys +} ; + +#endif diff --git a/src/libstddjb/iobufferk_init.c b/src/libstddjb/iobufferk_init.c new file mode 100644 index 0000000..03f7fae --- /dev/null +++ b/src/libstddjb/iobufferk_init.c @@ -0,0 +1,78 @@ +/* ISC license. */ + +#include <skalibs/sysdeps.h> + +#ifdef SKALIBS_HASSPLICE + +#include <sys/stat.h> +#include <fcntl.h> +#include <skalibs/djbunix.h> +#include <skalibs/iobuffer.h> + +static int iobufferk_init_0 (iobufferk_ref k) +{ + register int fd = open_write("/dev/null") ; + if (fd < 0) return 0 ; + if (coe(fd) < 0) + { + fd_close(fd) ; + return 0 ; + } + k->p[0] = -1 ; + k->p[1] = fd ; + return 1 ; +} + +static int iobufferk_nofd (iobufferk_ref k) +{ + k->p[0] = k->p[1] = -1 ; + return 1 ; +} + +static int iobufferk_init_3 (iobufferk_ref k) +{ + return (pipenbcoe(k->p) >= 0) ; +} + +static iobufferk_io_func_t_ref iobufferk_init_f[4] = +{ + &iobufferk_init_0, &iobufferk_nofd, &iobufferk_nofd, &iobufferk_init_3 +} ; + +int iobufferk_init (iobufferk_ref k, int fdin, int fdout) +{ + iobufferk tmp ; + struct stat st ; + register int r ; + if (fstat(fdin, &st) < 0) return 0 ; + r = fcntl(fdin, F_GETFL) ; + if (r < 0) return 0 ; + tmp.type = !S_ISFIFO(st.st_mode) ; + tmp.nb = !!(r & O_NONBLOCK) ; + if (fstat(fdout, &st) < 0) return 0 ; + r = fcntl(fdout, F_GETFL) ; + if (r < 0) return 0 ; + tmp.type |= (!S_ISFIFO(st.st_mode) << 1) ; + tmp.nb |= (r & O_NONBLOCK) ? 2 : 0 ; + tmp.fd[0] = fdin ; + tmp.fd[1] = fdout ; + tmp.n = 0 ; + if (!(*iobufferk_init_f[tmp.type])(&tmp)) return 0 ; + *k = tmp ; + return 1 ; +} + +#else + +#include <errno.h> +#include <skalibs/iobuffer.h> + +int iobufferk_init (iobufferk_ref k, int fdin, int fdout) +{ + (void)k ; + (void)fdin ; + (void)fdout ; + return (errno = ENOSYS, 0) ; +} + +#endif diff --git a/src/libstddjb/iobufferk_isworking.c b/src/libstddjb/iobufferk_isworking.c new file mode 100644 index 0000000..f02b7e0 --- /dev/null +++ b/src/libstddjb/iobufferk_isworking.c @@ -0,0 +1,48 @@ +/* ISC license. */ + +#include <skalibs/sysdeps.h> + +#ifdef SKALIBS_HASSPLICE + +#include <skalibs/nonposix.h> +#include <errno.h> +#include <fcntl.h> +#include <skalibs/iobuffer.h> + +int iobufferk_isworking (iobufferk_ref k) +{ + /* for now splice() with a length of 0 returns 0 no matter what, so this */ + /* test is useless. splice() should test the underlying filesystems even */ + /* if the length is 0. */ + +# if 0 + + register int e = errno ; + if (splice(k->fd[0], 0, k->p[1], 0, 0, 0) < 0) goto no ; + if (splice(k->p[0], 0, k->fd[1], 0, 0, 0) < 0) goto no ; + errno = e ; + return 1 ; + no: + errno = e ; + return 0 ; + +# else + + (void)k ; + return 1 ; + +# endif +} + +#else + +#include <skalibs/iobuffer.h> + +int iobufferk_isworking (iobufferk_ref k) +{ + (void)k ; + return 0 ; +} + +#endif + diff --git a/src/libstddjb/iobufferk_nosys.c b/src/libstddjb/iobufferk_nosys.c new file mode 100644 index 0000000..46f8be4 --- /dev/null +++ b/src/libstddjb/iobufferk_nosys.c @@ -0,0 +1,10 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/iobuffer.h> + +int iobufferk_nosys (iobufferk_ref k) +{ + (void)k ; + return (errno = ENOSYS, -1) ; +} diff --git a/src/libstddjb/iobufferu_fill.c b/src/libstddjb/iobufferu_fill.c new file mode 100644 index 0000000..7ebb67c --- /dev/null +++ b/src/libstddjb/iobufferu_fill.c @@ -0,0 +1,11 @@ +/* ISC license. */ + +#include <skalibs/buffer.h> +#include <skalibs/iobuffer.h> + +int iobufferu_fill (iobufferu_ref b) +{ + register int r = buffer_fill(&b->b[0]) ; + b->b[1].c.n = b->b[0].c.n ; + return r ; +} diff --git a/src/libstddjb/iobufferu_finish.c b/src/libstddjb/iobufferu_finish.c new file mode 100644 index 0000000..eb3749e --- /dev/null +++ b/src/libstddjb/iobufferu_finish.c @@ -0,0 +1,9 @@ +/* ISC license. */ + +#include <skalibs/alloc.h> +#include <skalibs/iobuffer.h> + +void iobufferu_finish (iobufferu_ref b) +{ + alloc_free(b->buf) ; +} diff --git a/src/libstddjb/iobufferu_flush.c b/src/libstddjb/iobufferu_flush.c new file mode 100644 index 0000000..734fab1 --- /dev/null +++ b/src/libstddjb/iobufferu_flush.c @@ -0,0 +1,11 @@ +/* ISC license. */ + +#include <skalibs/buffer.h> +#include <skalibs/iobuffer.h> + +int iobufferu_flush (iobufferu_ref b) +{ + register int r = buffer_flush(&b->b[1]) ; + b->b[0].c.p = b->b[1].c.p ; + return r ; +} diff --git a/src/libstddjb/iobufferu_init.c b/src/libstddjb/iobufferu_init.c new file mode 100644 index 0000000..e9ea5c8 --- /dev/null +++ b/src/libstddjb/iobufferu_init.c @@ -0,0 +1,15 @@ +/* ISC license. */ + +#include <skalibs/alloc.h> +#include <skalibs/buffer.h> +#include <skalibs/iobuffer.h> + +int iobufferu_init (iobufferu_ref b, int fdin, int fdout) +{ + register char *x = alloc(IOBUFFERU_SIZE) ; + if (!x) return 0 ; + b->buf = x ; + buffer_init(&b->b[0], &buffer_read, fdin, x, IOBUFFERU_SIZE) ; + buffer_init(&b->b[1], &buffer_write, fdout, x, IOBUFFERU_SIZE) ; + return 1 ; +} diff --git a/src/libstddjb/iopause.c b/src/libstddjb/iopause.c new file mode 100644 index 0000000..38e3b54 --- /dev/null +++ b/src/libstddjb/iopause.c @@ -0,0 +1,24 @@ +/* ISC license. */ + +#include <skalibs/sysdeps.h> +#include <skalibs/iopause.h> + +#ifdef SKALIBS_HASPPOLL + +iopause_func_t_ref const iopause_ = &iopause_ppoll ; + +#else + +#include <skalibs/config.h> + +#ifdef SKALIBS_FLAG_PREFERSELECT + +iopause_func_t_ref const iopause_ = &iopause_select ; + +#else + +iopause_func_t_ref const iopause_ = &iopause_poll ; + +#endif + +#endif diff --git a/src/libstddjb/iopause_poll.c b/src/libstddjb/iopause_poll.c new file mode 100644 index 0000000..e4e4da1 --- /dev/null +++ b/src/libstddjb/iopause_poll.c @@ -0,0 +1,19 @@ +/* ISC license. */ + +#include <errno.h> +#include <poll.h> +#include <skalibs/tai.h> +#include <skalibs/iopause.h> + +int iopause_poll (iopause_fd *x, unsigned int len, tain_t const *deadline, tain_t const *stamp) +{ + register int millisecs = 0 ; + if (!deadline) millisecs = -1 ; + else if (tain_less(stamp, deadline)) + { + tain_t t ; + tain_sub(&t, deadline, stamp) ; + millisecs = tain_to_millisecs(&t) ; + } + return poll(x, len, millisecs) ; +} diff --git a/src/libstddjb/iopause_ppoll.c b/src/libstddjb/iopause_ppoll.c new file mode 100644 index 0000000..b181d0a --- /dev/null +++ b/src/libstddjb/iopause_ppoll.c @@ -0,0 +1,44 @@ +/* ISC license. */ + +#include <skalibs/sysdeps.h> + +#ifdef SKALIBS_HASPPOLL + +#define _GNU_SOURCE +#include <errno.h> +#include <time.h> +#include <poll.h> +#include <skalibs/tai.h> +#include <skalibs/iopause.h> + +int iopause_ppoll (iopause_fd *x, unsigned int len, tain_t const *deadline, tain_t const *stamp) +{ + struct timespec ts = { .tv_sec = 0, .tv_nsec = 0 } ; + if (deadline && tain_less(stamp, deadline)) + { + tain_t delta ; + tain_sub(&delta, deadline, stamp) ; + if (!timespec_from_tain_relative(&ts, &delta)) + { + if (errno != ERANGE) return -1 ; + else deadline = 0 ; + } + } + return ppoll(x, len, deadline ? &ts : 0, 0) ; +} + +#else + +#include <errno.h> +#include <skalibs/iopause.h> + +int iopause_ppoll (iopause_fd *x, unsigned int len, tain_t const *deadline, tain_t const *stamp) +{ + (void)x ; + (void)len ; + (void)deadline ; + (void)stamp ; + return (errno = ENOSYS, -1) ; +} + +#endif diff --git a/src/libstddjb/iopause_select.c b/src/libstddjb/iopause_select.c new file mode 100644 index 0000000..a9c6529 --- /dev/null +++ b/src/libstddjb/iopause_select.c @@ -0,0 +1,63 @@ +/* ISC license. */ + +#include <sys/types.h> +#include <string.h> /* Solaris... */ +#include <errno.h> +#include <sys/select.h> +#include <skalibs/tai.h> +#include <skalibs/iopause.h> + +int iopause_select (iopause_fd *x, unsigned int len, tain_t const *deadline, tain_t const *stamp) +{ + struct timeval tv = { .tv_sec = 0, .tv_usec = 0 } ; + int nfds = 0 ; + fd_set rfds, wfds, xfds ; + int r ; + + FD_ZERO(&rfds) ; + FD_ZERO(&wfds) ; + FD_ZERO(&xfds) ; + if (deadline && tain_less(stamp, deadline)) + { + tain_t delta ; + tain_sub(&delta, deadline, stamp) ; + if (!timeval_from_tain_relative(&tv, &delta)) + { + if (errno != ERANGE) return -1 ; + else deadline = 0 ; + } + } + + { + register unsigned int i = 0 ; + for (; i < len ; i++) + { + x[i].revents = 0 ; + if (x[i].fd >= 0) + { + if (x[i].fd >= nfds) nfds = x[i].fd + 1 ; + if (x[i].events & IOPAUSE_READ) FD_SET(x[i].fd, &rfds) ; + if (x[i].events & IOPAUSE_WRITE) FD_SET(x[i].fd, &wfds) ; + if (x[i].events & IOPAUSE_EXCEPT) FD_SET(x[i].fd, &xfds) ; + } + } + } + + r = select(nfds, &rfds, &wfds, &xfds, deadline ? &tv : 0) ; + + if (r > 0) + { + register unsigned int i = 0 ; + for (; i < len ; i++) if (x[i].fd >= 0) + { + if ((x[i].events & IOPAUSE_READ) && FD_ISSET(x[i].fd, &rfds)) + x[i].revents |= IOPAUSE_READ ; + if ((x[i].events & IOPAUSE_WRITE) && FD_ISSET(x[i].fd, &wfds)) + x[i].revents |= IOPAUSE_WRITE ; + if ((x[i].events & IOPAUSE_EXCEPT) && FD_ISSET(x[i].fd, &xfds)) + x[i].revents |= IOPAUSE_EXCEPT ; + } + } + + return r ; +} diff --git a/src/libstddjb/iopause_stamp.c b/src/libstddjb/iopause_stamp.c new file mode 100644 index 0000000..d9a7e31 --- /dev/null +++ b/src/libstddjb/iopause_stamp.c @@ -0,0 +1,22 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/tai.h> +#include <skalibs/iopause.h> + +extern int iopause_stamp (iopause_fd *x, unsigned int n, tain_t const *deadline, tain_t *stamp) +{ + register int r ; + do + { + r = iopause(x, n, deadline, stamp) ; + if (stamp) + { + int e = errno ; + tain_now(stamp) ; + errno = e ; + } + } + while ((r < 0) && (errno == EINTR)) ; + return r ; +} diff --git a/src/libstddjb/iovec_from_siovec.c b/src/libstddjb/iovec_from_siovec.c new file mode 100644 index 0000000..154cca5 --- /dev/null +++ b/src/libstddjb/iovec_from_siovec.c @@ -0,0 +1,14 @@ +/* ISC license. */ + +#include <sys/types.h> +#include <sys/uio.h> +#include <skalibs/siovec.h> + +void iovec_from_siovec (struct iovec *iov, siovec_t const *v, unsigned int n) +{ + while (n--) + { + iov[n].iov_base = v[n].s ; + iov[n].iov_len = v[n].len ; + } +} diff --git a/src/libstddjb/ip46_scan.c b/src/libstddjb/ip46_scan.c new file mode 100644 index 0000000..97ebe4d --- /dev/null +++ b/src/libstddjb/ip46_scan.c @@ -0,0 +1,18 @@ +/* ISC license. */ + +#include <skalibs/ip46.h> + +#include <skalibs/fmtscan.h> +#include <skalibs/ip46.h> + +unsigned int ip46full_scan (char const *s, ip46full_t_ref ip) +{ + unsigned int len = ip6_scan(s, ip->ip) ; + if (len) ip->is6 = 1 ; + else + { + len = ip4_scan(s, ip->ip) ; + if (len) ip->is6 = 0 ; + } + return len ; +} diff --git a/src/libstddjb/ip46_scanlist.c b/src/libstddjb/ip46_scanlist.c new file mode 100644 index 0000000..37f2e18 --- /dev/null +++ b/src/libstddjb/ip46_scanlist.c @@ -0,0 +1,28 @@ +/* ISC license. */ + +#include <skalibs/ip46.h> + +#include <skalibs/bytestr.h> +#include <skalibs/fmtscan.h> + +unsigned int ip46full_scanlist (ip46full_t_ref out, unsigned int max, char const *s, unsigned int *num) +{ + unsigned int n = 0, w = 0 ; + for (; s[w] && (n < max) ; n++) + { + ip46full_t z ; + register unsigned int i = ip6_scan(s + w, z.ip) ; + if (i) z.is6 = 1 ; + else + { + i = ip4_scan(s + w, z.ip) ; + if (!i) break ; + z.is6 = 0 ; + } + out[n] = z ; + w += i ; + while (byte_chr(",; \t\r\n", 6, s[w]) < 6) w++ ; + } + *num = n ; + return w ; +} diff --git a/src/libstddjb/ip4_fmt.c b/src/libstddjb/ip4_fmt.c new file mode 100644 index 0000000..4c2f6a3 --- /dev/null +++ b/src/libstddjb/ip4_fmt.c @@ -0,0 +1,20 @@ +/* ISC license. */ + +#include <skalibs/uint32.h> +#include <skalibs/fmtscan.h> + +unsigned int ip4_fmt (char *s, char const *ip) +{ + unsigned int len = 0 ; + unsigned int i, j ; + for (j = 0 ; j < 4 ; j++) + { + i = uint32_fmt(s, (uint32)(unsigned char) ip[j]) ; + len += i ; + if (s) s += i ; + if (j == 3) break ; + if (s) *s++ = '.' ; + ++len ; + } + return len ; +} diff --git a/src/libstddjb/ip4_fmtu32.c b/src/libstddjb/ip4_fmtu32.c new file mode 100644 index 0000000..d4833e8 --- /dev/null +++ b/src/libstddjb/ip4_fmtu32.c @@ -0,0 +1,11 @@ +/* ISC license. */ + +#include <skalibs/uint32.h> +#include <skalibs/fmtscan.h> + +unsigned int ip4_fmtu32 (char *s, uint32 ip) +{ + char pack[4] ; + uint32_pack_big(pack, ip) ; + return ip4_fmt(s, pack) ; +} diff --git a/src/libstddjb/ip4_scan.c b/src/libstddjb/ip4_scan.c new file mode 100644 index 0000000..2873cd4 --- /dev/null +++ b/src/libstddjb/ip4_scan.c @@ -0,0 +1,23 @@ +/* ISC license. */ + +#include <skalibs/uint.h> + +unsigned int ip4_scan (char const *s, char *ip) +{ + register unsigned int j = 0 ; + unsigned int len = 0 ; + for (; j < 4 ; j++) + { + unsigned int u ; + register unsigned int i = uint_scan(s, &u) ; + if (!i) return 0 ; + ip[j] = (char)u ; + s += i ; + len += i ; + if (j == 3) break ; + if (*s != '.') return 0 ; + ++s ; + ++len ; + } + return len ; +} diff --git a/src/libstddjb/ip4_scanlist.c b/src/libstddjb/ip4_scanlist.c new file mode 100644 index 0000000..f1e3ccc --- /dev/null +++ b/src/libstddjb/ip4_scanlist.c @@ -0,0 +1,18 @@ +/* ISC license. */ + +#include <skalibs/bytestr.h> +#include <skalibs/fmtscan.h> + +unsigned int ip4_scanlist (char *out, unsigned int max, char const *s, unsigned int *num) +{ + unsigned int n = 0, w = 0 ; + for (; s[w] && (n < max) ; n++) + { + register unsigned int i = ip4_scan(s + w, out + (n << 2)) ; + if (!i) break ; + w += i ; + while (byte_chr(",:; \t\r\n", 7, s[w]) < 7) w++ ; + } + *num = n ; + return w ; +} diff --git a/src/libstddjb/ip4_scanlist_u32.c b/src/libstddjb/ip4_scanlist_u32.c new file mode 100644 index 0000000..26a4e38 --- /dev/null +++ b/src/libstddjb/ip4_scanlist_u32.c @@ -0,0 +1,19 @@ +/* ISC license. */ + +#include <skalibs/uint32.h> +#include <skalibs/bytestr.h> +#include <skalibs/fmtscan.h> + +unsigned int ip4_scanlist_u32 (uint32 *out, unsigned int max, char const *s, unsigned int *num) +{ + unsigned int n = 0, w = 0 ; + for (; s[w] && (n < max) ; n++) + { + register unsigned int i = ip4_scanu32(s + w, out + n) ; + if (!i) break ; + w += i ; + while (byte_chr(",:; \t\r\n", 7, s[w]) < 7) w++ ; + } + *num = n ; + return w ; +} diff --git a/src/libstddjb/ip4_scanu32.c b/src/libstddjb/ip4_scanu32.c new file mode 100644 index 0000000..a305926 --- /dev/null +++ b/src/libstddjb/ip4_scanu32.c @@ -0,0 +1,12 @@ +/* ISC license. */ + +#include <skalibs/uint32.h> +#include <skalibs/fmtscan.h> + +unsigned int ip4_scanu32 (char const *s, uint32 *ip) +{ + char pack[4] ; + register unsigned int r = ip4_scan(s, pack) ; + if (r) uint32_unpack_big(pack, ip) ; + return r ; +} diff --git a/src/libstddjb/ip6_fmt.c b/src/libstddjb/ip6_fmt.c new file mode 100644 index 0000000..afd8a21 --- /dev/null +++ b/src/libstddjb/ip6_fmt.c @@ -0,0 +1,79 @@ +/* ISC license. */ + +#include <skalibs/diuint.h> +#include <skalibs/fmtscan.h> + +#define px(c) ((j || (c)) ? (*s++ = fmtscan_asc(c), 1) : 0) + +static inline unsigned int xfmt16 (char *s, char const *key) +{ + register unsigned int j = 0 ; + j += px((unsigned char)key[0] >> 4) ; + j += px((unsigned char)key[0] & 15) ; + j += px((unsigned char)key[1] >> 4) ; + j += px((unsigned char)key[1] & 15) ; + return j ? j : (*s = '0', 1) ; +} + +static inline unsigned int find_colcol (char const *key, unsigned int *pos) +{ + diuint z[4] = { DIUINT_ZERO, DIUINT_ZERO, DIUINT_ZERO, DIUINT_ZERO } ; + unsigned int j = 0 ; + unsigned int max = 0 ; + register int iszero = 0 ; + register unsigned int i = 0 ; + for ( ; i < 8 ; i++) + { + if (key[i<<1] || key[(i<<1)+1]) + { + if (iszero) + { + iszero = 0 ; + z[j].right = i - z[j].left ; + if (z[j].right > max) max = z[j].right ; + j++ ; + } + } + else + { + if (!iszero) + { + iszero = 1 ; + z[j].left = i ; + } + } + } + if (iszero) + { + z[j].right = 8 - z[j].left ; + if (z[j].right > max) max = z[j].right ; + j++ ; + } + + if (max >= 2) + for (i = 0 ; i < j ; i++) if (z[i].right == max) return (*pos = z[i].left, max) ; + return 0 ; +} + +unsigned int ip6_fmt (char *s, char const *ip6) +{ + unsigned int w = 0 ; + register unsigned int i = 0 ; + unsigned int pos = 8 ; + unsigned int len = find_colcol(ip6, &pos) ; + for (; i < 8 ; i++) + { + if (i == pos) + { + if (!i) s[w++] = ':' ; + s[w++] = ':' ; + i += len-1 ; + } + else + { + w += xfmt16(s + w, ip6 + (i<<1)) ; + if (i < 7) s[w++] = ':' ; + } + } + return w ; +} diff --git a/src/libstddjb/ip6_scan.c b/src/libstddjb/ip6_scan.c new file mode 100644 index 0000000..cb2dc49 --- /dev/null +++ b/src/libstddjb/ip6_scan.c @@ -0,0 +1,35 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/uint16.h> +#include <skalibs/fmtscan.h> + +unsigned int ip6_scan (char const *s, char *ip6) +{ + static const unsigned char class[256] = "2222222222222222222222222222222222222222222222220000000000122222200000022222222222222222222222222000000222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222" ; + static const unsigned char table[5][3] = { "\024#\005", "\024\"\005", "\024\005\006", "\005\002\005", "\024\t\016" } ; + uint16 tmp[8] = { 0, 0, 0, 0, 0, 0, 0, 0 } ; + unsigned int pos = 8, j = 0, state = 0, i = 0 ; + + while (state < 5) + { + register unsigned char c = table[state][class[(unsigned char)s[i]] - '0'] ; + state = c & 7 ; + if (c & 0x20) { if (pos < 8) state = 5 ; else pos = j ; } + if (c & 0x10) + { + if (tmp[j] & 0xf000) state = 5 ; + else tmp[j] = (tmp[j] << 4) + fmtscan_num(s[i], 16) ; + } + if (c & 0x08) if ((++j > 7) && (state < 5)) state = 5 ; + i++ ; + } + + if (((pos < 8) && (j > 6)) || ((pos == 8) && (j < 8))) state = 5 ; + if (state == 5) return (errno = EINVAL, 0) ; + for (state = j ; state > pos ; state--) tmp[state - j + 7] = tmp[state - 1] ; + for (; state < pos + 8 - j ; state++) tmp[state] = 0 ; + + for (j = 0 ; j < 8 ; j++) uint16_pack_big(ip6 + (j<<1), tmp[j]) ; + return i - 1 ; +} diff --git a/src/libstddjb/ip6_scanlist.c b/src/libstddjb/ip6_scanlist.c new file mode 100644 index 0000000..8d751a6 --- /dev/null +++ b/src/libstddjb/ip6_scanlist.c @@ -0,0 +1,20 @@ +/* ISC license. */ + +#include <skalibs/bytestr.h> +#include <skalibs/fmtscan.h> + +unsigned int ip6_scanlist (char *out, unsigned int max, char const *s, unsigned int *num) +{ + unsigned int n = 0, w = 0 ; + for (; s[w] && (n < max) ; n++) + { + char ip[16] ; + register unsigned int i = ip6_scan(s + w, ip) ; + if (!i) break ; + byte_copy(out + (n << 4), 16, ip) ; + w += i ; + while (byte_chr(",; \t\r\n", 6, s[w]) < 6) w++ ; + } + *num = n ; + return w ; +} diff --git a/src/libstddjb/ipc_accept.c b/src/libstddjb/ipc_accept.c new file mode 100644 index 0000000..dc3eae7 --- /dev/null +++ b/src/libstddjb/ipc_accept.c @@ -0,0 +1,48 @@ +/* ISC license. */ + +#include <skalibs/sysdeps.h> +#include <skalibs/nonposix.h> +#include <errno.h> +#include <sys/socket.h> +#include <sys/un.h> +#include <skalibs/bytestr.h> +#include <skalibs/djbunix.h> +#include <skalibs/webipc.h> + +int ipc_accept_internal (int s, char *p, unsigned int l, int *trunc, unsigned int options) +{ + struct sockaddr_un sa ; + socklen_t dummy = sizeof sa ; + register int fd ; + byte_zero((char*)&sa, (unsigned int)dummy) ; + do +#ifdef SKALIBS_HASACCEPT4 + fd = accept4(s, (struct sockaddr *)&sa, &dummy, ((options & DJBUNIX_FLAG_NB) ? SOCK_NONBLOCK : 0) | ((options & DJBUNIX_FLAG_COE) ? SOCK_CLOEXEC : 0)) ; +#else + fd = accept(s, (struct sockaddr *)&sa, &dummy) ; +#endif + while ((fd == -1) && (errno == EINTR)) ; + if (fd == -1) return -1 ; +#ifndef SKALIBS_HASACCEPT4 + if ((((options & DJBUNIX_FLAG_NB) ? ndelay_on(fd) : ndelay_off(fd)) < 0) + || (((options & DJBUNIX_FLAG_COE) ? coe(fd) : uncoe(fd)) < 0)) + { + register int e = errno ; + fd_close(fd) ; + errno = e ; + return -1 ; + } +#endif + + if (p) + { + dummy = byte_chr(sa.sun_path, dummy, 0) ; + *trunc = 1 ; + if (!l) return fd ; + if (l < (dummy + 1)) dummy = l - 1 ; + else *trunc = 0 ; + byte_copy(p, dummy, sa.sun_path) ; + p[dummy] = 0 ; + } + return fd ; +} diff --git a/src/libstddjb/ipc_bind.c b/src/libstddjb/ipc_bind.c new file mode 100644 index 0000000..2bb8678 --- /dev/null +++ b/src/libstddjb/ipc_bind.c @@ -0,0 +1,20 @@ +/* ISC license. */ + +#include <skalibs/nonposix.h> +#include <sys/socket.h> +#include <sys/un.h> +#include <errno.h> +#include <skalibs/bytestr.h> +#include <skalibs/error.h> +#include <skalibs/webipc.h> + +int ipc_bind (int s, char const *p) +{ + struct sockaddr_un sa ; + register unsigned int l = str_len(p) ; + if (l > IPCPATH_MAX) return (errno = EPROTO, -1) ; + byte_zero((char *)&sa, sizeof sa) ; + sa.sun_family = AF_UNIX ; + byte_copy(sa.sun_path, l+1, p) ; + return bind(s, (struct sockaddr *)&sa, sizeof sa) ; +} diff --git a/src/libstddjb/ipc_bind_reuse.c b/src/libstddjb/ipc_bind_reuse.c new file mode 100644 index 0000000..31db745 --- /dev/null +++ b/src/libstddjb/ipc_bind_reuse.c @@ -0,0 +1,14 @@ +/* ISC license. */ + +#include <skalibs/nonposix.h> +#include <sys/socket.h> +#include <unistd.h> +#include <skalibs/webipc.h> + +int ipc_bind_reuse (int s, char const *p) +{ + unsigned int opt = 1 ; + setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof opt) ; + unlink(p) ; + return ipc_bind(s, p) ; +} diff --git a/src/libstddjb/ipc_connect.c b/src/libstddjb/ipc_connect.c new file mode 100644 index 0000000..6c5eac2 --- /dev/null +++ b/src/libstddjb/ipc_connect.c @@ -0,0 +1,25 @@ +/* ISC license. */ + +#include <skalibs/nonposix.h> +#include <errno.h> +#include <sys/socket.h> +#include <sys/un.h> +#include <skalibs/bytestr.h> +#include <skalibs/error.h> +#include <skalibs/webipc.h> + +int ipc_connect (int s, char const *p) +{ + struct sockaddr_un sa ; + unsigned int l = str_len(p) ; + if (l > IPCPATH_MAX) return (errno = EPROTO, 0) ; + byte_zero((char *) &sa, sizeof sa) ; + sa.sun_family = AF_UNIX ; + byte_copy(sa.sun_path, l+1, p) ; + if (connect(s, (struct sockaddr *)&sa, sizeof sa) == -1) + { + if (errno == EINTR) errno = EINPROGRESS ; + return 0 ; + } + return 1 ; +} diff --git a/src/libstddjb/ipc_connected.c b/src/libstddjb/ipc_connected.c new file mode 100644 index 0000000..4965c9f --- /dev/null +++ b/src/libstddjb/ipc_connected.c @@ -0,0 +1,20 @@ +/* ISC license. */ + +#include <skalibs/nonposix.h> +#include <sys/socket.h> +#include <sys/un.h> +#include <skalibs/allreadwrite.h> +#include <skalibs/webipc.h> + +int ipc_connected (int s) +{ + struct sockaddr_un sa ; + socklen_t dummy = sizeof sa ; + if (getpeername(s, (struct sockaddr *)&sa, &dummy) == -1) + { + char ch ; + fd_read(s, &ch, 1) ; /* sets errno */ + return 0 ; + } + return 1 ; +} diff --git a/src/libstddjb/ipc_dgram.c b/src/libstddjb/ipc_dgram.c new file mode 100644 index 0000000..ac61ee7 --- /dev/null +++ b/src/libstddjb/ipc_dgram.c @@ -0,0 +1,11 @@ +/* ISC license. */ + +#include <skalibs/nonposix.h> +#include <sys/socket.h> +#include <skalibs/djbunix.h> +#include <skalibs/webipc.h> + +int ipc_datagram_internal (unsigned int flags) +{ + return socket_internal(AF_UNIX, SOCK_DGRAM, 0, flags) ; +} diff --git a/src/libstddjb/ipc_eid.c b/src/libstddjb/ipc_eid.c new file mode 100644 index 0000000..81f608a --- /dev/null +++ b/src/libstddjb/ipc_eid.c @@ -0,0 +1,15 @@ +/* ISC license. */ + +#include <sys/types.h> +#include <skalibs/getpeereid.h> +#include <skalibs/webipc.h> + +int ipc_eid (int s, unsigned int *u, unsigned int *g) +{ + uid_t dummyu ; + gid_t dummyg ; + if (getpeereid(s, &dummyu, &dummyg) < 0) return -1 ; + *u = (unsigned int)dummyu ; + *g = (unsigned int)dummyg ; + return 0 ; +} diff --git a/src/libstddjb/ipc_listen.c b/src/libstddjb/ipc_listen.c new file mode 100644 index 0000000..a96be58 --- /dev/null +++ b/src/libstddjb/ipc_listen.c @@ -0,0 +1,10 @@ +/* ISC license. */ + +#include <skalibs/nonposix.h> +#include <sys/socket.h> +#include <skalibs/webipc.h> + +int ipc_listen (int s, int backlog) +{ + return listen(s, backlog) ; +} diff --git a/src/libstddjb/ipc_local.c b/src/libstddjb/ipc_local.c new file mode 100644 index 0000000..57ffb37 --- /dev/null +++ b/src/libstddjb/ipc_local.c @@ -0,0 +1,23 @@ +/* ISC license. */ + +#include <skalibs/nonposix.h> +#include <sys/socket.h> +#include <sys/un.h> +#include <skalibs/bytestr.h> +#include <skalibs/webipc.h> + +int ipc_local (int s, char *p, unsigned int l, int *trunc) +{ + struct sockaddr_un sa ; + socklen_t dummy = sizeof sa ; + byte_zero((char *)&sa, sizeof sa) ; + if (getsockname(s, (struct sockaddr *)&sa, &dummy) == -1) return -1 ; + dummy = byte_chr(sa.sun_path, dummy, 0) ; + *trunc = 1 ; + if (!l) return 0 ; + if (l < (dummy + 1)) dummy = l - 1 ; + else *trunc = 0 ; + byte_copy(p, dummy, sa.sun_path) ; + p[dummy] = 0 ; + return 0 ; +} diff --git a/src/libstddjb/ipc_pair.c b/src/libstddjb/ipc_pair.c new file mode 100644 index 0000000..6038d17 --- /dev/null +++ b/src/libstddjb/ipc_pair.c @@ -0,0 +1,11 @@ +/* ISC license. */ + +#include <skalibs/nonposix.h> +#include <sys/socket.h> +#include <skalibs/djbunix.h> +#include <skalibs/webipc.h> + +int ipc_pair_internal (int *sv, unsigned int flags) +{ + return socketpair_internal(AF_UNIX, SOCK_STREAM, 0, flags, sv) ; +} diff --git a/src/libstddjb/ipc_recv.c b/src/libstddjb/ipc_recv.c new file mode 100644 index 0000000..80806e7 --- /dev/null +++ b/src/libstddjb/ipc_recv.c @@ -0,0 +1,33 @@ +/* ISC license. */ + +#include <skalibs/nonposix.h> +#include <errno.h> +#include <sys/socket.h> +#include <sys/un.h> +#include <skalibs/bytestr.h> +#include <skalibs/error.h> +#include <skalibs/webipc.h> + +int ipc_recv (int fd, char *s, unsigned int len, char *path) +{ + struct sockaddr_un sa ; + socklen_t total = sizeof sa ; + char tmp[len] ; + register int r ; + do r = recvfrom(fd, tmp, len, 0, (struct sockaddr *)&sa, &total) ; + while ((r == -1) && (errno == EINTR)) ; + if (r < 0) return r ; + if (sa.sun_family != AF_UNIX) return (errno = EPROTO, -1) ; + if (path) + { + if (total == sizeof(sa_family_t)) path[0] = 0 ; + else + { + unsigned int l = str_len(sa.sun_path) ; + if (l > IPCPATH_MAX) return (errno = EPROTO, -1) ; + byte_copy(path, l+1, sa.sun_path) ; + } + } + byte_copy(s, r, tmp) ; + return r ; +} diff --git a/src/libstddjb/ipc_send.c b/src/libstddjb/ipc_send.c new file mode 100644 index 0000000..0e71d98 --- /dev/null +++ b/src/libstddjb/ipc_send.c @@ -0,0 +1,20 @@ +/* ISC license. */ + +#include <skalibs/nonposix.h> +#include <errno.h> +#include <sys/socket.h> +#include <sys/un.h> +#include <skalibs/bytestr.h> +#include <skalibs/error.h> +#include <skalibs/webipc.h> + +int ipc_send (int fd, char const *s, unsigned int len, char const *path) +{ + struct sockaddr_un sa ; + register unsigned int l = str_len(path) ; + if (l > IPCPATH_MAX) return (errno = EPROTO, -1) ; + byte_zero(&sa, sizeof sa) ; + sa.sun_family = AF_UNIX ; + byte_copy(sa.sun_path, l+1, path) ; + return sendto(fd, s, len, 0, (struct sockaddr *)&sa, sizeof sa) ; +} diff --git a/src/libstddjb/ipc_stream.c b/src/libstddjb/ipc_stream.c new file mode 100644 index 0000000..c2c6c1b --- /dev/null +++ b/src/libstddjb/ipc_stream.c @@ -0,0 +1,11 @@ +/* ISC license. */ + +#include <skalibs/nonposix.h> +#include <sys/socket.h> +#include <skalibs/djbunix.h> +#include <skalibs/webipc.h> + +int ipc_stream_internal (unsigned int flags) +{ + return socket_internal(AF_UNIX, SOCK_STREAM, 0, flags) ; +} diff --git a/src/libstddjb/ipc_timed_connect.c b/src/libstddjb/ipc_timed_connect.c new file mode 100644 index 0000000..4f8e73d --- /dev/null +++ b/src/libstddjb/ipc_timed_connect.c @@ -0,0 +1,26 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/error.h> +#include <skalibs/tai.h> +#include <skalibs/iopause.h> +#include <skalibs/webipc.h> + +int ipc_timed_connect (int s, char const *path, tain_t const *deadline, tain_t *stamp) +{ + if (!ipc_connect(s, path)) + { + iopause_fd x = { s, IOPAUSE_WRITE, 0 } ; + if (!error_isagain(errno) && !error_isalready(errno)) return 0 ; + for (;;) + { + register int r = iopause_stamp(&x, 1, deadline, stamp) ; + if (r < 0) return 0 ; + else if (!r) return (errno = ETIMEDOUT, 0) ; + else if (x.revents & IOPAUSE_EXCEPT) return 0 ; + else if (x.revents & IOPAUSE_WRITE) break ; + } + if (!ipc_connected(s)) return 0 ; + } + return 1 ; +} diff --git a/src/libstddjb/leapsecs_add.c b/src/libstddjb/leapsecs_add.c new file mode 100644 index 0000000..c24486b --- /dev/null +++ b/src/libstddjb/leapsecs_add.c @@ -0,0 +1,19 @@ +/* ISC license. */ + +#include <skalibs/uint64.h> +#include "djbtime-internal.h" + +int leapsecs_add_r (uint64 *t, char const *file, uint64 *leapsecs, int hit) +{ + uint64 u = *t ; + int n = leapsecs_init_r(file, leapsecs) ; + register unsigned int i = 0 ; + if (n < 0) return -1 ; + for (; i < (unsigned int)n ; i++) + { + if (u < leapsecs[i]) break ; + if (!hit || (leapsecs[i] < u)) ++u ; + } + *t = u ; + return n ; +} diff --git a/src/libstddjb/leapsecs_here.c b/src/libstddjb/leapsecs_here.c new file mode 100644 index 0000000..3ecdfd1 --- /dev/null +++ b/src/libstddjb/leapsecs_here.c @@ -0,0 +1,9 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include <skalibs/uint64.h> +#include "djbtime-internal.h" + +static uint64 leapsecs_here_tab[LEAPSECS_MAX+1] ; +uint64 *leapsecs_here = leapsecs_here_tab ; diff --git a/src/libstddjb/leapsecs_init.c b/src/libstddjb/leapsecs_init.c new file mode 100644 index 0000000..41f9b89 --- /dev/null +++ b/src/libstddjb/leapsecs_init.c @@ -0,0 +1,34 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/uint64.h> +#include <skalibs/djbunix.h> +#include "djbtime-internal.h" + +static unsigned int leapsecs_len (uint64 const *data) +{ + register unsigned int i = 1 ; + while (data[i]) i++ ; + return i ; +} + +static int leapsecs_read (char const *file, uint64 *data) +{ + char s[LEAPSECS_MAX * sizeof(uint64)] ; + register int n = openreadnclose(file, s, LEAPSECS_MAX * sizeof(uint64)) ; + if (n < 0) return -1 ; + if (n % sizeof(uint64)) return (errno = EINVAL, -1) ; + n /= sizeof(uint64) ; + { + register unsigned int i = 0 ; + for (; i < (unsigned int)n ; i++) + uint64_unpack_big(s + i * sizeof(uint64), data + i) ; + } + data[n] = 0 ; + return n ; +} + +int leapsecs_init_r (char const *file, uint64 *data) +{ + return data[0] ? (int)leapsecs_len(data) : leapsecs_read(file, data) ; +} diff --git a/src/libstddjb/leapsecs_sub.c b/src/libstddjb/leapsecs_sub.c new file mode 100644 index 0000000..271f592 --- /dev/null +++ b/src/libstddjb/leapsecs_sub.c @@ -0,0 +1,22 @@ +/* ISC license. */ + +#include <skalibs/uint64.h> +#include "djbtime-internal.h" + +int leapsecs_sub_r (uint64 *t, char const *file, uint64 *leapsecs) +{ + uint64 u = *t ; + uint64 d = 0 ; + int n = leapsecs_init_r(file, leapsecs) ; + register unsigned int i = 0 ; + register int hit = 0 ; + if (n < 0) return -1 ; + for (; i < (unsigned int)n ; i++) + { + if (u < leapsecs[i]) break ; + ++d ; + if (u == leapsecs[i]) hit = 1 ; + } + *t = u - d ; + return hit ; +} diff --git a/src/libstddjb/localtm_fmt.c b/src/libstddjb/localtm_fmt.c new file mode 100644 index 0000000..ee083ef --- /dev/null +++ b/src/libstddjb/localtm_fmt.c @@ -0,0 +1,17 @@ +/* ISC license. */ + +#include <time.h> +#include <skalibs/uint.h> +#include <skalibs/djbtime.h> + +unsigned int localtm_fmt (char *s, struct tm const *l) +{ + char *p = s ; + p += uint_fmt(p, 1900 + l->tm_year) ; *p++ = '-' ; + uint0_fmt(p, 1 + l->tm_mon, 2) ; p += 2 ; *p++ = '-' ; + uint0_fmt(p, l->tm_mday, 2) ; p += 2 ; *p++ = ' ' ; + uint0_fmt(p, l->tm_hour, 2) ; p += 2 ; *p++ = ':' ; + uint0_fmt(p, l->tm_min, 2) ; p += 2 ; *p++ = ':' ; + uint0_fmt(p, l->tm_sec, 2) ; p += 2 ; + return p - s ; +} diff --git a/src/libstddjb/localtm_from_ltm64.c b/src/libstddjb/localtm_from_ltm64.c new file mode 100644 index 0000000..63c5aac --- /dev/null +++ b/src/libstddjb/localtm_from_ltm64.c @@ -0,0 +1,23 @@ +/* ISC license. */ + +/* OpenBSD needs that for EOVERFLOW. wtfbsdseriously */ +#define _BSD_SOURCE + +#include <sys/types.h> +#include <errno.h> +#include <time.h> +#include <skalibs/uint64.h> +#include <skalibs/tai.h> +#include <skalibs/djbtime.h> + +int localtm_from_ltm64 (struct tm *l, uint64 uu, int tz) +{ + if (uu < TAI_MAGIC) return (errno = EINVAL, 0) ; + uu -= TAI_MAGIC ; + if (uu > 0xFFFFFFFFUL) return (errno = EOVERFLOW, 0) ; + { + time_t u = (time_t)uu ; + if (tz ? !localtime_r(&u, l) : !gmtime_r(&u, l)) return 0 ; + } + return 1 ; +} diff --git a/src/libstddjb/localtm_from_sysclock.c b/src/libstddjb/localtm_from_sysclock.c new file mode 100644 index 0000000..939bb21 --- /dev/null +++ b/src/libstddjb/localtm_from_sysclock.c @@ -0,0 +1,12 @@ +/* ISC license. */ + +#include <sys/types.h> +#include <time.h> +#include <skalibs/uint64.h> +#include <skalibs/djbtime.h> + +int localtm_from_sysclock (struct tm *l, uint64 u, int tz) +{ + if (!ltm64_from_sysclock(&u)) return 0 ; + return localtm_from_ltm64(l, u, tz) ; +} diff --git a/src/libstddjb/localtm_from_tai.c b/src/libstddjb/localtm_from_tai.c new file mode 100644 index 0000000..ad12cf2 --- /dev/null +++ b/src/libstddjb/localtm_from_tai.c @@ -0,0 +1,14 @@ +/* ISC license. */ + +#include <sys/types.h> +#include <time.h> +#include <skalibs/uint64.h> +#include <skalibs/tai.h> +#include <skalibs/djbtime.h> + +int localtm_from_tai (struct tm *l, tai_t const *t, int tz) +{ + uint64 u ; + if (!ltm64_from_tai(&u, t)) return 0 ; + return localtm_from_ltm64(l, u, tz) ; +} diff --git a/src/libstddjb/localtm_from_utc.c b/src/libstddjb/localtm_from_utc.c new file mode 100644 index 0000000..697621c --- /dev/null +++ b/src/libstddjb/localtm_from_utc.c @@ -0,0 +1,12 @@ +/* ISC license. */ + +#include <sys/types.h> +#include <time.h> +#include <skalibs/uint64.h> +#include <skalibs/djbtime.h> + +int localtm_from_utc (struct tm *l, uint64 u, int tz) +{ + if (!ltm64_from_utc(&u)) return 0 ; + return localtm_from_ltm64(l, u, tz) ; +} diff --git a/src/libstddjb/localtm_scan.c b/src/libstddjb/localtm_scan.c new file mode 100644 index 0000000..b028883 --- /dev/null +++ b/src/libstddjb/localtm_scan.c @@ -0,0 +1,40 @@ +/* ISC license. */ + +#include <errno.h> +#include <time.h> +#include <skalibs/djbtime.h> +#include <skalibs/uint.h> + +unsigned int localtm_scan (char const *s, struct tm *l) +{ + struct tm ll = { .tm_isdst = -1 } ; + unsigned int n = 0 ; unsigned int u ; + register unsigned int i = uint_scan(s+n, &u) ; + if (!i) goto fail ; n += i ; + if (u < 1900) goto fail ; u -= 1900 ; ll.tm_year = u ; + if (s[n++] != '-') goto fail ; + i = uint_scan(s+n, &u) ; + if (!i) goto fail ; n += i ; + if (!u || (u > 12)) goto fail ; u-- ; ll.tm_mon = u ; + if (s[n++] != '-') goto fail ; + i = uint_scan(s+n, &u) ; + if (!i) goto fail ; n += i ; + if (!u || (u > 31)) goto fail ; ll.tm_mday = u ; + if ((s[n] != ' ') && (s[n] != 'T')) goto fail ; n++ ; + i = uint_scan(s+n, &u) ; + if (!i) goto fail ; n += i ; + if (u > 23) goto fail ; ll.tm_hour = u ; + if (s[n++] != ':') goto fail ; + i = uint_scan(s+n, &u) ; + if (!i) goto fail ; n += i ; + if (u > 59) goto fail ; ll.tm_min = u ; + if (s[n++] != ':') goto fail ; + i = uint_scan(s+n, &u) ; + if (!i) goto fail ; n += i ; + if (u > 60) goto fail ; ll.tm_sec = u ; + if (mktime(&ll) == (time_t)-1) goto fail ; + *l = ll ; + return n ; + fail: + return (errno = EINVAL, 0) ; +} diff --git a/src/libstddjb/localtmn_fmt.c b/src/libstddjb/localtmn_fmt.c new file mode 100644 index 0000000..79a869d --- /dev/null +++ b/src/libstddjb/localtmn_fmt.c @@ -0,0 +1,12 @@ +/* ISC license. */ + +#include <skalibs/uint32.h> +#include <skalibs/djbtime.h> + +unsigned int localtmn_fmt (char *s, localtmn_t const *l) +{ + char *p = s ; + p += localtm_fmt(p, &l->tm) ; *p++ = '.' ; + uint320_fmt(p, l->nano, 9) ; p += 9 ; + return p - s ; +} diff --git a/src/libstddjb/localtmn_from_sysclock.c b/src/libstddjb/localtmn_from_sysclock.c new file mode 100644 index 0000000..2d4e4fd --- /dev/null +++ b/src/libstddjb/localtmn_from_sysclock.c @@ -0,0 +1,13 @@ +/* ISC license. */ + +#include <skalibs/tai.h> +#include <skalibs/djbtime.h> + +int localtmn_from_sysclock (localtmn_t_ref l, tain_t const *a, int tz) +{ + struct tm t ; + if (!localtm_from_sysclock(&t, a->sec.x, tz)) return 0 ; + l->tm = t ; + l->nano = a->nano ; + return 1 ; +} diff --git a/src/libstddjb/localtmn_from_tain.c b/src/libstddjb/localtmn_from_tain.c new file mode 100644 index 0000000..a3d3f6e --- /dev/null +++ b/src/libstddjb/localtmn_from_tain.c @@ -0,0 +1,13 @@ +/* ISC license. */ + +#include <skalibs/tai.h> +#include <skalibs/djbtime.h> + +int localtmn_from_tain (localtmn_t_ref l, tain_t const *a, int tz) +{ + struct tm t ; + if (!localtm_from_tai(&t, tain_secp(a), tz)) return 0 ; + l->tm = t ; + l->nano = a->nano ; + return 1 ; +} diff --git a/src/libstddjb/localtmn_scan.c b/src/libstddjb/localtmn_scan.c new file mode 100644 index 0000000..f33ab51 --- /dev/null +++ b/src/libstddjb/localtmn_scan.c @@ -0,0 +1,21 @@ +/* ISC license. */ + +#include <skalibs/uint32.h> +#include <skalibs/djbtime.h> + +unsigned int localtmn_scan (char const *s, localtmn_t_ref l) +{ + localtmn_t m ; + unsigned int n = localtm_scan(s, &m.tm) ; + if (!n) return 0 ; + s += n ; + if (*s++ != '.') m.nano = 0 ; + else + { + register unsigned int b = uint32_scan(s, &m.nano) ; + if (!b) return 0 ; + s += b ; n += b ; + } + *l = m ; + return n ; +} diff --git a/src/libstddjb/lock_ex.c b/src/libstddjb/lock_ex.c new file mode 100644 index 0000000..fde901b --- /dev/null +++ b/src/libstddjb/lock_ex.c @@ -0,0 +1,37 @@ +/* ISC license. */ + +#include <skalibs/sysdeps.h> + +#ifdef SKALIBS_HASFLOCK + +#include <skalibs/nonposix.h> +#include <errno.h> +#include <sys/file.h> +#include <skalibs/djbunix.h> + +int lock_ex (int fd) +{ + register int r ; + do + r = flock(fd, LOCK_EX) ; + while ((r == -1) && (errno == EINTR)) ; + return r ; +} + +#else + +#include <sys/types.h> +#include <unistd.h> +#include <errno.h> +#include <skalibs/djbunix.h> + +int lock_ex (int fd) +{ + register int r ; + do + r = lockf(fd, F_LOCK, 0) ; + while ((r == -1) && (errno == EINTR)) ; + return r ; +} + +#endif diff --git a/src/libstddjb/lock_exnb.c b/src/libstddjb/lock_exnb.c new file mode 100644 index 0000000..7fed9f0 --- /dev/null +++ b/src/libstddjb/lock_exnb.c @@ -0,0 +1,38 @@ +/* ISC license. */ + +#include <skalibs/sysdeps.h> + +#ifdef SKALIBS_HASFLOCK + +#include <skalibs/nonposix.h> +#include <errno.h> +#include <sys/file.h> +#include <skalibs/djbunix.h> + +int lock_exnb (int fd) +{ + register int r ; + do + r = flock(fd, LOCK_EX | LOCK_NB) ; + while ((r == -1) && (errno == EINTR)) ; + return r ; +} + +#else + +#include <sys/types.h> +#include <unistd.h> +#include <errno.h> +#include <skalibs/djbunix.h> + +int lock_exnb (int fd) +{ + register int r ; + do + r = lockf(fd, F_TLOCK, 0) ; + while ((r == -1) && (errno == EINTR)) ; + if ((r == -1) && (errno == EACCES)) errno = EAGAIN ; + return r ; +} + +#endif diff --git a/src/libstddjb/lock_sh.c b/src/libstddjb/lock_sh.c new file mode 100644 index 0000000..4a42dc1 --- /dev/null +++ b/src/libstddjb/lock_sh.c @@ -0,0 +1,37 @@ +/* ISC license. */ + +#include <skalibs/sysdeps.h> + +#ifdef SKALIBS_HASFLOCK + +#include <skalibs/nonposix.h> +#include <errno.h> +#include <sys/file.h> +#include <skalibs/djbunix.h> + +int lock_sh (int fd) +{ + register int r ; + do + r = flock(fd, LOCK_SH) ; + while ((r == -1) && (errno == EINTR)) ; + return r ; +} + +#else + +#include <sys/types.h> +#include <unistd.h> +#include <errno.h> +#include <skalibs/djbunix.h> + +int lock_sh (int fd) +{ + register int r ; + do + r = lockf(fd, F_LOCK, 0) ; + while ((r == -1) && (errno == EINTR)) ; + return r ; +} + +#endif diff --git a/src/libstddjb/lock_shnb.c b/src/libstddjb/lock_shnb.c new file mode 100644 index 0000000..6a8fd42 --- /dev/null +++ b/src/libstddjb/lock_shnb.c @@ -0,0 +1,38 @@ +/* ISC license. */ + +#include <skalibs/sysdeps.h> + +#ifdef SKALIBS_HASFLOCK + +#include <skalibs/nonposix.h> +#include <errno.h> +#include <sys/file.h> +#include <skalibs/djbunix.h> + +int lock_shnb (int fd) +{ + register int r ; + do + r = flock(fd, LOCK_SH | LOCK_NB) ; + while ((r == -1) && (errno == EINTR)) ; + return r ; +} + +#else + +#include <sys/types.h> +#include <unistd.h> +#include <errno.h> +#include <skalibs/djbunix.h> + +int lock_shnb (int fd) +{ + register int r ; + do + r = lockf(fd, F_TLOCK, 0) ; + while ((r == -1) && (errno == EINTR)) ; + if ((r == -1) && (errno == EACCES)) errno = EAGAIN ; + return r ; +} + +#endif diff --git a/src/libstddjb/lock_un.c b/src/libstddjb/lock_un.c new file mode 100644 index 0000000..099716a --- /dev/null +++ b/src/libstddjb/lock_un.c @@ -0,0 +1,37 @@ +/* ISC license. */ + +#include <skalibs/sysdeps.h> + +#ifdef SKALIBS_HASFLOCK + +#include <skalibs/nonposix.h> +#include <errno.h> +#include <sys/file.h> +#include <skalibs/djbunix.h> + +int lock_un (int fd) +{ + register int r ; + do + r = flock(fd, LOCK_UN) ; + while ((r == -1) && (errno == EINTR)) ; + return r ; +} + +#else + +#include <sys/types.h> +#include <unistd.h> +#include <errno.h> +#include <skalibs/djbunix.h> + +int lock_un (int fd) +{ + register int r ; + do + r = lockf(fd, F_ULOCK, 0) ; + while ((r == -1) && (errno == EINTR)) ; + return r ; +} + +#endif diff --git a/src/libstddjb/lolprintf.c b/src/libstddjb/lolprintf.c new file mode 100644 index 0000000..90cc5fc --- /dev/null +++ b/src/libstddjb/lolprintf.c @@ -0,0 +1,15 @@ +/* ISC license. */ + +#include <stdarg.h> +#include <skalibs/buffer.h> +#include <skalibs/lolstdio.h> + +int lolprintf (char const *format, ...) +{ + va_list args ; + int r ; + va_start(args, format) ; + r = vbprintf(buffer_1, format, args) ; + va_end(args) ; + return r ; +} diff --git a/src/libstddjb/long_fmt.c b/src/libstddjb/long_fmt.c new file mode 100644 index 0000000..552fe47 --- /dev/null +++ b/src/libstddjb/long_fmt.c @@ -0,0 +1,10 @@ +/* ISC license. */ + +#include <skalibs/ulong.h> + +unsigned int long_fmt (char *fmt, long n) +{ + if (n >= 0) return ulong_fmt(fmt, n) ; + if (fmt) *fmt++ = '-' ; + return 1 + ulong_fmt(fmt, -n) ; +} diff --git a/src/libstddjb/long_scan.c b/src/libstddjb/long_scan.c new file mode 100644 index 0000000..34a5e1a --- /dev/null +++ b/src/libstddjb/long_scan.c @@ -0,0 +1,6 @@ +/* ISC license. */ + +#include <skalibs/ulong.h> +#include "fmtscan-internal.h" + +SCANS(long, LONG) diff --git a/src/libstddjb/ltm64_from_localtm.c b/src/libstddjb/ltm64_from_localtm.c new file mode 100644 index 0000000..6169f04 --- /dev/null +++ b/src/libstddjb/ltm64_from_localtm.c @@ -0,0 +1,17 @@ +/* ISC license. */ + +#include <sys/types.h> +#include <errno.h> +#include <time.h> +#include <skalibs/tai.h> +#include <skalibs/uint64.h> +#include <skalibs/djbtime.h> + +int ltm64_from_localtm (uint64 *uu, struct tm const *l) +{ + struct tm ll = *l ; + time_t u = mktime(&ll) ; + if (u == (time_t)-1) return (errno = EINVAL, 0) ; + *uu = TAI_MAGIC + u ; + return 1 ; +} diff --git a/src/libstddjb/ltm64_from_sysclock.c b/src/libstddjb/ltm64_from_sysclock.c new file mode 100644 index 0000000..54aca39 --- /dev/null +++ b/src/libstddjb/ltm64_from_sysclock.c @@ -0,0 +1,24 @@ +/* ISC license. */ + +#include <skalibs/config.h> +#include <skalibs/uint64.h> +#include <skalibs/djbtime.h> + +#ifdef SKALIBS_FLAG_CLOCKISTAI + +#include <skalibs/tai.h> + +int ltm64_from_sysclock (uint64 *u) +{ + tai_t t = { *u + 10U } ; + return ltm64_from_tai(u, &t) ; +} + +#else + +int ltm64_from_sysclock (uint64 *u) +{ + return ltm64_from_utc(u) ; +} + +#endif diff --git a/src/libstddjb/ltm64_from_tai.c b/src/libstddjb/ltm64_from_tai.c new file mode 100644 index 0000000..c0650c5 --- /dev/null +++ b/src/libstddjb/ltm64_from_tai.c @@ -0,0 +1,23 @@ +/* ISC license. */ + +#include <skalibs/config.h> +#include <skalibs/uint64.h> +#include <skalibs/tai.h> +#include <skalibs/djbtime.h> + +#ifdef SKALIBS_FLAG_TZISRIGHT + +int ltm64_from_tai (uint64 *u, tai_t const *t) +{ + *u = t->x - 10U ; + return 1 ; +} + +#else + +int ltm64_from_tai (uint64 *u, tai_t const *t) +{ + return utc_from_tai(u, t) ; +} + +#endif diff --git a/src/libstddjb/ltm64_from_utc.c b/src/libstddjb/ltm64_from_utc.c new file mode 100644 index 0000000..8d66813 --- /dev/null +++ b/src/libstddjb/ltm64_from_utc.c @@ -0,0 +1,23 @@ +/* ISC license. */ + +#include <skalibs/config.h> +#include <skalibs/uint64.h> +#include <skalibs/djbtime.h> +#include "djbtime-internal.h" + +#ifdef SKALIBS_FLAG_TZISRIGHT + +int ltm64_from_utc (uint64 *u) +{ + return (leapsecs_add(u, 0) >= 0) ; +} + +#else + +int ltm64_from_utc (uint64 *u) +{ + (void)u ; + return 1 ; +} + +#endif diff --git a/src/libstddjb/mininetstring_read.c b/src/libstddjb/mininetstring_read.c new file mode 100644 index 0000000..6a38523 --- /dev/null +++ b/src/libstddjb/mininetstring_read.c @@ -0,0 +1,44 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/allreadwrite.h> +#include <skalibs/uint32.h> +#include <skalibs/stralloc.h> +#include <skalibs/mininetstring.h> + +int mininetstring_read (int fd, stralloc *sa, uint32 *w) +{ + if (!*w) + { + char pack[2] ; + switch (fd_read(fd, pack, 2)) + { + case -1 : return -1 ; + case 0 : return 0 ; + case 1 : *w = ((uint32)pack[0] << 8) | (1U << 31) ; break ; + case 2 : *w = ((uint32)pack[0] << 8) | (uint32)pack[1] | (1U << 30) ; break ; + default : return (errno = EDOM, -1) ; + } + } + if (*w & (1U << 31)) + { + char c ; + switch (fd_read(fd, &c, 1)) + { + case -1 : return -1 ; + case 0 : return (errno = EPIPE, -1) ; + case 1 : *w |= (uint32)c | (1U << 30) ; *w &= ~(1U << 31) ; break ; + default : return (errno = EDOM, -1) ; + } + } + if (*w & (1U << 30)) + { + if (!stralloc_readyplus(sa, *w & ~(1U << 30))) return -1 ; + *w &= ~(1U << 30) ; + } + { + register unsigned int r = allread(fd, sa->s + sa->len, *w) ; + sa->len += r ; *w -= r ; + } + return *w ? -1 : 1 ; +} diff --git a/src/libstddjb/mininetstring_write.c b/src/libstddjb/mininetstring_write.c new file mode 100644 index 0000000..6b31f17 --- /dev/null +++ b/src/libstddjb/mininetstring_write.c @@ -0,0 +1,37 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/uint16.h> +#include <skalibs/uint32.h> +#include <skalibs/allreadwrite.h> +#include <skalibs/mininetstring.h> + +int mininetstring_write (int fd, char const *s, uint16 len, uint32 *w) +{ + if (!w) + { + char pack[2] ; + uint16_pack_big(pack, len) ; + switch (fd_write(fd, pack, 2)) + { + case -1 : return -1 ; + case 0 : return (errno = EAGAIN, -1) ; + case 1 : *w = (1U << 31) ; break ; + case 2 : *w = len ; break ; + default : return (errno = EDOM, -1) ; + } + } + if (*w & (1U << 31)) + { + char c = len & 0xFFU ; + switch (fd_write(fd, &c, 1)) + { + case -1 : return -1 ; + case 0 : return (errno = EAGAIN, -1) ; + case 1 : *w = len ; break ; + default : return (errno = EDOM, -1) ; + } + } + *w -= allwrite(fd, s + len - *w, *w) ; + return *w ? -1 : 1 ; +} diff --git a/src/libstddjb/ndelay_off.c b/src/libstddjb/ndelay_off.c new file mode 100644 index 0000000..828acfa --- /dev/null +++ b/src/libstddjb/ndelay_off.c @@ -0,0 +1,11 @@ +/* ISC license. */ + +#include <sys/types.h> +#include <fcntl.h> +#include <skalibs/djbunix.h> + +int ndelay_off (int fd) +{ + register int got = fcntl(fd, F_GETFL) ; + return (got == -1) ? -1 : fcntl(fd, F_SETFL, got & ~O_NONBLOCK) ; +} diff --git a/src/libstddjb/ndelay_on.c b/src/libstddjb/ndelay_on.c new file mode 100644 index 0000000..186590b --- /dev/null +++ b/src/libstddjb/ndelay_on.c @@ -0,0 +1,11 @@ +/* ISC license. */ + +#include <sys/types.h> +#include <fcntl.h> +#include <skalibs/djbunix.h> + +int ndelay_on (int fd) +{ + register int got = fcntl(fd, F_GETFL) ; + return (got == -1) ? -1 : fcntl(fd, F_SETFL, got | O_NONBLOCK) ; +} diff --git a/src/libstddjb/netstring_append.c b/src/libstddjb/netstring_append.c new file mode 100644 index 0000000..9c14f49 --- /dev/null +++ b/src/libstddjb/netstring_append.c @@ -0,0 +1,19 @@ +/* ISC license. */ + +#include <skalibs/uint.h> +#include <skalibs/bytestr.h> +#include <skalibs/stralloc.h> +#include <skalibs/netstring.h> + +int netstring_appendb (stralloc *sa, char const *s, unsigned int len) +{ + char fmt[UINT_FMT] ; + unsigned int n = uint_fmt(fmt, len) ; + if (!stralloc_readyplus(sa, len + n + 2)) return 0 ; + fmt[n] = ':' ; + byte_copy(sa->s + sa->len, n+1, fmt) ; + byte_copy(sa->s + sa->len + n+1, len, s) ; + sa->s[sa->len + n+1 + len] = ',' ; + sa->len += n + 2 + len ; + return 1 ; +} diff --git a/src/libstddjb/netstring_appendv.c b/src/libstddjb/netstring_appendv.c new file mode 100644 index 0000000..1fc1406 --- /dev/null +++ b/src/libstddjb/netstring_appendv.c @@ -0,0 +1,27 @@ +/* ISC license. */ + +#include <skalibs/uint.h> +#include <skalibs/bytestr.h> +#include <skalibs/siovec.h> +#include <skalibs/stralloc.h> +#include <skalibs/netstring.h> + +int netstring_appendv (stralloc *sa, siovec_t const *v, unsigned int n) +{ + char fmt[UINT_FMT] ; + unsigned int len = 0, pos ; + register unsigned int i = 0 ; + for (; i < n ; i++) len += v[i].len ; + pos = uint_fmt(fmt, len) ; + if (!stralloc_readyplus(sa, len + pos + 2)) return 0 ; + fmt[pos] = ':' ; + byte_copy(sa->s + sa->len, pos+1, fmt) ; + sa->len += pos+1 ; + for (i = 0 ; i < n ; i++) + { + byte_copy(sa->s + sa->len, v[i].len, v[i].s) ; + sa->len += v[i].len ; + } + sa->s[sa->len++] = ',' ; + return 1 ; +} diff --git a/src/libstddjb/netstring_decode.c b/src/libstddjb/netstring_decode.c new file mode 100644 index 0000000..a81756b --- /dev/null +++ b/src/libstddjb/netstring_decode.c @@ -0,0 +1,22 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/fmtscan.h> +#include <skalibs/netstring.h> +#include <skalibs/stralloc.h> +#include <skalibs/uint.h> + +int netstring_decode (stralloc *sa, char const *s, unsigned int len) +{ + unsigned int nlen ; + register unsigned int pos ; + if (!len) return 0 ; + pos = uint_scan(s, &nlen) ; + if (pos >= len) return (errno = EINVAL, -1) ; + if (s[pos] != ':') return (errno = EINVAL, -1) ; + s += pos+1 ; len -= pos+1 ; + if (len <= nlen) return (errno = EINVAL, -1) ; + if (s[nlen] != ',') return (errno = EINVAL, -1) ; + if (!stralloc_catb(sa, s, nlen)) return -1 ; + return pos + nlen + 2 ; +} diff --git a/src/libstddjb/netstring_encode.c b/src/libstddjb/netstring_encode.c new file mode 100644 index 0000000..c13abd6 --- /dev/null +++ b/src/libstddjb/netstring_encode.c @@ -0,0 +1,17 @@ +/* ISC license. */ + +#include <skalibs/netstring.h> +#include <skalibs/stralloc.h> +#include <skalibs/uint.h> + +int netstring_encode (stralloc *sa, char const *s, unsigned int len) +{ + char fmt[UINT_FMT] ; + unsigned int pos = uint_fmt(fmt, len) ; + if (!stralloc_readyplus(sa, pos + len + 2)) return 0 ; + stralloc_catb(sa, fmt, pos) ; + stralloc_catb(sa, ":", 1) ; + stralloc_catb(sa, s, len) ; + stralloc_catb(sa, ",", 1) ; + return 1 ; +} diff --git a/src/libstddjb/netstring_get.c b/src/libstddjb/netstring_get.c new file mode 100644 index 0000000..6f6c602 --- /dev/null +++ b/src/libstddjb/netstring_get.c @@ -0,0 +1,54 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/allreadwrite.h> +#include <skalibs/uint.h> +#include <skalibs/bytestr.h> +#include <skalibs/buffer.h> +#include <skalibs/cbuffer.h> +#include <skalibs/error.h> +#include <skalibs/stralloc.h> +#include <skalibs/netstring.h> + +int netstring_okeof (buffer *b, unsigned int w) +{ + return (errno == EPIPE) && !w && buffer_isempty(b) ? (errno = 0, 1) : 0 ; +} + +int netstring_get (buffer *b, stralloc *sa, unsigned int *state) +{ + if (!*state) + { + unsigned int n ; + unsigned int len ; + char buf[UINT_FMT] ; + if (b->c.a < UINT_FMT+1) return (errno = EINVAL, -1) ; + for (;;) + { + register int r ; + len = buffer_getnofill(b, buf, UINT_FMT) ; + n = byte_chr(buf, len, ':') ; /* XXX: accepts :, as a valid netstring */ + if (n >= UINT_FMT) + { + buffer_unget(b, len) ; + return (errno = EPROTO, -1) ; + } + if (n < len) break ; + buffer_unget(b, len) ; + r = sanitize_read(buffer_fill(b)) ; + if (r <= 0) return r ; + } + buffer_unget(b, len - n - 1) ; + if (!n || n != uint_scan(buf, &len)) return (errno = EPROTO, -1) ; + if (!stralloc_readyplus(sa, len + 1)) return -1 ; + *state = len + 1 ; + } + { + unsigned int w = 0 ; + register int r = buffer_getall(b, sa->s + sa->len, *state, &w) ; + sa->len += w ; + *state -= w ; + if (r <= 0) return r ; + } + return (sa->s[--sa->len] == ',') ? 1 : (errno = EPROTO, -1) ; +} diff --git a/src/libstddjb/netstring_put.c b/src/libstddjb/netstring_put.c new file mode 100644 index 0000000..5a27b25 --- /dev/null +++ b/src/libstddjb/netstring_put.c @@ -0,0 +1,36 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/buffer.h> +#include <skalibs/netstring.h> +#include <skalibs/uint.h> + +int netstring_put (buffer *b, char const *s, unsigned int len, unsigned int *written) +{ + char fmt[UINT_FMT] ; + unsigned int n = uint_fmt(fmt, len) ; + if (*written > len + n + 2) return (errno = EINVAL, 0) ; + fmt[n] = ':' ; + if (*written < n + 1) + { + unsigned int w = *written ; + int r = buffer_putall(b, fmt, n+1, &w) ; + if (r < 0) return (*written = w, 0) ; + *written = n+1 ; + } + if (*written < n+1 + len) + { + unsigned int w = *written - (n+1) ; + int r = buffer_putall(b, s, len, &w) ; + *written = w + (n+1) ; + if (r < 0) return (*written = n+1 + w, 0) ; + *written = n+1 + len ; + } + { + unsigned int w = 0 ; + int r = buffer_putall(b, ",", 1, &w) ; + if (r < 0) return 0 ; + } + *written = 0 ; + return 1 ; +} diff --git a/src/libstddjb/ntp_from_tain.c b/src/libstddjb/ntp_from_tain.c new file mode 100644 index 0000000..43d5a42 --- /dev/null +++ b/src/libstddjb/ntp_from_tain.c @@ -0,0 +1,23 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/uint64.h> +#include <skalibs/tai.h> +#include <skalibs/djbtime.h> + +int ntp_from_tain (uint64 *u, tain_t const *a) +{ + uint64 secs, frac ; + if (!utc_from_tai(&secs, tain_secp(a))) return 0 ; + secs += NTP_OFFSET ; + if (secs < TAI_MAGIC + 2147483648UL) goto ifail ; + secs -= TAI_MAGIC ; + if (secs >= ((uint64)3 << 31)) goto ifail ; + secs &= (secs < ((uint64)1 << 32)) ? 0xFFFFFFFFUL : 0x7FFFFFFFUL ; + frac = ((uint64)a->nano << 32) / 1000000000UL ; + *u = (secs << 32) + frac ; + return 1 ; + ifail: + errno = EINVAL ; + return 0 ; +} diff --git a/src/libstddjb/open2.c b/src/libstddjb/open2.c new file mode 100644 index 0000000..780f345 --- /dev/null +++ b/src/libstddjb/open2.c @@ -0,0 +1,15 @@ +/* ISC license. */ + +#include <skalibs/nonposix.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <errno.h> + +int open2 (char const *s, unsigned int flags) +{ + register int r ; + do + r = open(s, (int)flags) ; + while ((r == -1) && (errno == EINTR)) ; + return r ; +} diff --git a/src/libstddjb/open3.c b/src/libstddjb/open3.c new file mode 100644 index 0000000..f990d63 --- /dev/null +++ b/src/libstddjb/open3.c @@ -0,0 +1,15 @@ +/* ISC license. */ + +#include <skalibs/nonposix.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <errno.h> + +int open3 (char const *s, unsigned int flags, unsigned int mode) +{ + register int r ; + do + r = open(s, (int)flags, (mode_t)mode) ; + while ((r == -1) && (errno == EINTR)) ; + return r ; +} diff --git a/src/libstddjb/open_append.c b/src/libstddjb/open_append.c new file mode 100644 index 0000000..7486312 --- /dev/null +++ b/src/libstddjb/open_append.c @@ -0,0 +1,10 @@ +/* ISC license. */ + +#include <skalibs/nonposix.h> +#include <fcntl.h> +#include <skalibs/djbunix.h> + +int open_append (char const *fn) +{ + return open3(fn, O_WRONLY | O_NONBLOCK | O_APPEND | O_CREAT, 0666) ; +} diff --git a/src/libstddjb/open_create.c b/src/libstddjb/open_create.c new file mode 100644 index 0000000..db072d1 --- /dev/null +++ b/src/libstddjb/open_create.c @@ -0,0 +1,10 @@ +/* ISC license. */ + +#include <skalibs/nonposix.h> +#include <fcntl.h> +#include <skalibs/djbunix.h> + +int open_create (char const *fn) +{ + return open3(fn, O_WRONLY | O_NONBLOCK | O_CREAT, 0666) ; +} diff --git a/src/libstddjb/open_excl.c b/src/libstddjb/open_excl.c new file mode 100644 index 0000000..83c7770 --- /dev/null +++ b/src/libstddjb/open_excl.c @@ -0,0 +1,10 @@ +/* ISC license. */ + +#include <skalibs/nonposix.h> +#include <fcntl.h> +#include <skalibs/djbunix.h> + +int open_excl (char const *fn) +{ + return open3(fn, O_WRONLY | O_CREAT | O_EXCL | O_NONBLOCK, 0666) ; +} diff --git a/src/libstddjb/open_read.c b/src/libstddjb/open_read.c new file mode 100644 index 0000000..cc1b191 --- /dev/null +++ b/src/libstddjb/open_read.c @@ -0,0 +1,10 @@ +/* ISC license. */ + +#include <skalibs/nonposix.h> +#include <fcntl.h> +#include <skalibs/djbunix.h> + +int open_read (char const *fn) +{ + return open2(fn, O_RDONLY | O_NONBLOCK) ; +} diff --git a/src/libstddjb/open_readb.c b/src/libstddjb/open_readb.c new file mode 100644 index 0000000..a8b0518 --- /dev/null +++ b/src/libstddjb/open_readb.c @@ -0,0 +1,15 @@ +/* ISC license. */ + +#include <skalibs/djbunix.h> + +int open_readb (char const *fn) +{ + register int fd = open_read(fn) ; + if (fd == -1) return -1 ; + if (ndelay_off(fd) == -1) + { + fd_close(fd) ; + return -1 ; + } + return fd ; +} diff --git a/src/libstddjb/open_trunc.c b/src/libstddjb/open_trunc.c new file mode 100644 index 0000000..b34e3c2 --- /dev/null +++ b/src/libstddjb/open_trunc.c @@ -0,0 +1,10 @@ +/* ISC license. */ + +#include <skalibs/nonposix.h> +#include <fcntl.h> +#include <skalibs/djbunix.h> + +int open_trunc (char const *fn) +{ + return open3(fn, O_WRONLY | O_NONBLOCK | O_TRUNC | O_CREAT, 0666) ; +} diff --git a/src/libstddjb/open_write.c b/src/libstddjb/open_write.c new file mode 100644 index 0000000..42a92c3 --- /dev/null +++ b/src/libstddjb/open_write.c @@ -0,0 +1,10 @@ +/* ISC license. */ + +#include <skalibs/nonposix.h> +#include <fcntl.h> +#include <skalibs/djbunix.h> + +int open_write (char const *fn) +{ + return open2(fn, O_WRONLY | O_NONBLOCK) ; +} diff --git a/src/libstddjb/openreadclose.c b/src/libstddjb/openreadclose.c new file mode 100644 index 0000000..cf9a736 --- /dev/null +++ b/src/libstddjb/openreadclose.c @@ -0,0 +1,21 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/stralloc.h> +#include <skalibs/djbunix.h> + +int openreadclose (char const *fn, stralloc *sa, unsigned int bufsize) +{ + int fd = open_readb(fn) ; + if (fd == -1) return (errno == ENOENT) ? 0 : -1 ; + if (!slurp(sa, fd)) + { + register int e = errno ; + fd_close(fd) ; + errno = e ; + return -1 ; + } + fd_close(fd) ; + (void)bufsize ; + return 0 ; +} diff --git a/src/libstddjb/openreadfileclose.c b/src/libstddjb/openreadfileclose.c new file mode 100644 index 0000000..90e6b47 --- /dev/null +++ b/src/libstddjb/openreadfileclose.c @@ -0,0 +1,37 @@ +/* ISC license. */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <errno.h> +#include <skalibs/allreadwrite.h> +#include <skalibs/stralloc.h> +#include <skalibs/djbunix.h> + +int openreadfileclose (char const *file, stralloc *sa, unsigned int limit) +{ + unsigned int n ; + int fd = open_readb(file) ; + if (fd < 0) return 0 ; + { + struct stat st ; + if (fstat(fd, &st) < 0) goto err ; + n = st.st_size ; + } + if (limit && (limit < n)) n = limit ; + if (!stralloc_ready_tuned(sa, sa->len + n, 0, 0, 1)) goto err ; + { + register unsigned int r = allread(fd, sa->s + sa->len, n) ; + sa->len += r ; + if (r < n) goto err ; + } + fd_close(fd) ; + return 1 ; + +err: + { + register int e = errno ; + fd_close(fd) ; + errno = e ; + } + return 0 ; +} diff --git a/src/libstddjb/openreadnclose.c b/src/libstddjb/openreadnclose.c new file mode 100644 index 0000000..b0cf5d0 --- /dev/null +++ b/src/libstddjb/openreadnclose.c @@ -0,0 +1,21 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/allreadwrite.h> +#include <skalibs/djbunix.h> + +int openreadnclose (char const *file, char *s, unsigned int n) +{ + register int r ; + int fd = open_readb(file) ; + if (fd == -1) return -1 ; + r = allread(fd, s, n) ; + if (r == -1) + { + fd_close(fd) ; + return -1 ; + } + fd_close(fd) ; + if ((r > 0) && (r < (int)n)) errno = EPIPE ; + return r ; +} diff --git a/src/libstddjb/openslurpclose.c b/src/libstddjb/openslurpclose.c new file mode 100644 index 0000000..5f67d76 --- /dev/null +++ b/src/libstddjb/openslurpclose.c @@ -0,0 +1,18 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/stralloc.h> +#include <skalibs/djbunix.h> + +int openslurpclose (stralloc *sa, char const *fn) +{ + int r ; + int e ; + int fd = open_readb(fn) ; + if (fd == -1) return 0 ; + r = slurp(sa, fd) ; + e = errno ; + fd_close(fd) ; + errno = e ; + return r ; +} diff --git a/src/libstddjb/openwritenclose_suffix.c b/src/libstddjb/openwritenclose_suffix.c new file mode 100644 index 0000000..1c538ed --- /dev/null +++ b/src/libstddjb/openwritenclose_suffix.c @@ -0,0 +1,29 @@ +/* ISC license. */ + +#include <errno.h> +#include <unistd.h> +#include <stdio.h> /* for rename() */ +#include <skalibs/uint64.h> +#include <skalibs/bytestr.h> +#include <skalibs/djbunix.h> + +int openwritenclose_suffix_internal (char const *fn, char const *s, unsigned int n, uint64 *dev, uint64 *ino, int dosync, char const *suffix) +{ + uint64 tmpdev, tmpino ; + unsigned int len = str_len(fn) ; + unsigned int suffixlen = str_len(suffix) ; + char tmp[len + suffixlen + 1] ; + byte_copy(tmp, len, fn) ; + byte_copy(tmp + len, suffixlen + 1, suffix) ; + if (!openwritenclose_unsafe_internal(tmp, s, n, dev ? &tmpdev : 0, ino ? &tmpino : 0, dosync)) return 0 ; + if (rename(tmp, fn) < 0) + { + register int e = errno ; + unlink(tmp) ; + errno = e ; + return 0 ; + } + if (dev) *dev = tmpdev ; + if (ino) *ino = tmpino ; + return 1 ; +} diff --git a/src/libstddjb/openwritenclose_unsafe.c b/src/libstddjb/openwritenclose_unsafe.c new file mode 100644 index 0000000..427f6a6 --- /dev/null +++ b/src/libstddjb/openwritenclose_unsafe.c @@ -0,0 +1,32 @@ +/* ISC license. */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <errno.h> +#include <unistd.h> +#include <skalibs/uint64.h> +#include <skalibs/allreadwrite.h> +#include <skalibs/djbunix.h> + +int openwritenclose_unsafe_internal (char const *fn, char const *s, unsigned int len, uint64 *dev, uint64 *ino, int dosync) +{ + struct stat st ; + int fd = open_trunc(fn) ; + if (fd < 0) return 0 ; + if (allwrite(fd, s, len) < len) goto fail ; + if ((dev || ino) && (fstat(fd, &st) < 0)) goto fail ; + if (dosync && (fd_sync(fd) < 0) && (errno != EINVAL)) goto fail ; + fd_close(fd) ; + if (dev) *dev = (uint64)st.st_dev ; + if (ino) *ino = (uint64)st.st_ino ; + return 1 ; + + fail: + { + register int e = errno ; + fd_close(fd) ; + unlink(fn) ; + errno = e ; + } + return 0 ; +} diff --git a/src/libstddjb/pathexec.c b/src/libstddjb/pathexec.c new file mode 100644 index 0000000..b7b088e --- /dev/null +++ b/src/libstddjb/pathexec.c @@ -0,0 +1,12 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include <skalibs/env.h> +#include <skalibs/djbunix.h> +#include <skalibs/environ.h> + +void pathexec (char const *const *argv) +{ + pathexec_fromenv(argv, (char const **)environ, env_len((char const **)environ)) ; +} diff --git a/src/libstddjb/pathexec0.c b/src/libstddjb/pathexec0.c new file mode 100644 index 0000000..5241452 --- /dev/null +++ b/src/libstddjb/pathexec0.c @@ -0,0 +1,12 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include <unistd.h> +#include <skalibs/djbunix.h> + +void pathexec0 (char const *const *argv) +{ + if (!argv[0]) _exit(0) ; + pathexec(argv) ; +} diff --git a/src/libstddjb/pathexec0_run.c b/src/libstddjb/pathexec0_run.c new file mode 100644 index 0000000..818877e --- /dev/null +++ b/src/libstddjb/pathexec0_run.c @@ -0,0 +1,10 @@ +/* ISC license. */ + +#include <unistd.h> +#include <skalibs/djbunix.h> + +void pathexec0_run (char const *const *argv, char const *const *envp) +{ + if (!argv[0]) _exit(0) ; + pathexec_run(argv[0], argv, envp) ; +} diff --git a/src/libstddjb/pathexec_fromenv.c b/src/libstddjb/pathexec_fromenv.c new file mode 100644 index 0000000..df8b0e6 --- /dev/null +++ b/src/libstddjb/pathexec_fromenv.c @@ -0,0 +1,17 @@ +/* ISC license. */ + +#include <skalibs/stralloc.h> +#include <skalibs/env.h> +#include <skalibs/djbunix.h> + +static stralloc plus = STRALLOC_ZERO ; + +int pathexec_env (char const *s, char const *t) /* historic, bad name */ +{ + return env_addmodif(&plus, s, t) ; +} + +void pathexec_fromenv (char const *const *argv, char const *const *envp, unsigned int envlen) +{ + pathexec_r(argv, envp, envlen, plus.s, plus.len) ; +} diff --git a/src/libstddjb/pathexec_r.c b/src/libstddjb/pathexec_r.c new file mode 100644 index 0000000..eb4a894 --- /dev/null +++ b/src/libstddjb/pathexec_r.c @@ -0,0 +1,8 @@ +/* ISC license. */ + +#include <skalibs/djbunix.h> + +void pathexec_r (char const *const *argv, char const *const *envp, unsigned int envlen, char const *modifs, unsigned int modiflen) +{ + pathexec_r_name(argv[0], argv, envp, envlen, modifs, modiflen) ; +} diff --git a/src/libstddjb/pathexec_r_name.c b/src/libstddjb/pathexec_r_name.c new file mode 100644 index 0000000..c5caf4e --- /dev/null +++ b/src/libstddjb/pathexec_r_name.c @@ -0,0 +1,13 @@ +/* ISC license. */ + +#include <skalibs/bytestr.h> +#include <skalibs/env.h> +#include <skalibs/djbunix.h> + +void pathexec_r_name (char const *file, char const *const *argv, char const *const *envp, unsigned int envlen, char const *modifs, unsigned int modiflen) +{ + unsigned int n = envlen + 1 + byte_count(modifs, modiflen, '\0') ; + char const *v[n] ; + if (env_merge(v, n, envp, envlen, modifs, modiflen)) + pathexec_run(file, argv, v) ; +} diff --git a/src/libstddjb/pathexec_run.c b/src/libstddjb/pathexec_run.c new file mode 100644 index 0000000..ced2ae6 --- /dev/null +++ b/src/libstddjb/pathexec_run.c @@ -0,0 +1,12 @@ +/* ISC license. */ + +#include <skalibs/config.h> +#include <skalibs/env.h> +#include <skalibs/djbunix.h> + +void pathexec_run (char const *file, char const *const *argv, char const *const *envp) +{ + register char const *path = env_get("PATH") ; + if (!path) path = SKALIBS_DEFAULTPATH ; + execvep(file, argv, envp, path) ; +} diff --git a/src/libstddjb/pipe_internal.c b/src/libstddjb/pipe_internal.c new file mode 100644 index 0000000..d5354de --- /dev/null +++ b/src/libstddjb/pipe_internal.c @@ -0,0 +1,45 @@ +/* ISC license. */ + +#include <skalibs/sysdeps.h> + +#ifdef SKALIBS_HASPIPE2 + +#define _NETBSD_SOURCE +#define _GNU_SOURCE + +#include <unistd.h> +#include <fcntl.h> +#include <skalibs/djbunix.h> + +int pipe_internal (int *p, unsigned int flags) +{ + return pipe2(p, ((flags & DJBUNIX_FLAG_COE) ? O_CLOEXEC : 0) | ((flags & DJBUNIX_FLAG_NB) ? O_NONBLOCK : 0)) ; +} + +#else + +#include <unistd.h> +#include <errno.h> +#include <skalibs/djbunix.h> + +int pipe_internal (int *p, unsigned int flags) +{ + int pi[2] ; + if (pipe(pi) < 0) return -1 ; + if (flags & DJBUNIX_FLAG_COE) + if ((coe(pi[0]) < 0) || (coe(pi[1]) < 0)) goto err ; + if (flags & DJBUNIX_FLAG_NB) + if ((ndelay_on(pi[0]) < 0) || (ndelay_on(pi[1]) < 0)) goto err ; + p[0] = pi[0] ; p[1] = pi[1] ; + return 0 ; + err: + { + register int e = errno ; + fd_close(pi[1]) ; + fd_close(pi[0]) ; + errno = e ; + } + return -1 ; +} + +#endif diff --git a/src/libstddjb/prog.c b/src/libstddjb/prog.c new file mode 100644 index 0000000..f6c683c --- /dev/null +++ b/src/libstddjb/prog.c @@ -0,0 +1,7 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include <skalibs/strerr2.h> + +char const *PROG = "(none)" ; diff --git a/src/libstddjb/prot.c b/src/libstddjb/prot.c new file mode 100644 index 0000000..6714cfb --- /dev/null +++ b/src/libstddjb/prot.c @@ -0,0 +1,19 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include <unistd.h> +#include <pwd.h> +#include <errno.h> +#include <skalibs/djbunix.h> + +int prot_setuidgid (char const *name) +{ + struct passwd *pw = getpwnam(name) ; + if (!pw) + { + if (!errno) errno = ESRCH ; + return 0 ; + } + return !prot_grps(name) && !setgid(pw->pw_gid) && !setuid(pw->pw_uid) ; +} diff --git a/src/libstddjb/prot_grps.c b/src/libstddjb/prot_grps.c new file mode 100644 index 0000000..cc4ba0d --- /dev/null +++ b/src/libstddjb/prot_grps.c @@ -0,0 +1,17 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include <skalibs/nonposix.h> +#include <unistd.h> +#include <grp.h> +#include <limits.h> +#include <skalibs/setgroups.h> +#include <skalibs/djbunix.h> + +int prot_grps (char const *name) +{ + gid_t tab[NGROUPS_MAX] ; + int n = prot_readgroups(name, tab, NGROUPS_MAX) ; + return n < 0 ? -1 : setgroups(n, tab) ; +} diff --git a/src/libstddjb/prot_readgroups.c b/src/libstddjb/prot_readgroups.c new file mode 100644 index 0000000..5559882 --- /dev/null +++ b/src/libstddjb/prot_readgroups.c @@ -0,0 +1,28 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include <sys/types.h> +#include <grp.h> +#include <errno.h> +#include <skalibs/bytestr.h> +#include <skalibs/djbunix.h> + +int prot_readgroups (char const *name, gid_t *tab, unsigned int max) +{ + unsigned int n = 0 ; + for (;;) + { + struct group *gr ; + register char **member ; + errno = 0 ; + if (n >= max) break ; + gr = getgrent() ; + if (!gr) break ; + for (member = gr->gr_mem ; *member ; member++) + if (!str_diff(name, *member)) break ; + if (*member) tab[n++] = gr->gr_gid ; + } + endgrent() ; + return errno ? -1 : (int)n ; +} diff --git a/src/libstddjb/realpath.c b/src/libstddjb/realpath.c new file mode 100644 index 0000000..f286137 --- /dev/null +++ b/src/libstddjb/realpath.c @@ -0,0 +1,11 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include <skalibs/skamisc.h> +#include <skalibs/djbunix.h> + +char *realpath (char const *name, char *buf) +{ + return realpath_tmp(name, buf, &satmp) ; +} diff --git a/src/libstddjb/realpath_tmp.c b/src/libstddjb/realpath_tmp.c new file mode 100644 index 0000000..8f877dd --- /dev/null +++ b/src/libstddjb/realpath_tmp.c @@ -0,0 +1,26 @@ +/* ISC license. */ + +#include <limits.h> +#include <errno.h> +#include <skalibs/bytestr.h> +#include <skalibs/stralloc.h> +#include <skalibs/djbunix.h> + +#ifndef PATH_MAX +# define PATH_MAX 4095 +#endif + +char *realpath_tmp (char const *name, char *buf, stralloc *tmp) +{ + unsigned int tmpbase = tmp->len ; + if (sarealpath(tmp, name) == -1) return (char *)0 ; + if (tmp->len - tmpbase > PATH_MAX) + { + tmp->len = tmpbase ; + return (errno = ENAMETOOLONG, (char *)0) ; + } + byte_copy(buf, tmp->len - tmpbase, tmp->s + tmpbase) ; + buf[tmp->len - tmpbase] = 0 ; + tmp->len = tmpbase ; + return buf ; +} diff --git a/src/libstddjb/rm_rf.c b/src/libstddjb/rm_rf.c new file mode 100644 index 0000000..3f8c00d --- /dev/null +++ b/src/libstddjb/rm_rf.c @@ -0,0 +1,11 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include <skalibs/skamisc.h> +#include <skalibs/djbunix.h> + +int rm_rf (char const *filename) +{ + return rm_rf_tmp(filename, &satmp) ; +} diff --git a/src/libstddjb/rm_rf_in_tmp.c b/src/libstddjb/rm_rf_in_tmp.c new file mode 100644 index 0000000..8a0a9ec --- /dev/null +++ b/src/libstddjb/rm_rf_in_tmp.c @@ -0,0 +1,93 @@ +/* ISC license. */ + +#include <sys/types.h> +#include <unistd.h> +#include <errno.h> +#include <skalibs/bytestr.h> +#include <skalibs/stralloc.h> +#include <skalibs/direntry.h> +#include <skalibs/djbunix.h> + +static int rmstarindir (DIR *dir, stralloc *tmp, unsigned int ipos) /* WARNING: closes dir */ +{ + unsigned int tmpbase = tmp->len ; + for (;;) + { + register direntry *d ; + errno = 0 ; + d = readdir(dir) ; + if (!d) break ; + if (d->d_name[0] == '.') + if (((d->d_name[1] == '.') && (d->d_name[2] == 0)) || (d->d_name[1] == 0)) + continue ; + if (!stralloc_cats(tmp, d->d_name) || !stralloc_0(tmp)) goto closeanderr ; + } + if (errno) goto closeanderr ; + dir_close(dir) ; + + { + unsigned int tmpstop = tmp->len ; + unsigned int fnbase = str_len(tmp->s + ipos) ; + unsigned int i = tmpbase ; + if (!stralloc_readyplus(tmp, fnbase+1)) goto err ; + stralloc_catb(tmp, tmp->s + ipos, fnbase) ; + stralloc_catb(tmp, "/", 1) ; + fnbase = tmp->len ; + for (; i < tmpstop ; i += tmp->len - fnbase) + { + register unsigned int n = str_len(tmp->s + i) ; + tmp->len = fnbase ; + if (!stralloc_readyplus(tmp, n+1)) goto err ; + stralloc_catb(tmp, tmp->s + i, n+1) ; + if (rm_rf_in_tmp(tmp, tmpstop) == -1) goto err ; + } + } + tmp->len = tmpbase ; + return 0 ; + +closeanderr: + { + register int e = errno ; + dir_close(dir) ; + errno = e ; + } +err: + tmp->len = tmpbase ; + return -1 ; +} + +int rm_rf_in_tmp (stralloc *tmp, unsigned int ipos) +{ + if (unlink(tmp->s + ipos) == 0) return 0 ; + if (errno == ENOENT) return 0 ; + if ((errno != EISDIR) && (errno != EPERM)) return -1 ; + { + register int h = (errno == EPERM) ; + register DIR *dir = opendir(tmp->s + ipos) ; + if (!dir) + { + if (h && (errno == ENOTDIR)) errno = EPERM ; + return -1 ; + } + if (rmstarindir(dir, tmp, ipos) == -1) return -1 ; + } + return rmdir(tmp->s + ipos) ; +} + +int rmstar_tmp (char const *dirname, stralloc *tmp) +{ + unsigned int tmpbase = tmp->len ; + if (!stralloc_cats(tmp, dirname)) return -1 ; + if (!stralloc_0(tmp)) goto err ; + { + register DIR *dir = opendir(dirname) ; + if (!dir) goto err ; + if (rmstarindir(dir, tmp, tmpbase) == -1) goto err ; + } + tmp->len = tmpbase ; + return 0 ; + +err: + tmp->len = tmpbase ; + return -1 ; +} diff --git a/src/libstddjb/rm_rf_tmp.c b/src/libstddjb/rm_rf_tmp.c new file mode 100644 index 0000000..6e434d7 --- /dev/null +++ b/src/libstddjb/rm_rf_tmp.c @@ -0,0 +1,18 @@ +/* ISC license. */ + +#include <skalibs/stralloc.h> +#include <skalibs/djbunix.h> + +int rm_rf_tmp (char const *filename, stralloc *tmp) +{ + unsigned int tmpbase = tmp->len ; + if (!stralloc_cats(tmp, filename)) return -1 ; + if (!stralloc_0(tmp)) goto err ; + if (rm_rf_in_tmp(tmp, tmpbase) == -1) goto err ; + tmp->len = tmpbase ; + return 0 ; + +err: + tmp->len = tmpbase ; + return -1 ; +} diff --git a/src/libstddjb/rmstar.c b/src/libstddjb/rmstar.c new file mode 100644 index 0000000..1870274 --- /dev/null +++ b/src/libstddjb/rmstar.c @@ -0,0 +1,11 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include <skalibs/skamisc.h> +#include <skalibs/djbunix.h> + +int rmstar (char const *dirname) +{ + return rmstar_tmp(dirname, &satmp) ; +} diff --git a/src/libstddjb/sabasename.c b/src/libstddjb/sabasename.c new file mode 100644 index 0000000..829b2a7 --- /dev/null +++ b/src/libstddjb/sabasename.c @@ -0,0 +1,17 @@ +/* ISC license. */ + +#include <skalibs/bytestr.h> +#include <skalibs/stralloc.h> +#include <skalibs/djbunix.h> + +int sabasename (stralloc *sa, char const *s, unsigned int len) +{ + if (!len) return stralloc_catb(sa, ".", 1) ; + while (len && (s[len-1] == '/')) len-- ; + if (!len) return stralloc_catb(sa, "/", 1) ; + { + register unsigned int i = byte_rchr(s, len, '/') ; + i = (i == len) ? 0 : i+1 ; + return stralloc_catb(sa, s + i, len - i) ; + } +} diff --git a/src/libstddjb/sadirname.c b/src/libstddjb/sadirname.c new file mode 100644 index 0000000..9fc4802 --- /dev/null +++ b/src/libstddjb/sadirname.c @@ -0,0 +1,18 @@ +/* ISC license. */ + +#include <skalibs/bytestr.h> +#include <skalibs/stralloc.h> +#include <skalibs/djbunix.h> + +int sadirname (stralloc *sa, char const *s, unsigned int len) +{ + if (!len) return stralloc_catb(sa, ".", 1) ; + while (len && (s[len-1] == '/')) len-- ; + if (!len) return stralloc_catb(sa, "/", 1) ; + { + register unsigned int i = byte_rchr(s, len, '/') ; + return (i == len) ? stralloc_catb(sa, ".", 1) : + (i == 0) ? stralloc_catb(sa, "/", 1) : + stralloc_catb(sa, s, i) ; + } +} diff --git a/src/libstddjb/sagetcwd.c b/src/libstddjb/sagetcwd.c new file mode 100644 index 0000000..d8c5dea --- /dev/null +++ b/src/libstddjb/sagetcwd.c @@ -0,0 +1,27 @@ +/* ISC license. */ + +#include <unistd.h> +#include <errno.h> +#include <skalibs/bytestr.h> +#include <skalibs/stralloc.h> +#include <skalibs/djbunix.h> + +int sagetcwd (stralloc *sa) +{ + unsigned int n = 128 ; + int wasnull = !sa->s ; + + for (;;) + { + if (!stralloc_readyplus(sa, n)) goto err ; + if (getcwd(sa->s + sa->len, n)) break ; + if (errno != ERANGE) goto err ; + n += 128 ; + } + sa->len += str_len(sa->s + sa->len) ; + return 0 ; + +err: + if (wasnull) stralloc_free(sa) ; + return -1 ; +} diff --git a/src/libstddjb/sagethostname.c b/src/libstddjb/sagethostname.c new file mode 100644 index 0000000..500a95c --- /dev/null +++ b/src/libstddjb/sagethostname.c @@ -0,0 +1,27 @@ +/* ISC license. */ + +#include <unistd.h> +#include <skalibs/bytestr.h> +#include <skalibs/stralloc.h> +#include <skalibs/djbunix.h> + +int sagethostname (stralloc *sa) +{ + unsigned int n = 128 ; + int wasnull = !sa->s ; + + for (;;) + { + if (!stralloc_readyplus(sa, n)) goto err ; + sa->s[sa->len + n - 2] = 0 ; + if (gethostname(sa->s + sa->len, n) == -1) goto err ; + if (!sa->s[sa->len + n - 2]) break ; + n += 128 ; + } + sa->len += str_len(sa->s + sa->len) ; + return 0 ; + +err: + if (wasnull) stralloc_free(sa) ; + return -1 ; +} diff --git a/src/libstddjb/sanitize_read.c b/src/libstddjb/sanitize_read.c new file mode 100644 index 0000000..bd8eee3 --- /dev/null +++ b/src/libstddjb/sanitize_read.c @@ -0,0 +1,11 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/allreadwrite.h> +#include <skalibs/error.h> + +int sanitize_read (int r) +{ + return r == -1 ? error_isagain(errno) ? (errno = 0, 0) : -1 : + !r ? (errno = EPIPE, -1) : r ; +} diff --git a/src/libstddjb/sareadlink.c b/src/libstddjb/sareadlink.c new file mode 100644 index 0000000..d6c2a4e --- /dev/null +++ b/src/libstddjb/sareadlink.c @@ -0,0 +1,27 @@ +/* ISC license. */ + +#include <unistd.h> +#include <skalibs/stralloc.h> +#include <skalibs/djbunix.h> + +int sareadlink (stralloc *sa, char const *path) +{ + unsigned int n = 128 ; + int wasnull = !sa->s ; + register int r ; + + for (;;) + { + if (!stralloc_readyplus(sa, n)) goto err ; + r = readlink(path, sa->s + sa->len, n) ; + if (r < 0) goto err ; + if ((unsigned int)r < n) break ; + n += 128 ; + } + sa->len += r ; + return 0 ; + +err: + if (wasnull) stralloc_free(sa) ; + return -1 ; +} diff --git a/src/libstddjb/satmp.c b/src/libstddjb/satmp.c new file mode 100644 index 0000000..833c74f --- /dev/null +++ b/src/libstddjb/satmp.c @@ -0,0 +1,6 @@ +/* ISC license. */ + +#include <skalibs/stralloc.h> +#include <skalibs/skamisc.h> + +stralloc satmp = STRALLOC_ZERO ; diff --git a/src/libstddjb/sauniquename.c b/src/libstddjb/sauniquename.c new file mode 100644 index 0000000..5a6ad83 --- /dev/null +++ b/src/libstddjb/sauniquename.c @@ -0,0 +1,28 @@ +/* ISC license. */ + +#include <unistd.h> +#include <skalibs/djbunix.h> +#include <skalibs/skamisc.h> +#include <skalibs/stralloc.h> +#include <skalibs/tai.h> +#include <skalibs/uint.h> + +int sauniquename (stralloc *sa) +{ + unsigned int base = sa->len ; + int wasnull = !sa->s ; + + if (!stralloc_readyplus(sa, TIMESTAMP + UINT_FMT + 131)) return -1 ; + sa->s[base] = ':' ; + timestamp(sa->s + base + 1) ; + sa->s[base + 1 + TIMESTAMP] = ':' ; + sa->len = base + 2 + TIMESTAMP ; + sa->len += uint_fmt(sa->s + sa->len, getpid()) ; + sa->s[sa->len++] = ':' ; + if (sagethostname(sa) == -1) goto err ; + return 0 ; + +err: + if (wasnull) stralloc_free(sa) ; else sa->len = base ; + return -1 ; +} diff --git a/src/libstddjb/seek_cur.c b/src/libstddjb/seek_cur.c new file mode 100644 index 0000000..cdfdac7 --- /dev/null +++ b/src/libstddjb/seek_cur.c @@ -0,0 +1,10 @@ +/* ISC license. */ + +#include <sys/types.h> +#include <unistd.h> +#include <skalibs/djbunix.h> + +long seek_cur (int fd) +{ + return (long)lseek(fd, 0, SEEK_CUR) ; +} diff --git a/src/libstddjb/seek_set.c b/src/libstddjb/seek_set.c new file mode 100644 index 0000000..b5883ac --- /dev/null +++ b/src/libstddjb/seek_set.c @@ -0,0 +1,13 @@ +/* ISC license. */ + +#include <sys/types.h> +#include <unistd.h> +#include <skalibs/djbunix.h> + +#define SET 0 /* sigh */ + +int seek_set (int fd, long pos) +{ + if (lseek(fd, (off_t) pos, SET) == -1) return -1 ; + return 0 ; +} diff --git a/src/libstddjb/selfpipe-internal.h b/src/libstddjb/selfpipe-internal.h new file mode 100644 index 0000000..994c179 --- /dev/null +++ b/src/libstddjb/selfpipe-internal.h @@ -0,0 +1,28 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#ifndef SELFPIPE_INTERNAL_H +#define SELFPIPE_INTERNAL_H + +#include <signal.h> +#include <skalibs/sysdeps.h> + +extern sigset_t selfpipe_caught ; + +#ifdef SKALIBS_HASSIGNALFD + +extern int selfpipe_fd ; + +#else + +#include <skalibs/sig.h> + +extern int selfpipe[2] ; +#define selfpipe_fd selfpipe[0] + +extern struct skasigaction const selfpipe_ssa ; + +#endif + +#endif diff --git a/src/libstddjb/selfpipe_finish.c b/src/libstddjb/selfpipe_finish.c new file mode 100644 index 0000000..47a889f --- /dev/null +++ b/src/libstddjb/selfpipe_finish.c @@ -0,0 +1,35 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include <signal.h> +#include <skalibs/sysdeps.h> +#include <skalibs/djbunix.h> +#include "selfpipe-internal.h" +#include <skalibs/selfpipe.h> + +#ifdef SKALIBS_HASSIGNALFD + +void selfpipe_finish (void) +{ + sigprocmask(SIG_UNBLOCK, &selfpipe_caught, 0) ; + sigemptyset(&selfpipe_caught) ; + fd_close(selfpipe_fd) ; + selfpipe_fd = -1 ; +} + +#else + +#include <skalibs/sig.h> +#include <skalibs/nsig.h> + +void selfpipe_finish (void) +{ + sig_restoreto(&selfpipe_caught, NSIG) ; + sigemptyset(&selfpipe_caught) ; + fd_close(selfpipe[1]) ; + fd_close(selfpipe[0]) ; + selfpipe[0] = selfpipe[1] = -1 ; +} + +#endif diff --git a/src/libstddjb/selfpipe_init.c b/src/libstddjb/selfpipe_init.c new file mode 100644 index 0000000..bd26d2f --- /dev/null +++ b/src/libstddjb/selfpipe_init.c @@ -0,0 +1,27 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include <errno.h> +#include <signal.h> +#include <skalibs/sysdeps.h> +#include "selfpipe-internal.h" +#include <skalibs/selfpipe.h> + +#ifdef SKALIBS_HASSIGNALFD +#include <sys/signalfd.h> +#else +#include <skalibs/djbunix.h> +#endif + +int selfpipe_init (void) +{ + if (selfpipe_fd >= 0) return (errno = EBUSY, -1) ; + sigemptyset(&selfpipe_caught) ; +#ifdef SKALIBS_HASSIGNALFD + selfpipe_fd = signalfd(-1, &selfpipe_caught, SFD_NONBLOCK | SFD_CLOEXEC) ; +#else + if (pipenbcoe(selfpipe) < 0) return -1 ; +#endif + return selfpipe_fd ; +} diff --git a/src/libstddjb/selfpipe_internal.c b/src/libstddjb/selfpipe_internal.c new file mode 100644 index 0000000..e5d5d95 --- /dev/null +++ b/src/libstddjb/selfpipe_internal.c @@ -0,0 +1,31 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include <signal.h> +#include <skalibs/sysdeps.h> +#include "selfpipe-internal.h" + +sigset_t selfpipe_caught ; + +#ifdef SKALIBS_HASSIGNALFD + +int selfpipe_fd = -1 ; + +#else + +#include <errno.h> +#include <skalibs/allreadwrite.h> +#include <skalibs/djbunix.h> + +int selfpipe[2] = { -1, -1 } ; + +static void selfpipe_trigger (int s) +{ + char c = (char)s ; + fd_write(selfpipe[1], &c, 1) ; +} + +struct skasigaction const selfpipe_ssa = { &selfpipe_trigger, SKASA_NOCLDSTOP | SKASA_MASKALL } ; + +#endif diff --git a/src/libstddjb/selfpipe_read.c b/src/libstddjb/selfpipe_read.c new file mode 100644 index 0000000..b68e67d --- /dev/null +++ b/src/libstddjb/selfpipe_read.c @@ -0,0 +1,31 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include <skalibs/sysdeps.h> +#include <skalibs/allreadwrite.h> +#include "selfpipe-internal.h" +#include <skalibs/selfpipe.h> + +#ifdef SKALIBS_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 + diff --git a/src/libstddjb/selfpipe_trap.c b/src/libstddjb/selfpipe_trap.c new file mode 100644 index 0000000..f07db64 --- /dev/null +++ b/src/libstddjb/selfpipe_trap.c @@ -0,0 +1,51 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include <errno.h> +#include <signal.h> +#include <skalibs/sysdeps.h> +#include "selfpipe-internal.h" +#include <skalibs/selfpipe.h> + +#ifdef SKALIBS_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 <skalibs/sig.h> + +int selfpipe_trap (int sig) +{ + if (selfpipe_fd < 0) return (errno = EBADF, -1) ; + if (sig_catcha(sig, &selfpipe_ssa) < 0) return -1 ; + if (sigaddset(&selfpipe_caught, sig) < 0) + { + int e = errno ; + sig_restore(sig) ; + errno = e ; + return -1 ; + } + return 0 ; +} + +#endif diff --git a/src/libstddjb/selfpipe_trapset.c b/src/libstddjb/selfpipe_trapset.c new file mode 100644 index 0000000..f8c35ee --- /dev/null +++ b/src/libstddjb/selfpipe_trapset.c @@ -0,0 +1,64 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include <errno.h> +#include <signal.h> +#include <skalibs/sysdeps.h> +#include "selfpipe-internal.h" +#include <skalibs/selfpipe.h> + +#ifdef SKALIBS_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 <skalibs/sig.h> +#include <skalibs/nsig.h> + +int selfpipe_trapset (sigset_t const *set) +{ + unsigned int i = 1 ; + if (selfpipe_fd < 0) return (errno = EBADF, -1) ; + for (; i <= NSIG ; i++) + { + register int h = sigismember(set, i) ; + if (h < 0) continue ; + if (h) + { + if (sig_catcha(i, &selfpipe_ssa) < 0) break ; + } + else if (sigismember(&selfpipe_caught, i)) + { + if (sig_restore(i) < 0) break ; + } + } + if (i <= NSIG) + { + int e = errno ; + sig_restoreto(set, i) ; + errno = e ; + return -1 ; + } + selfpipe_caught = *set ; + return 0 ; +} + +#endif diff --git a/src/libstddjb/selfpipe_untrap.c b/src/libstddjb/selfpipe_untrap.c new file mode 100644 index 0000000..776f2d7 --- /dev/null +++ b/src/libstddjb/selfpipe_untrap.c @@ -0,0 +1,54 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include <errno.h> +#include <signal.h> +#include <skalibs/sysdeps.h> +#include "selfpipe-internal.h" +#include <skalibs/selfpipe.h> + +#ifdef SKALIBS_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 <skalibs/sig.h> + +int selfpipe_untrap (int sig) +{ + register int r = sigismember(&selfpipe_caught, sig) ; + if (selfpipe_fd < 0) return (errno = EBADF, -1) ; + if (r < 0) return -1 ; + if (!r) return (errno = EINVAL, -1) ; + if (sig_restore(sig) < 0) return -1 ; + sigdelset(&selfpipe_caught, sig) ; + return 0 ; +} + +#endif diff --git a/src/libstddjb/sgetopt.c b/src/libstddjb/sgetopt.c new file mode 100644 index 0000000..7e6bdf6 --- /dev/null +++ b/src/libstddjb/sgetopt.c @@ -0,0 +1,24 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#undef SUBGETOPT_SHORT + +#include <skalibs/buffer.h> +#include <skalibs/sgetopt.h> + +int sgetopt_r (int argc, char const *const *argv, char const *opts, subgetopt_t *o) +{ + char c = (char)subgetopt_r(argc, argv, opts, o) ; + if (o->err && ((c == '?') || (c == ':'))) + { + buffer_puts(buffer_2, o->prog ? o->prog : argv[0]) ; + buffer_put(buffer_2, ": ", 2) ; + buffer_puts(buffer_2, ((c == '?') && argv[o->ind] && (o->ind < argc)) ? + "illegal option" : "option requires an argument") ; + buffer_put(buffer_2, " -- ", 4) ; + buffer_put(buffer_2, &c, 1) ; + buffer_putflush(buffer_2, "\n", 1) ; + } + return (int)c ; +} diff --git a/src/libstddjb/short_scan.c b/src/libstddjb/short_scan.c new file mode 100644 index 0000000..898ba9f --- /dev/null +++ b/src/libstddjb/short_scan.c @@ -0,0 +1,6 @@ +/* ISC license. */ + +#include <skalibs/ushort.h> +#include "fmtscan-internal.h" + +SCANS(short, SHRT) diff --git a/src/libstddjb/sig.c b/src/libstddjb/sig.c new file mode 100644 index 0000000..334b79a --- /dev/null +++ b/src/libstddjb/sig.c @@ -0,0 +1,18 @@ +/* ISC license. */ + +#include <signal.h> +#include <skalibs/sig.h> + +int sig_alarm = SIGALRM ; +int sig_child = SIGCHLD ; +int sig_stop = SIGSTOP ; +int sig_cont = SIGCONT ; +int sig_hangup = SIGHUP ; +int sig_int = SIGINT ; +int sig_kill = SIGKILL ; +int sig_pipe = SIGPIPE ; +int sig_term = SIGTERM ; +int sig_usr1 = SIGUSR1 ; +int sig_usr2 = SIGUSR2 ; +int sig_quit = SIGQUIT ; +int sig_abort = SIGABRT ; diff --git a/src/libstddjb/sig_block.c b/src/libstddjb/sig_block.c new file mode 100644 index 0000000..89ae51f --- /dev/null +++ b/src/libstddjb/sig_block.c @@ -0,0 +1,12 @@ +/* ISC license. */ + +#include <signal.h> +#include <skalibs/sig.h> + +void sig_block (int sig) +{ + sigset_t ss ; + sigemptyset(&ss) ; + sigaddset(&ss, sig) ; + sigprocmask(SIG_BLOCK, &ss, 0) ; +} diff --git a/src/libstddjb/sig_blocknone.c b/src/libstddjb/sig_blocknone.c new file mode 100644 index 0000000..8498f0f --- /dev/null +++ b/src/libstddjb/sig_blocknone.c @@ -0,0 +1,11 @@ +/* ISC license. */ + +#include <signal.h> +#include <skalibs/sig.h> + +void sig_blocknone (void) +{ + sigset_t ss ; + sigemptyset(&ss) ; + sigprocmask(SIG_SETMASK, &ss, 0) ; +} diff --git a/src/libstddjb/sig_blockset.c b/src/libstddjb/sig_blockset.c new file mode 100644 index 0000000..206c157 --- /dev/null +++ b/src/libstddjb/sig_blockset.c @@ -0,0 +1,9 @@ +/* ISC license. */ + +#include <signal.h> +#include <skalibs/sig.h> + +void sig_blockset (sigset_t const *set) +{ + sigprocmask(SIG_SETMASK, set, 0) ; +} diff --git a/src/libstddjb/sig_catch.c b/src/libstddjb/sig_catch.c new file mode 100644 index 0000000..d0a72df --- /dev/null +++ b/src/libstddjb/sig_catch.c @@ -0,0 +1,11 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include <skalibs/sig.h> + +int sig_catch (int sig, skasighandler_t_ref f) +{ + struct skasigaction ssa = { f, SKASA_MASKALL | SKASA_NOCLDSTOP } ; + return sig_catcha(sig, &ssa) ; +} diff --git a/src/libstddjb/sig_pause.c b/src/libstddjb/sig_pause.c new file mode 100644 index 0000000..7de8ff5 --- /dev/null +++ b/src/libstddjb/sig_pause.c @@ -0,0 +1,11 @@ +/* ISC license. */ + +#include <signal.h> +#include <skalibs/sig.h> + +void sig_pause (void) +{ + sigset_t ss ; + sigemptyset(&ss) ; + sigsuspend(&ss) ; +} diff --git a/src/libstddjb/sig_push.c b/src/libstddjb/sig_push.c new file mode 100644 index 0000000..96e5fb2 --- /dev/null +++ b/src/libstddjb/sig_push.c @@ -0,0 +1,11 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include <skalibs/sig.h> + +int sig_push (int sig, skasighandler_t_ref f) +{ + struct skasigaction ssa = { f, SKASA_MASKALL | SKASA_NOCLDSTOP } ; + return sig_pusha(sig, &ssa) ; +} diff --git a/src/libstddjb/sig_restoreto.c b/src/libstddjb/sig_restoreto.c new file mode 100644 index 0000000..523b14a --- /dev/null +++ b/src/libstddjb/sig_restoreto.c @@ -0,0 +1,17 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include <signal.h> +#include <skalibs/sig.h> + +void sig_restoreto (sigset_t const *set, unsigned int n) +{ + register unsigned int i = 1 ; + for (; i <= n ; i++) + { + register int h = sigismember(set, i) ; + if (h < 0) continue ; + if (h) sig_restore(i) ; + } +} diff --git a/src/libstddjb/sig_shield.c b/src/libstddjb/sig_shield.c new file mode 100644 index 0000000..ee5d9a9 --- /dev/null +++ b/src/libstddjb/sig_shield.c @@ -0,0 +1,17 @@ +/* ISC license. */ + +#include <signal.h> +#include <skalibs/sig.h> + +void sig_shield (void) +{ + sigset_t ss ; + sigemptyset(&ss) ; + sigaddset(&ss, SIGTERM) ; + sigaddset(&ss, SIGQUIT) ; + sigaddset(&ss, SIGABRT) ; + sigaddset(&ss, SIGINT) ; + sigaddset(&ss, SIGPIPE) ; + sigaddset(&ss, SIGHUP) ; + sigprocmask(SIG_BLOCK, &ss, 0) ; +} diff --git a/src/libstddjb/sig_stack.c b/src/libstddjb/sig_stack.c new file mode 100644 index 0000000..c414a88 --- /dev/null +++ b/src/libstddjb/sig_stack.c @@ -0,0 +1,29 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include <errno.h> +#include <signal.h> +#include <skalibs/sig.h> +#include <skalibs/nsig.h> + +static struct skasigaction skasigstack[NSIG][SIGSTACKSIZE] ; +static unsigned int sigsp[NSIG] ; + +int sig_pusha (int sig, struct skasigaction const *ssa) +{ + if ((sig <= 0) || (sig > NSIG)) return (errno = EINVAL, -1) ; + if (sigsp[sig-1] >= SIGSTACKSIZE) return (errno = ENOBUFS, -1) ; + if (skasigaction(sig, ssa, &skasigstack[sig-1][sigsp[sig-1]]) == -1) + return -1 ; + return ++sigsp[sig-1] ; +} + +int sig_pop (int sig) +{ + if ((sig <= 0) || (sig > NSIG)) return (errno = EINVAL, -1) ; + if (!sigsp[sig-1]) return (errno = EFAULT, -1); + if (skasigaction(sig, &skasigstack[sig-1][sigsp[sig-1]-1], 0) == -1) + return -1 ; + return --sigsp[sig-1] ; +} diff --git a/src/libstddjb/sig_unblock.c b/src/libstddjb/sig_unblock.c new file mode 100644 index 0000000..26d5c1b --- /dev/null +++ b/src/libstddjb/sig_unblock.c @@ -0,0 +1,12 @@ +/* ISC license. */ + +#include <signal.h> +#include <skalibs/sig.h> + +void sig_unblock (int sig) +{ + sigset_t ss ; + sigemptyset(&ss) ; + sigaddset(&ss, sig) ; + sigprocmask(SIG_UNBLOCK, &ss, 0) ; +} diff --git a/src/libstddjb/sig_unshield.c b/src/libstddjb/sig_unshield.c new file mode 100644 index 0000000..24918b4 --- /dev/null +++ b/src/libstddjb/sig_unshield.c @@ -0,0 +1,17 @@ +/* ISC license. */ + +#include <signal.h> +#include <skalibs/sig.h> + +void sig_unshield (void) +{ + sigset_t ss ; + sigemptyset(&ss) ; + sigaddset(&ss, SIGTERM) ; + sigaddset(&ss, SIGQUIT) ; + sigaddset(&ss, SIGABRT) ; + sigaddset(&ss, SIGINT) ; + sigaddset(&ss, SIGPIPE) ; + sigaddset(&ss, SIGHUP) ; + sigprocmask(SIG_UNBLOCK, &ss, 0) ; +} diff --git a/src/libstddjb/sigfpe.c b/src/libstddjb/sigfpe.c new file mode 100644 index 0000000..2ff92a7 --- /dev/null +++ b/src/libstddjb/sigfpe.c @@ -0,0 +1,9 @@ +/* ISC license. */ + +#include <signal.h> +#include <skalibs/segfault.h> + +int sigfpe (void) +{ + return raise(SIGFPE) == 0 ; +} diff --git a/src/libstddjb/sigsegv.c b/src/libstddjb/sigsegv.c new file mode 100644 index 0000000..80c963c --- /dev/null +++ b/src/libstddjb/sigsegv.c @@ -0,0 +1,9 @@ +/* ISC license. */ + +#include <signal.h> +#include <skalibs/segfault.h> + +int sigsegv (void) +{ + return raise(SIGSEGV) == 0 ; +} diff --git a/src/libstddjb/siovec_bytechr.c b/src/libstddjb/siovec_bytechr.c new file mode 100644 index 0000000..a825488 --- /dev/null +++ b/src/libstddjb/siovec_bytechr.c @@ -0,0 +1,17 @@ +/* ISC license. */ + +#include <skalibs/bytestr.h> +#include <skalibs/siovec.h> + +unsigned int siovec_bytechr (siovec_t const *v, unsigned int n, char c) +{ + unsigned int w = 0 ; + unsigned int i = 0 ; + for (; i < n ; i++) + { + register unsigned int pos = byte_chr(v[i].s, v[i].len, c) ; + w += pos ; + if (pos < v[i].len) break ; + } + return w ; +} diff --git a/src/libstddjb/siovec_bytein.c b/src/libstddjb/siovec_bytein.c new file mode 100644 index 0000000..e9db87d --- /dev/null +++ b/src/libstddjb/siovec_bytein.c @@ -0,0 +1,17 @@ +/* ISC license. */ + +#include <skalibs/bytestr.h> +#include <skalibs/siovec.h> + +unsigned int siovec_bytein (siovec_t const *v, unsigned int n, char const *sep, unsigned int seplen) +{ + unsigned int w = 0 ; + unsigned int i = 0 ; + for (; i < n ; i++) + { + register unsigned int pos = byte_in(v[i].s, v[i].len, sep, seplen) ; + w += pos ; + if (pos < v[i].len) break ; + } + return w ; +} diff --git a/src/libstddjb/siovec_deal.c b/src/libstddjb/siovec_deal.c new file mode 100644 index 0000000..fffea92 --- /dev/null +++ b/src/libstddjb/siovec_deal.c @@ -0,0 +1,24 @@ +/* ISC license. */ + +#include <skalibs/bytestr.h> +#include <skalibs/siovec.h> + +unsigned int siovec_deal (siovec_t const *vj, unsigned int nj, siovec_t const *vi, unsigned int ni) +{ + unsigned int w = 0 ; + unsigned int i = 0 ; + unsigned int j = 0 ; + unsigned int wi = 0 ; + unsigned int wj = 0 ; + while (i < ni && j < nj) + { + register unsigned int tor = vi[i].len - wi ; + register unsigned int tow = vj[j].len - wj ; + register unsigned int len = tor < tow ? tor : tow ; + byte_copy(vj[j].s + wj, len, vi[i].s + wi) ; + wi += len ; wj += len ; w += len ; + if (wi >= vi[i].len) { wi = 0 ; i++ ; } + if (wj >= vj[j].len) { wj = 0 ; j++ ; } + } + return w ; +} diff --git a/src/libstddjb/siovec_from_iovec.c b/src/libstddjb/siovec_from_iovec.c new file mode 100644 index 0000000..ffc0508 --- /dev/null +++ b/src/libstddjb/siovec_from_iovec.c @@ -0,0 +1,14 @@ +/* ISC license. */ + +#include <sys/types.h> +#include <sys/uio.h> +#include <skalibs/siovec.h> + +void siovec_from_iovec (siovec_t *v, struct iovec const *iov, unsigned int n) +{ + while (n--) + { + v[n].s = iov[n].iov_base ; + v[n].len = iov[n].iov_len ; + } +} diff --git a/src/libstddjb/siovec_gather.c b/src/libstddjb/siovec_gather.c new file mode 100644 index 0000000..23ae28a --- /dev/null +++ b/src/libstddjb/siovec_gather.c @@ -0,0 +1,18 @@ +/* ISC license. */ + +#include <skalibs/bytestr.h> +#include <skalibs/siovec.h> + +unsigned int siovec_gather (siovec_t const *v, unsigned int n, char *s, unsigned int max) +{ + unsigned int w = 0 ; + register unsigned int i = 0 ; + for (; i < n && w < max ; i++) + { + register unsigned int len = v[i].len ; + if ((w + len) > max) len = max - w ; + byte_copy(s + w, len, v[i].s) ; + w += len ; + } + return w ; +} diff --git a/src/libstddjb/siovec_len.c b/src/libstddjb/siovec_len.c new file mode 100644 index 0000000..5d53e53 --- /dev/null +++ b/src/libstddjb/siovec_len.c @@ -0,0 +1,10 @@ +/* ISC license. */ + +#include <skalibs/siovec.h> + +unsigned int siovec_len (siovec_t const *v, register unsigned int n) +{ + register unsigned int w = 0 ; + while (n--) w += v[n].len ; + return w ; +} diff --git a/src/libstddjb/siovec_scatter.c b/src/libstddjb/siovec_scatter.c new file mode 100644 index 0000000..256bef5 --- /dev/null +++ b/src/libstddjb/siovec_scatter.c @@ -0,0 +1,18 @@ +/* ISC license. */ + +#include <skalibs/bytestr.h> +#include <skalibs/siovec.h> + +unsigned int siovec_scatter (siovec_t const *v, unsigned int n, char const *s, unsigned int len) +{ + unsigned int w = 0 ; + register unsigned int i = 0 ; + for (; i < n && w < len ; i++) + { + register unsigned int chunklen = v[i].len ; + if (w + chunklen > len) chunklen = len - w ; + byte_copy(v[i].s, chunklen, s + w) ; + w += chunklen ; + } + return w ; +} diff --git a/src/libstddjb/siovec_seek.c b/src/libstddjb/siovec_seek.c new file mode 100644 index 0000000..34a8918 --- /dev/null +++ b/src/libstddjb/siovec_seek.c @@ -0,0 +1,25 @@ +/* ISC license. */ + +#include <skalibs/bytestr.h> +#include <skalibs/siovec.h> + +unsigned int siovec_seek (siovec_t *v, unsigned int n, unsigned int len) +{ + unsigned int w = 0 ; + register unsigned int i = 0 ; + for (; i < n ; i++) + { + if (len < v[i].len) break ; + w += v[i].len ; + len -= v[i].len ; + v[i].s = 0 ; + v[i].len = 0 ; + } + if (i < n) + { + v[i].s += len ; + v[i].len -= len ; + w += len ; + } + return w ; +} diff --git a/src/libstddjb/skagetln.c b/src/libstddjb/skagetln.c new file mode 100644 index 0000000..056cc38 --- /dev/null +++ b/src/libstddjb/skagetln.c @@ -0,0 +1,27 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/buffer.h> +#include <skalibs/siovec.h> +#include <skalibs/stralloc.h> +#include <skalibs/skamisc.h> + +int skagetln (buffer *b, stralloc *sa, char sep) +{ + unsigned int start = sa->len ; + for (;;) + { + siovec_t v[2] ; + unsigned int pos ; + int r ; + buffer_rpeek(b, v) ; + pos = siovec_bytechr(v, 2, sep) ; + 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 ; + 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/skagetlnsep.c b/src/libstddjb/skagetlnsep.c new file mode 100644 index 0000000..1d3b4ef --- /dev/null +++ b/src/libstddjb/skagetlnsep.c @@ -0,0 +1,27 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/buffer.h> +#include <skalibs/siovec.h> +#include <skalibs/stralloc.h> +#include <skalibs/skamisc.h> + +int skagetlnsep (buffer *b, stralloc *sa, char const *sep, unsigned int seplen) +{ + unsigned int start = sa->len ; + for (;;) + { + siovec_t v[2] ; + unsigned int 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 ; + 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/skasig_dfl.c b/src/libstddjb/skasig_dfl.c new file mode 100644 index 0000000..ca97b4f --- /dev/null +++ b/src/libstddjb/skasig_dfl.c @@ -0,0 +1,7 @@ +/* ISC license. */ + +#include <signal.h> +#include <skalibs/sig.h> + +struct skasigaction const SKASIG_DFL = { SIG_DFL, 0 } ; +struct skasigaction const SKASIG_IGN = { SIG_IGN, 0 } ; diff --git a/src/libstddjb/skasigaction.c b/src/libstddjb/skasigaction.c new file mode 100644 index 0000000..a673fcb --- /dev/null +++ b/src/libstddjb/skasigaction.c @@ -0,0 +1,24 @@ +/* ISC license. */ + +#include <signal.h> +#include <skalibs/sysdeps.h> +#include <skalibs/sig.h> + +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 ; +} diff --git a/src/libstddjb/slurp.c b/src/libstddjb/slurp.c new file mode 100644 index 0000000..553b29e --- /dev/null +++ b/src/libstddjb/slurp.c @@ -0,0 +1,31 @@ +/* ISC license. */ + +#include <skalibs/allreadwrite.h> +#include <skalibs/stralloc.h> +#include <skalibs/djbunix.h> + +#define N 4096 + +int slurp (stralloc *sa, int fd) +{ + register unsigned int salen = sa->len ; + for (;;) + { + int r ; + if (!stralloc_readyplus(sa, N)) break ; + r = fd_read(fd, sa->s + sa->len, N) ; + switch (r) + { + case -1: goto err ; + case 0: + stralloc_shrink(sa) ; + return 1 ; + default: + sa->len += r ; + } + } +err: + sa->len = salen ; + stralloc_shrink(sa) ; + return 0 ; +} diff --git a/src/libstddjb/socket_accept4.c b/src/libstddjb/socket_accept4.c new file mode 100644 index 0000000..e504375 --- /dev/null +++ b/src/libstddjb/socket_accept4.c @@ -0,0 +1,39 @@ +/* ISC license. */ + +#include <skalibs/sysdeps.h> +#include <skalibs/nonposix.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <errno.h> +#include <skalibs/uint16.h> +#include <skalibs/bytestr.h> +#include <skalibs/djbunix.h> +#include <skalibs/socket.h> + +int socket_accept4_internal (int s, char *ip, uint16 *port, unsigned int options) +{ + struct sockaddr_in sa ; + socklen_t dummy = sizeof sa ; + register int fd ; + do +#ifdef SKALIBS_HASACCEPT4 + fd = accept4(s, (struct sockaddr *)&sa, &dummy, ((options & DJBUNIX_FLAG_NB) ? SOCK_NONBLOCK : 0) | ((options & DJBUNIX_FLAG_COE) ? SOCK_CLOEXEC : 0)) ; +#else + fd = accept(s, (struct sockaddr *)&sa, &dummy) ; +#endif + while ((fd < 0) && (errno == EINTR)) ; + if (fd < 0) return -1 ; +#ifndef SKALIBS_HASACCEPT4 + if ((((options & DJBUNIX_FLAG_NB) ? ndelay_on(fd) : ndelay_off(fd)) < 0) + || (((options & DJBUNIX_FLAG_COE) ? coe(fd) : uncoe(fd)) < 0)) + { + register int e = errno ; + fd_close(fd) ; + errno = e ; + return -1 ; + } +#endif + byte_copy(ip, 4, (char *)&sa.sin_addr.s_addr) ; + uint16_unpack_big((char *)&sa.sin_port, port) ; + return fd ; +} diff --git a/src/libstddjb/socket_accept4_u32.c b/src/libstddjb/socket_accept4_u32.c new file mode 100644 index 0000000..18455fc --- /dev/null +++ b/src/libstddjb/socket_accept4_u32.c @@ -0,0 +1,13 @@ +/* ISC license. */ + +#include <skalibs/uint16.h> +#include <skalibs/uint32.h> +#include <skalibs/socket.h> + +int socket_accept4_internal_u32 (int s, uint32 *ip, uint16 *port, unsigned int options) +{ + char pack[4] ; + register int r = socket_accept4_internal(s, pack, port, options) ; + if (r >= 0) uint32_unpack_big(pack, ip) ; + return r ; +} diff --git a/src/libstddjb/socket_accept6.c b/src/libstddjb/socket_accept6.c new file mode 100644 index 0000000..8e87e46 --- /dev/null +++ b/src/libstddjb/socket_accept6.c @@ -0,0 +1,55 @@ +/* ISC license. */ + +#include <skalibs/sysdeps.h> +#include <skalibs/nonposix.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <errno.h> +#include <skalibs/uint16.h> +#include <skalibs/bytestr.h> +#include <skalibs/djbunix.h> +#include <skalibs/ip46.h> +#include <skalibs/socket.h> + +#ifdef SKALIBS_IPV6_ENABLED + +int socket_accept6_internal (int s, char *ip6, uint16 *port, unsigned int options) +{ + struct sockaddr_in6 sa ; + socklen_t dummy = sizeof sa ; + register int fd ; + do +#ifdef SKALIBS_HASACCEPT4 + fd = accept4(s, (struct sockaddr *)&sa, &dummy, ((options & DJBUNIX_FLAG_NB) ? SOCK_NONBLOCK : 0) | ((options & DJBUNIX_FLAG_COE) ? SOCK_CLOEXEC : 0)) ; +#else + fd = accept(s, (struct sockaddr *)&sa, &dummy) ; +#endif + while ((fd < 0) && (errno == EINTR)) ; + if (fd < 0) return -1 ; +#ifndef SKALIBS_HASACCEPT4 + if ((((options & DJBUNIX_FLAG_NB) ? ndelay_on(fd) : ndelay_off(fd)) < 0) + || (((options & DJBUNIX_FLAG_COE) ? coe(fd) : uncoe(fd)) < 0)) + { + register int e = errno ; + fd_close(fd) ; + errno = e ; + return -1 ; + } +#endif + byte_copy(ip6, 16, sa.sin6_addr.s6_addr) ; + uint16_unpack_big((char *)&sa.sin6_port, port) ; + return fd ; +} + +#else + +int socket_accept6_internal (int s, char *ip6, uint16 *port, unsigned int options) +{ + (void)s ; + (void)ip6 ; + (void)port ; + (void)options ; + return (errno = ENOSYS, -1) ; +} + +#endif diff --git a/src/libstddjb/socket_bind4.c b/src/libstddjb/socket_bind4.c new file mode 100644 index 0000000..e9c9593 --- /dev/null +++ b/src/libstddjb/socket_bind4.c @@ -0,0 +1,19 @@ +/* ISC license. */ + +#include <skalibs/nonposix.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <skalibs/uint16.h> +#include <skalibs/bytestr.h> +#include <skalibs/socket.h> + +int socket_bind4 (int s, char const *ip, uint16 port) +{ + struct sockaddr_in sa ; + byte_zero(&sa, sizeof sa) ; + sa.sin_family = AF_INET ; + uint16_big_endian((char *)&port, 1) ; + sa.sin_port = port ; + byte_copy(&sa.sin_addr.s_addr, 4, ip) ; + return bind(s, (struct sockaddr *)&sa, sizeof sa) ; +} diff --git a/src/libstddjb/socket_bind4r.c b/src/libstddjb/socket_bind4r.c new file mode 100644 index 0000000..55f0903 --- /dev/null +++ b/src/libstddjb/socket_bind4r.c @@ -0,0 +1,13 @@ +/* ISC license. */ + +#include <skalibs/nonposix.h> +#include <sys/socket.h> +#include <skalibs/uint16.h> +#include <skalibs/socket.h> + +int socket_bind4_reuse (int s, char const *ip, uint16 port) +{ + unsigned int opt = 1 ; + setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof opt) ; + return socket_bind4(s, ip, port) ; +} diff --git a/src/libstddjb/socket_bind6.c b/src/libstddjb/socket_bind6.c new file mode 100644 index 0000000..fa4cae1 --- /dev/null +++ b/src/libstddjb/socket_bind6.c @@ -0,0 +1,34 @@ +/* ISC license. */ + +#include <skalibs/nonposix.h> +#include <errno.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <skalibs/uint16.h> +#include <skalibs/bytestr.h> +#include <skalibs/socket.h> +#include <skalibs/ip46.h> + +#ifdef SKALIBS_IPV6_ENABLED + +int socket_bind6 (int s, char const *ip6, uint16 port) +{ + struct sockaddr_in6 sa ; + byte_zero(&sa, sizeof sa) ; + sa.sin6_family = AF_INET6 ; + uint16_pack_big((char *)&sa.sin6_port, port) ; + byte_copy(sa.sin6_addr.s6_addr, 16, ip6) ; + return bind(s, (struct sockaddr *)&sa, sizeof sa) ; +} + +#else + +int socket_bind6 (int s, char const *ip6, uint16 port) +{ + (void)s ; + (void)ip6 ; + (void)port ; + return (errno = ENOSYS, -1) ; +} + +#endif diff --git a/src/libstddjb/socket_bind6r.c b/src/libstddjb/socket_bind6r.c new file mode 100644 index 0000000..6bf5e0d --- /dev/null +++ b/src/libstddjb/socket_bind6r.c @@ -0,0 +1,13 @@ +/* ISC license. */ + +#include <skalibs/nonposix.h> +#include <sys/socket.h> +#include <skalibs/uint16.h> +#include <skalibs/socket.h> + +int socket_bind6_reuse (int s, char const *ip6, uint16 port) +{ + unsigned int opt = 1 ; + setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof opt) ; + return socket_bind6(s, ip6, port) ; +} diff --git a/src/libstddjb/socket_conn4.c b/src/libstddjb/socket_conn4.c new file mode 100644 index 0000000..0180378 --- /dev/null +++ b/src/libstddjb/socket_conn4.c @@ -0,0 +1,24 @@ +/* ISC license. */ + +#include <skalibs/nonposix.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <errno.h> +#include <skalibs/uint16.h> +#include <skalibs/bytestr.h> +#include <skalibs/socket.h> + +int socket_connect4 (int s, char const *ip, uint16 port) +{ + struct sockaddr_in sa ; + register int r ; + byte_zero(&sa, sizeof sa) ; + sa.sin_family = AF_INET ; + uint16_big_endian((char *)&port, 1) ; + sa.sin_port = port ; + byte_copy(&sa.sin_addr.s_addr, 4, ip) ; + do r = connect(s, (struct sockaddr *)&sa, sizeof sa) ; + while ((r == -1) && (errno == EINTR)) ; + if ((r == -1) && (errno == EALREADY)) errno = EINPROGRESS ; + return r ; +} diff --git a/src/libstddjb/socket_conn4_u32.c b/src/libstddjb/socket_conn4_u32.c new file mode 100644 index 0000000..20887ce --- /dev/null +++ b/src/libstddjb/socket_conn4_u32.c @@ -0,0 +1,12 @@ +/* ISC license. */ + +#include <skalibs/uint16.h> +#include <skalibs/uint32.h> +#include <skalibs/socket.h> + +int socket_connect4_u32 (int s, uint32 ip, uint16 port) +{ + char pack[4] ; + uint32_pack_big(pack, ip) ; + return socket_connect4(s, pack, port) ; +} diff --git a/src/libstddjb/socket_conn6.c b/src/libstddjb/socket_conn6.c new file mode 100644 index 0000000..49a64d1 --- /dev/null +++ b/src/libstddjb/socket_conn6.c @@ -0,0 +1,38 @@ +/* ISC license. */ + +#include <skalibs/nonposix.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <errno.h> +#include <skalibs/uint16.h> +#include <skalibs/bytestr.h> +#include <skalibs/socket.h> +#include <skalibs/ip46.h> + +#ifdef SKALIBS_IPV6_ENABLED + +int socket_connect6 (int s, char const *ip6, uint16 port) +{ + struct sockaddr_in6 sa ; + register int r ; + byte_zero(&sa, sizeof sa) ; + sa.sin6_family = AF_INET6 ; + uint16_pack_big((char *)&sa.sin6_port,port) ; + byte_copy(sa.sin6_addr.s6_addr, 16, ip6) ; + do r = connect(s, (struct sockaddr *)&sa, sizeof sa) ; + while ((r == -1) && (errno == EINTR)) ; + if ((r == -1) && (errno == EALREADY)) errno = EINPROGRESS ; + return r ; +} + +#else + +int socket_connect6 (int s, char const *ip6, uint16 port) +{ + (void)s ; + (void)ip6 ; + (void)port ; + return (errno = ENOSYS, -1) ; +} + +#endif diff --git a/src/libstddjb/socket_connected.c b/src/libstddjb/socket_connected.c new file mode 100644 index 0000000..895eaf3 --- /dev/null +++ b/src/libstddjb/socket_connected.c @@ -0,0 +1,20 @@ +/* ISC license. */ + +#include <skalibs/nonposix.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <skalibs/allreadwrite.h> +#include <skalibs/socket.h> + +int socket_connected (int s) +{ + struct sockaddr_in sa ; + socklen_t dummy = sizeof sa ; + if (getpeername(s, (struct sockaddr *)&sa, &dummy) == -1) + { + char ch ; + fd_read(s, &ch, 1) ; /* sets errno */ + return 0 ; + } + return 1 ; +} diff --git a/src/libstddjb/socket_deadlineconnstamp4.c b/src/libstddjb/socket_deadlineconnstamp4.c new file mode 100644 index 0000000..618852f --- /dev/null +++ b/src/libstddjb/socket_deadlineconnstamp4.c @@ -0,0 +1,14 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/uint16.h> +#include <skalibs/error.h> +#include <skalibs/tai.h> +#include <skalibs/socket.h> + +int socket_deadlineconnstamp (int s, char const *ip, uint16 port, tain_t const *deadline, tain_t *stamp) +{ + if (socket_connect4(s, ip, port) >= 0) return 1 ; + if (!error_isagain(errno) && !error_isalready(errno)) return 0 ; + return socket_waitconn(s, deadline, stamp) ; +} diff --git a/src/libstddjb/socket_deadlineconnstamp46.c b/src/libstddjb/socket_deadlineconnstamp46.c new file mode 100644 index 0000000..4ab2c9a --- /dev/null +++ b/src/libstddjb/socket_deadlineconnstamp46.c @@ -0,0 +1,15 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/uint16.h> +#include <skalibs/error.h> +#include <skalibs/tai.h> +#include <skalibs/socket.h> +#include <skalibs/ip46.h> + +int socket_deadlineconnstamp46 (int s, ip46_t const *i, uint16 port, tain_t const *deadline, tain_t *stamp) +{ + if (socket_connect46(s, i, port) >= 0) return 1 ; + if (!error_isagain(errno) && !error_isalready(errno)) return 0 ; + return socket_waitconn(s, deadline, stamp) ; +} diff --git a/src/libstddjb/socket_deadlineconnstamp4_u32.c b/src/libstddjb/socket_deadlineconnstamp4_u32.c new file mode 100644 index 0000000..4a82e50 --- /dev/null +++ b/src/libstddjb/socket_deadlineconnstamp4_u32.c @@ -0,0 +1,13 @@ +/* ISC license. */ + +#include <skalibs/uint16.h> +#include <skalibs/uint32.h> +#include <skalibs/tai.h> +#include <skalibs/socket.h> + +int socket_deadlineconnstamp4_u32 (int s, uint32 ip, uint16 port, tain_t const *deadline, tain_t *stamp) +{ + char pack[4] ; + uint32_pack_big(pack, ip) ; + return socket_deadlineconnstamp4(s, pack, port, deadline, stamp) ; +} diff --git a/src/libstddjb/socket_deadlineconnstamp6.c b/src/libstddjb/socket_deadlineconnstamp6.c new file mode 100644 index 0000000..a797d1e --- /dev/null +++ b/src/libstddjb/socket_deadlineconnstamp6.c @@ -0,0 +1,14 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/uint16.h> +#include <skalibs/error.h> +#include <skalibs/tai.h> +#include <skalibs/socket.h> + +int socket_deadlineconnstamp6 (int s, char const *ip, uint16 port, tain_t const *deadline, tain_t *stamp) +{ + if (socket_connect6(s, ip, port) >= 0) return 1 ; + if (!error_isagain(errno) && !error_isalready(errno)) return 0 ; + return socket_waitconn(s, deadline, stamp) ; +} diff --git a/src/libstddjb/socket_delay.c b/src/libstddjb/socket_delay.c new file mode 100644 index 0000000..7d1a8db --- /dev/null +++ b/src/libstddjb/socket_delay.c @@ -0,0 +1,13 @@ +/* ISC license. */ + +#include <skalibs/nonposix.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <netinet/tcp.h> +#include <skalibs/socket.h> + +int socket_tcpnodelay (int s) +{ + static int const opt = TCP_NODELAY ; + return setsockopt(s, IPPROTO_TCP, 1, &opt, sizeof(int)) ; +} diff --git a/src/libstddjb/socket_internal.c b/src/libstddjb/socket_internal.c new file mode 100644 index 0000000..ae57e06 --- /dev/null +++ b/src/libstddjb/socket_internal.c @@ -0,0 +1,33 @@ +/* ISC license. */ + +#include <skalibs/sysdeps.h> +#include <skalibs/nonposix.h> +#include <sys/socket.h> +#include <errno.h> +#include <skalibs/djbunix.h> + +#ifdef SKALIBS_HASACCEPT4 + +int socket_internal (int domain, int type, int protocol, unsigned int flags) +{ + return socket(domain, type | ((flags & DJBUNIX_FLAG_NB) ? SOCK_NONBLOCK : 0) | ((flags & DJBUNIX_FLAG_COE) ? SOCK_CLOEXEC : 0), protocol) ; +} + +#else + +int socket_internal (int domain, int type, int protocol, unsigned int flags) +{ + int s = socket(domain, type, protocol) ; + if (s == -1) return -1 ; + if ((((flags & DJBUNIX_FLAG_NB) ? ndelay_on(s) : ndelay_off(s)) < 0) + || (((flags & DJBUNIX_FLAG_COE) ? coe(s) : uncoe(s)) < 0)) + { + register int e = errno ; + fd_close(s) ; + errno = e ; + return -1 ; + } + return s ; +} + +#endif diff --git a/src/libstddjb/socket_ioloop.c b/src/libstddjb/socket_ioloop.c new file mode 100644 index 0000000..a158f01 --- /dev/null +++ b/src/libstddjb/socket_ioloop.c @@ -0,0 +1,30 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/error.h> +#include <skalibs/uint16.h> +#include <skalibs/tai.h> +#include <skalibs/iopause.h> +#include <skalibs/socket.h> + +int socket_ioloop (int s, char *buf, unsigned int len, char *ip, uint16 *port, socket_io_func_t_ref f, int w, tain_t const *deadline, tain_t *stamp) +{ + iopause_fd x = { .fd = s, .events = w ? IOPAUSE_WRITE : IOPAUSE_READ, .revents = 0 } ; + for (;;) + { + register int r = iopause_stamp(&x, 1, deadline, stamp) ; + if (r < 0) return -1 ; + if (!r) return (errno = ETIMEDOUT, -1) ; + if (x.revents & IOPAUSE_EXCEPT) return (errno = EIO, -1) ; + if (x.revents & x.events) + { + r = (*f)(s, buf, len, ip, port) ; + if (r < 0) + { + if (!error_isagain(errno)) return -1 ; + } + else return r ; + } + } +} + diff --git a/src/libstddjb/socket_ioloop_send4.c b/src/libstddjb/socket_ioloop_send4.c new file mode 100644 index 0000000..aff251d --- /dev/null +++ b/src/libstddjb/socket_ioloop_send4.c @@ -0,0 +1,8 @@ +/* ISC license. */ + +#include <skalibs/socket.h> + +int socket_ioloop_send4 (int fd, char *s, unsigned int len, char *ip, uint16 *port) +{ + return socket_send4(fd, s, len, ip, *port) ; +} diff --git a/src/libstddjb/socket_ioloop_send6.c b/src/libstddjb/socket_ioloop_send6.c new file mode 100644 index 0000000..151a58c --- /dev/null +++ b/src/libstddjb/socket_ioloop_send6.c @@ -0,0 +1,8 @@ +/* ISC license. */ + +#include <skalibs/socket.h> + +int socket_ioloop_send6 (int fd, char *s, unsigned int len, char *ip, uint16 *port) +{ + return socket_send6(fd, s, len, ip, *port) ; +} diff --git a/src/libstddjb/socket_local4.c b/src/libstddjb/socket_local4.c new file mode 100644 index 0000000..90ae93a --- /dev/null +++ b/src/libstddjb/socket_local4.c @@ -0,0 +1,20 @@ +/* ISC license. */ + +#include <skalibs/nonposix.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <skalibs/uint16.h> +#include <skalibs/bytestr.h> +#include <skalibs/socket.h> + +int socket_local4 (int s, char *ip, uint16 *port) +{ + struct sockaddr_in sa ; + socklen_t dummy = sizeof sa ; + + if (getsockname(s, (struct sockaddr *)&sa, &dummy) == -1) + return -1 ; + byte_copy(ip, 4, (char *)&sa.sin_addr.s_addr) ; + uint16_unpack_big((char *)&sa.sin_port, port) ; + return 0 ; +} diff --git a/src/libstddjb/socket_local46.c b/src/libstddjb/socket_local46.c new file mode 100644 index 0000000..a53bcac --- /dev/null +++ b/src/libstddjb/socket_local46.c @@ -0,0 +1,36 @@ +/* ISC license. */ + +#include <skalibs/nonposix.h> +#include <errno.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <skalibs/uint16.h> +#include <skalibs/bytestr.h> +#include <skalibs/ip46.h> + +#ifdef SKALIBS_IPV6_ENABLED + +int socket_local46 (int s, ip46_t_ref ip, uint16 *port) +{ + struct sockaddr sa ; + socklen_t dummy = sizeof sa ; + if (getsockname(s, &sa, &dummy) < 0) return -1 ; + if (sa.sa_family == AF_INET6) + { + register struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)&sa ; + byte_copy(ip->ip, 16, sa6->sin6_addr.s6_addr) ; + uint16_unpack_big((char *)&sa6->sin6_port, port) ; + ip->is6 = 1 ; + } + else if (sa.sa_family == AF_INET) + { + register struct sockaddr_in *sa4 = (struct sockaddr_in *)&sa ; + byte_copy(ip->ip, 4, &sa4->sin_addr.s_addr) ; + uint16_unpack_big((char *)&sa4->sin_port, port) ; + ip->is6 = 0 ; + } + else return (errno = EAFNOSUPPORT, -1) ; + return 0 ; +} + +#endif diff --git a/src/libstddjb/socket_local6.c b/src/libstddjb/socket_local6.c new file mode 100644 index 0000000..31ee1f0 --- /dev/null +++ b/src/libstddjb/socket_local6.c @@ -0,0 +1,37 @@ +/* ISC license. */ + +#include <skalibs/nonposix.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <skalibs/uint16.h> +#include <skalibs/bytestr.h> +#include <skalibs/socket.h> +#include <skalibs/ip46.h> + +#ifdef SKALIBS_IPV6_ENABLED + +int socket_local6 (int s, char *ip, uint16 *port) +{ + struct sockaddr_in6 sa ; + socklen_t dummy = sizeof sa ; + + if (getsockname(s, (struct sockaddr *)&sa, &dummy) == -1) + return -1 ; + byte_copy(ip, 16, sa.sin6_addr.s6_addr) ; + uint16_unpack_big((char *)&sa.sin6_port, port) ; + return 0 ; +} + +#else + +#include <errno.h> + +int socket_local6 (int s, char *ip, uint16 *port) +{ + (void)s ; + (void)ip ; + (void)port ; + return (errno = ENOSYS, -1) ; +} + +#endif diff --git a/src/libstddjb/socket_recv4.c b/src/libstddjb/socket_recv4.c new file mode 100644 index 0000000..02354e9 --- /dev/null +++ b/src/libstddjb/socket_recv4.c @@ -0,0 +1,22 @@ +/* ISC license. */ + +#include <skalibs/nonposix.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <errno.h> +#include <skalibs/uint16.h> +#include <skalibs/bytestr.h> +#include <skalibs/socket.h> + +int socket_recv4 (int s, char *buf, unsigned int len, char *ip, uint16 *port) +{ + struct sockaddr_in sa ; + socklen_t dummy = sizeof sa ; + register int r ; + do r = recvfrom(s, buf, len, 0, (struct sockaddr *)&sa, &dummy) ; + while ((r == -1) && (errno == EINTR)) ; + if (r == -1) return -1 ; + byte_copy(ip, 4, (char *)&sa.sin_addr) ; + uint16_unpack_big((char *)&sa.sin_port, port) ; + return r ; +} diff --git a/src/libstddjb/socket_recv6.c b/src/libstddjb/socket_recv6.c new file mode 100644 index 0000000..d745604 --- /dev/null +++ b/src/libstddjb/socket_recv6.c @@ -0,0 +1,39 @@ +/* ISC license. */ + +#include <skalibs/nonposix.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <errno.h> +#include <skalibs/uint16.h> +#include <skalibs/bytestr.h> +#include <skalibs/ip46.h> +#include <skalibs/socket.h> + +#ifdef SKALIBS_IPV6_ENABLED + +int socket_recv6 (int s, char *buf, unsigned int len, char *ip6, uint16 *port) +{ + struct sockaddr_in6 sa ; + socklen_t dummy = sizeof sa ; + register int r ; + do r = recvfrom(s, buf, len, 0, (struct sockaddr *)&sa, &dummy) ; + while ((r == -1) && (errno == EINTR)) ; + if (r == -1) return -1 ; + byte_copy(ip6, 16, sa.sin6_addr.s6_addr) ; + uint16_unpack_big((char *)&sa.sin6_port, port) ; + return r ; +} + +#else + +int socket_recv6 (int s, char *buf, unsigned int len, char *ip6, uint16 *port) +{ + (void)s ; + (void)buf ; + (void)len ; + (void)ip6 ; + (void)port ; + return (errno = ENOSYS, -1) ; +} + +#endif diff --git a/src/libstddjb/socket_remote4.c b/src/libstddjb/socket_remote4.c new file mode 100644 index 0000000..767a694 --- /dev/null +++ b/src/libstddjb/socket_remote4.c @@ -0,0 +1,20 @@ +/* ISC license. */ + +#include <skalibs/nonposix.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <skalibs/uint16.h> +#include <skalibs/bytestr.h> +#include <skalibs/socket.h> + +int socket_remote4 (int s, char *ip, uint16 *port) +{ + struct sockaddr_in sa ; + socklen_t dummy = sizeof sa ; + + if (getpeername(s, (struct sockaddr *)&sa, &dummy) == -1) + return -1 ; + byte_copy(ip, 4, (char *)&sa.sin_addr.s_addr) ; + uint16_unpack_big((char *)&sa.sin_port, port) ; + return 0 ; +} diff --git a/src/libstddjb/socket_remote46.c b/src/libstddjb/socket_remote46.c new file mode 100644 index 0000000..835b7c9 --- /dev/null +++ b/src/libstddjb/socket_remote46.c @@ -0,0 +1,36 @@ +/* ISC license. */ + +#include <skalibs/nonposix.h> +#include <errno.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <skalibs/uint16.h> +#include <skalibs/bytestr.h> +#include <skalibs/ip46.h> + +#ifdef SKALIBS_IPV6_ENABLED + +int socket_remote46 (int s, ip46_t_ref ip, uint16 *port) +{ + struct sockaddr sa ; + socklen_t dummy = sizeof sa ; + if (getpeername(s, &sa, &dummy) < 0) return -1 ; + if (sa.sa_family == AF_INET6) + { + register struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)&sa ; + byte_copy(ip->ip, 16, sa6->sin6_addr.s6_addr) ; + uint16_unpack_big((char *)&sa6->sin6_port, port) ; + ip->is6 = 1 ; + } + else if (sa.sa_family == AF_INET) + { + register struct sockaddr_in *sa4 = (struct sockaddr_in *)&sa ; + byte_copy(ip->ip, 4, &sa4->sin_addr.s_addr) ; + uint16_unpack_big((char *)&sa4->sin_port, port) ; + ip->is6 = 0 ; + } + else return (errno = EAFNOSUPPORT, -1) ; + return 0 ; +} + +#endif diff --git a/src/libstddjb/socket_remote6.c b/src/libstddjb/socket_remote6.c new file mode 100644 index 0000000..9d40d70 --- /dev/null +++ b/src/libstddjb/socket_remote6.c @@ -0,0 +1,36 @@ +/* ISC license. */ + +#include <skalibs/nonposix.h> +#include <errno.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <skalibs/uint16.h> +#include <skalibs/bytestr.h> +#include <skalibs/ip46.h> +#include <skalibs/socket.h> + +#ifdef SKALIBS_IPV6_ENABLED + +int socket_remote6 (int s, char *ip, uint16 *port) +{ + struct sockaddr_in6 sa ; + socklen_t dummy = sizeof sa ; + + if (getpeername(s, (struct sockaddr *)&sa, &dummy) == -1) + return -1 ; + byte_copy(ip, 16, sa.sin6_addr.s6_addr) ; + uint16_unpack_big((char *)&sa.sin6_port, port) ; + return 0 ; +} + +#else + +int socket_remote6 (int s, char *ip, uint16 *port) +{ + (void)s ; + (void)ip ; + (void)port ; + return (errno = ENOSYS, -1) ; +} + +#endif diff --git a/src/libstddjb/socket_send4.c b/src/libstddjb/socket_send4.c new file mode 100644 index 0000000..6078dff --- /dev/null +++ b/src/libstddjb/socket_send4.c @@ -0,0 +1,22 @@ +/* ISC license. */ + +#include <skalibs/nonposix.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <errno.h> +#include <skalibs/uint16.h> +#include <skalibs/bytestr.h> +#include <skalibs/socket.h> + +int socket_send4 (int s, char const *buf, unsigned int len, char const *ip, uint16 port) +{ + struct sockaddr_in sa ; + register int r ; + byte_zero((char *)&sa, sizeof sa) ; + sa.sin_family = AF_INET ; + uint16_pack_big((char *)&sa.sin_port, port) ; + byte_copy((char *)&sa.sin_addr, 4, ip) ; + do r = sendto(s, buf, len, 0, (struct sockaddr *)&sa, sizeof sa) ; + while ((r == -1) && (errno == EINTR)) ; + return r ; +} diff --git a/src/libstddjb/socket_send6.c b/src/libstddjb/socket_send6.c new file mode 100644 index 0000000..01319a1 --- /dev/null +++ b/src/libstddjb/socket_send6.c @@ -0,0 +1,39 @@ +/* ISC license. */ + +#include <skalibs/nonposix.h> +#include <errno.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <skalibs/uint16.h> +#include <skalibs/bytestr.h> +#include <skalibs/ip46.h> +#include <skalibs/socket.h> + +#ifdef SKALIBS_IPV6_ENABLED + +int socket_send6 (int s, char const *buf, unsigned int len, char const *ip6, uint16 port) +{ + struct sockaddr_in6 sa ; + register int r ; + byte_zero((char *)&sa, sizeof sa) ; + sa.sin6_family = AF_INET6 ; + uint16_pack_big((char *)&sa.sin6_port, port) ; + byte_copy(sa.sin6_addr.s6_addr, 16, ip6) ; + do r = sendto(s, buf, len, 0, (struct sockaddr *)&sa, sizeof sa) ; + while ((r == -1) && (errno == EINTR)) ; + return r ; +} + +#else + +int socket_send6 (int s, char const *buf, unsigned int len, char const *ip6, uint16 port) +{ + (void)s ; + (void)buf ; + (void)len ; + (void)ip6 ; + (void)port ; + return (errno = ENOSYS, -1) ; +} + +#endif diff --git a/src/libstddjb/socket_tcp4.c b/src/libstddjb/socket_tcp4.c new file mode 100644 index 0000000..8eecb67 --- /dev/null +++ b/src/libstddjb/socket_tcp4.c @@ -0,0 +1,11 @@ +/* ISC license. */ + +#include <skalibs/nonposix.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <skalibs/socket.h> + +int socket_tcp4_internal (unsigned int flags) +{ + return socket_internal(AF_INET, SOCK_STREAM, 0, flags) ; +} diff --git a/src/libstddjb/socket_tcp6.c b/src/libstddjb/socket_tcp6.c new file mode 100644 index 0000000..fd282fc --- /dev/null +++ b/src/libstddjb/socket_tcp6.c @@ -0,0 +1,38 @@ +/* ISC license. */ + +#include <skalibs/nonposix.h> +#include <errno.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <skalibs/djbunix.h> +#include <skalibs/ip46.h> +#include <skalibs/socket.h> + +#ifdef SKALIBS_IPV6_ENABLED + +int socket_tcp6_internal (unsigned int flags) +{ + int fd = socket_internal(AF_INET6, SOCK_STREAM, 0, flags) ; + if (fd < 0) return fd ; + { + int option = 1 ; + if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &option, sizeof(option)) < 0) + { + register int e = errno ; + fd_close(fd) ; + errno = e ; + return -1 ; + } + } + return fd ; +} + +#else + +int socket_tcp6_internal (unsigned int flags) +{ + (void)flags ; + return (errno = ENOSYS, -1) ; +} + +#endif diff --git a/src/libstddjb/socket_timeoutconn.c b/src/libstddjb/socket_timeoutconn.c new file mode 100644 index 0000000..ec7e251 --- /dev/null +++ b/src/libstddjb/socket_timeoutconn.c @@ -0,0 +1,13 @@ +/* ISC license. */ + +#include <skalibs/uint16.h> +#include <skalibs/tai.h> +#include <skalibs/socket.h> + +int socket_timeoutconn (int s, char const *ip, uint16 port, unsigned int timeout) +{ + tain_t stamp, deadline ; + tain_now(&stamp) ; + tain_addsec(&deadline, &stamp, timeout) ; + return socket_deadlineconnstamp4(s, ip, port, &deadline, &stamp) ; +} diff --git a/src/libstddjb/socket_tryr.c b/src/libstddjb/socket_tryr.c new file mode 100644 index 0000000..6544c9d --- /dev/null +++ b/src/libstddjb/socket_tryr.c @@ -0,0 +1,14 @@ +/* ISC license. */ + +#include <skalibs/nonposix.h> +#include <sys/socket.h> +#include <skalibs/socket.h> + +void socket_tryreservein (int s, unsigned int size) +{ + while (size >= 1024) + { + if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, &size, sizeof size) == 0) return ; + size -= (size >> 5) ; + } +} diff --git a/src/libstddjb/socket_udp4.c b/src/libstddjb/socket_udp4.c new file mode 100644 index 0000000..d6e8ead --- /dev/null +++ b/src/libstddjb/socket_udp4.c @@ -0,0 +1,11 @@ +/* ISC license. */ + +#include <skalibs/nonposix.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <skalibs/socket.h> + +int socket_udp4_internal (unsigned int flags) +{ + return socket_internal(AF_INET, SOCK_DGRAM, 0, flags) ; +} diff --git a/src/libstddjb/socket_udp6.c b/src/libstddjb/socket_udp6.c new file mode 100644 index 0000000..41d395a --- /dev/null +++ b/src/libstddjb/socket_udp6.c @@ -0,0 +1,38 @@ +/* ISC license. */ + +#include <skalibs/nonposix.h> +#include <errno.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <skalibs/djbunix.h> +#include <skalibs/ip46.h> +#include <skalibs/socket.h> + +#ifdef SKALIBS_IPV6_ENABLED + +int socket_udp6_internal (unsigned int flags) +{ + int fd = socket_internal(AF_INET6, SOCK_DGRAM, 0, flags) ; + if (fd < 0) return fd ; + { + int option = 1 ; + if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &option, sizeof(option)) < 0) + { + register int e = errno ; + fd_close(fd) ; + errno = e ; + return -1 ; + } + } + return fd ; +} + +#else + +int socket_udp6_internal (unsigned int flags) +{ + (void)flags ; + return (errno = ENOSYS, -1) ; +} + +#endif diff --git a/src/libstddjb/socket_waitconn.c b/src/libstddjb/socket_waitconn.c new file mode 100644 index 0000000..6e5c352 --- /dev/null +++ b/src/libstddjb/socket_waitconn.c @@ -0,0 +1,25 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/allreadwrite.h> +#include <skalibs/tai.h> +#include <skalibs/iopause.h> +#include <skalibs/socket.h> + +int socket_waitconn (int s, tain_t const *deadline, tain_t *stamp) +{ + iopause_fd x = { s, IOPAUSE_WRITE, 0 } ; + for (;;) + { + register int r = iopause_stamp(&x, 1, deadline, stamp) ; + if (r < 0) return 0 ; + if (!r) return (errno = ETIMEDOUT, 0) ; + if (x.revents & IOPAUSE_WRITE) break ; + if (x.revents & IOPAUSE_EXCEPT) + { + fd_write(s, "", 1) ; /* sets errno */ + return 0 ; + } + } + return socket_connected(s) ; +} diff --git a/src/libstddjb/socketpair_internal.c b/src/libstddjb/socketpair_internal.c new file mode 100644 index 0000000..8e62bdf --- /dev/null +++ b/src/libstddjb/socketpair_internal.c @@ -0,0 +1,56 @@ +/* ISC license. */ + +#include <skalibs/sysdeps.h> +#include <skalibs/nonposix.h> +#include <sys/socket.h> +#include <errno.h> +#include <skalibs/djbunix.h> + +#ifdef SKALIBS_HASACCEPT4 + +int socketpair_internal (int domain, int type, int protocol, unsigned int flags, int *sv) +{ + return socketpair(domain, type | ((flags & DJBUNIX_FLAG_NB) ? SOCK_NONBLOCK : 0) | ((flags & DJBUNIX_FLAG_COE) ? SOCK_CLOEXEC : 0), protocol, sv) ; +} + +#else + +int socketpair_internal (int domain, int type, int protocol, unsigned int flags, int *sv) +{ + int fd[2] ; + if (socketpair(domain, type, protocol, fd) < 0) return -1 ; + if (flags & DJBUNIX_FLAG_NB) + { + if (ndelay_on(fd[0]) < 0) goto err ; + if (ndelay_on(fd[1]) < 0) goto err ; + } + else + { + if (ndelay_off(fd[0]) < 0) goto err ; + if (ndelay_off(fd[1]) < 0) goto err ; + } + if (flags & DJBUNIX_FLAG_COE) + { + if (coe(fd[0]) < 0) goto err ; + if (coe(fd[1]) < 0) goto err ; + } + else + { + if (uncoe(fd[0]) < 0) goto err ; + if (uncoe(fd[1]) < 0) goto err ; + } + sv[0] = fd[0] ; + sv[1] = fd[1] ; + return 0 ; + + err: + { + register int e = errno ; + fd_close(fd[1]) ; + fd_close(fd[0]) ; + errno = e ; + } + return -1 ; +} + +#endif diff --git a/src/libstddjb/stamp.c b/src/libstddjb/stamp.c new file mode 100644 index 0000000..65becc6 --- /dev/null +++ b/src/libstddjb/stamp.c @@ -0,0 +1,7 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include <skalibs/tai.h> + +tain_t STAMP = TAIN_EPOCH ; diff --git a/src/libstddjb/str_chr.c b/src/libstddjb/str_chr.c new file mode 100644 index 0000000..ed55e50 --- /dev/null +++ b/src/libstddjb/str_chr.c @@ -0,0 +1,33 @@ +/* ISC license. */ + +#include <skalibs/config.h> +#include <skalibs/bytestr.h> + +#ifndef SKALIBS_FLAG_REPLACE_LIBC + +#include <string.h> + +unsigned int str_chr (register char const *s, int c) +{ + register char *p = strchr(s, c) ; + return p ? (unsigned int)(p - s) : strlen(s) ; +} + +#else + +unsigned int str_chr (register char const *s, int c) +{ + register char ch = c ; + register char const *t = s ; + + for (;;) + { + if (!*t) break; if (*t == ch) break; ++t; + if (!*t) break; if (*t == ch) break; ++t; + if (!*t) break; if (*t == ch) break; ++t; + if (!*t) break; if (*t == ch) break; ++t; + } + return t - s ; +} + +#endif diff --git a/src/libstddjb/str_cpy.c b/src/libstddjb/str_cpy.c new file mode 100644 index 0000000..179688c --- /dev/null +++ b/src/libstddjb/str_cpy.c @@ -0,0 +1,16 @@ +/* ISC license. */ + +#include <skalibs/config.h> + +#ifdef SKALIBS_FLAG_REPLACE_LIBC + +#include <skalibs/bytestr.h> + +unsigned int str_copy (char *s, char const *t) +{ + register unsigned int len = 0 ; + while ((*s = *t)) (s++, t++, len++) ; + return len ; +} + +#endif diff --git a/src/libstddjb/str_diff.c b/src/libstddjb/str_diff.c new file mode 100644 index 0000000..b85288a --- /dev/null +++ b/src/libstddjb/str_diff.c @@ -0,0 +1,24 @@ +/* ISC license. */ + +#include <skalibs/config.h> + +#ifdef SKALIBS_FLAG_REPLACE_LIBC + +#include <skalibs/bytestr.h> + +int str_diff (register char const *s, register char const *t) +{ + register char x ; + + for (;;) + { + x = *s; if (x != *t) break; if (!x) break; ++s; ++t; + x = *s; if (x != *t) break; if (!x) break; ++s; ++t; + x = *s; if (x != *t) break; if (!x) break; ++s; ++t; + x = *s; if (x != *t) break; if (!x) break; ++s; ++t; + } + return ((int)(unsigned int)(unsigned char) x) + - ((int)(unsigned int)(unsigned char) *t) ; +} + +#endif diff --git a/src/libstddjb/str_diffn.c b/src/libstddjb/str_diffn.c new file mode 100644 index 0000000..28f37f6 --- /dev/null +++ b/src/libstddjb/str_diffn.c @@ -0,0 +1,19 @@ +/* ISC license. */ + +#include <skalibs/config.h> +#include <skalibs/bytestr.h> + +#ifdef SKALIBS_FLAG_REPLACE_LIBC + +int str_diffn (register char const *s, register char const *t, register unsigned int len) +{ + while (len--) + { + if (*s != *t) return *s - *t ; + if (!*s) break ; + s++ ; t++ ; + } + return 0 ; +} + +#endif diff --git a/src/libstddjb/str_fmt.c b/src/libstddjb/str_fmt.c new file mode 100644 index 0000000..1c14c70 --- /dev/null +++ b/src/libstddjb/str_fmt.c @@ -0,0 +1,9 @@ +/* ISC license. */ + +#include <skalibs/bytestr.h> +#include <skalibs/fmtscan.h> + +unsigned int str_fmt (register char *d, char const *s) +{ + return strn_fmt(d, s, str_len(s)) ; +} diff --git a/src/libstddjb/str_len.c b/src/libstddjb/str_len.c new file mode 100644 index 0000000..4db2f4c --- /dev/null +++ b/src/libstddjb/str_len.c @@ -0,0 +1,21 @@ +/* ISC license. */ + +#include <skalibs/config.h> + +#ifdef SKALIBS_FLAG_REPLACE_LIBC + +#include <skalibs/bytestr.h> + +unsigned int str_len (char const *s) +{ + register char const *t = s ; + for (;;) + { + if (!*t) return t - s; ++t; + if (!*t) return t - s; ++t; + if (!*t) return t - s; ++t; + if (!*t) return t - s; ++t; + } +} + +#endif diff --git a/src/libstddjb/str_rchr.c b/src/libstddjb/str_rchr.c new file mode 100644 index 0000000..39a4822 --- /dev/null +++ b/src/libstddjb/str_rchr.c @@ -0,0 +1,28 @@ +/* ISC license. */ + +#include <skalibs/config.h> +#include <skalibs/bytestr.h> + +#ifndef SKALIBS_FLAG_REPLACE_LIBC + +#include <string.h> + +unsigned int str_rchr (register char const *s, int c) +{ + register char *p = strrchr(s, c) ; + return p ? (unsigned int)(p - s) : (unsigned int)strlen(s) ; +} + +#else + +unsigned int str_rchr (register char const *s, int c) +{ + register char ch = c ; + register char const *t = s ; + register char const *u = 0 ; + for ( ; *t ; t++) if (*t == ch) u = t ; + if (!u) u = t ; + return u - s ; +} + +#endif diff --git a/src/libstddjb/str_start.c b/src/libstddjb/str_start.c new file mode 100644 index 0000000..30396bd --- /dev/null +++ b/src/libstddjb/str_start.c @@ -0,0 +1,16 @@ +/* ISC license. */ + +#include <skalibs/bytestr.h> + +int str_start (register char const *s, register char const *t) +{ + register char x ; + + for (;;) + { + x = *t++; if (!x) return 1; if (x != *s++) return 0; + x = *t++; if (!x) return 1; if (x != *s++) return 0; + x = *t++; if (!x) return 1; if (x != *s++) return 0; + x = *t++; if (!x) return 1; if (x != *s++) return 0; + } +} diff --git a/src/libstddjb/str_strn.c b/src/libstddjb/str_strn.c new file mode 100644 index 0000000..7c2e425 --- /dev/null +++ b/src/libstddjb/str_strn.c @@ -0,0 +1,36 @@ +/* ISC license. */ + +#include <skalibs/config.h> +#include <skalibs/bytestr.h> + +#ifdef SKALIBS_FLAG_REPLACE_LIBC + +/* Very naive implementation, but it's small. */ + +unsigned int str_strn (char const *haystack, unsigned int hlen, char const *needle, unsigned int nlen) +{ + register unsigned int i = 0 ; + if (!nlen) return 0 ; + if (hlen < nlen) return hlen ; + hlen -= nlen ; + for (; i <= hlen ; i++) + if (!byte_diff(haystack+i, nlen, needle)) return i ; + return hlen+nlen ; +} + +#else + +#include <string.h> + +unsigned int str_strn (char const *haystack, unsigned int hlen, char const *needle, unsigned int nlen) +{ + char haystack2[hlen+1] ; + char needle2[nlen+1] ; + register char *p ; + byte_copy(haystack2, hlen, haystack) ; haystack2[hlen] = 0 ; + byte_copy(needle2, nlen, needle) ; needle2[nlen] = 0 ; + p = strstr(haystack2, needle2) ; + return p ? p - haystack2 : hlen ; +} + +#endif diff --git a/src/libstddjb/stralloc_append.c b/src/libstddjb/stralloc_append.c new file mode 100644 index 0000000..a51db36 --- /dev/null +++ b/src/libstddjb/stralloc_append.c @@ -0,0 +1,8 @@ +/* ISC license. */ + +#include <skalibs/stralloc.h> + +int stralloc_append (stralloc *sa, char c) +{ + return stralloc_catb(sa, &c, 1) ; +} diff --git a/src/libstddjb/stralloc_catb.c b/src/libstddjb/stralloc_catb.c new file mode 100644 index 0000000..bb03405 --- /dev/null +++ b/src/libstddjb/stralloc_catb.c @@ -0,0 +1,12 @@ +/* ISC license. */ + +#include <skalibs/bytestr.h> +#include <skalibs/stralloc.h> + +int stralloc_catb (stralloc *sa, char const *s, unsigned int n) +{ + if (!stralloc_readyplus(sa, n)) return 0 ; + byte_copy(sa->s + sa->len, n, s) ; + sa->len += n ; + return 1 ; +} diff --git a/src/libstddjb/stralloc_catv.c b/src/libstddjb/stralloc_catv.c new file mode 100644 index 0000000..1649f4c --- /dev/null +++ b/src/libstddjb/stralloc_catv.c @@ -0,0 +1,21 @@ +/* ISC license. */ + +#include <skalibs/bytestr.h> +#include <skalibs/siovec.h> +#include <skalibs/stralloc.h> + +int stralloc_catv (stralloc *sa, siovec_t const *v, unsigned int n) +{ + register unsigned int i = 0 ; + { + unsigned int total = 0 ; + for (; i < n ; i++) total += v[i].len ; + if (!stralloc_readyplus(sa, total)) return 0 ; + } + for (i = 0 ; i < n ; i++) + { + byte_copy(sa->s + sa->len, v[i].len, v[i].s) ; + sa->len += v[i].len ; + } + return 1 ; +} diff --git a/src/libstddjb/stralloc_copyb.c b/src/libstddjb/stralloc_copyb.c new file mode 100644 index 0000000..be2b397 --- /dev/null +++ b/src/libstddjb/stralloc_copyb.c @@ -0,0 +1,12 @@ +/* ISC license. */ + +#include <skalibs/bytestr.h> +#include <skalibs/stralloc.h> + +int stralloc_copyb (stralloc *sa, char const *s, unsigned int n) +{ + if (!stralloc_ready(sa, n)) return 0 ; + byte_copy(sa->s, n, s) ; + sa->len = n ; + return 1 ; +} diff --git a/src/libstddjb/stralloc_free.c b/src/libstddjb/stralloc_free.c new file mode 100644 index 0000000..889b2ca --- /dev/null +++ b/src/libstddjb/stralloc_free.c @@ -0,0 +1,10 @@ +/* ISC license. */ + +#include <skalibs/alloc.h> +#include <skalibs/stralloc.h> + +void stralloc_free (stralloc *sa) +{ + alloc_free(sa->s) ; + *sa = stralloc_zero ; +} diff --git a/src/libstddjb/stralloc_insertb.c b/src/libstddjb/stralloc_insertb.c new file mode 100644 index 0000000..339ffff --- /dev/null +++ b/src/libstddjb/stralloc_insertb.c @@ -0,0 +1,15 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/bytestr.h> +#include <skalibs/stralloc.h> + +int stralloc_insertb (stralloc *sa, unsigned int offset, char const *s, unsigned int n) +{ + if (offset > sa->len) return (errno = EINVAL, 0) ; + if (!stralloc_readyplus(sa, n)) return 0 ; + byte_copyr(sa->s + offset + n, sa->len - offset, sa->s + offset) ; + sa->len += n ; + byte_copyr(sa->s + offset, n, s) ; + return 1 ; +} diff --git a/src/libstddjb/stralloc_ready_tuned.c b/src/libstddjb/stralloc_ready_tuned.c new file mode 100644 index 0000000..04e1a41 --- /dev/null +++ b/src/libstddjb/stralloc_ready_tuned.c @@ -0,0 +1,25 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/alloc.h> +#include <skalibs/stralloc.h> + +int stralloc_ready_tuned (stralloc *sa, unsigned int n, unsigned int base, unsigned int a, unsigned int b) +{ + register unsigned int t ; + if (!b) return (errno = EINVAL, 0) ; + t = n + base + a * n / b ; + if (t < n) return (errno = ERANGE, 0) ; + if (!sa->s) + { + sa->s = alloc(t) ; + if (!sa->s) return 0 ; + sa->a = t ; + } + else if (n > sa->a) + { + if (!alloc_re(&sa->s, sa->a, t)) return 0 ; + sa->a = t ; + } + return 1 ; +} diff --git a/src/libstddjb/stralloc_reverse.c b/src/libstddjb/stralloc_reverse.c new file mode 100644 index 0000000..9ad29e7 --- /dev/null +++ b/src/libstddjb/stralloc_reverse.c @@ -0,0 +1,15 @@ +/* ISC license. */ + +#include <skalibs/bytestr.h> +#include <skalibs/stralloc.h> + +void stralloc_reverse (stralloc *sa) +{ + register unsigned int i = 0 ; + for (; i < sa->len >> 1 ; i++) + { + char tmp = sa->s[i] ; + sa->s[i] = sa->s[sa->len - 1 - i] ; + sa->s[sa->len - 1 - i] = tmp ; + } +} diff --git a/src/libstddjb/stralloc_reverse_blocks.c b/src/libstddjb/stralloc_reverse_blocks.c new file mode 100644 index 0000000..6a2e4b8 --- /dev/null +++ b/src/libstddjb/stralloc_reverse_blocks.c @@ -0,0 +1,17 @@ +/* ISC license. */ + +#include <skalibs/bytestr.h> +#include <skalibs/stralloc.h> + +void stralloc_reverse_blocks (stralloc *sa, unsigned int size) +{ + register unsigned int n = sa->len / (size << 1) ; + register unsigned int i = 0 ; + char tmp[size] ; + for (; i < n ; i++) + { + byte_copy(tmp, size, sa->s + i * size) ; + byte_copy(sa->s + i * size, size, sa->s + (2*n - 1 - i) * size) ; + byte_copy(sa->s + (2*n - 1 - i) * size, size, tmp) ; + } +} diff --git a/src/libstddjb/stralloc_shrink.c b/src/libstddjb/stralloc_shrink.c new file mode 100644 index 0000000..0dceca2 --- /dev/null +++ b/src/libstddjb/stralloc_shrink.c @@ -0,0 +1,14 @@ +/* ISC license. */ + +#include <skalibs/alloc.h> +#include <skalibs/stralloc.h> + +int stralloc_shrink (stralloc *sa) +{ + if (sa->a > sa->len) + { + if (!alloc_re(&sa->s, sa->a, sa->len)) return 0 ; + sa->a = sa->len ; + } + return 1 ; +} diff --git a/src/libstddjb/stralloc_zero.c b/src/libstddjb/stralloc_zero.c new file mode 100644 index 0000000..5c2185b --- /dev/null +++ b/src/libstddjb/stralloc_zero.c @@ -0,0 +1,5 @@ +/* ISC license. */ + +#include <skalibs/stralloc.h> + +stralloc const stralloc_zero = STRALLOC_ZERO ; diff --git a/src/libstddjb/strerr.c b/src/libstddjb/strerr.c new file mode 100644 index 0000000..ae70477 --- /dev/null +++ b/src/libstddjb/strerr.c @@ -0,0 +1,35 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include <unistd.h> +#include <errno.h> +#include <skalibs/buffer.h> +#include <skalibs/strerr.h> + +void strerr_warn (char const *x1, char const *x2, char const *x3, char const *x4, char const *x5, char const *x6, char const *x7, char const *x8, char const *x9, char const *x10, char const *se) +{ + int e = errno ; + if (x1) buffer_puts(buffer_2, x1) ; + if (x2) buffer_puts(buffer_2, x2) ; + if (x3) buffer_puts(buffer_2, x3) ; + if (x4) buffer_puts(buffer_2, x4) ; + if (x5) buffer_puts(buffer_2, x5) ; + if (x6) buffer_puts(buffer_2, x6) ; + if (x7) buffer_puts(buffer_2, x7) ; + if (x8) buffer_puts(buffer_2, x8) ; + if (x9) buffer_puts(buffer_2, x9) ; + if (x10) buffer_puts(buffer_2, x10) ; + if (se) buffer_puts(buffer_2, se) ; + buffer_putflush(buffer_2, "\n", 1) ; + errno = e ; +} + +void strerr_die (int e, char const *x1, char const *x2, char const *x3, char const *x4, char const *x5, char const *x6, char const *x7, char const *x8, char const *x9, char const *x10, char const *se) +{ + strerr_warn(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, se) ; + _exit(e) ; + + /* No, OpenBSD, this noreturn function does NOT return. + Please learn what _exit() does. */ +} diff --git a/src/libstddjb/strerr_sys.c b/src/libstddjb/strerr_sys.c new file mode 100644 index 0000000..46789d8 --- /dev/null +++ b/src/libstddjb/strerr_sys.c @@ -0,0 +1,22 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include <unistd.h> +#include <errno.h> +#include <skalibs/error.h> +#include <skalibs/strerr.h> + +void strerr_warnsys (char const *x1, char const *x2, char const *x3, char const *x4, char const *x5, char const *x6, char const *x7, char const *x8, char const *x9, char const *x10) +{ + strerr_warn(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, error_str(errno)) ; +} + +void strerr_diesys (int e, char const *x1, char const *x2, char const *x3, char const *x4, char const *x5, char const *x6, char const *x7, char const *x8, char const *x9, char const *x10) +{ + strerr_warnsys(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10) ; + _exit(e) ; + + /* No, OpenBSD, this noreturn function does NOT return. + Please learn what _exit() does. */ +} diff --git a/src/libstddjb/string_format.c b/src/libstddjb/string_format.c new file mode 100644 index 0000000..f81b03d --- /dev/null +++ b/src/libstddjb/string_format.c @@ -0,0 +1,33 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/bytestr.h> +#include <skalibs/stralloc.h> + +int string_format (stralloc *sa, char const *vars, char const *format, char const *const *args) +{ + static unsigned char const tab[2][4] = { "1442", "4833" } ; + char class[256] = "3222222222222222222222222222222222222022222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222" ; + unsigned int varlen = str_len(vars) ; + unsigned int base = sa->len ; + int wasnull = !sa->s ; + unsigned int state = 0 ; + + for (; state < varlen ; state++) + if (class[(unsigned char)vars[state]] == '2') + class[(unsigned char)vars[state]] = '1' ; + else return (errno = EINVAL, 0) ; + + for (state = 0 ; state < 2 ; format++) + { + unsigned char c = tab[state][class[(unsigned char)(*format)] - '0'] ; + state = c & 3 ; + if (c & 4) if (!stralloc_catb(sa, format, 1)) goto err ; + if (c & 8) if (!stralloc_cats(sa, args[byte_chr(vars, varlen, *format)])) goto err ; + } + if (state == 2) return 1 ; + errno = EINVAL ; + err: + if (wasnull) stralloc_free(sa) ; else sa->len = base ; + return 0 ; +} diff --git a/src/libstddjb/string_quote.c b/src/libstddjb/string_quote.c new file mode 100644 index 0000000..ed00402 --- /dev/null +++ b/src/libstddjb/string_quote.c @@ -0,0 +1,17 @@ +/* ISC license. */ + +#include <skalibs/stralloc.h> +#include <skalibs/skamisc.h> + +int string_quote (stralloc *sa, char const *s, unsigned int len) +{ + unsigned int base = sa->len ; + int wasnull = !sa->s ; + if (!stralloc_catb(sa, "\"", 1)) return 0 ; + if (!string_quote_nodelim(sa, s, len) || !stralloc_catb(sa, "\"", 1)) + { + if (wasnull) stralloc_free(sa) ; else sa->len = base ; + return 0 ; + } + return 1 ; +} diff --git a/src/libstddjb/string_quote_nodelim.c b/src/libstddjb/string_quote_nodelim.c new file mode 100644 index 0000000..dfe41ce --- /dev/null +++ b/src/libstddjb/string_quote_nodelim.c @@ -0,0 +1,9 @@ +/* ISC license. */ + +#include <skalibs/stralloc.h> +#include <skalibs/skamisc.h> + +int string_quote_nodelim (stralloc *sa, char const *s, unsigned int len) +{ + return string_quote_nodelim_mustquote(sa, s, len, "\"", 1) ; +} diff --git a/src/libstddjb/string_quote_nodelim_mustquote.c b/src/libstddjb/string_quote_nodelim_mustquote.c new file mode 100644 index 0000000..e52bce3 --- /dev/null +++ b/src/libstddjb/string_quote_nodelim_mustquote.c @@ -0,0 +1,62 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/bytestr.h> +#include <skalibs/fmtscan.h> +#include <skalibs/stralloc.h> +#include <skalibs/skamisc.h> + +int string_quote_nodelim_mustquote (stralloc *sa, char const *s, unsigned int len, char const *delim, unsigned int delimlen) +{ + char class[256] = "dddddddaaaaaaaddddddddddddddddddcccccccccccccccceeeeeeeeeeccccccccccccccccccccccccccccccccccbcccceeeeeecccccccecccececececcccccddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd" ; + + unsigned int base = sa->len ; + unsigned int i = 0 ; + int wasnull = !sa->s ; + + for (; i < delimlen ; i++) + if (class[(unsigned char)delim[i]] == 'c') + class[(unsigned char)delim[i]] = 'b' ; + else return (errno = EINVAL, 0) ; + + for (i = 0 ; i < len ; i++) + { + switch (class[(unsigned char)s[i]]) + { + case 'a' : + { + static char const tab[7] = "abtnvfr" ; + char fmt[2] = "\\" ; + fmt[1] = tab[s[i] - 7] ; + if (!stralloc_catb(sa, fmt, 2)) goto err ; + break ; + } + case 'b' : + { + char fmt[2] = "\\" ; + fmt[1] = s[i] ; + if (!stralloc_catb(sa, fmt, 2)) goto err ; + break ; + } + case 'c' : + case 'e' : + { + if (!stralloc_catb(sa, s+i, 1)) goto err ; + break ; + } + case 'd' : + { + char fmt[5] = "\\0x" ; + ucharn_fmt(fmt+3, s+i, 1) ; + if (!stralloc_catb(sa, fmt, 5)) goto err ; + break ; + } + default : errno = EFAULT ; goto err ; /* can't happen */ + } + } + return 1 ; + + err: + if (wasnull) stralloc_free(sa) ; else sa->len = base ; + return 0 ; +} diff --git a/src/libstddjb/string_unquote.c b/src/libstddjb/string_unquote.c new file mode 100644 index 0000000..f4482ff --- /dev/null +++ b/src/libstddjb/string_unquote.c @@ -0,0 +1,20 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/bytestr.h> +#include <skalibs/skamisc.h> + +int string_unquote (char *d, unsigned int *w, char const *s, unsigned int len, unsigned int *r) +{ + if (!len-- || (*s++ != '"')) return (errno = EINVAL, 0) ; + { + unsigned int rr, ww ; + char tmp[len] ; + if (!string_unquote_withdelim(tmp, &ww, s, len, &rr, "\"", 1)) return 0 ; + if (rr == len) return (errno = EPIPE, 0) ; + byte_copy(d, ww, tmp) ; + *w = ww ; + *r = rr + 2 ; + } + return 1 ; +} diff --git a/src/libstddjb/string_unquote_nodelim.c b/src/libstddjb/string_unquote_nodelim.c new file mode 100644 index 0000000..1dc90f1 --- /dev/null +++ b/src/libstddjb/string_unquote_nodelim.c @@ -0,0 +1,11 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/skamisc.h> + +int string_unquote_nodelim (char *d, char const *s, unsigned int len) +{ + unsigned int rr, ww ; + if (!string_unquote_withdelim(d, &ww, s, len, &rr, 0, 0)) return -1 ; + return (int)ww ; +} diff --git a/src/libstddjb/string_unquote_withdelim.c b/src/libstddjb/string_unquote_withdelim.c new file mode 100644 index 0000000..dd52dbd --- /dev/null +++ b/src/libstddjb/string_unquote_withdelim.c @@ -0,0 +1,60 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/error.h> +#include <skalibs/bytestr.h> +#include <skalibs/fmtscan.h> +#include <skalibs/skamisc.h> + +#define PUSH0 0x40 +#define PUSH 0x20 +#define PUSHSPEC 0x10 +#define STORE 0x08 +#define CALC 0x04 +#define SYNTAXERROR 0x02 +#define BROKENPIPE 0x01 + +int string_unquote_withdelim (char *d, unsigned int *w, char const *s, unsigned int len, unsigned int *r, char const *delim, unsigned int delimlen) +{ + register unsigned int i = 0 ; + static unsigned char const actions[5][9] = + { + { 0, 0, PUSH, PUSH, PUSH, PUSH, PUSH, PUSH, 0 }, + { PUSH, PUSH, 0, PUSH, PUSHSPEC, PUSH, PUSHSPEC, PUSH, BROKENPIPE }, + { PUSH0, PUSH0, PUSH0|PUSH, 0, PUSH0|PUSH, PUSH0|PUSH, PUSH0|PUSH, PUSH0|PUSH, PUSH0 }, + { SYNTAXERROR, SYNTAXERROR, STORE, SYNTAXERROR, STORE, STORE, SYNTAXERROR, SYNTAXERROR, BROKENPIPE }, + { SYNTAXERROR, SYNTAXERROR, CALC, SYNTAXERROR, CALC, CALC, SYNTAXERROR, SYNTAXERROR, BROKENPIPE } + } ; + static unsigned char const states[5][9] = + { + { 1, 5, 0, 0, 0, 0, 0, 0, 5 }, + { 0, 0, 2, 0, 0, 0, 0, 0, 6 }, + { 1, 5, 0, 3, 0, 0, 0, 0, 5 }, + { 6, 6, 4, 6, 4, 4, 6, 6, 6 }, + { 6, 6, 0, 6, 0, 0, 6, 6, 6 } + } ; + unsigned char class[256] = "7777777777777777777777777777777777777777777777772555555555777777777777777777777777777777777707777445554777777767776767673777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777" ; + unsigned char store = 0 ; + unsigned char state = 0 ; + for (; i < delimlen ; i++) + if (class[(unsigned char)delim[i]] == '7') + class[(unsigned char)delim[i]] = '1' ; + else return (errno = EINVAL, 0) ; + *w = 0 ; + + for (i = 0 ; state < 5 ; i++) + { + unsigned char c = i < len ? class[(unsigned char)s[i]] - '0' : 8 ; + unsigned char action = actions[state][c] ; + state = states[state][c] ; + if (action & PUSH0) d[(*w)++] = 0 ; + if (action & PUSH) d[(*w)++] = s[i] ; + if (action & PUSHSPEC) d[(*w)++] = 7 + byte_chr("abtnvfr", 7, s[i]) ; + if (action & STORE) store = fmtscan_num(s[i], 16) << 4 ; + if (action & CALC) d[(*w)++] = store | fmtscan_num(s[i], 16) ; + if (action & SYNTAXERROR) errno = EPROTO ; + if (action & BROKENPIPE) errno = EPIPE ; + } + *r = i - 1 ; + return (state == 5) ; +} diff --git a/src/libstddjb/strn_fmt.c b/src/libstddjb/strn_fmt.c new file mode 100644 index 0000000..bbb9651 --- /dev/null +++ b/src/libstddjb/strn_fmt.c @@ -0,0 +1,21 @@ +/* ISC license. */ + +#include <skalibs/fmtscan.h> +#include <skalibs/uint.h> + +unsigned int strn_fmt (char *blah, register char const *s, unsigned int len) +{ + register char *d = blah ; + unsigned int i ; + for (i = 0 ; i < len ; i++) + if ((s[i] >= 32) && ((unsigned char)s[i] < 127)) *d++ = s[i] ; + else + { + *d++ = '\\' ; + *d++ = '0' ; + *d++ = 'x' ; + if ((unsigned char)s[i] < 16) *d++ = '0' ; + d += uint_xfmt(d, (unsigned char)s[i]) ; + } + return d - blah ; +} diff --git a/src/libstddjb/subgetopt.c b/src/libstddjb/subgetopt.c new file mode 100644 index 0000000..69201c6 --- /dev/null +++ b/src/libstddjb/subgetopt.c @@ -0,0 +1,63 @@ +/* ISC license. */ + +#undef SUBGETOPT_SHORT +#include <skalibs/sgetopt.h> + +int subgetopt_r (int argc, char const *const *argv, char const *opts, subgetopt_t_ref o) +{ + o->arg = 0 ; + if ((o->ind >= argc) || !argv[o->ind]) return -1 ; + if (o->pos && !argv[o->ind][o->pos]) + { + o->ind++ ; + o->pos = 0 ; + if ((o->ind >= argc) || !argv[o->ind]) return -1 ; + } + + if (!o->pos) + { + if (argv[o->ind][0] != '-') return -1 ; + else + { + char c ; + o->pos++ ; + c = argv[o->ind][1] ; + if (c == '-') o->ind++ ; + if (!c || (c == '-')) + { + o->pos = 0 ; + return -1 ; + } + } + } + { + char c = argv[o->ind][o->pos++] ; + char const *s = opts ; + char retnoarg = (*s == ':') ? (s++, ':') : '?' ; + while (*s) + { + if (c == *s) + { + if (s[1] == ':') + { + o->arg = argv[o->ind++] + o->pos ; + o->pos = 0 ; + if (!*o->arg) + { + o->arg = argv[o->ind] ; + if ((o->ind >= argc) || !o->arg) + { + o->problem = c ; + return retnoarg ; + } + o->ind++ ; + } + } + return c ; + } + if (*++s == ':') s++ ; + } + o->problem = c ; + } + return '?' ; +} diff --git a/src/libstddjb/subgetopt_here.c b/src/libstddjb/subgetopt_here.c new file mode 100644 index 0000000..e0be29a --- /dev/null +++ b/src/libstddjb/subgetopt_here.c @@ -0,0 +1,7 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include <skalibs/sgetopt.h> + +subgetopt_t subgetopt_here = SUBGETOPT_ZERO ; diff --git a/src/libstddjb/sysclock_from_localtm.c b/src/libstddjb/sysclock_from_localtm.c new file mode 100644 index 0000000..6408fc8 --- /dev/null +++ b/src/libstddjb/sysclock_from_localtm.c @@ -0,0 +1,15 @@ +/* ISC license. */ + +#include <sys/types.h> +#include <time.h> +#include <skalibs/uint64.h> +#include <skalibs/djbtime.h> + +int sysclock_from_localtm (uint64 *uu, struct tm const *l) +{ + uint64 u ; + if (!ltm64_from_localtm(&u, l)) return 0 ; + if (!sysclock_from_ltm64(&u)) return 0 ; + *uu = u ; + return 1 ; +} diff --git a/src/libstddjb/sysclock_from_localtmn.c b/src/libstddjb/sysclock_from_localtmn.c new file mode 100644 index 0000000..7b227d2 --- /dev/null +++ b/src/libstddjb/sysclock_from_localtmn.c @@ -0,0 +1,13 @@ +/* ISC license. */ + +#include <skalibs/tai.h> +#include <skalibs/djbtime.h> + +int sysclock_from_localtmn (tain_t *a, localtmn_t const *l) +{ + uint64 u ; + if (!sysclock_from_localtm(&u, &l->tm)) return 0 ; + tai_u64(&a->sec, u) ; + a->nano = l->nano ; + return 1 ; +} diff --git a/src/libstddjb/sysclock_from_ltm64.c b/src/libstddjb/sysclock_from_ltm64.c new file mode 100644 index 0000000..a7e7a36 --- /dev/null +++ b/src/libstddjb/sysclock_from_ltm64.c @@ -0,0 +1,26 @@ +/* ISC license. */ + +#include <skalibs/config.h> +#include <skalibs/uint64.h> +#include <skalibs/djbtime.h> + +#ifdef SKALIBS_FLAG_CLOCKISTAI + +#include <skalibs/tai.h> + +int sysclock_from_ltm64 (uint64 *u) +{ + tai_t t ; + if (!tai_from_ltm64(&t, *u)) return 0 ; + *u = t.x - 10U ; + return 1 ; +} + +#else + +int sysclock_from_ltm64 (uint64 *u) +{ + return utc_from_sysclock(u) ; +} + +#endif diff --git a/src/libstddjb/sysclock_from_tai.c b/src/libstddjb/sysclock_from_tai.c new file mode 100644 index 0000000..3db2640 --- /dev/null +++ b/src/libstddjb/sysclock_from_tai.c @@ -0,0 +1,23 @@ +/* ISC license. */ + +#include <skalibs/config.h> +#include <skalibs/tai.h> + +#ifdef SKALIBS_FLAG_CLOCKISTAI + +int sysclock_from_tai (uint64 *u, tai_t const *t) +{ + *u = t->x - 10U ; + return 1 ; +} + +#else + +#include <skalibs/djbtime.h> + +int sysclock_from_tai (uint64 *u, tai_t const *t) +{ + return utc_from_tai(u, t) ; +} + +#endif diff --git a/src/libstddjb/sysclock_from_utc.c b/src/libstddjb/sysclock_from_utc.c new file mode 100644 index 0000000..25f9205 --- /dev/null +++ b/src/libstddjb/sysclock_from_utc.c @@ -0,0 +1,27 @@ +/* ISC license. */ + +#include <skalibs/config.h> +#include <skalibs/uint64.h> +#include <skalibs/djbtime.h> + +#ifdef SKALIBS_FLAG_CLOCKISTAI + +#include <skalibs/tai.h> + +int sysclock_from_utc (uint64 *u) +{ + tai_t t ; + if (!tai_from_utc(&t, *u)) return 0 ; + *u = t.x - 10 ; + return 1 ; +} + +#else + +int sysclock_from_utc (uint64 *u) +{ + (void)u ; + return 1 ; +} + +#endif diff --git a/src/libstddjb/sysclock_get.c b/src/libstddjb/sysclock_get.c new file mode 100644 index 0000000..3d14f96 --- /dev/null +++ b/src/libstddjb/sysclock_get.c @@ -0,0 +1,42 @@ +/* ISC license. */ + +#include <skalibs/config.h> +#include <skalibs/sysdeps.h> +#include <skalibs/tai.h> + +#ifdef SKALIBS_FLAG_USERT +# ifndef SKALIBS_HASCLOCKRT +# undef SKALIBS_FLAG_USERT +# warning "SKALIBS_FLAG_USERT set but SKALIBS_HASCLOCKRT not found. Clearing SKALIBS_FLAG_USERT." +# endif +#endif + +#ifdef SKALIBS_FLAG_USERT + +#include <time.h> + +int sysclock_get (tain_t *a) +{ + tain_t aa ; + struct timespec now ; + if (clock_gettime(CLOCK_REALTIME, &now) < 0) return 0 ; + if (!tain_from_timespec(&aa, &now)) return 0 ; + tain_add(a, &aa, &tain_nano500) ; + return 1 ; +} + +#else + +#include <sys/time.h> + +int sysclock_get (tain_t *a) +{ + tain_t aa ; + struct timeval now ; + if (gettimeofday(&now, 0) < 0) return 0 ; + if (!tain_from_timeval(&aa, &now)) return 0 ; + tain_add(a, &aa, &tain_nano500) ; + return 1 ; +} + +#endif diff --git a/src/libstddjb/sysclock_set.c b/src/libstddjb/sysclock_set.c new file mode 100644 index 0000000..0ec51c6 --- /dev/null +++ b/src/libstddjb/sysclock_set.c @@ -0,0 +1,53 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include <skalibs/config.h> +#include <skalibs/sysdeps.h> + +#ifdef SKALIBS_FLAG_USERT +# ifndef SKALIBS_HASCLOCKRT +# undef SKALIBS_FLAG_USERT +# warning "SKALIBS_FLAG_USERT set but SKALIBS_HASCLOCKRT not found. Clearing SKALIBS_FLAG_USERT." +# endif +#endif + +#ifndef SKALIBS_FLAG_USERT +# ifndef SKALIBS_HASSETTIMEOFDAY +# error "SKALIBS_FLAG_USERT clear but SKALIBS_HASSETTIMEOFDAY not found. How do your set your system clock?" +# endif +#endif + + +#ifdef SKALIBS_FLAG_USERT + +#include <time.h> +#include <skalibs/tai.h> + +int sysclock_set (tain_t const *a) +{ + struct timespec now ; + tain_t aa ; + tain_add(&aa, a, &tain_nano500) ; + if (!timespec_from_tain(&now, &aa)) return 0 ; + if (clock_settime(CLOCK_REALTIME, &now) < 0) return 0 ; + return 1 ; +} + +#else + +#include <skalibs/nonposix.h> +#include <sys/time.h> +#include <skalibs/tai.h> + +int sysclock_set (tain_t const *a) +{ + struct timeval now ; + tain_t aa ; + tain_add(&aa, a, &tain_nano500) ; + if (!timeval_from_tain(&now, &aa)) return 0 ; + if (settimeofday(&now, 0) < 0) return 0 ; + return 1 ; +} + +#endif diff --git a/src/libstddjb/tai_add.c b/src/libstddjb/tai_add.c new file mode 100644 index 0000000..91af283 --- /dev/null +++ b/src/libstddjb/tai_add.c @@ -0,0 +1,8 @@ +/* ISC license. */ + +#include <skalibs/tai.h> + +void tai_add (tai_t *t, tai_t const *u, tai_t const *v) +{ + tai_u64(t, tai_sec(u) + tai_sec(v)) ; +} diff --git a/src/libstddjb/tai_from_localtm.c b/src/libstddjb/tai_from_localtm.c new file mode 100644 index 0000000..1f43070 --- /dev/null +++ b/src/libstddjb/tai_from_localtm.c @@ -0,0 +1,14 @@ +/* ISC license. */ + +#include <sys/types.h> +#include <time.h> +#include <skalibs/uint64.h> +#include <skalibs/tai.h> +#include <skalibs/djbtime.h> + +int tai_from_localtm (tai_t *t, struct tm const *l) +{ + uint64 u ; + if (!ltm64_from_localtm(&u, l)) return 0 ; + return tai_from_ltm64(t, u) ; +} diff --git a/src/libstddjb/tai_from_ltm64.c b/src/libstddjb/tai_from_ltm64.c new file mode 100644 index 0000000..2538c00 --- /dev/null +++ b/src/libstddjb/tai_from_ltm64.c @@ -0,0 +1,23 @@ +/* ISC license. */ + +#include <skalibs/config.h> +#include <skalibs/uint64.h> +#include <skalibs/tai.h> +#include <skalibs/djbtime.h> + +#ifdef SKALIBS_FLAG_TZISRIGHT + +int tai_from_ltm64 (tai_t *t, uint64 u) +{ + tai_u64(t, u + 10U) ; + return 1 ; +} + +#else + +int tai_from_ltm64 (tai_t *t, uint64 u) +{ + return tai_from_utc(t, u) ; +} + +#endif diff --git a/src/libstddjb/tai_from_sysclock.c b/src/libstddjb/tai_from_sysclock.c new file mode 100644 index 0000000..c2bb546 --- /dev/null +++ b/src/libstddjb/tai_from_sysclock.c @@ -0,0 +1,23 @@ +/* ISC license. */ + +#include <skalibs/config.h> +#include <skalibs/tai.h> + +#ifdef SKALIBS_FLAG_CLOCKISTAI + +int tai_from_sysclock (tai_t *t, uint64 u) +{ + tai_u64(t, u + 10U) ; + return 1 ; +} + +#else + +#include <skalibs/djbtime.h> + +int tai_from_sysclock (tai_t *t, uint64 u) +{ + return tai_from_utc(t, u) ; +} + +#endif diff --git a/src/libstddjb/tai_from_timespec.c b/src/libstddjb/tai_from_timespec.c new file mode 100644 index 0000000..e9fbe3e --- /dev/null +++ b/src/libstddjb/tai_from_timespec.c @@ -0,0 +1,11 @@ +/* ISC license. */ + +#include <sys/types.h> +#include <time.h> +#include <skalibs/tai.h> + +int tai_from_timespec (tai_t *t, struct timespec const *ts) +{ + tai_unix(t, ts->tv_sec) ; + return 1 ; +} diff --git a/src/libstddjb/tai_from_timeval.c b/src/libstddjb/tai_from_timeval.c new file mode 100644 index 0000000..41cf5a1 --- /dev/null +++ b/src/libstddjb/tai_from_timeval.c @@ -0,0 +1,10 @@ +/* ISC license. */ + +#include <sys/time.h> +#include <skalibs/tai.h> + +int tai_from_timeval (tai_t *t, struct timeval const *tv) +{ + tai_unix(t, tv->tv_sec) ; + return 1 ; +} diff --git a/src/libstddjb/tai_from_utc.c b/src/libstddjb/tai_from_utc.c new file mode 100644 index 0000000..ba9cea9 --- /dev/null +++ b/src/libstddjb/tai_from_utc.c @@ -0,0 +1,14 @@ +/* ISC license. */ + +#include <skalibs/uint64.h> +#include <skalibs/tai.h> +#include <skalibs/djbtime.h> +#include "djbtime-internal.h" + +int tai_from_utc (tai_t *t, uint64 u) +{ + if (leapsecs_add(&u, 0) < 0) return 0 ; + u += 10 ; + t->x = u ; + return 1 ; +} diff --git a/src/libstddjb/tai_now.c b/src/libstddjb/tai_now.c new file mode 100644 index 0000000..a1847ab --- /dev/null +++ b/src/libstddjb/tai_now.c @@ -0,0 +1,13 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include <time.h> +#include <skalibs/uint64.h> +#include <skalibs/tai.h> + +int tai_now (tai_t *t) +{ + register uint64 u = TAI_MAGIC + time(0) ; + return tai_from_sysclock(t, u) ; +} diff --git a/src/libstddjb/tai_pack.c b/src/libstddjb/tai_pack.c new file mode 100644 index 0000000..f81afe2 --- /dev/null +++ b/src/libstddjb/tai_pack.c @@ -0,0 +1,9 @@ +/* ISC license. */ + +#include <skalibs/uint64.h> +#include <skalibs/tai.h> + +void tai_pack (char *s, tai_t const *t) +{ + uint64_pack_big(s, tai_sec(t)) ; +} diff --git a/src/libstddjb/tai_pack_little.c b/src/libstddjb/tai_pack_little.c new file mode 100644 index 0000000..41e552a --- /dev/null +++ b/src/libstddjb/tai_pack_little.c @@ -0,0 +1,9 @@ +/* ISC license. */ + +#include <skalibs/uint64.h> +#include <skalibs/tai.h> + +void tai_pack_little (char *s, tai_t const *t) +{ + uint64_pack(s, tai_sec(t)) ; +} diff --git a/src/libstddjb/tai_relative_from_timespec.c b/src/libstddjb/tai_relative_from_timespec.c new file mode 100644 index 0000000..34bb555 --- /dev/null +++ b/src/libstddjb/tai_relative_from_timespec.c @@ -0,0 +1,11 @@ +/* ISC license. */ + +#include <sys/types.h> +#include <time.h> +#include <skalibs/tai.h> + +int tai_relative_from_timespec (tai_t *t, struct timespec const *ts) +{ + tai_u64(t, ts->tv_sec) ; + return 1 ; +} diff --git a/src/libstddjb/tai_relative_from_timeval.c b/src/libstddjb/tai_relative_from_timeval.c new file mode 100644 index 0000000..f685da7 --- /dev/null +++ b/src/libstddjb/tai_relative_from_timeval.c @@ -0,0 +1,10 @@ +/* ISC license. */ + +#include <sys/time.h> +#include <skalibs/tai.h> + +int tai_relative_from_timeval (tai_t *t, struct timeval const *tv) +{ + tai_u64(t, tv->tv_sec) ; + return 1 ; +} diff --git a/src/libstddjb/tai_sub.c b/src/libstddjb/tai_sub.c new file mode 100644 index 0000000..d0c879e --- /dev/null +++ b/src/libstddjb/tai_sub.c @@ -0,0 +1,8 @@ +/* ISC license. */ + +#include <skalibs/tai.h> + +void tai_sub (tai_t *t, tai_t const *u, tai_t const *v) +{ + tai_u64(t, tai_sec(u) - tai_sec(v)) ; +} diff --git a/src/libstddjb/tai_unpack.c b/src/libstddjb/tai_unpack.c new file mode 100644 index 0000000..a733c4a --- /dev/null +++ b/src/libstddjb/tai_unpack.c @@ -0,0 +1,9 @@ +/* ISC license. */ + +#include <skalibs/uint64.h> +#include <skalibs/tai.h> + +void tai_unpack (char const *s, tai_t *t) +{ + uint64_unpack_big(s, &t->x) ; +} diff --git a/src/libstddjb/tai_unpack_little.c b/src/libstddjb/tai_unpack_little.c new file mode 100644 index 0000000..71804a5 --- /dev/null +++ b/src/libstddjb/tai_unpack_little.c @@ -0,0 +1,9 @@ +/* ISC license. */ + +#include <skalibs/uint64.h> +#include <skalibs/tai.h> + +void tai_unpack_little (char const *s, tai_t *t) +{ + uint64_unpack(s, &t->x) ; +} diff --git a/src/libstddjb/tain_add.c b/src/libstddjb/tain_add.c new file mode 100644 index 0000000..6c6a237 --- /dev/null +++ b/src/libstddjb/tain_add.c @@ -0,0 +1,14 @@ +/* ISC license. */ + +#include <skalibs/tai.h> + +void tain_add (tain_t *t, tain_t const *u, tain_t const *v) +{ + tai_add(&t->sec, &u->sec, &v->sec) ; + t->nano = u->nano + v->nano ; + if (t->nano > 999999999U) + { + t->nano -= 1000000000U ; + tai_u64(&t->sec, tai_sec(&t->sec)+1) ; + } +} diff --git a/src/libstddjb/tain_addsec.c b/src/libstddjb/tain_addsec.c new file mode 100644 index 0000000..f4252a7 --- /dev/null +++ b/src/libstddjb/tain_addsec.c @@ -0,0 +1,20 @@ +/* ISC license. */ + +#include <skalibs/tai.h> + +void tain_addsec (tain_t *b, tain_t const *a, int c) +{ + b->nano = a->nano ; + if (c >= 0) + { + tai_t t ; + tai_u64(&t, c) ; + tai_add(&b->sec, &a->sec, &t) ; + } + else + { + tai_t t ; + tai_u64(&t, -c) ; + tai_sub(&b->sec, &a->sec, &t) ; + } +} diff --git a/src/libstddjb/tain_approx.c b/src/libstddjb/tain_approx.c new file mode 100644 index 0000000..d749cdf --- /dev/null +++ b/src/libstddjb/tain_approx.c @@ -0,0 +1,8 @@ +/* ISC license. */ + +#include <skalibs/tai.h> + +double tain_approx (tain_t const *t) +{ + return tai_approx(&t->sec) + tain_frac(t) ; +} diff --git a/src/libstddjb/tain_clockmon.c b/src/libstddjb/tain_clockmon.c new file mode 100644 index 0000000..f14cd31 --- /dev/null +++ b/src/libstddjb/tain_clockmon.c @@ -0,0 +1,47 @@ +/* ISC license. */ + +#include <skalibs/sysdeps.h> +#include <skalibs/tai.h> + +#ifdef SKALIBS_HASCLOCKMON + +#include <time.h> + +int tain_clockmon_init (tain_t *offset) +{ + tain_t a, b ; + struct timespec ts ; + if (!tain_sysclock(&a)) return 0 ; + if (clock_gettime(CLOCK_MONOTONIC, &ts) < 0) return 0 ; + if (!tain_from_timespec(&b, &ts)) return 0 ; + tain_add(&a, &a, &tain_nano500) ; + tain_sub(offset, &a, &b) ; + return 1 ; +} + +int tain_clockmon (tain_t *a, tain_t const *offset) +{ + struct timespec ts ; + if (clock_gettime(CLOCK_MONOTONIC, &ts) < 0) return 0 ; + if (!tain_from_timespec(a, &ts)) return 0 ; + tain_add(a, a, offset) ; + return 1 ; +} + +#else + +#include <errno.h> + +int tain_clockmon_init (tain_t *offset) +{ + (void)offset ; + return (errno = ENOSYS, 0) ; +} + +int tain_clockmon (tain_t *a, tain_t const *offset) +{ + (void)a ; (void)offset ; + return (errno = ENOSYS, 0) ; +} + +#endif diff --git a/src/libstddjb/tain_fmt.c b/src/libstddjb/tain_fmt.c new file mode 100644 index 0000000..1fa04e3 --- /dev/null +++ b/src/libstddjb/tain_fmt.c @@ -0,0 +1,11 @@ +/* ISC license. */ + +#include <skalibs/fmtscan.h> +#include <skalibs/tai.h> + +unsigned int tain_fmt (char *s, tain_t const *a) +{ + char pack[TAIN_PACK] ; + tain_pack(pack, a) ; + return ucharn_fmt(s, pack, TAIN_PACK) ; +} diff --git a/src/libstddjb/tain_frac.c b/src/libstddjb/tain_frac.c new file mode 100644 index 0000000..45ee3b4 --- /dev/null +++ b/src/libstddjb/tain_frac.c @@ -0,0 +1,8 @@ +/* ISC license. */ + +#include <skalibs/tai.h> + +double tain_frac (tain_t const *t) +{ + return t->nano * 0.000000001 ; +} diff --git a/src/libstddjb/tain_from_localtmn.c b/src/libstddjb/tain_from_localtmn.c new file mode 100644 index 0000000..cc9bd19 --- /dev/null +++ b/src/libstddjb/tain_from_localtmn.c @@ -0,0 +1,13 @@ +/* ISC license. */ + +#include <skalibs/tai.h> +#include <skalibs/djbtime.h> + +int tain_from_localtmn (tain_t *a, localtmn_t const *l) +{ + tai_t t ; + if (!tai_from_localtm(&t, &l->tm)) return 0 ; + a->sec = t ; + a->nano = l->nano ; + return 1 ; +} diff --git a/src/libstddjb/tain_from_millisecs.c b/src/libstddjb/tain_from_millisecs.c new file mode 100644 index 0000000..e6bfca4 --- /dev/null +++ b/src/libstddjb/tain_from_millisecs.c @@ -0,0 +1,12 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/tai.h> + +int tain_from_millisecs (tain_t *a, int millisecs) +{ + if (millisecs < 0) return (errno = EINVAL, 0) ; + a->sec.x = millisecs / 1000 ; + a->nano = (millisecs % 1000) * 1000000U ; + return 1 ; +} diff --git a/src/libstddjb/tain_from_ntp.c b/src/libstddjb/tain_from_ntp.c new file mode 100644 index 0000000..6bf7697 --- /dev/null +++ b/src/libstddjb/tain_from_ntp.c @@ -0,0 +1,17 @@ +/* ISC license. */ + +#include <skalibs/uint64.h> +#include <skalibs/tai.h> +#include <skalibs/djbtime.h> + +int tain_from_ntp (tain_t *a, uint64 u) +{ + tai_t secs = { u >> 32 } ; + if (secs.x <= 0x7FFFFFFFUL) secs.x |= ((uint64)1 << 32) ; + secs.x += TAI_MAGIC ; + secs.x -= NTP_OFFSET ; + if (!tai_from_utc(&secs, secs.x)) return 0 ; + a->sec = secs ; + a->nano = ((u & 0xFFFFFFFFUL) * 1000000000) >> 32 ; + return 1 ; +} diff --git a/src/libstddjb/tain_from_timespec.c b/src/libstddjb/tain_from_timespec.c new file mode 100644 index 0000000..e862f46 --- /dev/null +++ b/src/libstddjb/tain_from_timespec.c @@ -0,0 +1,13 @@ +/* ISC license. */ + +#include <sys/types.h> +#include <time.h> +#include <errno.h> +#include <skalibs/tai.h> + +int tain_from_timespec (tain_t *a, struct timespec const *ts) +{ + if (!tai_from_timespec(tain_secp(a), ts)) return 0 ; + a->nano = ts->tv_nsec ; + return 1 ; +} diff --git a/src/libstddjb/tain_from_timeval.c b/src/libstddjb/tain_from_timeval.c new file mode 100644 index 0000000..9c74d13 --- /dev/null +++ b/src/libstddjb/tain_from_timeval.c @@ -0,0 +1,12 @@ +/* ISC license. */ + +#include <sys/time.h> +#include <errno.h> +#include <skalibs/tai.h> + +int tain_from_timeval (tain_t *a, struct timeval const *tv) +{ + if (!tai_from_timeval(tain_secp(a), tv)) return 0 ; + a->nano = 1000 * tv->tv_usec ; + return 1 ; +} diff --git a/src/libstddjb/tain_half.c b/src/libstddjb/tain_half.c new file mode 100644 index 0000000..a95072e --- /dev/null +++ b/src/libstddjb/tain_half.c @@ -0,0 +1,10 @@ +/* ISC license. */ + +#include <skalibs/tai.h> + +void tain_half (tain_t *t, tain_t const *u) +{ + t->nano = u->nano>>1 ; + if (tai_sec(&u->sec) & 1) t->nano += 500000000U ; + tai_u64(&t->sec, tai_sec(&u->sec)>>1) ; +} diff --git a/src/libstddjb/tain_infinite_relative.c b/src/libstddjb/tain_infinite_relative.c new file mode 100644 index 0000000..89d750c --- /dev/null +++ b/src/libstddjb/tain_infinite_relative.c @@ -0,0 +1,5 @@ +/* ISC license. */ + +#include <skalibs/tai.h> + +tain_t const tain_infinite_relative = TAIN_INFINITE_RELATIVE ; diff --git a/src/libstddjb/tain_less.c b/src/libstddjb/tain_less.c new file mode 100644 index 0000000..e52c058 --- /dev/null +++ b/src/libstddjb/tain_less.c @@ -0,0 +1,10 @@ +/* ISC license. */ + +#include <skalibs/tai.h> + +int tain_less (tain_t const *t, tain_t const *u) +{ + if (tai_sec(&t->sec) < tai_sec(&u->sec)) return 1 ; + if (tai_sec(&t->sec) > tai_sec(&u->sec)) return 0 ; + return t->nano < u->nano ; +} diff --git a/src/libstddjb/tain_nano500.c b/src/libstddjb/tain_nano500.c new file mode 100644 index 0000000..70d86c5 --- /dev/null +++ b/src/libstddjb/tain_nano500.c @@ -0,0 +1,5 @@ +/* ISC license. */ + +#include <skalibs/tai.h> + +tain_t const tain_nano500 = TAIN_NANO500 ; diff --git a/src/libstddjb/tain_now.c b/src/libstddjb/tain_now.c new file mode 100644 index 0000000..157087a --- /dev/null +++ b/src/libstddjb/tain_now.c @@ -0,0 +1,49 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include <skalibs/config.h> +#include <skalibs/sysdeps.h> +#include <skalibs/tai.h> + +#ifdef SKALIBS_FLAG_USEMON +# ifndef SKALIBS_HASCLOCKMON +# undef SKALIBS_FLAG_USEMON +# warning "SKALIBS_FLAG_USEMON set but SKALIBS_HASCLOCKMON not found. Clearing SKALIBS_FLAG_USEMON." +# endif +#endif + + +#ifdef SKALIBS_FLAG_USEMON + +static tain_t offset ; + +int tain_init () +{ + return tain_clockmon_init(&offset) ; +} + +int tain_now (tain_t *a) +{ + static int initted = 0 ; + if (!initted) + { + if (!tain_clockmon_init(&offset)) return 0 ; + initted = 1 ; + } + return tain_clockmon(a, &offset) ; +} + +#else + +int tain_init () +{ + return 1 ; +} + +int tain_now (tain_t *a) +{ + return tain_sysclock(a) ; +} + +#endif diff --git a/src/libstddjb/tain_pack.c b/src/libstddjb/tain_pack.c new file mode 100644 index 0000000..cb1918a --- /dev/null +++ b/src/libstddjb/tain_pack.c @@ -0,0 +1,10 @@ +/* ISC license. */ + +#include <skalibs/uint32.h> +#include <skalibs/tai.h> + +void tain_pack (char *s, tain_t const *t) +{ + tai_pack(s, &t->sec) ; + uint32_pack_big(s+8, t->nano) ; +} diff --git a/src/libstddjb/tain_pack_little.c b/src/libstddjb/tain_pack_little.c new file mode 100644 index 0000000..170da28 --- /dev/null +++ b/src/libstddjb/tain_pack_little.c @@ -0,0 +1,10 @@ +/* ISC license. */ + +#include <skalibs/uint32.h> +#include <skalibs/tai.h> + +void tain_pack_little (char *s, tain_t const *t) +{ + uint32_pack(s, t->nano) ; + tai_pack_little(s+4, &t->sec) ; +} diff --git a/src/libstddjb/tain_relative_from_timespec.c b/src/libstddjb/tain_relative_from_timespec.c new file mode 100644 index 0000000..e25793e --- /dev/null +++ b/src/libstddjb/tain_relative_from_timespec.c @@ -0,0 +1,13 @@ +/* ISC license. */ + +#include <sys/types.h> +#include <time.h> +#include <errno.h> +#include <skalibs/tai.h> + +int tain_relative_from_timespec (tain_t *a, struct timespec const *ts) +{ + if (!tai_relative_from_timespec(tain_secp(a), ts)) return 0 ; + a->nano = ts->tv_nsec ; + return 1 ; +} diff --git a/src/libstddjb/tain_relative_from_timeval.c b/src/libstddjb/tain_relative_from_timeval.c new file mode 100644 index 0000000..83aa1c3 --- /dev/null +++ b/src/libstddjb/tain_relative_from_timeval.c @@ -0,0 +1,12 @@ +/* ISC license. */ + +#include <sys/time.h> +#include <errno.h> +#include <skalibs/tai.h> + +int tain_relative_from_timeval (tain_t *a, struct timeval const *tv) +{ + if (!tai_relative_from_timeval(tain_secp(a), tv)) return 0 ; + a->nano = 1000 * tv->tv_usec ; + return 1 ; +} diff --git a/src/libstddjb/tain_scan.c b/src/libstddjb/tain_scan.c new file mode 100644 index 0000000..84a0cab --- /dev/null +++ b/src/libstddjb/tain_scan.c @@ -0,0 +1,12 @@ +/* ISC license. */ + +#include <skalibs/fmtscan.h> +#include <skalibs/tai.h> + +unsigned int tain_scan (char const *s, tain_t *a) +{ + char pack[TAIN_PACK] ; + register unsigned int r = ucharn_scan(s, pack, TAIN_PACK) ; + if (r) tain_unpack(pack, a) ; + return r ; +} diff --git a/src/libstddjb/tain_setnow.c b/src/libstddjb/tain_setnow.c new file mode 100644 index 0000000..a8b372f --- /dev/null +++ b/src/libstddjb/tain_setnow.c @@ -0,0 +1,13 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include <skalibs/tai.h> + +int tain_setnow (tain_t const *a) +{ + tain_t aa ; + if (!sysclock_from_tai(&aa.sec.x, &a->sec)) return 0 ; + aa.nano = a->nano ; + return sysclock_set(&aa) ; +} diff --git a/src/libstddjb/tain_sub.c b/src/libstddjb/tain_sub.c new file mode 100644 index 0000000..f7dd4eb --- /dev/null +++ b/src/libstddjb/tain_sub.c @@ -0,0 +1,15 @@ +/* ISC license. */ + +#include <skalibs/tai.h> + +void tain_sub (tain_t *t, tain_t const *u, tain_t const *v) +{ + tain_t uu = *u ; + tai_sub(&t->sec, &uu.sec, &v->sec) ; + t->nano = uu.nano - v->nano ; + if (t->nano > uu.nano) + { + t->nano += 1000000000U ; + tai_u64(&t->sec, tai_sec(&t->sec)-1) ; + } +} diff --git a/src/libstddjb/tain_sysclock.c b/src/libstddjb/tain_sysclock.c new file mode 100644 index 0000000..7f54db6 --- /dev/null +++ b/src/libstddjb/tain_sysclock.c @@ -0,0 +1,12 @@ +/* ISC license. */ + +#include <skalibs/tai.h> + +int tain_sysclock (tain_t *a) +{ + tain_t aa ; + if (!sysclock_get(&aa)) return 0 ; + if (!tai_from_sysclock(&a->sec, aa.sec.x)) return 0 ; + a->nano = aa.nano ; + return 1 ; +} diff --git a/src/libstddjb/tain_to_millisecs.c b/src/libstddjb/tain_to_millisecs.c new file mode 100644 index 0000000..0fa9395 --- /dev/null +++ b/src/libstddjb/tain_to_millisecs.c @@ -0,0 +1,11 @@ +/* ISC license. */ + +#include <skalibs/uint64.h> +#include <skalibs/tai.h> + +int tain_to_millisecs (tain_t const *a) +{ + if (a->sec.x > (uint64)2147483) return -1 ; + if ((a->sec.x == (uint64)2147483) && (a->nano > 646000000U)) return -1 ; + return a->sec.x * 1000 + (a->nano + 999999) / 1000000U ; +} diff --git a/src/libstddjb/tain_ulong.c b/src/libstddjb/tain_ulong.c new file mode 100644 index 0000000..2ba730a --- /dev/null +++ b/src/libstddjb/tain_ulong.c @@ -0,0 +1,9 @@ +/* ISC license. */ + +#include <skalibs/tai.h> + +void tain_ulong (tain_t *t, unsigned long s) +{ + tai_u64(&t->sec, s) ; + t->nano = 0 ; +} diff --git a/src/libstddjb/tain_unpack.c b/src/libstddjb/tain_unpack.c new file mode 100644 index 0000000..a62dc29 --- /dev/null +++ b/src/libstddjb/tain_unpack.c @@ -0,0 +1,10 @@ +/* ISC license. */ + +#include <skalibs/uint32.h> +#include <skalibs/tai.h> + +void tain_unpack (char const *s, tain_t *t) +{ + tai_unpack(s, &t->sec) ; + uint32_unpack_big(s+8, &t->nano) ; +} diff --git a/src/libstddjb/tain_unpack_little.c b/src/libstddjb/tain_unpack_little.c new file mode 100644 index 0000000..278d494 --- /dev/null +++ b/src/libstddjb/tain_unpack_little.c @@ -0,0 +1,10 @@ +/* ISC license. */ + +#include <skalibs/uint32.h> +#include <skalibs/tai.h> + +void tain_unpack_little (char const *s, tain_t *t) +{ + uint32_unpack(s, &t->nano) ; + tai_unpack_little(s+4, &t->sec) ; +} diff --git a/src/libstddjb/timespec_from_tai.c b/src/libstddjb/timespec_from_tai.c new file mode 100644 index 0000000..7bb84d4 --- /dev/null +++ b/src/libstddjb/timespec_from_tai.c @@ -0,0 +1,12 @@ +/* ISC license. */ + +#include <sys/types.h> +#include <time.h> +#include <skalibs/tai.h> + +int timespec_from_tai (struct timespec *ts, tai_t const *t) +{ + tai_t trel ; + tai_u64(&trel, tai_sec(t) - TAI_MAGIC) ; + return timespec_from_tai_relative(ts, &trel) ; +} diff --git a/src/libstddjb/timespec_from_tai_relative.c b/src/libstddjb/timespec_from_tai_relative.c new file mode 100644 index 0000000..42f2e95 --- /dev/null +++ b/src/libstddjb/timespec_from_tai_relative.c @@ -0,0 +1,19 @@ +/* ISC license. */ + +#include <sys/types.h> +#include <time.h> +#include <errno.h> +#include <skalibs/sysdeps.h> +#include <skalibs/uint64.h> +#include <skalibs/tai.h> + +int timespec_from_tai_relative (struct timespec *ts, tai_t const *t) +{ + if (tai_sec(t) >= (uint64)1 << 63) return (errno = EINVAL, 0) ; +#if SKALIBS_SIZEOFTIME < 8 + if (tai_sec(t) > 0xffffffffU) return (errno = ERANGE, 0) ; +#endif + ts->tv_sec = (time_t)tai_sec(t) ; + ts->tv_nsec = 0 ; + return 1 ; +} diff --git a/src/libstddjb/timespec_from_tain.c b/src/libstddjb/timespec_from_tain.c new file mode 100644 index 0000000..5eb6e30 --- /dev/null +++ b/src/libstddjb/timespec_from_tain.c @@ -0,0 +1,14 @@ +/* ISC license. */ + +#include <sys/types.h> +#include <time.h> +#include <skalibs/tai.h> + +int timespec_from_tain (struct timespec *ts, tain_t const *a) +{ + struct timespec tmp ; + if (!timespec_from_tai(&tmp, tain_secp(a))) return 0 ; + ts->tv_sec = tmp.tv_sec ; + ts->tv_nsec = a->nano ; + return 1 ; +} diff --git a/src/libstddjb/timespec_from_tain_relative.c b/src/libstddjb/timespec_from_tain_relative.c new file mode 100644 index 0000000..32e7993 --- /dev/null +++ b/src/libstddjb/timespec_from_tain_relative.c @@ -0,0 +1,14 @@ +/* ISC license. */ + +#include <sys/types.h> +#include <time.h> +#include <skalibs/tai.h> + +int timespec_from_tain_relative (struct timespec *ts, tain_t const *a) +{ + struct timespec tmp ; + if (!timespec_from_tai_relative(&tmp, tain_secp(a))) return 0 ; + ts->tv_sec = tmp.tv_sec ; + ts->tv_nsec = a->nano ; + return 1 ; +} diff --git a/src/libstddjb/timestamp.c b/src/libstddjb/timestamp.c new file mode 100644 index 0000000..7feb7c2 --- /dev/null +++ b/src/libstddjb/timestamp.c @@ -0,0 +1,9 @@ +/* ISC license. */ + +#include <skalibs/tai.h> + +int timestamp (char *s) +{ + tain_t now ; + return timestamp_r(s, &now) ; +} diff --git a/src/libstddjb/timestamp_fmt.c b/src/libstddjb/timestamp_fmt.c new file mode 100644 index 0000000..1956723 --- /dev/null +++ b/src/libstddjb/timestamp_fmt.c @@ -0,0 +1,9 @@ +/* ISC license. */ + +#include <skalibs/tai.h> + +unsigned int timestamp_fmt (char *s, tain_t const *a) +{ + *s = '@' ; + return 1 + tain_fmt(s+1, a) ; +} diff --git a/src/libstddjb/timestamp_r.c b/src/libstddjb/timestamp_r.c new file mode 100644 index 0000000..6eb8ab7 --- /dev/null +++ b/src/libstddjb/timestamp_r.c @@ -0,0 +1,10 @@ +/* ISC license. */ + +#include <skalibs/tai.h> + +int timestamp_r (char *s, tain_t *stamp) +{ + if (!tain_sysclock(stamp)) return 0 ; + timestamp_fmt(s, stamp) ; + return 1 ; +} diff --git a/src/libstddjb/timestamp_scan.c b/src/libstddjb/timestamp_scan.c new file mode 100644 index 0000000..1d48612 --- /dev/null +++ b/src/libstddjb/timestamp_scan.c @@ -0,0 +1,11 @@ +/* ISC license. */ + +#include <skalibs/tai.h> + +unsigned int timestamp_scan (char const *s, tain_t *a) +{ + register unsigned int r ; + if (*s != '@') return 0 ; + r = tain_scan(s+1, a) ; + return r ? r+1 : 0 ; +} diff --git a/src/libstddjb/timeval_from_tai.c b/src/libstddjb/timeval_from_tai.c new file mode 100644 index 0000000..d0c4777 --- /dev/null +++ b/src/libstddjb/timeval_from_tai.c @@ -0,0 +1,11 @@ +/* ISC license. */ + +#include <sys/time.h> +#include <skalibs/tai.h> + +int timeval_from_tai (struct timeval *tv, tai_t const *t) +{ + tai_t trel ; + tai_u64(&trel, tai_sec(t) - TAI_MAGIC) ; + return timeval_from_tai_relative(tv, &trel) ; +} diff --git a/src/libstddjb/timeval_from_tai_relative.c b/src/libstddjb/timeval_from_tai_relative.c new file mode 100644 index 0000000..94bd3f7 --- /dev/null +++ b/src/libstddjb/timeval_from_tai_relative.c @@ -0,0 +1,18 @@ +/* ISC license. */ + +#include <sys/time.h> +#include <errno.h> +#include <skalibs/sysdeps.h> +#include <skalibs/uint64.h> +#include <skalibs/tai.h> + +int timeval_from_tai_relative (struct timeval *tv, tai_t const *t) +{ + if (tai_sec(t) >= (uint64)1 << 63) return (errno = EINVAL, 0) ; +#if SKALIBS_SIZEOFTIME < 8 + if (tai_sec(t) > 0xffffffffU) return (errno = ERANGE, 0) ; +#endif + tv->tv_sec = (time_t)tai_sec(t) ; + tv->tv_usec = 0 ; + return 1 ; +} diff --git a/src/libstddjb/timeval_from_tain.c b/src/libstddjb/timeval_from_tain.c new file mode 100644 index 0000000..c780af7 --- /dev/null +++ b/src/libstddjb/timeval_from_tain.c @@ -0,0 +1,13 @@ +/* ISC license. */ + +#include <sys/time.h> +#include <skalibs/tai.h> + +int timeval_from_tain (struct timeval *tv, tain_t const *a) +{ + struct timeval tmp ; + if (!timeval_from_tai(&tmp, tain_secp(a))) return 0 ; + tv->tv_sec = tmp.tv_sec ; + tv->tv_usec = a->nano / 1000 ; + return 1 ; +} diff --git a/src/libstddjb/timeval_from_tain_relative.c b/src/libstddjb/timeval_from_tain_relative.c new file mode 100644 index 0000000..624293c --- /dev/null +++ b/src/libstddjb/timeval_from_tain_relative.c @@ -0,0 +1,13 @@ +/* ISC license. */ + +#include <sys/time.h> +#include <skalibs/tai.h> + +int timeval_from_tain_relative (struct timeval *tv, tain_t const *a) +{ + struct timeval tmp ; + if (!timeval_from_tai_relative(&tmp, tain_secp(a))) return 0 ; + tv->tv_sec = tmp.tv_sec ; + tv->tv_usec = a->nano / 1000 ; + return 1 ; +} diff --git a/src/libstddjb/ucharn_findlen.c b/src/libstddjb/ucharn_findlen.c new file mode 100644 index 0000000..1016647 --- /dev/null +++ b/src/libstddjb/ucharn_findlen.c @@ -0,0 +1,10 @@ +/* ISC license. */ + +#include <skalibs/fmtscan.h> + +unsigned int ucharn_findlen (char const *s) +{ + register unsigned int i = 0 ; + while (fmtscan_num(s[i], 16) <= 0xF) i++ ; + return i ; +} diff --git a/src/libstddjb/ucharn_fmt.c b/src/libstddjb/ucharn_fmt.c new file mode 100644 index 0000000..2943fdf --- /dev/null +++ b/src/libstddjb/ucharn_fmt.c @@ -0,0 +1,14 @@ +/* ISC license. */ + +#include <skalibs/fmtscan.h> + +unsigned int ucharn_fmt (char *s, char const *key, unsigned int n) +{ + register unsigned int i = 0 ; + for (; i < n ; i++) + { + s[i<<1] = fmtscan_asc((unsigned char)key[i] >> 4) ; + s[(i<<1)+1] = fmtscan_asc((unsigned char)key[i] & 0xF) ; + } + return n << 1 ; +} diff --git a/src/libstddjb/ucharn_fmt_little.c b/src/libstddjb/ucharn_fmt_little.c new file mode 100644 index 0000000..8450c46 --- /dev/null +++ b/src/libstddjb/ucharn_fmt_little.c @@ -0,0 +1,14 @@ +/* ISC license. */ + +#include <skalibs/fmtscan.h> + +unsigned int ucharn_fmt_little (char *s, char const *key, unsigned int n) +{ + register unsigned int i = 0 ; + for (; i < n ; i++) + { + s[i<<1] = fmtscan_asc((unsigned char)key[i] & 0xF) ; + s[(i<<1)+1] = fmtscan_asc((unsigned char)key[i] >> 4) ; + } + return n << 1 ; +} diff --git a/src/libstddjb/ucharn_scan.c b/src/libstddjb/ucharn_scan.c new file mode 100644 index 0000000..cdcc403 --- /dev/null +++ b/src/libstddjb/ucharn_scan.c @@ -0,0 +1,18 @@ +/* ISC license. */ + +#include <skalibs/fmtscan.h> + +unsigned int ucharn_scan (char const *s, char *key, unsigned int n) +{ + register unsigned int i = 0 ; + for (; i < n ; i++) + { + unsigned char c = fmtscan_num(s[2*i], 16) ; + if (c > 0xF) return 0 ; + key[i] = c << 4 ; + c = fmtscan_num(s[2*i+1], 16) ; + if (c > 0xF) return 0 ; + key[i] += c ; + } + return n << 1 ; +} diff --git a/src/libstddjb/ucharn_scan_little.c b/src/libstddjb/ucharn_scan_little.c new file mode 100644 index 0000000..5b66af5 --- /dev/null +++ b/src/libstddjb/ucharn_scan_little.c @@ -0,0 +1,18 @@ +/* ISC license. */ + +#include <skalibs/fmtscan.h> + +unsigned int ucharn_scan_little (char const *s, char *key, unsigned int n) +{ + register unsigned int i = 0 ; + for (; i < n ; i++) + { + unsigned char c = fmtscan_num(s[(i<<1)+1], 16) ; + if (c > 0xF) return 0 ; + key[i] = c << 4 ; + c = fmtscan_num(s[i<<1], 16) ; + if (c > 0xF) return 0 ; + key[i] += c ; + } + return n << 1 ; +} diff --git a/src/libstddjb/ucspi_get.c b/src/libstddjb/ucspi_get.c new file mode 100644 index 0000000..916ae2a --- /dev/null +++ b/src/libstddjb/ucspi_get.c @@ -0,0 +1,22 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/bytestr.h> +#include <skalibs/env.h> + +char const *ucspi_get (char const *s) +{ + char const *x = env_get("PROTO") ; + if (x) + { + unsigned int len = str_len(s) ; + unsigned int xlen = str_len(x) ; + char tmp[len + xlen + 1] ; + byte_copy(tmp, xlen, x) ; + byte_copy(tmp + xlen, len + 1, s) ; + x = env_get(tmp) ; + if (!x) errno = ENOENT ; + } + else errno = EINVAL ; + return x ; +} diff --git a/src/libstddjb/uint160_scan.c b/src/libstddjb/uint160_scan.c new file mode 100644 index 0000000..9a48514 --- /dev/null +++ b/src/libstddjb/uint160_scan.c @@ -0,0 +1,6 @@ +/* ISC license. */ + +#include <skalibs/uint16.h> +#include "fmtscan-internal.h" + +SCANB0(16) diff --git a/src/libstddjb/uint16_fmtlist.c b/src/libstddjb/uint16_fmtlist.c new file mode 100644 index 0000000..721b443 --- /dev/null +++ b/src/libstddjb/uint16_fmtlist.c @@ -0,0 +1,6 @@ +/* ISC license. */ + +#include <skalibs/uint16.h> +#include "fmtscan-internal.h" + +FMTL(16) diff --git a/src/libstddjb/uint16_pack.c b/src/libstddjb/uint16_pack.c new file mode 100644 index 0000000..c84f504 --- /dev/null +++ b/src/libstddjb/uint16_pack.c @@ -0,0 +1,10 @@ +/* ISC license. */ + +#include <skalibs/uint16.h> +#include <skalibs/bytestr.h> + +void uint16_pack (char *s, uint16 u) +{ + ((unsigned char *)s)[0] = T8(u) ; u >>= 8 ; + ((unsigned char *)s)[1] = T8(u) ; +} diff --git a/src/libstddjb/uint16_pack_big.c b/src/libstddjb/uint16_pack_big.c new file mode 100644 index 0000000..9fac1fa --- /dev/null +++ b/src/libstddjb/uint16_pack_big.c @@ -0,0 +1,10 @@ +/* ISC license. */ + +#include <skalibs/uint16.h> +#include <skalibs/bytestr.h> + +void uint16_pack_big (char *s, uint16 u) +{ + ((unsigned char *)s)[1] = T8(u) ; u >>= 8 ; + ((unsigned char *)s)[0] = T8(u) ; +} diff --git a/src/libstddjb/uint16_reverse.c b/src/libstddjb/uint16_reverse.c new file mode 100644 index 0000000..fedade1 --- /dev/null +++ b/src/libstddjb/uint16_reverse.c @@ -0,0 +1,14 @@ +/* ISC license. */ + +#include <skalibs/uint16.h> + +void uint16_reverse (char *s, unsigned int n) +{ + while (n--) + { + char c = s[0] ; + s[0] = s[1] ; + s[1] = c ; + s += 2 ; + } +} diff --git a/src/libstddjb/uint16_scan.c b/src/libstddjb/uint16_scan.c new file mode 100644 index 0000000..5665807 --- /dev/null +++ b/src/libstddjb/uint16_scan.c @@ -0,0 +1,6 @@ +/* ISC license. */ + +#include <skalibs/uint16.h> +#include "fmtscan-internal.h" + +SCANB(16) diff --git a/src/libstddjb/uint16_scanlist.c b/src/libstddjb/uint16_scanlist.c new file mode 100644 index 0000000..e98777f --- /dev/null +++ b/src/libstddjb/uint16_scanlist.c @@ -0,0 +1,6 @@ +/* ISC license. */ + +#include <skalibs/uint16.h> +#include "fmtscan-internal.h" + +SCANL(16) diff --git a/src/libstddjb/uint16_unpack.c b/src/libstddjb/uint16_unpack.c new file mode 100644 index 0000000..c3ade45 --- /dev/null +++ b/src/libstddjb/uint16_unpack.c @@ -0,0 +1,11 @@ +/* ISC license. */ + +#include <skalibs/uint16.h> +#include <skalibs/bytestr.h> + +void uint16_unpack (char const *s, uint16 *u) +{ + uint16 r = T8((unsigned char)s[1]) ; r <<= 8 ; + r += T8((unsigned char)s[0]) ; + *u = r ; +} diff --git a/src/libstddjb/uint16_unpack_big.c b/src/libstddjb/uint16_unpack_big.c new file mode 100644 index 0000000..2f22555 --- /dev/null +++ b/src/libstddjb/uint16_unpack_big.c @@ -0,0 +1,11 @@ +/* ISC license. */ + +#include <skalibs/uint16.h> +#include <skalibs/bytestr.h> + +void uint16_unpack_big (char const *s, uint16 *u) +{ + uint16 r = T8((unsigned char)s[0]) ; r <<= 8 ; + r += T8((unsigned char)s[1]) ; + *u = r ; +} diff --git a/src/libstddjb/uint320_scan.c b/src/libstddjb/uint320_scan.c new file mode 100644 index 0000000..103354c --- /dev/null +++ b/src/libstddjb/uint320_scan.c @@ -0,0 +1,6 @@ +/* ISC license. */ + +#include <skalibs/uint32.h> +#include "fmtscan-internal.h" + +SCANB0(32) diff --git a/src/libstddjb/uint32_fmtlist.c b/src/libstddjb/uint32_fmtlist.c new file mode 100644 index 0000000..978d72a --- /dev/null +++ b/src/libstddjb/uint32_fmtlist.c @@ -0,0 +1,6 @@ +/* ISC license. */ + +#include <skalibs/uint16.h> +#include "fmtscan-internal.h" + +FMTL(32) diff --git a/src/libstddjb/uint32_pack.c b/src/libstddjb/uint32_pack.c new file mode 100644 index 0000000..d467c3d --- /dev/null +++ b/src/libstddjb/uint32_pack.c @@ -0,0 +1,12 @@ +/* ISC license. */ + +#include <skalibs/uint32.h> +#include <skalibs/bytestr.h> + +void uint32_pack (char *s, uint32 u) +{ + ((unsigned char *)s)[0] = T8(u) ; u >>= 8 ; + ((unsigned char *)s)[1] = T8(u) ; u >>= 8 ; + ((unsigned char *)s)[2] = T8(u) ; u >>= 8 ; + ((unsigned char *)s)[3] = T8(u) ; +} diff --git a/src/libstddjb/uint32_pack_big.c b/src/libstddjb/uint32_pack_big.c new file mode 100644 index 0000000..487cf21 --- /dev/null +++ b/src/libstddjb/uint32_pack_big.c @@ -0,0 +1,12 @@ +/* ISC license. */ + +#include <skalibs/uint32.h> +#include <skalibs/bytestr.h> + +void uint32_pack_big (char *s, uint32 u) +{ + ((unsigned char *)s)[3] = T8(u) ; u >>= 8 ; + ((unsigned char *)s)[2] = T8(u) ; u >>= 8 ; + ((unsigned char *)s)[1] = T8(u) ; u >>= 8 ; + ((unsigned char *)s)[0] = T8(u) ; +} diff --git a/src/libstddjb/uint32_reverse.c b/src/libstddjb/uint32_reverse.c new file mode 100644 index 0000000..18b3b43 --- /dev/null +++ b/src/libstddjb/uint32_reverse.c @@ -0,0 +1,17 @@ +/* ISC license. */ + +#include <skalibs/uint32.h> + +void uint32_reverse (char *s, unsigned int n) +{ + while (n--) + { + char c = s[0] ; + s[0] = s[3] ; + s[3] = c ; + c = s[1] ; + s[1] = s[2] ; + s[2] = c ; + s += 4 ; + } +} diff --git a/src/libstddjb/uint32_scan.c b/src/libstddjb/uint32_scan.c new file mode 100644 index 0000000..06e2d77 --- /dev/null +++ b/src/libstddjb/uint32_scan.c @@ -0,0 +1,6 @@ +/* ISC license. */ + +#include <skalibs/uint32.h> +#include "fmtscan-internal.h" + +SCANB(32) diff --git a/src/libstddjb/uint32_scanlist.c b/src/libstddjb/uint32_scanlist.c new file mode 100644 index 0000000..f2bf094 --- /dev/null +++ b/src/libstddjb/uint32_scanlist.c @@ -0,0 +1,6 @@ +/* ISC license. */ + +#include <skalibs/uint16.h> +#include "fmtscan-internal.h" + +SCANL(32) diff --git a/src/libstddjb/uint32_unpack.c b/src/libstddjb/uint32_unpack.c new file mode 100644 index 0000000..d5dabcc --- /dev/null +++ b/src/libstddjb/uint32_unpack.c @@ -0,0 +1,13 @@ +/* ISC license. */ + +#include <skalibs/uint32.h> +#include <skalibs/bytestr.h> + +void uint32_unpack (char const *s, uint32 *u) +{ + uint32 r = T8((unsigned char)s[3]) ; r <<= 8 ; + r += T8((unsigned char)s[2]) ; r <<= 8 ; + r += T8((unsigned char)s[1]) ; r <<= 8 ; + r += T8((unsigned char)s[0]) ; + *u = r ; +} diff --git a/src/libstddjb/uint32_unpack_big.c b/src/libstddjb/uint32_unpack_big.c new file mode 100644 index 0000000..1a53292 --- /dev/null +++ b/src/libstddjb/uint32_unpack_big.c @@ -0,0 +1,13 @@ +/* ISC license. */ + +#include <skalibs/uint32.h> +#include <skalibs/bytestr.h> + +void uint32_unpack_big (char const *s, uint32 *u) +{ + uint32 r = T8((unsigned char)s[0]) ; r <<= 8 ; + r += T8((unsigned char)s[1]) ; r <<= 8 ; + r += T8((unsigned char)s[2]) ; r <<= 8 ; + r += T8((unsigned char)s[3]) ; + *u = r ; +} diff --git a/src/libstddjb/uint640_fmt.c b/src/libstddjb/uint640_fmt.c new file mode 100644 index 0000000..7153055 --- /dev/null +++ b/src/libstddjb/uint640_fmt.c @@ -0,0 +1,10 @@ +/* ISC license. */ + +#include <skalibs/uint64.h> + +unsigned int uint640_fmt_base (char *s, uint64 x, register unsigned int n, unsigned char base) +{ + register unsigned int len = uint64_fmt_base(0, x, base) ; + while (n-- > len) *s++ = '0' ; + return uint64_fmt_base(s, x, base) ; +} diff --git a/src/libstddjb/uint640_scan.c b/src/libstddjb/uint640_scan.c new file mode 100644 index 0000000..45c8e20 --- /dev/null +++ b/src/libstddjb/uint640_scan.c @@ -0,0 +1,6 @@ +/* ISC license. */ + +#include <skalibs/uint64.h> +#include "fmtscan-internal.h" + +SCANB0(64) diff --git a/src/libstddjb/uint64_fmt.c b/src/libstddjb/uint64_fmt.c new file mode 100644 index 0000000..cbe3382 --- /dev/null +++ b/src/libstddjb/uint64_fmt.c @@ -0,0 +1,19 @@ +/* ISC license. */ + +#include <skalibs/uint64.h> +#include <skalibs/fmtscan.h> + +unsigned int uint64_fmt_base (char *s, uint64 x, unsigned char base) +{ + register unsigned int len = 1 ; + { + register uint64 q = x ; + while (q >= base) { len++ ; q /= base ; } + } + if (s) + { + s += len ; + do { *--s = fmtscan_asc(x % base) ; x /= base ; } while (x) ; + } + return len ; +} diff --git a/src/libstddjb/uint64_fmtlist.c b/src/libstddjb/uint64_fmtlist.c new file mode 100644 index 0000000..4d18a8b --- /dev/null +++ b/src/libstddjb/uint64_fmtlist.c @@ -0,0 +1,6 @@ +/* ISC license. */ + +#include <skalibs/uint16.h> +#include "fmtscan-internal.h" + +FMTL(64) diff --git a/src/libstddjb/uint64_pack.c b/src/libstddjb/uint64_pack.c new file mode 100644 index 0000000..23c8e19 --- /dev/null +++ b/src/libstddjb/uint64_pack.c @@ -0,0 +1,16 @@ +/* ISC license. */ + +#include <skalibs/uint64.h> +#include <skalibs/bytestr.h> + +void uint64_pack (char *s, uint64 u) +{ + ((unsigned char *)s)[0] = T8(u) ; u >>= 8 ; + ((unsigned char *)s)[1] = T8(u) ; u >>= 8 ; + ((unsigned char *)s)[2] = T8(u) ; u >>= 8 ; + ((unsigned char *)s)[3] = T8(u) ; u >>= 8 ; + ((unsigned char *)s)[4] = T8(u) ; u >>= 8 ; + ((unsigned char *)s)[5] = T8(u) ; u >>= 8 ; + ((unsigned char *)s)[6] = T8(u) ; u >>= 8 ; + ((unsigned char *)s)[7] = T8(u) ; +} diff --git a/src/libstddjb/uint64_pack_big.c b/src/libstddjb/uint64_pack_big.c new file mode 100644 index 0000000..17d0206 --- /dev/null +++ b/src/libstddjb/uint64_pack_big.c @@ -0,0 +1,16 @@ +/* ISC license. */ + +#include <skalibs/uint64.h> +#include <skalibs/bytestr.h> + +void uint64_pack_big (char *s, uint64 u) +{ + ((unsigned char *)s)[7] = T8(u) ; u >>= 8 ; + ((unsigned char *)s)[6] = T8(u) ; u >>= 8 ; + ((unsigned char *)s)[5] = T8(u) ; u >>= 8 ; + ((unsigned char *)s)[4] = T8(u) ; u >>= 8 ; + ((unsigned char *)s)[3] = T8(u) ; u >>= 8 ; + ((unsigned char *)s)[2] = T8(u) ; u >>= 8 ; + ((unsigned char *)s)[1] = T8(u) ; u >>= 8 ; + ((unsigned char *)s)[0] = T8(u) ; +} diff --git a/src/libstddjb/uint64_reverse.c b/src/libstddjb/uint64_reverse.c new file mode 100644 index 0000000..f8730fe --- /dev/null +++ b/src/libstddjb/uint64_reverse.c @@ -0,0 +1,15 @@ +/* ISC license. */ + +#include <skalibs/uint64.h> + +void uint64_reverse (char *s, unsigned int n) +{ + while (n--) + { + char c = s[0] ; s[0] = s[7] ; s[7] = c ; + c = s[1] ; s[1] = s[6] ; s[6] = c ; + c = s[2] ; s[2] = s[5] ; s[5] = c ; + c = s[3] ; s[3] = s[4] ; s[4] = c ; + s += 8 ; + } +} diff --git a/src/libstddjb/uint64_scan.c b/src/libstddjb/uint64_scan.c new file mode 100644 index 0000000..530e84c --- /dev/null +++ b/src/libstddjb/uint64_scan.c @@ -0,0 +1,6 @@ +/* ISC license. */ + +#include <skalibs/uint64.h> +#include "fmtscan-internal.h" + +SCANB(64) diff --git a/src/libstddjb/uint64_scanlist.c b/src/libstddjb/uint64_scanlist.c new file mode 100644 index 0000000..4a22478 --- /dev/null +++ b/src/libstddjb/uint64_scanlist.c @@ -0,0 +1,6 @@ +/* ISC license. */ + +#include <skalibs/uint16.h> +#include "fmtscan-internal.h" + +SCANL(64) diff --git a/src/libstddjb/uint64_unpack.c b/src/libstddjb/uint64_unpack.c new file mode 100644 index 0000000..e0561d9 --- /dev/null +++ b/src/libstddjb/uint64_unpack.c @@ -0,0 +1,17 @@ +/* ISC license. */ + +#include <skalibs/uint64.h> +#include <skalibs/bytestr.h> + +void uint64_unpack (char const *s, uint64 *u) +{ + uint64 r = T8((unsigned char)s[7]) ; r <<= 8 ; + r += T8((unsigned char)s[6]) ; r <<= 8 ; + r += T8((unsigned char)s[5]) ; r <<= 8 ; + r += T8((unsigned char)s[4]) ; r <<= 8 ; + r += T8((unsigned char)s[3]) ; r <<= 8 ; + r += T8((unsigned char)s[2]) ; r <<= 8 ; + r += T8((unsigned char)s[1]) ; r <<= 8 ; + r += T8((unsigned char)s[0]) ; + *u = r ; +} diff --git a/src/libstddjb/uint64_unpack_big.c b/src/libstddjb/uint64_unpack_big.c new file mode 100644 index 0000000..ebb419b --- /dev/null +++ b/src/libstddjb/uint64_unpack_big.c @@ -0,0 +1,17 @@ +/* ISC license. */ + +#include <skalibs/uint64.h> +#include <skalibs/bytestr.h> + +void uint64_unpack_big (char const *s, uint64 *u) +{ + uint64 r = T8((unsigned char)s[0]) ; r <<= 8 ; + r += T8((unsigned char)s[1]) ; r <<= 8 ; + r += T8((unsigned char)s[2]) ; r <<= 8 ; + r += T8((unsigned char)s[3]) ; r <<= 8 ; + r += T8((unsigned char)s[4]) ; r <<= 8 ; + r += T8((unsigned char)s[5]) ; r <<= 8 ; + r += T8((unsigned char)s[6]) ; r <<= 8 ; + r += T8((unsigned char)s[7]) ; + *u = r ; +} diff --git a/src/libstddjb/uncoe.c b/src/libstddjb/uncoe.c new file mode 100644 index 0000000..61593b9 --- /dev/null +++ b/src/libstddjb/uncoe.c @@ -0,0 +1,11 @@ +/* ISC license. */ + +#include <fcntl.h> +#include <skalibs/djbunix.h> + +int uncoe (int fd) +{ + register int flags = fcntl(fd, F_GETFD, 0) ; + if (flags < 0) return -1 ; + return fcntl(fd, F_SETFD, flags & ~FD_CLOEXEC) ; +} diff --git a/src/libstddjb/unsanitize_read.c b/src/libstddjb/unsanitize_read.c new file mode 100644 index 0000000..efea22a --- /dev/null +++ b/src/libstddjb/unsanitize_read.c @@ -0,0 +1,11 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/allreadwrite.h> +#include <skalibs/error.h> + +int unsanitize_read (int r) +{ + return r == -1 ? errno == EPIPE ? (errno = 0, 0) : -1 : + !r ? (errno = EWOULDBLOCK, -1) : r ; +} diff --git a/src/libstddjb/utc_from_localtm.c b/src/libstddjb/utc_from_localtm.c new file mode 100644 index 0000000..cad1a06 --- /dev/null +++ b/src/libstddjb/utc_from_localtm.c @@ -0,0 +1,15 @@ +/* ISC license. */ + +#include <sys/types.h> +#include <time.h> +#include <skalibs/uint64.h> +#include <skalibs/djbtime.h> + +int utc_from_localtm (uint64 *uu, struct tm const *l) +{ + uint64 u ; + if (!ltm64_from_localtm(&u, l)) return 0 ; + if (!utc_from_ltm64(&u)) return 0 ; + *uu = u ; + return 1 ; +} diff --git a/src/libstddjb/utc_from_ltm64.c b/src/libstddjb/utc_from_ltm64.c new file mode 100644 index 0000000..44aea15 --- /dev/null +++ b/src/libstddjb/utc_from_ltm64.c @@ -0,0 +1,23 @@ +/* ISC license. */ + +#include <skalibs/config.h> +#include <skalibs/uint64.h> +#include <skalibs/djbtime.h> +#include "djbtime-internal.h" + +#ifdef SKALIBS_FLAG_CLOCKISTAI + +int utc_from_ltm64 (uint64 *u) +{ + return (leapsecs_sub(u) > 0) ; +} + +#else + +int utc_from_ltm64 (uint64 *u) +{ + (void)u ; + return 1 ; +} + +#endif diff --git a/src/libstddjb/utc_from_sysclock.c b/src/libstddjb/utc_from_sysclock.c new file mode 100644 index 0000000..979bb04 --- /dev/null +++ b/src/libstddjb/utc_from_sysclock.c @@ -0,0 +1,25 @@ +/* ISC license. */ + +#include <skalibs/config.h> +#include <skalibs/uint64.h> +#include <skalibs/djbtime.h> + +#ifdef SKALIBS_FLAG_CLOCKISTAI + +#include <skalibs/tai.h> + +int utc_from_sysclock (uint64 *u) +{ + tai_t t = { .x = *u + 10U } ; + return utc_from_tai(u, &t) ; +} + +#else + +int utc_from_sysclock (uint64 *u) +{ + (void)u ; + return 1 ; +} + +#endif diff --git a/src/libstddjb/utc_from_tai.c b/src/libstddjb/utc_from_tai.c new file mode 100644 index 0000000..f4d247e --- /dev/null +++ b/src/libstddjb/utc_from_tai.c @@ -0,0 +1,14 @@ +/* ISC license. */ + +#include <skalibs/uint64.h> +#include <skalibs/tai.h> +#include <skalibs/djbtime.h> +#include "djbtime-internal.h" + +int utc_from_tai (uint64 *u, tai_t const *t) +{ + uint64 tt = t->x - 10 ; + if (leapsecs_sub(&tt) < 0) return 0 ; + *u = tt ; + return 1 ; +} diff --git a/src/libstddjb/vbaprintf.c b/src/libstddjb/vbaprintf.c new file mode 100644 index 0000000..efc2bd1 --- /dev/null +++ b/src/libstddjb/vbaprintf.c @@ -0,0 +1,23 @@ +/* ISC license. */ + +#include <stdarg.h> +#include <stdio.h> +#include <skalibs/stralloc.h> +#include <skalibs/bufalloc.h> +#include <skalibs/lolstdio.h> + +int vbaprintf (bufalloc *ba, char const *format, va_list args) +{ + int r ; + { + va_list ugly ; + va_copy(ugly, args) ; + r = vsnprintf(0, 0, format, ugly) ; + va_end(ugly) ; + } + if (r < 0) return r ; + if (!stralloc_readyplus(&ba->x, (unsigned int)r + 1)) return -1 ; + r = vsnprintf(ba->x.s + ba->x.len, (unsigned int)r + 1, format, args) ; + if (r > 0) ba->x.len += r ; + return r ; +} diff --git a/src/libstddjb/vbprintf.c b/src/libstddjb/vbprintf.c new file mode 100644 index 0000000..a6a75f3 --- /dev/null +++ b/src/libstddjb/vbprintf.c @@ -0,0 +1,25 @@ +/* ISC license. */ + +#include <stdarg.h> +#include <stdio.h> +#include <skalibs/buffer.h> +#include <skalibs/lolstdio.h> + +int vbprintf (buffer *b, char const *format, va_list args) +{ + int r ; + { + va_list ugly ; + va_copy(ugly, args) ; + r = vsnprintf(0, 0, format, ugly) ; + va_end(ugly) ; + } + if (r < 0) return r ; + { + char buf[(unsigned int)r + 1] ; + r = vsnprintf(buf, (unsigned int)r + 1, format, args) ; + if (r < 0) return r ; + if (buffer_put(b, buf, r) < r) return -1 ; + } + return r ; +} diff --git a/src/libstddjb/wait_nointr.c b/src/libstddjb/wait_nointr.c new file mode 100644 index 0000000..02dcd42 --- /dev/null +++ b/src/libstddjb/wait_nointr.c @@ -0,0 +1,15 @@ +/* ISC license. */ + +#include <sys/types.h> +#include <sys/wait.h> +#include <errno.h> +#include <skalibs/djbunix.h> + +pid_t wait_nointr (int *wstat) +{ + register pid_t r ; + do + r = wait(wstat) ; + while ((r == (pid_t)-1) && (errno == EINTR)) ; + return r ; +} diff --git a/src/libstddjb/wait_pid_nohang.c b/src/libstddjb/wait_pid_nohang.c new file mode 100644 index 0000000..11beed6 --- /dev/null +++ b/src/libstddjb/wait_pid_nohang.c @@ -0,0 +1,17 @@ +/* ISC license. */ + +#include <sys/types.h> +#include <skalibs/djbunix.h> + +pid_t wait_pid_nohang (pid_t pid, int *wstat) +{ + int w = 0 ; + register pid_t r = 0 ; + while (r != pid) + { + r = wait_nohang(&w) ; + if (!r || (r == (pid_t)-1)) return (int)r ; + } + *wstat = w ; + return r ; +} diff --git a/src/libstddjb/wait_pids_nohang.c b/src/libstddjb/wait_pids_nohang.c new file mode 100644 index 0000000..3c52e6b --- /dev/null +++ b/src/libstddjb/wait_pids_nohang.c @@ -0,0 +1,23 @@ +/* ISC license. */ + +#include <sys/types.h> +#include <skalibs/djbunix.h> + +int wait_pids_nohang (pid_t const *pids, unsigned int len, int *wstat) +{ + for (;;) + { + int w ; + register pid_t r = wait_nohang(&w) ; + if (!r || (r == (pid_t)-1)) return (int)r ; + { + register unsigned int i = 0 ; + for (; i < len ; i++) if (r == pids[i]) break ; + if (i < len) + { + *wstat = w ; + return 1+i ; + } + } + } +} diff --git a/src/libstddjb/wait_reap.c b/src/libstddjb/wait_reap.c new file mode 100644 index 0000000..7049b27 --- /dev/null +++ b/src/libstddjb/wait_reap.c @@ -0,0 +1,11 @@ +/* ISC license. */ + +#include <skalibs/djbunix.h> + +unsigned int wait_reap () +{ + register unsigned int n = 0 ; + int wstat ; + while (wait_nohang(&wstat) > 0) n++ ; + return n ; +} diff --git a/src/libstddjb/waitn.c b/src/libstddjb/waitn.c new file mode 100644 index 0000000..0d01cd1 --- /dev/null +++ b/src/libstddjb/waitn.c @@ -0,0 +1,18 @@ +/* ISC license. */ + +#include <sys/types.h> +#include <skalibs/djbunix.h> + +int waitn (pid_t *pids, unsigned int n) +{ + while (n) + { + int wstat ; + register unsigned int i = 0 ; + register pid_t pid = wait_nointr(&wstat) ; + if (pid < 0) return 0 ; + for (; i < n ; i++) if (pid == pids[i]) break ; + if (i < n) pids[i] = pids[--n] ; + } + return 1 ; +} diff --git a/src/libstddjb/waitn_reap.c b/src/libstddjb/waitn_reap.c new file mode 100644 index 0000000..96a0c61 --- /dev/null +++ b/src/libstddjb/waitn_reap.c @@ -0,0 +1,19 @@ +/* ISC license. */ + +#include <sys/types.h> +#include <skalibs/djbunix.h> + +int waitn_reap (pid_t *pids, unsigned int len) +{ + unsigned int n = 0 ; + while (len) + { + int w ; + register int r = wait_pids_nohang(pids, len, &w) ; + if (r < 0) return r ; + else if (!r) break ; + pids[r-1] = pids[--len] ; + n++ ; + } + return (int)n ; +} diff --git a/src/libstddjb/waitpid_nointr.c b/src/libstddjb/waitpid_nointr.c new file mode 100644 index 0000000..8c6a65e --- /dev/null +++ b/src/libstddjb/waitpid_nointr.c @@ -0,0 +1,15 @@ +/* ISC license. */ + +#include <sys/types.h> +#include <sys/wait.h> +#include <errno.h> +#include <skalibs/djbunix.h> + +pid_t waitpid_nointr (pid_t pid, int *wstat, int flags) +{ + register pid_t r ; + do + r = waitpid(pid, wstat, flags) ; + while ((r == (pid_t)-1) && (errno == EINTR)) ; + return r ; +} diff --git a/src/libunixonacid/bufalloc_timed_flush.c b/src/libunixonacid/bufalloc_timed_flush.c new file mode 100644 index 0000000..df0eb79 --- /dev/null +++ b/src/libunixonacid/bufalloc_timed_flush.c @@ -0,0 +1,16 @@ +/* ISC license. */ + +#include <skalibs/bufalloc.h> +#include <skalibs/functypes.h> +#include <skalibs/tai.h> +#include <skalibs/unix-timed.h> + +static int bufalloc_isnonempty (bufalloc *ba) +{ + return !!bufalloc_len(ba) ; +} + +int bufalloc_timed_flush (bufalloc *ba, tain_t const *deadline, tain_t *stamp) +{ + return timed_flush(ba, (initfunc_t_ref)&bufalloc_getfd, (initfunc_t_ref)&bufalloc_isnonempty, (initfunc_t_ref)&bufalloc_flush, deadline, stamp) ; +} diff --git a/src/libunixonacid/buffer_timed_fill.c b/src/libunixonacid/buffer_timed_fill.c new file mode 100644 index 0000000..c6f580f --- /dev/null +++ b/src/libunixonacid/buffer_timed_fill.c @@ -0,0 +1,17 @@ +/* ISC license. */ + +#include <skalibs/allreadwrite.h> +#include <skalibs/buffer.h> +#include <skalibs/functypes.h> +#include <skalibs/tai.h> +#include <skalibs/unix-timed.h> + +static int get (buffer *b) +{ + return sanitize_read(buffer_fill(b)) ; +} + +int buffer_timed_fill (buffer *b, tain_t const *deadline, tain_t *stamp) +{ + return timed_get(b, (initfunc_t_ref)&buffer_getfd, (initfunc_t_ref)&get, deadline, stamp) ; +} diff --git a/src/libunixonacid/buffer_timed_flush.c b/src/libunixonacid/buffer_timed_flush.c new file mode 100644 index 0000000..63a2587 --- /dev/null +++ b/src/libunixonacid/buffer_timed_flush.c @@ -0,0 +1,16 @@ +/* ISC license. */ + +#include <skalibs/buffer.h> +#include <skalibs/functypes.h> +#include <skalibs/tai.h> +#include <skalibs/unix-timed.h> + +static int buffer_isnonempty (buffer *b) +{ + return !buffer_isempty(b) ; +} + +int timed_buffer_flush (buffer *b, tain_t const *deadline, tain_t *stamp) +{ + return timed_flush(b, (initfunc_t_ref)&buffer_getfd, (initfunc_t_ref)&buffer_isnonempty, (initfunc_t_ref)&buffer_flush, deadline, stamp) ; +} diff --git a/src/libunixonacid/buffer_timed_get.c b/src/libunixonacid/buffer_timed_get.c new file mode 100644 index 0000000..2f3b751 --- /dev/null +++ b/src/libunixonacid/buffer_timed_get.c @@ -0,0 +1,30 @@ +/* ISC license. */ + +#include <skalibs/buffer.h> +#include <skalibs/tai.h> +#include <skalibs/unix-timed.h> + +struct blah_s +{ + buffer *b ; + char *s ; + unsigned int len ; + unsigned int w ; +} ; + +static int getfd (struct blah_s *blah) +{ + return buffer_fd(blah->b) ; +} + +static int get (struct blah_s *blah) +{ + return buffer_getall(blah->b, blah->s, blah->len, &blah->w) ; +} + +unsigned int buffer_timed_get (buffer *b, char *s, unsigned int len, tain_t const *deadline, tain_t *stamp) +{ + struct blah_s blah = { .b = b, .s = s, .len = len, .w = 0 } ; + timed_get(&blah, (initfunc_t_ref)&getfd, (initfunc_t_ref)&get, deadline, stamp) ; + return blah.w ; +} diff --git a/src/libunixonacid/dd_cancel.c b/src/libunixonacid/dd_cancel.c new file mode 100644 index 0000000..22adf4e --- /dev/null +++ b/src/libunixonacid/dd_cancel.c @@ -0,0 +1,17 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/stralloc.h> +#include <skalibs/djbunix.h> +#include <skalibs/unix-transactional.h> + +void dd_cancel (dirdescriptor_t_ref dd) +{ + dirdescriptor_t zero = DIRDESCRIPTOR_ZERO ; + register int e = errno ; + fd_close(dd->fd) ; + rm_rf_in_tmp(&dd->new, 0) ; + stralloc_free(&dd->new) ; + *dd = zero ; + errno = e ; +} diff --git a/src/libunixonacid/dd_close.c b/src/libunixonacid/dd_close.c new file mode 100644 index 0000000..74961a1 --- /dev/null +++ b/src/libunixonacid/dd_close.c @@ -0,0 +1,9 @@ +/* ISC license. */ + +#include <skalibs/djbunix.h> +#include <skalibs/unix-transactional.h> + +int dd_close (dirdescriptor_t_ref dd) +{ + return (fd_close(dd->fd) >= 0) ; +} diff --git a/src/libunixonacid/dd_commit.c b/src/libunixonacid/dd_commit.c new file mode 100644 index 0000000..b55addb --- /dev/null +++ b/src/libunixonacid/dd_commit.c @@ -0,0 +1,68 @@ +/* ISC license. */ + +#include <unistd.h> +#include <errno.h> +#include <stdio.h> /* for rename() */ +#include <skalibs/bytestr.h> +#include <skalibs/stralloc.h> +#include <skalibs/djbunix.h> +#include <skalibs/random.h> +#include <skalibs/unix-transactional.h> + +static char const *mybasename (char const *s, unsigned int len) +{ + register unsigned int i = len ; + while (i--) if (s[i] == '/') return s + i + 1 ; + return s ; +} + +int dd_commit (dirdescriptor_t_ref dd) +{ + dirdescriptor_t zero = DIRDESCRIPTOR_ZERO ; + unsigned int len = str_len(dd->lnkfn) ; + unsigned int oldbase = dd->new.len ; + unsigned int newlnkbase ; + char const *lnkbn = mybasename(dd->lnkfn, len) ; + if (!sadirname(&dd->new, dd->lnkfn, len)) return 0 ; + if (!stralloc_catb(&dd->new, "/", 1)) goto fail ; + if (sareadlink(&dd->new, dd->lnkfn) < 0) + { + unsigned int lnkbnbase = dd->new.len ; + if (errno != EINVAL) goto fail ; + if (!stralloc_cats(&dd->new, lnkbn)) goto fail ; + if (random_sauniquename(&dd->new, 8) < 0) goto fail ; + if (!stralloc_0(&dd->new)) goto fail ; + if (rename(dd->lnkfn, dd->new.s + oldbase) < 0) goto fail ; + /* /!\ race condition right here: there's no lnkfn in the fs */ + if (symlink(dd->new.s + lnkbnbase, dd->lnkfn) < 0) /* now that's VERY BAD if it fails */ + { + register int e = errno ; + rename(dd->new.s + oldbase, dd->lnkfn) ; /* attempt to revert to initial situation */ + errno = e ; + goto fail ; /* and hope for the best */ + } + } + if (!stralloc_0(&dd->new)) goto fail ; + newlnkbase = dd->new.len ; + if (!stralloc_catb(&dd->new, dd->lnkfn, len)) goto fail ; + if (random_sauniquename(&dd->new, 8) < 0) goto fail ; + if (!stralloc_0(&dd->new)) goto fail ; + if (symlink(dd->new.s, dd->new.s + newlnkbase) < 0) goto fail ; + if (rename(dd->new.s + newlnkbase, dd->lnkfn) < 0) + { + register int e = errno ; + unlink(dd->new.s + newlnkbase) ; + errno = e ; + goto fail ; + } + fd_close(dd->fd) ; + dd->new.len = newlnkbase ; + rm_rf_in_tmp(&dd->new, oldbase) ; + stralloc_free(&dd->new) ; + *dd = zero ; + return 1 ; + + fail: + dd->new.len = oldbase ; + return 0 ; +} diff --git a/src/libunixonacid/dd_commit_devino.c b/src/libunixonacid/dd_commit_devino.c new file mode 100644 index 0000000..481db19 --- /dev/null +++ b/src/libunixonacid/dd_commit_devino.c @@ -0,0 +1,16 @@ +/* ISC license. */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <skalibs/uint64.h> +#include <skalibs/unix-transactional.h> + +int dd_commit_devino (dirdescriptor_t_ref dd, uint64 *dev, uint64 *ino) +{ + struct stat st ; + if (fstat(dd->fd, &st) < 0) return 0 ; + if (!dd_commit(dd)) return 0 ; + *dev = (uint64)st.st_dev ; + *ino = (uint64)st.st_ino ; + return 1 ; +} diff --git a/src/libunixonacid/dd_open_read.c b/src/libunixonacid/dd_open_read.c new file mode 100644 index 0000000..1996297 --- /dev/null +++ b/src/libunixonacid/dd_open_read.c @@ -0,0 +1,14 @@ +/* ISC license. */ + +#include <skalibs/djbunix.h> +#include <skalibs/unix-transactional.h> + +int dd_open_read (dirdescriptor_t_ref dd, char const *path) +{ + dirdescriptor_t d = DIRDESCRIPTOR_ZERO ; + d.fd = open_read(path) ; + if (d.fd < 0) return 0 ; + d.lnkfn = path ; + *dd = d ; + return 1 ; +} diff --git a/src/libunixonacid/dd_open_write.c b/src/libunixonacid/dd_open_write.c new file mode 100644 index 0000000..efee60f --- /dev/null +++ b/src/libunixonacid/dd_open_write.c @@ -0,0 +1,34 @@ +/* ISC license. */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <errno.h> +#include <skalibs/stralloc.h> +#include <skalibs/djbunix.h> +#include <skalibs/random.h> +#include <skalibs/unix-transactional.h> + +int dd_open_write (dirdescriptor_t_ref dd, char const *lnkfn, unsigned int mode) +{ + dirdescriptor_t d = DIRDESCRIPTOR_ZERO ; + d.lnkfn = lnkfn ; + if (!stralloc_cats(&d.new, lnkfn)) return 0 ; + if (random_sauniquename(&d.new, 8) < 0) goto fail ; + if (!stralloc_0(&d.new)) goto fail ; + if (mkdir(d.new.s, mode) < 0) goto fail ; + d.fd = open_read(d.new.s) ; + if (d.fd < 0) + { + register int e = errno ; + rmdir(d.new.s) ; + errno = e ; + goto fail ; + } + *dd = d ; + return 1 ; + + fail: + stralloc_free(&d.new) ; + return 0 ; +} diff --git a/src/libunixonacid/kolbak_call.c b/src/libunixonacid/kolbak_call.c new file mode 100644 index 0000000..b7b97c0 --- /dev/null +++ b/src/libunixonacid/kolbak_call.c @@ -0,0 +1,13 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/unixmessage.h> +#include <skalibs/kolbak.h> + +int kolbak_call (unixmessage_t const *m, kolbak_queue_t *q) +{ + if (q->head == q->tail) return (errno = EILSEQ, 0) ; + if (!(*q->x[q->head].f)(m, q->x[q->head].data)) return 0 ; + q->head = (q->head + 1) % q->n ; + return 1 ; +} diff --git a/src/libunixonacid/kolbak_enqueue.c b/src/libunixonacid/kolbak_enqueue.c new file mode 100644 index 0000000..80fce01 --- /dev/null +++ b/src/libunixonacid/kolbak_enqueue.c @@ -0,0 +1,15 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/kolbak.h> +#include <skalibs/unixmessage.h> + +int kolbak_enqueue (kolbak_queue_t *q, unixmessage_handler_func_t *f, void *data) +{ + register unsigned int newtail = (q->tail + 1) % q->n ; + if (newtail == q->head) return (errno = ENOBUFS, 0) ; + q->x[q->tail].f = f ; + q->x[q->tail].data = data ; + q->tail = newtail ; + return 1 ; +} diff --git a/src/libunixonacid/kolbak_queue_init.c b/src/libunixonacid/kolbak_queue_init.c new file mode 100644 index 0000000..6d91232 --- /dev/null +++ b/src/libunixonacid/kolbak_queue_init.c @@ -0,0 +1,14 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/kolbak.h> + +int kolbak_queue_init (kolbak_queue_t *q, kolbak_closure_t *s, unsigned int len) +{ + if (len < 2) return (errno = EINVAL, 0) ; + q->x = s ; + q->n = len ; + q->head = 0 ; + q->tail = 0 ; + return 1 ; +} diff --git a/src/libunixonacid/kolbak_unenqueue.c b/src/libunixonacid/kolbak_unenqueue.c new file mode 100644 index 0000000..894beea --- /dev/null +++ b/src/libunixonacid/kolbak_unenqueue.c @@ -0,0 +1,11 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/kolbak.h> + +int kolbak_unenqueue (kolbak_queue_t *q) +{ + if (q->head == q->tail) return (errno = EINVAL, 0) ; + q->tail = (q->tail + q->n - 1) % q->n ; + return 1 ; +} diff --git a/src/libunixonacid/mkdir_unique.c b/src/libunixonacid/mkdir_unique.c new file mode 100644 index 0000000..523ecef --- /dev/null +++ b/src/libunixonacid/mkdir_unique.c @@ -0,0 +1,24 @@ +/* ISC license. */ + +#include <sys/stat.h> +#include <skalibs/stralloc.h> +#include <skalibs/random.h> +#include <skalibs/unix-transactional.h> + +int mkdir_unique (stralloc *sa, char const *fn, unsigned int mode) +{ + unsigned int base = sa->len ; + int wasnull = !sa->s ; + if (!stralloc_cats(sa, fn)) return 0 ; + if (!stralloc_cats(sa, "/mkdir_unique")) goto fail ; + if (random_sauniquename(sa, 8) < 0) goto fail ; + if (!stralloc_0(sa)) goto fail ; + if (mkdir(sa->s + base, mode) < 0) goto fail ; + sa->len-- ; + return 1 ; + + fail: + if (wasnull) stralloc_free(sa) ; + else sa->len = base ; + return 0 ; +} diff --git a/src/libunixonacid/netstring_timed_get.c b/src/libunixonacid/netstring_timed_get.c new file mode 100644 index 0000000..04ace6c --- /dev/null +++ b/src/libunixonacid/netstring_timed_get.c @@ -0,0 +1,24 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/buffer.h> +#include <skalibs/stralloc.h> +#include <skalibs/netstring.h> +#include <skalibs/tai.h> +#include <skalibs/iopause.h> +#include <skalibs/unix-timed.h> + +int netstring_timed_get (buffer *b, stralloc *sa, tain_t const *deadline, tain_t *stamp) +{ + iopause_fd x = { .fd = buffer_fd(b), .events = IOPAUSE_READ } ; + unsigned int w = 0 ; + for (;;) + { + register int r = netstring_get(b, sa, &w) ; + if (r > 0) return r ; + if (r < 0) return 0 ; + r = iopause_stamp(&x, 1, deadline, stamp) ; + if (r < 0) return 0 ; + else if (!r) return (errno = ETIMEDOUT, 0) ; + } +} diff --git a/src/libunixonacid/open2_at.c b/src/libunixonacid/open2_at.c new file mode 100644 index 0000000..4deb837 --- /dev/null +++ b/src/libunixonacid/open2_at.c @@ -0,0 +1,60 @@ +/* ISC license. */ + +#include <skalibs/sysdeps.h> + +#ifdef SKALIBS_HASOPENAT + +#ifndef _ATFILE_SOURCE +#define _ATFILE_SOURCE +#endif + +#include <skalibs/nonposix.h> +#include <fcntl.h> +#include <skalibs/unix-transactional.h> + +int open2_at (int dirfd, char const *file, int flags) +{ + return openat(dirfd, file, flags) ; +} + +#else + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <errno.h> +#include <skalibs/djbunix.h> +#include <skalibs/unix-transactional.h> + +int open2_at (int dirfd, char const *file, int flags) +{ + int fd ; + int fdhere = open_read(".") ; + if (fdhere < 0) return -1 ; + if (fd_chdir(dirfd) < 0) + { + register int e = errno ; + fd_close(fdhere) ; + errno = e ; + return -1 ; + } + fd = open2(file, flags) ; + if (fd < 0) + { + register int e = errno ; + fd_chdir(fdhere) ; + fd_close(fdhere) ; + errno = e ; + return -1 ; + } + if (fd_chdir(fdhere) < 0) + { + register int e = errno ; + fd_close(fdhere) ; + errno = e ; + return -1 ; + } + return fd ; +} + +#endif diff --git a/src/libunixonacid/open3_at.c b/src/libunixonacid/open3_at.c new file mode 100644 index 0000000..d9c7222 --- /dev/null +++ b/src/libunixonacid/open3_at.c @@ -0,0 +1,60 @@ +/* ISC license. */ + +#include <skalibs/sysdeps.h> + +#ifdef SKALIBS_HASOPENAT + +#ifndef _ATFILE_SOURCE +#define _ATFILE_SOURCE +#endif + +#include <skalibs/nonposix.h> +#include <fcntl.h> +#include <skalibs/unix-transactional.h> + +int open3_at (int dirfd, char const *file, int flags, unsigned int mode) +{ + return openat(dirfd, file, flags, mode) ; +} + +#else + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <errno.h> +#include <skalibs/djbunix.h> +#include <skalibs/unix-transactional.h> + +int open3_at (int dirfd, char const *file, int flags, unsigned int mode) +{ + int fd ; + int fdhere = open_read(".") ; + if (fdhere < 0) return -1 ; + if (fd_chdir(dirfd) < 0) + { + register int e = errno ; + fd_close(fdhere) ; + errno = e ; + return -1 ; + } + fd = open3(file, flags, mode) ; + if (fd < 0) + { + register int e = errno ; + fd_chdir(fdhere) ; + fd_close(fdhere) ; + errno = e ; + return -1 ; + } + if (fd_chdir(fdhere) < 0) + { + register int e = errno ; + fd_close(fdhere) ; + errno = e ; + return -1 ; + } + return fd ; +} + +#endif diff --git a/src/libunixonacid/open_appendat.c b/src/libunixonacid/open_appendat.c new file mode 100644 index 0000000..debfe8a --- /dev/null +++ b/src/libunixonacid/open_appendat.c @@ -0,0 +1,11 @@ +/* ISC license. */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <skalibs/unix-transactional.h> + +int open_appendat (int fd, char const *name) +{ + return open3_at(fd, name, O_WRONLY | O_NONBLOCK | O_APPEND | O_CREAT, 0666) ; +} diff --git a/src/libunixonacid/open_appendatb.c b/src/libunixonacid/open_appendatb.c new file mode 100644 index 0000000..5a75120 --- /dev/null +++ b/src/libunixonacid/open_appendatb.c @@ -0,0 +1,12 @@ +/* ISC license. */ + +#include <skalibs/djbunix.h> +#include <skalibs/unix-transactional.h> + +int open_appendatb (int dirfd, char const *name) +{ + int fd = open_appendat(dirfd, name) ; + if (fd < 0) return -1 ; + if (ndelay_off(fd) < 0) return -1 ; + return fd ; +} diff --git a/src/libunixonacid/open_readat.c b/src/libunixonacid/open_readat.c new file mode 100644 index 0000000..7764ffc --- /dev/null +++ b/src/libunixonacid/open_readat.c @@ -0,0 +1,10 @@ +/* ISC license. */ + +#include <sys/types.h> +#include <fcntl.h> +#include <skalibs/unix-transactional.h> + +int open_readat (int fd, char const *name) +{ + return open2_at(fd, name, O_RDONLY | O_NONBLOCK) ; +} diff --git a/src/libunixonacid/open_readatb.c b/src/libunixonacid/open_readatb.c new file mode 100644 index 0000000..6e4cd0f --- /dev/null +++ b/src/libunixonacid/open_readatb.c @@ -0,0 +1,12 @@ +/* ISC license. */ + +#include <skalibs/djbunix.h> +#include <skalibs/unix-transactional.h> + +int open_readatb (int dirfd, char const *name) +{ + int fd = open_readat(dirfd, name) ; + if (fd < 0) return -1 ; + if (ndelay_off(fd) < 0) return -1 ; + return fd ; +} diff --git a/src/libunixonacid/open_truncat.c b/src/libunixonacid/open_truncat.c new file mode 100644 index 0000000..2a868d2 --- /dev/null +++ b/src/libunixonacid/open_truncat.c @@ -0,0 +1,10 @@ +/* ISC license. */ + +#include <sys/types.h> +#include <fcntl.h> +#include <skalibs/unix-transactional.h> + +int open_truncat (int fd, char const *name) +{ + return open3_at(fd, name, O_WRONLY | O_NONBLOCK | O_TRUNC | O_CREAT, 0666) ; +} diff --git a/src/libunixonacid/open_truncatb.c b/src/libunixonacid/open_truncatb.c new file mode 100644 index 0000000..fc4d685 --- /dev/null +++ b/src/libunixonacid/open_truncatb.c @@ -0,0 +1,12 @@ +/* ISC license. */ + +#include <skalibs/djbunix.h> +#include <skalibs/unix-transactional.h> + +int open_truncatb (int dirfd, char const *name) +{ + int fd = open_truncat(dirfd, name) ; + if (fd < 0) return -1 ; + if (ndelay_off(fd) < 0) return -1 ; + return fd ; +} diff --git a/src/libunixonacid/open_writeat.c b/src/libunixonacid/open_writeat.c new file mode 100644 index 0000000..6b1a173 --- /dev/null +++ b/src/libunixonacid/open_writeat.c @@ -0,0 +1,10 @@ +/* ISC license. */ + +#include <sys/types.h> +#include <fcntl.h> +#include <skalibs/unix-transactional.h> + +int open_writeat (int fd, char const *name) +{ + return open2_at(fd, name, O_WRONLY | O_NONBLOCK) ; +} diff --git a/src/libunixonacid/open_writeatb.c b/src/libunixonacid/open_writeatb.c new file mode 100644 index 0000000..fd75365 --- /dev/null +++ b/src/libunixonacid/open_writeatb.c @@ -0,0 +1,12 @@ +/* ISC license. */ + +#include <skalibs/djbunix.h> +#include <skalibs/unix-transactional.h> + +int open_writeatb (int dirfd, char const *name) +{ + int fd = open_writeat(dirfd, name) ; + if (fd < 0) return -1 ; + if (ndelay_off(fd) < 0) return -1 ; + return fd ; +} diff --git a/src/libunixonacid/opengetlnclose.c b/src/libunixonacid/opengetlnclose.c new file mode 100644 index 0000000..ca1959e --- /dev/null +++ b/src/libunixonacid/opengetlnclose.c @@ -0,0 +1,24 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/buffer.h> +#include <skalibs/stralloc.h> +#include <skalibs/djbunix.h> +#include <skalibs/skamisc.h> +#include <skalibs/unix-transactional.h> + +int opengetlnclose (char const *fn, stralloc *sa, int sep) +{ + char buf[BUFFER_INSIZE] ; + buffer b ; + register int r ; + register int e ; + int fd = open_readb(fn) ; + if (fd < 0) return -1 ; + buffer_init(&b, &buffer_read, fd, buf, BUFFER_INSIZE) ; + r = skagetln(&b, sa, sep) ; + e = errno ; + fd_close(fd) ; + errno = e ; + return r ; +} diff --git a/src/libunixonacid/opengetlnclose_at.c b/src/libunixonacid/opengetlnclose_at.c new file mode 100644 index 0000000..be2ffaf --- /dev/null +++ b/src/libunixonacid/opengetlnclose_at.c @@ -0,0 +1,24 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/buffer.h> +#include <skalibs/stralloc.h> +#include <skalibs/djbunix.h> +#include <skalibs/skamisc.h> +#include <skalibs/unix-transactional.h> + +int opengetlnclose_at (int dirfd, char const *fn, stralloc *sa, int sep) +{ + char buf[BUFFER_INSIZE] ; + buffer b ; + register int r ; + register int e ; + int fd = open_readatb(dirfd, fn) ; + if (fd < 0) return -1 ; + buffer_init(&b, &buffer_read, fd, buf, BUFFER_INSIZE) ; + r = skagetln(&b, sa, sep) ; + e = errno ; + fd_close(fd) ; + errno = e ; + return r ; +} diff --git a/src/libunixonacid/openreadnclose_at.c b/src/libunixonacid/openreadnclose_at.c new file mode 100644 index 0000000..4e8209d --- /dev/null +++ b/src/libunixonacid/openreadnclose_at.c @@ -0,0 +1,19 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/allreadwrite.h> +#include <skalibs/djbunix.h> +#include <skalibs/unix-transactional.h> + +unsigned int openreadnclose_at (int dirfd, char const *file, char *s, unsigned int n) +{ + register unsigned int r ; + register int e ; + int fd = open_readatb(dirfd, file) ; + if (fd < 0) return 0 ; + r = allread(fd, s, n) ; + e = errno ; + fd_close(fd) ; + errno = e ; + return r ; +} diff --git a/src/libunixonacid/openslurpclose_at.c b/src/libunixonacid/openslurpclose_at.c new file mode 100644 index 0000000..cf2f8ee --- /dev/null +++ b/src/libunixonacid/openslurpclose_at.c @@ -0,0 +1,21 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/stralloc.h> +#include <skalibs/djbunix.h> +#include <skalibs/unix-transactional.h> + +int openslurpclose_at (int dirfd, char const *fn, stralloc *sa) +{ + int fd = open_readatb(dirfd, fn) ; + if (fd < 0) return 0 ; + if (!slurp(sa, fd)) + { + register int e = errno ; + fd_close(fd) ; + errno = e ; + return 0 ; + } + fd_close(fd) ; + return 1 ; +} diff --git a/src/libunixonacid/openwritenclose.c b/src/libunixonacid/openwritenclose.c new file mode 100644 index 0000000..09149e2 --- /dev/null +++ b/src/libunixonacid/openwritenclose.c @@ -0,0 +1,11 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include <skalibs/skamisc.h> +#include <skalibs/unix-transactional.h> + +int openwritenclose (char const *fn, char const *s, unsigned int len) +{ + return openwritenclose_tmp(fn, s, len, &satmp) ; +} diff --git a/src/libunixonacid/openwritenclose_at.c b/src/libunixonacid/openwritenclose_at.c new file mode 100644 index 0000000..fe92a5e --- /dev/null +++ b/src/libunixonacid/openwritenclose_at.c @@ -0,0 +1,24 @@ +/* ISC license. */ + +#include <unistd.h> +#include <errno.h> +#include <skalibs/allreadwrite.h> +#include <skalibs/djbunix.h> +#include <skalibs/unix-transactional.h> + +unsigned int openwritenclose_at (int dirfd, char const *file, char const *s, unsigned int n) +{ + register unsigned int r ; + int fd = open_truncatb(dirfd, file) ; + if (fd < 0) return 0 ; + r = allwrite(fd, s, n) ; + if ((r < n) || (fsync(fd) < 0)) + { + register int e = errno ; + fd_close(fd) ; + errno = e ; + return r ; + } + fd_close(fd) ; + return r ; +} diff --git a/src/libunixonacid/openwritenclose_devino.c b/src/libunixonacid/openwritenclose_devino.c new file mode 100644 index 0000000..5edc646 --- /dev/null +++ b/src/libunixonacid/openwritenclose_devino.c @@ -0,0 +1,12 @@ +/* ISC license. */ + +/* MT-unsafe */ + +#include <skalibs/uint64.h> +#include <skalibs/skamisc.h> +#include <skalibs/unix-transactional.h> + +int openwritenclose_devino (char const *fn, char const *s, unsigned int len, uint64 *dev, uint64 *ino) +{ + return openwritenclose_devino_tmp(fn, s, len, dev, ino, &satmp) ; +} diff --git a/src/libunixonacid/openwritenclose_devino_tmp.c b/src/libunixonacid/openwritenclose_devino_tmp.c new file mode 100644 index 0000000..343da65 --- /dev/null +++ b/src/libunixonacid/openwritenclose_devino_tmp.c @@ -0,0 +1,35 @@ +/* ISC license. */ + +#include <errno.h> +#include <unistd.h> +#include <stdio.h> /* for rename() */ +#include <skalibs/uint64.h> +#include <skalibs/stralloc.h> +#include <skalibs/djbunix.h> +#include <skalibs/random.h> +#include <skalibs/unix-transactional.h> + +int openwritenclose_devino_tmp (char const *fn, char const *s, unsigned int len, uint64 *dev, uint64 *ino, stralloc *tmp) +{ + uint64 tmpdev, tmpino ; + unsigned int base = tmp->len ; + if (!stralloc_cats(tmp, fn)) return 0 ; + if (random_sauniquename(tmp, 8) < 0) goto fail ; + if (!stralloc_0(tmp)) goto fail ; + if (!openwritenclose_unsafe_devino_sync(tmp->s + base, s, len, &tmpdev, &tmpino)) goto fail ; + if (rename(tmp->s + base, fn) < 0) + { + register int e = errno ; + unlink(tmp->s + base) ; + errno = e ; + goto fail ; + } + tmp->len = base ; + *dev = tmpdev ; + *ino = tmpino ; + return 1 ; + + fail: + tmp->len = base ; + return 0 ; +} diff --git a/src/libunixonacid/openwritenclose_tmp.c b/src/libunixonacid/openwritenclose_tmp.c new file mode 100644 index 0000000..1ada80b --- /dev/null +++ b/src/libunixonacid/openwritenclose_tmp.c @@ -0,0 +1,11 @@ +/* ISC license. */ + +#include <skalibs/uint64.h> +#include <skalibs/stralloc.h> +#include <skalibs/unix-transactional.h> + +int openwritenclose_tmp (char const *fn, char const *s, unsigned int len, stralloc *tmp) +{ + uint64 dev, ino ; + return openwritenclose_devino_tmp(fn, s, len, &dev, &ino, tmp) ; +} diff --git a/src/libunixonacid/skaclient-internal.h b/src/libunixonacid/skaclient-internal.h new file mode 100644 index 0000000..f0a9bfe --- /dev/null +++ b/src/libunixonacid/skaclient-internal.h @@ -0,0 +1,15 @@ +/* ISC license. */ + +#ifndef SKACLIENT_INTERNAL_H +#define SKACLIENT_INTERNAL_H + +#include <skalibs/kolbak.h> +#include <skalibs/skaclient.h> +#include <skalibs/unixmessage.h> + +extern int skaclient_init (skaclient_t *, int, char *, unsigned int, char *, unsigned int, char *, unsigned int, char *, unsigned int, kolbak_closure_t *, unsigned int, char const *, unsigned int) ; +extern int skaclient_start_async_th (skaclient_t *, char *, unsigned int, char *, unsigned int, char *, unsigned int, char *, unsigned int, kolbak_closure_t *, unsigned int, char const *, char const *, unsigned int) ; +extern int skaclient_startf_async_th (skaclient_t *, char *, unsigned int, char *, unsigned int, char *, unsigned int, char *, unsigned int, kolbak_closure_t *, unsigned int, char const *, char const *const *, char const *const *, uint32, char const *, unsigned int) ; +extern int skaclient_start_cb (unixmessage_t const *, skaclient_cbdata_t *) ; + +#endif diff --git a/src/libunixonacid/skaclient_default_cb.c b/src/libunixonacid/skaclient_default_cb.c new file mode 100644 index 0000000..10934e5 --- /dev/null +++ b/src/libunixonacid/skaclient_default_cb.c @@ -0,0 +1,14 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/error.h> +#include <skalibs/skaclient.h> +#include <skalibs/unixmessage.h> + +int skaclient_default_cb (unixmessage_t const *m, void *p) +{ + unsigned char *err = p ; + if (m->len != 1 || m->nfds) return (errno = EPROTO, 0) ; + *err = m->s[0] ; + return 1 ; +} diff --git a/src/libunixonacid/skaclient_end.c b/src/libunixonacid/skaclient_end.c new file mode 100644 index 0000000..23dafab --- /dev/null +++ b/src/libunixonacid/skaclient_end.c @@ -0,0 +1,21 @@ +/* ISC license. */ + +#include <skalibs/djbunix.h> +#include <skalibs/skaclient.h> +#include <skalibs/unixmessage.h> + +void skaclient_end (skaclient_t *a) +{ + fd_close(a->syncout.fd) ; + fd_close(a->asyncout.fd) ; + unixmessage_sender_free(&a->syncout) ; + unixmessage_sender_free(&a->asyncout) ; + unixmessage_receiver_free(&a->syncin) ; + unixmessage_receiver_free(&a->asyncin) ; + if (a->pid && a->options & SKACLIENT_OPTION_WAITPID) + { + int wstat ; + waitpid_nointr(a->pid, &wstat, 0) ; + } + *a = skaclient_zero ; +} diff --git a/src/libunixonacid/skaclient_init.c b/src/libunixonacid/skaclient_init.c new file mode 100644 index 0000000..89ed59c --- /dev/null +++ b/src/libunixonacid/skaclient_init.c @@ -0,0 +1,32 @@ +/* ISC license. */ + +#include <skalibs/kolbak.h> +#include <skalibs/skaclient.h> +#include <skalibs/unixmessage.h> +#include "skaclient-internal.h" + +int skaclient_init ( + skaclient_t *a, + int fd, + char *bufss, + unsigned int bufsn, + char *auxbufss, + unsigned int auxbufsn, + char *bufas, + unsigned int bufan, + char *auxbufas, + unsigned int auxbufan, + kolbak_closure_t *q, + unsigned int qlen, + char const *before, + unsigned int beforelen) +{ + unixmessage_t msg = { .s = (char *)before, .len = beforelen, .fds = 0, .nfds = 0 } ; + if (!unixmessage_receiver_init(&a->syncin, fd, bufss, bufsn, auxbufss, auxbufsn) + || !unixmessage_receiver_init(&a->asyncin, -1, bufas, bufan, auxbufas, auxbufan) + || !kolbak_queue_init(&a->kq, q, qlen)) return 0 ; + unixmessage_sender_init(&a->syncout, fd) ; + unixmessage_sender_init(&a->asyncout, -1) ; + if (!unixmessage_put(&a->syncout, &msg)) return 0 ; + return 1 ; +} diff --git a/src/libunixonacid/skaclient_put.c b/src/libunixonacid/skaclient_put.c new file mode 100644 index 0000000..5e3dc92 --- /dev/null +++ b/src/libunixonacid/skaclient_put.c @@ -0,0 +1,10 @@ +/* ISC license. */ + +#include <skalibs/skaclient.h> +#include <skalibs/unixmessage.h> + +int skaclient_put (skaclient_t *a, char const *s, unsigned int len, unixmessage_handler_func_t *cb, void *result) +{ + unixmessage_t m = { .s = (char *)s, .len = len, .fds = 0, .nfds = 0 } ; + return skaclient_putmsg(a, &m, cb, result) ; +} diff --git a/src/libunixonacid/skaclient_putmsg.c b/src/libunixonacid/skaclient_putmsg.c new file mode 100644 index 0000000..9dcb37d --- /dev/null +++ b/src/libunixonacid/skaclient_putmsg.c @@ -0,0 +1,16 @@ +/* ISC license. */ + +#include <skalibs/kolbak.h> +#include <skalibs/skaclient.h> +#include <skalibs/unixmessage.h> + +int skaclient_putmsg_and_close (skaclient_t *a, unixmessage_t const *m, unsigned char const *bits, unixmessage_handler_func_t *cb, void *result) +{ + if (!kolbak_enqueue(&a->kq, cb, result)) return 0 ; + if (!unixmessage_put_and_close(&a->syncout, m, bits)) + { + kolbak_unenqueue(&a->kq) ; + return 0 ; + } + return 1 ; +} diff --git a/src/libunixonacid/skaclient_putmsgv.c b/src/libunixonacid/skaclient_putmsgv.c new file mode 100644 index 0000000..e53935a --- /dev/null +++ b/src/libunixonacid/skaclient_putmsgv.c @@ -0,0 +1,16 @@ +/* ISC license. */ + +#include <skalibs/kolbak.h> +#include <skalibs/skaclient.h> +#include <skalibs/unixmessage.h> + +int skaclient_putmsgv_and_close (skaclient_t *a, unixmessage_v_t const *m, unsigned char const *bits, unixmessage_handler_func_t *cb, void *result) +{ + if (!kolbak_enqueue(&a->kq, cb, result)) return 0 ; + if (!unixmessage_putv_and_close(&a->syncout, m, bits)) + { + kolbak_unenqueue(&a->kq) ; + return 0 ; + } + return 1 ; +} diff --git a/src/libunixonacid/skaclient_putv.c b/src/libunixonacid/skaclient_putv.c new file mode 100644 index 0000000..c41b092 --- /dev/null +++ b/src/libunixonacid/skaclient_putv.c @@ -0,0 +1,11 @@ +/* ISC license. */ + +#include <skalibs/siovec.h> +#include <skalibs/skaclient.h> +#include <skalibs/unixmessage.h> + +int skaclient_putv (skaclient_t *a, siovec_t const *v, unsigned int vlen, unixmessage_handler_func_t *cb, void *result) +{ + unixmessage_v_t m = { .v = (siovec_t *)v, .vlen = vlen, .fds = 0, .nfds = 0 } ; + return skaclient_putmsgv(a, &m, cb, result) ; +} diff --git a/src/libunixonacid/skaclient_send.c b/src/libunixonacid/skaclient_send.c new file mode 100644 index 0000000..8bd31ab --- /dev/null +++ b/src/libunixonacid/skaclient_send.c @@ -0,0 +1,11 @@ +/* ISC license. */ + +#include <skalibs/skaclient.h> +#include <skalibs/tai.h> +#include <skalibs/unixmessage.h> + +int skaclient_send (skaclient_t *a, char const *s, unsigned int len, unixmessage_handler_func_t *cb, void *result, tain_t const *deadline, tain_t *stamp) +{ + unixmessage_t m = { .s = (char *)s, .len = len, .fds = 0, .nfds = 0 } ; + return skaclient_sendmsg(a, &m, cb, result, deadline, stamp) ; +} diff --git a/src/libunixonacid/skaclient_sendmsg.c b/src/libunixonacid/skaclient_sendmsg.c new file mode 100644 index 0000000..3f88ec7 --- /dev/null +++ b/src/libunixonacid/skaclient_sendmsg.c @@ -0,0 +1,15 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/skaclient.h> +#include <skalibs/tai.h> +#include <skalibs/unixmessage.h> + +int skaclient_sendmsg_and_close (skaclient_t *a, unixmessage_t const *m, unsigned char const *bits, unixmessage_handler_func_t *cb, void *result, tain_t const *deadline, tain_t *stamp) +{ + register int r ; + if (!skaclient_putmsg_and_close(a, m, bits, cb, result)) return 0 ; + if (!skaclient_timed_flush(a, deadline, stamp)) return 0 ; + r = skaclient_timed_supdate(a, deadline, stamp) ; + return r < 0 ? 0 : !r ? (errno = EPIPE, 0) : 1 ; +} diff --git a/src/libunixonacid/skaclient_sendmsgv.c b/src/libunixonacid/skaclient_sendmsgv.c new file mode 100644 index 0000000..ac4bcdb --- /dev/null +++ b/src/libunixonacid/skaclient_sendmsgv.c @@ -0,0 +1,15 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/skaclient.h> +#include <skalibs/tai.h> +#include <skalibs/unixmessage.h> + +int skaclient_sendmsgv_and_close (skaclient_t *a, unixmessage_v_t const *m, unsigned char const *bits, unixmessage_handler_func_t *cb, void *result, tain_t const *deadline, tain_t *stamp) +{ + register int r ; + if (!skaclient_putmsgv_and_close(a, m, bits, cb, result)) return 0 ; + if (!skaclient_timed_flush(a, deadline, stamp)) return 0 ; + r = skaclient_timed_supdate(a, deadline, stamp) ; + return r < 0 ? 0 : !r ? (errno = EPIPE, 0) : 1 ; +} diff --git a/src/libunixonacid/skaclient_sendv.c b/src/libunixonacid/skaclient_sendv.c new file mode 100644 index 0000000..a140768 --- /dev/null +++ b/src/libunixonacid/skaclient_sendv.c @@ -0,0 +1,12 @@ +/* ISC license. */ + +#include <skalibs/siovec.h> +#include <skalibs/skaclient.h> +#include <skalibs/tai.h> +#include <skalibs/unixmessage.h> + +int skaclient_sendv (skaclient_t *a, siovec_t const *v, unsigned int vlen, unixmessage_handler_func_t *cb, void *result, tain_t const *deadline, tain_t *stamp) +{ + unixmessage_v_t m = { .v = (siovec_t *)v, .vlen = vlen, .fds = 0, .nfds = 0 } ; + return skaclient_sendmsgv(a, &m, cb, result, deadline, stamp) ; +} diff --git a/src/libunixonacid/skaclient_server_ack.c b/src/libunixonacid/skaclient_server_ack.c new file mode 100644 index 0000000..31ee9fe --- /dev/null +++ b/src/libunixonacid/skaclient_server_ack.c @@ -0,0 +1,30 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/bytestr.h> +#include <skalibs/djbunix.h> +#include <skalibs/error.h> +#include <skalibs/skaclient.h> +#include <skalibs/unixmessage.h> +#include <skalibs/webipc.h> + +int skaclient_server_ack (unixmessage_t const *clientmsg, unixmessage_sender_t *out, unixmessage_sender_t *asyncout, char const *before, unsigned int beforelen, char const *after, unsigned int afterlen) +{ + int fd[2] ; + unixmessage_t m = { .s = (char *)after, .len = afterlen, .fds = fd, .nfds = 1 } ; + static unsigned char const bits = 0xff ; + if (clientmsg->nfds + || clientmsg->len != beforelen + || byte_diff(clientmsg->s, beforelen, before)) return (errno = EPROTO, 0) ; + if (ipc_pair_nbcoe(fd) < 0) return 0 ; + unixmessage_sender_init(asyncout, fd[1]) ; + if (!unixmessage_put_and_close(out, &m, &bits)) + { + int e = errno ; + fd_close(fd[1]) ; + fd_close(fd[0]) ; + errno = e ; + return 0 ; + } + return 1 ; +} diff --git a/src/libunixonacid/skaclient_server_bidi_ack.c b/src/libunixonacid/skaclient_server_bidi_ack.c new file mode 100644 index 0000000..eede82c --- /dev/null +++ b/src/libunixonacid/skaclient_server_bidi_ack.c @@ -0,0 +1,12 @@ +/* ISC license. */ + +#include <skalibs/skaclient.h> +#include <skalibs/unixmessage.h> + +int skaclient_server_bidi_ack (unixmessage_t const *clientmsg, unixmessage_sender_t *out, unixmessage_sender_t *asyncout, unixmessage_receiver_t *asyncin, char *mainbuf, unsigned int mainlen, char *auxbuf, unsigned int auxlen, char const *before, unsigned int beforelen, char const *after, unsigned int afterlen) +{ + if (!unixmessage_receiver_init(asyncin, -1, mainbuf, mainlen, auxbuf, auxlen)) return 0 ; + if (!skaclient_server_ack(clientmsg, out, asyncout, before, beforelen, after, afterlen)) return 0 ; + asyncin->mainb.fd = unixmessage_sender_fd(asyncout) ; + return 1 ; +} diff --git a/src/libunixonacid/skaclient_server_init.c b/src/libunixonacid/skaclient_server_init.c new file mode 100644 index 0000000..bd7c143 --- /dev/null +++ b/src/libunixonacid/skaclient_server_init.c @@ -0,0 +1,15 @@ +/* ISC license. */ + +#include <skalibs/skaclient.h> +#include <skalibs/tai.h> +#include <skalibs/unixmessage.h> + +int skaclient_server_init (unixmessage_receiver_t *in, char *mainbuf, unsigned int mainlen, char *auxbuf, unsigned int auxlen, unixmessage_sender_t *out, unixmessage_sender_t *asyncout, char const *before, unsigned int beforelen, char const *after, unsigned int afterlen, tain_t const *deadline, tain_t *stamp) +{ + unixmessage_t m ; + if (!unixmessage_receiver_init(in, 0, mainbuf, mainlen, auxbuf, auxlen)) return 0 ; + unixmessage_sender_init(out, 1) ; + if (unixmessage_timed_receive(in, &m, deadline, stamp) < 0) return 0 ; + if (!skaclient_server_ack(&m, out, asyncout, before, beforelen, after, afterlen)) return 0 ; + return unixmessage_sender_timed_flush(out, deadline, stamp) ; +} diff --git a/src/libunixonacid/skaclient_start.c b/src/libunixonacid/skaclient_start.c new file mode 100644 index 0000000..b17750b --- /dev/null +++ b/src/libunixonacid/skaclient_start.c @@ -0,0 +1,43 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/kolbak.h> +#include <skalibs/skaclient.h> +#include <skalibs/tai.h> +#include "skaclient-internal.h" + +int skaclient_start ( + skaclient_t *a, + char *bufss, + unsigned int bufsn, + char *auxbufss, + unsigned int auxbufsn, + char *bufas, + unsigned int bufan, + char *auxbufas, + unsigned int auxbufan, + kolbak_closure_t *q, + unsigned int qlen, + char const *path, + char const *before, + unsigned int beforelen, + char const *after, + unsigned int afterlen, + tain_t const *deadline, + tain_t *stamp) +{ + skaclient_cbdata_t blah ; + unixmessage_t m ; + register int r ; + if (!skaclient_start_async(a, bufss, bufsn, auxbufss, auxbufsn, bufas, bufan, auxbufas, auxbufan, q, qlen, path, before, beforelen, after, afterlen, &blah)) return 0 ; + r = unixmessage_timed_receive(&a->syncin, &m, deadline, stamp) ; + if (r < 1) + { + int e = errno ; + if (!r) e = EPIPE ; + skaclient_end(a) ; + errno = e ; + return 0 ; + } + return kolbak_call(&m, &a->kq) ; +} diff --git a/src/libunixonacid/skaclient_start_async.c b/src/libunixonacid/skaclient_start_async.c new file mode 100644 index 0000000..4dbbf1c --- /dev/null +++ b/src/libunixonacid/skaclient_start_async.c @@ -0,0 +1,52 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/error.h> +#include <skalibs/kolbak.h> +#include <skalibs/skaclient.h> +#include <skalibs/unixmessage.h> +#include <skalibs/webipc.h> +#include "skaclient-internal.h" + +int skaclient_start_async ( + skaclient_t *a, + char *bufss, + unsigned int bufsn, + char *auxbufss, + unsigned int auxbufsn, + char *bufas, + unsigned int bufan, + char *auxbufas, + unsigned int auxbufan, + kolbak_closure_t *q, + unsigned int qlen, + char const *path, + char const *before, + unsigned int beforelen, + char const *after, + unsigned int afterlen, + skaclient_cbdata_t *blah) +{ + int fd = ipc_stream_nbcoe() ; + if (fd < 0) return 0 ; + if ((!ipc_connect(fd, path) && !error_isalready(errno)) + || !skaclient_init(a, fd, bufss, bufsn, auxbufss, auxbufsn, bufas, bufan, auxbufas, auxbufan, q, qlen, before, beforelen)) + { + register int e = errno ; + fd_close(fd) ; + errno = e ; + return 0 ; + } + a->pid = 0 ; + a->options = 0 ; + if (!kolbak_enqueue(&a->kq, (unixmessage_handler_func_t_ref)&skaclient_start_cb, blah)) + { + skaclient_end(a) ; + return 0 ; + } + blah->asyncin = &a->asyncin ; + blah->asyncout = &a->asyncout ; + blah->after = after ; + blah->afterlen = afterlen ; + return 1 ; +} diff --git a/src/libunixonacid/skaclient_start_cb.c b/src/libunixonacid/skaclient_start_cb.c new file mode 100644 index 0000000..6e641e2 --- /dev/null +++ b/src/libunixonacid/skaclient_start_cb.c @@ -0,0 +1,18 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/bytestr.h> +#include <skalibs/error.h> +#include <skalibs/skaclient.h> +#include <skalibs/unixmessage.h> +#include "skaclient-internal.h" + +int skaclient_start_cb (unixmessage_t const *m, skaclient_cbdata_t *blah) +{ + if (m->len != blah->afterlen + || byte_diff(m->s, m->len, blah->after) + || m->nfds != 1) return (errno = EPROTO, 0) ; + blah->asyncin->mainb.fd = m->fds[0] ; + blah->asyncout->fd = m->fds[0] ; + return 1 ; +} diff --git a/src/libunixonacid/skaclient_startf.c b/src/libunixonacid/skaclient_startf.c new file mode 100644 index 0000000..aa36323 --- /dev/null +++ b/src/libunixonacid/skaclient_startf.c @@ -0,0 +1,46 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/kolbak.h> +#include <skalibs/skaclient.h> +#include <skalibs/tai.h> +#include "skaclient-internal.h" + +int skaclient_startf ( + skaclient_t *a, + char *bufss, + unsigned int bufsn, + char *auxbufss, + unsigned int auxbufsn, + char *bufas, + unsigned int bufan, + char *auxbufas, + unsigned int auxbufan, + kolbak_closure_t *q, + unsigned int qlen, + char const *prog, + char const *const *argv, + char const *const *envp, + uint32 options, + char const *before, + unsigned int beforelen, + char const *after, + unsigned int afterlen, + tain_t const *deadline, + tain_t *stamp) +{ + skaclient_cbdata_t blah ; + unixmessage_t m ; + register int r ; + if (!skaclient_startf_async(a, bufss, bufsn, auxbufss, auxbufsn, bufas, bufan, auxbufas, auxbufan, q, qlen, prog, argv, envp, options, before, beforelen, after, afterlen, &blah)) return 0 ; + r = unixmessage_timed_receive(&a->syncin, &m, deadline, stamp) ; + if (r < 1) + { + int e = errno ; + if (!r) e = EPIPE ; + skaclient_end(a) ; + errno = e ; + return 0 ; + } + return kolbak_call(&m, &a->kq) ; +} diff --git a/src/libunixonacid/skaclient_startf_async.c b/src/libunixonacid/skaclient_startf_async.c new file mode 100644 index 0000000..4077c1e --- /dev/null +++ b/src/libunixonacid/skaclient_startf_async.c @@ -0,0 +1,61 @@ +/* ISC license. */ + +#include <sys/types.h> +#include <errno.h> +#include <signal.h> +#include <skalibs/djbunix.h> +#include <skalibs/kolbak.h> +#include <skalibs/skaclient.h> +#include <skalibs/uint32.h> +#include "skaclient-internal.h" + +int skaclient_startf_async ( + skaclient_t *a, + char *bufss, + unsigned int bufsn, + char *auxbufss, + unsigned int auxbufsn, + char *bufas, + unsigned int bufan, + char *auxbufas, + unsigned int auxbufan, + kolbak_closure_t *q, + unsigned int qlen, + char const *prog, + char const *const *argv, + char const *const *envp, + uint32 options, + char const *before, + unsigned int beforelen, + char const *after, + unsigned int afterlen, + skaclient_cbdata_t *blah) +{ + int fd ; + pid_t pid = child_spawn(prog, argv, envp, &fd, 1) ; + if (!pid) return 0 ; + if (!skaclient_init(a, fd, bufss, bufsn, auxbufss, auxbufsn, bufas, bufan, auxbufas, auxbufan, q, qlen, before, beforelen)) + { + register int e = errno ; + fd_close(fd) ; + if (options & SKACLIENT_OPTION_WAITPID) + { + int wstat ; + waitpid_nointr(a->pid, &wstat, 0) ; + } + errno = e ; + return 0 ; + } + a->pid = pid ; + a->options = options ; + if (!kolbak_enqueue(&a->kq, (unixmessage_handler_func_t_ref)&skaclient_start_cb, blah)) + { + skaclient_end(a) ; + return 0 ; + } + blah->asyncin = &a->asyncin ; + blah->asyncout = &a->asyncout ; + blah->after = after ; + blah->afterlen = afterlen ; + return 1 ; +} diff --git a/src/libunixonacid/skaclient_zero.c b/src/libunixonacid/skaclient_zero.c new file mode 100644 index 0000000..4bb85b5 --- /dev/null +++ b/src/libunixonacid/skaclient_zero.c @@ -0,0 +1,5 @@ +/* ISC license. */ + +#include <skalibs/skaclient.h> + +skaclient_t const skaclient_zero = SKACLIENT_ZERO ; diff --git a/src/libunixonacid/timed_flush.c b/src/libunixonacid/timed_flush.c new file mode 100644 index 0000000..2d60256 --- /dev/null +++ b/src/libunixonacid/timed_flush.c @@ -0,0 +1,26 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/error.h> +#include <skalibs/bufalloc.h> +#include <skalibs/functypes.h> +#include <skalibs/iopause.h> +#include <skalibs/tai.h> +#include <skalibs/unix-timed.h> + +int timed_flush (void *b, initfunc_t_ref getfd, initfunc_t_ref isnonempty, initfunc_t_ref flush, tain_t const *deadline, tain_t *stamp) +{ + iopause_fd x = { .fd = (*getfd)(b), .events = IOPAUSE_WRITE, .revents = 0 } ; + while ((*isnonempty)(b)) + { + register int r = iopause_stamp(&x, 1, deadline, stamp) ; + if (r < 0) return 0 ; + else if (!r) return (errno = ETIMEDOUT, 0) ; + else if (x.revents & IOPAUSE_WRITE) + { + if (!((*flush)(b)) && !error_isagain(errno)) return 0 ; + } + else if (x.revents & IOPAUSE_EXCEPT) return (*flush)(b) ; + } + return 1 ; +} diff --git a/src/libunixonacid/timed_get.c b/src/libunixonacid/timed_get.c new file mode 100644 index 0000000..0a02382 --- /dev/null +++ b/src/libunixonacid/timed_get.c @@ -0,0 +1,22 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/allreadwrite.h> +#include <skalibs/functypes.h> +#include <skalibs/tai.h> +#include <skalibs/iopause.h> +#include <skalibs/unix-timed.h> + +int timed_get (void *b, initfunc_t *getfd, initfunc_t *get, tain_t const *deadline, tain_t *stamp) +{ + iopause_fd x = { .fd = (*getfd)(b), .events = IOPAUSE_READ, .revents = 0 } ; + register int r = (*get)(b) ; + while (!r) + { + r = iopause_stamp(&x, 1, deadline, stamp) ; + if (!r) return (errno = ETIMEDOUT, -1) ; + else if (r > 0 && x.revents & (IOPAUSE_READ | IOPAUSE_EXCEPT)) + r = (*get)(b) ; + } + return unsanitize_read(r) ; +} diff --git a/src/libunixonacid/timed_getln.c b/src/libunixonacid/timed_getln.c new file mode 100644 index 0000000..0c442de --- /dev/null +++ b/src/libunixonacid/timed_getln.c @@ -0,0 +1,32 @@ +/* ISC license. */ + +#include <skalibs/allreadwrite.h> +#include <skalibs/buffer.h> +#include <skalibs/functypes.h> +#include <skalibs/skamisc.h> +#include <skalibs/stralloc.h> +#include <skalibs/tai.h> +#include <skalibs/unix-timed.h> + +struct blah_s +{ + buffer *b ; + stralloc *sa ; + char sep ; +} ; + +static int getfd (struct blah_s *blah) +{ + return buffer_fd(blah->b) ; +} + +static int get (struct blah_s *blah) +{ + return sanitize_read(skagetln(blah->b, blah->sa, blah->sep)) ; +} + +int timed_getln (buffer *b, stralloc *sa, char sep, tain_t const *deadline, tain_t *stamp) +{ + struct blah_s blah = { .b = b, .sa = sa, .sep = sep } ; + return timed_get(&blah, (initfunc_t_ref)&getfd, (initfunc_t_ref)&get, deadline, stamp) ; +} diff --git a/src/libunixonacid/timed_getlnmax.c b/src/libunixonacid/timed_getlnmax.c new file mode 100644 index 0000000..8953606 --- /dev/null +++ b/src/libunixonacid/timed_getlnmax.c @@ -0,0 +1,33 @@ +/* ISC license. */ + +#include <skalibs/allreadwrite.h> +#include <skalibs/buffer.h> +#include <skalibs/functypes.h> +#include <skalibs/skamisc.h> +#include <skalibs/tai.h> +#include <skalibs/unix-timed.h> + +struct blah_s +{ + buffer *b ; + char *d ; + unsigned int max ; + unsigned int w ; + char sep ; +} ; + +static int getfd (struct blah_s *blah) +{ + return buffer_fd(blah->b) ; +} + +static int get (struct blah_s *blah) +{ + return sanitize_read(getlnmax(blah->b, blah->d, blah->max, &blah->w, blah->sep)) ; +} + +int timed_getlnmax (buffer *b, char *d, unsigned int max, unsigned int *w, char sep, tain_t const *deadline, tain_t *stamp) +{ + struct blah_s blah = { .b = b, .d = d, .max = max, .w = 0, .sep = sep } ; + return timed_get(&blah, (initfunc_t_ref)&getfd, (initfunc_t_ref)&get, deadline, stamp) ; +} diff --git a/src/libunixonacid/unixmessage_bits_closeall.c b/src/libunixonacid/unixmessage_bits_closeall.c new file mode 100644 index 0000000..a963809 --- /dev/null +++ b/src/libunixonacid/unixmessage_bits_closeall.c @@ -0,0 +1,7 @@ +/* ISC license. */ + +#include <skalibs/bitarray.h> +#include <skalibs/unixmessage.h> + +static unsigned char _unixmessage_bits_closeall[bitarray_div8(UNIXMESSAGE_MAXFDS)] = "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" ; +unsigned char const *const unixmessage_bits_closeall = _unixmessage_bits_closeall ; diff --git a/src/libunixonacid/unixmessage_bits_closenone.c b/src/libunixonacid/unixmessage_bits_closenone.c new file mode 100644 index 0000000..79412a5 --- /dev/null +++ b/src/libunixonacid/unixmessage_bits_closenone.c @@ -0,0 +1,7 @@ +/* ISC license. */ + +#include <skalibs/bitarray.h> +#include <skalibs/unixmessage.h> + +static unsigned char _unixmessage_bits_closenone[bitarray_div8(UNIXMESSAGE_MAXFDS)] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" ; +unsigned char const *const unixmessage_bits_closenone = _unixmessage_bits_closenone ; diff --git a/src/libunixonacid/unixmessage_handle.c b/src/libunixonacid/unixmessage_handle.c new file mode 100644 index 0000000..ad5789c --- /dev/null +++ b/src/libunixonacid/unixmessage_handle.c @@ -0,0 +1,19 @@ +/* ISC license. */ + +#include <skalibs/unixmessage.h> + +int unixmessage_handle (unixmessage_receiver_t *b, unixmessage_handler_func_t *f, void *p) +{ + unsigned int n = UNIXMESSAGE_MAXREADS ; + int count = 0 ; + while (n--) + { + unixmessage_t m ; + register int r = unixmessage_receive(b, &m) ; + if (r < 0) return -1 ; + if (!r) break ; + if (!(*f)(&m, p)) return -2 ; + count++ ; + } + return count ; +} diff --git a/src/libunixonacid/unixmessage_put.c b/src/libunixonacid/unixmessage_put.c new file mode 100644 index 0000000..f6db23b --- /dev/null +++ b/src/libunixonacid/unixmessage_put.c @@ -0,0 +1,83 @@ +/* ISC license. */ + +#include <skalibs/sysdeps.h> +#ifdef SKALIBS_HASANCILAUTOCLOSE +#include <unistd.h> +#endif +#include <errno.h> +#include <skalibs/bitarray.h> +#include <skalibs/bytestr.h> +#include <skalibs/diuint.h> +#include <skalibs/stralloc.h> +#include <skalibs/genalloc.h> +#include <skalibs/siovec.h> +#include <skalibs/unixmessage.h> + +static inline int copyfds (char *s, int const *fds, unsigned int n, unsigned char const *bits) +{ + register unsigned int i = 0 ; + for (; i < n ; i++) + { + int fd = fds[i] ; + if (fd < 0) return (errno = EINVAL, -1) ; + if (bitarray_peek(bits, i)) fd = - fd - 1 ; +#ifdef SKALIBS_HASANCILAUTOCLOSE + else + { + fd = dup(fd) ; + if (fd < 0) + { + int e = errno ; + while (i--) + { + s -= sizeof(int) ; + byte_copy((char *)fd, sizeof(int), s) ; + if (fd >= 0) fd_close(fd) ; + } + errno = e ; + return 0 ; + } + } +#else +#endif + byte_copy(s, sizeof(int), (char const *)&fd) ; + s += sizeof(int) ; + } + return 1 ; +} + +static int reserve_and_copy (unixmessage_sender_t *b, unsigned int len, int const *fds, unsigned int nfds, unsigned char const *bits) +{ + diuint cur = { .left = b->data.len, .right = b->fds.len } ; + if (!genalloc_readyplus(diuint, &b->offsets, 1) + || !genalloc_readyplus(int, &b->fds, nfds) + || !stralloc_readyplus(&b->data, len)) + return 0 ; + if (!copyfds(b->fds.s + b->fds.len, fds, nfds, bits)) return 0 ; + b->fds.len += nfds * sizeof(int) ; + byte_copy(b->offsets.s + b->offsets.len, sizeof(diuint), (char const *)&cur) ; + b->offsets.len += sizeof(diuint) ; + return 1 ; +} + +int unixmessage_put_and_close (unixmessage_sender_t *b, unixmessage_t const *m, unsigned char const *bits) +{ + if (!reserve_and_copy(b, m->len, m->fds, m->nfds, bits)) return 0 ; + byte_copy(b->data.s + b->data.len, m->len, m->s) ; + b->data.len += m->len ; + return 1 ; +} + +int unixmessage_putv_and_close (unixmessage_sender_t *b, unixmessage_v_t const *m, unsigned char const *bits) +{ + unsigned int len = 0 ; + register unsigned int i = 0 ; + for (; i < m->vlen ; i++) len += m->v[i].len ; + if (!reserve_and_copy(b, len, m->fds, m->nfds, bits)) return 0 ; + for (i = 0 ; i < m->vlen ; i++) + { + byte_copy(b->data.s + b->data.len, m->v[i].len, m->v[i].s) ; + b->data.len += m->v[i].len ; + } + return 1 ; +} diff --git a/src/libunixonacid/unixmessage_read.c b/src/libunixonacid/unixmessage_read.c new file mode 100644 index 0000000..5a23b84 --- /dev/null +++ b/src/libunixonacid/unixmessage_read.c @@ -0,0 +1,60 @@ +/* ISC license. */ + +#define _XPG4_2 +#include <skalibs/sysdeps.h> +#include <skalibs/nonposix.h> +#include <errno.h> +#include <sys/socket.h> +#include <sys/uio.h> +#include <skalibs/buffer.h> +#include <skalibs/cbuffer.h> +#include <skalibs/djbunix.h> +#include <skalibs/error.h> +#include <skalibs/siovec.h> +#include <skalibs/unixmessage.h> + +int unixmessage_read (int fd, siovec_t const *v, unsigned int n, void *aux) +{ + int r ; + char ancilbuf[CMSG_SPACE(UNIXMESSAGE_MAXFDS * sizeof(int))] ; + struct iovec iov[n] ; + struct msghdr msghdr = + { + .msg_name = 0, + .msg_namelen = 0, + .msg_iov = iov, + .msg_iovlen = n, + .msg_flags = 0, + .msg_control = ancilbuf, + .msg_controllen = sizeof(ancilbuf) + } ; + iovec_from_siovec(iov, v, n) ; +#ifdef SKALIBS_HASCMSGCLOEXEC + r = recvmsg(fd, &msghdr, MSG_WAITALL | MSG_CMSG_CLOEXEC) ; +#else + r = recvmsg(fd, &msghdr, MSG_WAITALL) ; +#endif + if (r > 0) + { + struct cmsghdr *c = CMSG_FIRSTHDR(&msghdr) ; + if (c) + { + cbuffer_t *auxb = aux ; + unsigned int len ; + if (c->cmsg_level != SOL_SOCKET + || c->cmsg_type != SCM_RIGHTS) return (errno = EPROTO, -1-r) ; + len = (unsigned int)(c->cmsg_len - (CMSG_DATA(c) - (unsigned char *)c)) ; +#ifndef SKALIBS_HASCMSGCLOEXEC + { + register unsigned int i = 0 ; + for (; i < len/sizeof(int) ; i++) + if (coe(((int *)CMSG_DATA(c))[i]) < 0) return -1-r ; + } +#endif + if (msghdr.msg_flags | MSG_CTRUNC) return (errno = EPROTO, -1-r) ; + if (cbuffer_put(auxb, (char *)CMSG_DATA(c), len) < len) + return (errno = ENOBUFS, -1-r) ; + } + } + return r ; +} diff --git a/src/libunixonacid/unixmessage_receive.c b/src/libunixonacid/unixmessage_receive.c new file mode 100644 index 0000000..dc75263 --- /dev/null +++ b/src/libunixonacid/unixmessage_receive.c @@ -0,0 +1,44 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/allreadwrite.h> +#include <skalibs/buffer.h> +#include <skalibs/cbuffer.h> +#include <skalibs/error.h> +#include <skalibs/stralloc.h> +#include <skalibs/uint.h> +#include <skalibs/unixmessage.h> + +int unixmessage_receive (unixmessage_receiver_t *b, unixmessage_t *m) +{ + if (b->data.len == b->mainlen) + { + char pack[sizeof(unsigned int) << 1] ; + if (buffer_len(&b->mainb) < sizeof(unsigned int) << 1) + { + register int r = sanitize_read(buffer_fill(&b->mainb)) ; + if (r <= 0) return r ; + if (r < sizeof(unsigned int) << 1) return (errno = EWOULDBLOCK, 0) ; + } + buffer_getnofill(&b->mainb, pack, sizeof(unsigned int) << 1) ; + uint_unpack_big(pack, &b->mainlen) ; + uint_unpack_big(pack + sizeof(unsigned int), &b->auxlen) ; + if (b->auxlen > UNIXMESSAGE_MAXFDS) return (errno = EPROTO, -1) ; + b->auxlen *= sizeof(int) ; + if (!stralloc_ready(&b->data, b->mainlen)) return -1 ; + b->data.len = 0 ; + b->auxw = cbuffer_get(&b->auxb, (char *)b->fds, b->auxlen) ; + } + { + register int r = buffer_getall(&b->mainb, b->data.s, b->mainlen, &b->data.len) ; + if (r <= 0) return r ; + } + if (b->auxw < b->auxlen) + b->auxw += cbuffer_get(&b->auxb, (char *)b->fds, b->auxlen - b->auxw) ; + if (b->auxw < b->auxlen) return (errno = EPROTO, -1) ; + m->s = b->data.s ; + m->len = b->data.len ; + m->fds = b->fds ; + m->nfds = b->auxlen / sizeof(int) ; + return 1 ; +} diff --git a/src/libunixonacid/unixmessage_receiver_free.c b/src/libunixonacid/unixmessage_receiver_free.c new file mode 100644 index 0000000..c23cc77 --- /dev/null +++ b/src/libunixonacid/unixmessage_receiver_free.c @@ -0,0 +1,11 @@ +/* ISC license. */ + +#include <skalibs/stralloc.h> +#include <skalibs/unixmessage.h> + +void unixmessage_receiver_free (unixmessage_receiver_t *b) +{ + stralloc_free(&b->data) ; + b->mainb.fd = -1 ; + b->mainlen = b->auxlen = b->auxw = 0 ; +} diff --git a/src/libunixonacid/unixmessage_receiver_init.c b/src/libunixonacid/unixmessage_receiver_init.c new file mode 100644 index 0000000..982547c --- /dev/null +++ b/src/libunixonacid/unixmessage_receiver_init.c @@ -0,0 +1,17 @@ +/* ISC license. */ + +#include <errno.h> +#include <skalibs/buffer.h> +#include <skalibs/cbuffer.h> +#include <skalibs/stralloc.h> +#include <skalibs/unixmessage.h> + +int unixmessage_receiver_init (unixmessage_receiver_t *b, int fd, char *mainbuf, unsigned int mainlen, char *auxbuf, unsigned int auxlen) +{ + if (mainlen < 9 || auxlen < UNIXMESSAGE_MAXFDS * sizeof(int) + 1) return (errno = EINVAL, 0) ; + if (!cbuffer_init(&b->auxb, auxbuf, auxlen)) return 0 ; + if (!buffer_init_aux(&b->mainb, &unixmessage_read, fd, mainbuf, mainlen, &b->auxb)) return 0 ; + b->mainlen = b->auxlen = b->auxw = 0 ; + b->data = stralloc_zero ; + return 1 ; +} diff --git a/src/libunixonacid/unixmessage_sender_flush.c b/src/libunixonacid/unixmessage_sender_flush.c new file mode 100644 index 0000000..ab8d460 --- /dev/null +++ b/src/libunixonacid/unixmessage_sender_flush.c @@ -0,0 +1,82 @@ +/* ISC license. */ + +#define _XPG4_2 +#include <skalibs/sysdeps.h> +#include <skalibs/nonposix.h> +#include <sys/socket.h> +#include <sys/uio.h> +#include <unistd.h> +#include <skalibs/uint.h> +#include <skalibs/diuint.h> +#include <skalibs/stralloc.h> +#include <skalibs/genalloc.h> +#include <skalibs/djbunix.h> +#include <skalibs/unixmessage.h> + + /* MacOS X tries hard to be POSIX-compliant... and fails. */ +#ifndef MSG_NOSIGNAL +#define MSG_NOSIGNAL 0 +#endif + +int unixmessage_sender_flush (unixmessage_sender_t *b) +{ + diuint last = { .left = b->data.len, .right = genalloc_len(int, &b->fds) } ; + diuint *offsets = genalloc_s(diuint, &b->offsets) ; + unsigned int n = genalloc_len(diuint, &b->offsets) ; + unsigned int oldhead = b->head ; + for (; b->head < n ; b->head++) + { + diuint *next = b->head+1 < n ? offsets + b->head+1 : &last ; + unsigned int len = next->left - offsets[b->head].left ; + unsigned int nfds = next->right - offsets[b->head].right ; + char pack[sizeof(unsigned int) << 1] ; + struct iovec v[2] = + { + { .iov_base = pack, .iov_len = sizeof(unsigned int) << 1 }, + { .iov_base = b->data.s + offsets[b->head].left, .iov_len = len } + } ; + char ancilbuf[CMSG_SPACE(nfds * sizeof(int))] ; + struct msghdr hdr = + { + .msg_name = 0, + .msg_namelen = 0, + .msg_iov = v, + .msg_iovlen = 2, + .msg_control = nfds ? ancilbuf : 0, + .msg_controllen = nfds ? sizeof(ancilbuf) : 0 + } ; + uint_pack_big(pack, len) ; + uint_pack_big(pack + sizeof(unsigned int), nfds) ; + if (nfds) + { + struct cmsghdr *cp = CMSG_FIRSTHDR(&hdr) ; + register unsigned int i = 0 ; + cp->cmsg_level = SOL_SOCKET ; + cp->cmsg_type = SCM_RIGHTS ; + cp->cmsg_len = CMSG_LEN(nfds * sizeof(int)) ; + for (; i < nfds ; i++) + { + register int fd = genalloc_s(int, &b->fds)[offsets[b->head].right + i] ; + ((int *)CMSG_DATA(cp))[i] = fd < 0 ? -(fd+1) : fd ; + } + } + if (sendmsg(b->fd, &hdr, MSG_NOSIGNAL) < len + (sizeof(unsigned int) << 1)) + return -(int)(b->head-oldhead)-1 ; +#ifndef SKALIBS_HASANCILAUTOCLOSE + if (nfds) + { + register unsigned int i = 0 ; + for (; i < nfds ; i++) + { + register int fd = genalloc_s(int, &b->fds)[offsets[b->head].right + i] ; + if (fd < 0) fd_close(-(fd+1)) ; + } + } +#endif + } + b->data.len = 0 ; + genalloc_setlen(int, &b->fds, 0) ; + genalloc_setlen(diuint, &b->offsets, 0) ; + b->head = 0 ; + return (int)(n - oldhead) ; +} diff --git a/src/libunixonacid/unixmessage_sender_free.c b/src/libunixonacid/unixmessage_sender_free.c new file mode 100644 index 0000000..797220c --- /dev/null +++ b/src/libunixonacid/unixmessage_sender_free.c @@ -0,0 +1,29 @@ +/* ISC license. */ + +#include <skalibs/sysdeps.h> +#include <skalibs/diuint.h> +#include <skalibs/stralloc.h> +#include <skalibs/genalloc.h> +#include <skalibs/unixmessage.h> + +void unixmessage_sender_free (unixmessage_sender_t *b) +{ +#ifdef SKALIBS_HASANCILAUTOCLOSE + { + diuint *offsets = genalloc_s(unsigned int, &b->offsets) ; + unsigned int n = genalloc_len(unsigned int, &b->offsets) ; + int *fds = genalloc_s(int, &b->fds) ; + unsigned int nfds = genalloc_len(int, &b->fds) ; + for (; b->head < n ; b->head++) + { + register unsigned int last = b->head+1 < n ? offsets[b->head+1].right : nfds ; + register unsigned int i = offsets[b->head].right ; + for (; i < last ; i++) if (fds[i] >= 0) fd_close(fds[i]) ; + } + } +#endif + genalloc_free(diuint, &b->offsets) ; + genalloc_free(int, &b->fds) ; + stralloc_free(&b->data) ; + *b = unixmessage_sender_zero ; +} diff --git a/src/libunixonacid/unixmessage_sender_getfd.c b/src/libunixonacid/unixmessage_sender_getfd.c new file mode 100644 index 0000000..1f130eb --- /dev/null +++ b/src/libunixonacid/unixmessage_sender_getfd.c @@ -0,0 +1,8 @@ +/* ISC license. */ + +#include <skalibs/unixmessage.h> + +int unixmessage_sender_getfd (unixmessage_sender_t const *b) +{ + return b->fd ; +} diff --git a/src/libunixonacid/unixmessage_sender_init.c b/src/libunixonacid/unixmessage_sender_init.c new file mode 100644 index 0000000..07c0bc2 --- /dev/null +++ b/src/libunixonacid/unixmessage_sender_init.c @@ -0,0 +1,14 @@ +/* ISC license. */ + +#include <skalibs/stralloc.h> +#include <skalibs/genalloc.h> +#include <skalibs/unixmessage.h> + +void unixmessage_sender_init (unixmessage_sender_t *b, int fd) +{ + b->fd = fd ; + b->data = stralloc_zero ; + b->fds = genalloc_zero ; + b->offsets = genalloc_zero ; + b->head = 0 ; +} diff --git a/src/libunixonacid/unixmessage_sender_timed_flush.c b/src/libunixonacid/unixmessage_sender_timed_flush.c new file mode 100644 index 0000000..74e4937 --- /dev/null +++ b/src/libunixonacid/unixmessage_sender_timed_flush.c @@ -0,0 +1,17 @@ +/* ISC license. */ + +#include <skalibs/functypes.h> +#include <skalibs/genalloc.h> +#include <skalibs/tai.h> +#include <skalibs/unix-timed.h> +#include <skalibs/unixmessage.h> + +static int unixmessage_sender_isnonempty (unixmessage_sender_t *b) +{ + return !!genalloc_len(unsigned int, &b->offsets) ; +} + +int unixmessage_sender_timed_flush (unixmessage_sender_t *b, tain_t const *deadline, tain_t *stamp) +{ + return timed_flush(b, (initfunc_t_ref)&unixmessage_sender_getfd, (initfunc_t_ref)&unixmessage_sender_isnonempty, (initfunc_t_ref)&unixmessage_sender_flush, deadline, stamp) ; +} diff --git a/src/libunixonacid/unixmessage_sender_zero.c b/src/libunixonacid/unixmessage_sender_zero.c new file mode 100644 index 0000000..bda0a9b --- /dev/null +++ b/src/libunixonacid/unixmessage_sender_zero.c @@ -0,0 +1,5 @@ +/* ISC license. */ + +#include <skalibs/unixmessage.h> + +unixmessage_sender_t const unixmessage_sender_zero = UNIXMESSAGE_SENDER_ZERO ; diff --git a/src/libunixonacid/unixmessage_timed_handle.c b/src/libunixonacid/unixmessage_timed_handle.c new file mode 100644 index 0000000..5ac7ccd --- /dev/null +++ b/src/libunixonacid/unixmessage_timed_handle.c @@ -0,0 +1,30 @@ +/* ISC license. */ + +#include <skalibs/functypes.h> +#include <skalibs/tai.h> +#include <skalibs/unix-timed.h> +#include <skalibs/unixmessage.h> + +typedef struct unixmessage_handler_blah_s unixmessage_handler_blah_t, *unixmessage_handler_blah_t_ref ; +struct unixmessage_handler_blah_s +{ + unixmessage_receiver_t *b ; + unixmessage_handler_func_t *f ; + void *p ; +} ; + +static int getfd (unixmessage_handler_blah_t *blah) +{ + return unixmessage_receiver_fd(blah->b) ; +} + +static int get (unixmessage_handler_blah_t *blah) +{ + return unixmessage_handle(blah->b, blah->f, blah->p) ; +} + +int unixmessage_timed_handle (unixmessage_receiver_t *b, unixmessage_handler_func_t *f, void *p, tain_t const *deadline, tain_t *stamp) +{ + unixmessage_handler_blah_t blah = { .b = b, .f = f, .p = p } ; + return timed_get(&blah, (initfunc_t_ref)&getfd, (initfunc_t_ref)&get, deadline, stamp) ; +} diff --git a/src/libunixonacid/unixmessage_timed_receive.c b/src/libunixonacid/unixmessage_timed_receive.c new file mode 100644 index 0000000..3761d26 --- /dev/null +++ b/src/libunixonacid/unixmessage_timed_receive.c @@ -0,0 +1,29 @@ +/* ISC license. */ + +#include <skalibs/functypes.h> +#include <skalibs/tai.h> +#include <skalibs/unix-timed.h> +#include <skalibs/unixmessage.h> + +typedef struct unixmessage_get_s unixmessage_get_t, *unixmessage_get_t_ref ; +struct unixmessage_get_s +{ + unixmessage_receiver_t *b ; + unixmessage_t *m ; +} ; + +static int getfd (unixmessage_get_t *g) +{ + return unixmessage_receiver_fd(g->b) ; +} + +static int get (unixmessage_get_t *g) +{ + return unixmessage_receive(g->b, g->m) ; +} + +int unixmessage_timed_receive (unixmessage_receiver_t *b, unixmessage_t *m, tain_t const *deadline, tain_t *stamp) +{ + unixmessage_get_t g = { .b = b, .m = m } ; + return timed_get(&g, (initfunc_t *)&getfd, (initfunc_t *)&get, deadline, stamp) ; +} diff --git a/src/libunixonacid/unixmessage_v_zero.c b/src/libunixonacid/unixmessage_v_zero.c new file mode 100644 index 0000000..b4ab13a --- /dev/null +++ b/src/libunixonacid/unixmessage_v_zero.c @@ -0,0 +1,5 @@ +/* ISC license. */ + +#include <skalibs/unixmessage.h> + +unixmessage_v_t const unixmessage_v_zero = UNIXMESSAGE_V_ZERO ; diff --git a/src/libunixonacid/unixmessage_zero.c b/src/libunixonacid/unixmessage_zero.c new file mode 100644 index 0000000..4cfb242 --- /dev/null +++ b/src/libunixonacid/unixmessage_zero.c @@ -0,0 +1,5 @@ +/* ISC license. */ + +#include <skalibs/unixmessage.h> + +unixmessage_t const unixmessage_zero = UNIXMESSAGE_ZERO ; diff --git a/src/sysdeps/tryaccept4.c b/src/sysdeps/tryaccept4.c new file mode 100644 index 0000000..e27eb1a --- /dev/null +++ b/src/sysdeps/tryaccept4.c @@ -0,0 +1,33 @@ +/* ISC license. */ + +#undef _POSIX_C_SOURCE +#undef _XOPEN_SOURCE + +#ifndef _XPG4_2 +# define _XPG4_2 +#endif + +#ifndef _GNU_SOURCE +# define _GNU_SOURCE +#endif + +#include <sys/types.h> + +#if defined(__FreeBSD__) +# include <sys/param.h> +#endif + +#include <sys/socket.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <errno.h> + +int main (void) +{ + struct sockaddr blah ; + socklen_t blahlen = sizeof(blah) ; + int fd = open("/dev/null", O_RDONLY | O_NONBLOCK) ; + if (fd < 0) return 111 ; + if ((accept4(fd, &blah, &blahlen, SOCK_NONBLOCK) < 0) && (errno != ENOTSOCK)) return 1 ; + return 0 ; +} diff --git a/src/sysdeps/tryancilautoclose.c b/src/sysdeps/tryancilautoclose.c new file mode 100644 index 0000000..7b4a563 --- /dev/null +++ b/src/sysdeps/tryancilautoclose.c @@ -0,0 +1,116 @@ +/* ISC license. */ + +#undef _POSIX_C_SOURCE +#undef _XOPEN_SOURCE + +#ifndef _XPG4_2 +# define _XPG4_2 +#endif + +#include <sys/types.h> +#include <unistd.h> +#include <errno.h> +#include <sys/socket.h> +#include <sys/uio.h> +#if defined(__FreeBSD__) +# include <sys/param.h> +#endif + +typedef struct ancilbuf_s ancilbuf_t, *ancilbuf_t_ref ; +struct ancilbuf_s +{ + struct cmsghdr h ; + int fd ; +} ; + +static int ancil_send_fd (int sock, int fd) +{ + struct msghdr msghdr ; + struct iovec nothing_ptr ; + ancilbuf_t buf ; + struct cmsghdr *cmsg ; + char nothing = '!' ; + + nothing_ptr.iov_base = ¬hing ; + nothing_ptr.iov_len = 1 ; + msghdr.msg_name = 0 ; + msghdr.msg_namelen = 0 ; + msghdr.msg_iov = ¬hing_ptr ; + msghdr.msg_iovlen = 1 ; + msghdr.msg_flags = 0 ; + msghdr.msg_control = &buf ; + msghdr.msg_controllen = sizeof(ancilbuf_t) ; + cmsg = CMSG_FIRSTHDR(&msghdr) ; + cmsg->cmsg_len = msghdr.msg_controllen ; + cmsg->cmsg_level = SOL_SOCKET ; + cmsg->cmsg_type = SCM_RIGHTS ; + *((int *)CMSG_DATA(cmsg)) = fd ; + return (sendmsg(sock, &msghdr, 0) >= 0) ; +} + +static int ancil_recv_fd (int sock) +{ + struct msghdr msghdr ; + struct iovec nothing_ptr ; + ancilbuf_t buf ; + struct cmsghdr *cmsg ; + char nothing ; + + nothing_ptr.iov_base = ¬hing ; + nothing_ptr.iov_len = 1 ; + msghdr.msg_name = 0 ; + msghdr.msg_namelen = 0 ; + msghdr.msg_iov = ¬hing_ptr ; + msghdr.msg_iovlen = 1 ; + msghdr.msg_flags = 0 ; + msghdr.msg_control = &buf ; + msghdr.msg_controllen = sizeof(ancilbuf_t) ; + cmsg = CMSG_FIRSTHDR(&msghdr) ; + cmsg->cmsg_len = msghdr.msg_controllen ; + cmsg->cmsg_level = SOL_SOCKET ; + cmsg->cmsg_type = SCM_RIGHTS ; + *((int *)CMSG_DATA(cmsg)) = -1 ; + if (recvmsg(sock, &msghdr, 0) < 0) return -1 ; + return *((int *)CMSG_DATA(cmsg)) ; +} + +static int client (int sock) +{ + int p ; + char c ; + if (read(sock, &c, 1) < 1) return 111 ; + if (c != 'b') return 111 ; + p = ancil_recv_fd(sock) ; + if (p < 0) return 111 ; + if (read(sock, &c, 1) < 1) return 111 ; + if (c != 'a') return 111 ; + if (read(p, &c, 1) < 1) return 111 ; + if (c != 'K') return 111 ; + if (read(p, &c, 1) < 1) return 111 ; + return c ; +} + +static void server (int sock) +{ + int p[2] ; + char c = 1 ; + if (pipe(p) < 0) return ; + if (write(sock, "b", 1) < 1) return ; + if (!ancil_send_fd(sock, p[0])) return ; + if (write(sock, "a", 1) < 1) return ; + if (write(p[1], "K", 1) < 1) return ; + if ((close(p[0]) < 0) && (errno == EBADF)) c = 0 ; + write(p[1], &c, 1) ; +} + +int main (void) +{ + int fd[2] ; + if (socketpair(AF_UNIX, SOCK_STREAM, 0, fd) < 0) return 111 ; + switch (fork()) + { + case -1 : return 111 ; + case 0 : close(fd[0]) ; server(fd[1]) ; return 0 ; + default : close(fd[1]) ; return client(fd[0]) ; + } +} diff --git a/src/sysdeps/tryclockmon.c b/src/sysdeps/tryclockmon.c new file mode 100644 index 0000000..2564ed3 --- /dev/null +++ b/src/sysdeps/tryclockmon.c @@ -0,0 +1,11 @@ +/* ISC license. */ + +#include <sys/types.h> +#include <time.h> + +int main (void) +{ + struct timespec ts ; + if (clock_gettime(CLOCK_MONOTONIC, &ts) < 0) return 111 ; + return 0 ; +} diff --git a/src/sysdeps/tryclockrt.c b/src/sysdeps/tryclockrt.c new file mode 100644 index 0000000..01bae7c --- /dev/null +++ b/src/sysdeps/tryclockrt.c @@ -0,0 +1,11 @@ +/* ISC license. */ + +#include <sys/types.h> +#include <time.h> + +int main (void) +{ + struct timespec ts ; + if (clock_gettime(CLOCK_REALTIME, &ts) < 0) return 111 ; + return 0 ; +} diff --git a/src/sysdeps/trycmsgcloexec.c b/src/sysdeps/trycmsgcloexec.c new file mode 100644 index 0000000..7923340 --- /dev/null +++ b/src/sysdeps/trycmsgcloexec.c @@ -0,0 +1,25 @@ +/* ISC license. */ + +#undef _POSIX_C_SOURCE +#undef _XOPEN_SOURCE + +#ifndef _XPG4_2 +# define _XPG4_2 +#endif + +#ifndef _XPG_6 +# define _XPG6 +#endif + +#ifndef _GNU_SOURCE +# define _GNU_SOURCE +#endif + +#include <sys/types.h> +#include <sys/socket.h> + +int main (void) +{ + int flag = MSG_CMSG_CLOEXEC ; + return 0 ; +} diff --git a/src/sysdeps/trydevrandom.c b/src/sysdeps/trydevrandom.c new file mode 100644 index 0000000..395d008 --- /dev/null +++ b/src/sysdeps/trydevrandom.c @@ -0,0 +1,54 @@ +/* ISC license. */ + +#include <unistd.h> +#include <sys/types.h> +#include <fcntl.h> +#include <errno.h> + +static 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 ; +} + +static unsigned int allread (int fd, register char *buf, register unsigned int len) +{ + register unsigned int written = 0 ; + while (len) + { + register int w = fd_read(fd, buf, len) ; + if (!w) errno = EPIPE ; + if (w <= 0) break ; + written += w ; + buf += w ; + len -= w ; + } + return written ; +} + +static int byte_diff (char *s, unsigned int n, char *t) +{ + for (;;) + { + if (!n) return 0 ; + if (*s != *t) break ; + ++s ; ++t ; --n ; + } + return ((int)(unsigned int)(unsigned char) *s) + - ((int)(unsigned int)(unsigned char) *t); +} + +int main () +{ + char a[64] ; + char b[64] ; + int fd = open("/dev/random", O_RDONLY) ; + if ((fd == -1) || (allread(fd, a, 64) < 64) ) return 111 ; + close(fd) ; + fd = open("/dev/random", O_RDONLY) ; + if ((fd == -1) || (allread(fd, b, 64) < 64) ) return 111 ; + close(fd) ; + return !byte_diff(a, 64, b) ; +} diff --git a/src/sysdeps/trydevurandom.c b/src/sysdeps/trydevurandom.c new file mode 100644 index 0000000..3d0f912 --- /dev/null +++ b/src/sysdeps/trydevurandom.c @@ -0,0 +1,31 @@ +/* ISC license. */ + +#include <unistd.h> +#include <sys/types.h> +#include <fcntl.h> + +static int byte_diff (char *s, unsigned int n, char *t) +{ + for (;;) + { + if (!n) return 0 ; + if (*s != *t) break ; + ++s ; ++t ; --n ; + } + return ((int)(unsigned int)(unsigned char) *s) + - ((int)(unsigned int)(unsigned char) *t); +} + +int main () +{ + char a[64] ; + char b[64] ; + int fd ; + fd = open("/dev/urandom", O_RDONLY) ; + if ((fd == -1) || (read(fd, a, 64) < 64) ) return 111 ; + close(fd) ; + fd = open("/dev/urandom", O_RDONLY) ; + if ((fd == -1) || (read(fd, b, 64) < 64) ) return 111 ; + close(fd) ; + return (!byte_diff(a, 64, b)) ; +} diff --git a/src/sysdeps/tryendianness.c b/src/sysdeps/tryendianness.c new file mode 100644 index 0000000..3fa1938 --- /dev/null +++ b/src/sysdeps/tryendianness.c @@ -0,0 +1,43 @@ +/* ISC license. */ + +#include <stdio.h> + +int main (void) +{ + unsigned long i = 0xdeadbeefUL ; + if (sizeof(unsigned long) == 4) + if ((((unsigned char *)(&i))[0] == 0xef) + && (((unsigned char *)(&i))[1] == 0xbe) + && (((unsigned char *)(&i))[2] == 0xad) + && (((unsigned char *)(&i))[3] == 0xde)) + return (puts("little"), 0) ; + else if ((((unsigned char *)(&i))[0] == 0xde) + && (((unsigned char *)(&i))[1] == 0xad) + && (((unsigned char *)(&i))[2] == 0xbe) + && (((unsigned char *)(&i))[3] == 0xef)) + return (puts("big"), 0) ; + else return (puts("unknown"), 1) ; + else if (sizeof(unsigned long) == 8) + if ((((unsigned char *)(&i))[0] == 0xef) + && (((unsigned char *)(&i))[1] == 0xbe) + && (((unsigned char *)(&i))[2] == 0xad) + && (((unsigned char *)(&i))[3] == 0xde) + && (((unsigned char *)(&i))[4] == 0x00) + && (((unsigned char *)(&i))[5] == 0x00) + && (((unsigned char *)(&i))[6] == 0x00) + && (((unsigned char *)(&i))[7] == 0x00)) + return (puts("little"), 0) ; + else if (sizeof(unsigned long) == 8) + if ((((unsigned char *)(&i))[0] == 0x00) + && (((unsigned char *)(&i))[1] == 0x00) + && (((unsigned char *)(&i))[2] == 0x00) + && (((unsigned char *)(&i))[3] == 0x00) + && (((unsigned char *)(&i))[4] == 0xde) + && (((unsigned char *)(&i))[5] == 0xad) + && (((unsigned char *)(&i))[6] == 0xbe) + && (((unsigned char *)(&i))[7] == 0xef)) + return (puts("big"), 0) ; + else return (puts("unknown"), 1) ; + else return 1 ; + else return (puts("unknown unsigned long size"), 1) ; +} diff --git a/src/sysdeps/tryeproto.c b/src/sysdeps/tryeproto.c new file mode 100644 index 0000000..b5cc66c --- /dev/null +++ b/src/sysdeps/tryeproto.c @@ -0,0 +1,7 @@ +/* ISC license. */ + +#include <errno.h> +static int dummy ; +#ifndef EPROTO + syntax error ! +#endif diff --git a/src/sysdeps/tryeventfd.c b/src/sysdeps/tryeventfd.c new file mode 100644 index 0000000..3c3122c --- /dev/null +++ b/src/sysdeps/tryeventfd.c @@ -0,0 +1,10 @@ +/* ISC license. */ + +#include <sys/eventfd.h> + +int main (void) +{ + int fd = eventfd(0, EFD_NONBLOCK) ; + if (fd < 0) return 1 ; + return 0 ; +} diff --git a/src/sysdeps/tryflock.c b/src/sysdeps/tryflock.c new file mode 100644 index 0000000..47fadf8 --- /dev/null +++ b/src/sysdeps/tryflock.c @@ -0,0 +1,13 @@ +/* ISC license. */ + +#undef _POSIX_C_SOURCE +#undef _XOPEN_SOURCE + +#include <sys/types.h> +#include <sys/file.h> +#include <fcntl.h> + +int main (void) +{ + return flock(0, LOCK_EX | LOCK_UN | LOCK_NB) ; +} diff --git a/src/sysdeps/trygetpeereid.c b/src/sysdeps/trygetpeereid.c new file mode 100644 index 0000000..10a411a --- /dev/null +++ b/src/sysdeps/trygetpeereid.c @@ -0,0 +1,15 @@ +/* ISC license. */ + +#undef _POSIX_C_SOURCE +#undef _XOPEN_SOURCE + +#include <sys/types.h> +#include <unistd.h> + +int main (void) +{ + uid_t uid ; + gid_t gid ; + int s = 0 ; + return getpeereid(s, &uid, &gid) ; +} diff --git a/src/sysdeps/trygetpeerucred.c b/src/sysdeps/trygetpeerucred.c new file mode 100644 index 0000000..22dac68 --- /dev/null +++ b/src/sysdeps/trygetpeerucred.c @@ -0,0 +1,20 @@ +/* ISC license. */ + +#undef _POSIX_C_SOURCE +#undef _XOPEN_SOURCE + +#include <sys/types.h> +#include <ucred.h> + +int main (void) +{ + ucred_t *cred ; + uid_t uid ; + gid_t gid ; + int s = 0 ; + getpeerucred(s, &cred) ; + uid = ucred_geteuid(cred) ; + gid = ucred_getegid(cred) ; + ucred_free(cred) ; + return 0 ; +} diff --git a/src/sysdeps/tryipv6.c b/src/sysdeps/tryipv6.c new file mode 100644 index 0000000..0c7f306 --- /dev/null +++ b/src/sysdeps/tryipv6.c @@ -0,0 +1,35 @@ +/* ISC license. */ + +#undef _POSIX_C_SOURCE +#undef _XOPEN_SOURCE + +#define _XPG4_2 +#define _XPG6 + +#include <sys/types.h> + +#if defined(__FreeBSD__) +# include <sys/param.h> +#endif + +#include <errno.h> +#include <string.h> +#include <sys/socket.h> +#include <netinet/in.h> + +int main (void) +{ + int s ; + register int r ; + struct in6_addr foo ; + struct sockaddr_in6 bar ; + memset(&foo, 0, sizeof(struct sockaddr_in6)) ; + bar.sin6_addr = foo ; + bar.sin6_port = 1026 ; + s = socket(AF_INET6, SOCK_STREAM, 0) ; + if (s < 0) return 111 ; + do r = connect(s, (struct sockaddr *)&bar, sizeof bar) ; + while ((r == -1) && (errno == EINTR)) ; + if ((r == -1) && (errno == EALREADY)) errno = EINPROGRESS ; + return 0 ; +} diff --git a/src/sysdeps/trylinkat.c b/src/sysdeps/trylinkat.c new file mode 100644 index 0000000..3db0845 --- /dev/null +++ b/src/sysdeps/trylinkat.c @@ -0,0 +1,29 @@ +/* ISC license. */ + +#undef _POSIX_C_SOURCE +#undef _XOPEN_SOURCE + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + +#ifndef _ATFILE_SOURCE +#define _ATFILE_SOURCE +#endif + +#ifndef _INCOMPLETE_XOPEN_C063 +#define _INCOMPLETE_XOPEN_C063 +#endif + +#ifndef __EXTENSIONS__ +#define __EXTENSIONS__ +#endif + +#include <unistd.h> +#include <fcntl.h> + +int main (void) +{ + int r = linkat(AT_FDCWD, "/foo", AT_FDCWD, "foo", AT_SYMLINK_FOLLOW) ; + return (r < 0) ; +} diff --git a/src/sysdeps/trylsock.c b/src/sysdeps/trylsock.c new file mode 100644 index 0000000..b5b4413 --- /dev/null +++ b/src/sysdeps/trylsock.c @@ -0,0 +1,26 @@ +/* ISC license. */ + +#undef _POSIX_C_SOURCE +#undef _XOPEN_SOURCE + +#ifndef _XPG4_2 +# define _XPG4_2 +#endif + +#ifndef _GNU_SOURCE +# define _GNU_SOURCE +#endif + +#include <sys/types.h> + +#if defined(__FreeBSD__) +# include <sys/param.h> +#endif + +#include <sys/socket.h> + +int main (void) +{ + shutdown(0, 0) ; + return 0 ; +} diff --git a/src/sysdeps/trymalloc0.c b/src/sysdeps/trymalloc0.c new file mode 100644 index 0000000..0f68329 --- /dev/null +++ b/src/sysdeps/trymalloc0.c @@ -0,0 +1,4 @@ +/* ISC license */ + +#include <stdlib.h> +int main() { return !malloc(0) ; } diff --git a/src/sysdeps/tryopenat.c b/src/sysdeps/tryopenat.c new file mode 100644 index 0000000..d24a9cb --- /dev/null +++ b/src/sysdeps/tryopenat.c @@ -0,0 +1,29 @@ +/* ISC license. */ + +#undef _POSIX_C_SOURCE +#undef _XOPEN_SOURCE + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + +#ifndef _ATFILE_SOURCE +#define _ATFILE_SOURCE +#endif + +#ifndef _INCOMPLETE_XOPEN_C063 +#define _INCOMPLETE_XOPEN_C063 +#endif + +#ifndef __EXTENSIONS__ +#define __EXTENSIONS__ +#endif + +#include <sys/stat.h> +#include <fcntl.h> + +int main (void) +{ + int fd = openat(0, "/", O_RDONLY) ; + return (fd < 0) ; +} diff --git a/src/sysdeps/trypipe2.c b/src/sysdeps/trypipe2.c new file mode 100644 index 0000000..4e63182 --- /dev/null +++ b/src/sysdeps/trypipe2.c @@ -0,0 +1,17 @@ +/* ISC license. */ + +#ifndef _NETBSD_SOURCE +#define _NETBSD_SOURCE +#endif +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + +#include <unistd.h> + +int main (void) +{ + int p[2] ; + if (pipe2(p, 0) < 0) return 111 ; + return 0 ; +} diff --git a/src/sysdeps/tryposixspawn.c b/src/sysdeps/tryposixspawn.c new file mode 100644 index 0000000..dccdba4 --- /dev/null +++ b/src/sysdeps/tryposixspawn.c @@ -0,0 +1,16 @@ +/* ISC license. */ + +#include <sys/types.h> +#include <spawn.h> + +int main (void) +{ + pid_t pid ; + posix_spawn_file_actions_t actions ; + posix_spawnattr_t attr ; + char *const argv[2] = { "/bin/true", 0 } ; + char *const envp[1] = { 0 } ; + posix_spawnattr_setflags(&attr, 0) ; + posix_spawn_file_actions_init(&actions) ; + return posix_spawn(&pid, argv[0], 0, 0, argv, envp) ; +} diff --git a/src/sysdeps/tryppoll.c b/src/sysdeps/tryppoll.c new file mode 100644 index 0000000..33380b8 --- /dev/null +++ b/src/sysdeps/tryppoll.c @@ -0,0 +1,18 @@ +/* ISC license. */ + +#define _GNU_SOURCE +#include <sys/stat.h> +#include <fcntl.h> +#include <time.h> +#include <poll.h> + +int main (void) +{ + struct pollfd x = { .events = POLLIN } ; + struct timespec ts = { .tv_sec = 0, .tv_nsec = 10 } ; + x.fd = open("src/sysdeps/tryppoll.c", O_RDONLY); + if (x.fd < 0) return 111 ; + if (ppoll(&x, 1, &ts, 0) < 0) return 1 ; + if (x.revents != POLLIN) return 1 ; + return 0 ; +} diff --git a/src/sysdeps/tryrevoke.c b/src/sysdeps/tryrevoke.c new file mode 100644 index 0000000..9cbc615 --- /dev/null +++ b/src/sysdeps/tryrevoke.c @@ -0,0 +1,7 @@ +/* ISC license. */ + +#undef _POSIX_C_SOURCE +#undef _XOPEN_SOURCE + +#include <unistd.h> +int main () { return revoke("/") ; } diff --git a/src/sysdeps/trysendfile.c b/src/sysdeps/trysendfile.c new file mode 100644 index 0000000..6c99ad0 --- /dev/null +++ b/src/sysdeps/trysendfile.c @@ -0,0 +1,10 @@ +/* ISC license. */ + +#include <sys/types.h> +#include <sys/sendfile.h> + +int main (void) +{ + sendfile(1, 0, 0, 4096) ; + return 0 ; +} diff --git a/src/sysdeps/trysetgroups.c b/src/sysdeps/trysetgroups.c new file mode 100644 index 0000000..af2d8c6 --- /dev/null +++ b/src/sysdeps/trysetgroups.c @@ -0,0 +1,27 @@ +/* ISC license. */ + +#undef _POSIX_C_SOURCE +#undef _XOPEN_SOURCE + +#ifndef _BSD_SOURCE +#define _BSD_SOURCE +#endif + +#ifndef _NETBSD_SOURCE +#define _NETBSD_SOURCE +#endif + +#ifndef __EXTENSIONS__ +#define __EXTENSIONS__ +#endif + +#include <sys/types.h> +#include <unistd.h> +#include <grp.h> + +int main (void) +{ + gid_t g = 0 ; + setgroups(1, &g) ; + return 0 ; +} diff --git a/src/sysdeps/trysettimeofday.c b/src/sysdeps/trysettimeofday.c new file mode 100644 index 0000000..05ae3c4 --- /dev/null +++ b/src/sysdeps/trysettimeofday.c @@ -0,0 +1,27 @@ +/* ISC license. */ + +#undef _POSIX_C_SOURCE +#undef _XOPEN_SOURCE + +#ifndef _BSD_SOURCE +#define _BSD_SOURCE +#endif + +#ifndef _NETBSD_SOURCE +#define _NETBSD_SOURCE +#endif + +#ifndef __EXTENSIONS__ +#define __EXTENSIONS__ +#endif + +#include <sys/types.h> +#include <sys/time.h> + +int main (void) +{ + struct timeval tv ; + gettimeofday(&tv, 0) ; + settimeofday(&tv, 0) ; + return 0 ; +} diff --git a/src/sysdeps/trysignalfd.c b/src/sysdeps/trysignalfd.c new file mode 100644 index 0000000..1f06933 --- /dev/null +++ b/src/sysdeps/trysignalfd.c @@ -0,0 +1,13 @@ +/* ISC license. */ + +#include <sys/types.h> +#include <signal.h> +#include <sys/signalfd.h> + +int main (void) +{ + sigset_t foo ; + sigemptyset(&foo) ; + if (signalfd(-1, &foo, SFD_NONBLOCK) < 0) return 1 ; + return 0 ; +} diff --git a/src/sysdeps/trysizeofgid.c b/src/sysdeps/trysizeofgid.c new file mode 100644 index 0000000..75eeb2c --- /dev/null +++ b/src/sysdeps/trysizeofgid.c @@ -0,0 +1,8 @@ +#include <sys/types.h> +#include <stdio.h> + +int main (void) +{ + printf("%u\n", (unsigned int)sizeof(gid_t)) ; + return 0 ; +} diff --git a/src/sysdeps/trysizeoftime.c b/src/sysdeps/trysizeoftime.c new file mode 100644 index 0000000..13674de --- /dev/null +++ b/src/sysdeps/trysizeoftime.c @@ -0,0 +1,8 @@ +#include <sys/types.h> +#include <stdio.h> + +int main (void) +{ + printf("%u\n", (unsigned int)sizeof(time_t)) ; + return 0 ; +} diff --git a/src/sysdeps/trysizeofuint.c b/src/sysdeps/trysizeofuint.c new file mode 100644 index 0000000..ca4af39 --- /dev/null +++ b/src/sysdeps/trysizeofuint.c @@ -0,0 +1,7 @@ +#include <stdio.h> + +int main (void) +{ + printf("%u\n", (unsigned int)sizeof(unsigned int)) ; + return 0 ; +} diff --git a/src/sysdeps/trysizeofulong.c b/src/sysdeps/trysizeofulong.c new file mode 100644 index 0000000..f2f21b1 --- /dev/null +++ b/src/sysdeps/trysizeofulong.c @@ -0,0 +1,7 @@ +#include <stdio.h> + +int main (void) +{ + printf("%u\n", (unsigned int)sizeof(unsigned long)) ; + return 0 ; +} diff --git a/src/sysdeps/trysizeofushort.c b/src/sysdeps/trysizeofushort.c new file mode 100644 index 0000000..fd410bb --- /dev/null +++ b/src/sysdeps/trysizeofushort.c @@ -0,0 +1,7 @@ +#include <stdio.h> + +int main (void) +{ + printf("%u\n", (unsigned int)sizeof(unsigned short)) ; + return 0 ; +} diff --git a/src/sysdeps/trysopeercred.c b/src/sysdeps/trysopeercred.c new file mode 100644 index 0000000..0356fcf --- /dev/null +++ b/src/sysdeps/trysopeercred.c @@ -0,0 +1,29 @@ +/* ISC license. */ + +#undef _POSIX_C_SOURCE +#undef _XOPEN_SOURCE + +#ifndef _XPG4_2 +# define _XPG4_2 +#endif + +#ifndef _GNU_SOURCE +# define _GNU_SOURCE +#endif + +#include <sys/types.h> + +#if defined(__FreeBSD__) +# include <sys/param.h> +#endif + +#include <sys/socket.h> +#include <sys/un.h> + +int main (void) +{ + int s ; + struct ucred dummy ; + socklen_t len = sizeof(struct ucred) ; + return getsockopt(s, SOL_SOCKET, SO_PEERCRED, &dummy, &len) ; +} diff --git a/src/sysdeps/trysplice.c b/src/sysdeps/trysplice.c new file mode 100644 index 0000000..6b566b8 --- /dev/null +++ b/src/sysdeps/trysplice.c @@ -0,0 +1,28 @@ +/* ISC license. */ + +#define _GNU_SOURCE +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> + +#define N 4096 + +int main (void) +{ + char buf[N] ; + int p[2] ; + int fd ; + if (pipe(p) < 0) return 111 ; + fd = open("./src/sysdeps/trysplice.c", O_RDONLY) ; + if (fd < 0) return 111 ; + + for (;;) + { + register int r = splice(fd, 0, p[1], 0, N, 0) ; + if (r < 0) return 1 ; + if (!r) break ; + if (splice(p[0], 0, 1, 0, r, 0) < r) return 2 ; + } + return 0 ; +} diff --git a/src/sysdeps/trystrcasestr.c b/src/sysdeps/trystrcasestr.c new file mode 100644 index 0000000..f362202 --- /dev/null +++ b/src/sysdeps/trystrcasestr.c @@ -0,0 +1,21 @@ +/* ISC license. */ + +#undef _POSIX_C_SOURCE +#undef _XOPEN_SOURCE + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif +#ifndef _BSD_SOURCE +#define _BSD_SOURCE +#endif +#ifndef _NETBSD_SOURCE +#define _NETBSD_SOURCE +#endif + +#include <string.h> + +int main (void) +{ + return !strcasestr("foobar", "bar") ; +} diff --git a/src/sysdeps/tryuint64t.c b/src/sysdeps/tryuint64t.c new file mode 100644 index 0000000..23aafad --- /dev/null +++ b/src/sysdeps/tryuint64t.c @@ -0,0 +1,5 @@ +/* ISC license. */ + +#include <stdint.h> + +uint64_t dummy = 0 ; |