diff options
| -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) |
