diff --git a/src/bin/elua/main.c b/src/bin/elua/main.c index e2285f8dec..7c68decf15 100644 --- a/src/bin/elua/main.c +++ b/src/bin/elua/main.c @@ -1,6 +1,11 @@ /* The Lua runtime component of the EFL */ #include +#ifndef _WIN32 +#include +#include +#include +#endif #include "main.h" @@ -192,6 +197,81 @@ static int register_callbacks(lua_State *L) { return 1; } +static int elua_exec(lua_State *L) { +#ifndef _WIN32 + pid_t cpid = fork(); + if (cpid < 0) { + lua_pushnil(L); + lua_pushstring(L, strerror(errno)); + return 2; + } + if (!cpid) { + const char **argv = alloca((lua_gettop(L) + 1) * sizeof(char*)); + int i; + for (i = 0; i < lua_gettop(L); ++i) { + argv[i] = lua_tostring(L, i + 1); + } + argv[lua_gettop(L)] = NULL; + execv(argv[0], (char*const*)argv); + exit(1); + } else { + int status; + if (waitpid(cpid, &status, 0) < 0) { + lua_pushnil(L); + lua_pushstring(L, strerror(errno)); + return 2; + } + lua_pushinteger(L, status); + return 1; + } +#else + char buf[4096]; /* temporary, only because Windows API is retarded */ + char *cptr = buf; + + STARTUPINFO si; + PROCESS_INFORMATION pi; + ZeroMemory(&si, sizeof(si)); + si.cb = sizeof(si); + ZeroMemory(&si, sizeof(pi)); + + int i; + for (i = 1; i < lua_gettop(L); ++i) { + size_t l; + const char *arg = lua_tolstring(L, i + 1, &l); + *(cptr++) = '"'; + memcpy(cptr, l + 1, arg); + cptr += l; + *(cptr++) = '"' + if (i != (lua_gettop(L) - 1)) { + *(cptr++) = ' '; + } else { + cptr[0] = '\0'; + } + } + + if (!CreateProcess(lua_tostring(L, 1), buf, NULL, NULL, FALSE, 0, NULL, + NULL, &si, &pi)) { + LPVOID msgbuf; + DWORD dw = GetLastError(); + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER + | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NUL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&msgbuf, + 0, NULL); + lua_pushnil(L); + lua_pushstring(L, (const char*)msgbuf); + LocalFree(msgbuf); + return 2; + } + + int status; + if (!GetExitCodeProcess(pi.hProcess, &status)) status = 0; + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); + lua_pushinteger(L, status); + return 1; +#endif +} + struct Main_Data { int argc; char **argv; @@ -201,6 +281,7 @@ struct Main_Data { const luaL_reg cutillib[] = { { "init_module", init_module }, { "register_callbacks", register_callbacks }, + { "exec", elua_exec }, { NULL, NULL } }; diff --git a/src/bin/elua/xgettext.lua b/src/bin/elua/xgettext.lua index b849aefb5f..1dca2e2f4b 100644 --- a/src/bin/elua/xgettext.lua +++ b/src/bin/elua/xgettext.lua @@ -2,6 +2,7 @@ -- provides a drop-in replacement of xgettext that supports Lua (but not any -- other language) +local cutil = require("cutil") local getopt = require("getopt") local VERSION = "1.0.0" @@ -164,16 +165,16 @@ end local hasxgettext = os.getenv("XGETTEXT") if hasxgettext then - local gargs = { "\"" .. hasxgettext .. "\"" } + local gargs = { hasxgettext } for i = 1, #opts do - gargs[#gargs + 1] = "\"" .. arg[i] .. "\"" + gargs[#gargs + 1] = arg[i] end for i, v in ipairs(args) do if not v:match("^.+%.lua$") then gargs[#gargs + 1] = v end end - os.execute(table.concat(gargs, " ")) + cutil.exec(unpack(gargs)) end return true \ No newline at end of file