lua-users home
lua-l archive

io.close() discards return value of pclose(3)

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


Hello,
Processes opened with io.popen(), are closed using io.close(), which is also
used for closing streams associated with a file. The io.close() actually calls
pclose() and/or fclose() and returns a boolean, depending on whether the
operation was succesful.
The problem is that the pclose() C library function returns the exit status of
the command previously "opened" with popen(), but Lua's io.close() discards
this exit status. The exit status of the command is quite useful and I was
wondering if something could be done to change this behaviour.
I made some small changes to src/lib/liolib.c, by adding a io.pclose() function
that returns two values: a boolean as io.close() does and additionally a
number, the exit status of the command. I attach a patch that should be
applied against Lua 5.0.2.
Please let me know what do you think.
diff -ruN lua-5.0.2.orig/src/lib/liolib.c lua-5.0.2/src/lib/liolib.c
--- lua-5.0.2.orig/src/lib/liolib.c	Sat May 1 12:28:03 2004
+++ lua-5.0.2/src/lib/liolib.c	Sat May 1 21:38:44 2004
@@ -149,7 +149,7 @@
 if (f == stdin || f == stdout || f == stderr)
 return 0; /* file cannot be closed */
 else {
- int ok = (pclose(f) != -1) || (fclose(f) == 0);
+ int ok = (fclose(f) == 0);
 if (ok)
 *(FILE **)lua_touserdata(L, 1) = NULL; /* mark file as closed */
 return ok;
@@ -166,6 +166,41 @@
 }
 
 
+static int aux_pclose (lua_State *L) {
+ FILE *f = tofile(L, 1);
+ if (f == stdin || f == stdout || f == stderr)
+ return 0; /* file cannot be closed */
+ else {
+ int ok = pclose(f);
+ if (ok != -1)
+ *(FILE **)lua_touserdata(L, 1) = NULL; /* mark file as closed */
+ return ok;
+ }
+}
+
+
+static int io_pclose (lua_State *L) {
+#if !USE_POPEN
+ luaL_error(L, "`pclose' not supported");
+ return 0;
+#else
+ int i;
+ if (lua_isnone(L, 1) && lua_type(L, lua_upvalueindex(1)) == LUA_TTABLE) {
+ lua_pushstring(L, IO_OUTPUT);
+ lua_rawget(L, lua_upvalueindex(1));
+ }
+ i = aux_pclose(L) >> 8;
+ if (i == -1)
+ return pushresult(L, 0, NULL);
+ else {
+ pushresult(L, 1, NULL);
+ lua_pushnumber(L, (lua_Number)(i));
+ return 2;
+ }
+#endif
+}
+
+
 static int io_gc (lua_State *L) {
 FILE **f = topfile(L, 1);
 if (*f != NULL) /* ignore closed files */
@@ -497,6 +532,7 @@
 {"flush", io_flush},
 {"open", io_open},
 {"popen", io_popen},
+ {"pclose", io_pclose},
 {"read", io_read},
 {"tmpfile", io_tmpfile},
 {"type", io_type},

AltStyle によって変換されたページ (->オリジナル) /