diff options
| author | Kyle Evans <kevans@FreeBSD.org> | 2025-10-04 02:16:51 +0000 |
|---|---|---|
| committer | Kyle Evans <kevans@FreeBSD.org> | 2025-10-04 02:16:51 +0000 |
| commit | b11a5709ec2b61fefb03bfdd38e2f06d2c1107c1 (patch) | |
| tree | ca8f517b63619ad4752fa914eaeca8e2d3fce946 /libexec/flua/modules | |
| parent | 151bd3516b541823b16793460d73916e63d2b9c1 (diff) | |
Diffstat (limited to 'libexec/flua/modules')
| -rw-r--r-- | libexec/flua/modules/lfbsd.c | 285 | ||||
| -rw-r--r-- | libexec/flua/modules/lfbsd.h | 32 | ||||
| -rw-r--r-- | libexec/flua/modules/lfs.c | 448 | ||||
| -rw-r--r-- | libexec/flua/modules/lfs.h | 31 | ||||
| -rw-r--r-- | libexec/flua/modules/lposix.c | 699 | ||||
| -rw-r--r-- | libexec/flua/modules/lposix.h | 10 |
6 files changed, 0 insertions, 1505 deletions
diff --git a/libexec/flua/modules/lfbsd.c b/libexec/flua/modules/lfbsd.c deleted file mode 100644 index ef660ba9fd77..000000000000 --- a/libexec/flua/modules/lfbsd.c +++ /dev/null @@ -1,285 +0,0 @@ -/* - * SPDX-License-Identifier: BSD-2-Clause - * - * Copyright 2023 Baptiste Daroussin <bapt@FreeBSD.org> - * Copyright (C) 2025 Kyle Evans <kevans@FreeBSD.org> - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted providing that the following conditions~ - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include <sys/wait.h> - -#include <errno.h> -#include <fcntl.h> -#include <spawn.h> -#include <stdbool.h> -#include <string.h> -#include <stdio.h> -#include <unistd.h> - -#include <lua.h> -#include "lauxlib.h" -#include "lfbsd.h" - -#define FBSD_PROCESSHANDLE "fbsd_process_t*" - -struct fbsd_process { - int pid; - int stdin_fileno; - int stdout_fileno; -}; - -extern char **environ; - -static const char** -luaL_checkarraystrings(lua_State *L, int arg) -{ - const char **ret; - lua_Integer n, i; - int t; - int abs_arg = lua_absindex(L, arg); - luaL_checktype(L, abs_arg, LUA_TTABLE); - n = lua_rawlen(L, abs_arg); - ret = lua_newuserdata(L, (n+1)*sizeof(char*)); - for (i=0; i<n; i++) { - t = lua_rawgeti(L, abs_arg, i+1); - if (t == LUA_TNIL) - break; - luaL_argcheck(L, t == LUA_TSTRING, arg, "expected array of strings"); - ret[i] = lua_tostring(L, -1); - lua_pop(L, 1); - } - ret[i] = NULL; - return ret; -} - -static void -close_pipes(int pipes[2]) -{ - - if (pipes[0] != -1) - close(pipes[0]); - if (pipes[1] != -1) - close(pipes[1]); -} - -static int -lua_exec(lua_State *L) -{ - struct fbsd_process *proc; - int r; - posix_spawn_file_actions_t action; - int stdin_pipe[2] = {-1, -1}; - int stdout_pipe[2] = {-1, -1}; - pid_t pid; - const char **argv; - int n = lua_gettop(L); - bool capture_stdout; - luaL_argcheck(L, n > 0 && n <= 2, n >= 2 ? 2 : n, - "fbsd.exec takes exactly one or two arguments"); - - capture_stdout = lua_toboolean(L, 2); - if (pipe(stdin_pipe) < 0) { - lua_pushnil(L); - lua_pushstring(L, strerror(errno)); - lua_pushinteger(L, errno); - return (3); - } - if (capture_stdout && pipe(stdout_pipe) < 0) { - close_pipes(stdin_pipe); - lua_pushnil(L); - lua_pushstring(L, strerror(errno)); - lua_pushinteger(L, errno); - return (3); - } - - proc = lua_newuserdata(L, sizeof(*proc)); - proc->stdin_fileno = stdin_pipe[1]; - proc->stdout_fileno = stdout_pipe[1]; - posix_spawn_file_actions_init(&action); - posix_spawn_file_actions_adddup2(&action, stdin_pipe[0], STDIN_FILENO); - posix_spawn_file_actions_addclose(&action, stdin_pipe[1]); - if (stdin_pipe[0] != STDIN_FILENO) - posix_spawn_file_actions_addclose(&action, stdin_pipe[0]); - - /* - * Setup stdout to be captured if requested. Otherwise, we just let it - * go to our own stdout. - */ - if (stdout_pipe[0] != -1) { - posix_spawn_file_actions_adddup2(&action, stdout_pipe[0], - STDOUT_FILENO); - posix_spawn_file_actions_addclose(&action, stdout_pipe[1]); - if (stdout_pipe[0] != STDOUT_FILENO) { - posix_spawn_file_actions_addclose(&action, - stdout_pipe[0]); - } - } - - argv = luaL_checkarraystrings(L, 1); - if (0 != (r = posix_spawnp(&pid, argv[0], &action, NULL, - (char*const*)argv, environ))) { - close_pipes(stdin_pipe); - close_pipes(stdout_pipe); - posix_spawn_file_actions_destroy(&action); - lua_pop(L, 2); /* Pop off the process handle and args. */ - - lua_pushnil(L); - lua_pushstring(L, strerror(r)); - lua_pushinteger(L, r); - return (3); - } - - lua_pop(L, 1); - - close(stdin_pipe[0]); - if (stdout_pipe[0] != -1) - close(stdout_pipe[0]); - posix_spawn_file_actions_destroy(&action); - - proc->pid = pid; - luaL_setmetatable(L, FBSD_PROCESSHANDLE); - - return (1); -} - -static int -lua_process_close(lua_State *L) -{ - struct fbsd_process *proc; - int pstat, r; - - proc = luaL_checkudata(L, 1, FBSD_PROCESSHANDLE); - while (waitpid(proc->pid, &pstat, 0) == -1) { - if ((r = errno) != EINTR) { - lua_pushnil(L); - lua_pushstring(L, strerror(r)); - lua_pushinteger(L, r); - return (3); - } - } - - if (!WIFEXITED(pstat) || WEXITSTATUS(pstat) != 0) { - lua_pushnil(L); - lua_pushstring(L, "Abnormal termination"); - return (2); - } - - if (proc->stdin_fileno >= 0) { - close(proc->stdin_fileno); - proc->stdin_fileno = -1; - } - - if (proc->stdout_fileno >= 0) { - close(proc->stdout_fileno); - proc->stdout_fileno = -1; - } - - lua_pushboolean(L, 1); - return (1); -} - -static int -lua_process_makestdio(lua_State *L, int fd, const char *mode) -{ - luaL_Stream *p; - FILE *fp; - int r; - - if (fd == -1) { - lua_pushnil(L); - lua_pushstring(L, "Stream not captured"); - return (2); - } - - fp = fdopen(fd, mode); - if (fp == NULL) { - r = errno; - - lua_pushnil(L); - lua_pushstring(L, strerror(r)); - lua_pushinteger(L, r); - return (3); - } - - p = lua_newuserdata(L, sizeof(*p)); - p->closef = &lua_process_close; - p->f = fp; - luaL_setmetatable(L, LUA_FILEHANDLE); - return (1); -} - -static int -lua_process_stdin(lua_State *L) -{ - struct fbsd_process *proc; - - proc = luaL_checkudata(L, 1, FBSD_PROCESSHANDLE); - return (lua_process_makestdio(L, proc->stdin_fileno, "w")); -} - -static int -lua_process_stdout(lua_State *L) -{ - struct fbsd_process *proc; - - proc = luaL_checkudata(L, 1, FBSD_PROCESSHANDLE); - return (lua_process_makestdio(L, proc->stdout_fileno, "r")); -} - -#define PROCESS_SIMPLE(n) { #n, lua_process_ ## n } -static const struct luaL_Reg fbsd_process[] = { - PROCESS_SIMPLE(close), - PROCESS_SIMPLE(stdin), - PROCESS_SIMPLE(stdout), - { NULL, NULL }, -}; - -static const struct luaL_Reg fbsd_process_meta[] = { - { "__index", NULL }, - { "__gc", lua_process_close }, - { "__close", lua_process_close }, - { NULL, NULL }, -}; - -#define REG_SIMPLE(n) { #n, lua_ ## n } -static const struct luaL_Reg fbsd_lib[] = { - REG_SIMPLE(exec), - { NULL, NULL }, -}; -#undef REG_SIMPLE - -int -luaopen_fbsd(lua_State *L) -{ - luaL_newlib(L, fbsd_lib); - - luaL_newmetatable(L, FBSD_PROCESSHANDLE); - luaL_setfuncs(L, fbsd_process_meta, 0); - - luaL_newlibtable(L, fbsd_process); - luaL_setfuncs(L, fbsd_process, 0); - lua_setfield(L, -2, "__index"); - lua_pop(L, 1); - - return (1); -} diff --git a/libexec/flua/modules/lfbsd.h b/libexec/flua/modules/lfbsd.h deleted file mode 100644 index 01034a3ad7cd..000000000000 --- a/libexec/flua/modules/lfbsd.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * SPDX-License-Identifier: BSD-2-Clause - * - * Copyright 2023 Baptiste Daroussin <bapt@FreeBSD.org> - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted providing that the following conditions~ - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#pragma once - -#include <lua.h> - -int luaopen_fbsd(lua_State *L); diff --git a/libexec/flua/modules/lfs.c b/libexec/flua/modules/lfs.c deleted file mode 100644 index 8cb8d6fc9fed..000000000000 --- a/libexec/flua/modules/lfs.c +++ /dev/null @@ -1,448 +0,0 @@ -/*- - * Copyright (c) 2018 Conrad Meyer <cem@FreeBSD.org> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * Portions derived from https://github.com/keplerproject/luafilesystem under - * the terms of the MIT license: - * - * Copyright (c) 2003-2014 Kepler Project. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include <sys/cdefs.h> -#ifndef _STANDALONE -#include <sys/stat.h> -#include <dirent.h> -#include <errno.h> -#include <unistd.h> -#include <stdio.h> -#include <string.h> -#endif - -#include <lua.h> -#include "lauxlib.h" -#include "lfs.h" - -#ifdef _STANDALONE -#include "lstd.h" -#include "lutils.h" -#include "bootstrap.h" -#endif - -#ifndef nitems -#define nitems(x) (sizeof((x)) / sizeof((x)[0])) -#endif - -/* - * The goal is to emulate a subset of the upstream Lua FileSystem library, as - * faithfully as possible in the boot environment. Only APIs that seem useful - * need to emulated. - * - * Example usage: - * - * for file in lfs.dir("/boot") do - * print("\t"..file) - * end - * - * Prints: - * . - * .. - * (etc.) - * - * The other available API is lfs.attributes(), which functions somewhat like - * stat(2) and returns a table of values. Example code: - * - * attrs, errormsg, errorcode = lfs.attributes("/boot") - * if attrs == nil then - * print(errormsg) - * return errorcode - * end - * - * for k, v in pairs(attrs) do - * print(k .. ":\t" .. v) - * end - * return 0 - * - * Prints (on success): - * gid: 0 - * change: 140737488342640 - * mode: directory - * rdev: 0 - * ino: 4199275 - * dev: 140737488342544 - * modification: 140737488342576 - * size: 512 - * access: 140737488342560 - * permissions: 755 - * nlink: 58283552 - * uid: 1001 - */ - -#define DIR_METATABLE "directory iterator metatable" - -static int -lua_dir_iter_pushtype(lua_State *L __unused, const struct dirent *ent __unused) -{ - - /* - * This is a non-standard extension to luafilesystem for loader's - * benefit. The extra stat() calls to determine the entry type can - * be quite expensive on some systems, so this speeds up enumeration of - * /boot greatly by providing the type up front. - * - * This extension is compatible enough with luafilesystem, in that we're - * just using an extra return value for the iterator. - */ -#ifdef _STANDALONE - lua_pushinteger(L, ent->d_type); - return 1; -#else - return 0; -#endif -} - -static int -lua_dir_iter_next(lua_State *L) -{ - struct dirent *entry; - DIR *dp, **dpp; - - dpp = (DIR **)luaL_checkudata(L, 1, DIR_METATABLE); - dp = *dpp; - luaL_argcheck(L, dp != NULL, 1, "closed directory"); - -#ifdef _STANDALONE - entry = readdirfd(dp->fd); -#else - entry = readdir(dp); -#endif - if (entry == NULL) { - closedir(dp); - *dpp = NULL; - return 0; - } - - lua_pushstring(L, entry->d_name); - return 1 + lua_dir_iter_pushtype(L, entry); -} - -static int -lua_dir_iter_close(lua_State *L) -{ - DIR *dp, **dpp; - - dpp = (DIR **)lua_touserdata(L, 1); - dp = *dpp; - if (dp == NULL) - return 0; - - closedir(dp); - *dpp = NULL; - return 0; -} - -static int -lua_dir(lua_State *L) -{ - const char *path; - DIR *dp; - - if (lua_gettop(L) != 1) { - lua_pushnil(L); - return 1; - } - - path = luaL_checkstring(L, 1); - dp = opendir(path); - if (dp == NULL) { - lua_pushnil(L); - return 1; - } - - lua_pushcfunction(L, lua_dir_iter_next); - *(DIR **)lua_newuserdata(L, sizeof(DIR **)) = dp; - luaL_getmetatable(L, DIR_METATABLE); - lua_setmetatable(L, -2); - return 2; -} - -static void -register_metatable(lua_State *L) -{ - /* - * Create so-called metatable for iterator object returned by - * lfs.dir(). - */ - luaL_newmetatable(L, DIR_METATABLE); - - lua_newtable(L); - lua_pushcfunction(L, lua_dir_iter_next); - lua_setfield(L, -2, "next"); - lua_pushcfunction(L, lua_dir_iter_close); - lua_setfield(L, -2, "close"); - - /* Magically associate anonymous method table with metatable. */ - lua_setfield(L, -2, "__index"); - /* Implement magic destructor method */ - lua_pushcfunction(L, lua_dir_iter_close); - lua_setfield(L, -2, "__gc"); - - lua_pop(L, 1); -} - -#define PUSH_INTEGER(lname, stname) \ -static void \ -push_st_ ## lname (lua_State *L, struct stat *sb) \ -{ \ - lua_pushinteger(L, (lua_Integer)sb->st_ ## stname); \ -} -PUSH_INTEGER(dev, dev) -PUSH_INTEGER(ino, ino) -PUSH_INTEGER(nlink, nlink) -PUSH_INTEGER(uid, uid) -PUSH_INTEGER(gid, gid) -PUSH_INTEGER(rdev, rdev) -PUSH_INTEGER(access, atime) -PUSH_INTEGER(modification, mtime) -PUSH_INTEGER(change, ctime) -PUSH_INTEGER(size, size) -#undef PUSH_INTEGER - -static void -push_st_mode(lua_State *L, struct stat *sb) -{ - const char *mode_s; - mode_t mode; - - mode = (sb->st_mode & S_IFMT); - if (S_ISREG(mode)) - mode_s = "file"; - else if (S_ISDIR(mode)) - mode_s = "directory"; - else if (S_ISLNK(mode)) - mode_s = "link"; - else if (S_ISSOCK(mode)) - mode_s = "socket"; - else if (S_ISFIFO(mode)) - mode_s = "fifo"; - else if (S_ISCHR(mode)) - mode_s = "char device"; - else if (S_ISBLK(mode)) - mode_s = "block device"; - else - mode_s = "other"; - - lua_pushstring(L, mode_s); -} - -static void -push_st_permissions(lua_State *L, struct stat *sb) -{ - char buf[20]; - - /* - * XXX - * Could actually format as "-rwxrwxrwx" -- do we care? - */ - snprintf(buf, sizeof(buf), "%o", sb->st_mode & ~S_IFMT); - lua_pushstring(L, buf); -} - -#define PUSH_ENTRY(n) { #n, push_st_ ## n } -struct stat_members { - const char *name; - void (*push)(lua_State *, struct stat *); -} members[] = { - PUSH_ENTRY(mode), - PUSH_ENTRY(dev), - PUSH_ENTRY(ino), - PUSH_ENTRY(nlink), - PUSH_ENTRY(uid), - PUSH_ENTRY(gid), - PUSH_ENTRY(rdev), - PUSH_ENTRY(access), - PUSH_ENTRY(modification), - PUSH_ENTRY(change), - PUSH_ENTRY(size), - PUSH_ENTRY(permissions), -}; -#undef PUSH_ENTRY - -static int -lua_attributes(lua_State *L) -{ - struct stat sb; - const char *path, *member; - size_t i; - int rc; - - path = luaL_checkstring(L, 1); - if (path == NULL) { - lua_pushnil(L); - lua_pushfstring(L, "cannot convert first argument to string"); - lua_pushinteger(L, EINVAL); - return 3; - } - - rc = stat(path, &sb); - if (rc != 0) { - lua_pushnil(L); - lua_pushfstring(L, - "cannot obtain information from file '%s': %s", path, - strerror(errno)); - lua_pushinteger(L, errno); - return 3; - } - - if (lua_isstring(L, 2)) { - member = lua_tostring(L, 2); - for (i = 0; i < nitems(members); i++) { - if (strcmp(members[i].name, member) != 0) - continue; - - members[i].push(L, &sb); - return 1; - } - return luaL_error(L, "invalid attribute name '%s'", member); - } - - /* Create or reuse existing table */ - lua_settop(L, 2); - if (!lua_istable(L, 2)) - lua_newtable(L); - - /* Export all stat data to caller */ - for (i = 0; i < nitems(members); i++) { - lua_pushstring(L, members[i].name); - members[i].push(L, &sb); - lua_rawset(L, -3); - } - return 1; -} - -#ifndef _STANDALONE -#define lfs_mkdir_impl(path) (mkdir((path), \ - S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | \ - S_IROTH | S_IXOTH)) - -static int -lua_mkdir(lua_State *L) -{ - const char *path; - int error, serrno; - - path = luaL_checkstring(L, 1); - if (path == NULL) { - lua_pushnil(L); - lua_pushfstring(L, "cannot convert first argument to string"); - lua_pushinteger(L, EINVAL); - return 3; - } - - error = lfs_mkdir_impl(path); - if (error == -1) { - /* Save it; unclear what other libc functions may be invoked */ - serrno = errno; - lua_pushnil(L); - lua_pushfstring(L, strerror(serrno)); - lua_pushinteger(L, serrno); - return 3; - } - - lua_pushboolean(L, 1); - return 1; -} - -static int -lua_rmdir(lua_State *L) -{ - const char *path; - int error, serrno; - - path = luaL_checkstring(L, 1); - if (path == NULL) { - lua_pushnil(L); - lua_pushfstring(L, "cannot convert first argument to string"); - lua_pushinteger(L, EINVAL); - return 3; - } - - error = rmdir(path); - if (error == -1) { - /* Save it; unclear what other libc functions may be invoked */ - serrno = errno; - lua_pushnil(L); - lua_pushfstring(L, strerror(serrno)); - lua_pushinteger(L, serrno); - return 3; - } - - lua_pushboolean(L, 1); - return 1; -} -#endif - -#define REG_SIMPLE(n) { #n, lua_ ## n } -static const struct luaL_Reg fslib[] = { - REG_SIMPLE(attributes), - REG_SIMPLE(dir), -#ifndef _STANDALONE - REG_SIMPLE(mkdir), - REG_SIMPLE(rmdir), -#endif - { NULL, NULL }, -}; -#undef REG_SIMPLE - -int -luaopen_lfs(lua_State *L) -{ - register_metatable(L); - luaL_newlib(L, fslib); -#ifdef _STANDALONE - /* Non-standard extension for loader, used with lfs.dir(). */ - lua_pushinteger(L, DT_DIR); - lua_setfield(L, -2, "DT_DIR"); -#endif - return 1; -} diff --git a/libexec/flua/modules/lfs.h b/libexec/flua/modules/lfs.h deleted file mode 100644 index a99e66d7f601..000000000000 --- a/libexec/flua/modules/lfs.h +++ /dev/null @@ -1,31 +0,0 @@ -/*- - * Copyright (c) 2018 Conrad Meyer <cem@FreeBSD.org> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#pragma once - -#include <lua.h> - -int luaopen_lfs(lua_State *L); diff --git a/libexec/flua/modules/lposix.c b/libexec/flua/modules/lposix.c deleted file mode 100644 index 75cdd345aeaa..000000000000 --- a/libexec/flua/modules/lposix.c +++ /dev/null @@ -1,699 +0,0 @@ -/*- - * Copyright (c) 2019, 2023 Kyle Evans <kevans@FreeBSD.org> - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#include <sys/stat.h> -#include <sys/utsname.h> -#include <sys/wait.h> - -#include <errno.h> -#include <fnmatch.h> -#include <grp.h> -#include <libgen.h> -#include <pwd.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include <lua.h> -#include "lauxlib.h" -#include "lposix.h" - -static void -enforce_max_args(lua_State *L, int max) -{ - int narg; - - narg = lua_gettop(L); - luaL_argcheck(L, narg <= max, max + 1, "too many arguments"); -} - -/* - * Minimal implementation of luaposix needed for internal FreeBSD bits. - */ -static int -lua__exit(lua_State *L) -{ - int code; - - enforce_max_args(L, 1); - code = luaL_checkinteger(L, 1); - - _exit(code); -} - -static int -lua_basename(lua_State *L) -{ - char *inpath, *outpath; - - enforce_max_args(L, 1); - inpath = strdup(luaL_checkstring(L, 1)); - if (inpath == NULL) { - lua_pushnil(L); - lua_pushstring(L, strerror(ENOMEM)); - lua_pushinteger(L, ENOMEM); - return (3); - } - - outpath = basename(inpath); - lua_pushstring(L, outpath); - free(inpath); - return (1); -} - -static int -lua_chmod(lua_State *L) -{ - const char *path; - mode_t mode; - - enforce_max_args(L, 2); - path = luaL_checkstring(L, 1); - mode = (mode_t)luaL_checkinteger(L, 2); - - if (chmod(path, mode) == -1) { - lua_pushnil(L); - lua_pushstring(L, strerror(errno)); - lua_pushinteger(L, errno); - return (3); - } - lua_pushinteger(L, 0); - return (1); -} - -static int -lua_chown(lua_State *L) -{ - const char *path; - uid_t owner = (uid_t)-1; - gid_t group = (gid_t)-1; - int error; - - enforce_max_args(L, 3); - - path = luaL_checkstring(L, 1); - if (lua_isinteger(L, 2)) - owner = (uid_t)lua_tointeger(L, 2); - else if (lua_isstring(L, 2)) { - char buf[4096]; - struct passwd passwd, *pwd; - - error = getpwnam_r(lua_tostring(L, 2), &passwd, - buf, sizeof(buf), &pwd); - if (error == 0) - owner = pwd->pw_uid; - else - return (luaL_argerror(L, 2, - lua_pushfstring(L, "unknown user %s", - lua_tostring(L, 2)))); - } else if (!lua_isnoneornil(L, 2)) { - const char *type = luaL_typename(L, 2); - return (luaL_argerror(L, 2, - lua_pushfstring(L, "integer or string expected, got %s", - type))); - } - - if (lua_isinteger(L, 3)) - group = (gid_t)lua_tointeger(L, 3); - else if (lua_isstring(L, 3)) { - char buf[4096]; - struct group gr, *grp; - - error = getgrnam_r(lua_tostring(L, 3), &gr, buf, sizeof(buf), - &grp); - if (error == 0) - group = grp->gr_gid; - else - return (luaL_argerror(L, 3, - lua_pushfstring(L, "unknown group %s", - lua_tostring(L, 3)))); - } else if (!lua_isnoneornil(L, 3)) { - const char *type = luaL_typename(L, 3); - return (luaL_argerror(L, 3, - lua_pushfstring(L, "integer or string expected, got %s", - type))); - } - - if (chown(path, owner, group) == -1) { - lua_pushnil(L); - lua_pushstring(L, strerror(errno)); - lua_pushinteger(L, errno); - return (3); - } - lua_pushinteger(L, 0); - return (1); -} - -static int -lua_pclose(lua_State *L) -{ - int error, fd; - - enforce_max_args(L, 1); - - fd = luaL_checkinteger(L, 1); - if (fd < 0) { - error = EBADF; - goto err; - } - - if (close(fd) == 0) { - lua_pushinteger(L, 0); - return (1); - } - - error = errno; -err: - lua_pushnil(L); - lua_pushstring(L, strerror(error)); - lua_pushinteger(L, error); - return (3); - -} - -static int -lua_dup2(lua_State *L) -{ - int error, oldd, newd; - - enforce_max_args(L, 2); - - oldd = luaL_checkinteger(L, 1); - if (oldd < 0) { - error = EBADF; - goto err; - } - - newd = luaL_checkinteger(L, 2); - if (newd < 0) { - error = EBADF; - goto err; - } - - error = dup2(oldd, newd); - if (error >= 0) { - lua_pushinteger(L, error); - return (1); - } - - error = errno; -err: - lua_pushnil(L); - lua_pushstring(L, strerror(error)); - lua_pushinteger(L, error); - return (3); -} - -static int -lua_execp(lua_State *L) -{ - int argc, error; - const char *file; - const char **argv; - - enforce_max_args(L, 2); - - file = luaL_checkstring(L, 1); - luaL_checktype(L, 2, LUA_TTABLE); - - lua_len(L, 2); - argc = lua_tointeger(L, -1); - - /* - * Use lua_newuserdatauv() to allocate a scratch buffer that is tracked - * and freed by lua's GC. This avoid any chance of a leak if a lua error - * is raised later in this function (e.g. by luaL_argerror()). - * The (argc + 2) size gives enough space in the buffer for argv[0] and - * the terminating NULL. - */ - argv = lua_newuserdatauv(L, (argc + 2) * sizeof(char *), 0); - - /* - * Sequential tables in lua start at index 1 by convention. - * If there happens to be a string at index 0, use that to - * override the default argv[0]. This matches the lposix API. - */ - lua_pushinteger(L, 0); - lua_gettable(L, 2); - argv[0] = lua_tostring(L, -1); - if (argv[0] == NULL) { - argv[0] = file; - } - - for (int i = 1; i <= argc; i++) { - lua_pushinteger(L, i); - lua_gettable(L, 2); - argv[i] = lua_tostring(L, -1); - if (argv[i] == NULL) { - luaL_argerror(L, 2, - "argv table must contain only strings"); - } - } - argv[argc + 1] = NULL; - - execvp(file, (char **)argv); - error = errno; - - lua_pushnil(L); - lua_pushstring(L, strerror(error)); - lua_pushinteger(L, error); - return (3); -} - -static int -lua_fnmatch(lua_State *L) -{ - const char *pattern, *string; - int flags; - - enforce_max_args(L, 3); - pattern = luaL_checkstring(L, 1); - string = luaL_checkstring(L, 2); - flags = luaL_optinteger(L, 3, 0); - - lua_pushinteger(L, fnmatch(pattern, string, flags)); - - return (1); -} - -static int -lua_uname(lua_State *L) -{ - struct utsname name; - int error; - - enforce_max_args(L, 0); - - error = uname(&name); - if (error != 0) { - error = errno; - lua_pushnil(L); - lua_pushstring(L, strerror(error)); - lua_pushinteger(L, error); - return (3); - } - - lua_newtable(L); -#define setkv(f) do { \ - lua_pushstring(L, name.f); \ - lua_setfield(L, -2, #f); \ -} while (0) - setkv(sysname); - setkv(nodename); - setkv(release); - setkv(version); - setkv(machine); -#undef setkv - - return (1); -} - -static int -lua_dirname(lua_State *L) -{ - char *inpath, *outpath; - - enforce_max_args(L, 1); - - inpath = strdup(luaL_checkstring(L, 1)); - if (inpath == NULL) { - lua_pushnil(L); - lua_pushstring(L, strerror(ENOMEM)); - lua_pushinteger(L, ENOMEM); - return (3); - } - - outpath = dirname(inpath); - lua_pushstring(L, outpath); - free(inpath); - return (1); -} - -static int -lua_fork(lua_State *L) -{ - pid_t pid; - - enforce_max_args(L, 0); - - pid = fork(); - if (pid < 0) { - lua_pushnil(L); - lua_pushstring(L, strerror(errno)); - lua_pushinteger(L, errno); - return (3); - } - - lua_pushinteger(L, pid); - return (1); -} - -static int -lua_getpid(lua_State *L) -{ - enforce_max_args(L, 0); - - lua_pushinteger(L, getpid()); - return (1); -} - -static int -lua_pipe(lua_State *L) -{ - int error, fd[2]; - - enforce_max_args(L, 0); - - error = pipe(fd); - if (error != 0) { - lua_pushnil(L); - lua_pushstring(L, strerror(errno)); - lua_pushinteger(L, errno); - return (1); - } - - lua_pushinteger(L, fd[0]); - lua_pushinteger(L, fd[1]); - return (2); -} - -static int -lua_read(lua_State *L) -{ - char *buf; - ssize_t ret; - size_t sz; - int error, fd; - - enforce_max_args(L, 2); - fd = luaL_checkinteger(L, 1); - sz = luaL_checkinteger(L, 2); - - if (fd < 0) { - error = EBADF; - goto err; - } - - buf = malloc(sz); - if (buf == NULL) - goto err; - - /* - * For 0-byte reads, we'll still push the empty string and let the - * caller deal with EOF to match lposix semantics. - */ - ret = read(fd, buf, sz); - if (ret >= 0) - lua_pushlstring(L, buf, ret); - else if (ret < 0) - error = errno; /* Save to avoid clobber by free() */ - - free(buf); - if (error != 0) - goto err; - - /* Just the string pushed. */ - return (1); -err: - lua_pushnil(L); - lua_pushstring(L, strerror(error)); - lua_pushinteger(L, error); - return (3); -} - -static int -lua_realpath(lua_State *L) -{ - const char *inpath; - char *outpath; - - enforce_max_args(L, 1); - inpath = luaL_checkstring(L, 1); - - outpath = realpath(inpath, NULL); - if (outpath == NULL) { - lua_pushnil(L); - lua_pushstring(L, strerror(errno)); - lua_pushinteger(L, errno); - return (3); - } - - lua_pushstring(L, outpath); - free(outpath); - return (1); -} - -static int -lua_wait(lua_State *L) -{ - pid_t pid; - int options, status; - - enforce_max_args(L, 2); - pid = luaL_optinteger(L, 1, -1); - options = luaL_optinteger(L, 2, 0); - - status = 0; - pid = waitpid(pid, &status, options); - if (pid < 0) { - lua_pushnil(L); - lua_pushstring(L, strerror(errno)); - lua_pushinteger(L, errno); - return (3); - } - - lua_pushinteger(L, pid); - if (pid == 0) { - lua_pushliteral(L, "running"); - return (2); - } - - if (WIFCONTINUED(status)) { - lua_pushliteral(L, "continued"); - return (2); - } else if(WIFSTOPPED(status)) { - lua_pushliteral(L, "stopped"); - lua_pushinteger(L, WSTOPSIG(status)); - return (3); - } else if (WIFEXITED(status)) { - lua_pushliteral(L, "exited"); - lua_pushinteger(L, WEXITSTATUS(status)); - return (3); - } else if (WIFSIGNALED(status)) { - lua_pushliteral(L, "killed"); - lua_pushinteger(L, WTERMSIG(status)); - return (3); - } - - return (1); -} - -static int -lua_write(lua_State *L) -{ - const char *buf; - size_t bufsz, sz; - ssize_t ret; - off_t offset; - int error, fd; - - enforce_max_args(L, 4); - - fd = luaL_checkinteger(L, 1); - if (fd < 0) { - error = EBADF; - goto err; - } - - buf = luaL_checkstring(L, 2); - - bufsz = lua_rawlen(L, 2); - sz = luaL_optinteger(L, 3, bufsz); - - offset = luaL_optinteger(L, 4, 0); - - - if ((size_t)offset > bufsz || offset + sz > bufsz) { - lua_pushnil(L); - lua_pushfstring(L, - "write: invalid access offset %zu, size %zu in a buffer size %zu", - offset, sz, bufsz); - lua_pushinteger(L, EINVAL); - return (3); - } - - ret = write(fd, buf + offset, sz); - if (ret < 0) { - error = errno; - goto err; - } - - lua_pushinteger(L, ret); - return (1); -err: - lua_pushnil(L); - lua_pushstring(L, strerror(error)); - lua_pushinteger(L, error); - return (3); -} - -#define REG_DEF(n, func) { #n, func } -#define REG_SIMPLE(n) REG_DEF(n, lua_ ## n) -static const struct luaL_Reg libgenlib[] = { - REG_SIMPLE(basename), - REG_SIMPLE(dirname), - { NULL, NULL }, -}; - -static const struct luaL_Reg stdliblib[] = { - REG_SIMPLE(realpath), - { NULL, NULL }, -}; - -static const struct luaL_Reg fnmatchlib[] = { - REG_SIMPLE(fnmatch), - { NULL, NULL }, -}; - -static const struct luaL_Reg sys_statlib[] = { - REG_SIMPLE(chmod), - { NULL, NULL }, -}; - -static const struct luaL_Reg sys_utsnamelib[] = { - REG_SIMPLE(uname), - { NULL, NULL }, -}; - -static const struct luaL_Reg sys_waitlib[] = { - REG_SIMPLE(wait), - {NULL, NULL}, -}; - -static const struct luaL_Reg unistdlib[] = { - REG_SIMPLE(_exit), - REG_SIMPLE(chown), - REG_DEF(close, lua_pclose), - REG_SIMPLE(dup2), - REG_SIMPLE(execp), - REG_SIMPLE(fork), - REG_SIMPLE(getpid), - REG_SIMPLE(pipe), - REG_SIMPLE(read), - REG_SIMPLE(write), - { NULL, NULL }, -}; - -#undef REG_SIMPLE -#undef REG_DEF - -static int -luaopen_posix_libgen(lua_State *L) -{ - luaL_newlib(L, libgenlib); - return (1); -} - -static int -luaopen_posix_stdlib(lua_State *L) -{ - luaL_newlib(L, stdliblib); - return (1); -} - -static int -luaopen_posix_fnmatch(lua_State *L) -{ - luaL_newlib(L, fnmatchlib); - -#define setkv(f) do { \ - lua_pushinteger(L, f); \ - lua_setfield(L, -2, #f); \ -} while (0) - setkv(FNM_PATHNAME); - setkv(FNM_NOESCAPE); - setkv(FNM_NOMATCH); - setkv(FNM_PERIOD); -#undef setkv - - return 1; -} - -static int -luaopen_posix_sys_stat(lua_State *L) -{ - luaL_newlib(L, sys_statlib); - return (1); -} - -static int -luaopen_posix_sys_utsname(lua_State *L) -{ - luaL_newlib(L, sys_utsnamelib); - return 1; -} - -static int -luaopen_posix_sys_wait(lua_State *L) -{ - luaL_newlib(L, sys_waitlib); - -#define lua_pushflag(L, flag) do { \ - lua_pushinteger(L, flag); \ - lua_setfield(L, -2, #flag); \ -} while(0) - - /* Only these two exported by lposix */ - lua_pushflag(L, WNOHANG); - lua_pushflag(L, WUNTRACED); - - lua_pushflag(L, WCONTINUED); - lua_pushflag(L, WSTOPPED); -#ifdef WTRAPPED - lua_pushflag(L, WTRAPPED); -#endif - lua_pushflag(L, WEXITED); - lua_pushflag(L, WNOWAIT); -#undef lua_pushflag - - return (1); -} - -static int -luaopen_posix_unistd(lua_State *L) -{ - luaL_newlib(L, unistdlib); - return (1); -} - -int -luaopen_posix(lua_State *L) -{ - lua_newtable(L); /* posix */ - - luaL_requiref(L, "posix.fnmatch", luaopen_posix_fnmatch, 0); - lua_setfield(L, -2, "fnmatch"); - - luaL_requiref(L, "posix.libgen", luaopen_posix_libgen, 0); - lua_setfield(L, -2, "libgen"); - - luaL_requiref(L, "posix.stdlib", luaopen_posix_stdlib, 0); - lua_setfield(L, -2, "stdlib"); - - lua_newtable(L); /* posix.sys */ - luaL_requiref(L, "posix.sys.stat", luaopen_posix_sys_stat, 0); - lua_setfield(L, -2, "stat"); - luaL_requiref(L, "posix.sys.utsname", luaopen_posix_sys_utsname, 0); - lua_setfield(L, -2, "utsname"); - luaL_requiref(L, "posix.sys.wait", luaopen_posix_sys_wait, 0); - lua_setfield(L, -2, "wait"); - lua_setfield(L, -2, "sys"); - - luaL_requiref(L, "posix.unistd", luaopen_posix_unistd, 0); - lua_setfield(L, -2, "unistd"); - - return (1); -} diff --git a/libexec/flua/modules/lposix.h b/libexec/flua/modules/lposix.h deleted file mode 100644 index 1aa33f042571..000000000000 --- a/libexec/flua/modules/lposix.h +++ /dev/null @@ -1,10 +0,0 @@ -/*- - * - * This file is in the public domain. - */ - -#pragma once - -#include <lua.h> - -int luaopen_posix(lua_State *L); |
