2022-04-13 15:49:17 +00:00
|
|
|
/*-*- 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 │
|
|
|
|
│ │
|
|
|
|
│ Permission to use, copy, modify, and/or distribute this software for │
|
|
|
|
│ any purpose with or without fee is hereby granted, provided that the │
|
|
|
|
│ above copyright notice and this permission notice appear in all copies. │
|
|
|
|
│ │
|
|
|
|
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
|
|
|
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
|
|
|
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
|
|
|
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
|
|
|
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
|
|
|
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
|
|
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
|
|
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
|
|
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
2023-06-03 15:12:13 +00:00
|
|
|
#include "third_party/lua/lunix.h"
|
2022-04-13 15:49:17 +00:00
|
|
|
#include "libc/assert.h"
|
2022-10-06 11:55:26 +00:00
|
|
|
#include "libc/atomic.h"
|
2022-04-13 15:49:17 +00:00
|
|
|
#include "libc/calls/calls.h"
|
2022-11-06 02:49:41 +00:00
|
|
|
#include "libc/calls/cp.internal.h"
|
2022-04-21 20:44:59 +00:00
|
|
|
#include "libc/calls/ioctl.h"
|
2022-04-26 04:16:05 +00:00
|
|
|
#include "libc/calls/makedev.h"
|
2022-08-08 18:41:08 +00:00
|
|
|
#include "libc/calls/pledge.h"
|
2023-06-10 01:02:06 +00:00
|
|
|
#include "libc/calls/struct/bpf.internal.h"
|
2022-04-13 15:49:17 +00:00
|
|
|
#include "libc/calls/struct/dirent.h"
|
2022-08-17 06:23:34 +00:00
|
|
|
#include "libc/calls/struct/flock.h"
|
2022-04-13 21:43:42 +00:00
|
|
|
#include "libc/calls/struct/itimerval.h"
|
2022-08-13 20:11:56 +00:00
|
|
|
#include "libc/calls/struct/rlimit.h"
|
2022-04-28 16:42:36 +00:00
|
|
|
#include "libc/calls/struct/rusage.h"
|
2022-09-13 06:10:38 +00:00
|
|
|
#include "libc/calls/struct/sigaction.h"
|
2022-04-13 21:43:42 +00:00
|
|
|
#include "libc/calls/struct/siginfo.h"
|
2022-04-13 15:49:17 +00:00
|
|
|
#include "libc/calls/struct/sigset.h"
|
|
|
|
#include "libc/calls/struct/stat.h"
|
2022-08-18 06:27:17 +00:00
|
|
|
#include "libc/calls/struct/statfs.h"
|
2022-04-13 15:49:17 +00:00
|
|
|
#include "libc/calls/struct/timespec.h"
|
2022-04-24 16:59:22 +00:00
|
|
|
#include "libc/calls/struct/timeval.h"
|
2022-06-27 20:01:58 +00:00
|
|
|
#include "libc/calls/struct/winsize.h"
|
2022-04-13 21:43:42 +00:00
|
|
|
#include "libc/calls/ucontext.h"
|
2022-10-06 11:55:26 +00:00
|
|
|
#include "libc/dce.h"
|
2022-04-21 20:44:59 +00:00
|
|
|
#include "libc/dns/dns.h"
|
2022-04-13 15:49:17 +00:00
|
|
|
#include "libc/errno.h"
|
2022-07-20 22:13:39 +00:00
|
|
|
#include "libc/fmt/conv.h"
|
2022-04-13 15:49:17 +00:00
|
|
|
#include "libc/fmt/fmt.h"
|
2022-08-18 06:27:17 +00:00
|
|
|
#include "libc/fmt/itoa.h"
|
2022-04-24 16:59:22 +00:00
|
|
|
#include "libc/fmt/magnumstrs.internal.h"
|
2022-10-06 11:55:26 +00:00
|
|
|
#include "libc/intrin/atomic.h"
|
2022-08-13 20:11:56 +00:00
|
|
|
#include "libc/intrin/bits.h"
|
2022-09-13 06:10:38 +00:00
|
|
|
#include "libc/intrin/strace.internal.h"
|
2022-10-06 11:55:26 +00:00
|
|
|
#include "libc/limits.h"
|
2022-04-13 21:43:42 +00:00
|
|
|
#include "libc/log/log.h"
|
2022-04-13 15:49:17 +00:00
|
|
|
#include "libc/macros.internal.h"
|
|
|
|
#include "libc/mem/mem.h"
|
2022-04-26 04:16:05 +00:00
|
|
|
#include "libc/nt/runtime.h"
|
2022-10-06 11:55:26 +00:00
|
|
|
#include "libc/nt/synchronization.h"
|
2022-04-26 04:16:05 +00:00
|
|
|
#include "libc/runtime/clktck.h"
|
|
|
|
#include "libc/runtime/memtrack.internal.h"
|
2022-04-13 21:43:42 +00:00
|
|
|
#include "libc/runtime/runtime.h"
|
2022-10-06 11:55:26 +00:00
|
|
|
#include "libc/runtime/sysconf.h"
|
2022-04-13 15:49:17 +00:00
|
|
|
#include "libc/sock/sock.h"
|
2022-08-06 10:51:50 +00:00
|
|
|
#include "libc/sock/struct/ifconf.h"
|
|
|
|
#include "libc/sock/struct/linger.h"
|
|
|
|
#include "libc/sock/struct/pollfd.h"
|
2022-10-11 00:52:41 +00:00
|
|
|
#include "libc/sock/struct/sockaddr.h"
|
2022-04-18 15:54:42 +00:00
|
|
|
#include "libc/sock/syslog.h"
|
2022-09-13 06:10:38 +00:00
|
|
|
#include "libc/stdio/append.h"
|
2022-04-26 04:16:05 +00:00
|
|
|
#include "libc/stdio/stdio.h"
|
2022-07-20 22:13:39 +00:00
|
|
|
#include "libc/str/path.h"
|
2022-04-13 15:49:17 +00:00
|
|
|
#include "libc/str/str.h"
|
|
|
|
#include "libc/sysv/consts/af.h"
|
|
|
|
#include "libc/sysv/consts/at.h"
|
|
|
|
#include "libc/sysv/consts/clock.h"
|
|
|
|
#include "libc/sysv/consts/dt.h"
|
|
|
|
#include "libc/sysv/consts/f.h"
|
|
|
|
#include "libc/sysv/consts/fd.h"
|
2022-04-24 16:59:22 +00:00
|
|
|
#include "libc/sysv/consts/ip.h"
|
2022-04-13 15:49:17 +00:00
|
|
|
#include "libc/sysv/consts/ipproto.h"
|
2022-04-13 21:43:42 +00:00
|
|
|
#include "libc/sysv/consts/itimer.h"
|
2022-04-26 04:16:05 +00:00
|
|
|
#include "libc/sysv/consts/limits.h"
|
2022-04-18 15:54:42 +00:00
|
|
|
#include "libc/sysv/consts/log.h"
|
2022-10-06 11:55:26 +00:00
|
|
|
#include "libc/sysv/consts/map.h"
|
2022-04-13 15:49:17 +00:00
|
|
|
#include "libc/sysv/consts/msg.h"
|
2022-04-18 07:01:26 +00:00
|
|
|
#include "libc/sysv/consts/nr.h"
|
2022-04-13 15:49:17 +00:00
|
|
|
#include "libc/sysv/consts/o.h"
|
|
|
|
#include "libc/sysv/consts/ok.h"
|
2022-04-22 02:13:19 +00:00
|
|
|
#include "libc/sysv/consts/poll.h"
|
2022-10-06 11:55:26 +00:00
|
|
|
#include "libc/sysv/consts/prot.h"
|
2022-04-21 20:44:59 +00:00
|
|
|
#include "libc/sysv/consts/rlim.h"
|
2022-04-18 07:01:26 +00:00
|
|
|
#include "libc/sysv/consts/rlimit.h"
|
2022-04-28 16:42:36 +00:00
|
|
|
#include "libc/sysv/consts/rusage.h"
|
2022-06-24 00:37:07 +00:00
|
|
|
#include "libc/sysv/consts/s.h"
|
2022-04-13 15:49:17 +00:00
|
|
|
#include "libc/sysv/consts/sa.h"
|
|
|
|
#include "libc/sysv/consts/shut.h"
|
|
|
|
#include "libc/sysv/consts/sig.h"
|
2022-04-21 20:44:59 +00:00
|
|
|
#include "libc/sysv/consts/sio.h"
|
2022-04-24 16:59:22 +00:00
|
|
|
#include "libc/sysv/consts/so.h"
|
2022-04-13 15:49:17 +00:00
|
|
|
#include "libc/sysv/consts/sock.h"
|
2022-04-24 16:59:22 +00:00
|
|
|
#include "libc/sysv/consts/sol.h"
|
2022-08-18 06:27:17 +00:00
|
|
|
#include "libc/sysv/consts/st.h"
|
2022-04-24 16:59:22 +00:00
|
|
|
#include "libc/sysv/consts/tcp.h"
|
2022-06-18 08:10:29 +00:00
|
|
|
#include "libc/sysv/consts/utime.h"
|
2022-04-13 15:49:17 +00:00
|
|
|
#include "libc/sysv/consts/w.h"
|
2022-04-21 20:44:59 +00:00
|
|
|
#include "libc/sysv/errfuns.h"
|
2022-10-06 11:55:26 +00:00
|
|
|
#include "libc/thread/thread.h"
|
2022-04-26 04:16:05 +00:00
|
|
|
#include "libc/time/struct/tm.h"
|
2022-04-13 15:49:17 +00:00
|
|
|
#include "libc/time/time.h"
|
|
|
|
#include "libc/x/x.h"
|
2022-04-25 15:30:14 +00:00
|
|
|
#include "third_party/lua/cosmo.h"
|
2022-04-13 15:49:17 +00:00
|
|
|
#include "third_party/lua/lauxlib.h"
|
2022-04-26 04:16:05 +00:00
|
|
|
#include "third_party/lua/lgc.h"
|
2022-04-13 15:49:17 +00:00
|
|
|
#include "third_party/lua/lua.h"
|
|
|
|
#include "third_party/lua/luaconf.h"
|
2022-10-06 11:55:26 +00:00
|
|
|
#include "third_party/nsync/futex.internal.h"
|
2022-04-13 21:43:42 +00:00
|
|
|
#include "tool/net/luacheck.h"
|
2022-04-13 15:49:17 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @fileoverview UNIX system calls thinly wrapped for Lua
|
|
|
|
* @support Linux, Mac, Windows, FreeBSD, NetBSD, OpenBSD
|
|
|
|
*/
|
|
|
|
|
2022-04-13 21:43:42 +00:00
|
|
|
static lua_State *GL;
|
|
|
|
|
2022-05-29 21:47:14 +00:00
|
|
|
static void *LuaRealloc(lua_State *L, void *p, size_t n) {
|
2022-04-26 04:16:05 +00:00
|
|
|
void *p2;
|
|
|
|
if ((p2 = realloc(p, n))) {
|
|
|
|
return p2;
|
|
|
|
}
|
|
|
|
if (IsLegalSize(n)) {
|
2022-05-14 11:33:58 +00:00
|
|
|
WARNF("reacting to malloc() failure by running lua garbage collector...");
|
2022-04-26 04:16:05 +00:00
|
|
|
luaC_fullgc(L, 1);
|
|
|
|
p2 = realloc(p, n);
|
|
|
|
}
|
|
|
|
return p2;
|
|
|
|
}
|
|
|
|
|
2022-05-29 21:47:14 +00:00
|
|
|
static void *LuaAlloc(lua_State *L, size_t n) {
|
2022-05-16 23:49:20 +00:00
|
|
|
return LuaRealloc(L, 0, n);
|
2022-04-26 04:16:05 +00:00
|
|
|
}
|
|
|
|
|
2022-05-29 21:47:14 +00:00
|
|
|
static void *LuaAllocOrDie(lua_State *L, size_t n) {
|
2022-05-29 15:14:55 +00:00
|
|
|
void *p;
|
|
|
|
if ((p = LuaAlloc(L, n))) {
|
|
|
|
return p;
|
|
|
|
} else {
|
|
|
|
luaL_error(L, "out of memory");
|
2023-06-09 06:44:03 +00:00
|
|
|
__builtin_unreachable();
|
2022-05-29 15:14:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-28 16:42:36 +00:00
|
|
|
static lua_Integer FixLimit(long x) {
|
|
|
|
if (0 <= x && x < RLIM_INFINITY) {
|
|
|
|
return x;
|
|
|
|
} else {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
static void LuaPushSigset(lua_State *L, struct sigset set) {
|
2022-04-27 12:39:39 +00:00
|
|
|
struct sigset *sp = lua_newuserdatauv(L, sizeof(*sp), 1);
|
2022-04-26 04:16:05 +00:00
|
|
|
luaL_setmetatable(L, "unix.Sigset");
|
|
|
|
*sp = set;
|
|
|
|
}
|
|
|
|
|
2022-04-27 12:39:39 +00:00
|
|
|
static void LuaPushStat(lua_State *L, struct stat *st) {
|
|
|
|
struct stat *stp = lua_newuserdatauv(L, sizeof(*stp), 1);
|
|
|
|
luaL_setmetatable(L, "unix.Stat");
|
|
|
|
*stp = *st;
|
|
|
|
}
|
|
|
|
|
2022-08-18 06:27:17 +00:00
|
|
|
static void LuaPushStatfs(lua_State *L, struct statfs *st) {
|
|
|
|
struct statfs *stp = lua_newuserdatauv(L, sizeof(*stp), 1);
|
|
|
|
luaL_setmetatable(L, "unix.Statfs");
|
|
|
|
*stp = *st;
|
|
|
|
}
|
|
|
|
|
2022-04-28 16:42:36 +00:00
|
|
|
static void LuaPushRusage(lua_State *L, struct rusage *set) {
|
|
|
|
struct rusage *sp = lua_newuserdatauv(L, sizeof(*sp), 1);
|
|
|
|
luaL_setmetatable(L, "unix.Rusage");
|
|
|
|
*sp = *set;
|
|
|
|
}
|
|
|
|
|
2022-04-13 15:49:17 +00:00
|
|
|
static void LuaSetIntField(lua_State *L, const char *k, lua_Integer v) {
|
|
|
|
lua_pushinteger(L, v);
|
|
|
|
lua_setfield(L, -2, k);
|
|
|
|
}
|
|
|
|
|
|
|
|
static dontinline int ReturnInteger(lua_State *L, lua_Integer x) {
|
|
|
|
lua_pushinteger(L, x);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
static dontinline int ReturnBoolean(lua_State *L, int x) {
|
|
|
|
lua_pushboolean(L, !!x);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2022-04-21 11:01:42 +00:00
|
|
|
static dontinline int ReturnString(lua_State *L, const char *x) {
|
|
|
|
lua_pushstring(L, x);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2022-07-20 22:13:39 +00:00
|
|
|
int LuaUnixSysretErrno(lua_State *L, const char *call, int olderr) {
|
2022-04-27 12:39:39 +00:00
|
|
|
struct UnixErrno *ep;
|
2022-04-26 04:16:05 +00:00
|
|
|
int i, unixerr, winerr;
|
|
|
|
unixerr = errno;
|
2023-07-10 02:47:46 +00:00
|
|
|
winerr = IsWindows() ? GetLastError() : 0;
|
2022-04-26 04:16:05 +00:00
|
|
|
if (!IsTiny() && !(0 < unixerr && unixerr < (!IsWindows() ? 4096 : 65536))) {
|
|
|
|
WARNF("errno should not be %d", unixerr);
|
2022-04-18 15:54:42 +00:00
|
|
|
}
|
2022-04-26 04:16:05 +00:00
|
|
|
lua_pushnil(L);
|
2022-04-27 12:39:39 +00:00
|
|
|
ep = lua_newuserdatauv(L, sizeof(*ep), 1);
|
|
|
|
luaL_setmetatable(L, "unix.Errno");
|
2022-05-16 20:20:08 +00:00
|
|
|
ep->errno_ = unixerr;
|
2022-04-27 12:39:39 +00:00
|
|
|
ep->winerr = winerr;
|
|
|
|
ep->call = call;
|
2022-04-18 15:54:42 +00:00
|
|
|
errno = olderr;
|
2022-04-25 15:30:14 +00:00
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
|
2022-07-20 22:13:39 +00:00
|
|
|
static int SysretBool(lua_State *L, const char *call, int olderr, int rc) {
|
2022-04-24 16:59:22 +00:00
|
|
|
if (!IsTiny() && (rc != 0 && rc != -1)) {
|
|
|
|
WARNF("syscall supposed to return 0 / -1 but got %d", rc);
|
|
|
|
}
|
|
|
|
if (rc != -1) {
|
2022-04-25 15:30:14 +00:00
|
|
|
lua_pushboolean(L, true);
|
2022-04-26 12:20:53 +00:00
|
|
|
return 1;
|
2022-04-24 16:59:22 +00:00
|
|
|
} else {
|
2022-07-20 22:13:39 +00:00
|
|
|
return LuaUnixSysretErrno(L, call, olderr);
|
2022-04-24 16:59:22 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
static int SysretInteger(lua_State *L, const char *call, int olderr,
|
|
|
|
int64_t rc) {
|
2022-04-21 20:44:59 +00:00
|
|
|
if (rc != -1) {
|
2022-04-24 16:59:22 +00:00
|
|
|
if (!IsTiny() && olderr != errno) {
|
|
|
|
WARNF("errno unexpectedly changed %d → %d", olderr, errno);
|
|
|
|
}
|
2022-04-21 20:44:59 +00:00
|
|
|
lua_pushinteger(L, rc);
|
|
|
|
return 1;
|
|
|
|
} else {
|
2022-07-20 22:13:39 +00:00
|
|
|
return LuaUnixSysretErrno(L, call, olderr);
|
2022-04-21 20:44:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-06-23 10:39:44 +00:00
|
|
|
static int MakeSockaddr(lua_State *L, int i, struct sockaddr_storage *ss,
|
2022-06-22 10:04:25 +00:00
|
|
|
uint32_t *salen) {
|
2022-06-23 10:39:44 +00:00
|
|
|
bzero(ss, sizeof(*ss));
|
|
|
|
if (!lua_isinteger(L, i)) {
|
|
|
|
((struct sockaddr_un *)ss)->sun_family = AF_UNIX;
|
|
|
|
if (!memccpy(((struct sockaddr_un *)ss)->sun_path, luaL_checkstring(L, i),
|
|
|
|
0, sizeof(((struct sockaddr_un *)ss)->sun_path))) {
|
2022-06-22 10:04:25 +00:00
|
|
|
luaL_error(L, "unix path too long");
|
2023-06-09 06:44:03 +00:00
|
|
|
__builtin_unreachable();
|
2022-06-22 10:04:25 +00:00
|
|
|
}
|
|
|
|
*salen = sizeof(struct sockaddr_un);
|
|
|
|
return i + 1;
|
|
|
|
} else {
|
2022-06-23 10:39:44 +00:00
|
|
|
((struct sockaddr_in *)ss)->sin_family = AF_INET;
|
|
|
|
((struct sockaddr_in *)ss)->sin_addr.s_addr =
|
|
|
|
htonl(luaL_optinteger(L, i, 0));
|
|
|
|
((struct sockaddr_in *)ss)->sin_port = htons(luaL_optinteger(L, i + 1, 0));
|
2022-06-22 10:04:25 +00:00
|
|
|
*salen = sizeof(struct sockaddr_in);
|
|
|
|
return i + 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static int PushSockaddr(lua_State *L, const struct sockaddr_storage *ss) {
|
|
|
|
if (ss->ss_family == AF_INET) {
|
|
|
|
lua_pushinteger(L,
|
|
|
|
ntohl(((const struct sockaddr_in *)ss)->sin_addr.s_addr));
|
|
|
|
lua_pushinteger(L, ntohs(((const struct sockaddr_in *)ss)->sin_port));
|
|
|
|
return 2;
|
|
|
|
} else if (ss->ss_family == AF_UNIX) {
|
|
|
|
lua_pushstring(L, ((const struct sockaddr_un *)ss)->sun_path);
|
|
|
|
return 1;
|
|
|
|
} else {
|
|
|
|
luaL_error(L, "bad family");
|
2023-06-09 06:44:03 +00:00
|
|
|
__builtin_unreachable();
|
2022-06-22 10:04:25 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-24 16:59:22 +00:00
|
|
|
static void CheckOptvalsize(lua_State *L, uint32_t want, uint32_t got) {
|
|
|
|
if (!IsTiny()) {
|
|
|
|
if (want == got) return;
|
|
|
|
WARNF("getsockopt optvalsize should be %d but was %d", want, got);
|
2022-04-21 11:01:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-13 21:43:42 +00:00
|
|
|
static void FreeStringList(char **p) {
|
|
|
|
int i;
|
|
|
|
if (p) {
|
|
|
|
for (i = 0; p[i]; ++i) {
|
|
|
|
free(p[i]);
|
|
|
|
}
|
|
|
|
free(p);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-24 16:59:22 +00:00
|
|
|
static char **ConvertLuaArrayToStringList(lua_State *L, int i) {
|
|
|
|
int j, n;
|
|
|
|
char **p, *s;
|
|
|
|
luaL_checktype(L, i, LUA_TTABLE);
|
|
|
|
lua_len(L, i);
|
|
|
|
n = lua_tointeger(L, -1);
|
|
|
|
lua_pop(L, 1);
|
2022-05-16 23:49:20 +00:00
|
|
|
if ((p = LuaAlloc(L, (n + 1) * sizeof(*p)))) {
|
2022-04-24 16:59:22 +00:00
|
|
|
for (j = 1; j <= n; ++j) {
|
|
|
|
lua_geti(L, i, j);
|
|
|
|
s = strdup(lua_tostring(L, -1));
|
|
|
|
lua_pop(L, 1);
|
|
|
|
if (s) {
|
|
|
|
p[j - 1] = s;
|
|
|
|
} else {
|
|
|
|
FreeStringList(p);
|
|
|
|
p = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2022-04-26 04:16:05 +00:00
|
|
|
p[j - 1] = 0;
|
2022-04-24 16:59:22 +00:00
|
|
|
}
|
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
2022-04-13 15:49:17 +00:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// System Calls
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.exit([exitcode:int])
|
|
|
|
// └─→ ⊥
|
|
|
|
static wontreturn int LuaUnixExit(lua_State *L) {
|
|
|
|
_Exit(luaL_optinteger(L, 1, 0));
|
|
|
|
}
|
|
|
|
|
2022-04-25 15:30:14 +00:00
|
|
|
static dontinline int LuaUnixGetid(lua_State *L, int f(void)) {
|
|
|
|
return ReturnInteger(L, f());
|
|
|
|
}
|
|
|
|
|
2022-09-18 09:48:53 +00:00
|
|
|
static dontinline int LuaUnixGetUnsignedid(lua_State *L, unsigned f(void)) {
|
|
|
|
return ReturnInteger(L, f());
|
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.getpid()
|
|
|
|
// └─→ pid:int
|
2022-04-21 11:01:42 +00:00
|
|
|
static int LuaUnixGetpid(lua_State *L) {
|
2022-04-25 15:30:14 +00:00
|
|
|
return LuaUnixGetid(L, getpid);
|
2022-04-21 11:01:42 +00:00
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.getppid()
|
|
|
|
// └─→ pid:int
|
2022-04-21 11:01:42 +00:00
|
|
|
static int LuaUnixGetppid(lua_State *L) {
|
2022-04-25 15:30:14 +00:00
|
|
|
return LuaUnixGetid(L, getppid);
|
2022-04-21 11:01:42 +00:00
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.getuid()
|
|
|
|
// └─→ uid:int
|
2022-04-21 11:01:42 +00:00
|
|
|
static int LuaUnixGetuid(lua_State *L) {
|
2022-09-18 09:48:53 +00:00
|
|
|
return LuaUnixGetUnsignedid(L, getuid);
|
2022-04-21 11:01:42 +00:00
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.getgid()
|
|
|
|
// └─→ gid:int
|
2022-04-21 11:01:42 +00:00
|
|
|
static int LuaUnixGetgid(lua_State *L) {
|
2022-09-18 09:48:53 +00:00
|
|
|
return LuaUnixGetUnsignedid(L, getgid);
|
2022-04-21 11:01:42 +00:00
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.geteuid()
|
|
|
|
// └─→ uid:int
|
2022-04-24 16:59:22 +00:00
|
|
|
static int LuaUnixGeteuid(lua_State *L) {
|
2022-09-18 09:48:53 +00:00
|
|
|
return LuaUnixGetUnsignedid(L, geteuid);
|
2022-04-24 16:59:22 +00:00
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.getegid()
|
|
|
|
// └─→ gid:int
|
2022-04-24 16:59:22 +00:00
|
|
|
static int LuaUnixGetegid(lua_State *L) {
|
2022-09-18 09:48:53 +00:00
|
|
|
return LuaUnixGetUnsignedid(L, getegid);
|
2022-04-24 16:59:22 +00:00
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.umask(newmask:int)
|
|
|
|
// └─→ oldmask:int
|
2022-04-21 11:01:42 +00:00
|
|
|
static int LuaUnixUmask(lua_State *L) {
|
|
|
|
return ReturnInteger(L, umask(luaL_checkinteger(L, 1)));
|
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.access(path:str, how:int[, flags:int[, dirfd:int]])
|
|
|
|
// ├─→ true
|
|
|
|
// └─→ nil, unix.Errno
|
2022-04-13 15:49:17 +00:00
|
|
|
static int LuaUnixAccess(lua_State *L) {
|
2022-04-24 16:59:22 +00:00
|
|
|
int olderr = errno;
|
2022-04-26 04:16:05 +00:00
|
|
|
return SysretBool(
|
|
|
|
L, "access", olderr,
|
|
|
|
faccessat(luaL_optinteger(L, 3, AT_FDCWD), luaL_checkstring(L, 1),
|
|
|
|
luaL_checkinteger(L, 2), luaL_optinteger(L, 4, 0)));
|
2022-04-13 15:49:17 +00:00
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.mkdir(path:str[, mode:int[, dirfd:int]])
|
|
|
|
// ├─→ true
|
|
|
|
// └─→ nil, unix.Errno
|
2022-04-13 15:49:17 +00:00
|
|
|
static int LuaUnixMkdir(lua_State *L) {
|
2022-04-24 16:59:22 +00:00
|
|
|
int olderr = errno;
|
2022-04-25 15:30:14 +00:00
|
|
|
return SysretBool(
|
2022-04-26 04:16:05 +00:00
|
|
|
L, "mkdir", olderr,
|
|
|
|
mkdirat(luaL_optinteger(L, 3, AT_FDCWD), luaL_checkstring(L, 1),
|
|
|
|
luaL_optinteger(L, 2, 0755)));
|
2022-04-13 15:49:17 +00:00
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.makedirs(path:str[, mode:int])
|
|
|
|
// ├─→ true
|
|
|
|
// └─→ nil, unix.Errno
|
2022-04-18 15:54:42 +00:00
|
|
|
static int LuaUnixMakedirs(lua_State *L) {
|
2022-04-24 16:59:22 +00:00
|
|
|
int olderr = errno;
|
2022-04-25 15:30:14 +00:00
|
|
|
return SysretBool(
|
2022-04-26 04:16:05 +00:00
|
|
|
L, "makedirs", olderr,
|
|
|
|
makedirs(luaL_checkstring(L, 1), luaL_optinteger(L, 2, 0755)));
|
2022-04-18 15:54:42 +00:00
|
|
|
}
|
|
|
|
|
2022-07-09 06:06:46 +00:00
|
|
|
// unix.rmrf(path:str)
|
|
|
|
// ├─→ true
|
|
|
|
// └─→ nil, unix.Errno
|
|
|
|
static int LuaUnixRmrf(lua_State *L) {
|
|
|
|
int olderr = errno;
|
|
|
|
return SysretBool(L, "rmrf", olderr, rmrf(luaL_checkstring(L, 1)));
|
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.chdir(path:str)
|
|
|
|
// ├─→ true
|
|
|
|
// └─→ nil, unix.Errno
|
2022-04-13 15:49:17 +00:00
|
|
|
static int LuaUnixChdir(lua_State *L) {
|
2022-04-24 16:59:22 +00:00
|
|
|
int olderr = errno;
|
2022-04-26 04:16:05 +00:00
|
|
|
return SysretBool(L, "chdir", olderr, chdir(luaL_checkstring(L, 1)));
|
2022-04-13 15:49:17 +00:00
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.unlink(path:str[, dirfd:int])
|
|
|
|
// ├─→ true
|
|
|
|
// └─→ nil, unix.Errno
|
2022-04-13 15:49:17 +00:00
|
|
|
static int LuaUnixUnlink(lua_State *L) {
|
2022-04-24 16:59:22 +00:00
|
|
|
int olderr = errno;
|
2022-04-26 04:16:05 +00:00
|
|
|
return SysretBool(
|
|
|
|
L, "unlink", olderr,
|
|
|
|
unlinkat(luaL_optinteger(L, 2, AT_FDCWD), luaL_checkstring(L, 1), 0));
|
2022-04-13 15:49:17 +00:00
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.rmdir(path:str[, dirfd:int])
|
|
|
|
// ├─→ true
|
|
|
|
// └─→ nil, unix.Errno
|
2022-04-13 15:49:17 +00:00
|
|
|
static int LuaUnixRmdir(lua_State *L) {
|
2022-04-24 16:59:22 +00:00
|
|
|
int olderr = errno;
|
2022-04-26 04:16:05 +00:00
|
|
|
return SysretBool(L, "rmdir", olderr,
|
|
|
|
unlinkat(luaL_optinteger(L, 2, AT_FDCWD),
|
|
|
|
luaL_checkstring(L, 1), AT_REMOVEDIR));
|
2022-04-13 15:49:17 +00:00
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.rename(oldpath:str, newpath:str[, olddirfd:int, newdirfd:int])
|
|
|
|
// ├─→ true
|
|
|
|
// └─→ nil, unix.Errno
|
2022-04-13 15:49:17 +00:00
|
|
|
static int LuaUnixRename(lua_State *L) {
|
2022-04-24 16:59:22 +00:00
|
|
|
int olderr = errno;
|
2022-04-26 04:16:05 +00:00
|
|
|
return SysretBool(
|
|
|
|
L, "rename", olderr,
|
|
|
|
renameat(luaL_optinteger(L, 3, AT_FDCWD), luaL_checkstring(L, 1),
|
|
|
|
luaL_optinteger(L, 4, AT_FDCWD), luaL_checkstring(L, 2)));
|
2022-04-13 15:49:17 +00:00
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.link(existingpath:str, newpath:str[, flags:int[, olddirfd, newdirfd]])
|
|
|
|
// ├─→ true
|
|
|
|
// └─→ nil, unix.Errno
|
2022-04-13 15:49:17 +00:00
|
|
|
static int LuaUnixLink(lua_State *L) {
|
2022-04-24 16:59:22 +00:00
|
|
|
int olderr = errno;
|
2022-04-26 04:16:05 +00:00
|
|
|
return SysretBool(
|
|
|
|
L, "link", olderr,
|
|
|
|
linkat(luaL_optinteger(L, 4, AT_FDCWD), luaL_checkstring(L, 1),
|
|
|
|
luaL_optinteger(L, 5, AT_FDCWD), luaL_checkstring(L, 2),
|
|
|
|
luaL_optinteger(L, 3, 0)));
|
2022-04-13 15:49:17 +00:00
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.symlink(target:str, linkpath:str[, newdirfd:int])
|
|
|
|
// ├─→ true
|
|
|
|
// └─→ nil, unix.Errno
|
2022-04-13 15:49:17 +00:00
|
|
|
static int LuaUnixSymlink(lua_State *L) {
|
2022-04-24 16:59:22 +00:00
|
|
|
int olderr = errno;
|
2022-04-26 04:16:05 +00:00
|
|
|
return SysretBool(
|
|
|
|
L, "symlink", olderr,
|
|
|
|
symlinkat(luaL_checkstring(L, 1), luaL_optinteger(L, 3, AT_FDCWD),
|
|
|
|
luaL_checkstring(L, 2)));
|
2022-04-13 15:49:17 +00:00
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.chown(path:str, uid:int, gid:int[, flags:int[, dirfd:int]])
|
|
|
|
// ├─→ true
|
|
|
|
// └─→ nil, unix.Errno
|
2022-04-13 15:49:17 +00:00
|
|
|
static int LuaUnixChown(lua_State *L) {
|
2022-04-24 16:59:22 +00:00
|
|
|
int olderr = errno;
|
2022-04-26 04:16:05 +00:00
|
|
|
return SysretBool(
|
|
|
|
L, "chown", olderr,
|
|
|
|
fchownat(luaL_optinteger(L, 5, AT_FDCWD), luaL_checkstring(L, 1),
|
|
|
|
luaL_checkinteger(L, 2), luaL_checkinteger(L, 3),
|
|
|
|
luaL_optinteger(L, 4, 0)));
|
2022-04-13 15:49:17 +00:00
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.chmod(path:str, mode:int[, flags:int[, dirfd:int]])
|
|
|
|
// ├─→ true
|
|
|
|
// └─→ nil, unix.Errno
|
2022-04-13 15:49:17 +00:00
|
|
|
static int LuaUnixChmod(lua_State *L) {
|
2022-04-24 16:59:22 +00:00
|
|
|
int olderr = errno;
|
2022-04-26 04:16:05 +00:00
|
|
|
return SysretBool(
|
|
|
|
L, "chmod", olderr,
|
|
|
|
fchmodat(luaL_optinteger(L, 4, AT_FDCWD), luaL_checkstring(L, 1),
|
|
|
|
luaL_checkinteger(L, 2), luaL_optinteger(L, 3, 0)));
|
2022-04-13 15:49:17 +00:00
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.readlink(path:str[, dirfd:int])
|
|
|
|
// ├─→ content:str
|
|
|
|
// └─→ nil, unix.Errno
|
|
|
|
static int LuaUnixReadlink(lua_State *L) {
|
2022-07-22 20:44:00 +00:00
|
|
|
size_t got;
|
2022-04-26 04:16:05 +00:00
|
|
|
ssize_t rc;
|
2022-07-22 20:44:00 +00:00
|
|
|
luaL_Buffer lb;
|
|
|
|
int olderr = errno;
|
|
|
|
if ((rc = readlinkat(luaL_optinteger(L, 2, AT_FDCWD), luaL_checkstring(L, 1),
|
|
|
|
luaL_buffinitsize(L, &lb, BUFSIZ), BUFSIZ)) != -1) {
|
|
|
|
if ((got = rc) < BUFSIZ) {
|
|
|
|
luaL_pushresultsize(&lb, got);
|
2022-05-29 15:14:55 +00:00
|
|
|
return 1;
|
|
|
|
} else {
|
|
|
|
enametoolong();
|
2022-04-26 04:16:05 +00:00
|
|
|
}
|
|
|
|
}
|
2022-07-20 22:13:39 +00:00
|
|
|
return LuaUnixSysretErrno(L, "readlink", olderr);
|
2022-04-26 04:16:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// unix.getcwd()
|
|
|
|
// ├─→ path:str
|
|
|
|
// └─→ nil, unix.Errno
|
2022-04-13 15:49:17 +00:00
|
|
|
static int LuaUnixGetcwd(lua_State *L) {
|
|
|
|
char *path;
|
2022-05-11 09:50:03 +00:00
|
|
|
int olderr = errno;
|
2022-04-21 20:44:59 +00:00
|
|
|
if ((path = getcwd(0, 0))) {
|
|
|
|
lua_pushstring(L, path);
|
|
|
|
free(path);
|
|
|
|
return 1;
|
|
|
|
} else {
|
2022-07-20 22:13:39 +00:00
|
|
|
return LuaUnixSysretErrno(L, "getcwd", olderr);
|
2022-04-21 20:44:59 +00:00
|
|
|
}
|
2022-04-13 15:49:17 +00:00
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.fork()
|
|
|
|
// ├─┬─→ 0
|
|
|
|
// │ └─→ childpid:int
|
|
|
|
// └─→ nil, unix.Errno
|
2022-04-13 15:49:17 +00:00
|
|
|
static int LuaUnixFork(lua_State *L) {
|
2022-04-24 16:59:22 +00:00
|
|
|
int olderr = errno;
|
2022-04-26 04:16:05 +00:00
|
|
|
return SysretInteger(L, "fork", olderr, fork());
|
2022-04-24 16:59:22 +00:00
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.environ()
|
|
|
|
// └─→ {str,...}
|
2022-04-24 16:59:22 +00:00
|
|
|
static int LuaUnixEnviron(lua_State *L) {
|
|
|
|
int i;
|
|
|
|
char **e;
|
|
|
|
lua_newtable(L);
|
|
|
|
for (i = 0, e = environ; *e; ++e) {
|
|
|
|
lua_pushstring(L, *e);
|
|
|
|
lua_rawseti(L, -2, ++i);
|
|
|
|
}
|
|
|
|
return 1;
|
2022-04-13 15:49:17 +00:00
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.execve(prog:str[, args:List<*>, env:List<*>])
|
|
|
|
// └─→ nil, unix.Errno
|
2022-04-13 21:43:42 +00:00
|
|
|
static int LuaUnixExecve(lua_State *L) {
|
|
|
|
int olderr;
|
|
|
|
const char *prog;
|
2022-04-21 11:01:42 +00:00
|
|
|
char **argv, **envp, **freeme1, **freeme2, *ezargs[2];
|
2022-04-13 21:43:42 +00:00
|
|
|
olderr = errno;
|
|
|
|
prog = luaL_checkstring(L, 1);
|
2022-04-21 11:01:42 +00:00
|
|
|
if (!lua_isnoneornil(L, 2)) {
|
2022-04-24 16:59:22 +00:00
|
|
|
if ((argv = ConvertLuaArrayToStringList(L, 2))) {
|
|
|
|
freeme1 = argv;
|
|
|
|
if (!lua_isnoneornil(L, 3)) {
|
|
|
|
if ((envp = ConvertLuaArrayToStringList(L, 3))) {
|
|
|
|
freeme2 = envp;
|
|
|
|
} else {
|
|
|
|
FreeStringList(argv);
|
2022-07-20 22:13:39 +00:00
|
|
|
return LuaUnixSysretErrno(L, "execve", olderr);
|
2022-04-24 16:59:22 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
envp = environ;
|
|
|
|
freeme2 = 0;
|
|
|
|
}
|
2022-04-21 11:01:42 +00:00
|
|
|
} else {
|
2022-07-20 22:13:39 +00:00
|
|
|
return LuaUnixSysretErrno(L, "execve", olderr);
|
2022-04-21 11:01:42 +00:00
|
|
|
}
|
2022-04-13 21:43:42 +00:00
|
|
|
} else {
|
2022-04-21 11:01:42 +00:00
|
|
|
ezargs[0] = prog;
|
|
|
|
ezargs[1] = 0;
|
|
|
|
argv = ezargs;
|
2022-04-13 21:43:42 +00:00
|
|
|
envp = environ;
|
2022-04-21 11:01:42 +00:00
|
|
|
freeme1 = 0;
|
|
|
|
freeme2 = 0;
|
2022-04-13 21:43:42 +00:00
|
|
|
}
|
|
|
|
execve(prog, argv, envp);
|
2022-04-21 11:01:42 +00:00
|
|
|
FreeStringList(freeme1);
|
|
|
|
FreeStringList(freeme2);
|
2022-07-20 22:13:39 +00:00
|
|
|
return LuaUnixSysretErrno(L, "execve", olderr);
|
2022-04-13 21:43:42 +00:00
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.commandv(prog:str)
|
|
|
|
// ├─→ path:str
|
|
|
|
// └─→ nil, unix.Errno
|
2022-04-13 21:43:42 +00:00
|
|
|
static int LuaUnixCommandv(lua_State *L) {
|
2022-04-24 16:59:22 +00:00
|
|
|
int olderr;
|
2022-04-13 21:43:42 +00:00
|
|
|
const char *prog;
|
|
|
|
char *pathbuf, *resolved;
|
|
|
|
olderr = errno;
|
2022-04-24 16:59:22 +00:00
|
|
|
prog = luaL_checkstring(L, 1);
|
2022-05-29 15:14:55 +00:00
|
|
|
pathbuf = LuaAllocOrDie(L, PATH_MAX);
|
|
|
|
if ((resolved = commandv(prog, pathbuf, PATH_MAX))) {
|
|
|
|
lua_pushstring(L, resolved);
|
|
|
|
free(pathbuf);
|
|
|
|
return 1;
|
2022-04-13 21:43:42 +00:00
|
|
|
} else {
|
2022-05-29 15:14:55 +00:00
|
|
|
free(pathbuf);
|
2022-07-20 22:13:39 +00:00
|
|
|
return LuaUnixSysretErrno(L, "commandv", olderr);
|
2022-04-13 21:43:42 +00:00
|
|
|
}
|
2022-04-18 07:01:26 +00:00
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.realpath(path:str)
|
|
|
|
// ├─→ path:str
|
|
|
|
// └─→ nil, unix.Errno
|
2022-04-18 15:54:42 +00:00
|
|
|
static int LuaUnixRealpath(lua_State *L) {
|
|
|
|
char *resolved;
|
2022-04-24 16:59:22 +00:00
|
|
|
int olderr;
|
2022-04-18 15:54:42 +00:00
|
|
|
const char *path;
|
|
|
|
olderr = errno;
|
|
|
|
path = luaL_checkstring(L, 1);
|
|
|
|
if ((resolved = realpath(path, 0))) {
|
|
|
|
lua_pushstring(L, resolved);
|
|
|
|
free(resolved);
|
|
|
|
return 1;
|
|
|
|
} else {
|
2022-07-20 22:13:39 +00:00
|
|
|
return LuaUnixSysretErrno(L, "realpath", olderr);
|
2022-04-18 15:54:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// unix.syslog(priority:str, msg:str)
|
|
|
|
static int LuaUnixSyslog(lua_State *L) {
|
|
|
|
syslog(luaL_checkinteger(L, 1), "%s", luaL_checkstring(L, 2));
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.chroot(path:str)
|
|
|
|
// ├─→ true
|
|
|
|
// └─→ nil, unix.Errno
|
2022-04-18 07:01:26 +00:00
|
|
|
static int LuaUnixChroot(lua_State *L) {
|
2022-04-24 16:59:22 +00:00
|
|
|
int olderr = errno;
|
2022-04-26 04:16:05 +00:00
|
|
|
return SysretBool(L, "chroot", olderr, chroot(luaL_checkstring(L, 1)));
|
2022-04-18 07:01:26 +00:00
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.setrlimit(resource:int, soft:int[, hard:int])
|
|
|
|
// ├─→ true
|
|
|
|
// └─→ nil, unix.Errno
|
2022-04-18 07:01:26 +00:00
|
|
|
static int LuaUnixSetrlimit(lua_State *L) {
|
2022-04-24 16:59:22 +00:00
|
|
|
int olderr = errno;
|
|
|
|
int64_t soft = luaL_checkinteger(L, 2);
|
2022-04-25 15:30:14 +00:00
|
|
|
return SysretBool(
|
2022-04-26 04:16:05 +00:00
|
|
|
L, "setrlimit", olderr,
|
2022-04-24 16:59:22 +00:00
|
|
|
setrlimit(luaL_checkinteger(L, 1),
|
2022-04-26 04:16:05 +00:00
|
|
|
&(struct rlimit){soft, luaL_optinteger(L, 3, soft)}));
|
2022-04-18 07:01:26 +00:00
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.getrlimit(resource:int)
|
|
|
|
// ├─→ soft:int, hard:int
|
|
|
|
// └─→ nil, unix.Errno
|
2022-04-18 07:01:26 +00:00
|
|
|
static int LuaUnixGetrlimit(lua_State *L) {
|
2022-04-28 16:42:36 +00:00
|
|
|
int olderr = errno;
|
2022-04-18 07:01:26 +00:00
|
|
|
struct rlimit rlim;
|
2022-04-28 16:42:36 +00:00
|
|
|
if (!getrlimit(luaL_checkinteger(L, 1), &rlim)) {
|
|
|
|
lua_pushinteger(L, FixLimit(rlim.rlim_cur));
|
|
|
|
lua_pushinteger(L, FixLimit(rlim.rlim_max));
|
|
|
|
return 2;
|
2022-04-18 07:01:26 +00:00
|
|
|
} else {
|
2022-07-20 22:13:39 +00:00
|
|
|
return LuaUnixSysretErrno(L, "getrlimit", olderr);
|
2022-04-18 07:01:26 +00:00
|
|
|
}
|
2022-04-13 21:43:42 +00:00
|
|
|
}
|
|
|
|
|
2022-04-28 16:42:36 +00:00
|
|
|
// unix.getrusage([who:int])
|
|
|
|
// ├─→ unix.Rusage
|
|
|
|
// └─→ nil, unix.Errno
|
|
|
|
static int LuaUnixGetrusage(lua_State *L) {
|
|
|
|
struct rusage ru;
|
|
|
|
int olderr = errno;
|
|
|
|
if (!getrusage(luaL_optinteger(L, 1, RUSAGE_SELF), &ru)) {
|
|
|
|
LuaPushRusage(L, &ru);
|
|
|
|
return 1;
|
|
|
|
} else {
|
2022-07-20 22:13:39 +00:00
|
|
|
return LuaUnixSysretErrno(L, "getrusage", olderr);
|
2022-04-28 16:42:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.kill(pid:int, sig:int)
|
|
|
|
// ├─→ true
|
|
|
|
// └─→ nil, unix.Errno
|
2022-04-13 15:49:17 +00:00
|
|
|
static int LuaUnixKill(lua_State *L) {
|
2022-04-24 16:59:22 +00:00
|
|
|
int olderr = errno;
|
2022-04-26 04:16:05 +00:00
|
|
|
return SysretBool(L, "kill", olderr,
|
|
|
|
kill(luaL_checkinteger(L, 1), luaL_checkinteger(L, 2)));
|
2022-04-13 15:49:17 +00:00
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.raise(sig:int)
|
|
|
|
// ├─→ rc:int
|
|
|
|
// └─→ nil, unix.Errno
|
2022-04-13 15:49:17 +00:00
|
|
|
static int LuaUnixRaise(lua_State *L) {
|
2022-04-24 16:59:22 +00:00
|
|
|
int olderr = errno;
|
2022-04-26 04:16:05 +00:00
|
|
|
return SysretInteger(L, "raise", olderr, raise(luaL_checkinteger(L, 1)));
|
2022-04-13 15:49:17 +00:00
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.wait([pid:int, options:int])
|
2022-04-29 03:36:33 +00:00
|
|
|
// ├─→ pid:int, wstatus:int, unix.Rusage
|
2022-04-26 04:16:05 +00:00
|
|
|
// └─→ nil, unix.Errno
|
2022-04-13 15:49:17 +00:00
|
|
|
static int LuaUnixWait(lua_State *L) {
|
2022-04-28 16:42:36 +00:00
|
|
|
struct rusage ru;
|
2022-04-24 16:59:22 +00:00
|
|
|
int pid, wstatus, olderr = errno;
|
|
|
|
if ((pid = wait4(luaL_optinteger(L, 1, -1), &wstatus,
|
2022-04-28 16:42:36 +00:00
|
|
|
luaL_optinteger(L, 2, 0), &ru)) != -1) {
|
2022-04-24 16:59:22 +00:00
|
|
|
lua_pushinteger(L, pid);
|
2022-04-13 15:49:17 +00:00
|
|
|
lua_pushinteger(L, wstatus);
|
2022-04-28 16:42:36 +00:00
|
|
|
LuaPushRusage(L, &ru);
|
2022-04-25 15:30:14 +00:00
|
|
|
return 3;
|
2022-04-13 15:49:17 +00:00
|
|
|
} else {
|
2022-07-20 22:13:39 +00:00
|
|
|
return LuaUnixSysretErrno(L, "wait", olderr);
|
2022-04-13 15:49:17 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-17 06:23:34 +00:00
|
|
|
// unix.fcntl(fd:int, cmd:int[, ...])
|
|
|
|
// ├─→ ...
|
2022-04-26 04:16:05 +00:00
|
|
|
// └─→ nil, unix.Errno
|
2022-04-13 15:49:17 +00:00
|
|
|
static int LuaUnixFcntl(lua_State *L) {
|
2022-08-17 06:23:34 +00:00
|
|
|
struct flock lock;
|
|
|
|
int rc, fd, cmd, olderr = errno;
|
|
|
|
fd = luaL_checkinteger(L, 1);
|
|
|
|
cmd = luaL_checkinteger(L, 2);
|
|
|
|
if (cmd == F_SETLK || cmd == F_SETLKW || cmd == F_GETLK) {
|
|
|
|
lock.l_type = luaL_optinteger(L, 3, F_RDLCK);
|
|
|
|
lock.l_start = luaL_optinteger(L, 4, 0);
|
|
|
|
lock.l_len = luaL_optinteger(L, 5, 0);
|
|
|
|
lock.l_whence = luaL_optinteger(L, 6, SEEK_SET);
|
|
|
|
}
|
|
|
|
if (cmd == F_SETLK || cmd == F_SETLKW) {
|
|
|
|
return SysretBool(L, "fcntl(F_SETLK*)", olderr, fcntl(fd, cmd, &lock));
|
|
|
|
} else if (cmd == F_GETLK) {
|
|
|
|
if (fcntl(fd, cmd, &lock) != -1) {
|
|
|
|
if (lock.l_type == F_UNLCK) {
|
|
|
|
lua_pushinteger(L, F_UNLCK);
|
|
|
|
return 1;
|
|
|
|
} else {
|
|
|
|
lua_pushinteger(L, lock.l_type);
|
|
|
|
lua_pushinteger(L, lock.l_start);
|
|
|
|
lua_pushinteger(L, lock.l_len);
|
|
|
|
lua_pushinteger(L, lock.l_whence);
|
|
|
|
lua_pushinteger(L, lock.l_pid);
|
|
|
|
return 5;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
return LuaUnixSysretErrno(L, "fcntl(F_GETLK)", olderr);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
return SysretBool(L, "fcntl", olderr,
|
|
|
|
fcntl(fd, cmd, luaL_optinteger(L, 3, 0)));
|
|
|
|
}
|
2022-04-13 15:49:17 +00:00
|
|
|
}
|
|
|
|
|
2022-08-17 06:23:34 +00:00
|
|
|
// unix.dup(oldfd:int[, newfd:int[, flags:int[, lowest:int]]])
|
2022-04-26 04:16:05 +00:00
|
|
|
// ├─→ newfd:int
|
|
|
|
// └─→ nil, unix.Errno
|
2022-04-13 15:49:17 +00:00
|
|
|
static int LuaUnixDup(lua_State *L) {
|
2022-08-17 06:23:34 +00:00
|
|
|
int rc, oldfd, newfd, flags, lowno, olderr;
|
2022-04-13 15:49:17 +00:00
|
|
|
olderr = errno;
|
|
|
|
oldfd = luaL_checkinteger(L, 1);
|
|
|
|
newfd = luaL_optinteger(L, 2, -1);
|
|
|
|
flags = luaL_optinteger(L, 3, 0);
|
2022-08-17 06:23:34 +00:00
|
|
|
lowno = luaL_optinteger(L, 4, 0);
|
|
|
|
if (newfd < 0) {
|
|
|
|
if (!flags && !lowno) {
|
|
|
|
rc = dup(oldfd);
|
|
|
|
} else if (!flags) {
|
|
|
|
rc = fcntl(oldfd, F_DUPFD, lowno);
|
|
|
|
} else if (flags == O_CLOEXEC) {
|
|
|
|
rc = fcntl(oldfd, F_DUPFD_CLOEXEC, lowno);
|
|
|
|
} else {
|
|
|
|
rc = einval();
|
|
|
|
}
|
2022-04-13 15:49:17 +00:00
|
|
|
} else {
|
|
|
|
rc = dup3(oldfd, newfd, flags);
|
|
|
|
}
|
2022-04-26 04:16:05 +00:00
|
|
|
return SysretInteger(L, "dup", olderr, rc);
|
2022-04-13 15:49:17 +00:00
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.pipe([flags:int])
|
|
|
|
// ├─→ reader:int, writer:int
|
|
|
|
// └─→ nil, unix.Errno
|
2022-04-13 15:49:17 +00:00
|
|
|
static int LuaUnixPipe(lua_State *L) {
|
2022-04-24 16:59:22 +00:00
|
|
|
int pipefd[2], olderr = errno;
|
|
|
|
if (!pipe2(pipefd, luaL_optinteger(L, 1, 0))) {
|
2022-04-13 15:49:17 +00:00
|
|
|
lua_pushinteger(L, pipefd[0]);
|
|
|
|
lua_pushinteger(L, pipefd[1]);
|
|
|
|
return 2;
|
|
|
|
} else {
|
2022-07-20 22:13:39 +00:00
|
|
|
return LuaUnixSysretErrno(L, "pipe", olderr);
|
2022-04-13 15:49:17 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.getsid(pid:int)
|
|
|
|
// ├─→ sid:int
|
|
|
|
// └─→ nil, unix.Errno
|
2022-04-13 15:49:17 +00:00
|
|
|
static int LuaUnixGetsid(lua_State *L) {
|
2022-04-24 16:59:22 +00:00
|
|
|
int olderr = errno;
|
2022-04-26 04:16:05 +00:00
|
|
|
return SysretInteger(L, "getsid", olderr, getsid(luaL_checkinteger(L, 1)));
|
2022-04-13 15:49:17 +00:00
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
static dontinline int LuaUnixRc0(lua_State *L, const char *call, int f(void)) {
|
2022-04-24 16:59:22 +00:00
|
|
|
int olderr = errno;
|
2022-04-26 04:16:05 +00:00
|
|
|
return SysretInteger(L, call, olderr, f());
|
2022-04-16 17:40:23 +00:00
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.getpgrp()
|
|
|
|
// ├─→ pgid:int
|
|
|
|
// └─→ nil, unix.Errno
|
2022-04-25 15:30:14 +00:00
|
|
|
static int LuaUnixGetpgrp(lua_State *L) {
|
2022-04-26 04:16:05 +00:00
|
|
|
return LuaUnixRc0(L, "getpgrp", getpgrp);
|
2022-04-13 15:49:17 +00:00
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.setpgrp()
|
|
|
|
// ├─→ pgid:int
|
|
|
|
// └─→ nil, unix.Errno
|
2022-04-25 15:30:14 +00:00
|
|
|
static int LuaUnixSetpgrp(lua_State *L) {
|
2022-04-26 04:16:05 +00:00
|
|
|
return LuaUnixRc0(L, "setpgrp", setpgrp);
|
2022-04-25 15:30:14 +00:00
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.setsid()
|
|
|
|
// ├─→ sid:int
|
|
|
|
// └─→ nil, unix.Errno
|
2022-04-25 15:30:14 +00:00
|
|
|
static int LuaUnixSetsid(lua_State *L) {
|
2022-04-26 04:16:05 +00:00
|
|
|
return LuaUnixRc0(L, "setsid", setsid);
|
2022-04-25 15:30:14 +00:00
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.getpgid(pid:int)
|
|
|
|
// ├─→ pgid:int
|
|
|
|
// └─→ nil, unix.Errno
|
2022-04-25 15:30:14 +00:00
|
|
|
static int LuaUnixGetpgid(lua_State *L) {
|
2022-04-24 16:59:22 +00:00
|
|
|
int olderr = errno;
|
2022-04-26 04:16:05 +00:00
|
|
|
return SysretInteger(L, "getpgid", olderr, getpgid(luaL_checkinteger(L, 1)));
|
2022-04-13 15:49:17 +00:00
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.setpgid(pid:int, pgid:int)
|
|
|
|
// ├─→ true
|
|
|
|
// └─→ nil, unix.Errno
|
2022-04-25 15:30:14 +00:00
|
|
|
static int LuaUnixSetpgid(lua_State *L) {
|
2022-04-24 16:59:22 +00:00
|
|
|
int olderr = errno;
|
2022-04-26 04:16:05 +00:00
|
|
|
return SysretBool(L, "setpgid", olderr,
|
|
|
|
setpgid(luaL_checkinteger(L, 1), luaL_checkinteger(L, 2)));
|
2022-04-20 16:56:53 +00:00
|
|
|
}
|
|
|
|
|
2022-10-11 00:52:41 +00:00
|
|
|
static dontinline int LuaUnixSetid(lua_State *L, const char *call,
|
|
|
|
int f(unsigned)) {
|
2022-04-24 16:59:22 +00:00
|
|
|
int olderr = errno;
|
2022-04-26 04:16:05 +00:00
|
|
|
return SysretBool(L, call, olderr, f(luaL_checkinteger(L, 1)));
|
2022-04-13 15:49:17 +00:00
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.setuid(uid:int)
|
|
|
|
// ├─→ true
|
|
|
|
// └─→ nil, unix.Errno
|
2022-04-18 15:54:42 +00:00
|
|
|
static int LuaUnixSetuid(lua_State *L) {
|
2022-04-26 04:16:05 +00:00
|
|
|
return LuaUnixSetid(L, "setuid", setuid);
|
2022-04-18 15:54:42 +00:00
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.setgid(gid:int)
|
|
|
|
// ├─→ true
|
|
|
|
// └─→ nil, unix.Errno
|
2022-04-18 15:54:42 +00:00
|
|
|
static int LuaUnixSetgid(lua_State *L) {
|
2022-04-26 04:16:05 +00:00
|
|
|
return LuaUnixSetid(L, "setgid", setgid);
|
2022-04-25 15:30:14 +00:00
|
|
|
}
|
|
|
|
|
2022-07-14 03:55:27 +00:00
|
|
|
// unix.setfsuid(fsuid:int)
|
|
|
|
// ├─→ true
|
|
|
|
// └─→ nil, unix.Errno
|
|
|
|
static int LuaUnixSetfsuid(lua_State *L) {
|
|
|
|
return LuaUnixSetid(L, "setfsuid", setfsuid);
|
|
|
|
}
|
|
|
|
|
|
|
|
// unix.setfsgid(fsgid:int)
|
|
|
|
// ├─→ true
|
|
|
|
// └─→ nil, unix.Errno
|
|
|
|
static int LuaUnixSetfsgid(lua_State *L) {
|
|
|
|
return LuaUnixSetid(L, "setfsgid", setfsgid);
|
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
static dontinline int LuaUnixSetresid(lua_State *L, const char *call,
|
2022-04-25 15:30:14 +00:00
|
|
|
int f(uint32_t, uint32_t, uint32_t)) {
|
2022-04-18 15:54:42 +00:00
|
|
|
int olderr = errno;
|
2022-04-26 04:16:05 +00:00
|
|
|
return SysretBool(L, call, olderr,
|
2022-04-25 15:30:14 +00:00
|
|
|
f(luaL_checkinteger(L, 1), luaL_checkinteger(L, 2),
|
2022-04-26 04:16:05 +00:00
|
|
|
luaL_checkinteger(L, 3)));
|
2022-04-24 16:59:22 +00:00
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.setresuid(real:int, effective:int, saved:int)
|
|
|
|
// ├─→ true
|
|
|
|
// └─→ nil, unix.Errno
|
2022-04-24 16:59:22 +00:00
|
|
|
static int LuaUnixSetresuid(lua_State *L) {
|
2022-04-26 04:16:05 +00:00
|
|
|
return LuaUnixSetresid(L, "setresuid", setresuid);
|
2022-04-24 16:59:22 +00:00
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.setresgid(real:int, effective:int, saved:int)
|
|
|
|
// ├─→ true
|
|
|
|
// └─→ nil, unix.Errno
|
2022-04-24 16:59:22 +00:00
|
|
|
static int LuaUnixSetresgid(lua_State *L) {
|
2022-04-26 04:16:05 +00:00
|
|
|
return LuaUnixSetresid(L, "setresgid", setresgid);
|
2022-04-18 15:54:42 +00:00
|
|
|
}
|
|
|
|
|
2022-06-18 08:10:29 +00:00
|
|
|
// unix.utimensat(path[, asecs, ananos, msecs, mnanos[, dirfd[, flags]]])
|
|
|
|
// ├─→ 0
|
|
|
|
// └─→ nil, unix.Errno
|
|
|
|
static int LuaUnixUtimensat(lua_State *L) {
|
|
|
|
struct timespec ts;
|
|
|
|
int olderr = errno;
|
|
|
|
return SysretInteger(
|
|
|
|
L, "utimensat", olderr,
|
|
|
|
utimensat(
|
|
|
|
luaL_optinteger(L, 6, AT_FDCWD), luaL_checkstring(L, 1),
|
|
|
|
(struct timespec[2]){
|
|
|
|
{luaL_optinteger(L, 2, 0), luaL_optinteger(L, 3, UTIME_NOW)},
|
|
|
|
{luaL_optinteger(L, 4, 0), luaL_optinteger(L, 5, UTIME_NOW)},
|
|
|
|
},
|
|
|
|
luaL_optinteger(L, 7, 0)));
|
|
|
|
}
|
|
|
|
|
|
|
|
// unix.futimens(fd:int[, asecs, ananos, msecs, mnanos])
|
|
|
|
// ├─→ 0
|
|
|
|
// └─→ nil, unix.Errno
|
|
|
|
static int LuaUnixFutimens(lua_State *L) {
|
|
|
|
struct timespec ts;
|
|
|
|
int olderr = errno;
|
|
|
|
return SysretInteger(
|
|
|
|
L, "futimens", olderr,
|
|
|
|
futimens(luaL_checkinteger(L, 1),
|
|
|
|
(struct timespec[2]){
|
|
|
|
{luaL_optinteger(L, 2, 0), luaL_optinteger(L, 3, UTIME_NOW)},
|
|
|
|
{luaL_optinteger(L, 4, 0), luaL_optinteger(L, 5, UTIME_NOW)},
|
|
|
|
}));
|
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.clock_gettime([clock:int])
|
|
|
|
// ├─→ seconds:int, nanos:int
|
|
|
|
// └─→ nil, unix.Errno
|
2022-04-13 15:49:17 +00:00
|
|
|
static int LuaUnixGettime(lua_State *L) {
|
|
|
|
struct timespec ts;
|
2022-04-24 16:59:22 +00:00
|
|
|
int rc, olderr = errno;
|
|
|
|
if (!clock_gettime(luaL_optinteger(L, 1, CLOCK_REALTIME), &ts)) {
|
2022-04-13 15:49:17 +00:00
|
|
|
lua_pushinteger(L, ts.tv_sec);
|
|
|
|
lua_pushinteger(L, ts.tv_nsec);
|
2022-04-26 04:16:05 +00:00
|
|
|
return 2;
|
2022-04-13 15:49:17 +00:00
|
|
|
} else {
|
2022-07-20 22:13:39 +00:00
|
|
|
return LuaUnixSysretErrno(L, "clock_gettime", olderr);
|
2022-04-13 15:49:17 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-18 10:02:13 +00:00
|
|
|
// unix.nanosleep(seconds:int[, nanos:int])
|
2022-04-26 04:16:05 +00:00
|
|
|
// ├─→ remseconds:int, remnanos:int
|
|
|
|
// └─→ nil, unix.Errno
|
2022-04-13 15:49:17 +00:00
|
|
|
static int LuaUnixNanosleep(lua_State *L) {
|
2022-04-24 16:59:22 +00:00
|
|
|
int olderr = errno;
|
2022-04-13 15:49:17 +00:00
|
|
|
struct timespec req, rem;
|
|
|
|
req.tv_sec = luaL_checkinteger(L, 1);
|
|
|
|
req.tv_nsec = luaL_optinteger(L, 2, 0);
|
2022-04-24 16:59:22 +00:00
|
|
|
if (!nanosleep(&req, &rem)) {
|
2022-04-13 15:49:17 +00:00
|
|
|
lua_pushinteger(L, rem.tv_sec);
|
|
|
|
lua_pushinteger(L, rem.tv_nsec);
|
2022-04-26 04:16:05 +00:00
|
|
|
return 2;
|
2022-04-13 15:49:17 +00:00
|
|
|
} else {
|
2022-07-20 22:13:39 +00:00
|
|
|
return LuaUnixSysretErrno(L, "nanosleep", olderr);
|
2022-04-13 15:49:17 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-22 05:07:21 +00:00
|
|
|
// unix.sync()
|
2022-04-13 15:49:17 +00:00
|
|
|
static int LuaUnixSync(lua_State *L) {
|
|
|
|
sync();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.fsync(fd:int)
|
|
|
|
// ├─→ true
|
|
|
|
// └─→ nil, unix.Errno
|
2022-04-13 15:49:17 +00:00
|
|
|
static int LuaUnixFsync(lua_State *L) {
|
2022-04-24 16:59:22 +00:00
|
|
|
int olderr = errno;
|
2022-04-26 04:16:05 +00:00
|
|
|
return SysretBool(L, "fsync", olderr, fsync(luaL_checkinteger(L, 1)));
|
2022-04-13 15:49:17 +00:00
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.fdatasync(fd:int)
|
|
|
|
// ├─→ true
|
|
|
|
// └─→ nil, unix.Errno
|
2022-04-13 15:49:17 +00:00
|
|
|
static int LuaUnixFdatasync(lua_State *L) {
|
2022-04-24 16:59:22 +00:00
|
|
|
int olderr = errno;
|
2022-04-26 04:16:05 +00:00
|
|
|
return SysretBool(L, "fdatasync", olderr, fdatasync(luaL_checkinteger(L, 1)));
|
2022-04-13 15:49:17 +00:00
|
|
|
}
|
|
|
|
|
2022-05-12 16:43:01 +00:00
|
|
|
// unix.open(path:str[, flags:int[, mode:int[, dirfd:int]]])
|
2022-04-26 04:16:05 +00:00
|
|
|
// ├─→ fd:int
|
|
|
|
// └─→ nil, unix.Errno
|
2022-04-13 15:49:17 +00:00
|
|
|
static int LuaUnixOpen(lua_State *L) {
|
2022-04-24 16:59:22 +00:00
|
|
|
int olderr = errno;
|
2022-04-26 04:16:05 +00:00
|
|
|
return SysretInteger(
|
|
|
|
L, "open", olderr,
|
|
|
|
openat(luaL_optinteger(L, 4, AT_FDCWD), luaL_checkstring(L, 1),
|
2022-05-12 16:43:01 +00:00
|
|
|
luaL_optinteger(L, 2, O_RDONLY), luaL_optinteger(L, 3, 0)));
|
2022-04-13 15:49:17 +00:00
|
|
|
}
|
|
|
|
|
2022-08-14 20:28:07 +00:00
|
|
|
// unix.tmpfd()
|
|
|
|
// ├─→ fd:int
|
|
|
|
// └─→ nil, unix.Errno
|
|
|
|
static int LuaUnixTmpfd(lua_State *L) {
|
|
|
|
int olderr = errno;
|
|
|
|
return SysretInteger(L, "tmpfd", olderr, tmpfd());
|
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.close(fd:int)
|
|
|
|
// ├─→ true
|
|
|
|
// └─→ nil, unix.Errno
|
2022-04-13 15:49:17 +00:00
|
|
|
static int LuaUnixClose(lua_State *L) {
|
2022-04-24 16:59:22 +00:00
|
|
|
int olderr = errno;
|
2022-04-26 04:16:05 +00:00
|
|
|
return SysretBool(L, "close", olderr, close(luaL_checkinteger(L, 1)));
|
2022-04-13 15:49:17 +00:00
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.lseek(fd:int, offset:int[, whence:int])
|
|
|
|
// ├─→ newposbytes:int
|
|
|
|
// └─→ nil, unix.Errno
|
2022-04-24 16:59:22 +00:00
|
|
|
static int LuaUnixLseek(lua_State *L) {
|
|
|
|
int olderr = errno;
|
2022-04-26 04:16:05 +00:00
|
|
|
return SysretInteger(L, "lseek", olderr,
|
2022-04-25 15:30:14 +00:00
|
|
|
lseek(luaL_checkinteger(L, 1), luaL_checkinteger(L, 2),
|
2022-04-26 04:16:05 +00:00
|
|
|
luaL_optinteger(L, 3, SEEK_SET)));
|
2022-04-13 15:49:17 +00:00
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.truncate(path:str[, length:int])
|
|
|
|
// ├─→ true
|
|
|
|
// └─→ nil, unix.Errno
|
2022-04-13 15:49:17 +00:00
|
|
|
static int LuaUnixTruncate(lua_State *L) {
|
2022-04-24 16:59:22 +00:00
|
|
|
int olderr = errno;
|
2022-04-26 04:16:05 +00:00
|
|
|
return SysretBool(L, "truncate", olderr,
|
|
|
|
truncate(luaL_checkstring(L, 1), luaL_optinteger(L, 2, 0)));
|
2022-04-13 15:49:17 +00:00
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.ftruncate(fd:int[, length:int])
|
|
|
|
// ├─→ true
|
|
|
|
// └─→ nil, unix.Errno
|
2022-04-24 16:59:22 +00:00
|
|
|
static int LuaUnixFtruncate(lua_State *L) {
|
|
|
|
int olderr = errno;
|
2022-04-25 15:30:14 +00:00
|
|
|
return SysretBool(
|
2022-04-26 04:16:05 +00:00
|
|
|
L, "ftruncate", olderr,
|
|
|
|
ftruncate(luaL_checkinteger(L, 1), luaL_optinteger(L, 2, 0)));
|
2022-04-24 16:59:22 +00:00
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.read(fd:int[, bufsiz:str[, offset:int]])
|
|
|
|
// ├─→ data:str
|
|
|
|
// └─→ nil, unix.Errno
|
2022-04-13 15:49:17 +00:00
|
|
|
static int LuaUnixRead(lua_State *L) {
|
|
|
|
char *buf;
|
|
|
|
size_t got;
|
2022-04-26 04:16:05 +00:00
|
|
|
ssize_t rc;
|
2022-04-21 16:15:36 +00:00
|
|
|
int fd, olderr;
|
2022-04-26 04:16:05 +00:00
|
|
|
lua_Integer bufsiz, offset;
|
2022-04-13 15:49:17 +00:00
|
|
|
olderr = errno;
|
|
|
|
fd = luaL_checkinteger(L, 1);
|
|
|
|
bufsiz = luaL_optinteger(L, 2, BUFSIZ);
|
|
|
|
offset = luaL_optinteger(L, 3, -1);
|
|
|
|
bufsiz = MIN(bufsiz, 0x7ffff000);
|
2022-05-29 15:14:55 +00:00
|
|
|
buf = LuaAllocOrDie(L, bufsiz);
|
|
|
|
if (offset == -1) {
|
|
|
|
rc = read(fd, buf, bufsiz);
|
|
|
|
} else {
|
|
|
|
rc = pread(fd, buf, bufsiz, offset);
|
|
|
|
}
|
|
|
|
if (rc != -1) {
|
|
|
|
got = rc;
|
|
|
|
lua_pushlstring(L, buf, got);
|
|
|
|
free(buf);
|
|
|
|
return 1;
|
2022-04-13 15:49:17 +00:00
|
|
|
} else {
|
2022-05-29 15:14:55 +00:00
|
|
|
free(buf);
|
2022-07-20 22:13:39 +00:00
|
|
|
return LuaUnixSysretErrno(L, "read", olderr);
|
2022-04-13 15:49:17 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.write(fd:int, data:str[, offset:int])
|
|
|
|
// ├─→ wrotebytes:int
|
|
|
|
// └─→ nil, unix.Errno
|
2022-04-13 15:49:17 +00:00
|
|
|
static int LuaUnixWrite(lua_State *L) {
|
2022-04-26 04:16:05 +00:00
|
|
|
ssize_t rc;
|
2022-04-13 15:49:17 +00:00
|
|
|
size_t size;
|
|
|
|
int fd, olderr;
|
|
|
|
const char *data;
|
2022-04-26 04:16:05 +00:00
|
|
|
lua_Integer offset;
|
2022-04-13 15:49:17 +00:00
|
|
|
olderr = errno;
|
|
|
|
fd = luaL_checkinteger(L, 1);
|
|
|
|
data = luaL_checklstring(L, 2, &size);
|
|
|
|
offset = luaL_optinteger(L, 3, -1);
|
|
|
|
if (offset == -1) {
|
|
|
|
rc = write(fd, data, size);
|
|
|
|
} else {
|
|
|
|
rc = pwrite(fd, data, size, offset);
|
|
|
|
}
|
2022-04-26 04:16:05 +00:00
|
|
|
return SysretInteger(L, "write", olderr, rc);
|
2022-04-13 15:49:17 +00:00
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.stat(path:str[, flags:int[, dirfd:int]])
|
|
|
|
// ├─→ unix.Stat
|
|
|
|
// └─→ nil, unix.Errno
|
2022-04-13 15:49:17 +00:00
|
|
|
static int LuaUnixStat(lua_State *L) {
|
2022-04-27 12:39:39 +00:00
|
|
|
struct stat st;
|
|
|
|
int olderr = errno;
|
|
|
|
if (!fstatat(luaL_optinteger(L, 3, AT_FDCWD), luaL_checkstring(L, 1), &st,
|
|
|
|
luaL_optinteger(L, 2, 0))) {
|
|
|
|
LuaPushStat(L, &st);
|
|
|
|
return 1;
|
|
|
|
} else {
|
2022-07-20 22:13:39 +00:00
|
|
|
return LuaUnixSysretErrno(L, "stat", olderr);
|
2022-04-24 16:59:22 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.fstat(fd:int)
|
|
|
|
// ├─→ unix.Stat
|
|
|
|
// └─→ nil, unix.Errno
|
2022-04-24 16:59:22 +00:00
|
|
|
static int LuaUnixFstat(lua_State *L) {
|
2022-04-27 12:39:39 +00:00
|
|
|
struct stat st;
|
|
|
|
int olderr = errno;
|
|
|
|
if (!fstat(luaL_checkinteger(L, 1), &st)) {
|
|
|
|
LuaPushStat(L, &st);
|
|
|
|
return 1;
|
|
|
|
} else {
|
2022-07-20 22:13:39 +00:00
|
|
|
return LuaUnixSysretErrno(L, "fstat", olderr);
|
2022-04-13 15:49:17 +00:00
|
|
|
}
|
2022-04-24 16:59:22 +00:00
|
|
|
}
|
|
|
|
|
2022-08-18 06:27:17 +00:00
|
|
|
// unix.statfs(path:str)
|
|
|
|
// ├─→ unix.Statfs
|
|
|
|
// └─→ nil, unix.Errno
|
|
|
|
static int LuaUnixStatfs(lua_State *L) {
|
|
|
|
struct statfs f;
|
|
|
|
int olderr = errno;
|
|
|
|
if (!statfs(luaL_checkstring(L, 1), &f)) {
|
|
|
|
LuaPushStatfs(L, &f);
|
|
|
|
return 1;
|
|
|
|
} else {
|
|
|
|
return LuaUnixSysretErrno(L, "statfs", olderr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// unix.fstatfs(fd:int)
|
|
|
|
// ├─→ unix.Stat
|
|
|
|
// └─→ nil, unix.Errno
|
|
|
|
static int LuaUnixFstatfs(lua_State *L) {
|
|
|
|
struct statfs f;
|
|
|
|
int olderr = errno;
|
|
|
|
if (!fstatfs(luaL_checkinteger(L, 1), &f)) {
|
|
|
|
LuaPushStatfs(L, &f);
|
|
|
|
return 1;
|
|
|
|
} else {
|
|
|
|
return LuaUnixSysretErrno(L, "fstatfs", olderr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-24 16:59:22 +00:00
|
|
|
static bool IsSockoptBool(int l, int x) {
|
|
|
|
if (l == SOL_SOCKET) {
|
2022-04-25 15:30:14 +00:00
|
|
|
return x == SO_TYPE || //
|
|
|
|
x == SO_DEBUG || //
|
|
|
|
x == SO_ERROR || //
|
|
|
|
x == SO_BROADCAST || //
|
|
|
|
x == SO_REUSEADDR || //
|
|
|
|
x == SO_REUSEPORT || //
|
|
|
|
x == SO_KEEPALIVE || //
|
|
|
|
x == SO_ACCEPTCONN || //
|
|
|
|
x == SO_DONTROUTE; //
|
2022-04-24 16:59:22 +00:00
|
|
|
} else if (l = SOL_TCP) {
|
|
|
|
return x == TCP_NODELAY || //
|
|
|
|
x == TCP_CORK || //
|
|
|
|
x == TCP_QUICKACK || //
|
2022-07-17 09:40:39 +00:00
|
|
|
x == TCP_SAVE_SYN || //
|
2022-04-24 16:59:22 +00:00
|
|
|
x == TCP_FASTOPEN_CONNECT || //
|
|
|
|
x == TCP_DEFER_ACCEPT; //
|
|
|
|
} else if (l = SOL_IP) {
|
|
|
|
return x == IP_HDRINCL; //
|
2022-04-13 15:49:17 +00:00
|
|
|
} else {
|
2022-04-24 16:59:22 +00:00
|
|
|
return false;
|
2022-04-13 15:49:17 +00:00
|
|
|
}
|
2022-04-24 16:59:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static bool IsSockoptInt(int l, int x) {
|
|
|
|
if (l == SOL_SOCKET) {
|
|
|
|
return x == SO_SNDBUF || //
|
|
|
|
x == SO_RCVBUF || //
|
|
|
|
x == SO_RCVLOWAT || //
|
|
|
|
x == SO_SNDLOWAT; //
|
|
|
|
} else if (l = SOL_TCP) {
|
|
|
|
return x == TCP_FASTOPEN || //
|
|
|
|
x == TCP_KEEPCNT || //
|
|
|
|
x == TCP_MAXSEG || //
|
|
|
|
x == TCP_SYNCNT || //
|
|
|
|
x == TCP_NOTSENT_LOWAT || //
|
|
|
|
x == TCP_WINDOW_CLAMP || //
|
|
|
|
x == TCP_KEEPIDLE || //
|
|
|
|
x == TCP_KEEPINTVL; //
|
|
|
|
} else if (l = SOL_IP) {
|
|
|
|
return x == IP_TOS || //
|
|
|
|
x == IP_MTU || //
|
|
|
|
x == IP_TTL; //
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool IsSockoptTimeval(int l, int x) {
|
|
|
|
if (l == SOL_SOCKET) {
|
|
|
|
return x == SO_RCVTIMEO || //
|
|
|
|
x == SO_SNDTIMEO; //
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static int LuaUnixSetsockopt(lua_State *L) {
|
2022-04-26 04:16:05 +00:00
|
|
|
void *optval;
|
2022-04-25 15:30:14 +00:00
|
|
|
struct linger l;
|
2022-04-26 04:16:05 +00:00
|
|
|
uint32_t optsize;
|
2022-04-24 16:59:22 +00:00
|
|
|
struct timeval tv;
|
2022-04-26 04:16:05 +00:00
|
|
|
int rc, fd, level, optname, optint, olderr = errno;
|
2022-04-24 16:59:22 +00:00
|
|
|
fd = luaL_checkinteger(L, 1);
|
|
|
|
level = luaL_checkinteger(L, 2);
|
|
|
|
optname = luaL_checkinteger(L, 3);
|
2022-07-17 09:40:39 +00:00
|
|
|
if (level == -1 || optname == 0) {
|
|
|
|
NoProtocolOption:
|
|
|
|
enoprotoopt();
|
2022-07-20 22:13:39 +00:00
|
|
|
return LuaUnixSysretErrno(L, "setsockopt", olderr);
|
2022-07-17 09:40:39 +00:00
|
|
|
}
|
2022-04-24 16:59:22 +00:00
|
|
|
if (IsSockoptBool(level, optname)) {
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.setsockopt(fd:int, level:int, optname:int, value:bool)
|
|
|
|
// ├─→ true
|
|
|
|
// └─→ nil, unix.Errno
|
|
|
|
optint = lua_toboolean(L, 4);
|
|
|
|
optval = &optint;
|
|
|
|
optsize = sizeof(optint);
|
2022-04-24 16:59:22 +00:00
|
|
|
} else if (IsSockoptInt(level, optname)) {
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.setsockopt(fd:int, level:int, optname:int, value:int)
|
|
|
|
// ├─→ true
|
|
|
|
// └─→ nil, unix.Errno
|
|
|
|
optint = luaL_checkinteger(L, 4);
|
|
|
|
optval = &optint;
|
|
|
|
optsize = sizeof(optint);
|
2022-04-24 16:59:22 +00:00
|
|
|
} else if (IsSockoptTimeval(level, optname)) {
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.setsockopt(fd:int, level:int, optname:int, secs:int[, nanos:int])
|
|
|
|
// ├─→ true
|
|
|
|
// └─→ nil, unix.Errno
|
2022-04-24 16:59:22 +00:00
|
|
|
tv.tv_sec = luaL_checkinteger(L, 4);
|
2022-06-22 10:04:25 +00:00
|
|
|
tv.tv_usec = luaL_optinteger(L, 5, 0) / 1000;
|
2022-04-26 04:16:05 +00:00
|
|
|
optval = &tv;
|
|
|
|
optsize = sizeof(tv);
|
2022-04-25 15:30:14 +00:00
|
|
|
} else if (level == SOL_SOCKET && optname == SO_LINGER) {
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.setsockopt(fd:int, level:int, optname:int, secs:int, enabled:bool)
|
|
|
|
// ├─→ true
|
|
|
|
// └─→ nil, unix.Errno
|
|
|
|
l.l_linger = luaL_checkinteger(L, 4);
|
|
|
|
l.l_onoff = lua_toboolean(L, 5);
|
|
|
|
optval = &l;
|
|
|
|
optsize = sizeof(l);
|
2022-04-24 16:59:22 +00:00
|
|
|
} else {
|
2022-07-17 09:40:39 +00:00
|
|
|
goto NoProtocolOption;
|
2022-04-24 16:59:22 +00:00
|
|
|
}
|
2022-04-26 04:16:05 +00:00
|
|
|
return SysretBool(L, "setsockopt", olderr,
|
|
|
|
setsockopt(fd, level, optname, optval, optsize));
|
2022-04-24 16:59:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int LuaUnixGetsockopt(lua_State *L) {
|
2022-07-17 09:40:39 +00:00
|
|
|
char *p;
|
2022-04-26 04:16:05 +00:00
|
|
|
uint32_t size;
|
2022-04-25 15:30:14 +00:00
|
|
|
struct linger l;
|
2022-04-24 16:59:22 +00:00
|
|
|
struct timeval tv;
|
|
|
|
int rc, fd, level, optname, optval, olderr = errno;
|
|
|
|
fd = luaL_checkinteger(L, 1);
|
|
|
|
level = luaL_checkinteger(L, 2);
|
|
|
|
optname = luaL_checkinteger(L, 3);
|
2022-07-17 09:40:39 +00:00
|
|
|
if (level == -1 || optname == 0) {
|
|
|
|
NoProtocolOption:
|
|
|
|
enoprotoopt();
|
2022-07-20 22:13:39 +00:00
|
|
|
return LuaUnixSysretErrno(L, "setsockopt", olderr);
|
2022-07-17 09:40:39 +00:00
|
|
|
}
|
2022-04-26 04:16:05 +00:00
|
|
|
if (IsSockoptBool(level, optname) || IsSockoptInt(level, optname)) {
|
2022-04-25 15:30:14 +00:00
|
|
|
// unix.getsockopt(fd:int, level:int, optname:int)
|
2022-04-26 04:16:05 +00:00
|
|
|
// ├─→ value:int
|
|
|
|
// └─→ nil, unix.Errno
|
|
|
|
size = sizeof(optval);
|
|
|
|
if (getsockopt(fd, level, optname, &optval, &size) != -1) {
|
|
|
|
CheckOptvalsize(L, sizeof(optval), size);
|
2022-04-24 16:59:22 +00:00
|
|
|
lua_pushinteger(L, optval);
|
2022-04-25 16:31:28 +00:00
|
|
|
return 1;
|
2022-04-24 16:59:22 +00:00
|
|
|
}
|
|
|
|
} else if (IsSockoptTimeval(level, optname)) {
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.getsockopt(fd:int, level:int, optname:int)
|
|
|
|
// ├─→ secs:int, nsecs:int
|
|
|
|
// └─→ nil, unix.Errno
|
|
|
|
size = sizeof(tv);
|
|
|
|
if (getsockopt(fd, level, optname, &tv, &size) != -1) {
|
|
|
|
CheckOptvalsize(L, sizeof(tv), size);
|
2022-04-24 16:59:22 +00:00
|
|
|
lua_pushinteger(L, tv.tv_sec);
|
2022-04-26 04:16:05 +00:00
|
|
|
lua_pushinteger(L, tv.tv_usec * 1000);
|
|
|
|
return 2;
|
2022-04-25 15:30:14 +00:00
|
|
|
}
|
|
|
|
} else if (level == SOL_SOCKET && optname == SO_LINGER) {
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.getsockopt(fd:int, unix.SOL_SOCKET, unix.SO_LINGER)
|
|
|
|
// ├─→ seconds:int, enabled:bool
|
|
|
|
// └─→ nil, unix.Errno
|
|
|
|
size = sizeof(l);
|
|
|
|
if (getsockopt(fd, level, optname, &l, &size) != -1) {
|
|
|
|
CheckOptvalsize(L, sizeof(l), size);
|
2022-04-25 15:30:14 +00:00
|
|
|
lua_pushinteger(L, l.l_linger);
|
2022-04-26 04:16:05 +00:00
|
|
|
lua_pushboolean(L, !!l.l_onoff);
|
|
|
|
return 1;
|
2022-04-24 16:59:22 +00:00
|
|
|
}
|
2022-07-17 09:40:39 +00:00
|
|
|
} else if (level == SOL_TCP && optname == TCP_SAVED_SYN) {
|
|
|
|
// unix.getsockopt(fd:int, unix.SOL_TCP, unix.SO_SAVED_SYN)
|
|
|
|
// ├─→ syn_packet_bytes:str
|
|
|
|
// └─→ nil, unix.Errno
|
|
|
|
if ((p = malloc((size = 1500)))) {
|
|
|
|
if (getsockopt(fd, level, optname, p, &size) != -1) {
|
|
|
|
lua_pushlstring(L, p, size);
|
|
|
|
free(p);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
free(p);
|
|
|
|
}
|
2022-04-24 16:59:22 +00:00
|
|
|
} else {
|
2022-07-17 09:40:39 +00:00
|
|
|
goto NoProtocolOption;
|
2022-04-13 15:49:17 +00:00
|
|
|
}
|
2022-07-20 22:13:39 +00:00
|
|
|
return LuaUnixSysretErrno(L, "getsockopt", olderr);
|
2022-04-13 15:49:17 +00:00
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.socket([family:int[, type:int[, protocol:int]]])
|
|
|
|
// ├─→ fd:int
|
|
|
|
// └─→ nil, unix.Errno
|
2022-04-13 15:49:17 +00:00
|
|
|
static int LuaUnixSocket(lua_State *L) {
|
2022-04-24 16:59:22 +00:00
|
|
|
int olderr = errno;
|
2022-06-22 10:04:25 +00:00
|
|
|
int family = luaL_optinteger(L, 1, AF_INET);
|
2022-07-09 06:06:46 +00:00
|
|
|
return SysretInteger(L, "socket", olderr,
|
|
|
|
socket(family, luaL_optinteger(L, 2, SOCK_STREAM),
|
|
|
|
luaL_optinteger(L, 3, 0)));
|
2022-04-13 15:49:17 +00:00
|
|
|
}
|
|
|
|
|
2022-04-24 16:59:22 +00:00
|
|
|
// unix.socketpair([family:int[, type:int[, protocol:int]]])
|
2022-04-26 04:16:05 +00:00
|
|
|
// ├─→ fd1:int, fd2:int
|
|
|
|
// └─→ nil, unix.Errno
|
2022-04-13 15:49:17 +00:00
|
|
|
static int LuaUnixSocketpair(lua_State *L) {
|
2022-04-24 16:59:22 +00:00
|
|
|
int sv[2], olderr = errno;
|
2022-05-11 09:50:03 +00:00
|
|
|
if (!socketpair(luaL_optinteger(L, 1, AF_UNIX),
|
|
|
|
luaL_optinteger(L, 2, SOCK_STREAM), luaL_optinteger(L, 3, 0),
|
|
|
|
sv)) {
|
2022-04-13 15:49:17 +00:00
|
|
|
lua_pushinteger(L, sv[0]);
|
|
|
|
lua_pushinteger(L, sv[1]);
|
|
|
|
return 2;
|
|
|
|
} else {
|
2022-07-20 22:13:39 +00:00
|
|
|
return LuaUnixSysretErrno(L, "socketpair", olderr);
|
2022-04-13 15:49:17 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.bind(fd:int[, ip:uint32, port:uint16])
|
2022-06-22 10:04:25 +00:00
|
|
|
// unix.bind(fd:int[, unixpath:str])
|
2022-04-26 04:16:05 +00:00
|
|
|
// ├─→ true
|
|
|
|
// └─→ nil, unix.Errno
|
2022-04-13 15:49:17 +00:00
|
|
|
static int LuaUnixBind(lua_State *L) {
|
2022-06-22 10:04:25 +00:00
|
|
|
uint32_t salen;
|
2022-06-23 10:39:44 +00:00
|
|
|
struct sockaddr_storage ss;
|
2022-04-24 16:59:22 +00:00
|
|
|
int olderr = errno;
|
2022-06-23 10:39:44 +00:00
|
|
|
MakeSockaddr(L, 2, &ss, &salen);
|
2022-10-11 00:52:41 +00:00
|
|
|
return SysretBool(
|
|
|
|
L, "bind", olderr,
|
|
|
|
bind(luaL_checkinteger(L, 1), (struct sockaddr *)&ss, salen));
|
2022-04-25 15:30:14 +00:00
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.connect(fd:int, ip:uint32, port:uint16)
|
2022-06-22 10:04:25 +00:00
|
|
|
// unix.connect(fd:int, unixpath:str)
|
2022-04-26 04:16:05 +00:00
|
|
|
// ├─→ true
|
|
|
|
// └─→ nil, unix.Errno
|
2022-04-13 15:49:17 +00:00
|
|
|
static int LuaUnixConnect(lua_State *L) {
|
2022-06-22 10:04:25 +00:00
|
|
|
uint32_t salen;
|
2022-06-23 10:39:44 +00:00
|
|
|
struct sockaddr_storage ss;
|
2022-04-24 16:59:22 +00:00
|
|
|
int olderr = errno;
|
2022-06-23 10:39:44 +00:00
|
|
|
MakeSockaddr(L, 2, &ss, &salen);
|
2022-10-11 00:52:41 +00:00
|
|
|
return SysretBool(
|
|
|
|
L, "connect", olderr,
|
|
|
|
connect(luaL_checkinteger(L, 1), (struct sockaddr *)&ss, salen));
|
2022-04-13 15:49:17 +00:00
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.listen(fd:int[, backlog:int])
|
|
|
|
// ├─→ true
|
|
|
|
// └─→ nil, unix.Errno
|
2022-04-13 15:49:17 +00:00
|
|
|
static int LuaUnixListen(lua_State *L) {
|
2022-04-24 16:59:22 +00:00
|
|
|
int olderr = errno;
|
2022-04-26 04:16:05 +00:00
|
|
|
return SysretBool(L, "listen", olderr,
|
|
|
|
listen(luaL_checkinteger(L, 1), luaL_optinteger(L, 2, 10)));
|
2022-04-13 15:49:17 +00:00
|
|
|
}
|
|
|
|
|
2022-06-22 10:04:25 +00:00
|
|
|
static int LuaUnixGetname(lua_State *L, const char *name,
|
2022-10-11 00:52:41 +00:00
|
|
|
int func(int, struct sockaddr *, uint32_t *)) {
|
2022-06-22 10:04:25 +00:00
|
|
|
int olderr;
|
2022-04-13 15:49:17 +00:00
|
|
|
uint32_t addrsize;
|
2022-06-22 10:04:25 +00:00
|
|
|
struct sockaddr_storage ss = {0};
|
2022-04-13 15:49:17 +00:00
|
|
|
olderr = errno;
|
2022-06-22 10:04:25 +00:00
|
|
|
addrsize = sizeof(ss) - 1;
|
2022-10-11 00:52:41 +00:00
|
|
|
if (!func(luaL_checkinteger(L, 1), (struct sockaddr *)&ss, &addrsize)) {
|
2022-06-22 10:04:25 +00:00
|
|
|
return PushSockaddr(L, &ss);
|
2022-04-13 15:49:17 +00:00
|
|
|
} else {
|
2022-07-20 22:13:39 +00:00
|
|
|
return LuaUnixSysretErrno(L, name, olderr);
|
2022-04-13 15:49:17 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-06-22 10:04:25 +00:00
|
|
|
// unix.getsockname(fd:int)
|
|
|
|
// ├─→ ip:uint32, port:uint16
|
|
|
|
// ├─→ unixpath:str
|
|
|
|
// └─→ nil, unix.Errno
|
|
|
|
static int LuaUnixGetsockname(lua_State *L) {
|
|
|
|
return LuaUnixGetname(L, "getsockname", getsockname);
|
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.getpeername(fd:int)
|
|
|
|
// ├─→ ip:uint32, port:uint16
|
2022-06-22 10:04:25 +00:00
|
|
|
// ├─→ unixpath:str
|
2022-04-26 04:16:05 +00:00
|
|
|
// └─→ nil, unix.Errno
|
2022-04-13 15:49:17 +00:00
|
|
|
static int LuaUnixGetpeername(lua_State *L) {
|
2022-06-22 10:04:25 +00:00
|
|
|
return LuaUnixGetname(L, "getpeername", getpeername);
|
2022-04-13 15:49:17 +00:00
|
|
|
}
|
|
|
|
|
2022-04-25 15:30:14 +00:00
|
|
|
// unix.siocgifconf()
|
2022-04-26 04:16:05 +00:00
|
|
|
// ├─→ {{name:str,ip:uint32,netmask:uint32}, ...}
|
|
|
|
// └─→ nil, unix.Errno
|
2022-04-21 20:44:59 +00:00
|
|
|
static int LuaUnixSiocgifconf(lua_State *L) {
|
|
|
|
size_t n;
|
|
|
|
char *data;
|
|
|
|
int i, fd, olderr;
|
|
|
|
struct ifreq *ifr;
|
|
|
|
struct ifconf conf;
|
|
|
|
olderr = errno;
|
2022-05-29 15:14:55 +00:00
|
|
|
data = LuaAllocOrDie(L, (n = 4096));
|
2022-04-22 02:13:19 +00:00
|
|
|
if ((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP)) == -1) {
|
2022-04-21 20:44:59 +00:00
|
|
|
free(data);
|
2022-07-20 22:13:39 +00:00
|
|
|
return LuaUnixSysretErrno(L, "siocgifconf", olderr);
|
2022-04-21 20:44:59 +00:00
|
|
|
}
|
|
|
|
conf.ifc_buf = data;
|
|
|
|
conf.ifc_len = n;
|
|
|
|
if (ioctl(fd, SIOCGIFCONF, &conf) == -1) {
|
|
|
|
close(fd);
|
|
|
|
free(data);
|
2022-07-20 22:13:39 +00:00
|
|
|
return LuaUnixSysretErrno(L, "siocgifconf", olderr);
|
2022-04-21 20:44:59 +00:00
|
|
|
}
|
|
|
|
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);
|
2022-04-25 15:30:14 +00:00
|
|
|
lua_pushliteral(L, "name");
|
2022-04-21 20:44:59 +00:00
|
|
|
lua_pushstring(L, ifr->ifr_name);
|
|
|
|
lua_settable(L, -3);
|
2022-04-25 15:30:14 +00:00
|
|
|
lua_pushliteral(L, "ip");
|
2022-04-21 20:44:59 +00:00
|
|
|
lua_pushinteger(
|
|
|
|
L, ntohl(((struct sockaddr_in *)&ifr->ifr_addr)->sin_addr.s_addr));
|
|
|
|
lua_settable(L, -3);
|
|
|
|
if (ioctl(fd, SIOCGIFNETMASK, ifr) != -1) {
|
2022-04-25 15:30:14 +00:00
|
|
|
lua_pushliteral(L, "netmask");
|
2022-04-21 20:44:59 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2022-08-11 18:27:25 +00:00
|
|
|
// sandbox.pledge([promises:str[, execpromises:str[, mode:int]]])
|
2022-04-28 16:42:36 +00:00
|
|
|
// ├─→ true
|
|
|
|
// └─→ nil, unix.Errno
|
|
|
|
static int LuaUnixPledge(lua_State *L) {
|
|
|
|
int olderr = errno;
|
2022-08-11 18:27:25 +00:00
|
|
|
__pledge_mode = luaL_optinteger(L, 3, 0);
|
2022-07-18 14:23:15 +00:00
|
|
|
return SysretBool(L, "pledge", olderr,
|
2023-06-03 15:12:13 +00:00
|
|
|
pledge(luaL_optstring(L, 1, 0), luaL_optstring(L, 2, 0)));
|
2022-07-18 14:23:15 +00:00
|
|
|
}
|
|
|
|
|
2022-07-23 12:22:19 +00:00
|
|
|
// sandbox.unveil([path:str[, permissions:str]])
|
2022-07-18 14:23:15 +00:00
|
|
|
// ├─→ true
|
|
|
|
// └─→ nil, unix.Errno
|
|
|
|
static int LuaUnixUnveil(lua_State *L) {
|
|
|
|
int olderr = errno;
|
|
|
|
return SysretBool(L, "unveil", olderr,
|
2022-07-23 12:22:19 +00:00
|
|
|
unveil(luaL_optstring(L, 1, 0), luaL_optstring(L, 2, 0)));
|
2022-04-28 16:42:36 +00:00
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.gethostname()
|
|
|
|
// ├─→ host:str
|
|
|
|
// └─→ nil, unix.Errno
|
2022-04-21 20:44:59 +00:00
|
|
|
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();
|
|
|
|
}
|
|
|
|
}
|
2022-07-20 22:13:39 +00:00
|
|
|
return LuaUnixSysretErrno(L, "gethostname", olderr);
|
2022-04-21 20:44:59 +00:00
|
|
|
}
|
|
|
|
|
2022-04-25 15:30:14 +00:00
|
|
|
// unix.accept(serverfd:int[, flags:int])
|
2022-04-26 04:16:05 +00:00
|
|
|
// ├─→ clientfd:int, ip:uint32, port:uint16
|
2022-06-22 10:04:25 +00:00
|
|
|
// ├─→ clientfd:int, unixpath:str
|
2022-04-26 04:16:05 +00:00
|
|
|
// └─→ nil, unix.Errno
|
2022-04-13 15:49:17 +00:00
|
|
|
static int LuaUnixAccept(lua_State *L) {
|
|
|
|
uint32_t addrsize;
|
2022-06-22 10:04:25 +00:00
|
|
|
struct sockaddr_storage ss;
|
2022-04-25 15:30:14 +00:00
|
|
|
int clientfd, serverfd, olderr, flags;
|
2022-04-13 15:49:17 +00:00
|
|
|
olderr = errno;
|
2022-06-22 10:04:25 +00:00
|
|
|
addrsize = sizeof(ss);
|
2022-04-13 15:49:17 +00:00
|
|
|
serverfd = luaL_checkinteger(L, 1);
|
2022-04-25 15:30:14 +00:00
|
|
|
flags = luaL_optinteger(L, 2, 0);
|
2022-10-11 00:52:41 +00:00
|
|
|
clientfd = accept4(serverfd, (struct sockaddr *)&ss, &addrsize, flags);
|
2022-04-13 15:49:17 +00:00
|
|
|
if (clientfd != -1) {
|
|
|
|
lua_pushinteger(L, clientfd);
|
2022-06-22 10:04:25 +00:00
|
|
|
return 1 + PushSockaddr(L, &ss);
|
2022-04-13 15:49:17 +00:00
|
|
|
} else {
|
2022-07-20 22:13:39 +00:00
|
|
|
return LuaUnixSysretErrno(L, "accept", olderr);
|
2022-04-13 15:49:17 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-17 06:23:34 +00:00
|
|
|
// unix.poll({[fd:int]=events:int, ...}[, timeoutms:int[, mask:unix.Sigset]])
|
2022-04-26 04:16:05 +00:00
|
|
|
// ├─→ {[fd:int]=revents:int, ...}
|
|
|
|
// └─→ nil, unix.Errno
|
2022-04-21 20:44:59 +00:00
|
|
|
static int LuaUnixPoll(lua_State *L) {
|
|
|
|
size_t nfds;
|
2022-08-17 06:23:34 +00:00
|
|
|
struct sigset *mask;
|
|
|
|
struct timespec ts, *tsp;
|
2022-04-26 04:16:05 +00:00
|
|
|
struct pollfd *fds, *fds2;
|
2022-08-17 06:23:34 +00:00
|
|
|
int i, fd, events, olderr = errno;
|
2022-04-21 20:44:59 +00:00
|
|
|
luaL_checktype(L, 1, LUA_TTABLE);
|
2022-08-17 06:23:34 +00:00
|
|
|
if (!lua_isnoneornil(L, 2)) {
|
2022-11-06 02:49:41 +00:00
|
|
|
ts = timespec_frommillis(luaL_checkinteger(L, 2));
|
2022-08-17 06:23:34 +00:00
|
|
|
tsp = &ts;
|
|
|
|
} else {
|
|
|
|
tsp = 0;
|
|
|
|
}
|
|
|
|
if (!lua_isnoneornil(L, 3)) {
|
|
|
|
mask = luaL_checkudata(L, 3, "unix.Sigset");
|
|
|
|
} else {
|
|
|
|
mask = 0;
|
|
|
|
}
|
2022-04-21 20:44:59 +00:00
|
|
|
lua_pushnil(L);
|
|
|
|
for (fds = 0, nfds = 0; lua_next(L, 1);) {
|
|
|
|
if (lua_isinteger(L, -2)) {
|
2022-05-16 23:49:20 +00:00
|
|
|
if ((fds2 = LuaRealloc(L, fds, (nfds + 1) * sizeof(*fds)))) {
|
2022-04-26 04:16:05 +00:00
|
|
|
fds2[nfds].fd = lua_tointeger(L, -2);
|
|
|
|
fds2[nfds].events = lua_tointeger(L, -1);
|
|
|
|
fds = fds2;
|
|
|
|
++nfds;
|
|
|
|
} else {
|
|
|
|
free(fds);
|
2022-07-20 22:13:39 +00:00
|
|
|
return LuaUnixSysretErrno(L, "poll", olderr);
|
2022-04-26 04:16:05 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// ignore non-integer key
|
2022-04-21 20:44:59 +00:00
|
|
|
}
|
|
|
|
lua_pop(L, 1);
|
|
|
|
}
|
|
|
|
olderr = errno;
|
2022-08-17 06:23:34 +00:00
|
|
|
if ((events = ppoll(fds, nfds, tsp, mask)) != -1) {
|
2022-04-21 20:44:59 +00:00
|
|
|
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);
|
2022-07-20 22:13:39 +00:00
|
|
|
return LuaUnixSysretErrno(L, "poll", olderr);
|
2022-04-21 20:44:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.recvfrom(fd:int[, bufsiz:int[, flags:int]])
|
|
|
|
// ├─→ data:str, ip:uint32, port:uint16
|
2022-06-22 10:04:25 +00:00
|
|
|
// ├─→ data:str, unixpath:str
|
2022-04-26 04:16:05 +00:00
|
|
|
// └─→ nil, unix.Errno
|
2022-04-13 15:49:17 +00:00
|
|
|
static int LuaUnixRecvfrom(lua_State *L) {
|
|
|
|
char *buf;
|
|
|
|
size_t got;
|
|
|
|
ssize_t rc;
|
|
|
|
uint32_t addrsize;
|
2022-04-26 04:16:05 +00:00
|
|
|
lua_Integer bufsiz;
|
2022-06-22 10:04:25 +00:00
|
|
|
struct sockaddr_storage ss;
|
|
|
|
int fd, flags, pushed, olderr = errno;
|
|
|
|
addrsize = sizeof(ss);
|
2022-04-13 15:49:17 +00:00
|
|
|
fd = luaL_checkinteger(L, 1);
|
|
|
|
bufsiz = luaL_optinteger(L, 2, 1500);
|
|
|
|
bufsiz = MIN(bufsiz, 0x7ffff000);
|
2022-05-11 09:50:03 +00:00
|
|
|
flags = luaL_optinteger(L, 3, 0);
|
2022-05-29 15:14:55 +00:00
|
|
|
buf = LuaAllocOrDie(L, bufsiz);
|
2022-10-11 00:52:41 +00:00
|
|
|
if ((rc = recvfrom(fd, buf, bufsiz, flags, (struct sockaddr *)&ss,
|
|
|
|
&addrsize)) != -1) {
|
2022-05-29 15:14:55 +00:00
|
|
|
got = rc;
|
|
|
|
lua_pushlstring(L, buf, got);
|
2022-06-22 10:04:25 +00:00
|
|
|
pushed = 1 + PushSockaddr(L, &ss);
|
2022-05-29 15:14:55 +00:00
|
|
|
free(buf);
|
2022-06-22 10:04:25 +00:00
|
|
|
return pushed;
|
2022-04-13 15:49:17 +00:00
|
|
|
} else {
|
2022-05-29 15:14:55 +00:00
|
|
|
free(buf);
|
2022-07-20 22:13:39 +00:00
|
|
|
return LuaUnixSysretErrno(L, "recvfrom", olderr);
|
2022-04-13 15:49:17 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.recv(fd:int[, bufsiz:int[, flags:int]])
|
|
|
|
// ├─→ data:str
|
|
|
|
// └─→ nil, unix.Errno
|
2022-04-15 06:39:48 +00:00
|
|
|
static int LuaUnixRecv(lua_State *L) {
|
|
|
|
char *buf;
|
|
|
|
size_t got;
|
|
|
|
ssize_t rc;
|
2022-04-26 04:16:05 +00:00
|
|
|
lua_Integer bufsiz;
|
2022-05-11 09:50:03 +00:00
|
|
|
int fd, flags, pushed, olderr = errno;
|
2022-04-15 06:39:48 +00:00
|
|
|
fd = luaL_checkinteger(L, 1);
|
|
|
|
bufsiz = luaL_optinteger(L, 2, 1500);
|
|
|
|
bufsiz = MIN(bufsiz, 0x7ffff000);
|
2022-05-11 09:50:03 +00:00
|
|
|
flags = luaL_optinteger(L, 3, 0);
|
2022-05-29 15:14:55 +00:00
|
|
|
buf = LuaAllocOrDie(L, bufsiz);
|
|
|
|
rc = recv(fd, buf, bufsiz, flags);
|
|
|
|
if (rc != -1) {
|
|
|
|
got = rc;
|
|
|
|
lua_pushlstring(L, buf, got);
|
|
|
|
free(buf);
|
|
|
|
return 1;
|
2022-04-15 06:39:48 +00:00
|
|
|
} else {
|
2022-05-29 15:14:55 +00:00
|
|
|
free(buf);
|
2022-07-20 22:13:39 +00:00
|
|
|
return LuaUnixSysretErrno(L, "recv", olderr);
|
2022-04-15 06:39:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.send(fd:int, data:str[, flags:int])
|
|
|
|
// ├─→ sent:int
|
|
|
|
// └─→ nil, unix.Errno
|
2022-04-15 06:39:48 +00:00
|
|
|
static int LuaUnixSend(lua_State *L) {
|
|
|
|
char *data;
|
|
|
|
ssize_t rc;
|
|
|
|
size_t sent, size;
|
2022-05-11 09:50:03 +00:00
|
|
|
int fd, flags, olderr = errno;
|
2022-04-15 06:39:48 +00:00
|
|
|
fd = luaL_checkinteger(L, 1);
|
|
|
|
data = luaL_checklstring(L, 2, &size);
|
2022-05-11 09:50:03 +00:00
|
|
|
flags = luaL_optinteger(L, 3, 0);
|
2022-04-26 04:16:05 +00:00
|
|
|
return SysretInteger(L, "send", olderr, send(fd, data, size, flags));
|
2022-04-15 06:39:48 +00:00
|
|
|
}
|
|
|
|
|
2022-04-24 16:59:22 +00:00
|
|
|
// unix.sendto(fd:int, data:str, ip:uint32, port:uint16[, flags:int])
|
2022-06-22 10:04:25 +00:00
|
|
|
// unix.sendto(fd:int, data:str, unixpath:str[, flags:int])
|
2022-04-26 04:16:05 +00:00
|
|
|
// ├─→ sent:int
|
|
|
|
// └─→ nil, unix.Errno
|
2022-04-13 15:49:17 +00:00
|
|
|
static int LuaUnixSendto(lua_State *L) {
|
|
|
|
char *data;
|
2022-06-22 10:04:25 +00:00
|
|
|
size_t size;
|
|
|
|
uint32_t salen;
|
2022-06-23 10:39:44 +00:00
|
|
|
struct sockaddr_storage ss;
|
2022-06-22 10:04:25 +00:00
|
|
|
int i, fd, flags, olderr = errno;
|
2022-04-13 15:49:17 +00:00
|
|
|
fd = luaL_checkinteger(L, 1);
|
|
|
|
data = luaL_checklstring(L, 2, &size);
|
2022-06-23 10:39:44 +00:00
|
|
|
i = MakeSockaddr(L, 3, &ss, &salen);
|
2022-06-22 10:04:25 +00:00
|
|
|
flags = luaL_optinteger(L, i, 0);
|
2022-10-11 00:52:41 +00:00
|
|
|
return SysretInteger(
|
|
|
|
L, "sendto", olderr,
|
|
|
|
sendto(fd, data, size, flags, (struct sockaddr *)&ss, salen));
|
2022-04-13 15:49:17 +00:00
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.shutdown(fd:int, how:int)
|
|
|
|
// ├─→ true
|
|
|
|
// └─→ nil, unix.Errno
|
2022-04-13 15:49:17 +00:00
|
|
|
static int LuaUnixShutdown(lua_State *L) {
|
2022-04-24 16:59:22 +00:00
|
|
|
int olderr = errno;
|
2022-04-26 04:16:05 +00:00
|
|
|
return SysretBool(L, "shutdown", olderr,
|
|
|
|
shutdown(luaL_checkinteger(L, 1), luaL_checkinteger(L, 2)));
|
2022-04-13 15:49:17 +00:00
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.sigprocmask(how:int, newmask:unix.Sigset)
|
|
|
|
// ├─→ oldmask:unix.Sigset
|
|
|
|
// └─→ nil, unix.Errno
|
2022-04-13 15:49:17 +00:00
|
|
|
static int LuaUnixSigprocmask(lua_State *L) {
|
|
|
|
uint64_t imask;
|
2022-05-11 09:50:03 +00:00
|
|
|
int olderr = errno;
|
|
|
|
struct sigset oldmask;
|
|
|
|
if (!sigprocmask(luaL_checkinteger(L, 1),
|
|
|
|
luaL_checkudata(L, 2, "unix.Sigset"), &oldmask)) {
|
2022-04-26 04:16:05 +00:00
|
|
|
LuaPushSigset(L, oldmask);
|
2022-04-13 15:49:17 +00:00
|
|
|
return 1;
|
|
|
|
} else {
|
2022-07-20 22:13:39 +00:00
|
|
|
return LuaUnixSysretErrno(L, "sigprocmask", olderr);
|
2022-04-13 15:49:17 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-02 12:08:35 +00:00
|
|
|
static void LuaUnixOnSignal(int sig, siginfo_t *si, void *ctx) {
|
2022-04-26 04:16:05 +00:00
|
|
|
int type;
|
|
|
|
lua_State *L = GL;
|
2022-04-13 21:43:42 +00:00
|
|
|
STRACE("LuaUnixOnSignal(%G)", sig);
|
2022-04-26 04:16:05 +00:00
|
|
|
lua_getglobal(L, "__signal_handlers");
|
|
|
|
type = lua_rawgeti(L, -1, sig);
|
|
|
|
lua_remove(L, -2); // pop __signal_handlers
|
|
|
|
if (type == LUA_TFUNCTION) {
|
|
|
|
lua_pushinteger(L, sig);
|
|
|
|
if (lua_pcall(L, 1, 0, 0) != LUA_OK) {
|
|
|
|
ERRORF("(lua) %s failed: %s", strsignal(sig), lua_tostring(L, -1));
|
|
|
|
lua_pop(L, 1); // pop error
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
lua_pop(L, 1); // pop handler
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// unix.sigaction(sig:int[, handler:func|int[, flags:int[, mask:unix.Sigset]]])
|
|
|
|
// ├─→ oldhandler:func|int, flags:int, mask:unix.Sigset
|
|
|
|
// └─→ nil, unix.Errno
|
2022-04-13 15:49:17 +00:00
|
|
|
static int LuaUnixSigaction(lua_State *L) {
|
2022-04-26 04:16:05 +00:00
|
|
|
struct sigset *mask;
|
2022-05-11 09:50:03 +00:00
|
|
|
int i, n, sig, olderr = errno;
|
|
|
|
struct sigaction sa, oldsa, *saptr = &sa;
|
2022-04-13 21:43:42 +00:00
|
|
|
sigemptyset(&sa.sa_mask);
|
2022-04-13 15:49:17 +00:00
|
|
|
sig = luaL_checkinteger(L, 1);
|
2022-04-13 21:43:42 +00:00
|
|
|
if (!(1 <= sig && sig <= NSIG)) {
|
|
|
|
luaL_argerror(L, 1, "signal number invalid");
|
2023-06-09 06:44:03 +00:00
|
|
|
__builtin_unreachable();
|
2022-04-13 15:49:17 +00:00
|
|
|
}
|
2022-04-13 21:43:42 +00:00
|
|
|
if (lua_isnoneornil(L, 2)) {
|
|
|
|
// if handler/flags/mask aren't passed,
|
|
|
|
// then we're quering the current state
|
|
|
|
saptr = 0;
|
|
|
|
} else if (lua_isinteger(L, 2)) {
|
|
|
|
// bypass handling signals using lua code if possible
|
|
|
|
sa.sa_sigaction = (void *)luaL_checkinteger(L, 2);
|
|
|
|
} else if (lua_isfunction(L, 2)) {
|
|
|
|
sa.sa_sigaction = LuaUnixOnSignal;
|
|
|
|
// lua probably isn't async signal safe, so...
|
|
|
|
// let's mask all the lua handlers during handling
|
|
|
|
sigaddset(&sa.sa_mask, sig);
|
|
|
|
lua_getglobal(L, "__signal_handlers");
|
|
|
|
luaL_checktype(L, -1, LUA_TTABLE);
|
|
|
|
lua_len(L, -1);
|
|
|
|
n = lua_tointeger(L, -1);
|
|
|
|
lua_pop(L, 1);
|
|
|
|
for (i = 1; i <= MIN(n, NSIG); ++i) {
|
|
|
|
if (lua_geti(L, -1, i) == LUA_TFUNCTION) {
|
|
|
|
sigaddset(&sa.sa_mask, i);
|
|
|
|
}
|
|
|
|
lua_pop(L, 1);
|
|
|
|
}
|
|
|
|
lua_pop(L, 1);
|
|
|
|
} else {
|
|
|
|
luaL_argerror(L, 2, "sigaction handler not integer or function");
|
2023-06-09 06:44:03 +00:00
|
|
|
__builtin_unreachable();
|
2022-04-13 21:43:42 +00:00
|
|
|
}
|
2022-04-26 04:16:05 +00:00
|
|
|
if (!lua_isnoneornil(L, 4)) {
|
|
|
|
mask = luaL_checkudata(L, 4, "unix.Sigset");
|
|
|
|
sa.sa_mask.__bits[0] |= mask->__bits[0];
|
|
|
|
sa.sa_mask.__bits[1] |= mask->__bits[1];
|
2022-07-09 06:06:46 +00:00
|
|
|
lua_remove(L, 4);
|
|
|
|
}
|
|
|
|
if (lua_isnoneornil(L, 3)) {
|
|
|
|
sa.sa_flags = 0;
|
|
|
|
} else {
|
|
|
|
sa.sa_flags = lua_tointeger(L, 3);
|
|
|
|
lua_remove(L, 3);
|
2022-04-26 04:16:05 +00:00
|
|
|
}
|
2022-04-13 21:43:42 +00:00
|
|
|
if (!sigaction(sig, saptr, &oldsa)) {
|
|
|
|
lua_getglobal(L, "__signal_handlers");
|
|
|
|
// push the old handler result to stack. if the global lua handler
|
|
|
|
// table has a real function, then we prefer to return that. if it's
|
|
|
|
// absent or a raw integer value, then we're better off returning
|
|
|
|
// what the kernel gave us in &oldsa.
|
2022-04-26 04:16:05 +00:00
|
|
|
if (lua_rawgeti(L, -1, sig) != LUA_TFUNCTION) {
|
2022-04-13 21:43:42 +00:00
|
|
|
lua_pop(L, 1);
|
|
|
|
lua_pushinteger(L, (intptr_t)oldsa.sa_handler);
|
|
|
|
}
|
|
|
|
if (saptr) {
|
|
|
|
// update the global lua table
|
|
|
|
if (sa.sa_sigaction == LuaUnixOnSignal) {
|
|
|
|
lua_pushvalue(L, -3);
|
|
|
|
} else {
|
|
|
|
lua_pushnil(L);
|
|
|
|
}
|
2022-04-26 04:16:05 +00:00
|
|
|
lua_rawseti(L, -3, sig);
|
2022-04-13 21:43:42 +00:00
|
|
|
}
|
|
|
|
// remove the signal handler table from stack
|
|
|
|
lua_remove(L, -2);
|
2022-04-26 04:16:05 +00:00
|
|
|
// finish pushing the last 2/3 results
|
2022-04-13 21:43:42 +00:00
|
|
|
lua_pushinteger(L, oldsa.sa_flags);
|
2022-04-26 04:16:05 +00:00
|
|
|
LuaPushSigset(L, oldsa.sa_mask);
|
|
|
|
return 3;
|
2022-04-13 15:49:17 +00:00
|
|
|
} else {
|
2022-07-20 22:13:39 +00:00
|
|
|
return LuaUnixSysretErrno(L, "sigaction", olderr);
|
2022-04-13 15:49:17 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.sigsuspend([mask:Sigmask])
|
|
|
|
// └─→ nil, unix.Errno
|
2022-04-13 21:43:42 +00:00
|
|
|
static int LuaUnixSigsuspend(lua_State *L) {
|
2022-04-25 15:30:14 +00:00
|
|
|
int olderr = errno;
|
2022-05-11 09:50:03 +00:00
|
|
|
sigsuspend(!lua_isnoneornil(L, 1) ? luaL_checkudata(L, 1, "unix.Sigset") : 0);
|
2022-07-20 22:13:39 +00:00
|
|
|
return LuaUnixSysretErrno(L, "sigsuspend", olderr);
|
2022-04-13 21:43:42 +00:00
|
|
|
}
|
|
|
|
|
2022-09-09 11:20:13 +00:00
|
|
|
// unix.sigpending()
|
|
|
|
// ├─→ mask:unix.Sigset
|
|
|
|
// └─→ nil, unix.Errno
|
|
|
|
static int LuaUnixSigpending(lua_State *L) {
|
|
|
|
int olderr = errno;
|
|
|
|
struct sigset mask;
|
|
|
|
if (!sigpending(&mask)) {
|
|
|
|
LuaPushSigset(L, mask);
|
|
|
|
return 1;
|
|
|
|
} else {
|
|
|
|
return LuaUnixSysretErrno(L, "sigpending", olderr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.setitimer(which[, intervalsec, intns, valuesec, valuens])
|
|
|
|
// ├─→ intervalsec:int, intervalns:int, valuesec:int, valuens:int
|
|
|
|
// └─→ nil, unix.Errno
|
2022-04-13 21:43:42 +00:00
|
|
|
static int LuaUnixSetitimer(lua_State *L) {
|
2022-05-11 09:50:03 +00:00
|
|
|
int which, olderr = errno;
|
2022-04-13 21:43:42 +00:00
|
|
|
struct itimerval it, oldit, *itptr;
|
|
|
|
which = luaL_checkinteger(L, 1);
|
|
|
|
if (!lua_isnoneornil(L, 2)) {
|
|
|
|
itptr = ⁢
|
|
|
|
it.it_interval.tv_sec = luaL_optinteger(L, 2, 0);
|
2022-04-26 04:16:05 +00:00
|
|
|
it.it_interval.tv_usec = luaL_optinteger(L, 3, 0) / 1000;
|
2022-04-13 21:43:42 +00:00
|
|
|
it.it_value.tv_sec = luaL_optinteger(L, 4, 0);
|
2022-04-26 04:16:05 +00:00
|
|
|
it.it_value.tv_usec = luaL_optinteger(L, 5, 0) / 1000;
|
2022-04-13 21:43:42 +00:00
|
|
|
} else {
|
|
|
|
itptr = 0;
|
|
|
|
}
|
|
|
|
if (!setitimer(which, itptr, &oldit)) {
|
|
|
|
lua_pushinteger(L, oldit.it_interval.tv_sec);
|
2022-04-26 04:16:05 +00:00
|
|
|
lua_pushinteger(L, oldit.it_interval.tv_usec * 1000);
|
2022-04-13 21:43:42 +00:00
|
|
|
lua_pushinteger(L, oldit.it_value.tv_sec);
|
2022-04-26 04:16:05 +00:00
|
|
|
lua_pushinteger(L, oldit.it_value.tv_usec * 1000);
|
|
|
|
return 4;
|
2022-04-13 21:43:42 +00:00
|
|
|
} else {
|
2022-07-20 22:13:39 +00:00
|
|
|
return LuaUnixSysretErrno(L, "setitimer", olderr);
|
2022-04-13 21:43:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-28 16:42:36 +00:00
|
|
|
static int LuaUnixStr(lua_State *L, char *f(int)) {
|
2022-04-25 15:30:14 +00:00
|
|
|
return ReturnString(L, f(luaL_checkinteger(L, 1)));
|
2022-04-24 16:59:22 +00:00
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.strsignal(sig:int)
|
|
|
|
// └─→ symbol:str
|
2022-04-13 21:43:42 +00:00
|
|
|
static int LuaUnixStrsignal(lua_State *L) {
|
2022-04-25 15:30:14 +00:00
|
|
|
return LuaUnixStr(L, strsignal);
|
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.WIFEXITED(wstatus)
|
|
|
|
// └─→ bool
|
2022-04-21 11:01:42 +00:00
|
|
|
static int LuaUnixWifexited(lua_State *L) {
|
2022-10-06 11:55:26 +00:00
|
|
|
return ReturnBoolean(L, !!WIFEXITED(luaL_checkinteger(L, 1)));
|
2022-04-21 11:01:42 +00:00
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.WEXITSTATUS(wstatus)
|
|
|
|
// └─→ exitcode:uint8
|
2022-04-21 11:01:42 +00:00
|
|
|
static int LuaUnixWexitstatus(lua_State *L) {
|
|
|
|
return ReturnInteger(L, WEXITSTATUS(luaL_checkinteger(L, 1)));
|
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.WIFSIGNALED(wstatus)
|
|
|
|
// └─→ bool
|
2022-04-21 11:01:42 +00:00
|
|
|
static int LuaUnixWifsignaled(lua_State *L) {
|
2022-10-06 11:55:26 +00:00
|
|
|
return ReturnBoolean(L, !!WIFSIGNALED(luaL_checkinteger(L, 1)));
|
2022-04-21 11:01:42 +00:00
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.WTERMSIG(wstatus)
|
|
|
|
// └─→ sig:uint8
|
2022-04-21 11:01:42 +00:00
|
|
|
static int LuaUnixWtermsig(lua_State *L) {
|
|
|
|
return ReturnInteger(L, WTERMSIG(luaL_checkinteger(L, 1)));
|
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
static dontinline int LuaUnixTime(lua_State *L, const char *call,
|
|
|
|
struct tm *f(const time_t *, struct tm *)) {
|
|
|
|
int64_t ts;
|
|
|
|
struct tm tm;
|
|
|
|
int olderr = errno;
|
|
|
|
ts = luaL_checkinteger(L, 1);
|
|
|
|
if (f(&ts, &tm)) {
|
|
|
|
lua_pushinteger(L, tm.tm_year + 1900);
|
|
|
|
lua_pushinteger(L, tm.tm_mon + 1); // 1 ≤ mon ≤ 12
|
|
|
|
lua_pushinteger(L, tm.tm_mday); // 1 ≤ mday ≤ 31
|
|
|
|
lua_pushinteger(L, tm.tm_hour); // 0 ≤ hour ≤ 23
|
|
|
|
lua_pushinteger(L, tm.tm_min); // 0 ≤ min ≤ 59
|
|
|
|
lua_pushinteger(L, tm.tm_sec); // 0 ≤ sec ≤ 60
|
|
|
|
lua_pushinteger(L, tm.tm_gmtoff); // ±93600 seconds
|
|
|
|
lua_pushinteger(L, tm.tm_wday); // 0 ≤ wday ≤ 6
|
|
|
|
lua_pushinteger(L, tm.tm_yday); // 0 ≤ yday ≤ 365
|
|
|
|
lua_pushinteger(L, tm.tm_isdst); // daylight savings
|
|
|
|
lua_pushstring(L, tm.tm_zone);
|
|
|
|
return 11;
|
|
|
|
} else {
|
2022-07-20 22:13:39 +00:00
|
|
|
return LuaUnixSysretErrno(L, call, olderr);
|
2022-04-26 04:16:05 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// unix.gmtime(unixsecs:int)
|
|
|
|
// ├─→ year,mon,mday,hour,min,sec,gmtoffsec,wday,yday,dst:int,zone:str
|
|
|
|
// └─→ nil,unix.Errno
|
|
|
|
static int LuaUnixGmtime(lua_State *L) {
|
|
|
|
return LuaUnixTime(L, "gmtime", gmtime_r);
|
|
|
|
}
|
|
|
|
|
|
|
|
// unix.localtime(unixts:int)
|
|
|
|
// ├─→ year,mon,mday,hour,min,sec,gmtoffsec,wday,yday,dst:int,zone:str
|
|
|
|
// └─→ nil,unix.Errno
|
|
|
|
static int LuaUnixLocaltime(lua_State *L) {
|
|
|
|
return LuaUnixTime(L, "localtime", localtime_r);
|
|
|
|
}
|
|
|
|
|
|
|
|
// unix.major(rdev:int)
|
|
|
|
// └─→ major:int
|
|
|
|
static int LuaUnixMajor(lua_State *L) {
|
|
|
|
return ReturnInteger(L, major(luaL_checkinteger(L, 1)));
|
|
|
|
}
|
|
|
|
|
|
|
|
// unix.minor(rdev:int)
|
|
|
|
// └─→ minor:int
|
|
|
|
static int LuaUnixMinor(lua_State *L) {
|
|
|
|
return ReturnInteger(L, minor(luaL_checkinteger(L, 1)));
|
|
|
|
}
|
|
|
|
|
2022-06-23 11:05:51 +00:00
|
|
|
// unix.S_ISDIR(mode:int)
|
|
|
|
// └─→ bool
|
|
|
|
static int LuaUnixSisdir(lua_State *L) {
|
|
|
|
lua_pushboolean(L, S_ISDIR(luaL_checkinteger(L, 1)));
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// unix.S_ISCHR(mode:int)
|
|
|
|
// └─→ bool
|
|
|
|
static int LuaUnixSischr(lua_State *L) {
|
|
|
|
lua_pushboolean(L, S_ISCHR(luaL_checkinteger(L, 1)));
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// unix.S_ISBLK(mode:int)
|
|
|
|
// └─→ bool
|
|
|
|
static int LuaUnixSisblk(lua_State *L) {
|
|
|
|
lua_pushboolean(L, S_ISBLK(luaL_checkinteger(L, 1)));
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// unix.S_ISREG(mode:int)
|
|
|
|
// └─→ bool
|
|
|
|
static int LuaUnixSisreg(lua_State *L) {
|
|
|
|
lua_pushboolean(L, S_ISREG(luaL_checkinteger(L, 1)));
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// unix.S_ISFIFO(mode:int)
|
|
|
|
// └─→ bool
|
|
|
|
static int LuaUnixSisfifo(lua_State *L) {
|
|
|
|
lua_pushboolean(L, S_ISFIFO(luaL_checkinteger(L, 1)));
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// unix.S_ISLNK(mode:int)
|
|
|
|
// └─→ bool
|
|
|
|
static int LuaUnixSislnk(lua_State *L) {
|
|
|
|
lua_pushboolean(L, S_ISLNK(luaL_checkinteger(L, 1)));
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// unix.S_ISSOCK(mode:int)
|
|
|
|
// └─→ bool
|
|
|
|
static int LuaUnixSissock(lua_State *L) {
|
|
|
|
lua_pushboolean(L, S_ISSOCK(luaL_checkinteger(L, 1)));
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2022-06-27 20:01:58 +00:00
|
|
|
// unix.isatty(fd:int)
|
|
|
|
// ├─→ true
|
|
|
|
// └─→ nil, unix.Errno
|
|
|
|
static int LuaUnixIsatty(lua_State *L) {
|
|
|
|
int olderr = errno;
|
|
|
|
return SysretBool(L, "isatty", olderr, isatty(luaL_checkinteger(L, 1)));
|
|
|
|
}
|
|
|
|
|
|
|
|
// unix.tiocgwinsz(fd:int)
|
|
|
|
// ├─→ rows:int, cols:int
|
|
|
|
// └─→ nil, unix.Errno
|
|
|
|
static int LuaUnixTiocgwinsz(lua_State *L) {
|
|
|
|
struct winsize ws;
|
|
|
|
int olderr = errno;
|
|
|
|
if (!ioctl(luaL_checkinteger(L, 1), TIOCGWINSZ, &ws)) {
|
|
|
|
lua_pushinteger(L, ws.ws_row);
|
|
|
|
lua_pushinteger(L, ws.ws_col);
|
|
|
|
return 2;
|
|
|
|
} else {
|
2022-07-20 22:13:39 +00:00
|
|
|
return LuaUnixSysretErrno(L, "tiocgwinsz", olderr);
|
2022-06-27 20:01:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-10-06 11:55:26 +00:00
|
|
|
// unix.sched_yield()
|
|
|
|
static int LuaUnixSchedYield(lua_State *L) {
|
|
|
|
sched_yield();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2023-07-06 22:38:08 +00:00
|
|
|
// unix.verynice()
|
|
|
|
static int LuaUnixVerynice(lua_State *L) {
|
|
|
|
verynice();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2022-04-13 15:49:17 +00:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
2022-04-25 15:30:14 +00:00
|
|
|
// unix.Stat object
|
2022-04-13 15:49:17 +00:00
|
|
|
|
2022-04-28 03:18:34 +00:00
|
|
|
static struct stat *GetUnixStat(lua_State *L) {
|
2022-04-27 12:39:39 +00:00
|
|
|
return luaL_checkudata(L, 1, "unix.Stat");
|
2022-04-13 15:49:17 +00:00
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.Stat:size()
|
|
|
|
// └─→ bytes:int
|
2022-04-13 15:49:17 +00:00
|
|
|
static int LuaUnixStatSize(lua_State *L) {
|
|
|
|
return ReturnInteger(L, GetUnixStat(L)->st_size);
|
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.Stat:mode()
|
|
|
|
// └─→ mode:int
|
2022-04-13 15:49:17 +00:00
|
|
|
static int LuaUnixStatMode(lua_State *L) {
|
|
|
|
return ReturnInteger(L, GetUnixStat(L)->st_mode);
|
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.Stat:dev()
|
|
|
|
// └─→ dev:int
|
2022-04-13 15:49:17 +00:00
|
|
|
static int LuaUnixStatDev(lua_State *L) {
|
|
|
|
return ReturnInteger(L, GetUnixStat(L)->st_dev);
|
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.Stat:ino()
|
|
|
|
// └─→ inodeint
|
2022-04-13 15:49:17 +00:00
|
|
|
static int LuaUnixStatIno(lua_State *L) {
|
|
|
|
return ReturnInteger(L, GetUnixStat(L)->st_ino);
|
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.Stat:nlink()
|
|
|
|
// └─→ count:int
|
2022-04-13 15:49:17 +00:00
|
|
|
static int LuaUnixStatNlink(lua_State *L) {
|
|
|
|
return ReturnInteger(L, GetUnixStat(L)->st_nlink);
|
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.Stat:rdev()
|
|
|
|
// └─→ rdev:int
|
2022-04-13 15:49:17 +00:00
|
|
|
static int LuaUnixStatRdev(lua_State *L) {
|
|
|
|
return ReturnInteger(L, GetUnixStat(L)->st_rdev);
|
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.Stat:uid()
|
|
|
|
// └─→ uid:int
|
2022-04-13 15:49:17 +00:00
|
|
|
static int LuaUnixStatUid(lua_State *L) {
|
|
|
|
return ReturnInteger(L, GetUnixStat(L)->st_uid);
|
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.Stat:gid()
|
|
|
|
// └─→ gid:int
|
2022-04-13 15:49:17 +00:00
|
|
|
static int LuaUnixStatGid(lua_State *L) {
|
|
|
|
return ReturnInteger(L, GetUnixStat(L)->st_gid);
|
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.Stat:blocks()
|
|
|
|
// └─→ count:int
|
2022-04-13 15:49:17 +00:00
|
|
|
static int LuaUnixStatBlocks(lua_State *L) {
|
|
|
|
return ReturnInteger(L, GetUnixStat(L)->st_blocks);
|
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.Stat:blksize()
|
|
|
|
// └─→ bytes:int
|
2022-04-13 15:49:17 +00:00
|
|
|
static int LuaUnixStatBlksize(lua_State *L) {
|
|
|
|
return ReturnInteger(L, GetUnixStat(L)->st_blksize);
|
|
|
|
}
|
|
|
|
|
2022-04-28 16:42:36 +00:00
|
|
|
static dontinline int ReturnTimespec(lua_State *L, struct timespec *ts) {
|
2022-04-25 15:30:14 +00:00
|
|
|
lua_pushinteger(L, ts->tv_sec);
|
|
|
|
lua_pushinteger(L, ts->tv_nsec);
|
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.Stat:atim()
|
|
|
|
// └─→ unixts:int, nanos:int
|
2022-04-13 15:49:17 +00:00
|
|
|
static int LuaUnixStatAtim(lua_State *L) {
|
2022-04-28 16:42:36 +00:00
|
|
|
return ReturnTimespec(L, &GetUnixStat(L)->st_atim);
|
2022-04-13 15:49:17 +00:00
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.Stat:mtim()
|
|
|
|
// └─→ unixts:int, nanos:int
|
2022-04-13 15:49:17 +00:00
|
|
|
static int LuaUnixStatMtim(lua_State *L) {
|
2022-04-28 16:42:36 +00:00
|
|
|
return ReturnTimespec(L, &GetUnixStat(L)->st_mtim);
|
2022-04-13 15:49:17 +00:00
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.Stat:ctim()
|
|
|
|
// └─→ unixts:int, nanos:int
|
2022-04-13 15:49:17 +00:00
|
|
|
static int LuaUnixStatCtim(lua_State *L) {
|
2022-04-28 16:42:36 +00:00
|
|
|
return ReturnTimespec(L, &GetUnixStat(L)->st_ctim);
|
2022-04-13 15:49:17 +00:00
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.Stat:birthtim()
|
|
|
|
// └─→ unixts:int, nanos:int
|
2022-04-18 07:01:26 +00:00
|
|
|
static int LuaUnixStatBirthtim(lua_State *L) {
|
2022-04-28 16:42:36 +00:00
|
|
|
return ReturnTimespec(L, &GetUnixStat(L)->st_birthtim);
|
2022-04-18 07:01:26 +00:00
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.Stat:gen()
|
|
|
|
// └─→ gen:int [xnu/bsd]
|
|
|
|
static int LuaUnixStatGen(lua_State *L) {
|
|
|
|
return ReturnInteger(L, GetUnixStat(L)->st_gen);
|
|
|
|
}
|
|
|
|
|
|
|
|
// unix.Stat:flags()
|
|
|
|
// └─→ flags:int [xnu/bsd]
|
|
|
|
static int LuaUnixStatFlags(lua_State *L) {
|
|
|
|
return ReturnInteger(L, GetUnixStat(L)->st_flags);
|
|
|
|
}
|
|
|
|
|
2022-04-25 15:30:14 +00:00
|
|
|
static int LuaUnixStatToString(lua_State *L) {
|
2022-08-18 06:27:17 +00:00
|
|
|
char ibuf[21];
|
|
|
|
luaL_Buffer b;
|
|
|
|
struct stat *st;
|
|
|
|
st = GetUnixStat(L);
|
|
|
|
luaL_buffinit(L, &b);
|
|
|
|
luaL_addstring(&b, "unix.Stat({size=");
|
|
|
|
FormatInt64(ibuf, st->st_size);
|
|
|
|
luaL_addstring(&b, ibuf);
|
|
|
|
if (st->st_mode) {
|
|
|
|
luaL_addstring(&b, ", mode=");
|
|
|
|
FormatOctal32(ibuf, st->st_mode, 1);
|
|
|
|
luaL_addstring(&b, ibuf);
|
|
|
|
}
|
|
|
|
if (st->st_ino) {
|
|
|
|
luaL_addstring(&b, ", ino=");
|
|
|
|
FormatUint64(ibuf, st->st_ino);
|
|
|
|
luaL_addstring(&b, ibuf);
|
|
|
|
}
|
|
|
|
if (st->st_nlink) {
|
|
|
|
luaL_addstring(&b, ", nlink=");
|
|
|
|
FormatUint64(ibuf, st->st_nlink);
|
|
|
|
luaL_addstring(&b, ibuf);
|
|
|
|
}
|
|
|
|
if (st->st_uid) {
|
|
|
|
luaL_addstring(&b, ", uid=");
|
|
|
|
FormatUint32(ibuf, st->st_uid);
|
|
|
|
luaL_addstring(&b, ibuf);
|
|
|
|
}
|
|
|
|
if (st->st_gid) {
|
|
|
|
luaL_addstring(&b, ", gid=");
|
|
|
|
FormatUint32(ibuf, st->st_gid);
|
|
|
|
luaL_addstring(&b, ibuf);
|
|
|
|
}
|
|
|
|
if (st->st_flags) {
|
|
|
|
luaL_addstring(&b, ", flags=");
|
|
|
|
FormatUint32(ibuf, st->st_flags);
|
|
|
|
luaL_addstring(&b, ibuf);
|
|
|
|
}
|
|
|
|
if (st->st_dev) {
|
|
|
|
luaL_addstring(&b, ", dev=");
|
|
|
|
FormatUint64(ibuf, st->st_dev);
|
|
|
|
luaL_addstring(&b, ibuf);
|
|
|
|
}
|
|
|
|
if (st->st_rdev) {
|
|
|
|
luaL_addstring(&b, ", rdev=");
|
|
|
|
FormatUint64(ibuf, st->st_rdev);
|
|
|
|
luaL_addstring(&b, ibuf);
|
|
|
|
}
|
|
|
|
if (st->st_blksize) {
|
|
|
|
luaL_addstring(&b, ", blksize=");
|
|
|
|
FormatInt64(ibuf, st->st_blksize);
|
|
|
|
luaL_addstring(&b, ibuf);
|
|
|
|
}
|
|
|
|
if (st->st_blocks) {
|
|
|
|
luaL_addstring(&b, ", blocks=");
|
|
|
|
FormatInt64(ibuf, st->st_blocks);
|
|
|
|
luaL_addstring(&b, ibuf);
|
|
|
|
}
|
|
|
|
luaL_addstring(&b, "})");
|
|
|
|
luaL_pushresult(&b);
|
2022-04-25 15:30:14 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2022-04-13 15:49:17 +00:00
|
|
|
static const luaL_Reg kLuaUnixStatMeth[] = {
|
2022-04-25 15:30:14 +00:00
|
|
|
{"atim", LuaUnixStatAtim}, //
|
|
|
|
{"birthtim", LuaUnixStatBirthtim}, //
|
|
|
|
{"blksize", LuaUnixStatBlksize}, //
|
|
|
|
{"blocks", LuaUnixStatBlocks}, //
|
|
|
|
{"ctim", LuaUnixStatCtim}, //
|
2022-04-18 07:01:26 +00:00
|
|
|
{"dev", LuaUnixStatDev}, //
|
2022-04-25 15:30:14 +00:00
|
|
|
{"gid", LuaUnixStatGid}, //
|
2022-04-18 07:01:26 +00:00
|
|
|
{"ino", LuaUnixStatIno}, //
|
2022-04-25 15:30:14 +00:00
|
|
|
{"mode", LuaUnixStatMode}, //
|
|
|
|
{"mtim", LuaUnixStatMtim}, //
|
2022-04-18 07:01:26 +00:00
|
|
|
{"nlink", LuaUnixStatNlink}, //
|
|
|
|
{"rdev", LuaUnixStatRdev}, //
|
2022-04-25 15:30:14 +00:00
|
|
|
{"size", LuaUnixStatSize}, //
|
2022-04-18 07:01:26 +00:00
|
|
|
{"uid", LuaUnixStatUid}, //
|
2022-04-26 04:16:05 +00:00
|
|
|
{"flags", LuaUnixStatFlags}, //
|
|
|
|
{"gen", LuaUnixStatGen}, //
|
2022-04-18 07:01:26 +00:00
|
|
|
{0}, //
|
2022-04-13 15:49:17 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static const luaL_Reg kLuaUnixStatMeta[] = {
|
2022-04-25 15:30:14 +00:00
|
|
|
{"__tostring", LuaUnixStatToString}, //
|
2022-08-18 06:27:17 +00:00
|
|
|
{"__repr", LuaUnixStatToString}, //
|
2022-04-25 15:30:14 +00:00
|
|
|
{0}, //
|
2022-04-13 15:49:17 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static void LuaUnixStatObj(lua_State *L) {
|
2022-04-25 15:30:14 +00:00
|
|
|
luaL_newmetatable(L, "unix.Stat");
|
2022-04-13 15:49:17 +00:00
|
|
|
luaL_setfuncs(L, kLuaUnixStatMeta, 0);
|
|
|
|
luaL_newlibtable(L, kLuaUnixStatMeth);
|
|
|
|
luaL_setfuncs(L, kLuaUnixStatMeth, 0);
|
|
|
|
lua_setfield(L, -2, "__index");
|
|
|
|
lua_pop(L, 1);
|
|
|
|
}
|
|
|
|
|
2022-08-18 06:27:17 +00:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// unix.Statfs object
|
|
|
|
|
|
|
|
static struct statfs *GetUnixStatfs(lua_State *L) {
|
|
|
|
return luaL_checkudata(L, 1, "unix.Statfs");
|
|
|
|
}
|
|
|
|
|
|
|
|
// unix.Statfs:type()
|
|
|
|
// └─→ bytes:int
|
|
|
|
static int LuaUnixStatfsType(lua_State *L) {
|
|
|
|
return ReturnInteger(L, GetUnixStatfs(L)->f_type);
|
|
|
|
}
|
|
|
|
|
|
|
|
// unix.Statfs:bsize()
|
|
|
|
// └─→ bsize:int
|
|
|
|
static int LuaUnixStatfsBsize(lua_State *L) {
|
|
|
|
return ReturnInteger(L, GetUnixStatfs(L)->f_bsize);
|
|
|
|
}
|
|
|
|
|
|
|
|
// unix.Statfs:blocks()
|
|
|
|
// └─→ blocks:int
|
|
|
|
static int LuaUnixStatfsBlocks(lua_State *L) {
|
|
|
|
return ReturnInteger(L, GetUnixStatfs(L)->f_blocks);
|
|
|
|
}
|
|
|
|
|
|
|
|
// unix.Statfs:bfree()
|
|
|
|
// └─→ bfreedeint
|
|
|
|
static int LuaUnixStatfsBfree(lua_State *L) {
|
|
|
|
return ReturnInteger(L, GetUnixStatfs(L)->f_bfree);
|
|
|
|
}
|
|
|
|
|
|
|
|
// unix.Statfs:bavail()
|
|
|
|
// └─→ count:int
|
|
|
|
static int LuaUnixStatfsBavail(lua_State *L) {
|
|
|
|
return ReturnInteger(L, GetUnixStatfs(L)->f_bavail);
|
|
|
|
}
|
|
|
|
|
|
|
|
// unix.Statfs:files()
|
|
|
|
// └─→ files:int
|
|
|
|
static int LuaUnixStatfsFiles(lua_State *L) {
|
|
|
|
return ReturnInteger(L, GetUnixStatfs(L)->f_files);
|
|
|
|
}
|
|
|
|
|
|
|
|
// unix.Statfs:ffree()
|
|
|
|
// └─→ ffree:int
|
|
|
|
static int LuaUnixStatfsFfree(lua_State *L) {
|
|
|
|
return ReturnInteger(L, GetUnixStatfs(L)->f_ffree);
|
|
|
|
}
|
|
|
|
|
|
|
|
// unix.Statfs:fsid()
|
2022-08-23 03:49:33 +00:00
|
|
|
// └─→ x:int, y:int
|
2022-08-18 06:27:17 +00:00
|
|
|
static int LuaUnixStatfsFsid(lua_State *L) {
|
2022-08-23 03:49:33 +00:00
|
|
|
struct statfs *f = GetUnixStatfs(L);
|
|
|
|
lua_pushinteger(L, f->f_fsid.__val[0]);
|
|
|
|
lua_pushinteger(L, f->f_fsid.__val[1]);
|
|
|
|
return 2;
|
2022-08-18 06:27:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// unix.Statfs:namelen()
|
|
|
|
// └─→ count:int
|
|
|
|
static int LuaUnixStatfsNamelen(lua_State *L) {
|
|
|
|
return ReturnInteger(L, GetUnixStatfs(L)->f_namelen);
|
|
|
|
}
|
|
|
|
|
|
|
|
// unix.Statfs:frsize()
|
|
|
|
// └─→ bytes:int
|
|
|
|
static int LuaUnixStatfsFrsize(lua_State *L) {
|
|
|
|
return ReturnInteger(L, GetUnixStatfs(L)->f_frsize);
|
|
|
|
}
|
|
|
|
|
|
|
|
// unix.Statfs:flags()
|
|
|
|
// └─→ bytes:int
|
|
|
|
static int LuaUnixStatfsFlags(lua_State *L) {
|
|
|
|
return ReturnInteger(L, GetUnixStatfs(L)->f_flags);
|
|
|
|
}
|
|
|
|
|
|
|
|
// unix.Statfs:owner()
|
|
|
|
// └─→ bytes:int
|
|
|
|
static int LuaUnixStatfsOwner(lua_State *L) {
|
|
|
|
return ReturnInteger(L, GetUnixStatfs(L)->f_owner);
|
|
|
|
}
|
|
|
|
|
|
|
|
// unix.Statfs:fstypename()
|
|
|
|
// └─→ fstypename:str
|
|
|
|
static int LuaUnixStatfsFstypename(lua_State *L) {
|
|
|
|
return ReturnString(L, GetUnixStatfs(L)->f_fstypename);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int LuaUnixStatfsToString(lua_State *L) {
|
|
|
|
char ibuf[21];
|
|
|
|
luaL_Buffer b;
|
|
|
|
struct statfs *f;
|
|
|
|
f = GetUnixStatfs(L);
|
|
|
|
luaL_buffinit(L, &b);
|
|
|
|
luaL_addstring(&b, "unix.Statfs({type=");
|
|
|
|
FormatInt64(ibuf, f->f_type);
|
|
|
|
luaL_addstring(&b, ibuf);
|
|
|
|
luaL_addstring(&b, ", fstypename=\"");
|
|
|
|
luaL_addstring(&b, f->f_fstypename);
|
|
|
|
luaL_addstring(&b, "\"");
|
|
|
|
if (f->f_bsize) {
|
|
|
|
luaL_addstring(&b, ", bsize=");
|
|
|
|
FormatInt64(ibuf, f->f_bsize);
|
|
|
|
luaL_addstring(&b, ibuf);
|
|
|
|
}
|
|
|
|
if (f->f_blocks) {
|
|
|
|
luaL_addstring(&b, ", blocks=");
|
|
|
|
FormatInt64(ibuf, f->f_blocks);
|
|
|
|
luaL_addstring(&b, ibuf);
|
|
|
|
}
|
|
|
|
if (f->f_bfree) {
|
|
|
|
luaL_addstring(&b, ", bfree=");
|
|
|
|
FormatInt64(ibuf, f->f_bfree);
|
|
|
|
luaL_addstring(&b, ibuf);
|
|
|
|
}
|
|
|
|
if (f->f_bavail) {
|
|
|
|
luaL_addstring(&b, ", bavail=");
|
|
|
|
FormatInt64(ibuf, f->f_bavail);
|
|
|
|
luaL_addstring(&b, ibuf);
|
|
|
|
}
|
|
|
|
if (f->f_files) {
|
|
|
|
luaL_addstring(&b, ", files=");
|
|
|
|
FormatInt64(ibuf, f->f_files);
|
|
|
|
luaL_addstring(&b, ibuf);
|
|
|
|
}
|
|
|
|
if (f->f_ffree) {
|
|
|
|
luaL_addstring(&b, ", ffree=");
|
|
|
|
FormatInt64(ibuf, f->f_ffree);
|
|
|
|
luaL_addstring(&b, ibuf);
|
|
|
|
}
|
2022-08-23 03:49:33 +00:00
|
|
|
if (f->f_fsid.__val[0] || f->f_fsid.__val[1]) {
|
|
|
|
luaL_addstring(&b, ", fsid={");
|
|
|
|
FormatUint64(ibuf, f->f_fsid.__val[0]);
|
|
|
|
luaL_addstring(&b, ibuf);
|
|
|
|
luaL_addstring(&b, ", ");
|
|
|
|
FormatUint64(ibuf, f->f_fsid.__val[1]);
|
2022-08-18 06:27:17 +00:00
|
|
|
luaL_addstring(&b, ibuf);
|
2022-08-23 03:49:33 +00:00
|
|
|
luaL_addstring(&b, "}");
|
2022-08-18 06:27:17 +00:00
|
|
|
}
|
|
|
|
if (f->f_namelen) {
|
|
|
|
luaL_addstring(&b, ", namelen=");
|
|
|
|
FormatUint64(ibuf, f->f_namelen);
|
|
|
|
luaL_addstring(&b, ibuf);
|
|
|
|
}
|
|
|
|
if (f->f_flags) {
|
|
|
|
luaL_addstring(&b, ", flags=");
|
|
|
|
FormatHex64(ibuf, f->f_flags, 2);
|
|
|
|
luaL_addstring(&b, ibuf);
|
|
|
|
}
|
|
|
|
if (f->f_owner) {
|
|
|
|
luaL_addstring(&b, ", owner=");
|
|
|
|
FormatUint32(ibuf, f->f_owner);
|
|
|
|
luaL_addstring(&b, ibuf);
|
|
|
|
}
|
|
|
|
luaL_addstring(&b, "})");
|
|
|
|
luaL_pushresult(&b);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const luaL_Reg kLuaUnixStatfsMeth[] = {
|
|
|
|
{"type", LuaUnixStatfsType}, //
|
|
|
|
{"bsize", LuaUnixStatfsBsize}, //
|
|
|
|
{"blocks", LuaUnixStatfsBlocks}, //
|
|
|
|
{"bfree", LuaUnixStatfsBfree}, //
|
|
|
|
{"bavail", LuaUnixStatfsBavail}, //
|
|
|
|
{"files", LuaUnixStatfsFiles}, //
|
|
|
|
{"ffree", LuaUnixStatfsFfree}, //
|
|
|
|
{"fsid", LuaUnixStatfsFsid}, //
|
|
|
|
{"namelen", LuaUnixStatfsNamelen}, //
|
|
|
|
{"frsize", LuaUnixStatfsFrsize}, //
|
|
|
|
{"flags", LuaUnixStatfsFlags}, //
|
|
|
|
{"owner", LuaUnixStatfsOwner}, //
|
|
|
|
{"fstypename", LuaUnixStatfsFstypename}, //
|
|
|
|
{0}, //
|
|
|
|
};
|
|
|
|
|
|
|
|
static const luaL_Reg kLuaUnixStatfsMeta[] = {
|
|
|
|
{"__tostring", LuaUnixStatfsToString}, //
|
|
|
|
{"__repr", LuaUnixStatfsToString}, //
|
|
|
|
{0}, //
|
|
|
|
};
|
|
|
|
|
|
|
|
static void LuaUnixStatfsObj(lua_State *L) {
|
|
|
|
luaL_newmetatable(L, "unix.Statfs");
|
|
|
|
luaL_setfuncs(L, kLuaUnixStatfsMeta, 0);
|
|
|
|
luaL_newlibtable(L, kLuaUnixStatfsMeth);
|
|
|
|
luaL_setfuncs(L, kLuaUnixStatfsMeth, 0);
|
|
|
|
lua_setfield(L, -2, "__index");
|
|
|
|
lua_pop(L, 1);
|
|
|
|
}
|
|
|
|
|
2022-04-28 16:42:36 +00:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// unix.Rusage object
|
|
|
|
|
|
|
|
static struct rusage *GetUnixRusage(lua_State *L) {
|
|
|
|
return luaL_checkudata(L, 1, "unix.Rusage");
|
|
|
|
}
|
|
|
|
|
|
|
|
static dontinline int ReturnTimeval(lua_State *L, struct timeval *tv) {
|
|
|
|
lua_pushinteger(L, tv->tv_sec);
|
|
|
|
lua_pushinteger(L, tv->tv_usec * 1000);
|
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
// unix.Rusage:utime()
|
|
|
|
// └─→ unixts:int, nanos:int
|
|
|
|
static int LuaUnixRusageUtime(lua_State *L) {
|
|
|
|
return ReturnTimeval(L, &GetUnixRusage(L)->ru_utime);
|
|
|
|
}
|
|
|
|
|
|
|
|
// unix.Rusage:stime()
|
|
|
|
// └─→ unixts:int, nanos:int
|
|
|
|
static int LuaUnixRusageStime(lua_State *L) {
|
|
|
|
return ReturnTimeval(L, &GetUnixRusage(L)->ru_stime);
|
|
|
|
}
|
|
|
|
|
|
|
|
// unix.Rusage:maxrss()
|
|
|
|
// └─→ kilobytes:int
|
|
|
|
static int LuaUnixRusageMaxrss(lua_State *L) {
|
|
|
|
return ReturnInteger(L, GetUnixRusage(L)->ru_maxrss);
|
|
|
|
}
|
|
|
|
|
|
|
|
// unix.Rusage:ixrss()
|
|
|
|
// └─→ integralkilobytes:int
|
|
|
|
static int LuaUnixRusageIxrss(lua_State *L) {
|
|
|
|
return ReturnInteger(L, GetUnixRusage(L)->ru_ixrss);
|
|
|
|
}
|
|
|
|
|
|
|
|
// unid.Rusage:idrss()
|
|
|
|
// └─→ integralkilobytes:int
|
|
|
|
static int LuaUnixRusageIdrss(lua_State *L) {
|
|
|
|
return ReturnInteger(L, GetUnixRusage(L)->ru_idrss);
|
|
|
|
}
|
|
|
|
|
|
|
|
// unis.Rusage:isrss()
|
|
|
|
// └─→ integralkilobytes:int
|
|
|
|
static int LuaUnixRusageIsrss(lua_State *L) {
|
|
|
|
return ReturnInteger(L, GetUnixRusage(L)->ru_isrss);
|
|
|
|
}
|
|
|
|
|
|
|
|
// unix.Rusage:minflt()
|
|
|
|
// └─→ count:int
|
|
|
|
static int LuaUnixRusageMinflt(lua_State *L) {
|
|
|
|
return ReturnInteger(L, GetUnixRusage(L)->ru_minflt);
|
|
|
|
}
|
|
|
|
|
|
|
|
// unix.Rusage:majflt()
|
|
|
|
// └─→ count:int
|
|
|
|
static int LuaUnixRusageMajflt(lua_State *L) {
|
|
|
|
return ReturnInteger(L, GetUnixRusage(L)->ru_majflt);
|
|
|
|
}
|
|
|
|
|
|
|
|
// unix.Rusage:nswap()
|
|
|
|
// └─→ count:int
|
|
|
|
static int LuaUnixRusageNswap(lua_State *L) {
|
|
|
|
return ReturnInteger(L, GetUnixRusage(L)->ru_nswap);
|
|
|
|
}
|
|
|
|
|
|
|
|
// unix.Rusage:inblock()
|
|
|
|
// └─→ count:int
|
|
|
|
static int LuaUnixRusageInblock(lua_State *L) {
|
|
|
|
return ReturnInteger(L, GetUnixRusage(L)->ru_inblock);
|
|
|
|
}
|
|
|
|
|
|
|
|
// unix.Rusage:oublock()
|
|
|
|
// └─→ count:int
|
|
|
|
static int LuaUnixRusageOublock(lua_State *L) {
|
|
|
|
return ReturnInteger(L, GetUnixRusage(L)->ru_oublock);
|
|
|
|
}
|
|
|
|
|
|
|
|
// unix.Rusage:msgsnd()
|
|
|
|
// └─→ count:int
|
|
|
|
static int LuaUnixRusageMsgsnd(lua_State *L) {
|
|
|
|
return ReturnInteger(L, GetUnixRusage(L)->ru_msgsnd);
|
|
|
|
}
|
|
|
|
|
|
|
|
// unix.Rusage:msgrcv()
|
|
|
|
// └─→ count:int
|
|
|
|
static int LuaUnixRusageMsgrcv(lua_State *L) {
|
|
|
|
return ReturnInteger(L, GetUnixRusage(L)->ru_msgrcv);
|
|
|
|
}
|
|
|
|
|
|
|
|
// unix.Rusage:nsignals()
|
|
|
|
// └─→ count:int
|
|
|
|
static int LuaUnixRusageNsignals(lua_State *L) {
|
|
|
|
return ReturnInteger(L, GetUnixRusage(L)->ru_nsignals);
|
|
|
|
}
|
|
|
|
|
|
|
|
// unix.Rusage:nvcsw()
|
|
|
|
// └─→ count:int
|
|
|
|
static int LuaUnixRusageNvcsw(lua_State *L) {
|
|
|
|
return ReturnInteger(L, GetUnixRusage(L)->ru_nvcsw);
|
|
|
|
}
|
|
|
|
|
|
|
|
// unix.Rusage:nivcsw()
|
|
|
|
// └─→ count:int
|
|
|
|
static int LuaUnixRusageNivcsw(lua_State *L) {
|
|
|
|
return ReturnInteger(L, GetUnixRusage(L)->ru_nivcsw);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int LuaUnixRusageToString(lua_State *L) {
|
|
|
|
char *b = 0;
|
|
|
|
struct rusage *ru = GetUnixRusage(L);
|
|
|
|
appends(&b, "{");
|
|
|
|
appendf(&b, "%s={%ld, %ld}", "utime", ru->ru_utime.tv_sec,
|
|
|
|
ru->ru_utime.tv_usec * 1000);
|
|
|
|
if (ru->ru_stime.tv_sec || ru->ru_stime.tv_usec) {
|
|
|
|
appendw(&b, READ16LE(", "));
|
|
|
|
appendf(&b, "%s={%ld, %ld}", "stime", ru->ru_stime.tv_sec,
|
|
|
|
ru->ru_stime.tv_usec * 1000);
|
|
|
|
}
|
|
|
|
if (ru->ru_maxrss) appendf(&b, ", %s=%ld", "maxrss", ru->ru_maxrss);
|
|
|
|
if (ru->ru_ixrss) appendf(&b, ", %s=%ld", "ixrss", ru->ru_ixrss);
|
|
|
|
if (ru->ru_idrss) appendf(&b, ", %s=%ld", "idrss", ru->ru_idrss);
|
|
|
|
if (ru->ru_isrss) appendf(&b, ", %s=%ld", "isrss", ru->ru_isrss);
|
|
|
|
if (ru->ru_minflt) appendf(&b, ", %s=%ld", "minflt", ru->ru_minflt);
|
|
|
|
if (ru->ru_majflt) appendf(&b, ", %s=%ld", "majflt", ru->ru_majflt);
|
|
|
|
if (ru->ru_nswap) appendf(&b, ", %s=%ld", "nswap", ru->ru_nswap);
|
|
|
|
if (ru->ru_inblock) appendf(&b, ", %s=%ld", "inblock", ru->ru_inblock);
|
|
|
|
if (ru->ru_oublock) appendf(&b, ", %s=%ld", "oublock", ru->ru_oublock);
|
|
|
|
if (ru->ru_msgsnd) appendf(&b, ", %s=%ld", "msgsnd", ru->ru_msgsnd);
|
|
|
|
if (ru->ru_msgrcv) appendf(&b, ", %s=%ld", "msgrcv", ru->ru_msgrcv);
|
|
|
|
if (ru->ru_nsignals) appendf(&b, ", %s=%ld", "nsignals", ru->ru_nsignals);
|
|
|
|
if (ru->ru_nvcsw) appendf(&b, ", %s=%ld", "nvcsw", ru->ru_nvcsw);
|
|
|
|
if (ru->ru_nivcsw) appendf(&b, ", %s=%ld", "nivcsw", ru->ru_nivcsw);
|
|
|
|
appendw(&b, '}');
|
|
|
|
lua_pushlstring(L, b, appendz(b).i);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const luaL_Reg kLuaUnixRusageMeth[] = {
|
|
|
|
{"utime", LuaUnixRusageUtime}, //
|
|
|
|
{"stime", LuaUnixRusageStime}, //
|
|
|
|
{"maxrss", LuaUnixRusageMaxrss}, //
|
|
|
|
{"ixrss", LuaUnixRusageIxrss}, //
|
|
|
|
{"idrss", LuaUnixRusageIdrss}, //
|
|
|
|
{"isrss", LuaUnixRusageIsrss}, //
|
|
|
|
{"minflt", LuaUnixRusageMinflt}, //
|
|
|
|
{"majflt", LuaUnixRusageMajflt}, //
|
|
|
|
{"nswap", LuaUnixRusageNswap}, //
|
|
|
|
{"inblock", LuaUnixRusageInblock}, //
|
|
|
|
{"oublock", LuaUnixRusageOublock}, //
|
|
|
|
{"msgsnd", LuaUnixRusageMsgsnd}, //
|
|
|
|
{"msgrcv", LuaUnixRusageMsgrcv}, //
|
|
|
|
{"nsignals", LuaUnixRusageNsignals}, //
|
|
|
|
{"nvcsw", LuaUnixRusageNvcsw}, //
|
|
|
|
{"nivcsw", LuaUnixRusageNivcsw}, //
|
|
|
|
{0}, //
|
|
|
|
};
|
|
|
|
|
|
|
|
static const luaL_Reg kLuaUnixRusageMeta[] = {
|
|
|
|
{"__repr", LuaUnixRusageToString}, //
|
|
|
|
{"__tostring", LuaUnixRusageToString}, //
|
|
|
|
{0}, //
|
|
|
|
};
|
|
|
|
|
|
|
|
static void LuaUnixRusageObj(lua_State *L) {
|
|
|
|
luaL_newmetatable(L, "unix.Rusage");
|
|
|
|
luaL_setfuncs(L, kLuaUnixRusageMeta, 0);
|
|
|
|
luaL_newlibtable(L, kLuaUnixRusageMeth);
|
|
|
|
luaL_setfuncs(L, kLuaUnixRusageMeth, 0);
|
|
|
|
lua_setfield(L, -2, "__index");
|
|
|
|
lua_pop(L, 1);
|
|
|
|
}
|
|
|
|
|
2022-04-13 15:49:17 +00:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
2022-04-25 15:30:14 +00:00
|
|
|
// unix.Errno object
|
|
|
|
|
2022-04-27 12:39:39 +00:00
|
|
|
static struct UnixErrno *GetUnixErrno(lua_State *L) {
|
|
|
|
return luaL_checkudata(L, 1, "unix.Errno");
|
2022-04-25 15:30:14 +00:00
|
|
|
}
|
|
|
|
|
2022-04-28 16:42:36 +00:00
|
|
|
// unix.Errno:errno()
|
|
|
|
// └─→ errno:int
|
2022-04-26 04:16:05 +00:00
|
|
|
static int LuaUnixErrnoErrno(lua_State *L) {
|
2022-05-16 20:20:08 +00:00
|
|
|
return ReturnInteger(L, GetUnixErrno(L)->errno_);
|
2022-04-25 15:30:14 +00:00
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
static int LuaUnixErrnoWinerr(lua_State *L) {
|
|
|
|
return ReturnInteger(L, GetUnixErrno(L)->winerr);
|
2022-04-25 15:30:14 +00:00
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
static int LuaUnixErrnoName(lua_State *L) {
|
2022-09-13 06:10:38 +00:00
|
|
|
return ReturnString(L, _strerrno(GetUnixErrno(L)->errno_));
|
2022-04-26 04:16:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int LuaUnixErrnoDoc(lua_State *L) {
|
2022-09-13 06:10:38 +00:00
|
|
|
return ReturnString(L, _strerdoc(GetUnixErrno(L)->errno_));
|
2022-04-25 15:30:14 +00:00
|
|
|
}
|
|
|
|
|
2022-04-28 16:42:36 +00:00
|
|
|
static int LuaUnixErrnoCall(lua_State *L) {
|
|
|
|
return ReturnString(L, GetUnixErrno(L)->call);
|
|
|
|
}
|
|
|
|
|
2022-04-25 15:30:14 +00:00
|
|
|
static int LuaUnixErrnoToString(lua_State *L) {
|
2022-04-26 04:16:05 +00:00
|
|
|
char msg[256];
|
|
|
|
struct UnixErrno *e;
|
|
|
|
e = GetUnixErrno(L);
|
|
|
|
if (e->call) {
|
2022-05-16 20:20:08 +00:00
|
|
|
strerror_wr(e->errno_, e->winerr, msg, sizeof(msg));
|
2022-04-26 04:16:05 +00:00
|
|
|
lua_pushfstring(L, "%s() failed: %s", e->call, msg);
|
|
|
|
} else {
|
2022-09-13 06:10:38 +00:00
|
|
|
lua_pushstring(L, _strerrno(e->errno_));
|
2022-04-26 04:16:05 +00:00
|
|
|
}
|
2022-04-25 15:30:14 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const luaL_Reg kLuaUnixErrnoMeth[] = {
|
2022-04-28 16:42:36 +00:00
|
|
|
{"errno", LuaUnixErrnoErrno}, //
|
|
|
|
{"winerr", LuaUnixErrnoWinerr}, //
|
|
|
|
{"name", LuaUnixErrnoName}, //
|
|
|
|
{"call", LuaUnixErrnoCall}, //
|
|
|
|
{"doc", LuaUnixErrnoDoc}, //
|
|
|
|
{0}, //
|
2022-04-25 15:30:14 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static const luaL_Reg kLuaUnixErrnoMeta[] = {
|
|
|
|
{"__tostring", LuaUnixErrnoToString}, //
|
|
|
|
{0}, //
|
|
|
|
};
|
|
|
|
|
|
|
|
static void LuaUnixErrnoObj(lua_State *L) {
|
|
|
|
luaL_newmetatable(L, "unix.Errno");
|
|
|
|
luaL_setfuncs(L, kLuaUnixErrnoMeta, 0);
|
|
|
|
luaL_newlibtable(L, kLuaUnixErrnoMeth);
|
|
|
|
luaL_setfuncs(L, kLuaUnixErrnoMeth, 0);
|
|
|
|
lua_setfield(L, -2, "__index");
|
|
|
|
lua_pop(L, 1);
|
|
|
|
}
|
|
|
|
|
2022-10-06 11:55:26 +00:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// unix.Memory object
|
|
|
|
|
|
|
|
struct Memory {
|
|
|
|
union {
|
|
|
|
char *bytes;
|
|
|
|
atomic_long *words;
|
|
|
|
} u;
|
|
|
|
size_t size;
|
|
|
|
void *map;
|
|
|
|
size_t mapsize;
|
|
|
|
pthread_mutex_t *lock;
|
|
|
|
};
|
|
|
|
|
|
|
|
// unix.Memory:read([offset:int[, bytes:int]])
|
|
|
|
// └─→ str
|
|
|
|
static int LuaUnixMemoryRead(lua_State *L) {
|
|
|
|
size_t i, n;
|
|
|
|
struct Memory *m;
|
|
|
|
m = luaL_checkudata(L, 1, "unix.Memory");
|
|
|
|
i = luaL_optinteger(L, 2, 0);
|
|
|
|
if (lua_isnoneornil(L, 3)) {
|
|
|
|
// unix.Memory:read([offset:int])
|
|
|
|
// extracts nul-terminated string
|
|
|
|
if (i > m->size) {
|
|
|
|
luaL_error(L, "out of range");
|
2023-06-09 06:44:03 +00:00
|
|
|
__builtin_unreachable();
|
2022-10-06 11:55:26 +00:00
|
|
|
}
|
|
|
|
n = strnlen(m->u.bytes + i, m->size - i);
|
|
|
|
} else {
|
|
|
|
// unix.Memory:read(offset:int, bytes:int)
|
|
|
|
// read binary data with boundary checking
|
|
|
|
n = luaL_checkinteger(L, 3);
|
|
|
|
if (i > m->size || n >= m->size || i + n > m->size) {
|
|
|
|
luaL_error(L, "out of range");
|
2023-06-09 06:44:03 +00:00
|
|
|
__builtin_unreachable();
|
2022-10-06 11:55:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
pthread_mutex_lock(m->lock);
|
|
|
|
lua_pushlstring(L, m->u.bytes + i, n);
|
|
|
|
pthread_mutex_unlock(m->lock);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2022-10-08 15:39:13 +00:00
|
|
|
// unix.Memory:write([offset:int,] data:str[, bytes:int])
|
2022-10-06 11:55:26 +00:00
|
|
|
static int LuaUnixMemoryWrite(lua_State *L) {
|
2022-10-08 15:39:13 +00:00
|
|
|
int b;
|
2022-10-06 11:55:26 +00:00
|
|
|
const char *s;
|
|
|
|
size_t i, n, j;
|
|
|
|
struct Memory *m;
|
|
|
|
m = luaL_checkudata(L, 1, "unix.Memory");
|
2022-10-08 15:39:13 +00:00
|
|
|
if (!lua_isnumber(L, 2)) {
|
|
|
|
// unix.Memory:write(data:str[, bytes:int])
|
|
|
|
i = 0;
|
|
|
|
s = luaL_checklstring(L, 2, &n);
|
|
|
|
b = 3;
|
|
|
|
} else {
|
|
|
|
// unix.Memory:write(offset:int, data:str[, bytes:int])
|
|
|
|
i = luaL_checkinteger(L, 2);
|
|
|
|
s = luaL_checklstring(L, 3, &n);
|
|
|
|
b = 4;
|
|
|
|
}
|
2022-10-06 11:55:26 +00:00
|
|
|
if (i > m->size) {
|
|
|
|
luaL_error(L, "out of range");
|
2023-06-09 06:44:03 +00:00
|
|
|
__builtin_unreachable();
|
2022-10-06 11:55:26 +00:00
|
|
|
}
|
2022-10-08 15:39:13 +00:00
|
|
|
if (lua_isnoneornil(L, b)) {
|
2022-10-06 11:55:26 +00:00
|
|
|
// unix.Memory:write(data:str[, offset:int])
|
|
|
|
// writes binary data, plus a nul terminator
|
|
|
|
if (i < n < m->size) {
|
|
|
|
// include lua string's implicit nul so this round trips with
|
|
|
|
// unix.Memory:read(offset:int) even when we're overwriting a
|
|
|
|
// larger string that was previously inserted
|
|
|
|
n += 1;
|
|
|
|
} else {
|
|
|
|
// there's no room to include the implicit nul-terminator so
|
|
|
|
// leave it out which is safe b/c Memory:read() uses strnlen
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// unix.Memory:write(data:str, offset:int, bytes:int])
|
|
|
|
// writes binary data without including nul-terminator
|
2022-10-08 15:39:13 +00:00
|
|
|
j = luaL_checkinteger(L, b);
|
2022-10-06 11:55:26 +00:00
|
|
|
if (j > n) {
|
2022-10-08 15:39:13 +00:00
|
|
|
luaL_argerror(L, b, "bytes is more than what's in data");
|
2023-06-09 06:44:03 +00:00
|
|
|
__builtin_unreachable();
|
2022-10-06 11:55:26 +00:00
|
|
|
}
|
|
|
|
n = j;
|
|
|
|
}
|
|
|
|
if (i + n > m->size) {
|
|
|
|
luaL_error(L, "out of range");
|
2023-06-09 06:44:03 +00:00
|
|
|
__builtin_unreachable();
|
2022-10-06 11:55:26 +00:00
|
|
|
}
|
|
|
|
pthread_mutex_lock(m->lock);
|
|
|
|
memcpy(m->u.bytes + i, s, n);
|
|
|
|
pthread_mutex_unlock(m->lock);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static atomic_long *GetWord(lua_State *L) {
|
|
|
|
size_t i;
|
|
|
|
struct Memory *m;
|
|
|
|
m = luaL_checkudata(L, 1, "unix.Memory");
|
|
|
|
i = luaL_checkinteger(L, 2);
|
|
|
|
if (i >= m->size / sizeof(*m->u.words)) {
|
|
|
|
luaL_error(L, "out of range");
|
2023-06-09 06:44:03 +00:00
|
|
|
__builtin_unreachable();
|
2022-10-06 11:55:26 +00:00
|
|
|
}
|
|
|
|
return m->u.words + i;
|
|
|
|
}
|
|
|
|
|
|
|
|
// unix.Memory:load(word_index:int)
|
|
|
|
// └─→ int
|
|
|
|
static int LuaUnixMemoryLoad(lua_State *L) {
|
|
|
|
lua_pushinteger(L, atomic_load_explicit(GetWord(L), memory_order_relaxed));
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// unix.Memory:store(word_index:int, value:int)
|
|
|
|
static int LuaUnixMemoryStore(lua_State *L) {
|
|
|
|
atomic_store_explicit(GetWord(L), luaL_checkinteger(L, 3),
|
|
|
|
memory_order_relaxed);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// unix.Memory:xchg(word_index:int, value:int)
|
|
|
|
// └─→ int
|
|
|
|
static int LuaUnixMemoryXchg(lua_State *L) {
|
|
|
|
lua_pushinteger(L, atomic_exchange(GetWord(L), luaL_checkinteger(L, 3)));
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// unix.Memory:cmpxchg(word_index:int, old:int, new:int)
|
|
|
|
// └─→ success:bool, old:int
|
|
|
|
static int LuaUnixMemoryCmpxchg(lua_State *L) {
|
|
|
|
long old = luaL_checkinteger(L, 3);
|
|
|
|
lua_pushboolean(L, atomic_compare_exchange_strong(GetWord(L), &old,
|
|
|
|
luaL_checkinteger(L, 4)));
|
|
|
|
lua_pushinteger(L, old);
|
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
// unix.Memory:add(word_index:int, value:int)
|
|
|
|
// └─→ old:int
|
|
|
|
static int LuaUnixMemoryAdd(lua_State *L) {
|
|
|
|
lua_pushinteger(L, atomic_fetch_add(GetWord(L), luaL_checkinteger(L, 3)));
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// unix.Memory:and(word_index:int, value:int)
|
|
|
|
// └─→ old:int
|
|
|
|
static int LuaUnixMemoryAnd(lua_State *L) {
|
|
|
|
lua_pushinteger(L, atomic_fetch_and(GetWord(L), luaL_checkinteger(L, 3)));
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// unix.Memory:or(word_index:int, value:int)
|
|
|
|
// └─→ old:int
|
|
|
|
static int LuaUnixMemoryOr(lua_State *L) {
|
|
|
|
lua_pushinteger(L, atomic_fetch_or(GetWord(L), luaL_checkinteger(L, 3)));
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// unix.Memory:xor(word_index:int, value:int)
|
|
|
|
// └─→ old:int
|
|
|
|
static int LuaUnixMemoryXor(lua_State *L) {
|
|
|
|
lua_pushinteger(L, atomic_fetch_xor(GetWord(L), luaL_checkinteger(L, 3)));
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// unix.Memory:wait(word_index:int, expect:int[, abs_deadline:int[, nanos:int]])
|
|
|
|
// ├─→ 0
|
|
|
|
// ├─→ nil, unix.Errno(unix.EINTR)
|
|
|
|
// ├─→ nil, unix.Errno(unix.EAGAIN)
|
|
|
|
// └─→ nil, unix.Errno(unix.ETIMEDOUT)
|
|
|
|
static int LuaUnixMemoryWait(lua_State *L) {
|
|
|
|
lua_Integer expect;
|
|
|
|
int rc, olderr = errno;
|
|
|
|
struct timespec ts, now, *deadline;
|
|
|
|
expect = luaL_checkinteger(L, 3);
|
|
|
|
if (!(INT32_MIN <= expect && expect <= INT32_MAX)) {
|
|
|
|
luaL_argerror(L, 3, "must be an int32_t");
|
2023-06-09 06:44:03 +00:00
|
|
|
__builtin_unreachable();
|
2022-10-06 11:55:26 +00:00
|
|
|
}
|
|
|
|
if (lua_isnoneornil(L, 4)) {
|
|
|
|
deadline = 0; // wait forever
|
|
|
|
} else {
|
|
|
|
ts.tv_sec = luaL_checkinteger(L, 4);
|
|
|
|
ts.tv_nsec = luaL_optinteger(L, 5, 0);
|
|
|
|
deadline = &ts;
|
|
|
|
}
|
2022-11-06 02:49:41 +00:00
|
|
|
BEGIN_CANCELLATION_POINT;
|
2022-10-14 15:25:47 +00:00
|
|
|
rc = nsync_futex_wait_((atomic_int *)GetWord(L), expect,
|
|
|
|
PTHREAD_PROCESS_SHARED, deadline);
|
2022-11-06 02:49:41 +00:00
|
|
|
END_CANCELLATION_POINT;
|
2022-10-06 11:55:26 +00:00
|
|
|
if (rc < 0) errno = -rc, rc = -1;
|
|
|
|
return SysretInteger(L, "futex_wait", olderr, rc);
|
|
|
|
}
|
|
|
|
|
|
|
|
// unix.Memory:wake(index:int[, count:int])
|
|
|
|
// └─→ woken:int
|
|
|
|
static int LuaUnixMemoryWake(lua_State *L) {
|
|
|
|
int count, woken;
|
|
|
|
count = luaL_optinteger(L, 3, INT_MAX);
|
2022-10-14 15:25:47 +00:00
|
|
|
woken = nsync_futex_wake_((atomic_int *)GetWord(L), count,
|
|
|
|
PTHREAD_PROCESS_SHARED);
|
2022-10-06 11:55:26 +00:00
|
|
|
_npassert(woken >= 0);
|
|
|
|
return ReturnInteger(L, woken);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int LuaUnixMemoryTostring(lua_State *L) {
|
|
|
|
char s[128];
|
|
|
|
struct Memory *m;
|
|
|
|
m = luaL_checkudata(L, 1, "unix.Memory");
|
|
|
|
snprintf(s, sizeof(s), "unix.Memory(%zu)", m->size);
|
|
|
|
lua_pushstring(L, s);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int LuaUnixMemoryGc(lua_State *L) {
|
|
|
|
struct Memory *m;
|
|
|
|
m = luaL_checkudata(L, 1, "unix.Memory");
|
|
|
|
if (m->u.bytes) {
|
|
|
|
_npassert(!munmap(m->map, m->mapsize));
|
|
|
|
m->u.bytes = 0;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const luaL_Reg kLuaUnixMemoryMeth[] = {
|
|
|
|
{"read", LuaUnixMemoryRead}, //
|
|
|
|
{"write", LuaUnixMemoryWrite}, //
|
|
|
|
{"load", LuaUnixMemoryLoad}, //
|
|
|
|
{"store", LuaUnixMemoryStore}, //
|
|
|
|
{"xchg", LuaUnixMemoryXchg}, //
|
|
|
|
{"cmpxchg", LuaUnixMemoryCmpxchg}, //
|
2022-10-06 16:41:22 +00:00
|
|
|
{"fetch_add", LuaUnixMemoryAdd}, //
|
|
|
|
{"fetch_and", LuaUnixMemoryAnd}, //
|
|
|
|
{"fetch_or", LuaUnixMemoryOr}, //
|
|
|
|
{"fetch_xor", LuaUnixMemoryXor}, //
|
2022-10-06 11:55:26 +00:00
|
|
|
{"wait", LuaUnixMemoryWait}, //
|
|
|
|
{"wake", LuaUnixMemoryWake}, //
|
|
|
|
{0}, //
|
|
|
|
};
|
|
|
|
|
|
|
|
static const luaL_Reg kLuaUnixMemoryMeta[] = {
|
|
|
|
{"__tostring", LuaUnixMemoryTostring}, //
|
|
|
|
{"__repr", LuaUnixMemoryTostring}, //
|
|
|
|
{"__gc", LuaUnixMemoryGc}, //
|
|
|
|
{0}, //
|
|
|
|
};
|
|
|
|
|
|
|
|
static void LuaUnixMemoryObj(lua_State *L) {
|
|
|
|
luaL_newmetatable(L, "unix.Memory");
|
|
|
|
luaL_setfuncs(L, kLuaUnixMemoryMeta, 0);
|
|
|
|
luaL_newlibtable(L, kLuaUnixMemoryMeth);
|
|
|
|
luaL_setfuncs(L, kLuaUnixMemoryMeth, 0);
|
|
|
|
lua_setfield(L, -2, "__index");
|
|
|
|
lua_pop(L, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int LuaUnixMapshared(lua_State *L) {
|
|
|
|
char *p;
|
|
|
|
size_t n, c, g;
|
|
|
|
struct Memory *m;
|
|
|
|
pthread_mutexattr_t mattr;
|
|
|
|
n = luaL_checkinteger(L, 1);
|
|
|
|
if (!n) {
|
|
|
|
luaL_error(L, "can't map empty region");
|
2023-06-09 06:44:03 +00:00
|
|
|
__builtin_unreachable();
|
2022-10-06 11:55:26 +00:00
|
|
|
}
|
|
|
|
if (n % sizeof(long)) {
|
|
|
|
luaL_error(L, "size must be multiple of word size");
|
2023-06-09 06:44:03 +00:00
|
|
|
__builtin_unreachable();
|
2022-10-06 11:55:26 +00:00
|
|
|
}
|
|
|
|
if (!IsLegalSize(n)) {
|
|
|
|
luaL_error(L, "map size too big");
|
2023-06-09 06:44:03 +00:00
|
|
|
__builtin_unreachable();
|
2022-10-06 11:55:26 +00:00
|
|
|
}
|
|
|
|
c = n;
|
|
|
|
c += sizeof(*m->lock);
|
|
|
|
g = sysconf(_SC_PAGESIZE);
|
|
|
|
c = ROUNDUP(c, g);
|
|
|
|
if (!(p = _mapshared(c))) {
|
|
|
|
luaL_error(L, "out of memory");
|
2023-06-09 06:44:03 +00:00
|
|
|
__builtin_unreachable();
|
2022-10-06 11:55:26 +00:00
|
|
|
}
|
|
|
|
m = lua_newuserdatauv(L, sizeof(*m), 1);
|
|
|
|
luaL_setmetatable(L, "unix.Memory");
|
|
|
|
m->u.bytes = p + sizeof(*m->lock);
|
|
|
|
m->size = n;
|
|
|
|
m->map = p;
|
|
|
|
m->mapsize = c;
|
|
|
|
m->lock = (pthread_mutex_t *)p;
|
|
|
|
pthread_mutexattr_init(&mattr);
|
|
|
|
pthread_mutexattr_settype(&mattr, PTHREAD_MUTEX_NORMAL);
|
|
|
|
pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_SHARED);
|
|
|
|
pthread_mutex_init(m->lock, &mattr);
|
|
|
|
pthread_mutexattr_destroy(&mattr);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// unix.Sigset object
|
|
|
|
|
|
|
|
// unix.Sigset(sig:int, ...)
|
|
|
|
// └─→ unix.Sigset
|
|
|
|
static int LuaUnixSigset(lua_State *L) {
|
|
|
|
int i, n;
|
|
|
|
lua_Integer sig;
|
|
|
|
struct sigset set;
|
|
|
|
sigemptyset(&set);
|
|
|
|
n = lua_gettop(L);
|
|
|
|
for (i = 1; i <= n; ++i) {
|
|
|
|
sig = luaL_checkinteger(L, i);
|
|
|
|
if (1 <= sig && sig <= NSIG) {
|
|
|
|
set.__bits[(sig - 1) >> 6] |= 1ull << ((sig - 1) & 63);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
LuaPushSigset(L, set);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// unix.Sigset:add(sig:int)
|
|
|
|
static int LuaUnixSigsetAdd(lua_State *L) {
|
|
|
|
lua_Integer sig;
|
|
|
|
struct sigset *set;
|
|
|
|
set = luaL_checkudata(L, 1, "unix.Sigset");
|
|
|
|
sig = luaL_checkinteger(L, 2);
|
|
|
|
if (1 <= sig && sig <= NSIG) {
|
|
|
|
set->__bits[(sig - 1) >> 6] |= 1ull << ((sig - 1) & 63);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// unix.Sigset:remove(sig:int)
|
|
|
|
static int LuaUnixSigsetRemove(lua_State *L) {
|
|
|
|
lua_Integer sig;
|
|
|
|
struct sigset *set;
|
|
|
|
set = luaL_checkudata(L, 1, "unix.Sigset");
|
|
|
|
sig = luaL_checkinteger(L, 2);
|
|
|
|
if (1 <= sig && sig <= NSIG) {
|
|
|
|
set->__bits[(sig - 1) >> 6] &= ~(1ull << ((sig - 1) & 63));
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// unix.Sigset:fill()
|
|
|
|
static int LuaUnixSigsetFill(lua_State *L) {
|
|
|
|
struct sigset *set;
|
|
|
|
set = luaL_checkudata(L, 1, "unix.Sigset");
|
|
|
|
memset(set, -1, sizeof(*set));
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// unix.Sigset:clear()
|
|
|
|
static int LuaUnixSigsetClear(lua_State *L) {
|
|
|
|
struct sigset *set;
|
|
|
|
set = luaL_checkudata(L, 1, "unix.Sigset");
|
|
|
|
bzero(set, sizeof(*set));
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// unix.Sigset:contains(sig:int)
|
|
|
|
// └─→ bool
|
|
|
|
static int LuaUnixSigsetContains(lua_State *L) {
|
|
|
|
lua_Integer sig;
|
|
|
|
struct sigset *set;
|
|
|
|
set = luaL_checkudata(L, 1, "unix.Sigset");
|
|
|
|
sig = luaL_checkinteger(L, 2);
|
|
|
|
return ReturnBoolean(
|
|
|
|
L, (1 <= sig && sig <= NSIG)
|
|
|
|
? !!(set->__bits[(sig - 1) >> 6] & (1ull << ((sig - 1) & 63)))
|
|
|
|
: false);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int LuaUnixSigsetTostring(lua_State *L) {
|
|
|
|
char *b = 0;
|
|
|
|
int sig, first;
|
|
|
|
struct sigset *ss;
|
|
|
|
ss = luaL_checkudata(L, 1, "unix.Sigset");
|
|
|
|
appends(&b, "unix.Sigset");
|
|
|
|
appendw(&b, '(');
|
|
|
|
for (sig = first = 1; sig <= NSIG; ++sig) {
|
|
|
|
if (sigismember(ss, sig) == 1) {
|
|
|
|
if (!first) {
|
|
|
|
appendw(&b, READ16LE(", "));
|
|
|
|
} else {
|
|
|
|
first = 0;
|
|
|
|
}
|
|
|
|
appendw(&b, READ64LE("unix.\0\0"));
|
|
|
|
appends(&b, strsignal(sig));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
appendw(&b, ')');
|
|
|
|
lua_pushlstring(L, b, appendz(b).i);
|
|
|
|
free(b);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const luaL_Reg kLuaUnixSigsetMeth[] = {
|
|
|
|
{"add", LuaUnixSigsetAdd}, //
|
|
|
|
{"fill", LuaUnixSigsetFill}, //
|
|
|
|
{"clear", LuaUnixSigsetClear}, //
|
|
|
|
{"remove", LuaUnixSigsetRemove}, //
|
|
|
|
{"contains", LuaUnixSigsetContains}, //
|
|
|
|
{0}, //
|
|
|
|
};
|
|
|
|
|
|
|
|
static const luaL_Reg kLuaUnixSigsetMeta[] = {
|
|
|
|
{"__tostring", LuaUnixSigsetTostring}, //
|
|
|
|
{"__repr", LuaUnixSigsetTostring}, //
|
|
|
|
{0}, //
|
|
|
|
};
|
|
|
|
|
|
|
|
static void LuaUnixSigsetObj(lua_State *L) {
|
|
|
|
luaL_newmetatable(L, "unix.Sigset");
|
|
|
|
luaL_setfuncs(L, kLuaUnixSigsetMeta, 0);
|
|
|
|
luaL_newlibtable(L, kLuaUnixSigsetMeth);
|
|
|
|
luaL_setfuncs(L, kLuaUnixSigsetMeth, 0);
|
|
|
|
lua_setfield(L, -2, "__index");
|
|
|
|
lua_pop(L, 1);
|
|
|
|
}
|
|
|
|
|
2022-04-25 15:30:14 +00:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// unix.Dir object
|
2022-04-13 15:49:17 +00:00
|
|
|
|
2022-04-28 03:18:34 +00:00
|
|
|
static DIR **GetUnixDirSelf(lua_State *L) {
|
2022-04-25 15:30:14 +00:00
|
|
|
return luaL_checkudata(L, 1, "unix.Dir");
|
2022-04-13 15:49:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static DIR *GetDirOrDie(lua_State *L) {
|
2022-04-28 03:18:34 +00:00
|
|
|
DIR **dirp;
|
|
|
|
dirp = GetUnixDirSelf(L);
|
|
|
|
if (*dirp) return *dirp;
|
2022-04-25 15:30:14 +00:00
|
|
|
luaL_argerror(L, 1, "unix.UnixDir is closed");
|
2023-06-09 06:44:03 +00:00
|
|
|
__builtin_unreachable();
|
2022-04-13 15:49:17 +00:00
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.Dir:close()
|
|
|
|
// ├─→ true
|
|
|
|
// └─→ nil, unix.Errno
|
2022-04-13 15:49:17 +00:00
|
|
|
static int LuaUnixDirClose(lua_State *L) {
|
2022-04-28 03:18:34 +00:00
|
|
|
DIR **dirp;
|
2022-04-18 07:01:26 +00:00
|
|
|
int rc, olderr;
|
2022-04-28 03:18:34 +00:00
|
|
|
dirp = GetUnixDirSelf(L);
|
|
|
|
if (*dirp) {
|
2022-05-11 09:50:03 +00:00
|
|
|
olderr = errno;
|
2022-04-28 03:18:34 +00:00
|
|
|
rc = closedir(*dirp);
|
|
|
|
*dirp = 0;
|
2022-04-26 04:16:05 +00:00
|
|
|
return SysretBool(L, "closedir", olderr, rc);
|
|
|
|
} else {
|
|
|
|
lua_pushboolean(L, true);
|
|
|
|
return 1;
|
|
|
|
}
|
2022-04-13 15:49:17 +00:00
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.Dir:read()
|
|
|
|
// ├─→ name:str, kind:int, ino:int, off:int
|
|
|
|
// └─→ nil
|
2022-04-13 15:49:17 +00:00
|
|
|
static int LuaUnixDirRead(lua_State *L) {
|
|
|
|
struct dirent *ent;
|
|
|
|
if ((ent = readdir(GetDirOrDie(L)))) {
|
|
|
|
lua_pushlstring(L, ent->d_name, strnlen(ent->d_name, sizeof(ent->d_name)));
|
|
|
|
lua_pushinteger(L, ent->d_type);
|
|
|
|
lua_pushinteger(L, ent->d_ino);
|
|
|
|
lua_pushinteger(L, ent->d_off);
|
2022-04-26 04:16:05 +00:00
|
|
|
return 4;
|
2022-04-13 15:49:17 +00:00
|
|
|
} else {
|
2022-04-26 04:16:05 +00:00
|
|
|
// end of directory stream condition
|
|
|
|
// we make the assumption getdents() won't fail
|
|
|
|
lua_pushnil(L);
|
|
|
|
return 1;
|
2022-04-13 15:49:17 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.Dir:fd()
|
|
|
|
// ├─→ fd:int
|
|
|
|
// └─→ nil, unix.Errno
|
2022-04-13 15:49:17 +00:00
|
|
|
static int LuaUnixDirFd(lua_State *L) {
|
2022-05-11 09:50:03 +00:00
|
|
|
int fd, olderr = errno;
|
2022-04-13 15:49:17 +00:00
|
|
|
fd = dirfd(GetDirOrDie(L));
|
|
|
|
if (fd != -1) {
|
|
|
|
lua_pushinteger(L, fd);
|
|
|
|
return 1;
|
|
|
|
} else {
|
2022-07-20 22:13:39 +00:00
|
|
|
return LuaUnixSysretErrno(L, "dirfd", olderr);
|
2022-04-13 15:49:17 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// unix.Dir:tell()
|
|
|
|
// ├─→ off:int
|
|
|
|
// └─→ nil, unix.Errno
|
2022-04-13 15:49:17 +00:00
|
|
|
static int LuaUnixDirTell(lua_State *L) {
|
2022-04-26 04:16:05 +00:00
|
|
|
int olderr = errno;
|
|
|
|
return SysretInteger(L, "telldir", olderr, telldir(GetDirOrDie(L)));
|
2022-04-13 15:49:17 +00:00
|
|
|
}
|
|
|
|
|
2022-04-25 15:30:14 +00:00
|
|
|
// unix.Dir:rewind()
|
2022-04-13 15:49:17 +00:00
|
|
|
static int LuaUnixDirRewind(lua_State *L) {
|
|
|
|
rewinddir(GetDirOrDie(L));
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2022-04-28 03:18:34 +00:00
|
|
|
static int ReturnDir(lua_State *L, DIR *dir) {
|
|
|
|
DIR **dirp;
|
|
|
|
dirp = lua_newuserdatauv(L, sizeof(*dirp), 1);
|
2022-04-26 04:16:05 +00:00
|
|
|
luaL_setmetatable(L, "unix.Dir");
|
2022-04-28 03:18:34 +00:00
|
|
|
*dirp = dir;
|
2022-04-26 04:16:05 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// unix.opendir(path:str)
|
|
|
|
// ├─→ state:unix.Dir
|
|
|
|
// └─→ nil, unix.Errno
|
|
|
|
static int LuaUnixOpendir(lua_State *L) {
|
2022-04-28 03:18:34 +00:00
|
|
|
DIR *dir;
|
2022-04-26 04:16:05 +00:00
|
|
|
int olderr = errno;
|
2022-04-28 03:18:34 +00:00
|
|
|
if ((dir = opendir(luaL_checkstring(L, 1)))) {
|
|
|
|
return ReturnDir(L, dir);
|
|
|
|
} else {
|
2022-07-20 22:13:39 +00:00
|
|
|
return LuaUnixSysretErrno(L, "opendir", olderr);
|
2022-04-26 04:16:05 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// unix.fdopendir(fd:int)
|
|
|
|
// ├─→ next:function, state:unix.Dir
|
|
|
|
// └─→ nil, unix.Errno
|
|
|
|
static int LuaUnixFdopendir(lua_State *L) {
|
2022-04-28 03:18:34 +00:00
|
|
|
DIR *dir;
|
|
|
|
int olderr = errno;
|
|
|
|
if ((dir = fdopendir(luaL_checkinteger(L, 1)))) {
|
|
|
|
return ReturnDir(L, dir);
|
|
|
|
} else {
|
2022-07-20 22:13:39 +00:00
|
|
|
return LuaUnixSysretErrno(L, "fdopendir", olderr);
|
2022-04-26 04:16:05 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-13 15:49:17 +00:00
|
|
|
static const luaL_Reg kLuaUnixDirMeth[] = {
|
|
|
|
{"close", LuaUnixDirClose}, //
|
|
|
|
{"read", LuaUnixDirRead}, //
|
|
|
|
{"fd", LuaUnixDirFd}, //
|
|
|
|
{"tell", LuaUnixDirTell}, //
|
|
|
|
{"rewind", LuaUnixDirRewind}, //
|
|
|
|
{0}, //
|
|
|
|
};
|
|
|
|
|
|
|
|
static const luaL_Reg kLuaUnixDirMeta[] = {
|
2022-04-26 04:16:05 +00:00
|
|
|
{"__call", LuaUnixDirRead}, //
|
|
|
|
{"__gc", LuaUnixDirClose}, //
|
|
|
|
{0}, //
|
2022-04-13 15:49:17 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static void LuaUnixDirObj(lua_State *L) {
|
2022-04-25 15:30:14 +00:00
|
|
|
luaL_newmetatable(L, "unix.Dir");
|
2022-04-13 15:49:17 +00:00
|
|
|
luaL_setfuncs(L, kLuaUnixDirMeta, 0);
|
|
|
|
luaL_newlibtable(L, kLuaUnixDirMeth);
|
|
|
|
luaL_setfuncs(L, kLuaUnixDirMeth, 0);
|
|
|
|
lua_setfield(L, -2, "__index");
|
|
|
|
lua_pop(L, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// UNIX module
|
|
|
|
|
|
|
|
static const luaL_Reg kLuaUnix[] = {
|
2022-06-23 11:05:51 +00:00
|
|
|
{"S_ISBLK", LuaUnixSisblk}, // is st:mode() a block device?
|
|
|
|
{"S_ISCHR", LuaUnixSischr}, // is st:mode() a character device?
|
|
|
|
{"S_ISDIR", LuaUnixSisdir}, // is st:mode() a directory?
|
|
|
|
{"S_ISFIFO", LuaUnixSisfifo}, // is st:mode() a fifo?
|
|
|
|
{"S_ISLNK", LuaUnixSislnk}, // is st:mode() a symbolic link?
|
|
|
|
{"S_ISREG", LuaUnixSisreg}, // is st:mode() a regular file?
|
|
|
|
{"S_ISSOCK", LuaUnixSissock}, // is st:mode() a socket?
|
2022-04-26 04:16:05 +00:00
|
|
|
{"Sigset", LuaUnixSigset}, // creates signal bitmask
|
2022-06-18 08:10:29 +00:00
|
|
|
{"WEXITSTATUS", LuaUnixWexitstatus}, // gets exit status from wait status
|
|
|
|
{"WIFEXITED", LuaUnixWifexited}, // gets exit code from wait status
|
|
|
|
{"WIFSIGNALED", LuaUnixWifsignaled}, // determines if died due to signal
|
|
|
|
{"WTERMSIG", LuaUnixWtermsig}, // gets the signal code
|
|
|
|
{"accept", LuaUnixAccept}, // create client fd for client
|
2022-04-13 15:49:17 +00:00
|
|
|
{"access", LuaUnixAccess}, // check my file authorization
|
2022-06-18 08:10:29 +00:00
|
|
|
{"bind", LuaUnixBind}, // reserve network interface address
|
2022-04-13 15:49:17 +00:00
|
|
|
{"chdir", LuaUnixChdir}, // change directory
|
|
|
|
{"chmod", LuaUnixChmod}, // change mode of file
|
2022-06-18 08:10:29 +00:00
|
|
|
{"chown", LuaUnixChown}, // change owner of file
|
|
|
|
{"chroot", LuaUnixChroot}, // change root directory
|
|
|
|
{"clock_gettime", LuaUnixGettime}, // get timestamp w/ nano precision
|
|
|
|
{"close", LuaUnixClose}, // close file or socket
|
2022-04-13 21:43:42 +00:00
|
|
|
{"commandv", LuaUnixCommandv}, // resolve program on $PATH
|
2022-06-18 08:10:29 +00:00
|
|
|
{"connect", LuaUnixConnect}, // connect to remote address
|
2022-04-13 15:49:17 +00:00
|
|
|
{"dup", LuaUnixDup}, // copy fd to lowest empty slot
|
2022-06-18 08:10:29 +00:00
|
|
|
{"environ", LuaUnixEnviron}, // get environment variables
|
|
|
|
{"execve", LuaUnixExecve}, // replace process with program
|
|
|
|
{"exit", LuaUnixExit}, // exit w/o atexit
|
|
|
|
{"fcntl", LuaUnixFcntl}, // manipulate file descriptor
|
|
|
|
{"fdatasync", LuaUnixFdatasync}, // flush open file w/o metadata
|
2022-04-24 16:59:22 +00:00
|
|
|
{"fdopendir", LuaUnixFdopendir}, // read directory entry list
|
2022-06-18 08:10:29 +00:00
|
|
|
{"fork", LuaUnixFork}, // make child process via mitosis
|
|
|
|
{"fstat", LuaUnixFstat}, // get file info from fd
|
2022-08-18 06:27:17 +00:00
|
|
|
{"fstatfs", LuaUnixFstatfs}, // get filesystem info from fd
|
2022-04-13 15:49:17 +00:00
|
|
|
{"fsync", LuaUnixFsync}, // flush open file
|
2022-04-24 16:59:22 +00:00
|
|
|
{"ftruncate", LuaUnixFtruncate}, // shrink or extend file medium
|
2022-06-18 08:10:29 +00:00
|
|
|
{"futimens", LuaUnixFutimens}, // change access/modified time
|
|
|
|
{"getcwd", LuaUnixGetcwd}, // get current directory
|
|
|
|
{"getegid", LuaUnixGetegid}, // get effective group id of process
|
|
|
|
{"geteuid", LuaUnixGeteuid}, // get effective user id of process
|
|
|
|
{"getgid", LuaUnixGetgid}, // get real group id of process
|
|
|
|
{"gethostname", LuaUnixGethostname}, // get hostname of this machine
|
|
|
|
{"getpeername", LuaUnixGetpeername}, // get address of remote end
|
|
|
|
{"getpgid", LuaUnixGetpgid}, // get process group id of pid
|
|
|
|
{"getpgrp", LuaUnixGetpgrp}, // get process group id
|
|
|
|
{"getpid", LuaUnixGetpid}, // get id of this process
|
|
|
|
{"getppid", LuaUnixGetppid}, // get parent process id
|
2022-04-18 07:01:26 +00:00
|
|
|
{"getrlimit", LuaUnixGetrlimit}, // query resource limits
|
2022-04-28 16:42:36 +00:00
|
|
|
{"getrusage", LuaUnixGetrusage}, // query resource usages
|
2022-04-13 15:49:17 +00:00
|
|
|
{"getsid", LuaUnixGetsid}, // get session id of pid
|
2022-06-18 08:10:29 +00:00
|
|
|
{"getsockname", LuaUnixGetsockname}, // get address of local end
|
|
|
|
{"getsockopt", LuaUnixGetsockopt}, // get socket tunings
|
2022-04-13 15:49:17 +00:00
|
|
|
{"getuid", LuaUnixGetuid}, // get real user id of process
|
2022-06-18 08:10:29 +00:00
|
|
|
{"gmtime", LuaUnixGmtime}, // destructure unix timestamp
|
2022-06-27 20:01:58 +00:00
|
|
|
{"isatty", LuaUnixIsatty}, // detects pseudoteletypewriters
|
2022-06-18 08:10:29 +00:00
|
|
|
{"kill", LuaUnixKill}, // signal child process
|
|
|
|
{"link", LuaUnixLink}, // create hard link
|
|
|
|
{"listen", LuaUnixListen}, // begin listening for clients
|
|
|
|
{"localtime", LuaUnixLocaltime}, // localize unix timestamp
|
|
|
|
{"lseek", LuaUnixLseek}, // seek in file
|
|
|
|
{"major", LuaUnixMajor}, // extract device info
|
|
|
|
{"makedirs", LuaUnixMakedirs}, // make directory and parents too
|
2022-10-06 11:55:26 +00:00
|
|
|
{"mapshared", LuaUnixMapshared}, // mmap(MAP_SHARED) w/ mutex+atomics
|
2022-06-18 08:10:29 +00:00
|
|
|
{"minor", LuaUnixMinor}, // extract device info
|
|
|
|
{"mkdir", LuaUnixMkdir}, // make directory
|
2022-04-13 15:49:17 +00:00
|
|
|
{"nanosleep", LuaUnixNanosleep}, // sleep w/ nano precision
|
2022-06-18 08:10:29 +00:00
|
|
|
{"open", LuaUnixOpen}, // open file fd at lowest slot
|
|
|
|
{"opendir", LuaUnixOpendir}, // read directory entry list
|
|
|
|
{"pipe", LuaUnixPipe}, // create two anon fifo fds
|
|
|
|
{"pledge", LuaUnixPledge}, // enables syscall sandbox
|
2022-04-21 20:44:59 +00:00
|
|
|
{"poll", LuaUnixPoll}, // waits for file descriptor events
|
2022-06-18 08:10:29 +00:00
|
|
|
{"raise", LuaUnixRaise}, // signal this process
|
|
|
|
{"read", LuaUnixRead}, // read from file or socket
|
|
|
|
{"readlink", LuaUnixReadlink}, // reads symbolic link
|
|
|
|
{"realpath", LuaUnixRealpath}, // abspath without dots/symlinks
|
2022-04-15 06:39:48 +00:00
|
|
|
{"recv", LuaUnixRecv}, // receive tcp from some address
|
2022-04-13 15:49:17 +00:00
|
|
|
{"recvfrom", LuaUnixRecvfrom}, // receive udp from some address
|
2022-06-18 08:10:29 +00:00
|
|
|
{"rename", LuaUnixRename}, // rename file or directory
|
|
|
|
{"rmdir", LuaUnixRmdir}, // remove empty directory
|
2022-07-09 06:06:46 +00:00
|
|
|
{"rmrf", LuaUnixRmrf}, // remove file recursively
|
2022-10-06 11:55:26 +00:00
|
|
|
{"sched_yield", LuaUnixSchedYield}, // relinquish scheduled quantum
|
2022-04-15 06:39:48 +00:00
|
|
|
{"send", LuaUnixSend}, // send tcp to some address
|
2022-04-13 15:49:17 +00:00
|
|
|
{"sendto", LuaUnixSendto}, // send udp to some address
|
2022-07-16 01:07:34 +00:00
|
|
|
{"setfsgid", LuaUnixSetfsgid}, // set/get group id for fs ops
|
|
|
|
{"setfsuid", LuaUnixSetfsuid}, // set/get user id for fs ops
|
|
|
|
{"setgid", LuaUnixSetgid}, // set real group id of process
|
|
|
|
{"setitimer", LuaUnixSetitimer}, // set alarm clock
|
|
|
|
{"setpgid", LuaUnixSetpgid}, // set process group id for pid
|
|
|
|
{"setpgrp", LuaUnixSetpgrp}, // sets process group id
|
|
|
|
{"setresgid", LuaUnixSetresgid}, // sets real/effective/saved gids
|
|
|
|
{"setresuid", LuaUnixSetresuid}, // sets real/effective/saved uids
|
|
|
|
{"setrlimit", LuaUnixSetrlimit}, // prevent cpu memory bombs
|
|
|
|
{"setsid", LuaUnixSetsid}, // create a new session id
|
|
|
|
{"setsockopt", LuaUnixSetsockopt}, // tune socket options
|
|
|
|
{"setuid", LuaUnixSetuid}, // set real user id of process
|
|
|
|
{"shutdown", LuaUnixShutdown}, // make socket half empty or full
|
|
|
|
{"sigaction", LuaUnixSigaction}, // install signal handler
|
2022-09-09 11:20:13 +00:00
|
|
|
{"sigpending", LuaUnixSigpending}, // get pending signals
|
2022-10-06 11:55:26 +00:00
|
|
|
{"sigprocmask", LuaUnixSigprocmask}, // change signal mask
|
2022-04-13 21:43:42 +00:00
|
|
|
{"sigsuspend", LuaUnixSigsuspend}, // wait for signal
|
2022-06-18 08:10:29 +00:00
|
|
|
{"siocgifconf", LuaUnixSiocgifconf}, // get list of network interfaces
|
|
|
|
{"socket", LuaUnixSocket}, // create network communication fd
|
|
|
|
{"socketpair", LuaUnixSocketpair}, // create bidirectional pipe
|
|
|
|
{"stat", LuaUnixStat}, // get file info from path
|
2022-08-18 06:27:17 +00:00
|
|
|
{"statfs", LuaUnixStatfs}, // get filesystem info from path
|
2022-04-13 21:43:42 +00:00
|
|
|
{"strsignal", LuaUnixStrsignal}, // turn signal into string
|
2022-06-18 08:10:29 +00:00
|
|
|
{"symlink", LuaUnixSymlink}, // create symbolic link
|
|
|
|
{"sync", LuaUnixSync}, // flushes files and disks
|
|
|
|
{"syslog", LuaUnixSyslog}, // logs to system log
|
2022-07-09 06:06:46 +00:00
|
|
|
{"tiocgwinsz", LuaUnixTiocgwinsz}, // pseudoteletypewriter dimensions
|
2022-08-14 20:28:07 +00:00
|
|
|
{"tmpfd", LuaUnixTmpfd}, // create anonymous file
|
2022-06-18 08:10:29 +00:00
|
|
|
{"truncate", LuaUnixTruncate}, // shrink or extend file medium
|
|
|
|
{"umask", LuaUnixUmask}, // set default file mask
|
|
|
|
{"unlink", LuaUnixUnlink}, // remove file
|
2022-07-18 14:23:15 +00:00
|
|
|
{"unveil", LuaUnixUnveil}, // filesystem sandboxing
|
2022-06-18 08:10:29 +00:00
|
|
|
{"utimensat", LuaUnixUtimensat}, // change access/modified time
|
2023-07-06 22:38:08 +00:00
|
|
|
{"verynice", LuaUnixVerynice}, // lowest priority
|
2022-06-18 08:10:29 +00:00
|
|
|
{"wait", LuaUnixWait}, // wait for child to change status
|
|
|
|
{"write", LuaUnixWrite}, // write to file or socket
|
2022-04-13 15:49:17 +00:00
|
|
|
{0}, //
|
|
|
|
};
|
|
|
|
|
2022-04-24 16:59:22 +00:00
|
|
|
static void LoadMagnums(lua_State *L, struct MagnumStr *ms, const char *pfx) {
|
2022-04-13 15:49:17 +00:00
|
|
|
int i;
|
2022-04-24 16:59:22 +00:00
|
|
|
char b[64], *p;
|
|
|
|
p = stpcpy(b, pfx);
|
2022-04-25 15:30:14 +00:00
|
|
|
for (i = 0; ms[i].x != MAGNUM_TERMINATOR; ++i) {
|
|
|
|
stpcpy(p, MAGNUM_STRING(ms, i));
|
|
|
|
LuaSetIntField(L, b, MAGNUM_NUMBER(ms, i));
|
2022-04-24 16:59:22 +00:00
|
|
|
}
|
|
|
|
}
|
2022-04-13 15:49:17 +00:00
|
|
|
|
2022-04-24 16:59:22 +00:00
|
|
|
int LuaUnix(lua_State *L) {
|
2022-04-13 21:43:42 +00:00
|
|
|
GL = L;
|
2022-04-13 15:49:17 +00:00
|
|
|
luaL_newlib(L, kLuaUnix);
|
2022-04-26 04:16:05 +00:00
|
|
|
LuaUnixSigsetObj(L);
|
2022-04-28 16:42:36 +00:00
|
|
|
LuaUnixRusageObj(L);
|
2022-08-18 06:27:17 +00:00
|
|
|
LuaUnixStatfsObj(L);
|
2022-10-06 11:55:26 +00:00
|
|
|
LuaUnixMemoryObj(L);
|
2022-04-26 04:16:05 +00:00
|
|
|
LuaUnixErrnoObj(L);
|
2022-04-13 15:49:17 +00:00
|
|
|
LuaUnixStatObj(L);
|
|
|
|
LuaUnixDirObj(L);
|
2022-04-13 21:43:42 +00:00
|
|
|
lua_newtable(L);
|
|
|
|
lua_setglobal(L, "__signal_handlers");
|
2022-04-13 15:49:17 +00:00
|
|
|
|
2022-04-24 16:59:22 +00:00
|
|
|
LoadMagnums(L, kErrnoNames, "");
|
2022-06-26 01:17:31 +00:00
|
|
|
LoadMagnums(L, kSignalNames, "");
|
2022-04-25 15:30:14 +00:00
|
|
|
LoadMagnums(L, kIpOptnames, "IP_");
|
|
|
|
LoadMagnums(L, kTcpOptnames, "TCP_");
|
|
|
|
LoadMagnums(L, kSockOptnames, "SO_");
|
|
|
|
LoadMagnums(L, kClockNames, "CLOCK_");
|
2022-04-13 15:49:17 +00:00
|
|
|
|
2023-06-15 00:02:57 +00:00
|
|
|
// open()
|
|
|
|
LuaSetIntField(L, "O_RDONLY", O_RDONLY);
|
|
|
|
LuaSetIntField(L, "O_WRONLY", O_WRONLY);
|
|
|
|
LuaSetIntField(L, "O_RDWR", O_RDWR);
|
|
|
|
LuaSetIntField(L, "O_ACCMODE", O_ACCMODE);
|
|
|
|
LoadMagnums(L, kOpenFlags, "O_");
|
|
|
|
|
2022-04-13 15:49:17 +00:00
|
|
|
// seek() whence
|
|
|
|
LuaSetIntField(L, "SEEK_SET", SEEK_SET);
|
|
|
|
LuaSetIntField(L, "SEEK_CUR", SEEK_CUR);
|
|
|
|
LuaSetIntField(L, "SEEK_END", SEEK_END);
|
|
|
|
|
|
|
|
// fcntl() stuff
|
|
|
|
LuaSetIntField(L, "F_GETFD", F_GETFD);
|
|
|
|
LuaSetIntField(L, "F_SETFD", F_SETFD);
|
|
|
|
LuaSetIntField(L, "F_GETFL", F_GETFL);
|
|
|
|
LuaSetIntField(L, "F_SETFL", F_SETFL);
|
|
|
|
LuaSetIntField(L, "F_UNLCK", F_UNLCK);
|
|
|
|
LuaSetIntField(L, "F_RDLCK", F_RDLCK);
|
|
|
|
LuaSetIntField(L, "F_WRLCK", F_WRLCK);
|
|
|
|
LuaSetIntField(L, "F_SETLK", F_SETLK);
|
|
|
|
LuaSetIntField(L, "F_SETLKW", F_SETLKW);
|
2022-08-17 06:23:34 +00:00
|
|
|
LuaSetIntField(L, "F_GETLK", F_GETLK);
|
2022-04-13 15:49:17 +00:00
|
|
|
LuaSetIntField(L, "FD_CLOEXEC", FD_CLOEXEC);
|
|
|
|
|
|
|
|
// access() mode
|
|
|
|
LuaSetIntField(L, "R_OK", R_OK);
|
|
|
|
LuaSetIntField(L, "W_OK", W_OK);
|
|
|
|
LuaSetIntField(L, "X_OK", X_OK);
|
|
|
|
LuaSetIntField(L, "F_OK", F_OK);
|
|
|
|
|
2022-04-18 07:01:26 +00:00
|
|
|
// rlimit() resources
|
|
|
|
LuaSetIntField(L, "RLIMIT_AS", RLIMIT_AS);
|
2022-04-20 16:56:53 +00:00
|
|
|
LuaSetIntField(L, "RLIMIT_RSS", RLIMIT_RSS);
|
2022-04-18 07:01:26 +00:00
|
|
|
LuaSetIntField(L, "RLIMIT_CPU", RLIMIT_CPU);
|
|
|
|
LuaSetIntField(L, "RLIMIT_FSIZE", RLIMIT_FSIZE);
|
|
|
|
LuaSetIntField(L, "RLIMIT_NPROC", RLIMIT_NPROC);
|
|
|
|
LuaSetIntField(L, "RLIMIT_NOFILE", RLIMIT_NOFILE);
|
|
|
|
|
2022-04-13 15:49:17 +00:00
|
|
|
// wait() options
|
|
|
|
LuaSetIntField(L, "WNOHANG", WNOHANG);
|
|
|
|
|
|
|
|
// socket() family
|
|
|
|
LuaSetIntField(L, "AF_UNSPEC", AF_UNSPEC);
|
|
|
|
LuaSetIntField(L, "AF_UNIX", AF_UNIX);
|
|
|
|
LuaSetIntField(L, "AF_INET", AF_INET);
|
|
|
|
|
|
|
|
// socket() type
|
|
|
|
LuaSetIntField(L, "SOCK_STREAM", SOCK_STREAM);
|
|
|
|
LuaSetIntField(L, "SOCK_DGRAM", SOCK_DGRAM);
|
2022-04-24 16:59:22 +00:00
|
|
|
LuaSetIntField(L, "SOCK_RAW", SOCK_RAW);
|
|
|
|
LuaSetIntField(L, "SOCK_RDM", SOCK_RDM);
|
|
|
|
LuaSetIntField(L, "SOCK_SEQPACKET", SOCK_SEQPACKET);
|
2022-04-13 15:49:17 +00:00
|
|
|
LuaSetIntField(L, "SOCK_CLOEXEC", SOCK_CLOEXEC);
|
2022-05-11 09:50:03 +00:00
|
|
|
LuaSetIntField(L, "SOCK_NONBLOCK", SOCK_NONBLOCK);
|
2022-04-13 15:49:17 +00:00
|
|
|
|
|
|
|
// socket() protocol
|
2022-04-24 16:59:22 +00:00
|
|
|
LuaSetIntField(L, "IPPROTO_IP", IPPROTO_IP);
|
|
|
|
LuaSetIntField(L, "IPPROTO_ICMP", IPPROTO_ICMP);
|
2022-04-13 15:49:17 +00:00
|
|
|
LuaSetIntField(L, "IPPROTO_TCP", IPPROTO_TCP);
|
|
|
|
LuaSetIntField(L, "IPPROTO_UDP", IPPROTO_UDP);
|
2022-04-24 16:59:22 +00:00
|
|
|
LuaSetIntField(L, "IPPROTO_RAW", IPPROTO_RAW);
|
2022-04-13 15:49:17 +00:00
|
|
|
|
|
|
|
// shutdown() how
|
|
|
|
LuaSetIntField(L, "SHUT_RD", SHUT_RD);
|
|
|
|
LuaSetIntField(L, "SHUT_WR", SHUT_WR);
|
|
|
|
LuaSetIntField(L, "SHUT_RDWR", SHUT_RDWR);
|
|
|
|
|
|
|
|
// recvfrom() / sendto() flags
|
|
|
|
LuaSetIntField(L, "MSG_WAITALL", MSG_WAITALL);
|
|
|
|
LuaSetIntField(L, "MSG_DONTROUTE", MSG_DONTROUTE);
|
|
|
|
LuaSetIntField(L, "MSG_PEEK", MSG_PEEK);
|
|
|
|
LuaSetIntField(L, "MSG_OOB", MSG_OOB);
|
|
|
|
LuaSetIntField(L, "MSG_NOSIGNAL", MSG_NOSIGNAL);
|
2022-06-27 20:01:58 +00:00
|
|
|
LuaSetIntField(L, "MSG_MORE", MSG_MORE);
|
2022-04-13 15:49:17 +00:00
|
|
|
|
|
|
|
// readdir() type
|
|
|
|
LuaSetIntField(L, "DT_UNKNOWN", DT_UNKNOWN);
|
|
|
|
LuaSetIntField(L, "DT_REG", DT_REG);
|
|
|
|
LuaSetIntField(L, "DT_DIR", DT_DIR);
|
|
|
|
LuaSetIntField(L, "DT_BLK", DT_BLK);
|
|
|
|
LuaSetIntField(L, "DT_LNK", DT_LNK);
|
|
|
|
LuaSetIntField(L, "DT_CHR", DT_CHR);
|
|
|
|
LuaSetIntField(L, "DT_FIFO", DT_FIFO);
|
|
|
|
LuaSetIntField(L, "DT_SOCK", DT_SOCK);
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// poll() flags
|
2022-04-22 02:13:19 +00:00
|
|
|
LuaSetIntField(L, "POLLIN", POLLIN);
|
|
|
|
LuaSetIntField(L, "POLLPRI", POLLPRI);
|
|
|
|
LuaSetIntField(L, "POLLOUT", POLLOUT);
|
|
|
|
LuaSetIntField(L, "POLLERR", POLLERR);
|
|
|
|
LuaSetIntField(L, "POLLHUP", POLLHUP);
|
|
|
|
LuaSetIntField(L, "POLLNVAL", POLLNVAL);
|
|
|
|
LuaSetIntField(L, "POLLRDBAND", POLLRDBAND);
|
|
|
|
LuaSetIntField(L, "POLLRDNORM", POLLRDNORM);
|
|
|
|
LuaSetIntField(L, "POLLWRBAND", POLLWRBAND);
|
|
|
|
LuaSetIntField(L, "POLLWRNORM", POLLWRNORM);
|
|
|
|
LuaSetIntField(L, "POLLRDHUP", POLLRDHUP);
|
|
|
|
|
2022-04-13 15:49:17 +00:00
|
|
|
// i/o options
|
|
|
|
LuaSetIntField(L, "AT_FDCWD", AT_FDCWD);
|
2022-04-26 04:16:05 +00:00
|
|
|
LuaSetIntField(L, "AT_EACCESS", AT_EACCESS);
|
2022-04-13 15:49:17 +00:00
|
|
|
LuaSetIntField(L, "AT_SYMLINK_NOFOLLOW", AT_SYMLINK_NOFOLLOW);
|
|
|
|
|
|
|
|
// sigprocmask() handlers
|
|
|
|
LuaSetIntField(L, "SIG_BLOCK", SIG_BLOCK);
|
|
|
|
LuaSetIntField(L, "SIG_UNBLOCK", SIG_UNBLOCK);
|
|
|
|
LuaSetIntField(L, "SIG_SETMASK", SIG_SETMASK);
|
|
|
|
|
|
|
|
// sigaction() handlers
|
|
|
|
LuaSetIntField(L, "SIG_DFL", (intptr_t)SIG_DFL);
|
|
|
|
LuaSetIntField(L, "SIG_IGN", (intptr_t)SIG_IGN);
|
|
|
|
|
2022-06-18 08:10:29 +00:00
|
|
|
// utimensat() magnums
|
|
|
|
LuaSetIntField(L, "UTIME_NOW", UTIME_NOW);
|
|
|
|
LuaSetIntField(L, "UTIME_OMIT", UTIME_OMIT);
|
|
|
|
|
2022-04-13 21:43:42 +00:00
|
|
|
// setitimer() which
|
|
|
|
LuaSetIntField(L, "ITIMER_REAL", ITIMER_REAL); // portable
|
|
|
|
LuaSetIntField(L, "ITIMER_PROF", ITIMER_PROF);
|
|
|
|
LuaSetIntField(L, "ITIMER_VIRTUAL", ITIMER_VIRTUAL);
|
|
|
|
|
2022-04-18 15:54:42 +00:00
|
|
|
// syslog() stuff
|
|
|
|
LuaSetIntField(L, "LOG_EMERG", LOG_EMERG);
|
|
|
|
LuaSetIntField(L, "LOG_ALERT", LOG_ALERT);
|
|
|
|
LuaSetIntField(L, "LOG_CRIT", LOG_CRIT);
|
|
|
|
LuaSetIntField(L, "LOG_ERR", LOG_ERR);
|
|
|
|
LuaSetIntField(L, "LOG_WARNING", LOG_WARNING);
|
|
|
|
LuaSetIntField(L, "LOG_NOTICE", LOG_NOTICE);
|
|
|
|
LuaSetIntField(L, "LOG_INFO", LOG_INFO);
|
|
|
|
LuaSetIntField(L, "LOG_DEBUG", LOG_DEBUG);
|
|
|
|
|
2022-04-24 16:59:22 +00:00
|
|
|
// setsockopt() level
|
|
|
|
LuaSetIntField(L, "SOL_IP", SOL_IP);
|
|
|
|
LuaSetIntField(L, "SOL_SOCKET", SOL_SOCKET);
|
|
|
|
LuaSetIntField(L, "SOL_TCP", SOL_TCP);
|
|
|
|
LuaSetIntField(L, "SOL_UDP", SOL_UDP);
|
|
|
|
|
2022-04-26 04:16:05 +00:00
|
|
|
// sigaction() flags
|
|
|
|
LuaSetIntField(L, "SA_RESTART", SA_RESTART);
|
|
|
|
LuaSetIntField(L, "SA_RESETHAND", SA_RESETHAND);
|
|
|
|
LuaSetIntField(L, "SA_NODEFER", SA_NODEFER);
|
|
|
|
LuaSetIntField(L, "SA_NOCLDWAIT", SA_NOCLDWAIT);
|
|
|
|
LuaSetIntField(L, "SA_NOCLDSTOP", SA_NOCLDSTOP);
|
|
|
|
|
2022-04-28 16:42:36 +00:00
|
|
|
// getrusage() who
|
|
|
|
LuaSetIntField(L, "RUSAGE_SELF", RUSAGE_SELF);
|
|
|
|
LuaSetIntField(L, "RUSAGE_THREAD", RUSAGE_THREAD);
|
|
|
|
LuaSetIntField(L, "RUSAGE_CHILDREN", RUSAGE_CHILDREN);
|
|
|
|
LuaSetIntField(L, "RUSAGE_BOTH", RUSAGE_BOTH);
|
|
|
|
|
|
|
|
LuaSetIntField(L, "ARG_MAX", __arg_max());
|
2022-04-26 04:16:05 +00:00
|
|
|
LuaSetIntField(L, "BUFSIZ", BUFSIZ);
|
|
|
|
LuaSetIntField(L, "CLK_TCK", CLK_TCK);
|
2022-04-28 16:42:36 +00:00
|
|
|
LuaSetIntField(L, "NAME_MAX", _NAME_MAX);
|
|
|
|
LuaSetIntField(L, "NSIG", _NSIG);
|
|
|
|
LuaSetIntField(L, "PATH_MAX", _PATH_MAX);
|
2022-04-26 04:16:05 +00:00
|
|
|
LuaSetIntField(L, "PIPE_BUF", PIPE_BUF);
|
|
|
|
|
2022-08-11 18:27:25 +00:00
|
|
|
// pledge() flags
|
|
|
|
LuaSetIntField(L, "PLEDGE_PENALTY_KILL_THREAD", PLEDGE_PENALTY_KILL_THREAD);
|
|
|
|
LuaSetIntField(L, "PLEDGE_PENALTY_KILL_PROCESS", PLEDGE_PENALTY_KILL_PROCESS);
|
|
|
|
LuaSetIntField(L, "PLEDGE_PENALTY_RETURN_EPERM", PLEDGE_PENALTY_RETURN_EPERM);
|
|
|
|
LuaSetIntField(L, "PLEDGE_STDERR_LOGGING", PLEDGE_STDERR_LOGGING);
|
|
|
|
|
2022-08-18 06:27:17 +00:00
|
|
|
// statfs::f_flags
|
|
|
|
LuaSetIntField(L, "ST_RDONLY", ST_RDONLY);
|
|
|
|
LuaSetIntField(L, "ST_NOSUID", ST_NOSUID);
|
|
|
|
LuaSetIntField(L, "ST_NODEV", ST_NODEV);
|
|
|
|
LuaSetIntField(L, "ST_NOEXEC", ST_NOEXEC);
|
|
|
|
LuaSetIntField(L, "ST_SYNCHRONOUS", ST_SYNCHRONOUS);
|
|
|
|
LuaSetIntField(L, "ST_NOATIME", ST_NOATIME);
|
|
|
|
LuaSetIntField(L, "ST_RELATIME", ST_RELATIME);
|
|
|
|
LuaSetIntField(L, "ST_APPEND", ST_APPEND);
|
|
|
|
LuaSetIntField(L, "ST_IMMUTABLE", ST_IMMUTABLE);
|
|
|
|
LuaSetIntField(L, "ST_MANDLOCK", ST_MANDLOCK);
|
|
|
|
LuaSetIntField(L, "ST_NODIRATIME", ST_NODIRATIME);
|
|
|
|
LuaSetIntField(L, "ST_WRITE", ST_WRITE);
|
|
|
|
|
2022-04-13 15:49:17 +00:00
|
|
|
return 1;
|
|
|
|
}
|