From d8f22a19065567515cea1606e8f59835da95f7ca Mon Sep 17 00:00:00 2001 From: Tobias Ulmer Date: Mon, 18 Nov 2013 14:29:22 +0100 Subject: [PATCH] Implement e2lib.execvp() Signed-off-by: Tobias Ulmer --- generic/e2lib.lua | 15 +++++++++++ generic/le2lib.c | 63 +++++++++++++++++++++++++++++++++++------------ 2 files changed, 62 insertions(+), 16 deletions(-) diff --git a/generic/e2lib.lua b/generic/e2lib.lua index 469fddc..fad6d07 100644 --- a/generic/e2lib.lua +++ b/generic/e2lib.lua @@ -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. diff --git a/generic/le2lib.c b/generic/le2lib.c index 4296542..3734a79 100644 --- a/generic/le2lib.c +++ b/generic/le2lib.c @@ -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) { - 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 }, -- 2.39.5