tagline |
---|
processes and IPC |
A library for creating, controlling and communicating with child processes. Works on Windows, Linux and OSX.
Tested on Windows and Linux.
Missing features:
- named mutexes, semaphores and events.
- setting CPU and RAM limits.
- CPU and RAM monitoring.
proc.exec(opt | cmd,...) -> p
spawn a child process
proc.exec_luafile(opt | script,...) -> p
spawn a process running a Lua script
p:kill()
kill process
p:wait([expires]) -> status
wait for a process to finish
p:status() -> active|finished|killed|forgotten
process status
p:exit_code() -> code | nil,status
get process exit code
p:forget()
close process handles
proc.env(k) -> v
get env. var
proc.env(k, v)
set env. var
proc.env(k, false)
delete env. var
proc.env() -> env
get all env. vars
proc.esc(s, ['win'|'unix']) -> s
escape string (but not quote)
proc.quote_arg(s, ['win'|'unix']) -> s
quote as cmdline arg
Spawn a child process and return a process object to query and control the process. Options can be given as separate args or in a table.
cmd
can be either a string or an array containing the filepath of the executable to run and its command-line arguments.env
is a table of environment variables (if not given, the current environment is inherited).cur_dir
is the directory to start the process in.stdin
,stdout
,stderr
are pipe ends created withfs.pipe()
to redirect the standard input, output and error streams of the process; you can also set any of these totrue
to have them opened (and closed) for you.autokill
kills the process when the calling process exits.
Spawn a process running a Lua script, using the same LuaJIT executable
as that of the running process. The process starts in the current directory
unless otherwise specified. The arguments and options are the same as for
exec()
, except that cmd
must be a Lua file instead of an executable file.
Only use uppercase env. var names because like file names, env. vars are case-sensitive on POSIX, but case-insensitive on Windows.
Only use proc.env()
to read variables instead of os.getenv()
because
the latter won't see the changes made to variables.
Only use exit status codes in the 0..255 range because Windows exit codes are int32 but POSIX codes are limited to a byte.
In Windows, if you kill a process from Task Manager, exit_code()
returns 1
instead of nil, 'killed'
, and status()
returns 'finished'
instead
of 'killed'
. You only get 'killed'
when you kill the process yourself
by calling kill()
.
The only way to safely redirect both stdin and stdout of child processes without potentially causing deadlocks is to use async pipes and perform the writes and the reads in separate [sock] threads.
Don't forget to close the stdin file when you're done with it to signal end-of-input to the child process.
Don't forget to check for a zero-length read which can happen any time and signals that the child process closed its end of the pipe.
Always call forget() when you're done with the process, even after you killed it, but not before you're done with all its redirected pipes if any (because forget() also closes them).
In Linux, if you start your autokilled process from a thread other than the main thread, the process is killed when the thread finishes, IOW autokill is only portable if you start processes from the main thread.
In Windows, the autokill behavior is by default inherited by the child processes. In Linux it isn't. IOW autkill inheritance is not portable.