diff --git a/libexec/flua/Makefile b/libexec/flua/Makefile index 6d05d9d72a52..7a58b2265a5a 100644 --- a/libexec/flua/Makefile +++ b/libexec/flua/Makefile @@ -1,41 +1,41 @@ .include LUASRC?= ${SRCTOP}/contrib/lua/src .PATH: ${LUASRC} PROG= flua WARNS?= 2 MAN= # No manpage; this is internal. CWARNFLAGS.gcc+= -Wno-format-nonliteral LIBADD= lua # Entry point SRCS+= lua.c # FreeBSD Extensions .PATH: ${.CURDIR}/modules SRCS+= linit_flua.c -SRCS+= lfs.c lposix.c +SRCS+= lfs.c lposix.c lfbsd.c CFLAGS+= -I${SRCTOP}/lib/liblua -I${.CURDIR}/modules -I${LUASRC} CFLAGS+= -DLUA_PROGNAME="\"${PROG}\"" # readline bits; these aren't needed if we're building a bootstrap flua, as we # don't expect that one to see any REPL usage. .if !defined(BOOTSTRAPPING) CFLAGS+= -DLUA_USE_READLINE CFLAGS+= -I${SRCTOP}/lib/libedit -I${SRCTOP}/contrib/libedit LIBADD+= edit LDFLAGS+= -Wl,-E .endif UCLSRC?= ${SRCTOP}/contrib/libucl .PATH: ${UCLSRC}/lua SRCS+= lua_ucl.c CFLAGS+= -I${UCLSRC}/include -I${UCLSRC}/src -I${UCLSRC}/uthash LIBADD+= ucl .include diff --git a/libexec/flua/linit_flua.c b/libexec/flua/linit_flua.c index 671a0300783c..4d4d69920e94 100644 --- a/libexec/flua/linit_flua.c +++ b/libexec/flua/linit_flua.c @@ -1,75 +1,77 @@ /* ** $Id: linit.c,v 1.39.1.1 2017/04/19 17:20:42 roberto Exp $ ** Initialization of libraries for lua.c and other clients ** See Copyright Notice in lua.h */ #define linit_c #define LUA_LIB /* ** If you embed Lua in your program and need to open the standard ** libraries, call luaL_openlibs in your program. If you need a ** different set of libraries, copy this file to your project and edit ** it to suit your needs. ** ** You can also *preload* libraries, so that a later 'require' can ** open the library, which is already linked to the application. ** For that, do the following code: ** ** luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE); ** lua_pushcfunction(L, luaopen_modname); ** lua_setfield(L, -2, modname); ** lua_pop(L, 1); // remove PRELOAD table */ #include "lprefix.h" #include #include "lua.h" #include "lualib.h" #include "lauxlib.h" #include "lfs.h" #include "lposix.h" +#include "lfbsd.h" #include "lua_ucl.h" /* ** these libs are loaded by lua.c and are readily available to any Lua ** program */ static const luaL_Reg loadedlibs[] = { {"_G", luaopen_base}, {LUA_LOADLIBNAME, luaopen_package}, {LUA_COLIBNAME, luaopen_coroutine}, {LUA_TABLIBNAME, luaopen_table}, {LUA_IOLIBNAME, luaopen_io}, {LUA_OSLIBNAME, luaopen_os}, {LUA_STRLIBNAME, luaopen_string}, {LUA_MATHLIBNAME, luaopen_math}, {LUA_UTF8LIBNAME, luaopen_utf8}, {LUA_DBLIBNAME, luaopen_debug}, #if defined(LUA_COMPAT_BITLIB) {LUA_BITLIBNAME, luaopen_bit32}, #endif /* FreeBSD Extensions */ {"lfs", luaopen_lfs}, {"posix.sys.stat", luaopen_posix_sys_stat}, {"posix.unistd", luaopen_posix_unistd}, {"ucl", luaopen_ucl}, + {"fbsd", luaopen_fbsd}, {NULL, NULL} }; LUALIB_API void luaL_openlibs (lua_State *L) { const luaL_Reg *lib; /* "require" functions from 'loadedlibs' and set results to global table */ for (lib = loadedlibs; lib->func; lib++) { luaL_requiref(L, lib->name, lib->func, 1); lua_pop(L, 1); /* remove lib */ } } diff --git a/libexec/flua/modules/lfbsd.c b/libexec/flua/modules/lfbsd.c new file mode 100644 index 000000000000..30cafcc7309e --- /dev/null +++ b/libexec/flua/modules/lfbsd.c @@ -0,0 +1,134 @@ +/* + * 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. + */ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include "lauxlib.h" +#include "lfbsd.h" + +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 1 ? 2 : n, + "fbsd.exec takes exactly one argument"); + + if (pipe(stdin_pipe) < 0) { + lua_pushnil(L); + lua_pushstring(L, strerror(errno)); + lua_pushinteger(L, errno); + return (3); + } + + 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]); + + argv = luaL_checkarraystrings(L, 1); + if (0 != (r = posix_spawnp(&pid, argv[0], &action, NULL, + (char*const*)argv, environ))) { + lua_pushnil(L); + lua_pushstring(L, strerror(r)); + lua_pushinteger(L, r); + return (3); + } + while (waitpid(pid, &pstat, 0) == -1) { + if (errno != EINTR) { + lua_pushnil(L); + lua_pushstring(L, strerror(r)); + lua_pushinteger(L, r); + return (3); + } + } + + if (WEXITSTATUS(pstat) != 0) { + lua_pushnil(L); + lua_pushstring(L, "Abnormal termination"); + lua_pushinteger(L, r); + return (3); + } + + posix_spawn_file_actions_destroy(&action); + + if (stdin_pipe[0] != -1) + close(stdin_pipe[0]); + if (stdin_pipe[1] != -1) + close(stdin_pipe[1]); + lua_pushinteger(L, pid); + return 1; +} + +#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); + return (1); +} diff --git a/libexec/flua/modules/lfbsd.h b/libexec/flua/modules/lfbsd.h new file mode 100644 index 000000000000..01034a3ad7cd --- /dev/null +++ b/libexec/flua/modules/lfbsd.h @@ -0,0 +1,32 @@ +/* + * 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);