From 1599b818d91d363e5fcda0deda9741f0074a28c6 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Thu, 21 Apr 2022 13:44:59 -0700 Subject: [PATCH] Make more fixes and improvements --- Makefile | 2 +- libc/calls/calls.mk | 2 +- libc/fmt/fmt.c | 397 +----------------- libc/fmt/{fmts.h => fmt.internal.h} | 17 +- libc/fmt/ntoa.c | 2 +- libc/fmt/pad.c | 2 +- libc/fmt/pflink.h | 2 - libc/fmt/stoa.c | 4 +- .../{PowerProf => PowrProf}/SetSuspendState.s | 2 +- libc/nt/master.sh | 4 +- libc/nt/nt.mk | 32 +- libc/stdio/dtoa.c | 379 ++++++++++++++++- third_party/lua/lapi.c | 34 ++ third_party/lua/llimits.h | 1 - tool/build/jail.c | 11 +- tool/net/demo/unix-info.lua | 80 ++++ .../net/demo/{unix.lua => unix-rawsocket.lua} | 0 tool/net/demo/unix-subprocess.lua | 44 ++ tool/net/demo/unix2.lua | 26 -- tool/net/echo.c | 21 +- tool/net/help.txt | 73 +++- tool/net/lunix.c | 166 ++++++-- tool/net/net.mk | 9 +- tool/net/redbean.c | 86 ++-- 24 files changed, 858 insertions(+), 538 deletions(-) rename libc/fmt/{fmts.h => fmt.internal.h} (55%) rename libc/nt/{PowerProf => PowrProf}/SetSuspendState.s (78%) create mode 100644 tool/net/demo/unix-info.lua rename tool/net/demo/{unix.lua => unix-rawsocket.lua} (100%) create mode 100644 tool/net/demo/unix-subprocess.lua delete mode 100644 tool/net/demo/unix2.lua diff --git a/Makefile b/Makefile index efb2c9a5d..2c29072ff 100644 --- a/Makefile +++ b/Makefile @@ -281,7 +281,7 @@ COSMOPOLITAN_OBJECTS = \ LIBC_RAND \ LIBC_SYSV_CALLS \ LIBC_NT_PSAPI \ - LIBC_NT_POWERPROF \ + LIBC_NT_POWRPROF \ LIBC_NT_PDH \ LIBC_NT_SHELL32 \ LIBC_NT_GDI32 \ diff --git a/libc/calls/calls.mk b/libc/calls/calls.mk index 9a6f7858c..dfa690101 100644 --- a/libc/calls/calls.mk +++ b/libc/calls/calls.mk @@ -46,7 +46,7 @@ LIBC_CALLS_A_DIRECTDEPS = \ LIBC_NT_NTDLL \ LIBC_NT_PDH \ LIBC_NT_PSAPI \ - LIBC_NT_POWERPROF \ + LIBC_NT_POWRPROF \ LIBC_NT_WS2_32 \ LIBC_STR \ LIBC_STUBS \ diff --git a/libc/fmt/fmt.c b/libc/fmt/fmt.c index 692d5244e..2964eda62 100644 --- a/libc/fmt/fmt.c +++ b/libc/fmt/fmt.c @@ -21,7 +21,7 @@ #include "libc/bits/weaken.h" #include "libc/fmt/conv.h" #include "libc/fmt/fmt.h" -#include "libc/fmt/fmts.h" +#include "libc/fmt/fmt.internal.h" #include "libc/fmt/internal.h" #include "libc/fmt/itoa.h" #include "libc/intrin/nomultics.internal.h" @@ -33,25 +33,6 @@ #include "libc/sysv/errfuns.h" #include "third_party/gdtoa/gdtoa.h" -#define PUT(C) \ - do { \ - char Buf[1] = {C}; \ - if (out(Buf, arg, 1) == -1) { \ - return -1; \ - } \ - } while (0) - -static const char kSpecialFloats[2][2][4] = {{"INF", "inf"}, {"NAN", "nan"}}; - -static void __fmt_free_dtoa(char **mem) { - if (*mem) { - if (weaken(freedtoa)) { - weaken(freedtoa)(*mem); - } - *mem = 0; - } -} - static int __fmt_atoi(const char **str) { int i; for (i = 0; '0' <= **str && **str <= '9'; ++*str) { @@ -129,11 +110,6 @@ static int __fmt_atoi(const char **str) { * @vforksafe if floating point isn't used */ hidden int __fmt(void *fn, void *arg, const char *format, va_list va) { - union { - double d; - uint32_t u[2]; - uint64_t q; - } pun; long ld; void *p; unsigned u; @@ -145,13 +121,12 @@ hidden int __fmt(void *fn, void *arg, const char *format, va_list va) { const char *alphabet; int (*out)(const char *, void *, size_t); unsigned char signbit, log2base; - int c, d, k, w, n, i1, ui, bw, bex; - char *s, *q, *se, *mem, qchar, special[8]; - int sgn, alt, sign, prec, prec1, flags, width, decpt, lasterr; + char *s, *q, qchar; + int d, w, n; + int sign, prec, flags, width, lasterr; lasterr = errno; out = fn ? fn : (void *)missingno; - mem = 0; while (*format) { if (*format != '%') { @@ -361,7 +336,6 @@ hidden int __fmt(void *fn, void *arg, const char *format, va_list va) { } break; } - case 'c': prec = 1; flags |= FLAGS_PRECISION; @@ -369,12 +343,10 @@ hidden int __fmt(void *fn, void *arg, const char *format, va_list va) { p = charbuf; charbuf[0] = va_arg(va, int); goto FormatString; - case 'm': p = weaken(strerror) ? weaken(strerror)(lasterr) : "?"; signbit = 0; goto FormatString; - case 'r': // undocumented %r specifier // used for good carriage return @@ -385,11 +357,9 @@ hidden int __fmt(void *fn, void *arg, const char *format, va_list va) { p = "\r\e[K"; goto FormatString; } - case 'q': flags |= FLAGS_QUOTE; /* fallthrough */ - case 's': p = va_arg(va, void *); FormatString: @@ -397,369 +367,40 @@ hidden int __fmt(void *fn, void *arg, const char *format, va_list va) { return -1; } break; - case 'n': // nonstandard %n specifier // used to print newlines that work in raw terminal modes - if (__nomultics) PUT('\r'); - PUT('\n'); + if (__nomultics) __FMT_PUT('\r'); + __FMT_PUT('\n'); break; - case 'F': case 'f': - if (!(flags & FLAGS_PRECISION)) prec = 6; - if (longdouble) { - pun.d = va_arg(va, long double); - } else { - pun.d = va_arg(va, double); - } - FormatDtoa: + case 'G': + case 'g': + case 'e': + case 'E': + case 'a': + case 'A': if (!weaken(__fmt_dtoa)) { p = "?"; - goto FormatThatThing; - } - assert(!mem); - s = mem = weaken(__fmt_dtoa)(pun.d, 3, prec, &decpt, &sgn, &se); - if (decpt == 9999) { - Format9999: - bzero(special, sizeof(special)); - p = q = special; - if (sgn) { - *q++ = '-'; - } else if (flags & FLAGS_PLUS) { - *q++ = '+'; - } else if (flags & FLAGS_SPACE) { - *q++ = ' '; - } - memcpy(q, kSpecialFloats[*s == 'N'][d >= 'a'], 4); - FormatThatThing: - __fmt_free_dtoa(&mem); - mem = 0; - prec = alt = 0; + prec = 0; flags &= ~(FLAGS_PRECISION | FLAGS_PLUS | FLAGS_SPACE); goto FormatString; } - FormatReal: - if (sgn) sign = '-'; - if (prec > 0) width -= prec; - if (width > 0) { - if (sign) --width; - if (decpt <= 0) { - --width; - if (prec > 0) --width; - } else { - if (s == se) decpt = 1; - width -= decpt; - if (prec > 0 || alt) --width; - } - } - if (width > 0 && !(flags & FLAGS_LEFT)) { - if (flags & FLAGS_ZEROPAD) { - if (sign) PUT(sign); - sign = 0; - do PUT('0'); - while (--width > 0); - } else { - do PUT(' '); - while (--width > 0); - } - } - if (sign) PUT(sign); - if (decpt <= 0) { - PUT('0'); - if (prec > 0 || alt) PUT('.'); - while (decpt < 0) { - PUT('0'); - prec--; - decpt++; - } - } else { - do { - if ((c = *s)) { - s++; - } else { - c = '0'; - } - PUT(c); - } while (--decpt > 0); - if (prec > 0 || alt) PUT('.'); - } - while (--prec >= 0) { - if ((c = *s)) { - s++; - } else { - c = '0'; - } - PUT(c); - } - while (--width >= 0) { - PUT(' '); - } - __fmt_free_dtoa(&mem); - continue; - - case 'G': - case 'g': - if (!(flags & FLAGS_PRECISION)) prec = 6; - if (longdouble) { - pun.d = va_arg(va, long double); - } else { - pun.d = va_arg(va, double); - } - if (prec < 0) prec = 0; - if (!weaken(__fmt_dtoa)) { - p = "?"; - goto FormatThatThing; - } - assert(!mem); - s = mem = - weaken(__fmt_dtoa)(pun.d, prec ? 2 : 0, prec, &decpt, &sgn, &se); - if (decpt == 9999) goto Format9999; - c = se - s; - prec1 = prec; - if (!prec) { - prec = c; - prec1 = c + (s[1] || alt ? 5 : 4); - } - if (decpt > -4 && decpt <= prec1) { - if (alt) { - prec -= decpt; - } else { - prec = c - decpt; - } - if (prec < 0) prec = 0; - goto FormatReal; - } - d -= 2; - if (!alt && prec > c) prec = c; - --prec; - goto FormatExpo; - - case 'e': - case 'E': - if (!(flags & FLAGS_PRECISION)) prec = 6; - if (longdouble) { - pun.d = va_arg(va, long double); - } else { - pun.d = va_arg(va, double); - } - if (prec < 0) prec = 0; - if (!weaken(__fmt_dtoa)) { - p = "?"; - goto FormatThatThing; - } - assert(!mem); - s = mem = weaken(__fmt_dtoa)(pun.d, 2, prec + 1, &decpt, &sgn, &se); - if (decpt == 9999) goto Format9999; - FormatExpo: - if (sgn) sign = '-'; - if ((width -= prec + 5) > 0) { - if (sign) --width; - if (prec || alt) --width; - } - if ((c = --decpt) < 0) c = -c; - while (c >= 100) { - --width; - c /= 10; - } - if (width > 0 && !(flags & FLAGS_LEFT)) { - if (flags & FLAGS_ZEROPAD) { - if (sign) PUT(sign); - sign = 0; - do PUT('0'); - while (--width > 0); - } else { - do PUT(' '); - while (--width > 0); - } - } - if (sign) PUT(sign); - PUT(*s++); - if (prec || alt) PUT('.'); - while (--prec >= 0) { - if ((c = *s)) { - s++; - } else { - c = '0'; - } - PUT(c); - } - __fmt_free_dtoa(&mem); - PUT(d); - if (decpt < 0) { - PUT('-'); - decpt = -decpt; - } else { - PUT('+'); - } - for (c = 2, k = 10; 10 * k <= decpt; c++) k *= 10; - for (;;) { - i1 = decpt / k; - PUT(i1 + '0'); - if (--c <= 0) break; - decpt -= i1 * k; - decpt *= 10; - } - while (--width >= 0) { - PUT(' '); - } - continue; - - case 'a': - alphabet = "0123456789abcdefpx"; - goto FormatBinary; - case 'A': - alphabet = "0123456789ABCDEFPX"; - FormatBinary: - if (longdouble) { - pun.d = va_arg(va, long double); - } else { - pun.d = va_arg(va, double); - } - if ((pun.u[1] & 0x7ff00000) == 0x7ff00000) { - goto FormatDtoa; - } - if (pun.u[1] & 0x80000000) { - sign = '-'; - pun.u[1] &= 0x7fffffff; - } - if (pun.d) { - c = '1'; - bex = (pun.u[1] >> 20) - 1023; - pun.u[1] &= 0xfffff; - if (bex == -1023) { - ++bex; - if (pun.u[1]) { - do { - --bex; - pun.u[1] <<= 1; - if (pun.u[0] & 0x80000000) pun.u[1] |= 1; - pun.u[0] <<= 1; - } while (pun.u[1] < 0x100000); - } else { - while (!(pun.u[0] & 0x80000000)) { - --bex; - pun.u[0] <<= 1; - } - bex -= 21; - pun.u[1] = pun.u[0] >> 11; - pun.u[0] <<= 21; - } - } - } else { - c = '0'; - bex = 0; - } - if (flags & FLAGS_PRECISION) { - if (prec > 13) prec = 13; - if (pun.d && prec < 13) { - pun.u[1] |= 0x100000; - if (prec < 5) { - ui = 1u << ((5 - prec) * 4 - 1); - if (pun.u[1] & ui) { - if (pun.u[1] & ((ui - 1) | (ui << 1)) || pun.u[0]) { - pun.u[1] += ui; - BexCheck: - if (pun.u[1] & 0x200000) { - ++bex; - pun.u[1] >>= 1; - } - } - } - } else if (prec == 5) { - if (pun.u[0] & 0x80000000) { - BumpIt: - ++pun.u[1]; - goto BexCheck; - } - } else { - i1 = (13 - prec) * 4; - ui = 1u << (i1 - 1); - if (pun.u[0] & ui && pun.u[0] & ((ui - 1) | (ui << 1))) { - pun.u[0] += ui; - if (!(pun.u[0] >> i1)) goto BumpIt; - } - } - } - } else { - if ((ui = pun.u[0])) { - ui = __builtin_ctz(ui); - prec = 6 + ((32 - ROUNDDOWN(ui, 4)) >> 2) - 1; - } else if ((ui = pun.u[1] & 0xfffff)) { - ui = __builtin_ctz(ui); - prec = (20 - ROUNDDOWN(ui, 4)) >> 2; - } else { - prec = 0; - } - } - bw = 1; - if (bex) { - if ((i1 = bex) < 0) i1 = -i1; - while (i1 >= 10) { - ++bw; - i1 /= 10; - } - } - if (pun.u[1] & 0x80000000) { - pun.u[1] &= 0x7fffffff; - if (pun.d || sign) sign = '-'; - } - if ((width -= bw + 5) > 0) { - if (sign) --width; - if (prec || alt) --width; - } - if (pun.q && prec > 0) { - width -= ROUNDUP(bsrl(pun.q) + 1, 4) >> 2; - } - if (width > 0 && !(flags & FLAGS_LEFT)) { - if (flags & FLAGS_ZEROPAD) { - if (sign) { - PUT(sign); - sign = 0; - } - do PUT('0'); - while (--width > 0); - } else { - do PUT(' '); - while (--width > 0); - } - } - if (sign) PUT(sign); - PUT('0'); - PUT(alphabet[17]); - PUT(c); - if (prec > 0 || alt) PUT('.'); - while (prec-- > 0) { - PUT(alphabet[(pun.q >> 48) & 0xf]); - pun.q <<= 4; - } - PUT(alphabet[16]); - if (bex < 0) { - PUT('-'); - bex = -bex; - } else { - PUT('+'); - } - for (c = 1; 10 * c <= bex;) c *= 10; - for (;;) { - i1 = bex / c; - PUT('0' + i1); - if (!--bw) break; - bex -= i1 * c; - bex *= 10; + if (weaken(__fmt_dtoa)(out, arg, d, flags, prec, sign, width, + longdouble, qchar, signbit, alphabet, + va) == -1) { + return -1; } break; - case '%': - PUT('%'); + __FMT_PUT('%'); break; - default: - PUT(format[-1]); + __FMT_PUT(format[-1]); break; } } - assert(!mem); return 0; } diff --git a/libc/fmt/fmts.h b/libc/fmt/fmt.internal.h similarity index 55% rename from libc/fmt/fmts.h rename to libc/fmt/fmt.internal.h index c56f88650..48f4662a7 100644 --- a/libc/fmt/fmts.h +++ b/libc/fmt/fmt.internal.h @@ -1,11 +1,19 @@ -#ifndef COSMOPOLITAN_LIBC_FMT_FMTS_H_ -#define COSMOPOLITAN_LIBC_FMT_FMTS_H_ +#ifndef COSMOPOLITAN_LIBC_FMT_FMT_INTERNAL_H_ +#define COSMOPOLITAN_LIBC_FMT_FMT_INTERNAL_H_ #define PRINTF_NTOA_BUFFER_SIZE 144 #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ +#define __FMT_PUT(C) \ + do { \ + char Buf[1] = {C}; \ + if (out(Buf, arg, 1) == -1) { \ + return -1; \ + } \ + } while (0) + int __fmt_pad(int (*)(const char *, void *, size_t), void *, unsigned long) hidden; int __fmt_stoa(int (*)(const char *, void *, size_t), void *, void *, @@ -14,8 +22,9 @@ int __fmt_stoa(int (*)(const char *, void *, size_t), void *, void *, int __fmt_ntoa(int (*)(const char *, void *, size_t), void *, va_list, unsigned char, unsigned long, unsigned long, unsigned long, unsigned char, const char *) hidden; -char *__fmt_dtoa(double, int, int, int *, int *, char **) hidden; +int __fmt_dtoa(int (*)(const char *, void *, size_t), void *, int, int, int, + int, int, bool, char, unsigned char, const char *, va_list); COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ -#endif /* COSMOPOLITAN_LIBC_FMT_FMTS_H_ */ +#endif /* COSMOPOLITAN_LIBC_FMT_FMT_INTERNAL_H_ */ diff --git a/libc/fmt/ntoa.c b/libc/fmt/ntoa.c index 3b788dbb0..c3d838e53 100644 --- a/libc/fmt/ntoa.c +++ b/libc/fmt/ntoa.c @@ -20,7 +20,7 @@ #include "libc/assert.h" #include "libc/fmt/conv.h" #include "libc/fmt/divmod10.internal.h" -#include "libc/fmt/fmts.h" +#include "libc/fmt/fmt.internal.h" #include "libc/fmt/internal.h" #include "libc/limits.h" diff --git a/libc/fmt/pad.c b/libc/fmt/pad.c index c489c745f..9a1eac704 100644 --- a/libc/fmt/pad.c +++ b/libc/fmt/pad.c @@ -16,7 +16,7 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/fmt/fmts.h" +#include "libc/fmt/fmt.internal.h" int __fmt_pad(int out(const char *, void *, size_t), void *arg, unsigned long n) { diff --git a/libc/fmt/pflink.h b/libc/fmt/pflink.h index e8c8be11f..4e7f2fb8b 100644 --- a/libc/fmt/pflink.h +++ b/libc/fmt/pflink.h @@ -1,7 +1,6 @@ #ifndef COSMOPOLITAN_LIBC_FMT_PFLINK_H_ #define COSMOPOLITAN_LIBC_FMT_PFLINK_H_ #include "libc/dce.h" -#include "libc/fmt/fmts.h" #include "libc/mem/mem.h" #include "libc/runtime/runtime.h" #include "libc/str/str.h" @@ -23,7 +22,6 @@ ({ \ if (___PFLINK(FMT, strpbrk, "faAeg")) STATIC_YOINK("__fmt_dtoa"); \ if (___PFLINK(FMT, strpbrk, "cmrqs")) { \ - if (___PFLINK(FMT, strchr, '#')) STATIC_YOINK("kCp437"); \ if (___PFLINK(FMT, strstr, "%m")) STATIC_YOINK("strerror"); \ if (!IsTiny() && (___PFLINK(FMT, strstr, "%*") || \ ___PFLINK(FMT, strpbrk, "0123456789"))) { \ diff --git a/libc/fmt/stoa.c b/libc/fmt/stoa.c index 239f49af7..f7efa15ac 100644 --- a/libc/fmt/stoa.c +++ b/libc/fmt/stoa.c @@ -20,7 +20,7 @@ #include "libc/bits/bits.h" #include "libc/bits/safemacros.internal.h" #include "libc/bits/weaken.h" -#include "libc/fmt/fmts.h" +#include "libc/fmt/fmt.internal.h" #include "libc/fmt/internal.h" #include "libc/nexgen32e/bsr.h" #include "libc/str/str.h" @@ -46,7 +46,7 @@ static int __fmt_stoa_wide(out_f out, void *a, uint64_t w) { static int __fmt_stoa_bing(out_f out, void *a, uint64_t w) { char buf[8]; - w = tpenc((*weaken(kCp437))[w & 0xFF]); + w = tpenc(kCp437[w & 0xFF]); WRITE64LE(buf, w); return out(buf, a, w ? (bsr(w) >> 3) + 1 : 1); } diff --git a/libc/nt/PowerProf/SetSuspendState.s b/libc/nt/PowrProf/SetSuspendState.s similarity index 78% rename from libc/nt/PowerProf/SetSuspendState.s rename to libc/nt/PowrProf/SetSuspendState.s index 1cc2efb42..51b532fa1 100644 --- a/libc/nt/PowerProf/SetSuspendState.s +++ b/libc/nt/PowrProf/SetSuspendState.s @@ -1,5 +1,5 @@ .include "o/libc/nt/codegen.inc" -.imp PowerProf,__imp_SetSuspendState,SetSuspendState,0 +.imp PowrProf,__imp_SetSuspendState,SetSuspendState,0 .text.windows SetSuspendState: diff --git a/libc/nt/master.sh b/libc/nt/master.sh index 582ae5adf..562cb3c3b 100755 --- a/libc/nt/master.sh +++ b/libc/nt/master.sh @@ -4052,10 +4052,10 @@ imp 'SetTcpEntry' SetTcpEntry iphlpapi 0 imp 'UnenableRouter' UnenableRouter iphlpapi 0 imp 'UnregisterInterfaceTimestampConfigChange' UnregisterInterfaceTimestampConfigChange iphlpapi 0 -# POWERPROF.DLL +# POWRPROF.DLL # # Name Actual DLL Hint Arity -imp 'SetSuspendState' SetSuspendState PowerProf 0 3 +imp 'SetSuspendState' SetSuspendState PowrProf 0 3 # PDH.DLL # diff --git a/libc/nt/nt.mk b/libc/nt/nt.mk index 4278107bd..67d25a6a4 100644 --- a/libc/nt/nt.mk +++ b/libc/nt/nt.mk @@ -311,22 +311,22 @@ $(LIBC_NT_IPHLPAPI_A).pkg: \ #─────────────────────────────────────────────────────────────────────────────── -LIBC_NT_ARTIFACTS += LIBC_NT_POWERPROF_A -LIBC_NT_POWERPROF = $(LIBC_NT_POWERPROF_A_DEPS) $(LIBC_NT_POWERPROF_A) -LIBC_NT_POWERPROF_A = o/$(MODE)/libc/nt/powerprof.a -LIBC_NT_POWERPROF_A_SRCS := $(wildcard libc/nt/PowerProf/*.s) -LIBC_NT_POWERPROF_A_OBJS = $(LIBC_NT_POWERPROF_A_SRCS:%.s=o/$(MODE)/%.o) -LIBC_NT_POWERPROF_A_CHECKS = $(LIBC_NT_POWERPROF_A).pkg -LIBC_NT_POWERPROF_A_DIRECTDEPS = LIBC_NT_KERNEL32 -LIBC_NT_POWERPROF_A_DEPS := \ - $(call uniq,$(foreach x,$(LIBC_NT_POWERPROF_A_DIRECTDEPS),$($(x)))) -$(LIBC_NT_POWERPROF_A): \ - libc/nt/PowerProf/ \ - $(LIBC_NT_POWERPROF_A).pkg \ - $(LIBC_NT_POWERPROF_A_OBJS) -$(LIBC_NT_POWERPROF_A).pkg: \ - $(LIBC_NT_POWERPROF_A_OBJS) \ - $(foreach x,$(LIBC_NT_POWERPROF_A_DIRECTDEPS),$($(x)_A).pkg) +LIBC_NT_ARTIFACTS += LIBC_NT_POWRPROF_A +LIBC_NT_POWRPROF = $(LIBC_NT_POWRPROF_A_DEPS) $(LIBC_NT_POWRPROF_A) +LIBC_NT_POWRPROF_A = o/$(MODE)/libc/nt/powrprof.a +LIBC_NT_POWRPROF_A_SRCS := $(wildcard libc/nt/PowrProf/*.s) +LIBC_NT_POWRPROF_A_OBJS = $(LIBC_NT_POWRPROF_A_SRCS:%.s=o/$(MODE)/%.o) +LIBC_NT_POWRPROF_A_CHECKS = $(LIBC_NT_POWRPROF_A).pkg +LIBC_NT_POWRPROF_A_DIRECTDEPS = LIBC_NT_KERNEL32 +LIBC_NT_POWRPROF_A_DEPS := \ + $(call uniq,$(foreach x,$(LIBC_NT_POWRPROF_A_DIRECTDEPS),$($(x)))) +$(LIBC_NT_POWRPROF_A): \ + libc/nt/PowrProf/ \ + $(LIBC_NT_POWRPROF_A).pkg \ + $(LIBC_NT_POWRPROF_A_OBJS) +$(LIBC_NT_POWRPROF_A).pkg: \ + $(LIBC_NT_POWRPROF_A_OBJS) \ + $(foreach x,$(LIBC_NT_POWRPROF_A_DIRECTDEPS),$($(x)_A).pkg) #─────────────────────────────────────────────────────────────────────────────── diff --git a/libc/stdio/dtoa.c b/libc/stdio/dtoa.c index f58202db5..6919d56a6 100644 --- a/libc/stdio/dtoa.c +++ b/libc/stdio/dtoa.c @@ -1,7 +1,7 @@ /*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ │vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ ╞══════════════════════════════════════════════════════════════════════════════╡ -│ Copyright 2021 Justine Alexandra Roberts Tunney │ +│ Copyright 2022 Justine Alexandra Roberts Tunney │ │ │ │ Permission to use, copy, modify, and/or distribute this software for │ │ any purpose with or without fee is hereby granted, provided that the │ @@ -16,10 +16,379 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/fmt/fmts.h" +#include "libc/assert.h" +#include "libc/fmt/fmt.h" +#include "libc/fmt/fmt.internal.h" +#include "libc/fmt/internal.h" +#include "libc/macros.internal.h" +#include "libc/nexgen32e/bsr.h" #include "third_party/gdtoa/gdtoa.h" -char *__fmt_dtoa(double d0, int mode, int ndigits, int *decpt, int *sign, - char **rve) { - return dtoa(d0, mode, ndigits, decpt, sign, rve); +static const char kSpecialFloats[2][2][4] = {{"INF", "inf"}, {"NAN", "nan"}}; + +static void __fmt_free_dtoa(char **mem) { + if (*mem) { + freedtoa(*mem); + *mem = 0; + } +} + +int __fmt_dtoa(int (*out)(const char *, void *, size_t), void *arg, int d, + int flags, int prec, int sign, int width, bool longdouble, + char qchar, unsigned char signbit, const char *alphabet, + va_list va) { + union { + double d; + uint32_t u[2]; + uint64_t q; + } pun; + int c, k, i1, ui, bw, bex, sgn, prec1, decpt; + char *s, *p, *q, *se, *mem, special[8]; + mem = 0; + switch (d) { + case 'F': + case 'f': + if (!(flags & FLAGS_PRECISION)) prec = 6; + if (longdouble) { + pun.d = va_arg(va, long double); + } else { + pun.d = va_arg(va, double); + } + FormatDtoa: + assert(!mem); + s = mem = dtoa(pun.d, 3, prec, &decpt, &sgn, &se); + if (decpt == 9999) { + Format9999: + bzero(special, sizeof(special)); + p = q = special; + if (sgn) { + *q++ = '-'; + } else if (flags & FLAGS_PLUS) { + *q++ = '+'; + } else if (flags & FLAGS_SPACE) { + *q++ = ' '; + } + memcpy(q, kSpecialFloats[*s == 'N'][d >= 'a'], 4); + FormatThatThing: + __fmt_free_dtoa(&mem); + mem = 0; + prec = 0; + flags &= ~(FLAGS_PRECISION | FLAGS_PLUS | FLAGS_SPACE); + goto FormatString; + } + FormatReal: + if (sgn) sign = '-'; + if (prec > 0) width -= prec; + if (width > 0) { + if (sign) --width; + if (decpt <= 0) { + --width; + if (prec > 0) --width; + } else { + if (s == se) decpt = 1; + width -= decpt; + if (prec > 0) --width; + } + } + if (width > 0 && !(flags & FLAGS_LEFT)) { + if (flags & FLAGS_ZEROPAD) { + if (sign) __FMT_PUT(sign); + sign = 0; + do + __FMT_PUT('0'); + while (--width > 0); + } else { + do + __FMT_PUT(' '); + while (--width > 0); + } + } + if (sign) __FMT_PUT(sign); + if (decpt <= 0) { + __FMT_PUT('0'); + if (prec > 0) __FMT_PUT('.'); + while (decpt < 0) { + __FMT_PUT('0'); + prec--; + decpt++; + } + } else { + do { + if ((c = *s)) { + s++; + } else { + c = '0'; + } + __FMT_PUT(c); + } while (--decpt > 0); + if (prec > 0) __FMT_PUT('.'); + } + while (--prec >= 0) { + if ((c = *s)) { + s++; + } else { + c = '0'; + } + __FMT_PUT(c); + } + while (--width >= 0) { + __FMT_PUT(' '); + } + __fmt_free_dtoa(&mem); + break; + + case 'G': + case 'g': + if (!(flags & FLAGS_PRECISION)) prec = 6; + if (longdouble) { + pun.d = va_arg(va, long double); + } else { + pun.d = va_arg(va, double); + } + if (prec < 0) prec = 0; + assert(!mem); + s = mem = dtoa(pun.d, prec ? 2 : 0, prec, &decpt, &sgn, &se); + if (decpt == 9999) goto Format9999; + c = se - s; + prec1 = prec; + if (!prec) { + prec = c; + prec1 = c + (s[1] ? 5 : 4); + } + if (decpt > -4 && decpt <= prec1) { + prec = c - decpt; + if (prec < 0) prec = 0; + goto FormatReal; + } + d -= 2; + if (prec > c) prec = c; + --prec; + goto FormatExpo; + + case 'e': + case 'E': + if (!(flags & FLAGS_PRECISION)) prec = 6; + if (longdouble) { + pun.d = va_arg(va, long double); + } else { + pun.d = va_arg(va, double); + } + if (prec < 0) prec = 0; + if (!dtoa) { + p = "?"; + goto FormatThatThing; + } + assert(!mem); + s = mem = dtoa(pun.d, 2, prec + 1, &decpt, &sgn, &se); + if (decpt == 9999) goto Format9999; + FormatExpo: + if (sgn) sign = '-'; + if ((width -= prec + 5) > 0) { + if (sign) --width; + if (prec) --width; + } + if ((c = --decpt) < 0) c = -c; + while (c >= 100) { + --width; + c /= 10; + } + if (width > 0 && !(flags & FLAGS_LEFT)) { + if (flags & FLAGS_ZEROPAD) { + if (sign) __FMT_PUT(sign); + sign = 0; + do + __FMT_PUT('0'); + while (--width > 0); + } else { + do + __FMT_PUT(' '); + while (--width > 0); + } + } + if (sign) __FMT_PUT(sign); + __FMT_PUT(*s++); + if (prec) __FMT_PUT('.'); + while (--prec >= 0) { + if ((c = *s)) { + s++; + } else { + c = '0'; + } + __FMT_PUT(c); + } + __fmt_free_dtoa(&mem); + __FMT_PUT(d); + if (decpt < 0) { + __FMT_PUT('-'); + decpt = -decpt; + } else { + __FMT_PUT('+'); + } + for (c = 2, k = 10; 10 * k <= decpt; c++) k *= 10; + for (;;) { + i1 = decpt / k; + __FMT_PUT(i1 + '0'); + if (--c <= 0) break; + decpt -= i1 * k; + decpt *= 10; + } + while (--width >= 0) { + __FMT_PUT(' '); + } + break; + + case 'a': + alphabet = "0123456789abcdefpx"; + goto FormatBinary; + case 'A': + alphabet = "0123456789ABCDEFPX"; + FormatBinary: + if (longdouble) { + pun.d = va_arg(va, long double); + } else { + pun.d = va_arg(va, double); + } + if ((pun.u[1] & 0x7ff00000) == 0x7ff00000) { + goto FormatDtoa; + } + if (pun.u[1] & 0x80000000) { + sign = '-'; + pun.u[1] &= 0x7fffffff; + } + if (pun.d) { + c = '1'; + bex = (pun.u[1] >> 20) - 1023; + pun.u[1] &= 0xfffff; + if (bex == -1023) { + ++bex; + if (pun.u[1]) { + do { + --bex; + pun.u[1] <<= 1; + if (pun.u[0] & 0x80000000) pun.u[1] |= 1; + pun.u[0] <<= 1; + } while (pun.u[1] < 0x100000); + } else { + while (!(pun.u[0] & 0x80000000)) { + --bex; + pun.u[0] <<= 1; + } + bex -= 21; + pun.u[1] = pun.u[0] >> 11; + pun.u[0] <<= 21; + } + } + } else { + c = '0'; + bex = 0; + } + if (flags & FLAGS_PRECISION) { + if (prec > 13) prec = 13; + if (pun.d && prec < 13) { + pun.u[1] |= 0x100000; + if (prec < 5) { + ui = 1u << ((5 - prec) * 4 - 1); + if (pun.u[1] & ui) { + if (pun.u[1] & ((ui - 1) | (ui << 1)) || pun.u[0]) { + pun.u[1] += ui; + BexCheck: + if (pun.u[1] & 0x200000) { + ++bex; + pun.u[1] >>= 1; + } + } + } + } else if (prec == 5) { + if (pun.u[0] & 0x80000000) { + BumpIt: + ++pun.u[1]; + goto BexCheck; + } + } else { + i1 = (13 - prec) * 4; + ui = 1u << (i1 - 1); + if (pun.u[0] & ui && pun.u[0] & ((ui - 1) | (ui << 1))) { + pun.u[0] += ui; + if (!(pun.u[0] >> i1)) goto BumpIt; + } + } + } + } else { + if ((ui = pun.u[0])) { + ui = __builtin_ctz(ui); + prec = 6 + ((32 - ROUNDDOWN(ui, 4)) >> 2) - 1; + } else if ((ui = pun.u[1] & 0xfffff)) { + ui = __builtin_ctz(ui); + prec = (20 - ROUNDDOWN(ui, 4)) >> 2; + } else { + prec = 0; + } + } + bw = 1; + if (bex) { + if ((i1 = bex) < 0) i1 = -i1; + while (i1 >= 10) { + ++bw; + i1 /= 10; + } + } + if (pun.u[1] & 0x80000000) { + pun.u[1] &= 0x7fffffff; + if (pun.d || sign) sign = '-'; + } + if ((width -= bw + 5) > 0) { + if (sign) --width; + if (prec) --width; + } + if (pun.q && prec > 0) { + width -= ROUNDUP(bsrl(pun.q) + 1, 4) >> 2; + } + if (width > 0 && !(flags & FLAGS_LEFT)) { + if (flags & FLAGS_ZEROPAD) { + if (sign) { + __FMT_PUT(sign); + sign = 0; + } + do + __FMT_PUT('0'); + while (--width > 0); + } else { + do + __FMT_PUT(' '); + while (--width > 0); + } + } + if (sign) __FMT_PUT(sign); + __FMT_PUT('0'); + __FMT_PUT(alphabet[17]); + __FMT_PUT(c); + if (prec > 0) __FMT_PUT('.'); + while (prec-- > 0) { + __FMT_PUT(alphabet[(pun.q >> 48) & 0xf]); + pun.q <<= 4; + } + __FMT_PUT(alphabet[16]); + if (bex < 0) { + __FMT_PUT('-'); + bex = -bex; + } else { + __FMT_PUT('+'); + } + for (c = 1; 10 * c <= bex;) c *= 10; + for (;;) { + i1 = bex / c; + __FMT_PUT('0' + i1); + if (!--bw) break; + bex -= i1 * c; + bex *= 10; + } + break; + + FormatString: + if (__fmt_stoa(out, arg, p, flags, prec, width, signbit, qchar) == -1) { + return -1; + } + break; + } + return 0; } diff --git a/third_party/lua/lapi.c b/third_party/lua/lapi.c index 5948a72d9..ae3212cb9 100644 --- a/third_party/lua/lapi.c +++ b/third_party/lua/lapi.c @@ -1001,6 +1001,15 @@ LUA_API void lua_setfield (lua_State *L, int idx, const char *k) { } +/** + * lua_seti [-1, +0, e] + * + * Does the equivalent to t[n] = v, where t is the value at the given index + * and v is the value on the top of the stack. + * + * This function pops the value from the stack. As in Lua, this function may + * trigger a metamethod for the "newindex" event (see §2.4). + */ LUA_API void lua_seti (lua_State *L, int idx, lua_Integer n) { TValue *t; const TValue *slot; @@ -1033,11 +1042,27 @@ static void aux_rawset (lua_State *L, int idx, TValue *key, int n) { } +/** + * lua_rawset [-2, +0, m] + * + * Similar to lua_settable, but does a raw assignment (i.e., without + * metamethods). + */ LUA_API void lua_rawset (lua_State *L, int idx) { aux_rawset(L, idx, s2v(L->top - 2), 2); } +/** + * lua_rawsetp [-1, +0, m] + * + * Does the equivalent of t[p] = v, where t is the table at the given index, + * p is encoded as a light userdata, and v is the value on the top of the + * stack. + * + * This function pops the value from the stack. The assignment is raw, that + * is, it does not use the __newindex metavalue. + */ LUA_API void lua_rawsetp (lua_State *L, int idx, const void *p) { TValue k; setpvalue(&k, cast_voidp(p)); @@ -1045,6 +1070,15 @@ LUA_API void lua_rawsetp (lua_State *L, int idx, const void *p) { } +/** + * lua_rawseti [-1, +0, m] + * + * Does the equivalent of t[i] = v, where t is the table at the given index + * and v is the value on the top of the stack. + * + * This function pops the value from the stack. The assignment is raw, that + * is, it does not use the __newindex metavalue. + */ LUA_API void lua_rawseti (lua_State *L, int idx, lua_Integer n) { Table *t; lua_lock(L); diff --git a/third_party/lua/llimits.h b/third_party/lua/llimits.h index e4a82be97..babd88ae2 100644 --- a/third_party/lua/llimits.h +++ b/third_party/lua/llimits.h @@ -86,7 +86,6 @@ typedef LUAI_UACINT l_uacInt; */ #if defined LUAI_ASSERT #undef NDEBUG -#include #define lua_assert(c) assert(c) #endif diff --git a/tool/build/jail.c b/tool/build/jail.c index 82fde2a88..f744decaa 100644 --- a/tool/build/jail.c +++ b/tool/build/jail.c @@ -45,6 +45,7 @@ static const struct sock_filter kSandboxFilter[] = { _SECCOMP_ALLOW_SYSCALL(0x008), // lseek _SECCOMP_ALLOW_SYSCALL(0x009), // mmap _SECCOMP_ALLOW_SYSCALL(0x00b), // munmap + _SECCOMP_ALLOW_SYSCALL(0x04f), // getcwd _SECCOMP_ALLOW_SYSCALL(0x003), // close _SECCOMP_ALLOW_SYSCALL(0x010), // ioctl todo _SECCOMP_ALLOW_SYSCALL(0x016), // pipe @@ -60,6 +61,15 @@ static const struct sock_filter kSandboxFilter[] = { _SECCOMP_ALLOW_SYSCALL(0x127), // preadv _SECCOMP_ALLOW_SYSCALL(0x128), // pwritev _SECCOMP_ALLOW_SYSCALL(0x0d9), // getdents + _SECCOMP_ALLOW_SYSCALL(0x027), // getpid + _SECCOMP_ALLOW_SYSCALL(0x066), // getuid + _SECCOMP_ALLOW_SYSCALL(0x068), // getgid + _SECCOMP_ALLOW_SYSCALL(0x06e), // getppid + _SECCOMP_ALLOW_SYSCALL(0x06f), // getpgrp + _SECCOMP_ALLOW_SYSCALL(0x07c), // getsid + _SECCOMP_ALLOW_SYSCALL(0x06b), // geteuid + _SECCOMP_ALLOW_SYSCALL(0x06c), // getegid + _SECCOMP_ALLOW_SYSCALL(0x061), // getrlimit _SECCOMP_ALLOW_SYSCALL(0x028), // sendfile _SECCOMP_ALLOW_SYSCALL(0x02d), // recvfrom _SECCOMP_ALLOW_SYSCALL(0x033), // getsockname @@ -67,7 +77,6 @@ static const struct sock_filter kSandboxFilter[] = { _SECCOMP_ALLOW_SYSCALL(0x00f), // rt_sigreturn _SECCOMP_ALLOW_SYSCALL(0x0e4), // clock_gettime _SECCOMP_ALLOW_SYSCALL(0x060), // gettimeofday - _SECCOMP_ALLOW_SYSCALL(0x027), // getpid _SECCOMP_ALLOW_SYSCALL(0x03f), // uname _SECCOMP_ALLOW_SYSCALL(0x03c), // exit _SECCOMP_ALLOW_SYSCALL(0x0e7), // exit_group diff --git a/tool/net/demo/unix-info.lua b/tool/net/demo/unix-info.lua new file mode 100644 index 000000000..17b2bec87 --- /dev/null +++ b/tool/net/demo/unix-info.lua @@ -0,0 +1,80 @@ +local unix = require 'unix' + +Write('\r\n') +Write('redbean\r\n') +Write('

