[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: [PATCH] file:close() return-value is consistent with the manual.
- From: David Favro <lua@...>
- Date: Sat, 12 Feb 2011 07:09:07 -0500
The 5.2-alpha manual says that file:close() [i.e. io.close()], when called on a
file-descriptor that had been opened by io.popen(), returns the process's
exit-status; this was not the behavior on POSIX platforms: it returned the
return-value of pclose(3), which POSIX.1-2008 (as well as the Linux manpage)
documents as being the same as is returned by waitpid(2), which must be
interpreted by the macros in <sys/wait.h>. This is corrected.
Furthermore, the single return-value doesn't adequately reflect the possible
exit statuses of a child process, which can also exit with a signal: so (per Sam
Roberts's idea) an additional return-value returns the signal-number if the
child process terminates with a signal, in which case the first return-value is
nil. The second return-value will be nil if the child process exited rather
than terminated from a signal, and on platforms which don't support it.
See http://pubs.opengroup.org/onlinepubs/9699919799/functions/pclose.html
---
doc/manual.html | 9 ++++++++-
src/liolib.c | 27 +++++++++++++++++++++++++--
2 files changed, 33 insertions(+), 3 deletions(-)
diff --git a/doc/manual.html b/doc/manual.html
index c154821..c0882ae 100644
--- a/doc/manual.html
+++ b/doc/manual.html
@@ -8795,7 +8795,14 @@ but that takes an unpredictable amount of time to happen.
<p>
If <code>file</code> was created with <a href="#pdf-io.popen"><code>io.popen</code></a>,
-a successful close returns the exit status of the process.
+a successful close returns the exit status of the process. On platforms that
+support it, if the child process terminated due to a signal, nil will be
+returned and the signal number is returned as a second return value. If the
+process exited rather than died from a signal, and on platforms which do not
+support signals, the second return-value is nil.
+Note that since popen() executes the command via a shell, the child process will
+not appear to have terminated due to signal unless it was executed via "exec",
+or if the shell itself died due to signal.
diff --git a/src/liolib.c b/src/liolib.c
index 658601a..b1fc70b 100644
--- a/src/liolib.c
+++ b/src/liolib.c
@@ -18,6 +18,11 @@
#include "lauxlib.h"
#include "lualib.h"
+#if defined(LUA_USE_POSIX)
+ #include <sys/wait.h>
+#endif
+
+
#define MAX_SIZE_T (~(size_t)0)
@@ -147,8 +152,26 @@ static int io_pclose (lua_State *L) {
if (stat == -1) /* error? */
return pushresult(L, 0, NULL);
else {
- lua_pushinteger(L, stat);
- return 1; /* return status */
+ #if defined(LUA_USE_POSIX)
+ /* return:
+ * process-exit-status or nil if signaled,
+ * signal-number if signaled or nil if not
+ */
+ const int exited = WIFEXITED ( stat );
+ const int signaled = WIFSIGNALED( stat );
+ if ( exited ) {
+ lua_pushinteger( L, WEXITSTATUS(stat) );
+ return 1;
+ }
+ else {
+ lua_pushnil(L);
+ lua_pushinteger( L, signaled ? WTERMSIG(stat) : 0 );
+ return 2;
+ }
+ #else
+ lua_pushinteger(L, stat);
+ return 1; /* return status */
+ #endif
}
}
--
1.7.0.4