File luaexecute.diff of Package rpm.33195

--- rpmio/rpmlua.c.orig	2024-02-14 11:16:13.057303422 +0000
+++ rpmio/rpmlua.c	2024-02-14 11:17:18.349296227 +0000
@@ -27,8 +27,12 @@
 #define lua_pushglobaltable(L)	lua_pushvalue(L, LUA_GLOBALSINDEX)
 #endif
 
+#include <errno.h>
 #include <unistd.h>
 #include <assert.h>
+#include <spawn.h>
+#include <sys/types.h>
+#include <sys/wait.h>
 
 #include <rpm/rpmio.h>
 #include <rpm/rpmmacro.h>
@@ -40,6 +44,7 @@
 
 #define _RPMLUA_INTERNAL
 #include "rpmio/rpmlua.h"
+#include "rpmio/rpmio_internal.h"
 
 #include "debug.h"
 
@@ -66,6 +71,20 @@ static void *nextFileFuncParam = NULL;
 static int luaopen_rpm(lua_State *L);
 static int rpm_print(lua_State *L);
 
+static int pusherror(lua_State *L, int code, const char *info)
+{
+    lua_pushnil(L);
+    lua_pushstring(L, info ? info : strerror(code));
+    lua_pushnumber(L, code);
+    return 3;
+}
+
+static int pushresult(lua_State *L, int result)
+{
+    lua_pushnumber(L, result);
+    return 1;
+}
+
 rpmlua rpmluaGetGlobalState(void)
 {
     INITSTATE(NULL, lua);
@@ -894,6 +913,32 @@ static int rpm_print (lua_State *L)
     return 0;
 }
 
+static int rpm_execute(lua_State *L)
+{
+    const char *file = luaL_checkstring(L, 1);
+    int i, n = lua_gettop(L);
+    int status;
+    pid_t pid;
+
+    char **argv = malloc((n + 1) * sizeof(char *));
+    if (argv == NULL)
+	return luaL_error(L, "not enough memory");
+    argv[0] = (char *)file;
+    for (i = 1; i < n; i++)
+	argv[i] = (char *)luaL_checkstring(L, i + 1);
+    argv[i] = NULL;
+    rpmSetCloseOnExec();
+    status = posix_spawnp(&pid, file, NULL, NULL, argv, environ);
+    free(argv);
+    if (status != 0)
+	return pusherror(L, status, NULL);
+    if (waitpid(pid, &status, 0) == -1)
+	return pusherror(L, errno, NULL);
+    if (status != 0)
+	return pusherror(L, status, "exit code");
+    return pushresult(L, status);
+}
+
 static const luaL_Reg rpmlib[] = {
     {"b64encode", rpm_b64encode},
     {"b64decode", rpm_b64decode},
@@ -906,6 +951,7 @@ static const luaL_Reg rpmlib[] = {
     {"call", rpm_call},
     {"interactive", rpm_interactive},
     {"next_file", rpm_next_file},
+    {"execute", rpm_execute},
     {NULL, NULL}
 };
 
openSUSE Build Service is sponsored by