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 */
|
/* The Lua runtime component of the EFL */
|
||||||
|
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
|
#ifndef _WIN32
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
|
||||||
|
@ -192,6 +197,81 @@ static int register_callbacks(lua_State *L) {
|
||||||
return 1;
|
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 {
|
struct Main_Data {
|
||||||
int argc;
|
int argc;
|
||||||
char **argv;
|
char **argv;
|
||||||
|
@ -201,6 +281,7 @@ struct Main_Data {
|
||||||
const luaL_reg cutillib[] = {
|
const luaL_reg cutillib[] = {
|
||||||
{ "init_module", init_module },
|
{ "init_module", init_module },
|
||||||
{ "register_callbacks", register_callbacks },
|
{ "register_callbacks", register_callbacks },
|
||||||
|
{ "exec", elua_exec },
|
||||||
{ NULL, NULL }
|
{ NULL, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
-- provides a drop-in replacement of xgettext that supports Lua (but not any
|
-- provides a drop-in replacement of xgettext that supports Lua (but not any
|
||||||
-- other language)
|
-- other language)
|
||||||
|
|
||||||
|
local cutil = require("cutil")
|
||||||
local getopt = require("getopt")
|
local getopt = require("getopt")
|
||||||
|
|
||||||
local VERSION = "1.0.0"
|
local VERSION = "1.0.0"
|
||||||
|
@ -164,16 +165,16 @@ end
|
||||||
|
|
||||||
local hasxgettext = os.getenv("XGETTEXT")
|
local hasxgettext = os.getenv("XGETTEXT")
|
||||||
if hasxgettext then
|
if hasxgettext then
|
||||||
local gargs = { "\"" .. hasxgettext .. "\"" }
|
local gargs = { hasxgettext }
|
||||||
for i = 1, #opts do
|
for i = 1, #opts do
|
||||||
gargs[#gargs + 1] = "\"" .. arg[i] .. "\""
|
gargs[#gargs + 1] = arg[i]
|
||||||
end
|
end
|
||||||
for i, v in ipairs(args) do
|
for i, v in ipairs(args) do
|
||||||
if not v:match("^.+%.lua$") then
|
if not v:match("^.+%.lua$") then
|
||||||
gargs[#gargs + 1] = v
|
gargs[#gargs + 1] = v
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
os.execute(table.concat(gargs, " "))
|
cutil.exec(unpack(gargs))
|
||||||
end
|
end
|
||||||
|
|
||||||
return true
|
return true
|
Loading…
Reference in New Issue