]> git.e2factory.org Git - e2factory.git/commitdiff
Implement e2lib.execvp()
authorTobias Ulmer <tu@emlix.com>
Mon, 18 Nov 2013 13:29:22 +0000 (14:29 +0100)
committerTobias Ulmer <tu@emlix.com>
Wed, 16 Nov 2016 14:41:17 +0000 (15:41 +0100)
Signed-off-by: Tobias Ulmer <tu@emlix.com>
generic/e2lib.lua
generic/le2lib.c

index 469fddc2a57013613d6f5f3668550bb73de8b603..fad6d074e1d33da64d878ea9c220398ebe4898d9 100644 (file)
@@ -296,6 +296,21 @@ function e2lib.kill(pid, sig)
     return true
 end
 
+--- Execute a process image and replace the current process.
+-- See execvp(3) for more information.
+-- @param file File name or path to execute. PATH is searched.
+-- @param argv Vector containing arguments for the process. First argument
+--             should be the file name itself.
+-- @return False on error. It does not return on success.
+-- @return Error object on failure.
+function e2lib.execvp(filenm, argv)
+    local rc, errstring
+
+    rc, errstring = le2lib.execvp(filenm, argv)
+
+    return false, err.new("executing process %q failed: %s", filenm, errstring)
+end
+
 --- Interrupt handling.
 --
 -- le2lib sets up a SIGINT handler that calls back into this function.
index 4296542913224e1d7bdcb83085e33ecd67cc3a90..3734a792888fa65c20c493dc3d36057c642f6d88 100644 (file)
@@ -387,26 +387,56 @@ do_unsetenv(lua_State *lua)
 #endif
 
 static int
-do_exec(lua_State *lua)
+do_execvp(lua_State *L)
 {
-       const int max_args = 256;
-       const char *args[max_args+1];
-       int rc, i;
-       for (i=0; i<max_args+1; i++) {
-               args[i] = luaL_optlstring(lua, i+1, NULL, NULL);
-               if (!args[i]) {
-                       break;
-               }
+       const char *file;
+       char **argv;
+       size_t argc;
+       int i = 0;
+
+       file = lua_tostring(L, 1);
+       if (file == NULL) {
+               lua_pushboolean(L, 0);
+               lua_pushstring(L, "do_execvp: missing/wrong file argument");
+               return 2;
        }
-       if( i > max_args) {
-               lua_pushboolean(lua, 0);
-               return 1;
+
+       if (!lua_istable(L, 2)) {
+               lua_pushboolean(L, 0);
+               lua_pushstring(L, "do_execvp: missing/wrong argv argument");
+               return 2;
        }
-       args[i] = NULL;
-       rc = execvp(args[0], (char * const*)args);
-       lua_pushboolean(lua, rc == 0);
 
-       return 1;
+       argc = lua_objlen(L, 2);
+       if (argc == 0) {
+               lua_pushboolean(L, 0);
+               lua_pushstring(L, "do_execvp: 1+ argv arguments required");
+               return 2;
+       }
+
+       argv = malloc(argc * sizeof(char *));
+       if (argv == NULL) {
+               lua_pushboolean(L, 0);
+               lua_pushstring(L, "do_execvp: 1+ argv arguments required");
+               return 2;
+       }
+
+       for (; i < argc; i++) {
+               lua_rawgeti(L, 2, i+1); /* table index starts at 1 */
+               argv[i] = (char *)lua_tostring(L, lua_gettop(L));
+       }
+       argv[i] = NULL;
+
+
+
+       execvp(file, argv);
+
+       /* If it returns at all something is wrong */
+       free(argv);
+       lua_pushboolean(L, 0);
+       lua_pushstring(L, strerror(errno));
+
+       return 2;
 }
 
 static int
@@ -862,6 +892,7 @@ static luaL_Reg lib[] = {
        { "closefrom", closefrom },
        { "cwd", get_working_directory },
        { "directory", get_directory },
+       { "execvp", do_execvp },
        { "exists", file_exists },
        { "fork", lua_fork },
        { "getpid", do_getpid },