diff options
author | Mike Pall <mike> | 2012-09-24 19:00:54 +0200 |
---|---|---|
committer | Mike Pall <mike> | 2012-09-24 19:00:54 +0200 |
commit | cfca926cc2e2b63e94492f0a1f5c033f6db3a6f5 (patch) | |
tree | 4601d6b067fcea09b9e1368b998baa1b48de4866 | |
parent | 125cc879884b19ffa9181b7a52d1b7b73759301e (diff) | |
download | luajit-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.h | 2 | ||||
-rw-r--r-- | src/lib_aux.c | 55 | ||||
-rw-r--r-- | src/lib_io.c | 56 | ||||
-rw-r--r-- | src/lib_os.c | 34 |
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. */ |
79 | LUALIB_API int luaL_fileresult(lua_State *L, int stat, const char *fname); | ||
80 | LUALIB_API int luaL_execresult(lua_State *L, int stat); | ||
79 | LUALIB_API int (luaL_loadfilex) (lua_State *L, const char *filename, | 81 | LUALIB_API int (luaL_loadfilex) (lua_State *L, const char *filename, |
80 | const char *mode); | 82 | const char *mode); |
81 | LUALIB_API int (luaL_loadbufferx) (lua_State *L, const char *buff, size_t sz, | 83 | LUALIB_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 | |||
31 | LUALIB_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 | |||
49 | LUALIB_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 | ||
26 | LUALIB_API const char *luaL_findtable(lua_State *L, int idx, | 81 | LUALIB_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 | |||
45 | static 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 | ||
65 | static IOFileUD *io_tofilep(lua_State *L) | 43 | static 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 | ||
285 | LJLIB_CF(io_method_flush) LJLIB_REC(io_flush 0) | 271 | LJLIB_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 | ||
290 | LJLIB_CF(io_method_seek) | 276 | LJLIB_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 | ||
344 | LJLIB_PUSH(top-2) /* io_lines_iter */ | 330 | LJLIB_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 | ||
392 | LJLIB_CF(io_popen) | 378 | LJLIB_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 | ||
423 | LJLIB_CF(io_close) | 409 | LJLIB_CF(io_close) |
@@ -437,7 +423,7 @@ LJLIB_CF(io_write) LJLIB_REC(io_write GCROOT_IO_OUTPUT) | |||
437 | 423 | ||
438 | LJLIB_CF(io_flush) LJLIB_REC(io_flush GCROOT_IO_OUTPUT) | 424 | LJLIB_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 | ||
443 | static int io_std_getset(lua_State *L, ptrdiff_t id, const char *mode) | 429 | static 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 | ||
34 | static 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 | |||
48 | LJLIB_CF(os_execute) | 34 | LJLIB_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 | ||
58 | LJLIB_CF(os_remove) | 58 | LJLIB_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 | ||
64 | LJLIB_CF(os_rename) | 64 | LJLIB_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 | ||
71 | LJLIB_CF(os_tmpname) | 71 | LJLIB_CF(os_tmpname) |