From b11a5709ec2b61fefb03bfdd38e2f06d2c1107c1 Mon Sep 17 00:00:00 2001 From: Kyle Evans Date: Fri, 3 Oct 2025 21:16:51 -0500 Subject: flua: kick out the remaining builtin modules Bootstrap flua has some magic now to handle modules by building them in and discovering them via linker sets. This is slightly cleaner than always building them in and baking them into loadedlibs for both bootstrap and system flua. Adjust the stand build now that these three libs have their own new homes. Reviewed by: bapt, emaste Differential Revision: https://reviews.freebsd.org/D51891 --- libexec/flua/modules/lfbsd.c | 285 ----------------- libexec/flua/modules/lfbsd.h | 32 -- libexec/flua/modules/lfs.c | 448 --------------------------- libexec/flua/modules/lfs.h | 31 -- libexec/flua/modules/lposix.c | 699 ------------------------------------------ libexec/flua/modules/lposix.h | 10 - 6 files changed, 1505 deletions(-) delete mode 100644 libexec/flua/modules/lfbsd.c delete mode 100644 libexec/flua/modules/lfbsd.h delete mode 100644 libexec/flua/modules/lfs.c delete mode 100644 libexec/flua/modules/lfs.h delete mode 100644 libexec/flua/modules/lposix.c delete mode 100644 libexec/flua/modules/lposix.h (limited to 'libexec/flua/modules') 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 - * Copyright (C) 2025 Kyle Evans - * - * 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 - -#include -#include -#include -#include -#include -#include -#include - -#include -#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 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 - * - * 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 - -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 - * 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 -#ifndef _STANDALONE -#include -#include -#include -#include -#include -#include -#endif - -#include -#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 - * 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 - -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 - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#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 - -int luaopen_posix(lua_State *L); -- cgit v1.3