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

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

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) {
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;

View file

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

View file

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

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/.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 \

View file

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