lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]

On Wed, Apr 18, 2007 at 03:53:01PM -0300, Roberto Ierusalimschy wrote:
> As Ross pointed out, the ability to close stdin together with its use
> in several places in Lua is wrong. So, either we should check that
> stdin is valid (how??) whenever we use it, or we drop its use
> altogether, or we avoid it being closed. For what the standard Lua
> distribution is aimed, the last option seems the most reasonable.

IIRC, the reason the original poster was closing stdin not for daemonization,
but because on windows, keeping a file open can interfere with other processes
ability to read/write the file. So not allowing std* to be closed solves one
problem, but creates another.

I'd like to make the case that support for the ANSI C freopen() is what's
needed here.

It would allow the original poster to reopen his file (closing the file that
Notepad or whatever was fighting with lua over), it allows people to control
where the output of os.execute() goes, allows reopening stdout to /dev/null and
stderr to a log file (useful even when you aren't writing a daemon), etc., etc.

And its trivial to implement!


Usage would be:

-- freopen.lua
f = io.stdout

assert(f:reopen("_file", "w"))
assert(os.execute'echo thing')
data = f:read'*l'
io.stderr:write('read <''>\n')
assert(data == 'something')

% diff -u lua-5.1.2/src/liolib.c lua-5.1.1/src/liolib.c
--- lua-5.1.2/src/liolib.c      2006-05-08 13:14:16.000000000 -0700
+++ lua-5.1.1/src/liolib.c      2007-04-18 14:58:40.000000000 -0700
@@ -457,6 +457,16 @@
   return pushresult(L, fflush(tofile(L)) == 0, NULL);

+static int f_reopen (lua_State *L) {
+  const char *filename = luaL_checkstring(L, 2);
+  const char *mode = luaL_optstring(L, 3, "r");
+  FILE **pf = topfile(L);
+  if(*pf)
+    *pf = freopen(filename, mode, *pf);
+  return (*pf == NULL) ? pushresult(L, 0, filename) : 1;

 static const luaL_Reg iolib[] = {
   {"close", io_close},
@@ -476,6 +486,7 @@

 static const luaL_Reg flib[] = {
   {"close", io_close},
+  {"reopen", f_reopen},
   {"flush", f_flush},
   {"lines", f_lines},
   {"read", f_read},