elua: utility func to exec a process (without spawning a shell like os.execute)
This commit is contained in:
parent
58409c521a
commit
cbeaf5b58a
|
@ -1,6 +1,11 @@
|
|||
/* The Lua runtime component of the EFL */
|
||||
|
||||
#include <getopt.h>
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#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 }
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue