From 79cb336d74697ca38d6d2f2068781086cfaa9076 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Thu, 19 Apr 2007 17:22:32 -0300 Subject: does not allow standard files to be closed --- liolib.c | 51 ++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 36 insertions(+), 15 deletions(-) (limited to 'liolib.c') diff --git a/liolib.c b/liolib.c index 4ddaab23..6ad58f31 100644 --- a/liolib.c +++ b/liolib.c @@ -1,5 +1,5 @@ /* -** $Id: liolib.c,v 2.74 2006/06/22 16:12:59 roberto Exp roberto $ +** $Id: liolib.c,v 2.75 2006/09/18 14:03:18 roberto Exp roberto $ ** Standard I/O (and system) library ** See Copyright Notice in lua.h */ @@ -93,8 +93,17 @@ static FILE **newfile (lua_State *L) { /* -** this function has a separated environment, which defines the -** correct __close for 'popen' files +** function to (not) close the standard files stdin, stdout, and stderr +*/ +static int io_noclose (lua_State *L) { + lua_pushnil(L); + lua_pushliteral(L, "cannot close standard file"); + return 2; +} + + +/* +** function to close 'popen' files */ static int io_pclose (lua_State *L) { FILE **p = topfile(L); @@ -104,6 +113,9 @@ static int io_pclose (lua_State *L) { } +/* +** function to close regular files +*/ static int io_fclose (lua_State *L) { FILE **p = topfile(L); int ok = (fclose(*p) == 0); @@ -129,8 +141,8 @@ static int io_close (lua_State *L) { static int io_gc (lua_State *L) { FILE *f = *topfile(L); - /* ignore closed files and standard files */ - if (f != NULL && f != stdin && f != stdout && f != stderr) + /* ignore closed files */ + if (f != NULL) aux_close(L); return 0; } @@ -155,6 +167,10 @@ static int io_open (lua_State *L) { } +/* +** this function has a separated environment, which defines the +** correct __close for 'popen' files +*/ static int io_popen (lua_State *L) { const char *filename = luaL_checkstring(L, 1); const char *mode = luaL_optstring(L, 2, "r"); @@ -502,31 +518,36 @@ static void createstdfile (lua_State *L, FILE *f, int k, const char *fname) { lua_pushvalue(L, -1); lua_rawseti(L, LUA_ENVIRONINDEX, k); } - lua_setfield(L, -2, fname); + lua_pushvalue(L, -2); /* copy environment */ + lua_setfenv(L, -2); /* set it */ + lua_setfield(L, -3, fname); +} + + +static void newfenv (lua_State *L, lua_CFunction cls) { + lua_createtable(L, 0, 1); + lua_pushcfunction(L, cls); + lua_setfield(L, -2, "__close"); } LUALIB_API int luaopen_io (lua_State *L) { createmeta(L); /* create (private) environment (with fields IO_INPUT, IO_OUTPUT, __close) */ - lua_createtable(L, 2, 1); + newfenv(L, io_fclose); lua_replace(L, LUA_ENVIRONINDEX); /* open library */ luaL_register(L, LUA_IOLIBNAME, iolib); /* create (and set) default files */ + newfenv(L, io_noclose); /* close function for default files */ createstdfile(L, stdin, IO_INPUT, "stdin"); createstdfile(L, stdout, IO_OUTPUT, "stdout"); createstdfile(L, stderr, 0, "stderr"); - /* create environment for 'popen' */ + lua_pop(L, 1); /* pop environment for default files */ lua_getfield(L, -1, "popen"); - lua_createtable(L, 0, 1); - lua_pushcfunction(L, io_pclose); - lua_setfield(L, -2, "__close"); - lua_setfenv(L, -2); + newfenv(L, io_pclose); /* create environment for 'popen' */ + lua_setfenv(L, -2); /* set fenv for 'popen' */ lua_pop(L, 1); /* pop 'popen' */ - /* set default close function */ - lua_pushcfunction(L, io_fclose); - lua_setfield(L, LUA_ENVIRONINDEX, "__close"); return 1; } -- cgit v1.2.3-55-g6feb