summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Silverstone <dsilvers@digital-scurf.org>2012-09-12 11:30:50 +0100
committerDaniel Silverstone <dsilvers@digital-scurf.org>2012-09-12 11:30:50 +0100
commit9015b9fd70e9d8a7215af131ebf950479c64a47c (patch)
treec5f05a0228d4729bf7ea4e9b44a73a646318e1dd
parent1bdbe528d4050d770e76b5a166e324ef6ce39d35 (diff)
downloadluxio-9015b9fd70e9d8a7215af131ebf950479c64a47c.tar.gz
Add prefork and preexec support to luxio.subprocess.spawn
-rw-r--r--luxio/subprocess.lua33
1 files changed, 32 insertions, 1 deletions
diff --git a/luxio/subprocess.lua b/luxio/subprocess.lua
index 3da5993..617d20b 100644
--- a/luxio/subprocess.lua
+++ b/luxio/subprocess.lua
@@ -48,6 +48,13 @@
-- If you want to change directory before exec in the child, you can pass
-- cwd="/some/path".
--
+-- To run some code before forking, pass prefork=somefunction and to
+-- run code before exec (in the child) pass preexec=somefunction.
+--
+-- If the prefork function raises an error then the spawn will be stopped and
+-- the error propagated. If the preexec function raises an error then the exec
+-- will be stopped and the child will exit with status code 1.
+--
-- spawn_simple has one additional tweak. If 'stdin' is provided as
-- a string then it will automatically write that string to the stdin
-- of the child (and close the FD afterwards) for you automatically.
@@ -100,6 +107,7 @@ local stderr_fh = sio.stderr
local setenv = l.setenv
local unsetenv = l.unsetenv
local _exit = l._exit
+local _TRACEBACK = debug.traceback
local F_SETFD = l.F_SETFD
local F_GETFD = l.F_GETFD
@@ -236,6 +244,21 @@ local function _spawn(t)
-- Finally, let's fork
+ if proc.args.prefork then
+ local ok, msg = xpcall(proc.args.prefork, function(...)
+ for fd in pairs(parent_close) do
+ close(fd)
+ end
+ for fd in pairs(child_close) do
+ close(fd)
+ end
+ return _TRACEBACK(...)
+ end)
+ if not ok then
+ error(msg)
+ end
+ end
+
local pid, errno = fork()
_assert(pid > -1, "Unable to fork()")
@@ -305,7 +328,15 @@ local function _spawn(t)
local cwd = tostring(proc.args.cwd)
local ret, err = chdir(cwd)
if ret ~= 0 then
- stderr_fh:write("chdir(" .. cwd .. "): " .. err)
+ stderr_fh:write("chdir(" .. cwd .. "): " .. err .. "\n")
+ _exit(1)
+ end
+ end
+
+ if proc.args.preexec then
+ local ok, msg = xpcall(proc.args.preexec, _TRACEBACK)
+ if not ok then
+ stderr_fh:write(msg .. "\n")
_exit(1)
end
end