aboutsummaryrefslogtreecommitdiff
path: root/src/lib_io.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib_io.c')
-rw-r--r--src/lib_io.c56
1 files changed, 21 insertions, 35 deletions
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)