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.c55
1 files changed, 27 insertions, 28 deletions
diff --git a/src/lib_io.c b/src/lib_io.c
index d5786e5d..a3278ab2 100644
--- a/src/lib_io.c
+++ b/src/lib_io.c
@@ -19,8 +19,10 @@
19#include "lj_obj.h" 19#include "lj_obj.h"
20#include "lj_gc.h" 20#include "lj_gc.h"
21#include "lj_err.h" 21#include "lj_err.h"
22#include "lj_buf.h"
22#include "lj_str.h" 23#include "lj_str.h"
23#include "lj_state.h" 24#include "lj_state.h"
25#include "lj_strfmt.h"
24#include "lj_ff.h" 26#include "lj_ff.h"
25#include "lj_lib.h" 27#include "lj_lib.h"
26 28
@@ -84,7 +86,7 @@ static IOFileUD *io_file_open(lua_State *L, const char *mode)
84 IOFileUD *iof = io_file_new(L); 86 IOFileUD *iof = io_file_new(L);
85 iof->fp = fopen(fname, mode); 87 iof->fp = fopen(fname, mode);
86 if (iof->fp == NULL) 88 if (iof->fp == NULL)
87 luaL_argerror(L, 1, lj_str_pushf(L, "%s: %s", fname, strerror(errno))); 89 luaL_argerror(L, 1, lj_strfmt_pushf(L, "%s: %s", fname, strerror(errno)));
88 return iof; 90 return iof;
89} 91}
90 92
@@ -97,11 +99,8 @@ static int io_file_close(lua_State *L, IOFileUD *iof)
97 int stat = -1; 99 int stat = -1;
98#if LJ_TARGET_POSIX 100#if LJ_TARGET_POSIX
99 stat = pclose(iof->fp); 101 stat = pclose(iof->fp);
100#elif LJ_TARGET_WINDOWS 102#elif LJ_TARGET_WINDOWS && !LJ_TARGET_XBOXONE && !LJ_TARGET_UWP
101 stat = _pclose(iof->fp); 103 stat = _pclose(iof->fp);
102#else
103 lua_assert(0);
104 return 0;
105#endif 104#endif
106#if LJ_52 105#if LJ_52
107 iof->fp = NULL; 106 iof->fp = NULL;
@@ -110,7 +109,8 @@ static int io_file_close(lua_State *L, IOFileUD *iof)
110 ok = (stat != -1); 109 ok = (stat != -1);
111#endif 110#endif
112 } else { 111 } else {
113 lua_assert((iof->type & IOFILE_TYPE_MASK) == IOFILE_TYPE_STDF); 112 lj_assertL((iof->type & IOFILE_TYPE_MASK) == IOFILE_TYPE_STDF,
113 "close of unknown FILE* type");
114 setnilV(L->top++); 114 setnilV(L->top++);
115 lua_pushliteral(L, "cannot close standard file"); 115 lua_pushliteral(L, "cannot close standard file");
116 return 2; 116 return 2;
@@ -145,7 +145,7 @@ static int io_file_readline(lua_State *L, FILE *fp, MSize chop)
145 MSize m = LUAL_BUFFERSIZE, n = 0, ok = 0; 145 MSize m = LUAL_BUFFERSIZE, n = 0, ok = 0;
146 char *buf; 146 char *buf;
147 for (;;) { 147 for (;;) {
148 buf = lj_str_needbuf(L, &G(L)->tmpbuf, m); 148 buf = lj_buf_tmp(L, m);
149 if (fgets(buf+n, m-n, fp) == NULL) break; 149 if (fgets(buf+n, m-n, fp) == NULL) break;
150 n += (MSize)strlen(buf+n); 150 n += (MSize)strlen(buf+n);
151 ok |= n; 151 ok |= n;
@@ -161,7 +161,7 @@ static void io_file_readall(lua_State *L, FILE *fp)
161{ 161{
162 MSize m, n; 162 MSize m, n;
163 for (m = LUAL_BUFFERSIZE, n = 0; ; m += m) { 163 for (m = LUAL_BUFFERSIZE, n = 0; ; m += m) {
164 char *buf = lj_str_needbuf(L, &G(L)->tmpbuf, m); 164 char *buf = lj_buf_tmp(L, m);
165 n += (MSize)fread(buf+n, 1, m-n, fp); 165 n += (MSize)fread(buf+n, 1, m-n, fp);
166 if (n != m) { 166 if (n != m) {
167 setstrV(L, L->top++, lj_str_new(L, buf, (size_t)n)); 167 setstrV(L, L->top++, lj_str_new(L, buf, (size_t)n));
@@ -174,7 +174,7 @@ static void io_file_readall(lua_State *L, FILE *fp)
174static int io_file_readlen(lua_State *L, FILE *fp, MSize m) 174static int io_file_readlen(lua_State *L, FILE *fp, MSize m)
175{ 175{
176 if (m) { 176 if (m) {
177 char *buf = lj_str_needbuf(L, &G(L)->tmpbuf, m); 177 char *buf = lj_buf_tmp(L, m);
178 MSize n = (MSize)fread(buf, 1, m, fp); 178 MSize n = (MSize)fread(buf, 1, m, fp);
179 setstrV(L, L->top++, lj_str_new(L, buf, (size_t)n)); 179 setstrV(L, L->top++, lj_str_new(L, buf, (size_t)n));
180 lj_gc_check(L); 180 lj_gc_check(L);
@@ -202,13 +202,12 @@ static int io_file_read(lua_State *L, IOFileUD *iof, int start)
202 for (n = start; nargs-- && ok; n++) { 202 for (n = start; nargs-- && ok; n++) {
203 if (tvisstr(L->base+n)) { 203 if (tvisstr(L->base+n)) {
204 const char *p = strVdata(L->base+n); 204 const char *p = strVdata(L->base+n);
205 if (p[0] != '*') 205 if (p[0] == '*') p++;
206 lj_err_arg(L, n+1, LJ_ERR_INVOPT); 206 if (p[0] == 'n')
207 if (p[1] == 'n')
208 ok = io_file_readnum(L, fp); 207 ok = io_file_readnum(L, fp);
209 else if ((p[1] & ~0x20) == 'L') 208 else if ((p[0] & ~0x20) == 'L')
210 ok = io_file_readline(L, fp, (p[1] == 'l')); 209 ok = io_file_readline(L, fp, (p[0] == 'l'));
211 else if (p[1] == 'a') 210 else if (p[0] == 'a')
212 io_file_readall(L, fp); 211 io_file_readall(L, fp);
213 else 212 else
214 lj_err_arg(L, n+1, LJ_ERR_INVFMT); 213 lj_err_arg(L, n+1, LJ_ERR_INVFMT);
@@ -232,19 +231,11 @@ static int io_file_write(lua_State *L, IOFileUD *iof, int start)
232 cTValue *tv; 231 cTValue *tv;
233 int status = 1; 232 int status = 1;
234 for (tv = L->base+start; tv < L->top; tv++) { 233 for (tv = L->base+start; tv < L->top; tv++) {
235 if (tvisstr(tv)) { 234 MSize len;
236 MSize len = strV(tv)->len; 235 const char *p = lj_strfmt_wstrnum(L, tv, &len);
237 status = status && (fwrite(strVdata(tv), 1, len, fp) == len); 236 if (!p)
238 } else if (tvisint(tv)) {
239 char buf[LJ_STR_INTBUF];
240 char *p = lj_str_bufint(buf, intV(tv));
241 size_t len = (size_t)(buf+LJ_STR_INTBUF-p);
242 status = status && (fwrite(p, 1, len, fp) == len);
243 } else if (tvisnum(tv)) {
244 status = status && (fprintf(fp, LUA_NUMBER_FMT, numV(tv)) > 0);
245 } else {
246 lj_err_argt(L, (int)(tv - L->base) + 1, LUA_TSTRING); 237 lj_err_argt(L, (int)(tv - L->base) + 1, LUA_TSTRING);
247 } 238 status = status && (fwrite(p, 1, len, fp) == len);
248 } 239 }
249 if (LJ_52 && status) { 240 if (LJ_52 && status) {
250 L->top = L->base+1; 241 L->top = L->base+1;
@@ -319,6 +310,14 @@ LJLIB_CF(io_method_flush) LJLIB_REC(io_flush 0)
319 return luaL_fileresult(L, fflush(io_tofile(L)->fp) == 0, NULL); 310 return luaL_fileresult(L, fflush(io_tofile(L)->fp) == 0, NULL);
320} 311}
321 312
313#if LJ_32 && defined(__ANDROID__) && __ANDROID_API__ < 24
314/* The Android NDK is such an unmatched marvel of engineering. */
315extern int fseeko32(FILE *, long int, int) __asm__("fseeko");
316extern long int ftello32(FILE *) __asm__("ftello");
317#define fseeko(fp, pos, whence) (fseeko32((fp), (pos), (whence)))
318#define ftello(fp) (ftello32((fp)))
319#endif
320
322LJLIB_CF(io_method_seek) 321LJLIB_CF(io_method_seek)
323{ 322{
324 FILE *fp = io_tofile(L)->fp; 323 FILE *fp = io_tofile(L)->fp;
@@ -419,7 +418,7 @@ LJLIB_CF(io_open)
419 418
420LJLIB_CF(io_popen) 419LJLIB_CF(io_popen)
421{ 420{
422#if LJ_TARGET_POSIX || LJ_TARGET_WINDOWS 421#if LJ_TARGET_POSIX || (LJ_TARGET_WINDOWS && !LJ_TARGET_XBOXONE && !LJ_TARGET_UWP)
423 const char *fname = strdata(lj_lib_checkstr(L, 1)); 422 const char *fname = strdata(lj_lib_checkstr(L, 1));
424 GCstr *s = lj_lib_optstr(L, 2); 423 GCstr *s = lj_lib_optstr(L, 2);
425 const char *mode = s ? strdata(s) : "r"; 424 const char *mode = s ? strdata(s) : "r";