diff options
author | Christian Pointner <equinox@spreadspace.org> | 2010-11-20 03:54:03 +0000 |
---|---|---|
committer | Christian Pointner <equinox@spreadspace.org> | 2010-11-20 03:54:03 +0000 |
commit | ed2b30813416ac267a9eb058fff5d004a8af1c79 (patch) | |
tree | 511bf02dc1c602d9d676985489e4dbe317ed41e1 | |
parent | cleanup (diff) |
added first verion of
- waitpid
- exec
- pipe
fixed timeout at select
git-svn-id: https://svn.spreadspace.org/gcsd/trunk@44 ac14a137-c7f1-4531-abe0-07747231d213
-rw-r--r-- | src/l_util.c | 77 | ||||
-rw-r--r-- | src/main_loop.lua | 14 |
2 files changed, 83 insertions, 8 deletions
diff --git a/src/l_util.c b/src/l_util.c index b08682a..734253f 100644 --- a/src/l_util.c +++ b/src/l_util.c @@ -36,6 +36,10 @@ #include <sys/select.h> #include <errno.h> #include <string.h> +#include <unistd.h> +#include <stdlib.h> +#include <sys/types.h> +#include <sys/wait.h> #include "l_util.h" @@ -116,9 +120,9 @@ static int l_util_select(lua_State *L) struct timeval tv; struct timeval* timeout = NULL; - if(ms > 0) { - tv.tv_sec = 0; - tv.tv_usec = ms * 1000; + if(ms >= 0) { + tv.tv_sec = ms / 1000; + tv.tv_usec = (ms % 1000) * 1000; timeout = &tv; } int ret = select(max_fd+1, &readables, &writeables, NULL, timeout); @@ -140,20 +144,79 @@ static int l_util_select(lua_State *L) static int l_util_exec(lua_State *L) { - //TODO: implement fork/exec - return 0; + const char* script = luaL_checkstring(L, 1); + char** argv = NULL; + char** evp = NULL; + + pid_t pid; + pid = fork(); + if(pid == -1) { + lua_pushnil(L); + lua_pushstring(L, strerror(errno)); // FIXXXXXME: strerror is not threadsafe!!! + return 2; + } + + if(!pid) { + int fd; + for (fd=getdtablesize();fd>=0;--fd) // close all file descriptors + close(fd); + + execve(script, argv, evp); + exit(-1); + } + + lua_pushinteger(L, pid); + return 1; } static int l_util_waitpid(lua_State *L) { - //TODO: implement waitpid - return 0; + int status = 0; + pid_t pid = waitpid(-1, &status, WNOHANG); + if(!pid || (pid < 0 && (errno == ECHILD))) { + lua_pushinteger(L, 0); + return 1; + } + if(pid < 0) { + lua_pushnil(L); + lua_pushstring(L, strerror(errno)); // FIXXXXXME: strerror is not threadsafe!!! + return 2; + } + + lua_pushinteger(L, pid); + if(WIFEXITED(status)) { + lua_pushliteral(L, "exit"); + lua_pushinteger(L, WEXITSTATUS(status)); + } + else if(WIFSIGNALED(status)) { + lua_pushliteral(L, "signal"); + lua_pushinteger(L, WTERMSIG(status)); + } + else { + lua_pushliteral(L, "unknown"); + lua_pushnil(L); + } + return 3; +} + +static int l_util_pipe(lua_State *L) +{ + int pipefd[2]; + if(pipe(pipefd) == -1) { + lua_pushnil(L); + lua_pushstring(L, strerror(errno)); // FIXXXXXME: strerror is not threadsafe!!! + return 2; + } + lua_pushinteger(L, pipefd[0]); + lua_pushinteger(L, pipefd[1]); + return 2; } static const struct luaL_reg util_funcs [] = { { "select", l_util_select }, { "exec", l_util_exec }, { "waitpid", l_util_waitpid }, + { "pipe", l_util_pipe }, { NULL, NULL } }; diff --git a/src/main_loop.lua b/src/main_loop.lua index c310cdb..c186722 100644 --- a/src/main_loop.lua +++ b/src/main_loop.lua @@ -74,6 +74,13 @@ function main_loop(opt) log.printf(log.NOTICE, "main_loop started") local sig = signal.init() + local pid, err = util.exec("./tmp.sh") + if(pid == nil) then + log.printf(log.DEBUG, "exec script failed: %s", err) + else + log.printf(log.DEBUG, "script started with pid %d", pid) + end + local return_value = module_list:init(opt) if(return_value == defines.KILL_DAEMON) then return_value = -1 @@ -85,7 +92,12 @@ function main_loop(opt) local readable, writeable, err = util.select({ sig, unpack(get_readables()) }, get_writeables(), 10) if(err) then if(err == "timeout") then - -- TODO: handle timeouts + local pid, reason, status = util.waitpid() + if(pid == nil) then + log.printf(log.DEBUG, "waitpid failed: " .. reason) + elseif(pid > 0) then + log.printf(log.DEBUG, "child with pid %d stopped, reason: %s, code: %d", pid, reason, status) + end elseif(err == "signal") then -- ignore this else |