Make more fixes and improvements

This commit is contained in:
Justine Tunney 2022-04-21 13:44:59 -07:00
parent 01b25e267b
commit 1599b818d9
24 changed files with 858 additions and 538 deletions

View file

@ -281,7 +281,7 @@ COSMOPOLITAN_OBJECTS = \
LIBC_RAND \ LIBC_RAND \
LIBC_SYSV_CALLS \ LIBC_SYSV_CALLS \
LIBC_NT_PSAPI \ LIBC_NT_PSAPI \
LIBC_NT_POWERPROF \ LIBC_NT_POWRPROF \
LIBC_NT_PDH \ LIBC_NT_PDH \
LIBC_NT_SHELL32 \ LIBC_NT_SHELL32 \
LIBC_NT_GDI32 \ LIBC_NT_GDI32 \

View file

@ -46,7 +46,7 @@ LIBC_CALLS_A_DIRECTDEPS = \
LIBC_NT_NTDLL \ LIBC_NT_NTDLL \
LIBC_NT_PDH \ LIBC_NT_PDH \
LIBC_NT_PSAPI \ LIBC_NT_PSAPI \
LIBC_NT_POWERPROF \ LIBC_NT_POWRPROF \
LIBC_NT_WS2_32 \ LIBC_NT_WS2_32 \
LIBC_STR \ LIBC_STR \
LIBC_STUBS \ LIBC_STUBS \

View file

@ -21,7 +21,7 @@
#include "libc/bits/weaken.h" #include "libc/bits/weaken.h"
#include "libc/fmt/conv.h" #include "libc/fmt/conv.h"
#include "libc/fmt/fmt.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/internal.h"
#include "libc/fmt/itoa.h" #include "libc/fmt/itoa.h"
#include "libc/intrin/nomultics.internal.h" #include "libc/intrin/nomultics.internal.h"
@ -33,25 +33,6 @@
#include "libc/sysv/errfuns.h" #include "libc/sysv/errfuns.h"
#include "third_party/gdtoa/gdtoa.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) { static int __fmt_atoi(const char **str) {
int i; int i;
for (i = 0; '0' <= **str && **str <= '9'; ++*str) { 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 * @vforksafe if floating point isn't used
*/ */
hidden int __fmt(void *fn, void *arg, const char *format, va_list va) { 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; long ld;
void *p; void *p;
unsigned u; unsigned u;
@ -145,13 +121,12 @@ hidden int __fmt(void *fn, void *arg, const char *format, va_list va) {
const char *alphabet; const char *alphabet;
int (*out)(const char *, void *, size_t); int (*out)(const char *, void *, size_t);
unsigned char signbit, log2base; unsigned char signbit, log2base;
int c, d, k, w, n, i1, ui, bw, bex; char *s, *q, qchar;
char *s, *q, *se, *mem, qchar, special[8]; int d, w, n;
int sgn, alt, sign, prec, prec1, flags, width, decpt, lasterr; int sign, prec, flags, width, lasterr;
lasterr = errno; lasterr = errno;
out = fn ? fn : (void *)missingno; out = fn ? fn : (void *)missingno;
mem = 0;
while (*format) { while (*format) {
if (*format != '%') { if (*format != '%') {
@ -361,7 +336,6 @@ hidden int __fmt(void *fn, void *arg, const char *format, va_list va) {
} }
break; break;
} }
case 'c': case 'c':
prec = 1; prec = 1;
flags |= FLAGS_PRECISION; flags |= FLAGS_PRECISION;
@ -369,12 +343,10 @@ hidden int __fmt(void *fn, void *arg, const char *format, va_list va) {
p = charbuf; p = charbuf;
charbuf[0] = va_arg(va, int); charbuf[0] = va_arg(va, int);
goto FormatString; goto FormatString;
case 'm': case 'm':
p = weaken(strerror) ? weaken(strerror)(lasterr) : "?"; p = weaken(strerror) ? weaken(strerror)(lasterr) : "?";
signbit = 0; signbit = 0;
goto FormatString; goto FormatString;
case 'r': case 'r':
// undocumented %r specifier // undocumented %r specifier
// used for good carriage return // 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"; p = "\r\e[K";
goto FormatString; goto FormatString;
} }
case 'q': case 'q':
flags |= FLAGS_QUOTE; flags |= FLAGS_QUOTE;
/* fallthrough */ /* fallthrough */
case 's': case 's':
p = va_arg(va, void *); p = va_arg(va, void *);
FormatString: FormatString:
@ -397,369 +367,40 @@ hidden int __fmt(void *fn, void *arg, const char *format, va_list va) {
return -1; return -1;
} }
break; break;
case 'n': case 'n':
// nonstandard %n specifier // nonstandard %n specifier
// used to print newlines that work in raw terminal modes // used to print newlines that work in raw terminal modes
if (__nomultics) PUT('\r'); if (__nomultics) __FMT_PUT('\r');
PUT('\n'); __FMT_PUT('\n');
break; break;
case 'F': case 'F':
case 'f': case 'f':
if (!(flags & FLAGS_PRECISION)) prec = 6; case 'G':
if (longdouble) { case 'g':
pun.d = va_arg(va, long double); case 'e':
} else { case 'E':
pun.d = va_arg(va, double); case 'a':
} case 'A':
FormatDtoa:
if (!weaken(__fmt_dtoa)) { if (!weaken(__fmt_dtoa)) {
p = "?"; p = "?";
goto FormatThatThing; prec = 0;
}
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;
flags &= ~(FLAGS_PRECISION | FLAGS_PLUS | FLAGS_SPACE); flags &= ~(FLAGS_PRECISION | FLAGS_PLUS | FLAGS_SPACE);
goto FormatString; goto FormatString;
} }
FormatReal: if (weaken(__fmt_dtoa)(out, arg, d, flags, prec, sign, width,
if (sgn) sign = '-'; longdouble, qchar, signbit, alphabet,
if (prec > 0) width -= prec; va) == -1) {
if (width > 0) { return -1;
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;
} }
break; break;
case '%': case '%':
PUT('%'); __FMT_PUT('%');
break; break;
default: default:
PUT(format[-1]); __FMT_PUT(format[-1]);
break; break;
} }
} }
assert(!mem);
return 0; return 0;
} }

