summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Pall <mike>2012-09-24 19:00:54 +0200
committerMike Pall <mike>2012-09-24 19:00:54 +0200
commitcfca926cc2e2b63e94492f0a1f5c033f6db3a6f5 (patch)
tree4601d6b067fcea09b9e1368b998baa1b48de4866
parent125cc879884b19ffa9181b7a52d1b7b73759301e (diff)
downloadluajit-cfca926cc2e2b63e94492f0a1f5c033f6db3a6f5.tar.gz
luajit-cfca926cc2e2b63e94492f0a1f5c033f6db3a6f5.tar.bz2
luajit-cfca926cc2e2b63e94492f0a1f5c033f6db3a6f5.zip
From Lua 5.2: Extended results from os.execute() and pipe:close().
Needs -DLUAJIT_ENABLE_LUA52COMPAT.
-rw-r--r--src/lauxlib.h2
-rw-r--r--src/lib_aux.c55
-rw-r--r--src/lib_io.c56
-rw-r--r--src/lib_os.c34
4 files changed, 95 insertions, 52 deletions
diff --git a/src/lauxlib.h b/src/lauxlib.h
index 80585f64..b0f66d68 100644
--- a/src/lauxlib.h
+++ b/src/lauxlib.h
@@ -76,6 +76,8 @@ LUALIB_API const char *(luaL_findtable) (lua_State *L, int idx,
76 const char *fname, int szhint); 76 const char *fname, int szhint);
77 77
78/* From Lua 5.2. */ 78/* From Lua 5.2. */
79LUALIB_API int luaL_fileresult(lua_State *L, int stat, const char *fname);
80LUALIB_API int luaL_execresult(lua_State *L, int stat);
79LUALIB_API int (luaL_loadfilex) (lua_State *L, const char *filename, 81LUALIB_API int (luaL_loadfilex) (lua_State *L, const char *filename,
80 const char *mode); 82 const char *mode);
81LUALIB_API int (luaL_loadbufferx) (lua_State *L, const char *buff, size_t sz, 83LUALIB_API int (luaL_loadbufferx) (lua_State *L, const char *buff, size_t sz,
diff --git a/src/lib_aux.c b/src/lib_aux.c
index 8fbee71b..4419fde9 100644
--- a/src/lib_aux.c
+++ b/src/lib_aux.c
@@ -19,8 +19,63 @@
19#include "lj_obj.h" 19#include "lj_obj.h"
20#include "lj_err.h" 20#include "lj_err.h"
21#include "lj_state.h" 21#include "lj_state.h"
22#include "lj_trace.h"
22#include "lj_lib.h" 23#include "lj_lib.h"
23 24
25#if LJ_TARGET_POSIX
26#include <sys/wait.h>
27#endif
28
29/* -- I/O error handling -------------------------------------------------- */
30
31LUALIB_API int luaL_fileresult(lua_State *L, int stat, const char *fname)
32{
33 if (stat) {
34 setboolV(L->top++, 1);
35 return 1;
36 } else {
37 int en = errno; /* Lua API calls may change this value. */
38 setnilV(L->top++);
39 if (fname)
40 lua_pushfstring(L, "%s: %s", fname, strerror(en));
41 else
42 lua_pushfstring(L, "%s", strerror(en));
43 setintV(L->top++, en);
44 lj_trace_abort(G(L));
45 return 3;
46 }
47}
48
49LUALIB_API int luaL_execresult(lua_State *L, int stat)
50{
51 if (stat != -1) {
52#if LJ_TARGET_POSIX
53 if (WIFSIGNALED(stat)) {
54 stat = WTERMSIG(stat);
55 setnilV(L->top++);
56 lua_pushliteral(L, "signal");
57 } else {
58 if (WIFEXITED(stat))
59 stat = WEXITSTATUS(stat);
60 if (stat == 0)
61 setboolV(L->top++, 1);
62 else
63 setnilV(L->top++);
64 lua_pushliteral(L, "exit");
65 }
66#else
67 if (stat == 0)
68 setboolV(L->top++, 1);
69 else
70 setnilV(L->top++);
71 lua_pushliteral(L, "exit");
72#endif
73 setintV(L->top++, stat);
74 return 3;
75 }
76 return luaL_fileresult(L, 0, NULL);
77}
78
24/* -- Module registration ------------------------------------------------- */ 79/* -- Module registration ------------------------------------------------- */
25 80
26LUALIB_API const char *luaL_findtable(lua_State *L, int idx, 81LUALIB_API const char *luaL_findtable(lua_State *L, int idx,
diff --git a/src/lib_io.c b/src/lib_io.c
index ad99b9b7..142bfae5 100644
--- a/src/lib_io.c
+++ b/src/lib_io.c
@@ -17,11 +17,9 @@
17#include "lualib.h" 17#include "lualib.h"
18 18
19#include "lj_obj.h" 19#include "lj_obj.h"
20#include "lj_gc.h"
21#include "lj_err.h" 20#include "lj_err.h"
22#include "lj_str.h" 21#include "lj_str.h"
23#include "lj_ff.h" 22#include "lj_ff.h"
24#include "lj_trace.h"
25#include "lj_lib.h" 23#include "lj_lib.h"
26 24
27/* Userdata payload for I/O file. */ 25/* Userdata payload for I/O file. */
@@ -40,26 +38,6 @@ typedef struct IOFileUD {
40#define IOSTDF_UD(L, id) (&gcref(G(L)->gcroot[(id)])->ud) 38#define IOSTDF_UD(L, id) (&gcref(G(L)->gcroot[(id)])->ud)
41#define IOSTDF_IOF(L, id) ((IOFileUD *)uddata(IOSTDF_UD(L, (id)))) 39#define IOSTDF_IOF(L, id) ((IOFileUD *)uddata(IOSTDF_UD(L, (id))))
42 40
43/* -- Error handling ------------------------------------------------------ */
44
45static int io_pushresult(lua_State *L, int ok, const char *fname)
46{
47 if (ok) {
48 setboolV(L->top++, 1);
49 return 1;
50 } else {
51 int en = errno; /* Lua API calls may change this value. */
52 setnilV(L->top++);
53 if (fname)
54 lua_pushfstring(L, "%s: %s", fname, strerror(en));
55 else
56 lua_pushfstring(L, "%s", strerror(en));
57 setintV(L->top++, en);
58 lj_trace_abort(G(L));
59 return 3;
60 }
61}
62
63/* -- Open/close helpers -------------------------------------------------- */ 41/* -- Open/close helpers -------------------------------------------------- */
64 42
65static IOFileUD *io_tofilep(lua_State *L) 43static IOFileUD *io_tofilep(lua_State *L)
@@ -114,12 +92,20 @@ static int io_file_close(lua_State *L, IOFileUD *iof)
114 if ((iof->type & IOFILE_TYPE_MASK) == IOFILE_TYPE_FILE) { 92 if ((iof->type & IOFILE_TYPE_MASK) == IOFILE_TYPE_FILE) {
115 ok = (fclose(iof->fp) == 0); 93 ok = (fclose(iof->fp) == 0);
116 } else if ((iof->type & IOFILE_TYPE_MASK) == IOFILE_TYPE_PIPE) { 94 } else if ((iof->type & IOFILE_TYPE_MASK) == IOFILE_TYPE_PIPE) {
95 int stat = -1;
117#if LJ_TARGET_POSIX 96#if LJ_TARGET_POSIX
118 ok = (pclose(iof->fp) != -1); 97 stat = pclose(iof->fp);
119#elif LJ_TARGET_WINDOWS 98#elif LJ_TARGET_WINDOWS
120 ok = (_pclose(iof->fp) != -1); 99 stat = _pclose(iof->fp);
100#else
101 lua_assert(0);
102 return 0;
103#endif
104#if LJ_52
105 iof->fp = NULL;
106 return luaL_execresult(L, stat);
121#else 107#else
122 ok = 0; 108 ok = (stat != -1);
123#endif 109#endif
124 } else { 110 } else {
125 lua_assert((iof->type & IOFILE_TYPE_MASK) == IOFILE_TYPE_STDF); 111 lua_assert((iof->type & IOFILE_TYPE_MASK) == IOFILE_TYPE_STDF);
@@ -128,7 +114,7 @@ static int io_file_close(lua_State *L, IOFileUD *iof)
128 return 2; 114 return 2;
129 } 115 }
130 iof->fp = NULL; 116 iof->fp = NULL;
131 return io_pushresult(L, ok, NULL); 117 return luaL_fileresult(L, ok, NULL);
132} 118}
133 119
134/* -- Read/write helpers -------------------------------------------------- */ 120/* -- Read/write helpers -------------------------------------------------- */
@@ -233,7 +219,7 @@ static int io_file_read(lua_State *L, FILE *fp, int start)
233 } 219 }
234 } 220 }
235 if (ferror(fp)) 221 if (ferror(fp))
236 return io_pushresult(L, 0, NULL); 222 return luaL_fileresult(L, 0, NULL);
237 if (!ok) 223 if (!ok)
238 setnilV(L->top-1); /* Replace last result with nil. */ 224 setnilV(L->top-1); /* Replace last result with nil. */
239 return n - start; 225 return n - start;
@@ -258,7 +244,7 @@ static int io_file_write(lua_State *L, FILE *fp, int start)
258 lj_err_argt(L, (int)(tv - L->base) + 1, LUA_TSTRING); 244 lj_err_argt(L, (int)(tv - L->base) + 1, LUA_TSTRING);
259 } 245 }
260 } 246 }
261 return io_pushresult(L, status, NULL); 247 return luaL_fileresult(L, status, NULL);
262} 248}
263 249
264/* -- I/O file methods ---------------------------------------------------- */ 250/* -- I/O file methods ---------------------------------------------------- */
@@ -284,7 +270,7 @@ LJLIB_CF(io_method_write) LJLIB_REC(io_write 0)
284 270
285LJLIB_CF(io_method_flush) LJLIB_REC(io_flush 0) 271LJLIB_CF(io_method_flush) LJLIB_REC(io_flush 0)
286{ 272{
287 return io_pushresult(L, fflush(io_tofile(L)->fp) == 0, NULL); 273 return luaL_fileresult(L, fflush(io_tofile(L)->fp) == 0, NULL);
288} 274}
289 275
290LJLIB_CF(io_method_seek) 276LJLIB_CF(io_method_seek)
@@ -316,7 +302,7 @@ LJLIB_CF(io_method_seek)
316 res = fseek(fp, (long)ofs, opt); 302 res = fseek(fp, (long)ofs, opt);
317#endif 303#endif
318 if (res) 304 if (res)
319 return io_pushresult(L, 0, NULL); 305 return luaL_fileresult(L, 0, NULL);
320#if LJ_TARGET_POSIX 306#if LJ_TARGET_POSIX
321 ofs = ftello(fp); 307 ofs = ftello(fp);
322#elif _MSC_VER >= 1400 308#elif _MSC_VER >= 1400
@@ -338,7 +324,7 @@ LJLIB_CF(io_method_setvbuf)
338 if (opt == 0) opt = _IOFBF; 324 if (opt == 0) opt = _IOFBF;
339 else if (opt == 1) opt = _IOLBF; 325 else if (opt == 1) opt = _IOLBF;
340 else if (opt == 2) opt = _IONBF; 326 else if (opt == 2) opt = _IONBF;
341 return io_pushresult(L, setvbuf(fp, NULL, opt, sz) == 0, NULL); 327 return luaL_fileresult(L, setvbuf(fp, NULL, opt, sz) == 0, NULL);
342} 328}
343 329
344LJLIB_PUSH(top-2) /* io_lines_iter */ 330LJLIB_PUSH(top-2) /* io_lines_iter */
@@ -386,7 +372,7 @@ LJLIB_CF(io_open)
386 const char *mode = s ? strdata(s) : "r"; 372 const char *mode = s ? strdata(s) : "r";
387 IOFileUD *iof = io_file_new(L); 373 IOFileUD *iof = io_file_new(L);
388 iof->fp = fopen(fname, mode); 374 iof->fp = fopen(fname, mode);
389 return iof->fp != NULL ? 1 : io_pushresult(L, 0, fname); 375 return iof->fp != NULL ? 1 : luaL_fileresult(L, 0, fname);
390} 376}
391 377
392LJLIB_CF(io_popen) 378LJLIB_CF(io_popen)
@@ -403,7 +389,7 @@ LJLIB_CF(io_popen)
403#else 389#else
404 iof->fp = _popen(fname, mode); 390 iof->fp = _popen(fname, mode);
405#endif 391#endif
406 return iof->fp != NULL ? 1 : io_pushresult(L, 0, fname); 392 return iof->fp != NULL ? 1 : luaL_fileresult(L, 0, fname);
407#else 393#else
408 return luaL_error(L, LUA_QL("popen") " not supported"); 394 return luaL_error(L, LUA_QL("popen") " not supported");
409#endif 395#endif
@@ -417,7 +403,7 @@ LJLIB_CF(io_tmpfile)
417#else 403#else
418 iof->fp = tmpfile(); 404 iof->fp = tmpfile();
419#endif 405#endif
420 return iof->fp != NULL ? 1 : io_pushresult(L, 0, NULL); 406 return iof->fp != NULL ? 1 : luaL_fileresult(L, 0, NULL);
421} 407}
422 408
423LJLIB_CF(io_close) 409LJLIB_CF(io_close)
@@ -437,7 +423,7 @@ LJLIB_CF(io_write) LJLIB_REC(io_write GCROOT_IO_OUTPUT)
437 423
438LJLIB_CF(io_flush) LJLIB_REC(io_flush GCROOT_IO_OUTPUT) 424LJLIB_CF(io_flush) LJLIB_REC(io_flush GCROOT_IO_OUTPUT)
439{ 425{
440 return io_pushresult(L, fflush(io_stdfile(L, GCROOT_IO_OUTPUT)) == 0, NULL); 426 return luaL_fileresult(L, fflush(io_stdfile(L, GCROOT_IO_OUTPUT)) == 0, NULL);
441} 427}
442 428
443static int io_std_getset(lua_State *L, ptrdiff_t id, const char *mode) 429static int io_std_getset(lua_State *L, ptrdiff_t id, const char *mode)
diff --git a/src/lib_os.c b/src/lib_os.c
index 2412d47b..21774975 100644
--- a/src/lib_os.c
+++ b/src/lib_os.c
@@ -31,41 +31,41 @@
31 31
32#define LJLIB_MODULE_os 32#define LJLIB_MODULE_os
33 33
34static int os_pushresult(lua_State *L, int i, const char *filename)
35{
36 int en = errno; /* calls to Lua API may change this value */
37 if (i) {
38 setboolV(L->top-1, 1);
39 return 1;
40 } else {
41 setnilV(L->top-1);
42 lua_pushfstring(L, "%s: %s", filename, strerror(en));
43 lua_pushinteger(L, en);
44 return 3;
45 }
46}
47
48LJLIB_CF(os_execute) 34LJLIB_CF(os_execute)
49{ 35{
50#if LJ_TARGET_CONSOLE 36#if LJ_TARGET_CONSOLE
37#if LJ_52
38 errno = ENOSYS;
39 return luaL_fileresult(L, 0, NULL);
40#else
51 lua_pushinteger(L, -1); 41 lua_pushinteger(L, -1);
42 return 1;
43#endif
52#else 44#else
53 lua_pushinteger(L, system(luaL_optstring(L, 1, NULL))); 45 const char *cmd = luaL_optstring(L, 1, NULL);
46 int stat = system(cmd);
47#if LJ_52
48 if (cmd)
49 return luaL_execresult(L, stat);
50 setboolV(L->top++, 1);
51#else
52 setintV(L->top++, stat);
54#endif 53#endif
55 return 1; 54 return 1;
55#endif
56} 56}
57 57
58LJLIB_CF(os_remove) 58LJLIB_CF(os_remove)
59{ 59{
60 const char *filename = luaL_checkstring(L, 1); 60 const char *filename = luaL_checkstring(L, 1);
61 return os_pushresult(L, remove(filename) == 0, filename); 61 return luaL_fileresult(L, remove(filename) == 0, filename);
62} 62}
63 63
64LJLIB_CF(os_rename) 64LJLIB_CF(os_rename)
65{ 65{
66 const char *fromname = luaL_checkstring(L, 1); 66 const char *fromname = luaL_checkstring(L, 1);
67 const char *toname = luaL_checkstring(L, 2); 67 const char *toname = luaL_checkstring(L, 2);
68 return os_pushresult(L, rename(fromname, toname) == 0, fromname); 68 return luaL_fileresult(L, rename(fromname, toname) == 0, fromname);
69} 69}
70 70
71LJLIB_CF(os_tmpname) 71LJLIB_CF(os_tmpname)