This is not a proposal to modify the Lua core, but a design proposal for an API which extends the Lua core. This API is meant to provide a more complete programming environment for stand-alone Lua programs on today's popular operating systems (Windows, MacOSX and POSIX platforms).
There are [implementations for POSIX and Windows] hosted on LuaForge. These are highly usable implementations, but should be considered only for testing purposes while the API is still being standardized.
Note that all these functions return the standard (nil,"error message") on failure and that, unless otherwise specified, they return (true) on success.
require "ex"
os.getenv(name)
os.setenv(name, value)
os.setenv(name, nil)
os.environ()
os.chdir(pathname)
os.mkdir(pathname)
os.remove(pathname)
pathname = os.currentdir()
for entry in os.dir(pathname) do ; end
entry = os.dirent(pathname) entry = os.dirent(file)
Both the iterator function returned by os.dir() and the os.dirent() function return an 'entry' table. This table contains at least the following fields:
Implementations may add other fields or even methods.
file:lock(mode, offset, length) io.lock(file, mode, offset, length)
file:unlock(offset, length) io.unlock(file, offset, length)
Note that both file:lock() and file:unlock() extend the metatable for Lua file objects.
rd, wr = io.pipe()
os.sleep(seconds) os.sleep(interval, unit)
os.sleep(3.8) -- sleep for 3.8 seconds local microseconds = 1e6 os.sleep(3800000, microseconds) -- sleep for 3800000 µs local ticks = 100 os.sleep(380, ticks) -- sleep for 380 ticks
proc = os.spawn(filename) proc = os.spawn{filename, [args-opts]} proc = os.spawn{command=filename, [args-opts]}
exitcode = proc:wait()
All functions are also available under the ex namespace:
ex.getenv(name) ex.setenv(name, value) ex.environ() ex.chdir(pathname) ex.mkdir(pathname) ex.currentdir() ex.dir(pathname) ex.dirent(pathname) ex.lock(file, mode, offset, length) ex.unlock(file, offset, length) ex.pipe() ex.sleep(interval, [unit]) ex.spawn(...) ex.wait(proc)
Note that ex.getenv is here mostly for parallelism, but also because under Windows, using the SetEnvironmentVariable?() API requires overriding the standard os.getenv implementation which uses getenv() to use GetEnvironmentVariable?() instead.
require "ex" -- run the echo command proc = os.spawn"/bin/echo" proc = os.spawn{"/bin/echo", "hello", "world"} proc = os.spawn{command="/bin/echo", "hello", "world"} -- run the id command vars = { LANG="fr_FR" } proc = os.spawn{"/bin/id", "-un", env=vars} proc = os.spawn{command="/bin/id", "-un", env=vars) -- Useless use of cat local rd, wr = assert(io.pipe()) local proc = assert(os.spawn("/bin/cat", {stdin=rd})) rd:close() wr:write("Hello world\n") wr:close() proc:wait() -- Run a program with a modified environment local env = os.environ() env.LUA_PATH = "/usr/share/lib/lua/?.lua" env.LUA_CPATH = "/usr/share/lib/lua/?.so" local proc = assert(os.spawn("lua", {args = {"-e", 'print"Hello world\n"'}, env=env })) proc:wait() -- popen2() function popen2(...) local in_rd, in_wr = io.pipe() local out_rd, out_wr = io.pipe() local proc, err = os.spawn{stdin = in_rd, stdout = out_wr, ...} in_rd:close(); out_wr:close() if not proc then in_wr:close(); out_rd:close() return proc, err end return proc, out_rd, in_wr end -- usage: local p, i, o = assert(popen2("wc", "-w")) o:write("Hello world"); o:close() print(i:read"*l"); i:close() p:wait()