View file

@ -1,11 +1,19 @@
#ifndef COSMOPOLITAN_LIBC_FMT_FMTS_H_ #ifndef COSMOPOLITAN_LIBC_FMT_FMT_INTERNAL_H_
#define COSMOPOLITAN_LIBC_FMT_FMTS_H_ #define COSMOPOLITAN_LIBC_FMT_FMT_INTERNAL_H_
#define PRINTF_NTOA_BUFFER_SIZE 144 #define PRINTF_NTOA_BUFFER_SIZE 144
#if !(__ASSEMBLER__ + __LINKER__ + 0) #if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_ 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 *, int __fmt_pad(int (*)(const char *, void *, size_t), void *,
unsigned long) hidden; unsigned long) hidden;
int __fmt_stoa(int (*)(const char *, void *, size_t), void *, void *, 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, int __fmt_ntoa(int (*)(const char *, void *, size_t), void *, va_list,
unsigned char, unsigned long, unsigned long, unsigned long, unsigned char, unsigned long, unsigned long, unsigned long,
unsigned char, const char *) hidden; 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_ COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_LIBC_FMT_FMTS_H_ */ #endif /* COSMOPOLITAN_LIBC_FMT_FMT_INTERNAL_H_ */

View file

@ -20,7 +20,7 @@
#include "libc/assert.h" #include "libc/assert.h"
#include "libc/fmt/conv.h" #include "libc/fmt/conv.h"
#include "libc/fmt/divmod10.internal.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/fmt/internal.h"
#include "libc/limits.h" #include "libc/limits.h"

View file

@ -16,7 +16,7 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE. 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, int __fmt_pad(int out(const char *, void *, size_t), void *arg,
unsigned long n) { unsigned long n) {

View file

@ -1,7 +1,6 @@
#ifndef COSMOPOLITAN_LIBC_FMT_PFLINK_H_ #ifndef COSMOPOLITAN_LIBC_FMT_PFLINK_H_
#define COSMOPOLITAN_LIBC_FMT_PFLINK_H_ #define COSMOPOLITAN_LIBC_FMT_PFLINK_H_
#include "libc/dce.h" #include "libc/dce.h"
#include "libc/fmt/fmts.h"
#include "libc/mem/mem.h" #include "libc/mem/mem.h"
#include "libc/runtime/runtime.h" #include "libc/runtime/runtime.h"
#include "libc/str/str.h" #include "libc/str/str.h"
@ -23,7 +22,6 @@
({ \ ({ \
if (___PFLINK(FMT, strpbrk, "faAeg")) STATIC_YOINK("__fmt_dtoa"); \ if (___PFLINK(FMT, strpbrk, "faAeg")) STATIC_YOINK("__fmt_dtoa"); \
if (___PFLINK(FMT, strpbrk, "cmrqs")) { \ if (___PFLINK(FMT, strpbrk, "cmrqs")) { \
if (___PFLINK(FMT, strchr, '#')) STATIC_YOINK("kCp437"); \
if (___PFLINK(FMT, strstr, "%m")) STATIC_YOINK("strerror"); \ if (___PFLINK(FMT, strstr, "%m")) STATIC_YOINK("strerror"); \
if (!IsTiny() && (___PFLINK(FMT, strstr, "%*") || \ if (!IsTiny() && (___PFLINK(FMT, strstr, "%*") || \
___PFLINK(FMT, strpbrk, "0123456789"))) { \ ___PFLINK(FMT, strpbrk, "0123456789"))) { \

View file

@ -20,7 +20,7 @@
#include "libc/bits/bits.h" #include "libc/bits/bits.h"
#include "libc/bits/safemacros.internal.h" #include "libc/bits/safemacros.internal.h"
#include "libc/bits/weaken.h" #include "libc/bits/weaken.h"
#include "libc/fmt/fmts.h" #include "libc/fmt/fmt.internal.h"
#include "libc/fmt/internal.h" #include "libc/fmt/internal.h"
#include "libc/nexgen32e/bsr.h" #include "libc/nexgen32e/bsr.h"
#include "libc/str/str.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) { static int __fmt_stoa_bing(out_f out, void *a, uint64_t w) {
char buf[8]; char buf[8];
w = tpenc((*weaken(kCp437))[w & 0xFF]); w = tpenc(kCp437[w & 0xFF]);
WRITE64LE(buf, w); WRITE64LE(buf, w);
return out(buf, a, w ? (bsr(w) >> 3) + 1 : 1); return out(buf, a, w ? (bsr(w) >> 3) + 1 : 1);
} }

View file

@ -1,5 +1,5 @@
.include "o/libc/nt/codegen.inc" .include "o/libc/nt/codegen.inc"
.imp PowerProf,__imp_SetSuspendState,SetSuspendState,0 .imp PowrProf,__imp_SetSuspendState,SetSuspendState,0
.text.windows .text.windows
SetSuspendState: SetSuspendState:

View file

@ -4052,10 +4052,10 @@ imp 'SetTcpEntry' SetTcpEntry iphlpapi 0
imp 'UnenableRouter' UnenableRouter iphlpapi 0 imp 'UnenableRouter' UnenableRouter iphlpapi 0
imp 'UnregisterInterfaceTimestampConfigChange' UnregisterInterfaceTimestampConfigChange iphlpapi 0 imp 'UnregisterInterfaceTimestampConfigChange' UnregisterInterfaceTimestampConfigChange iphlpapi 0
# POWERPROF.DLL # POWRPROF.DLL
# #
# Name Actual DLL Hint Arity # Name Actual DLL Hint Arity
imp 'SetSuspendState' SetSuspendState PowerProf 0 3 imp 'SetSuspendState' SetSuspendState PowrProf 0 3
# PDH.DLL # PDH.DLL
# #

View file

@ -311,22 +311,22 @@ $(LIBC_NT_IPHLPAPI_A).pkg: \
#─────────────────────────────────────────────────────────────────────────────── #───────────────────────────────────────────────────────────────────────────────
LIBC_NT_ARTIFACTS += LIBC_NT_POWERPROF_A LIBC_NT_ARTIFACTS += LIBC_NT_POWRPROF_A
LIBC_NT_POWERPROF = $(LIBC_NT_POWERPROF_A_DEPS) $(LIBC_NT_POWERPROF_A) LIBC_NT_POWRPROF = $(LIBC_NT_POWRPROF_A_DEPS) $(LIBC_NT_POWRPROF_A)
LIBC_NT_POWERPROF_A = o/$(MODE)/libc/nt/powerprof.a LIBC_NT_POWRPROF_A = o/$(MODE)/libc/nt/powrprof.a
LIBC_NT_POWERPROF_A_SRCS := $(wildcard libc/nt/PowerProf/*.s) LIBC_NT_POWRPROF_A_SRCS := $(wildcard libc/nt/PowrProf/*.s)
LIBC_NT_POWERPROF_A_OBJS = $(LIBC_NT_POWERPROF_A_SRCS:%.s=o/$(MODE)/%.o) LIBC_NT_POWRPROF_A_OBJS = $(LIBC_NT_POWRPROF_A_SRCS:%.s=o/$(MODE)/%.o)
LIBC_NT_POWERPROF_A_CHECKS = $(LIBC_NT_POWERPROF_A).pkg LIBC_NT_POWRPROF_A_CHECKS = $(LIBC_NT_POWRPROF_A).pkg
LIBC_NT_POWERPROF_A_DIRECTDEPS = LIBC_NT_KERNEL32 LIBC_NT_POWRPROF_A_DIRECTDEPS = LIBC_NT_KERNEL32
LIBC_NT_POWERPROF_A_DEPS := \ LIBC_NT_POWRPROF_A_DEPS := \
$(call uniq,$(foreach x,$(LIBC_NT_POWERPROF_A_DIRECTDEPS),$($(x)))) $(call uniq,$(foreach x,$(LIBC_NT_POWRPROF_A_DIRECTDEPS),$($(x))))
$(LIBC_NT_POWERPROF_A): \ $(LIBC_NT_POWRPROF_A): \
libc/nt/PowerProf/ \ libc/nt/PowrProf/ \
$(LIBC_NT_POWERPROF_A).pkg \ $(LIBC_NT_POWRPROF_A).pkg \
$(LIBC_NT_POWERPROF_A_OBJS) $(LIBC_NT_POWRPROF_A_OBJS)
$(LIBC_NT_POWERPROF_A).pkg: \ $(LIBC_NT_POWRPROF_A).pkg: \
$(LIBC_NT_POWERPROF_A_OBJS) \ $(LIBC_NT_POWRPROF_A_OBJS) \
$(foreach x,$(LIBC_NT_POWERPROF_A_DIRECTDEPS),$($(x)_A).pkg) $(foreach x,$(LIBC_NT_POWRPROF_A_DIRECTDEPS),$($(x)_A).pkg)
#─────────────────────────────────────────────────────────────────────────────── #───────────────────────────────────────────────────────────────────────────────

View file

@ -1,7 +1,7 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ /*-*- 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 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 Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the 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 TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE. 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" #include "third_party/gdtoa/gdtoa.h"
char *__fmt_dtoa(double d0, int mode, int ndigits, int *decpt, int *sign, static const char kSpecialFloats[2][2][4] = {{"INF", "inf"}, {"NAN", "nan"}};
char **rve) {
return dtoa(d0, mode, ndigits, decpt, sign, rve); 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;
} }

View file

@ -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) { LUA_API void lua_seti (lua_State *L, int idx, lua_Integer n) {
TValue *t; TValue *t;
const TValue *slot; 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) { LUA_API void lua_rawset (lua_State *L, int idx) {
aux_rawset(L, idx, s2v(L->top - 2), 2); 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) { LUA_API void lua_rawsetp (lua_State *L, int idx, const void *p) {
TValue k; TValue k;
setpvalue(&k, cast_voidp(p)); 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) { LUA_API void lua_rawseti (lua_State *L, int idx, lua_Integer n) {
Table *t; Table *t;
lua_lock(L); lua_lock(L);

View file

@ -86,7 +86,6 @@ typedef LUAI_UACINT l_uacInt;
*/ */
#if defined LUAI_ASSERT #if defined LUAI_ASSERT
#undef NDEBUG #undef NDEBUG
#include <assert.h>
#define lua_assert(c) assert(c) #define lua_assert(c) assert(c)
#endif #endif

View file

@ -45,6 +45,7 @@ static const struct sock_filter kSandboxFilter[] = {
_SECCOMP_ALLOW_SYSCALL(0x008), // lseek _SECCOMP_ALLOW_SYSCALL(0x008), // lseek
_SECCOMP_ALLOW_SYSCALL(0x009), // mmap _SECCOMP_ALLOW_SYSCALL(0x009), // mmap
_SECCOMP_ALLOW_SYSCALL(0x00b), // munmap _SECCOMP_ALLOW_SYSCALL(0x00b), // munmap
_SECCOMP_ALLOW_SYSCALL(0x04f), // getcwd
_SECCOMP_ALLOW_SYSCALL(0x003), // close _SECCOMP_ALLOW_SYSCALL(0x003), // close
_SECCOMP_ALLOW_SYSCALL(0x010), // ioctl todo _SECCOMP_ALLOW_SYSCALL(0x010), // ioctl todo
_SECCOMP_ALLOW_SYSCALL(0x016), // pipe _SECCOMP_ALLOW_SYSCALL(0x016), // pipe
@ -60,6 +61,15 @@ static const struct sock_filter kSandboxFilter[] = {
_SECCOMP_ALLOW_SYSCALL(0x127), // preadv _SECCOMP_ALLOW_SYSCALL(0x127), // preadv
_SECCOMP_ALLOW_SYSCALL(0x128), // pwritev _SECCOMP_ALLOW_SYSCALL(0x128), // pwritev
_SECCOMP_ALLOW_SYSCALL(0x0d9), // getdents _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(0x028), // sendfile
_SECCOMP_ALLOW_SYSCALL(0x02d), // recvfrom _SECCOMP_ALLOW_SYSCALL(0x02d), // recvfrom
_SECCOMP_ALLOW_SYSCALL(0x033), // getsockname _SECCOMP_ALLOW_SYSCALL(0x033), // getsockname
@ -67,7 +77,6 @@ static const struct sock_filter kSandboxFilter[] = {
_SECCOMP_ALLOW_SYSCALL(0x00f), // rt_sigreturn _SECCOMP_ALLOW_SYSCALL(0x00f), // rt_sigreturn
_SECCOMP_ALLOW_SYSCALL(0x0e4), // clock_gettime _SECCOMP_ALLOW_SYSCALL(0x0e4), // clock_gettime
_SECCOMP_ALLOW_SYSCALL(0x060), // gettimeofday _SECCOMP_ALLOW_SYSCALL(0x060), // gettimeofday
_SECCOMP_ALLOW_SYSCALL(0x027), // getpid
_SECCOMP_ALLOW_SYSCALL(0x03f), // uname _SECCOMP_ALLOW_SYSCALL(0x03f), // uname
_SECCOMP_ALLOW_SYSCALL(0x03c), // exit _SECCOMP_ALLOW_SYSCALL(0x03c), // exit
_SECCOMP_ALLOW_SYSCALL(0x0e7), // exit_group _SECCOMP_ALLOW_SYSCALL(0x0e7), // exit_group

View file

@ -0,0 +1,80 @@
local unix = require 'unix'
Write('<!doctype html>\r\n')
Write('<title>redbean</title>\r\n')
Write('<h3>UNIX Information Demo</h3>\r\n')
Write('<dl>\r\n')
Write('<dt>getuid()\r\n')
Write(string.format('<dd>%d\r\n', unix.getuid()))
Write('<dt>getgid()\r\n')
Write(string.format('<dd>%d\r\n', unix.getgid()))
Write('<dt>getpid()\r\n')
Write(string.format('<dd>%d\r\n', unix.getpid()))
Write('<dt>getppid()\r\n')
Write(string.format('<dd>%d\r\n', unix.getppid()))
Write('<dt>getpgrp()\r\n')
Write(string.format('<dd>%d\r\n', unix.getpgrp()))
Write('<dt>getsid(0)\r\n')
sid, errno = unix.getsid(0)
if sid then
Write(string.format('<dd>%d\r\n', sid))
else
Write(string.format('<dd>%s\r\n', EscapeHtml(unix.strerrno(errno))))
end
Write('<dt>gethostname()\r\n')
Write(string.format('<dd>%s\r\n', EscapeHtml(unix.gethostname())))
Write('<dt>getcwd()\r\n')
Write(string.format('<dd>%s\r\n', EscapeHtml(unix.getcwd())))
function PrintResourceLimit(name, id)
soft, hard, errno = unix.getrlimit(id)
Write(string.format('<dt>getrlimit(%s)\r\n', name))
if soft then
Write('<dd>')
Write('soft ')
if soft == -1 then
Write('')
else
Write(string.format('%d', soft))
end
Write('<br>\r\n')
Write('hard ')
if hard == -1 then
Write('')
else
Write(string.format('%d', hard))
end
Write('\r\n')
else
Write(string.format('<dd>%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('<dt>siocgifconf()\r\n')
Write('<dd>\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<br>\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('</dl>\r\n')

View file

@ -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()

View file

@ -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

View file

@ -47,15 +47,16 @@ void PrintUsage(char **argv) {
} }
void UdpServer(void) { void UdpServer(void) {
int ip;
ssize_t rc; ssize_t rc;
struct sockaddr_in addr2; struct sockaddr_in addr2;
uint32_t addrsize2 = sizeof(struct sockaddr_in); uint32_t addrsize2 = sizeof(struct sockaddr_in);
CHECK_NE(-1, (sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))); CHECK_NE(-1, (sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)));
CHECK_NE(-1, bind(sock, &addr, addrsize)); CHECK_NE(-1, bind(sock, &addr, addrsize));
CHECK_NE(-1, getsockname(sock, &addr2, &addrsize2)); CHECK_NE(-1, getsockname(sock, &addr2, &addrsize2));
kprintf("udp server %hhu.%hhu.%hhu.%hhu %hu%n", addr2.sin_addr.s_addr >> 24, ip = ntohl(addr2.sin_addr.s_addr);
addr2.sin_addr.s_addr >> 16, addr2.sin_addr.s_addr >> 8, kprintf("udp server %hhu.%hhu.%hhu.%hhu %hu%n", ip >> 24, ip >> 16, ip >> 8,
addr2.sin_addr.s_addr, addr2.sin_port); ip, ntohs(addr2.sin_port));
for (;;) { for (;;) {
CHECK_NE(-1, CHECK_NE(-1,
(rc = recvfrom(sock, buf, sizeof(buf), 0, &addr2, &addrsize2))); (rc = recvfrom(sock, buf, sizeof(buf), 0, &addr2, &addrsize2)));
@ -73,23 +74,23 @@ void UdpClient(void) {
} }
void TcpServer(void) { void TcpServer(void) {
int client;
ssize_t rc; ssize_t rc;
int ip, client;
struct sockaddr_in addr2; struct sockaddr_in addr2;
uint32_t addrsize2 = sizeof(struct sockaddr_in); uint32_t addrsize2 = sizeof(struct sockaddr_in);
CHECK_NE(-1, (sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP))); CHECK_NE(-1, (sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)));
CHECK_NE(-1, bind(sock, &addr, addrsize)); CHECK_NE(-1, bind(sock, &addr, addrsize));
CHECK_NE(-1, listen(sock, 10)); CHECK_NE(-1, listen(sock, 10));
CHECK_NE(-1, getsockname(sock, &addr2, &addrsize2)); CHECK_NE(-1, getsockname(sock, &addr2, &addrsize2));
kprintf("tcp server %hhu.%hhu.%hhu.%hhu %hu%n", addr2.sin_addr.s_addr >> 24, ip = ntohl(addr2.sin_addr.s_addr);
addr2.sin_addr.s_addr >> 16, addr2.sin_addr.s_addr >> 8, kprintf("tcp server %hhu.%hhu.%hhu.%hhu %hu%n", ip >> 24, ip >> 16, ip >> 8,
addr2.sin_addr.s_addr, addr2.sin_port); ip, ntohs(addr2.sin_port));
for (;;) { for (;;) {
addrsize2 = sizeof(struct sockaddr_in); addrsize2 = sizeof(struct sockaddr_in);
CHECK_NE(-1, (client = accept(sock, &addr2, &addrsize2))); CHECK_NE(-1, (client = accept(sock, &addr2, &addrsize2)));
kprintf("got client %hhu.%hhu.%hhu.%hhu %hu%n", addr2.sin_addr.s_addr >> 24, ip = ntohl(addr2.sin_addr.s_addr);
addr2.sin_addr.s_addr >> 16, addr2.sin_addr.s_addr >> 8, kprintf("got client %hhu.%hhu.%hhu.%hhu %hu%n", ip >> 24, ip >> 16, ip >> 8,
addr2.sin_addr.s_addr, addr2.sin_port); ip, ntohs(addr2.sin_port));
for (;;) { for (;;) {
CHECK_NE(-1, (rc = read(client, buf, sizeof(buf)))); CHECK_NE(-1, (rc = read(client, buf, sizeof(buf))));
if (!rc) break; if (!rc) break;

View file

@ -1440,7 +1440,7 @@ UNIX MODULE
end end
end end
unix.close(reader) unix.close(reader)
unix.wait(-1) unix.wait()
end end
unix.wait([pid:int, options:int]) unix.wait([pid:int, options:int])
@ -1705,6 +1705,28 @@ UNIX MODULE
Further note that calling `unix.bind(sock)` is equivalent to not Further note that calling `unix.bind(sock)` is equivalent to not
calling bind() at all, since the above behavior is the default. 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] unix.listen(fd:int[, backlog]) → rc:int[, errno:int]
Begins listening for incoming connections on a socket. Begins listening for incoming connections on a socket.
@ -1802,20 +1824,6 @@ UNIX MODULE
unix.sigaction(unix.SIGALRM, MyOnSigAlrm, unix.SA_RESETHAND) unix.sigaction(unix.SIGALRM, MyOnSigAlrm, unix.SA_RESETHAND)
unix.setitimer(unix.ITIMER_REAL, 0, 0, 1, 0) 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 unix.strerrno(errno:int) → str
Turns `errno` code into its symbolic name, e.g. `"EINTR"`. 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. Turns platform-specific `sig` code into its name, e.g.
`strsignal(9)` always returns `"SIGKILL"`. `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 unix.stat(x) → UnixStat*, errno:int
Gets information about file or directory. `x` may be a file or Gets information about file or directory. `x` may be a file or

View file

@ -18,6 +18,7 @@
*/ */
#include "libc/assert.h" #include "libc/assert.h"
#include "libc/calls/calls.h" #include "libc/calls/calls.h"
#include "libc/calls/ioctl.h"
#include "libc/calls/sigbits.h" #include "libc/calls/sigbits.h"
#include "libc/calls/strace.internal.h" #include "libc/calls/strace.internal.h"
#include "libc/calls/struct/dirent.h" #include "libc/calls/struct/dirent.h"
@ -27,6 +28,7 @@
#include "libc/calls/struct/stat.h" #include "libc/calls/struct/stat.h"
#include "libc/calls/struct/timespec.h" #include "libc/calls/struct/timespec.h"
#include "libc/calls/ucontext.h" #include "libc/calls/ucontext.h"
#include "libc/dns/dns.h"
#include "libc/errno.h" #include "libc/errno.h"
#include "libc/fmt/fmt.h" #include "libc/fmt/fmt.h"
#include "libc/fmt/kerrornames.internal.h" #include "libc/fmt/kerrornames.internal.h"
@ -52,13 +54,15 @@
#include "libc/sysv/consts/nr.h" #include "libc/sysv/consts/nr.h"
#include "libc/sysv/consts/o.h" #include "libc/sysv/consts/o.h"
#include "libc/sysv/consts/ok.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/rlimit.h"
#include "libc/sysv/consts/sa.h" #include "libc/sysv/consts/sa.h"
#include "libc/sysv/consts/shut.h" #include "libc/sysv/consts/shut.h"
#include "libc/sysv/consts/sig.h" #include "libc/sysv/consts/sig.h"
#include "libc/sysv/consts/sio.h"
#include "libc/sysv/consts/sock.h" #include "libc/sysv/consts/sock.h"
#include "libc/sysv/consts/w.h" #include "libc/sysv/consts/w.h"
#include "libc/sysv/errfuns.h"
#include "libc/time/time.h" #include "libc/time/time.h"
#include "libc/x/x.h" #include "libc/x/x.h"
#include "third_party/lua/lauxlib.h" #include "third_party/lua/lauxlib.h"
@ -104,14 +108,6 @@ static dontinline int ReturnTimespec(lua_State *L, struct timespec *ts) {
return 2; 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) { static int ReturnErrno(lua_State *L, int nils, int olderr) {
int i; int i;
for (i = 0; i < nils; ++i) { for (i = 0; i < nils; ++i) {
@ -122,6 +118,15 @@ static int ReturnErrno(lua_State *L, int nils, int olderr) {
return nils + 1; 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) { static char **ConvertLuaArrayToStringList(lua_State *L, int i) {
int j, n; int j, n;
char **p; char **p;
@ -146,7 +151,7 @@ static char **ConvertLuaTableToEnvList(lua_State *L, int i) {
lua_pushnil(L); lua_pushnil(L);
for (n = 0; lua_next(L, i);) { for (n = 0; lua_next(L, i);) {
if (lua_type(L, -2) == LUA_TSTRING) { 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)); p[n - 1] = xasprintf("%s=%s", lua_tostring(L, -2), lua_tostring(L, -1));
} }
lua_pop(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] // unix.getcwd(path:str, mode:int) → rc:int[, errno:int]
static int LuaUnixGetcwd(lua_State *L) { static int LuaUnixGetcwd(lua_State *L) {
int olderr;
char *path; char *path;
path = getcwd(0, 0); olderr = errno;
assert(path); if ((path = getcwd(0, 0))) {
lua_pushstring(L, path); lua_pushstring(L, path);
free(path); free(path);
return 1; return 1;
} else {
return ReturnErrno(L, 1, olderr);
}
} }
// unix.fork() → childpid|0:int[, errno:int] // unix.fork() → childpid|0:int[, errno:int]
@ -374,9 +383,7 @@ static int LuaUnixExecve(lua_State *L) {
execve(prog, argv, envp); execve(prog, argv, envp);
FreeStringList(freeme1); FreeStringList(freeme1);
FreeStringList(freeme2); FreeStringList(freeme2);
lua_pushinteger(L, errno); return ReturnErrno(L, 1, olderr);
errno = olderr;
return 1;
} }
// unix.commandv(prog:str) → path:str[, errno:int] // unix.commandv(prog:str) → path:str[, errno:int]
@ -450,8 +457,8 @@ static int LuaUnixGetrlimit(lua_State *L) {
olderr = errno; olderr = errno;
resource = luaL_checkinteger(L, 1); resource = luaL_checkinteger(L, 1);
if (!getrlimit(resource, &rlim)) { if (!getrlimit(resource, &rlim)) {
lua_pushinteger(L, rlim.rlim_cur); lua_pushinteger(L, rlim.rlim_cur < RLIM_INFINITY ? rlim.rlim_cur : -1);
lua_pushinteger(L, rlim.rlim_max); lua_pushinteger(L, rlim.rlim_max < RLIM_INFINITY ? rlim.rlim_max : -1);
return 2; return 2;
} else { } else {
return ReturnErrno(L, 2, olderr); 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) { static int LuaUnixGetpeername(lua_State *L) {
int fd, olderr; int fd, olderr;
uint32_t addrsize; 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) { static int LuaUnixAccept(lua_State *L) {
uint32_t addrsize; uint32_t addrsize;
struct sockaddr_in sa; 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] // unix.recvfrom(fd[, bufsiz[, flags]]) → data, ip, port[, errno]
// flags can have MSG_{WAITALL,DONTROUTE,PEEK,OOB}, etc. // flags can have MSG_{WAITALL,DONTROUTE,PEEK,OOB}, etc.
static int LuaUnixRecvfrom(lua_State *L) { static int LuaUnixRecvfrom(lua_State *L) {
@ -1286,11 +1392,6 @@ static int LuaUnixWtermsig(lua_State *L) {
return ReturnInteger(L, WTERMSIG(luaL_checkinteger(L, 1))); 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 // UnixStat* object
@ -1568,10 +1669,12 @@ static const luaL_Reg kLuaUnix[] = {
{"setuid", LuaUnixSetuid}, // set real user id of process {"setuid", LuaUnixSetuid}, // set real user id of process
{"getgid", LuaUnixGetgid}, // get real group id of process {"getgid", LuaUnixGetgid}, // get real group id of process
{"setgid", LuaUnixSetgid}, // set 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 {"clock_gettime", LuaUnixGettime}, // get timestamp w/ nano precision
{"nanosleep", LuaUnixNanosleep}, // sleep w/ nano precision {"nanosleep", LuaUnixNanosleep}, // sleep w/ nano precision
{"socket", LuaUnixSocket}, // create network communication fd {"socket", LuaUnixSocket}, // create network communication fd
{"socketpair", LuaUnixSocketpair}, // create bidirectional pipe {"socketpair", LuaUnixSocketpair}, // create bidirectional pipe
{"poll", LuaUnixPoll}, // waits for file descriptor events
{"bind", LuaUnixBind}, // reserve network interface address {"bind", LuaUnixBind}, // reserve network interface address
{"listen", LuaUnixListen}, // begin listening for clients {"listen", LuaUnixListen}, // begin listening for clients
{"accept", LuaUnixAccept}, // create client fd for client {"accept", LuaUnixAccept}, // create client fd for client
@ -1583,11 +1686,11 @@ static const luaL_Reg kLuaUnix[] = {
{"shutdown", LuaUnixShutdown}, // make socket half empty or full {"shutdown", LuaUnixShutdown}, // make socket half empty or full
{"getpeername", LuaUnixGetpeername}, // get address of remote end {"getpeername", LuaUnixGetpeername}, // get address of remote end
{"getsockname", LuaUnixGetsockname}, // get address of local end {"getsockname", LuaUnixGetsockname}, // get address of local end
{"siocgifconf", LuaUnixSiocgifconf}, // get list of network interfaces
{"sigaction", LuaUnixSigaction}, // install signal handler {"sigaction", LuaUnixSigaction}, // install signal handler
{"sigprocmask", LuaUnixSigprocmask}, // change signal mask {"sigprocmask", LuaUnixSigprocmask}, // change signal mask
{"sigsuspend", LuaUnixSigsuspend}, // wait for signal {"sigsuspend", LuaUnixSigsuspend}, // wait for signal
{"setitimer", LuaUnixSetitimer}, // set alarm clock {"setitimer", LuaUnixSetitimer}, // set alarm clock
{"reboot", LuaUnixReboot}, // reboots system
{"strerror", LuaUnixStrerror}, // turn errno into string {"strerror", LuaUnixStrerror}, // turn errno into string
{"strerrno", LuaUnixStrerrno}, // turn errno into string {"strerrno", LuaUnixStrerrno}, // turn errno into string
{"strsignal", LuaUnixStrsignal}, // turn signal 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_INFO", LOG_INFO);
LuaSetIntField(L, "LOG_DEBUG", LOG_DEBUG); 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; return 1;
} }

View file

@ -171,7 +171,9 @@ o/tinylinux/tool/net/redbean.com: \
o/$(MODE)/tool/net/demo/.init.lua.zip.o \ o/$(MODE)/tool/net/demo/.init.lua.zip.o \
o/$(MODE)/tool/net/demo/.reload.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/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/fetch.lua.zip.o \
o/$(MODE)/tool/net/demo/hello.lua.zip.o \ o/$(MODE)/tool/net/demo/hello.lua.zip.o \
o/$(MODE)/tool/net/demo/maxmind.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/largon2.o \
o/$(MODE)/tool/net/net.pkg \ o/$(MODE)/tool/net/net.pkg \
o/$(MODE)/tool/net/demo/sql.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/unix2.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/fetch.lua.zip.o \
o/$(MODE)/tool/net/demo/hello.lua.zip.o \ o/$(MODE)/tool/net/demo/hello.lua.zip.o \
o/$(MODE)/tool/net/demo/redbean.lua.zip.o \ o/$(MODE)/tool/net/demo/redbean.lua.zip.o \

View file

@ -6608,45 +6608,65 @@ static int ExitWorker(void) {
static const struct sock_filter kSandboxOnline[] = { static const struct sock_filter kSandboxOnline[] = {
_SECCOMP_MACHINE(AUDIT_ARCH_X86_64), // _SECCOMP_MACHINE(AUDIT_ARCH_X86_64), //
_SECCOMP_LOAD_SYSCALL_NR(), // _SECCOMP_LOAD_SYSCALL_NR(), //
_SECCOMP_ALLOW_SYSCALL(0x0013), // readv _SECCOMP_ALLOW_SYSCALL(0x013), // readv
_SECCOMP_ALLOW_SYSCALL(0x0014), // writev _SECCOMP_ALLOW_SYSCALL(0x014), // writev
_SECCOMP_ALLOW_SYSCALL(0x0009), // mmap _SECCOMP_ALLOW_SYSCALL(0x009), // mmap
_SECCOMP_ALLOW_SYSCALL(0x000b), // munmap _SECCOMP_ALLOW_SYSCALL(0x00b), // munmap
_SECCOMP_ALLOW_SYSCALL(0x0000), // read _SECCOMP_ALLOW_SYSCALL(0x000), // read
_SECCOMP_ALLOW_SYSCALL(0x0001), // write _SECCOMP_ALLOW_SYSCALL(0x001), // write
_SECCOMP_ALLOW_SYSCALL(0x0003), // close _SECCOMP_ALLOW_SYSCALL(0x003), // close
_SECCOMP_ALLOW_SYSCALL(0x0008), // lseek _SECCOMP_ALLOW_SYSCALL(0x008), // lseek
_SECCOMP_ALLOW_SYSCALL(0x000f), // rt_sigreturn _SECCOMP_ALLOW_SYSCALL(0x04f), // getcwd
_SECCOMP_ALLOW_SYSCALL(0x00e7), // exit_group _SECCOMP_ALLOW_SYSCALL(0x027), // getpid
_SECCOMP_ALLOW_SYSCALL(0x0106), // newfstatat _SECCOMP_ALLOW_SYSCALL(0x066), // getuid
_SECCOMP_ALLOW_SYSCALL(0x00e4), // clock_gettime _SECCOMP_ALLOW_SYSCALL(0x068), // getgid
_SECCOMP_ALLOW_SYSCALL(0x003f), // uname _SECCOMP_ALLOW_SYSCALL(0x06e), // getppid
_SECCOMP_ALLOW_SYSCALL(0x0048), // fcntl _SECCOMP_ALLOW_SYSCALL(0x06f), // getpgrp
_SECCOMP_ALLOW_SYSCALL(0x0029), // socket _SECCOMP_ALLOW_SYSCALL(0x07c), // getsid
_SECCOMP_ALLOW_SYSCALL(0x002a), // connect _SECCOMP_ALLOW_SYSCALL(0x06b), // geteuid
_SECCOMP_ALLOW_SYSCALL(0x002c), // sendto _SECCOMP_ALLOW_SYSCALL(0x06c), // getegid
_SECCOMP_ALLOW_SYSCALL(0x002d), // recvfrom _SECCOMP_ALLOW_SYSCALL(0x061), // getrlimit
_SECCOMP_ALLOW_SYSCALL(0x0036), // setsockopt _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 _SECCOMP_LOG_AND_RETURN_ERRNO(1), // EPERM
}; };
static const struct sock_filter kSandboxOffline[] = { static const struct sock_filter kSandboxOffline[] = {
_SECCOMP_MACHINE(AUDIT_ARCH_X86_64), // _SECCOMP_MACHINE(AUDIT_ARCH_X86_64), //
_SECCOMP_LOAD_SYSCALL_NR(), // _SECCOMP_LOAD_SYSCALL_NR(), //
_SECCOMP_ALLOW_SYSCALL(0x0013), // readv _SECCOMP_ALLOW_SYSCALL(0x013), // readv
_SECCOMP_ALLOW_SYSCALL(0x0014), // writev _SECCOMP_ALLOW_SYSCALL(0x014), // writev
_SECCOMP_ALLOW_SYSCALL(0x0000), // read _SECCOMP_ALLOW_SYSCALL(0x000), // read
_SECCOMP_ALLOW_SYSCALL(0x0001), // write _SECCOMP_ALLOW_SYSCALL(0x001), // write
_SECCOMP_ALLOW_SYSCALL(0x0009), // mmap _SECCOMP_ALLOW_SYSCALL(0x009), // mmap
_SECCOMP_ALLOW_SYSCALL(0x000b), // munmap _SECCOMP_ALLOW_SYSCALL(0x00b), // munmap
_SECCOMP_ALLOW_SYSCALL(0x0003), // close _SECCOMP_ALLOW_SYSCALL(0x003), // close
_SECCOMP_ALLOW_SYSCALL(0x0008), // lseek _SECCOMP_ALLOW_SYSCALL(0x008), // lseek
_SECCOMP_ALLOW_SYSCALL(0x000f), // rt_sigreturn _SECCOMP_ALLOW_SYSCALL(0x04f), // getcwd
_SECCOMP_ALLOW_SYSCALL(0x00e7), // exit_group _SECCOMP_ALLOW_SYSCALL(0x027), // getpid
_SECCOMP_ALLOW_SYSCALL(0x0106), // newfstatat _SECCOMP_ALLOW_SYSCALL(0x066), // getuid
_SECCOMP_ALLOW_SYSCALL(0x00e4), // clock_gettime _SECCOMP_ALLOW_SYSCALL(0x068), // getgid
_SECCOMP_ALLOW_SYSCALL(0x003f), // uname _SECCOMP_ALLOW_SYSCALL(0x06e), // getppid
_SECCOMP_ALLOW_SYSCALL(0x0048), // fcntl _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 _SECCOMP_LOG_AND_RETURN_ERRNO(1), // EPERM
}; };