aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIsaac Freund <ifreund@freebsdfoundation.org>2025-05-05 09:57:13 +0000
committerEd Maste <emaste@FreeBSD.org>2025-05-12 18:27:57 +0000
commit7080a0c170daf8e4b3f331ec33003b2f8893dc23 (patch)
treecb51e93327c86b007dbd27a1de3678ae16753d3c
parente3b16f53a6455903a7e814045584fe203d4fff64 (diff)
flua: add posix.unistd.execp
This matches the interface of lposix, although I do wonder why they went with execp rather than execvp for the function name here. Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D50177
-rw-r--r--libexec/flua/modules/lposix.c57
1 files changed, 57 insertions, 0 deletions
diff --git a/libexec/flua/modules/lposix.c b/libexec/flua/modules/lposix.c
index a706adf2c353..816d4bc688d2 100644
--- a/libexec/flua/modules/lposix.c
+++ b/libexec/flua/modules/lposix.c
@@ -199,6 +199,62 @@ err:
}
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;
@@ -513,6 +569,7 @@ static const struct luaL_Reg unistdlib[] = {
REG_SIMPLE(chown),
REG_DEF(close, lua_pclose),
REG_SIMPLE(dup2),
+ REG_SIMPLE(execp),
REG_SIMPLE(fork),
REG_SIMPLE(getpid),
REG_SIMPLE(pipe),