[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: io.popen: reading both stdout AND stderr
- From: Philipp Janda <siffiejoe@...>
- Date: Thu, 15 Aug 2013 17:01:57 +0200
Hi!
Am 15.08.2013 15:57 schröbte Lorenzo Donati:
[...]
BTW. If Lua team doesn't deem it useful enough to enhance popen in this
sense, IMO this should be added at least to lfs
On a related note, although a robust workhorse, I find lfs a bit
lacking. I'd really like it to be a little more feature complete.
Maybe you are looking at the wrong library. What about lua-apr[1][2]
(also available as a rock[3])?
[1]: https://github.com/xolox/lua-apr/
[2]: http://peterodding.com/code/lua/apr/
[3]: http://luarocks.org/repositories/rocks/#lua-apr
lua-apr is still for Lua 5.1 only, but I have a quick-and-dirty patch
for Lua 5.2 support, if you are interested ...
Features I miss from lfs (which should be easy to bind to already
existing APIs in the host OS):
* mkdir cannot create directories recursively ( mkdir "a/b/c" gives an
error if "a" doesn't exist, whereas I'd like to have a flag to tell it
"do make all the intermediate dirs")
apr.dir_make_recursive(path [, permissions]) → status
* File copy operations.
apr.file_copy(source, target [, permissions]) → status
apr.file_append(source, target [, permissions]) → status
apr.file_link(source, target) → status
* Pathname existance checking and
canonalization/normalization/resolution (e.g. lfs.exists
"/foo/bar/a/b/../../c" would return "/foo/bar/c" if this file exists, or
nil otherwise)
apr.filepath_root(path [, option, ...]) → root, path
apr.filepath_parent(path [, option, ...]) → parent, filename
apr.filepath_name(path [, split]) → filename [, extension]
apr.filepath_merge(root, path [, option, ...]) → merged
etc...
* lfs.dir iterator should not return ".." and "." as directories.
Especially ".." is dangerous when building recursive functions on top of
lfs.dir: you could by mistake recurse upwards (I'm always wrapping
lfs.dir to remove ".." and ".", but this inconvenient and error prone -
I don't know you, but I never used lfs.dir output directly). At least
this behaviour should be documented.
Other operations that are not strictly file-system operations, but IMO
too much connected to them:
* lfs.setenv (to pair os.getenv)
apr.env_set(name, value) → status
apr.env_delete(name) → status
* lfs.popen (as said above)
* lfs.execute having a richer API than os.execute (e.g. see wxWidgets
wxExecute) and allowing sync/async execution
apr.proc_create(program) → process
apr.proc_detach(daemonize) → status
process:user_set(username [, password]) → status
process:cmdtype_set(type) → status
process:dir_set(path) → status
process:io_set(stdin, stdout, stderr) → status
process:exec([args]) → status
process:wait(how) → done [, why, code]
process:kill(how) → status
etc....
Regarding your enhanced popen, this is as far as I got:
local apr = require( "apr" )
local proc = assert( apr.proc_create( "./xxx.sh" ) )
assert( proc:cmdtype_set( "program" ) )
assert( proc:io_set( 'none', 'parent-block', 'parent-block' ) )
assert( proc:exec{} )
local out = proc:out_get()
local err = proc:err_get()
print( out:read() )
print( err:read() )
local done, why, code = assert( proc:wait( true ) )
if why == "exit" then
print( "exit status:", code )
else
print( "killed by signal:", code )
end
The problem (which lfs would face as well) is multiplexing the io of
stdout and stderr so that no process is blocked and no output lost ...
I acknowledge that many of the above can be built on top of lfs, but
sometimes it is tricky and anyway not as efficient as wrapping existing
OS APIs.
Cheers.
-- Lorenzo
Philipp