2 ** $Id: liolib.c,v 2.73 2006/05/08 20:14:16 roberto Exp $
3 ** Standard I/O (and system) library
4 ** See Copyright Notice in lua.h
27 static const char *const fnames
[] = {"input", "output"};
30 static int pushresult (lua_State
*L
, int i
, const char *filename
) {
31 int en
= errno
; /* calls to Lua API may change this value */
33 lua_pushboolean(L
, 1);
39 lua_pushfstring(L
, "%s: %s", filename
, strerror(en
));
41 lua_pushfstring(L
, "%s", strerror(en
));
42 lua_pushinteger(L
, en
);
48 static void fileerror (lua_State
*L
, int arg
, const char *filename
) {
49 lua_pushfstring(L
, "%s: %s", filename
, strerror(errno
));
50 luaL_argerror(L
, arg
, lua_tostring(L
, -1));
54 #define topfile(L) ((FILE **)luaL_checkudata(L, 1, LUA_FILEHANDLE))
57 static int io_type (lua_State
*L
) {
60 ud
= lua_touserdata(L
, 1);
61 lua_getfield(L
, LUA_REGISTRYINDEX
, LUA_FILEHANDLE
);
62 if (ud
== NULL
|| !lua_getmetatable(L
, 1) || !lua_rawequal(L
, -2, -1))
63 lua_pushnil(L
); /* not a file */
64 else if (*((FILE **)ud
) == NULL
)
65 lua_pushliteral(L
, "closed file");
67 lua_pushliteral(L
, "file");
72 static FILE *tofile (lua_State
*L
) {
73 FILE **f
= topfile(L
);
75 luaL_error(L
, "attempt to use a closed file");
82 ** When creating file handles, always creates a `closed' file handle
83 ** before opening the actual file; so, if there is a memory error, the
84 ** file is not left opened.
86 static FILE **newfile (lua_State
*L
) {
87 FILE **pf
= (FILE **)lua_newuserdata(L
, sizeof(FILE *));
88 *pf
= NULL
; /* file handle is currently `closed' */
89 luaL_getmetatable(L
, LUA_FILEHANDLE
);
90 lua_setmetatable(L
, -2);
96 ** this function has a separated environment, which defines the
97 ** correct __close for 'popen' files
99 static int io_pclose (lua_State
*L
) {
100 FILE **p
= topfile(L
);
101 int ok
= lua_pclose(L
, *p
);
103 return pushresult(L
, ok
, NULL
);
107 static int io_fclose (lua_State
*L
) {
108 FILE **p
= topfile(L
);
109 int ok
= (fclose(*p
) == 0);
111 return pushresult(L
, ok
, NULL
);
115 static int aux_close (lua_State
*L
) {
117 lua_getfield(L
, -1, "__close");
118 return (lua_tocfunction(L
, -1))(L
);
122 static int io_close (lua_State
*L
) {
123 if (lua_isnone(L
, 1))
124 lua_rawgeti(L
, LUA_ENVIRONINDEX
, IO_OUTPUT
);
125 tofile(L
); /* make sure argument is a file */
130 static int io_gc (lua_State
*L
) {
131 FILE *f
= *topfile(L
);
132 /* ignore closed files and standard files */
133 if (f
!= NULL
&& f
!= stdin
&& f
!= stdout
&& f
!= stderr
)
139 static int io_tostring (lua_State
*L
) {
140 FILE *f
= *topfile(L
);
142 lua_pushstring(L
, "file (closed)");
144 lua_pushfstring(L
, "file (%p)", f
);
149 static int io_open (lua_State
*L
) {
150 const char *filename
= luaL_checkstring(L
, 1);
151 const char *mode
= luaL_optstring(L
, 2, "r");
152 FILE **pf
= newfile(L
);
153 *pf
= fopen(filename
, mode
);
154 return (*pf
== NULL
) ? pushresult(L
, 0, filename
) : 1;
158 static int io_popen (lua_State
*L
) {
159 const char *filename
= luaL_checkstring(L
, 1);
160 const char *mode
= luaL_optstring(L
, 2, "r");
161 FILE **pf
= newfile(L
);
162 *pf
= lua_popen(L
, filename
, mode
);
163 return (*pf
== NULL
) ? pushresult(L
, 0, filename
) : 1;
167 static int io_tmpfile (lua_State
*L
) {
168 FILE **pf
= newfile(L
);
170 return (*pf
== NULL
) ? pushresult(L
, 0, NULL
) : 1;
174 static FILE *getiofile (lua_State
*L
, int findex
) {
176 lua_rawgeti(L
, LUA_ENVIRONINDEX
, findex
);
177 f
= *(FILE **)lua_touserdata(L
, -1);
179 luaL_error(L
, "standard %s file is closed", fnames
[findex
- 1]);
184 static int g_iofile (lua_State
*L
, int f
, const char *mode
) {
185 if (!lua_isnoneornil(L
, 1)) {
186 const char *filename
= lua_tostring(L
, 1);
188 FILE **pf
= newfile(L
);
189 *pf
= fopen(filename
, mode
);
191 fileerror(L
, 1, filename
);
194 tofile(L
); /* check that it's a valid file handle */
197 lua_rawseti(L
, LUA_ENVIRONINDEX
, f
);
199 /* return current value */
200 lua_rawgeti(L
, LUA_ENVIRONINDEX
, f
);
205 static int io_input (lua_State
*L
) {
206 return g_iofile(L
, IO_INPUT
, "r");
210 static int io_output (lua_State
*L
) {
211 return g_iofile(L
, IO_OUTPUT
, "w");
215 static int io_readline (lua_State
*L
);
218 static void aux_lines (lua_State
*L
, int idx
, int toclose
) {
219 lua_pushvalue(L
, idx
);
220 lua_pushboolean(L
, toclose
); /* close/not close file when finished */
221 lua_pushcclosure(L
, io_readline
, 2);
225 static int f_lines (lua_State
*L
) {
226 tofile(L
); /* check that it's a valid file handle */
232 static int io_lines (lua_State
*L
) {
233 if (lua_isnoneornil(L
, 1)) { /* no arguments? */
234 /* will iterate over default input */
235 lua_rawgeti(L
, LUA_ENVIRONINDEX
, IO_INPUT
);
239 const char *filename
= luaL_checkstring(L
, 1);
240 FILE **pf
= newfile(L
);
241 *pf
= fopen(filename
, "r");
243 fileerror(L
, 1, filename
);
244 aux_lines(L
, lua_gettop(L
), 1);
251 ** {======================================================
253 ** =======================================================
257 static int read_number (lua_State
*L
, FILE *f
) {
259 if (fscanf(f
, LUA_NUMBER_SCAN
, &d
) == 1) {
260 lua_pushnumber(L
, d
);
263 else return 0; /* read fails */
267 static int test_eof (lua_State
*L
, FILE *f
) {
270 lua_pushlstring(L
, NULL
, 0);
275 static int read_line (lua_State
*L
, FILE *f
) {
277 luaL_buffinit(L
, &b
);
280 char *p
= luaL_prepbuffer(&b
);
281 if (fgets(p
, LUAL_BUFFERSIZE
, f
) == NULL
) { /* eof? */
282 luaL_pushresult(&b
); /* close buffer */
283 return (lua_strlen(L
, -1) > 0); /* check whether read something */
286 if (l
== 0 || p
[l
-1] != '\n')
289 luaL_addsize(&b
, l
- 1); /* do not include `eol' */
290 luaL_pushresult(&b
); /* close buffer */
291 return 1; /* read at least an `eol' */
297 static int read_chars (lua_State
*L
, FILE *f
, size_t n
) {
298 size_t rlen
; /* how much to read */
299 size_t nr
; /* number of chars actually read */
301 luaL_buffinit(L
, &b
);
302 rlen
= LUAL_BUFFERSIZE
; /* try to read that much each time */
304 char *p
= luaL_prepbuffer(&b
);
305 if (rlen
> n
) rlen
= n
; /* cannot read more than asked */
306 nr
= fread(p
, sizeof(char), rlen
, f
);
307 luaL_addsize(&b
, nr
);
308 n
-= nr
; /* still have to read `n' chars */
309 } while (n
> 0 && nr
== rlen
); /* until end of count or eof */
310 luaL_pushresult(&b
); /* close buffer */
311 return (n
== 0 || lua_strlen(L
, -1) > 0);
315 static int g_read (lua_State
*L
, FILE *f
, int first
) {
316 int nargs
= lua_gettop(L
) - 1;
320 if (nargs
== 0) { /* no arguments? */
321 success
= read_line(L
, f
);
322 n
= first
+1; /* to return 1 result */
324 else { /* ensure stack space for all results and for auxlib's buffer */
325 luaL_checkstack(L
, nargs
+LUA_MINSTACK
, "too many arguments");
327 for (n
= first
; nargs
-- && success
; n
++) {
328 if (lua_type(L
, n
) == LUA_TNUMBER
) {
329 size_t l
= (size_t)lua_tointeger(L
, n
);
330 success
= (l
== 0) ? test_eof(L
, f
) : read_chars(L
, f
, l
);
333 const char *p
= lua_tostring(L
, n
);
334 luaL_argcheck(L
, p
&& p
[0] == '*', n
, "invalid option");
336 case 'n': /* number */
337 success
= read_number(L
, f
);
340 success
= read_line(L
, f
);
343 read_chars(L
, f
, ~((size_t)0)); /* read MAX_SIZE_T chars */
344 success
= 1; /* always success */
347 return luaL_argerror(L
, n
, "invalid format");
353 return pushresult(L
, 0, NULL
);
355 lua_pop(L
, 1); /* remove last result */
356 lua_pushnil(L
); /* push nil instead */
362 static int io_read (lua_State
*L
) {
363 return g_read(L
, getiofile(L
, IO_INPUT
), 1);
367 static int f_read (lua_State
*L
) {
368 return g_read(L
, tofile(L
), 2);
372 static int io_readline (lua_State
*L
) {
373 FILE *f
= *(FILE **)lua_touserdata(L
, lua_upvalueindex(1));
375 if (f
== NULL
) /* file is already closed? */
376 luaL_error(L
, "file is already closed");
377 sucess
= read_line(L
, f
);
379 return luaL_error(L
, "%s", strerror(errno
));
380 if (sucess
) return 1;
382 if (lua_toboolean(L
, lua_upvalueindex(2))) { /* generator created file? */
384 lua_pushvalue(L
, lua_upvalueindex(1));
385 aux_close(L
); /* close it */
391 /* }====================================================== */
394 static int g_write (lua_State
*L
, FILE *f
, int arg
) {
395 int nargs
= lua_gettop(L
) - 1;
397 for (; nargs
--; arg
++) {
398 if (lua_type(L
, arg
) == LUA_TNUMBER
) {
399 /* optimization: could be done exactly as for strings */
401 fprintf(f
, LUA_NUMBER_FMT
, lua_tonumber(L
, arg
)) > 0;
405 const char *s
= luaL_checklstring(L
, arg
, &l
);
406 status
= status
&& (fwrite(s
, sizeof(char), l
, f
) == l
);
409 return pushresult(L
, status
, NULL
);
413 static int io_write (lua_State
*L
) {
414 return g_write(L
, getiofile(L
, IO_OUTPUT
), 1);
418 static int f_write (lua_State
*L
) {
419 return g_write(L
, tofile(L
), 2);
423 static int f_seek (lua_State
*L
) {
424 static const int mode
[] = {SEEK_SET
, SEEK_CUR
, SEEK_END
};
425 static const char *const modenames
[] = {"set", "cur", "end", NULL
};
427 int op
= luaL_checkoption(L
, 2, "cur", modenames
);
428 long offset
= luaL_optlong(L
, 3, 0);
429 op
= fseek(f
, offset
, mode
[op
]);
431 return pushresult(L
, 0, NULL
); /* error */
433 lua_pushinteger(L
, ftell(f
));
439 static int f_setvbuf (lua_State
*L
) {
440 static const int mode
[] = {_IONBF
, _IOFBF
, _IOLBF
};
441 static const char *const modenames
[] = {"no", "full", "line", NULL
};
443 int op
= luaL_checkoption(L
, 2, NULL
, modenames
);
444 lua_Integer sz
= luaL_optinteger(L
, 3, LUAL_BUFFERSIZE
);
445 int res
= setvbuf(f
, NULL
, mode
[op
], sz
);
446 return pushresult(L
, res
== 0, NULL
);
451 static int io_flush (lua_State
*L
) {
452 return pushresult(L
, fflush(getiofile(L
, IO_OUTPUT
)) == 0, NULL
);
456 static int f_flush (lua_State
*L
) {
457 return pushresult(L
, fflush(tofile(L
)) == 0, NULL
);
461 static const luaL_Reg iolib
[] = {
467 {"output", io_output
},
470 {"tmpfile", io_tmpfile
},
477 static const luaL_Reg flib
[] = {
483 {"setvbuf", f_setvbuf
},
486 {"__tostring", io_tostring
},
491 static void createmeta (lua_State
*L
) {
492 luaL_newmetatable(L
, LUA_FILEHANDLE
); /* create metatable for file handles */
493 lua_pushvalue(L
, -1); /* push metatable */
494 lua_setfield(L
, -2, "__index"); /* metatable.__index = metatable */
495 luaL_register(L
, NULL
, flib
); /* file methods */
499 static void createstdfile (lua_State
*L
, FILE *f
, int k
, const char *fname
) {
502 lua_pushvalue(L
, -1);
503 lua_rawseti(L
, LUA_ENVIRONINDEX
, k
);
505 lua_setfield(L
, -2, fname
);
509 LUALIB_API
int luaopen_io (lua_State
*L
) {
511 /* create (private) environment (with fields IO_INPUT, IO_OUTPUT, __close) */
512 lua_createtable(L
, 2, 1);
513 lua_replace(L
, LUA_ENVIRONINDEX
);
515 luaL_register(L
, LUA_IOLIBNAME
, iolib
);
516 /* create (and set) default files */
517 createstdfile(L
, stdin
, IO_INPUT
, "stdin");
518 createstdfile(L
, stdout
, IO_OUTPUT
, "stdout");
519 createstdfile(L
, stderr
, 0, "stderr");
520 /* create environment for 'popen' */
521 lua_getfield(L
, -1, "popen");
522 lua_createtable(L
, 0, 1);
523 lua_pushcfunction(L
, io_pclose
);
524 lua_setfield(L
, -2, "__close");
526 lua_pop(L
, 1); /* pop 'popen' */
527 /* set default close function */
528 lua_pushcfunction(L
, io_fclose
);
529 lua_setfield(L
, LUA_ENVIRONINDEX
, "__close");