summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Kendrick (humdrum) <rjek@rjek.com>2012-09-12 11:35:27 +0100
committerRob Kendrick (humdrum) <rjek@rjek.com>2012-09-12 11:35:27 +0100
commit7aa97221a6d559e6887d86c4b6829bbaa5e80940 (patch)
treeaeb0dc177d886f3f218ae8b4d38350fbb1179336
parent85be999abc770c56700ca09d7e1d0cea4c58dd8b (diff)
parent9015b9fd70e9d8a7215af131ebf950479c64a47c (diff)
downloadluxio-7aa97221a6d559e6887d86c4b6829bbaa5e80940.tar.gz
Fixes from Daniel
-rw-r--r--luxio/simple.lua2
-rw-r--r--luxio/subprocess.lua46
2 files changed, 47 insertions, 1 deletions
diff --git a/luxio/simple.lua b/luxio/simple.lua
index 8c59e84..c19d348 100644
--- a/luxio/simple.lua
+++ b/luxio/simple.lua
@@ -1184,7 +1184,7 @@ end
local lchdir = l.chdir
local function chdir(path)
- local r, err = chdir(path)
+ local r, err = lchdir(path)
if r == -1 then
return err("chdir", errno)
end
diff --git a/luxio/subprocess.lua b/luxio/subprocess.lua
index d0a7c91..617d20b 100644
--- a/luxio/subprocess.lua
+++ b/luxio/subprocess.lua
@@ -45,6 +45,16 @@
-- If you want the child (during pre-exec) to close additional FDs then
-- you can specify them in a table called close_in_child
--
+-- 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.
@@ -92,9 +102,12 @@ local dup2 = l.dup2
local fcntl = l.fcntl
local bclear = l.bit.bclear
local wrap_fd = sio.wrap_fd
+local chdir = sio.chdir
+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
@@ -231,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()")
@@ -295,6 +323,24 @@ local function _spawn(t)
end
end
+ -- Change directory if needed
+ if proc.args.cwd then
+ local cwd = tostring(proc.args.cwd)
+ local ret, err = chdir(cwd)
+ if ret ~= 0 then
+ 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
+
-- Run the child process
exec_fn(exe, unpack(proc.args))