UNIX Information Demo

\r\n') + +Write('
\r\n') +Write('
getuid()\r\n') +Write(string.format('
%d\r\n', unix.getuid())) +Write('
getgid()\r\n') +Write(string.format('
%d\r\n', unix.getgid())) +Write('
getpid()\r\n') +Write(string.format('
%d\r\n', unix.getpid())) +Write('
getppid()\r\n') +Write(string.format('
%d\r\n', unix.getppid())) +Write('
getpgrp()\r\n') +Write(string.format('
%d\r\n', unix.getpgrp())) + +Write('
getsid(0)\r\n') +sid, errno = unix.getsid(0) +if sid then + Write(string.format('
%d\r\n', sid)) +else + Write(string.format('
%s\r\n', EscapeHtml(unix.strerrno(errno)))) +end + +Write('
gethostname()\r\n') +Write(string.format('
%s\r\n', EscapeHtml(unix.gethostname()))) +Write('
getcwd()\r\n') +Write(string.format('
%s\r\n', EscapeHtml(unix.getcwd()))) + +function PrintResourceLimit(name, id) + soft, hard, errno = unix.getrlimit(id) + Write(string.format('
getrlimit(%s)\r\n', name)) + if soft then + Write('
') + Write('soft ') + if soft == -1 then + Write('∞') + else + Write(string.format('%d', soft)) + end + Write('
\r\n') + Write('hard ') + if hard == -1 then + Write('∞') + else + Write(string.format('%d', hard)) + end + Write('\r\n') + else + Write(string.format('
%s\r\n', EscapeHtml(unix.strerrno(errno)))) + end +end +PrintResourceLimit('RLIMIT_AS', unix.RLIMIT_AS) +PrintResourceLimit('RLIMIT_RSS', unix.RLIMIT_RSS) +PrintResourceLimit('RLIMIT_CPU', unix.RLIMIT_CPU) +PrintResourceLimit('RLIMIT_FSIZE', unix.RLIMIT_FSIZE) +PrintResourceLimit('RLIMIT_NPROC', unix.RLIMIT_NPROC) +PrintResourceLimit('RLIMIT_NOFILE', unix.RLIMIT_NOFILE) + +Write('
siocgifconf()\r\n') +Write('
\r\n') +ifs, errno = unix.siocgifconf() +if ifs then + for i = 1,#ifs do + if ifs[i].netmask ~= 0 then + cidr = 32 - Bsf(ifs[i].netmask) + else + cidr = 0 + end + Write(string.format('%s %s/%d
\r\n', + EscapeHtml(ifs[i].name), + FormatIp(ifs[i].ip), + cidr)) + end +else + Write(string.format('%s\r\n', EscapeHtml(unix.strerrno(errno)))) +end +Write('
\r\n') diff --git a/tool/net/demo/unix.lua b/tool/net/demo/unix-rawsocket.lua similarity index 100% rename from tool/net/demo/unix.lua rename to tool/net/demo/unix-rawsocket.lua diff --git a/tool/net/demo/unix-subprocess.lua b/tool/net/demo/unix-subprocess.lua new file mode 100644 index 000000000..71c9e9576 --- /dev/null +++ b/tool/net/demo/unix-subprocess.lua @@ -0,0 +1,44 @@ +-- example of how to run the ls command +-- and pipe its output to the http user +local unix = require "unix" +function main() + syscall = 'commandv' + ls, errno = unix.commandv("ls") + if ls then + syscall = 'pipe' + reader, writer, errno = unix.pipe() + if reader then + syscall = 'fork' + child, errno = unix.fork() + if child then + if child == 0 then + unix.close(1) + unix.dup(writer) + unix.close(writer) + unix.close(reader) + unix.execve(ls, {ls, "-Shal"}) + unix.exit(127) + else + unix.close(writer) + SetStatus(200) + SetHeader('Content-Type', 'text/plain') + while true do + data = unix.read(reader) + if data ~= "" then + Write(data) + else + break + end + end + unix.close(reader) + unix.wait(-1) + return + end + end + end + end + SetStatus(200) + SetHeader('Content-Type', 'text/plain') + Write(string.format('error %s calling %s()', unix.strerrno(errno), syscall)) +end +main() diff --git a/tool/net/demo/unix2.lua b/tool/net/demo/unix2.lua deleted file mode 100644 index de95a2bca..000000000 --- a/tool/net/demo/unix2.lua +++ /dev/null @@ -1,26 +0,0 @@ --- example of how to run the ls command --- and pipe its output to the http user -local unix = require "unix" -ls = unix.commandv("ls") -reader, writer = unix.pipe() -if unix.fork() == 0 then - unix.close(1) - unix.dup(writer) - unix.close(writer) - unix.close(reader) - unix.execve(ls, {ls, "-Shal"}) - unix.exit(127) -else - unix.close(writer) - SetHeader('Content-Type', 'text/plain') - while true do - data = unix.read(reader) - if data ~= "" then - Write(data) - else - break - end - end - unix.close(reader) - unix.wait(-1) -end diff --git a/tool/net/echo.c b/tool/net/echo.c index 109464f43..a1e36161c 100644 --- a/tool/net/echo.c +++ b/tool/net/echo.c @@ -47,15 +47,16 @@ void PrintUsage(char **argv) { } void UdpServer(void) { + int ip; ssize_t rc; struct sockaddr_in addr2; uint32_t addrsize2 = sizeof(struct sockaddr_in); CHECK_NE(-1, (sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))); CHECK_NE(-1, bind(sock, &addr, addrsize)); CHECK_NE(-1, getsockname(sock, &addr2, &addrsize2)); - kprintf("udp server %hhu.%hhu.%hhu.%hhu %hu%n", addr2.sin_addr.s_addr >> 24, - addr2.sin_addr.s_addr >> 16, addr2.sin_addr.s_addr >> 8, - addr2.sin_addr.s_addr, addr2.sin_port); + ip = ntohl(addr2.sin_addr.s_addr); + kprintf("udp server %hhu.%hhu.%hhu.%hhu %hu%n", ip >> 24, ip >> 16, ip >> 8, + ip, ntohs(addr2.sin_port)); for (;;) { CHECK_NE(-1, (rc = recvfrom(sock, buf, sizeof(buf), 0, &addr2, &addrsize2))); @@ -73,23 +74,23 @@ void UdpClient(void) { } void TcpServer(void) { - int client; ssize_t rc; + int ip, client; struct sockaddr_in addr2; uint32_t addrsize2 = sizeof(struct sockaddr_in); CHECK_NE(-1, (sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP))); CHECK_NE(-1, bind(sock, &addr, addrsize)); CHECK_NE(-1, listen(sock, 10)); CHECK_NE(-1, getsockname(sock, &addr2, &addrsize2)); - kprintf("tcp server %hhu.%hhu.%hhu.%hhu %hu%n", addr2.sin_addr.s_addr >> 24, - addr2.sin_addr.s_addr >> 16, addr2.sin_addr.s_addr >> 8, - addr2.sin_addr.s_addr, addr2.sin_port); + ip = ntohl(addr2.sin_addr.s_addr); + kprintf("tcp server %hhu.%hhu.%hhu.%hhu %hu%n", ip >> 24, ip >> 16, ip >> 8, + ip, ntohs(addr2.sin_port)); for (;;) { addrsize2 = sizeof(struct sockaddr_in); CHECK_NE(-1, (client = accept(sock, &addr2, &addrsize2))); - kprintf("got client %hhu.%hhu.%hhu.%hhu %hu%n", addr2.sin_addr.s_addr >> 24, - addr2.sin_addr.s_addr >> 16, addr2.sin_addr.s_addr >> 8, - addr2.sin_addr.s_addr, addr2.sin_port); + ip = ntohl(addr2.sin_addr.s_addr); + kprintf("got client %hhu.%hhu.%hhu.%hhu %hu%n", ip >> 24, ip >> 16, ip >> 8, + ip, ntohs(addr2.sin_port)); for (;;) { CHECK_NE(-1, (rc = read(client, buf, sizeof(buf)))); if (!rc) break; diff --git a/tool/net/help.txt b/tool/net/help.txt index e3a45e91d..72830b9b0 100644 --- a/tool/net/help.txt +++ b/tool/net/help.txt @@ -1440,7 +1440,7 @@ UNIX MODULE end end unix.close(reader) - unix.wait(-1) + unix.wait() end unix.wait([pid:int, options:int]) @@ -1705,6 +1705,28 @@ UNIX MODULE Further note that calling `unix.bind(sock)` is equivalent to not calling bind() at all, since the above behavior is the default. + unix.siocgifconf() → {{name:str,ip:uint32,netmask:uint32}, ...}[, errno:int] + + Returns list of network adapter addresses. + + unix.poll({fd:int=events:int, ...}[, timeoutms:int]) + → {fd:int=revents:int, ...}[, errno:int] + + Checks for events on a set of file descriptors. + + The table of file descriptors to poll uses sparse integer keys. Any + pairs with non-integer keys will be ignored. Pairs with negative + keys are ignored by poll(). The returned table will be a subset of + the supplied file descriptors. + + `timeoutms` is the number of seconds to block. If this is set to -1 + then that means block as long as it takes until there's an event or + an interrupt. If the timeout expires, an empty table is returned. + + unix.gethostname() → host:str[, errno:int] + + Returns hostname of system. + unix.listen(fd:int[, backlog]) → rc:int[, errno:int] Begins listening for incoming connections on a socket. @@ -1802,20 +1824,6 @@ UNIX MODULE unix.sigaction(unix.SIGALRM, MyOnSigAlrm, unix.SA_RESETHAND) unix.setitimer(unix.ITIMER_REAL, 0, 0, 1, 0) - unix.reboot(how:int) → str - - Changes power status of system. - - `how` may be `RB_AUTOBOOT` to reboot, `RB_POWER_OFF` to power - down, `RB_HALT_SYSTEM` to literally just stop the processor, or - `RB_SW_SUSPEND` to put the machine into a suspend state. These - magnums will be set to -1 if the method isn't supported on the - host platform. - - By default, an implicit sync() is performed. That's to help - prevent you from losing data. If you don't want to shutdown - gracefully, then you can bitwise or `RB_NOSYNC` into `how`. - unix.strerrno(errno:int) → str Turns `errno` code into its symbolic name, e.g. `"EINTR"`. @@ -1829,6 +1837,41 @@ UNIX MODULE Turns platform-specific `sig` code into its name, e.g. `strsignal(9)` always returns `"SIGKILL"`. + unix.setrlimit(resource:int, soft:int[, hard:int]) → rc:int[, errno:int] + + Changes resource limit. + + `resource` may be one of: + + - `RLIMIT_AS` limits the size of the virtual address space. This + will work on all platforms. It's emulated on XNU and Windows which + means it won't propagate across execve() currently. + + - `RLIMIT_CPU` causes `SIGXCPU` to be sent to the process when the + soft limit on CPU time is exceeded, and the process is destroyed + when the hard limit is exceeded. It works everywhere but Windows + where it should be possible to poll getrusage() with setitimer() + + - `RLIMIT_FSIZE` causes `SIGXFSZ` to sent to the process when the + soft limit on file size is exceeded and the process is destroyed + when the hard limit is exceeded. It works everywhere but Windows + + - `RLIMIT_NPROC` limits the number of simultaneous processes and it + should work on all platforms except Windows. Please be advised it + limits the process, with respect to the activities of the user id + as a whole. + + - `RLIMIT_NOFILE` limits the number of open file descriptors and it + should work on all platforms except Windows (TODO) + + If a limit isn't supported by the host platform, it'll be set to + 127. On most platforms these limits are enforced by the kernel and + as such are inherited by subprocesses. + + unix.getrlimit(resource:int) → soft:int, hard:int[, errno:int] + + Returns information about resource limit. + unix.stat(x) → UnixStat*, errno:int Gets information about file or directory. `x` may be a file or diff --git a/tool/net/lunix.c b/tool/net/lunix.c index 0a3a758c2..9c8a15f14 100644 --- a/tool/net/lunix.c +++ b/tool/net/lunix.c @@ -18,6 +18,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/assert.h" #include "libc/calls/calls.h" +#include "libc/calls/ioctl.h" #include "libc/calls/sigbits.h" #include "libc/calls/strace.internal.h" #include "libc/calls/struct/dirent.h" @@ -27,6 +28,7 @@ #include "libc/calls/struct/stat.h" #include "libc/calls/struct/timespec.h" #include "libc/calls/ucontext.h" +#include "libc/dns/dns.h" #include "libc/errno.h" #include "libc/fmt/fmt.h" #include "libc/fmt/kerrornames.internal.h" @@ -52,13 +54,15 @@ #include "libc/sysv/consts/nr.h" #include "libc/sysv/consts/o.h" #include "libc/sysv/consts/ok.h" -#include "libc/sysv/consts/reboot.h" +#include "libc/sysv/consts/rlim.h" #include "libc/sysv/consts/rlimit.h" #include "libc/sysv/consts/sa.h" #include "libc/sysv/consts/shut.h" #include "libc/sysv/consts/sig.h" +#include "libc/sysv/consts/sio.h" #include "libc/sysv/consts/sock.h" #include "libc/sysv/consts/w.h" +#include "libc/sysv/errfuns.h" #include "libc/time/time.h" #include "libc/x/x.h" #include "third_party/lua/lauxlib.h" @@ -104,14 +108,6 @@ static dontinline int ReturnTimespec(lua_State *L, struct timespec *ts) { return 2; } -static int ReturnRc(lua_State *L, int64_t rc, int olderr) { - lua_pushinteger(L, rc); - if (rc != -1) return 1; - lua_pushinteger(L, errno); - errno = olderr; - return 2; -} - static int ReturnErrno(lua_State *L, int nils, int olderr) { int i; for (i = 0; i < nils; ++i) { @@ -122,6 +118,15 @@ static int ReturnErrno(lua_State *L, int nils, int olderr) { return nils + 1; } +static int ReturnRc(lua_State *L, int64_t rc, int olderr) { + if (rc != -1) { + lua_pushinteger(L, rc); + return 1; + } else { + return ReturnErrno(L, 1, olderr); + } +} + static char **ConvertLuaArrayToStringList(lua_State *L, int i) { int j, n; char **p; @@ -146,7 +151,7 @@ static char **ConvertLuaTableToEnvList(lua_State *L, int i) { lua_pushnil(L); for (n = 0; lua_next(L, i);) { if (lua_type(L, -2) == LUA_TSTRING) { - p = xrealloc(p, (++n + 1) * sizeof(char *)); + p = xrealloc(p, (++n + 1) * sizeof(*p)); p[n - 1] = xasprintf("%s=%s", lua_tostring(L, -2), lua_tostring(L, -1)); } lua_pop(L, 1); @@ -322,12 +327,16 @@ static int LuaUnixChmod(lua_State *L) { // unix.getcwd(path:str, mode:int) → rc:int[, errno:int] static int LuaUnixGetcwd(lua_State *L) { + int olderr; char *path; - path = getcwd(0, 0); - assert(path); - lua_pushstring(L, path); - free(path); - return 1; + olderr = errno; + if ((path = getcwd(0, 0))) { + lua_pushstring(L, path); + free(path); + return 1; + } else { + return ReturnErrno(L, 1, olderr); + } } // unix.fork() → childpid|0:int[, errno:int] @@ -374,9 +383,7 @@ static int LuaUnixExecve(lua_State *L) { execve(prog, argv, envp); FreeStringList(freeme1); FreeStringList(freeme2); - lua_pushinteger(L, errno); - errno = olderr; - return 1; + return ReturnErrno(L, 1, olderr); } // unix.commandv(prog:str) → path:str[, errno:int] @@ -450,8 +457,8 @@ static int LuaUnixGetrlimit(lua_State *L) { olderr = errno; resource = luaL_checkinteger(L, 1); if (!getrlimit(resource, &rlim)) { - lua_pushinteger(L, rlim.rlim_cur); - lua_pushinteger(L, rlim.rlim_max); + lua_pushinteger(L, rlim.rlim_cur < RLIM_INFINITY ? rlim.rlim_cur : -1); + lua_pushinteger(L, rlim.rlim_max < RLIM_INFINITY ? rlim.rlim_max : -1); return 2; } else { return ReturnErrno(L, 2, olderr); @@ -931,7 +938,7 @@ static int LuaUnixGetsockname(lua_State *L) { } } -// unix.getpeername(fd) → ip, port, errno +// unix.getpeername(fd:int) → ip:uint32, port:uint16[, errno:int] static int LuaUnixGetpeername(lua_State *L) { int fd, olderr; uint32_t addrsize; @@ -948,7 +955,72 @@ static int LuaUnixGetpeername(lua_State *L) { } } -// unix.accept(serverfd:int) → clientfd:int, ip:uint32, port:uint16, errno +// unix.siocgifconf() → {{name:str,ip:uint32,netmask:uint32}, ...}[, errno:int] +static int LuaUnixSiocgifconf(lua_State *L) { + size_t n; + char *data; + int i, fd, olderr; + struct ifreq *ifr; + struct ifconf conf; + olderr = errno; + if (!(data = malloc((n = 4096)))) { + return ReturnErrno(L, 1, olderr); + } + if ((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) { + free(data); + return ReturnErrno(L, 1, olderr); + } + conf.ifc_buf = data; + conf.ifc_len = n; + if (ioctl(fd, SIOCGIFCONF, &conf) == -1) { + close(fd); + free(data); + return ReturnErrno(L, 1, olderr); + } + lua_newtable(L); + i = 0; + for (ifr = (struct ifreq *)data; (char *)ifr < data + conf.ifc_len; ++ifr) { + if (ifr->ifr_addr.sa_family != AF_INET) continue; + lua_createtable(L, 0, 3); + lua_pushstring(L, "name"); + lua_pushstring(L, ifr->ifr_name); + lua_settable(L, -3); + lua_pushstring(L, "ip"); + lua_pushinteger( + L, ntohl(((struct sockaddr_in *)&ifr->ifr_addr)->sin_addr.s_addr)); + lua_settable(L, -3); + if (ioctl(fd, SIOCGIFNETMASK, ifr) != -1) { + lua_pushstring(L, "netmask"); + lua_pushinteger( + L, ntohl(((struct sockaddr_in *)&ifr->ifr_addr)->sin_addr.s_addr)); + lua_settable(L, -3); + } + lua_rawseti(L, -2, ++i); + } + close(fd); + free(data); + return 1; +} + +// unix.gethostname() → host:str[, errno:int] +static int LuaUnixGethostname(lua_State *L) { + int rc, olderr; + char buf[DNS_NAME_MAX + 1]; + olderr = errno; + if ((rc = gethostname(buf, sizeof(buf))) != -1) { + if (strnlen(buf, sizeof(buf)) < sizeof(buf)) { + lua_pushstring(L, buf); + return 1; + } else { + enomem(); + return ReturnErrno(L, 1, olderr); + } + } else { + return ReturnErrno(L, 1, olderr); + } +} + +// unix.accept(serverfd:int) → clientfd:int, ip:uint32, port:uint16[, errno:int] static int LuaUnixAccept(lua_State *L) { uint32_t addrsize; struct sockaddr_in sa; @@ -967,6 +1039,40 @@ static int LuaUnixAccept(lua_State *L) { } } +// unix.poll({fd:int=events:int, ...}[, timeoutms:int]) +// → {fd:int=revents:int, ...}[, errno:int] +static int LuaUnixPoll(lua_State *L) { + size_t nfds; + struct pollfd *fds; + int i, fd, olderr, events, timeoutms; + luaL_checktype(L, 1, LUA_TTABLE); + lua_pushnil(L); + for (fds = 0, nfds = 0; lua_next(L, 1);) { + if (lua_isinteger(L, -2)) { + fds = xrealloc(fds, ++nfds * sizeof(*fds)); + fds[nfds - 1].fd = lua_tointeger(L, -2); + fds[nfds - 1].events = lua_tointeger(L, -1); + } + lua_pop(L, 1); + } + timeoutms = luaL_optinteger(L, 2, -1); + olderr = errno; + if ((events = poll(fds, nfds, timeoutms)) != -1) { + lua_createtable(L, events, 0); + for (i = 0; i < nfds; ++i) { + if (fds[i].revents && fds[i].fd >= 0) { + lua_pushinteger(L, fds[i].revents); + lua_rawseti(L, -2, fds[i].fd); + } + } + free(fds); + return 1; + } else { + free(fds); + return ReturnErrno(L, 1, olderr); + } +} + // unix.recvfrom(fd[, bufsiz[, flags]]) → data, ip, port[, errno] // flags can have MSG_{WAITALL,DONTROUTE,PEEK,OOB}, etc. static int LuaUnixRecvfrom(lua_State *L) { @@ -1286,11 +1392,6 @@ static int LuaUnixWtermsig(lua_State *L) { return ReturnInteger(L, WTERMSIG(luaL_checkinteger(L, 1))); } -// unix.reboot(how:int) → rc:int[, errno:int] -static int LuaUnixReboot(lua_State *L) { - return ReturnInteger(L, reboot(luaL_checkinteger(L, 1))); -} - //////////////////////////////////////////////////////////////////////////////// // UnixStat* object @@ -1568,10 +1669,12 @@ static const luaL_Reg kLuaUnix[] = { {"setuid", LuaUnixSetuid}, // set real user id of process {"getgid", LuaUnixGetgid}, // get real group id of process {"setgid", LuaUnixSetgid}, // set real group id of process + {"gethostname", LuaUnixGethostname}, // get hostname of this machine {"clock_gettime", LuaUnixGettime}, // get timestamp w/ nano precision {"nanosleep", LuaUnixNanosleep}, // sleep w/ nano precision {"socket", LuaUnixSocket}, // create network communication fd {"socketpair", LuaUnixSocketpair}, // create bidirectional pipe + {"poll", LuaUnixPoll}, // waits for file descriptor events {"bind", LuaUnixBind}, // reserve network interface address {"listen", LuaUnixListen}, // begin listening for clients {"accept", LuaUnixAccept}, // create client fd for client @@ -1583,11 +1686,11 @@ static const luaL_Reg kLuaUnix[] = { {"shutdown", LuaUnixShutdown}, // make socket half empty or full {"getpeername", LuaUnixGetpeername}, // get address of remote end {"getsockname", LuaUnixGetsockname}, // get address of local end + {"siocgifconf", LuaUnixSiocgifconf}, // get list of network interfaces {"sigaction", LuaUnixSigaction}, // install signal handler {"sigprocmask", LuaUnixSigprocmask}, // change signal mask {"sigsuspend", LuaUnixSigsuspend}, // wait for signal {"setitimer", LuaUnixSetitimer}, // set alarm clock - {"reboot", LuaUnixReboot}, // reboots system {"strerror", LuaUnixStrerror}, // turn errno into string {"strerrno", LuaUnixStrerrno}, // turn errno into string {"strsignal", LuaUnixStrsignal}, // turn signal into string @@ -1765,12 +1868,5 @@ int LuaUnix(lua_State *L) { LuaSetIntField(L, "LOG_INFO", LOG_INFO); LuaSetIntField(L, "LOG_DEBUG", LOG_DEBUG); - // reboot() howto - LuaSetIntField(L, "RB_AUTOBOOT", RB_AUTOBOOT); - LuaSetIntField(L, "RB_POWER_OFF", RB_POWER_OFF); - LuaSetIntField(L, "RB_HALT_SYSTEM", RB_HALT_SYSTEM); - LuaSetIntField(L, "RB_SW_SUSPEND", RB_SW_SUSPEND); - LuaSetIntField(L, "RB_NOSYNC", RB_NOSYNC); - return 1; } diff --git a/tool/net/net.mk b/tool/net/net.mk index df426b8e3..74c56ff93 100644 --- a/tool/net/net.mk +++ b/tool/net/net.mk @@ -171,7 +171,9 @@ o/tinylinux/tool/net/redbean.com: \ o/$(MODE)/tool/net/demo/.init.lua.zip.o \ o/$(MODE)/tool/net/demo/.reload.lua.zip.o \ o/$(MODE)/tool/net/demo/sql.lua.zip.o \ -o/$(MODE)/tool/net/demo/unix.lua.zip.o \ +o/$(MODE)/tool/net/demo/unix-rawsocket.lua.zip.o \ +o/$(MODE)/tool/net/demo/unix-subprocess.lua.zip.o \ +o/$(MODE)/tool/net/demo/unix-info.lua.zip.o \ o/$(MODE)/tool/net/demo/fetch.lua.zip.o \ o/$(MODE)/tool/net/demo/hello.lua.zip.o \ o/$(MODE)/tool/net/demo/maxmind.lua.zip.o \ @@ -213,8 +215,9 @@ o/$(MODE)/tool/net/redbean-demo.com.dbg: \ o/$(MODE)/tool/net/largon2.o \ o/$(MODE)/tool/net/net.pkg \ o/$(MODE)/tool/net/demo/sql.lua.zip.o \ - o/$(MODE)/tool/net/demo/unix.lua.zip.o \ - o/$(MODE)/tool/net/demo/unix2.lua.zip.o \ + o/$(MODE)/tool/net/demo/unix-rawsocket.lua.zip.o \ + o/$(MODE)/tool/net/demo/unix-subprocess.lua.zip.o \ + o/$(MODE)/tool/net/demo/unix-info.lua.zip.o \ o/$(MODE)/tool/net/demo/fetch.lua.zip.o \ o/$(MODE)/tool/net/demo/hello.lua.zip.o \ o/$(MODE)/tool/net/demo/redbean.lua.zip.o \ diff --git a/tool/net/redbean.c b/tool/net/redbean.c index f67cd2512..15d3afd0d 100644 --- a/tool/net/redbean.c +++ b/tool/net/redbean.c @@ -6608,45 +6608,65 @@ static int ExitWorker(void) { static const struct sock_filter kSandboxOnline[] = { _SECCOMP_MACHINE(AUDIT_ARCH_X86_64), // _SECCOMP_LOAD_SYSCALL_NR(), // - _SECCOMP_ALLOW_SYSCALL(0x0013), // readv - _SECCOMP_ALLOW_SYSCALL(0x0014), // writev - _SECCOMP_ALLOW_SYSCALL(0x0009), // mmap - _SECCOMP_ALLOW_SYSCALL(0x000b), // munmap - _SECCOMP_ALLOW_SYSCALL(0x0000), // read - _SECCOMP_ALLOW_SYSCALL(0x0001), // write - _SECCOMP_ALLOW_SYSCALL(0x0003), // close - _SECCOMP_ALLOW_SYSCALL(0x0008), // lseek - _SECCOMP_ALLOW_SYSCALL(0x000f), // rt_sigreturn - _SECCOMP_ALLOW_SYSCALL(0x00e7), // exit_group - _SECCOMP_ALLOW_SYSCALL(0x0106), // newfstatat - _SECCOMP_ALLOW_SYSCALL(0x00e4), // clock_gettime - _SECCOMP_ALLOW_SYSCALL(0x003f), // uname - _SECCOMP_ALLOW_SYSCALL(0x0048), // fcntl - _SECCOMP_ALLOW_SYSCALL(0x0029), // socket - _SECCOMP_ALLOW_SYSCALL(0x002a), // connect - _SECCOMP_ALLOW_SYSCALL(0x002c), // sendto - _SECCOMP_ALLOW_SYSCALL(0x002d), // recvfrom - _SECCOMP_ALLOW_SYSCALL(0x0036), // setsockopt + _SECCOMP_ALLOW_SYSCALL(0x013), // readv + _SECCOMP_ALLOW_SYSCALL(0x014), // writev + _SECCOMP_ALLOW_SYSCALL(0x009), // mmap + _SECCOMP_ALLOW_SYSCALL(0x00b), // munmap + _SECCOMP_ALLOW_SYSCALL(0x000), // read + _SECCOMP_ALLOW_SYSCALL(0x001), // write + _SECCOMP_ALLOW_SYSCALL(0x003), // close + _SECCOMP_ALLOW_SYSCALL(0x008), // lseek + _SECCOMP_ALLOW_SYSCALL(0x04f), // getcwd + _SECCOMP_ALLOW_SYSCALL(0x027), // getpid + _SECCOMP_ALLOW_SYSCALL(0x066), // getuid + _SECCOMP_ALLOW_SYSCALL(0x068), // getgid + _SECCOMP_ALLOW_SYSCALL(0x06e), // getppid + _SECCOMP_ALLOW_SYSCALL(0x06f), // getpgrp + _SECCOMP_ALLOW_SYSCALL(0x07c), // getsid + _SECCOMP_ALLOW_SYSCALL(0x06b), // geteuid + _SECCOMP_ALLOW_SYSCALL(0x06c), // getegid + _SECCOMP_ALLOW_SYSCALL(0x061), // getrlimit + _SECCOMP_ALLOW_SYSCALL(0x00f), // rt_sigreturn + _SECCOMP_ALLOW_SYSCALL(0x0e7), // exit_group + _SECCOMP_ALLOW_SYSCALL(0x106), // newfstatat + _SECCOMP_ALLOW_SYSCALL(0x0e4), // clock_gettime + _SECCOMP_ALLOW_SYSCALL(0x03f), // uname + _SECCOMP_ALLOW_SYSCALL(0x048), // fcntl + _SECCOMP_ALLOW_SYSCALL(0x029), // socket + _SECCOMP_ALLOW_SYSCALL(0x02a), // connect + _SECCOMP_ALLOW_SYSCALL(0x02c), // sendto + _SECCOMP_ALLOW_SYSCALL(0x02d), // recvfrom + _SECCOMP_ALLOW_SYSCALL(0x036), // setsockopt _SECCOMP_LOG_AND_RETURN_ERRNO(1), // EPERM }; static const struct sock_filter kSandboxOffline[] = { _SECCOMP_MACHINE(AUDIT_ARCH_X86_64), // _SECCOMP_LOAD_SYSCALL_NR(), // - _SECCOMP_ALLOW_SYSCALL(0x0013), // readv - _SECCOMP_ALLOW_SYSCALL(0x0014), // writev - _SECCOMP_ALLOW_SYSCALL(0x0000), // read - _SECCOMP_ALLOW_SYSCALL(0x0001), // write - _SECCOMP_ALLOW_SYSCALL(0x0009), // mmap - _SECCOMP_ALLOW_SYSCALL(0x000b), // munmap - _SECCOMP_ALLOW_SYSCALL(0x0003), // close - _SECCOMP_ALLOW_SYSCALL(0x0008), // lseek - _SECCOMP_ALLOW_SYSCALL(0x000f), // rt_sigreturn - _SECCOMP_ALLOW_SYSCALL(0x00e7), // exit_group - _SECCOMP_ALLOW_SYSCALL(0x0106), // newfstatat - _SECCOMP_ALLOW_SYSCALL(0x00e4), // clock_gettime - _SECCOMP_ALLOW_SYSCALL(0x003f), // uname - _SECCOMP_ALLOW_SYSCALL(0x0048), // fcntl + _SECCOMP_ALLOW_SYSCALL(0x013), // readv + _SECCOMP_ALLOW_SYSCALL(0x014), // writev + _SECCOMP_ALLOW_SYSCALL(0x000), // read + _SECCOMP_ALLOW_SYSCALL(0x001), // write + _SECCOMP_ALLOW_SYSCALL(0x009), // mmap + _SECCOMP_ALLOW_SYSCALL(0x00b), // munmap + _SECCOMP_ALLOW_SYSCALL(0x003), // close + _SECCOMP_ALLOW_SYSCALL(0x008), // lseek + _SECCOMP_ALLOW_SYSCALL(0x04f), // getcwd + _SECCOMP_ALLOW_SYSCALL(0x027), // getpid + _SECCOMP_ALLOW_SYSCALL(0x066), // getuid + _SECCOMP_ALLOW_SYSCALL(0x068), // getgid + _SECCOMP_ALLOW_SYSCALL(0x06e), // getppid + _SECCOMP_ALLOW_SYSCALL(0x06f), // getpgrp + _SECCOMP_ALLOW_SYSCALL(0x07c), // getsid + _SECCOMP_ALLOW_SYSCALL(0x06b), // geteuid + _SECCOMP_ALLOW_SYSCALL(0x06c), // getegid + _SECCOMP_ALLOW_SYSCALL(0x061), // getrlimit + _SECCOMP_ALLOW_SYSCALL(0x00f), // rt_sigreturn + _SECCOMP_ALLOW_SYSCALL(0x0e7), // exit_group + _SECCOMP_ALLOW_SYSCALL(0x106), // newfstatat + _SECCOMP_ALLOW_SYSCALL(0x0e4), // clock_gettime + _SECCOMP_ALLOW_SYSCALL(0x03f), // uname + _SECCOMP_ALLOW_SYSCALL(0x048), // fcntl _SECCOMP_LOG_AND_RETURN_ERRNO(1), // EPERM };