Line data Source code
1 : /*
2 : ** $Id: liolib.c,v 2.112.1.1 2013/04/12 18:48:47 roberto Exp $
3 : ** Standard I/O (and system) library
4 : ** See Copyright Notice in lua.h
5 : */
6 :
7 :
8 : /*
9 : ** This definition must come before the inclusion of 'stdio.h'; it
10 : ** should not affect non-POSIX systems
11 : */
12 : #if !defined(_FILE_OFFSET_BITS)
13 : #define _LARGEFILE_SOURCE 1
14 : #define _FILE_OFFSET_BITS 64
15 : #endif
16 :
17 :
18 : #include <errno.h>
19 : #include <stdio.h>
20 : #include <stdlib.h>
21 : #include <string.h>
22 :
23 : #define liolib_c
24 : #define LUA_LIB
25 :
26 : #include "lua.h"
27 :
28 : #include "lauxlib.h"
29 : #include "lualib.h"
30 :
31 :
32 : #if !defined(lua_checkmode)
33 :
34 : /*
35 : ** Check whether 'mode' matches '[rwa]%+?b?'.
36 : ** Change this macro to accept other modes for 'fopen' besides
37 : ** the standard ones.
38 : */
39 : #define lua_checkmode(mode) \
40 : (*mode != '\0' && strchr("rwa", *(mode++)) != NULL && \
41 : (*mode != '+' || ++mode) && /* skip if char is '+' */ \
42 : (*mode != 'b' || ++mode) && /* skip if char is 'b' */ \
43 : (*mode == '\0'))
44 :
45 : #endif
46 :
47 : /*
48 : ** {======================================================
49 : ** lua_popen spawns a new process connected to the current
50 : ** one through the file streams.
51 : ** =======================================================
52 : */
53 :
54 : #if !defined(lua_popen) /* { */
55 :
56 : #if defined(LUA_USE_POPEN) /* { */
57 :
58 : #define lua_popen(L,c,m) ((void)L, fflush(NULL), popen(c,m))
59 : #define lua_pclose(L,file) ((void)L, pclose(file))
60 :
61 : #elif defined(LUA_WIN) /* }{ */
62 :
63 : #define lua_popen(L,c,m) ((void)L, _popen(c,m))
64 : #define lua_pclose(L,file) ((void)L, _pclose(file))
65 :
66 :
67 : #else /* }{ */
68 :
69 : #define lua_popen(L,c,m) ((void)((void)c, m), \
70 : luaL_error(L, LUA_QL("popen") " not supported"), (FILE*)0)
71 : #define lua_pclose(L,file) ((void)((void)L, file), -1)
72 :
73 :
74 : #endif /* } */
75 :
76 : #endif /* } */
77 :
78 : /* }====================================================== */
79 :
80 :
81 : /*
82 : ** {======================================================
83 : ** lua_fseek: configuration for longer offsets
84 : ** =======================================================
85 : */
86 :
87 : #if !defined(lua_fseek) && !defined(LUA_ANSI) /* { */
88 :
89 : #if defined(LUA_USE_POSIX) /* { */
90 :
91 : #define l_fseek(f,o,w) fseeko(f,o,w)
92 : #define l_ftell(f) ftello(f)
93 : #define l_seeknum off_t
94 :
95 : #elif defined(LUA_WIN) && !defined(_CRTIMP_TYPEINFO) \
96 : && defined(_MSC_VER) && (_MSC_VER >= 1400) /* }{ */
97 : /* Windows (but not DDK) and Visual C++ 2005 or higher */
98 :
99 : #define l_fseek(f,o,w) _fseeki64(f,o,w)
100 : #define l_ftell(f) _ftelli64(f)
101 : #define l_seeknum __int64
102 :
103 : #endif /* } */
104 :
105 : #endif /* } */
106 :
107 :
108 : #if !defined(l_fseek) /* default definitions */
109 : #define l_fseek(f,o,w) fseek(f,o,w)
110 : #define l_ftell(f) ftell(f)
111 : #define l_seeknum long
112 : #endif
113 :
114 : /* }====================================================== */
115 :
116 :
117 : #define IO_PREFIX "_IO_"
118 : #define IO_INPUT (IO_PREFIX "input")
119 : #define IO_OUTPUT (IO_PREFIX "output")
120 :
121 :
122 : typedef luaL_Stream LStream;
123 :
124 :
125 : #define tolstream(L) ((LStream *)luaL_checkudata(L, 1, LUA_FILEHANDLE))
126 :
127 : #define isclosed(p) ((p)->closef == NULL)
128 :
129 :
130 9 : static int io_type (lua_State *L) {
131 : LStream *p;
132 9 : luaL_checkany(L, 1);
133 9 : p = (LStream *)luaL_testudata(L, 1, LUA_FILEHANDLE);
134 9 : if (p == NULL)
135 1 : lua_pushnil(L); /* not a file */
136 8 : else if (isclosed(p))
137 2 : lua_pushliteral(L, "closed file");
138 : else
139 6 : lua_pushliteral(L, "file");
140 9 : return 1;
141 : }
142 :
143 :
144 12 : static int f_tostring (lua_State *L) {
145 12 : LStream *p = tolstream(L);
146 12 : if (isclosed(p))
147 2 : lua_pushliteral(L, "file (closed)");
148 : else
149 10 : lua_pushfstring(L, "file (%p)", p->f);
150 12 : return 1;
151 : }
152 :
153 :
154 267 : static FILE *tofile (lua_State *L) {
155 267 : LStream *p = tolstream(L);
156 267 : if (isclosed(p))
157 6 : luaL_error(L, "attempt to use a closed file");
158 : lua_assert(p->f);
159 261 : return p->f;
160 : }
161 :
162 :
163 : /*
164 : ** When creating file handles, always creates a `closed' file handle
165 : ** before opening the actual file; so, if there is a memory error, the
166 : ** file is not left opened.
167 : */
168 384 : static LStream *newprefile (lua_State *L) {
169 384 : LStream *p = (LStream *)lua_newuserdata(L, sizeof(LStream));
170 384 : p->closef = NULL; /* mark file handle as 'closed' */
171 384 : luaL_setmetatable(L, LUA_FILEHANDLE);
172 384 : return p;
173 : }
174 :
175 :
176 356 : static int aux_close (lua_State *L) {
177 356 : LStream *p = tolstream(L);
178 356 : lua_CFunction cf = p->closef;
179 356 : p->closef = NULL; /* mark stream as closed */
180 356 : return (*cf)(L); /* close it */
181 : }
182 :
183 :
184 115 : static int io_close (lua_State *L) {
185 115 : if (lua_isnone(L, 1)) /* no argument? */
186 3 : lua_getfield(L, LUA_REGISTRYINDEX, IO_OUTPUT); /* use standard output */
187 115 : tofile(L); /* make sure argument is an open stream */
188 113 : return aux_close(L);
189 : }
190 :
191 :
192 357 : static int f_gc (lua_State *L) {
193 357 : LStream *p = tolstream(L);
194 357 : if (!isclosed(p) && p->f != NULL)
195 242 : aux_close(L); /* ignore closed and incompletely open files */
196 357 : return 0;
197 : }
198 :
199 :
200 : /*
201 : ** function to close regular files
202 : */
203 62 : static int io_fclose (lua_State *L) {
204 62 : LStream *p = tolstream(L);
205 62 : int res = fclose(p->f);
206 62 : return luaL_fileresult(L, (res == 0), NULL);
207 : }
208 :
209 :
210 66 : static LStream *newfile (lua_State *L) {
211 66 : LStream *p = newprefile(L);
212 66 : p->f = NULL;
213 66 : p->closef = &io_fclose;
214 66 : return p;
215 : }
216 :
217 :
218 5 : static void opencheck (lua_State *L, const char *fname, const char *mode) {
219 5 : LStream *p = newfile(L);
220 5 : p->f = fopen(fname, mode);
221 5 : if (p->f == NULL)
222 2 : luaL_error(L, "cannot open file " LUA_QS " (%s)", fname, strerror(errno));
223 3 : }
224 :
225 :
226 58 : static int io_open (lua_State *L) {
227 58 : const char *filename = luaL_checkstring(L, 1);
228 58 : const char *mode = luaL_optstring(L, 2, "r");
229 58 : LStream *p = newfile(L);
230 58 : const char *md = mode; /* to traverse/check mode */
231 58 : luaL_argcheck(L, lua_checkmode(md), 2, "invalid mode");
232 57 : p->f = fopen(filename, mode);
233 57 : return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1;
234 : }
235 :
236 :
237 : /*
238 : ** function to close 'popen' files
239 : */
240 60 : static int io_pclose (lua_State *L) {
241 60 : LStream *p = tolstream(L);
242 60 : return luaL_execresult(L, lua_pclose(L, p->f));
243 : }
244 :
245 :
246 60 : static int io_popen (lua_State *L) {
247 60 : const char *filename = luaL_checkstring(L, 1);
248 60 : const char *mode = luaL_optstring(L, 2, "r");
249 60 : LStream *p = newprefile(L);
250 60 : p->f = lua_popen(L, filename, mode);
251 60 : p->closef = &io_pclose;
252 60 : return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1;
253 : }
254 :
255 :
256 3 : static int io_tmpfile (lua_State *L) {
257 3 : LStream *p = newfile(L);
258 3 : p->f = tmpfile();
259 3 : return (p->f == NULL) ? luaL_fileresult(L, 0, NULL) : 1;
260 : }
261 :
262 :
263 8 : static FILE *getiofile (lua_State *L, const char *findex) {
264 : LStream *p;
265 8 : lua_getfield(L, LUA_REGISTRYINDEX, findex);
266 8 : p = (LStream *)lua_touserdata(L, -1);
267 8 : if (isclosed(p))
268 0 : luaL_error(L, "standard %s file is closed", findex + strlen(IO_PREFIX));
269 8 : return p->f;
270 : }
271 :
272 :
273 11 : static int g_iofile (lua_State *L, const char *f, const char *mode) {
274 11 : if (!lua_isnoneornil(L, 1)) {
275 7 : const char *filename = lua_tostring(L, 1);
276 7 : if (filename)
277 3 : opencheck(L, filename, mode);
278 : else {
279 4 : tofile(L); /* check that it's a valid file handle */
280 4 : lua_pushvalue(L, 1);
281 : }
282 6 : lua_setfield(L, LUA_REGISTRYINDEX, f);
283 : }
284 : /* return current value */
285 10 : lua_getfield(L, LUA_REGISTRYINDEX, f);
286 10 : return 1;
287 : }
288 :
289 :
290 6 : static int io_input (lua_State *L) {
291 6 : return g_iofile(L, IO_INPUT, "r");
292 : }
293 :
294 :
295 5 : static int io_output (lua_State *L) {
296 5 : return g_iofile(L, IO_OUTPUT, "w");
297 : }
298 :
299 :
300 : static int io_readline (lua_State *L);
301 :
302 :
303 8 : static void aux_lines (lua_State *L, int toclose) {
304 : int i;
305 8 : int n = lua_gettop(L) - 1; /* number of arguments to read */
306 : /* ensure that arguments will fit here and into 'io_readline' stack */
307 8 : luaL_argcheck(L, n <= LUA_MINSTACK - 3, LUA_MINSTACK - 3, "too many options");
308 8 : lua_pushvalue(L, 1); /* file handle */
309 8 : lua_pushinteger(L, n); /* number of arguments to read */
310 8 : lua_pushboolean(L, toclose); /* close/not close file when finished */
311 9 : for (i = 1; i <= n; i++) lua_pushvalue(L, i + 1); /* copy arguments */
312 8 : lua_pushcclosure(L, io_readline, 3 + n);
313 8 : }
314 :
315 :
316 5 : static int f_lines (lua_State *L) {
317 5 : tofile(L); /* check that it's a valid file handle */
318 5 : aux_lines(L, 0);
319 5 : return 1;
320 : }
321 :
322 :
323 4 : static int io_lines (lua_State *L) {
324 : int toclose;
325 4 : if (lua_isnone(L, 1)) lua_pushnil(L); /* at least one argument */
326 4 : if (lua_isnil(L, 1)) { /* no file name? */
327 2 : lua_getfield(L, LUA_REGISTRYINDEX, IO_INPUT); /* get default input */
328 2 : lua_replace(L, 1); /* put it at index 1 */
329 2 : tofile(L); /* check that it's a valid file handle */
330 2 : toclose = 0; /* do not close it after iteration */
331 : }
332 : else { /* open a new file */
333 2 : const char *filename = luaL_checkstring(L, 1);
334 2 : opencheck(L, filename, "r");
335 1 : lua_replace(L, 1); /* put file at index 1 */
336 1 : toclose = 1; /* close it after iteration */
337 : }
338 3 : aux_lines(L, toclose);
339 3 : return 1;
340 : }
341 :
342 :
343 : /*
344 : ** {======================================================
345 : ** READ
346 : ** =======================================================
347 : */
348 :
349 :
350 14 : static int read_number (lua_State *L, FILE *f) {
351 : lua_Number d;
352 14 : if (fscanf(f, LUA_NUMBER_SCAN, &d) == 1) {
353 12 : lua_pushnumber(L, d);
354 12 : return 1;
355 : }
356 : else {
357 2 : lua_pushnil(L); /* "result" to be removed */
358 2 : return 0; /* read fails */
359 : }
360 : }
361 :
362 :
363 1 : static int test_eof (lua_State *L, FILE *f) {
364 1 : int c = getc(f);
365 1 : ungetc(c, f);
366 1 : lua_pushlstring(L, NULL, 0);
367 1 : return (c != EOF);
368 : }
369 :
370 :
371 261 : static int read_line (lua_State *L, FILE *f, int chop) {
372 : luaL_Buffer b;
373 261 : luaL_buffinit(L, &b);
374 0 : for (;;) {
375 : size_t l;
376 261 : char *p = luaL_prepbuffer(&b);
377 261 : if (fgets(p, LUAL_BUFFERSIZE, f) == NULL) { /* eof? */
378 17 : luaL_pushresult(&b); /* close buffer */
379 17 : return (lua_rawlen(L, -1) > 0); /* check whether read something */
380 : }
381 244 : l = strlen(p);
382 244 : if (l == 0 || p[l-1] != '\n')
383 0 : luaL_addsize(&b, l);
384 : else {
385 244 : luaL_addsize(&b, l - chop); /* chop 'eol' if needed */
386 244 : luaL_pushresult(&b); /* close buffer */
387 244 : return 1; /* read at least an `eol' */
388 : }
389 : }
390 : }
391 :
392 :
393 : #define MAX_SIZE_T (~(size_t)0)
394 :
395 1 : static void read_all (lua_State *L, FILE *f) {
396 1 : size_t rlen = LUAL_BUFFERSIZE; /* how much to read in each cycle */
397 : luaL_Buffer b;
398 1 : luaL_buffinit(L, &b);
399 0 : for (;;) {
400 1 : char *p = luaL_prepbuffsize(&b, rlen);
401 1 : size_t nr = fread(p, sizeof(char), rlen, f);
402 1 : luaL_addsize(&b, nr);
403 1 : if (nr < rlen) break; /* eof? */
404 0 : else if (rlen <= (MAX_SIZE_T / 4)) /* avoid buffers too large */
405 0 : rlen *= 2; /* double buffer size at each iteration */
406 : }
407 1 : luaL_pushresult(&b); /* close buffer */
408 1 : }
409 :
410 :
411 4 : static int read_chars (lua_State *L, FILE *f, size_t n) {
412 : size_t nr; /* number of chars actually read */
413 : char *p;
414 : luaL_Buffer b;
415 4 : luaL_buffinit(L, &b);
416 4 : p = luaL_prepbuffsize(&b, n); /* prepare buffer to read whole block */
417 4 : nr = fread(p, sizeof(char), n, f); /* try to read 'n' chars */
418 4 : luaL_addsize(&b, nr);
419 4 : luaL_pushresult(&b); /* close buffer */
420 4 : return (nr > 0); /* true iff read something */
421 : }
422 :
423 :
424 273 : static int g_read (lua_State *L, FILE *f, int first) {
425 273 : int nargs = lua_gettop(L) - 1;
426 : int success;
427 : int n;
428 273 : clearerr(f);
429 273 : if (nargs == 0) { /* no arguments? */
430 176 : success = read_line(L, f, 1);
431 176 : n = first+1; /* to return 1 result */
432 : }
433 : else { /* ensure stack space for all results and for auxlib's buffer */
434 97 : luaL_checkstack(L, nargs+LUA_MINSTACK, "too many arguments");
435 97 : success = 1;
436 202 : for (n = first; nargs-- && success; n++) {
437 106 : if (lua_type(L, n) == LUA_TNUMBER) {
438 5 : size_t l = (size_t)lua_tointeger(L, n);
439 5 : success = (l == 0) ? test_eof(L, f) : read_chars(L, f, l);
440 : }
441 : else {
442 101 : const char *p = lua_tostring(L, n);
443 101 : luaL_argcheck(L, p && p[0] == '*', n, "invalid option");
444 101 : switch (p[1]) {
445 14 : case 'n': /* number */
446 14 : success = read_number(L, f);
447 14 : break;
448 83 : case 'l': /* line */
449 83 : success = read_line(L, f, 1);
450 83 : break;
451 2 : case 'L': /* line with end-of-line */
452 2 : success = read_line(L, f, 0);
453 2 : break;
454 1 : case 'a': /* file */
455 1 : read_all(L, f); /* read entire file */
456 1 : success = 1; /* always success */
457 1 : break;
458 1 : default:
459 1 : return luaL_argerror(L, n, "invalid format");
460 : }
461 : }
462 : }
463 : }
464 272 : if (ferror(f))
465 0 : return luaL_fileresult(L, 0, NULL);
466 272 : if (!success) {
467 19 : lua_pop(L, 1); /* remove last result */
468 19 : lua_pushnil(L); /* push nil instead */
469 : }
470 272 : return n - first;
471 : }
472 :
473 :
474 5 : static int io_read (lua_State *L) {
475 5 : return g_read(L, getiofile(L, IO_INPUT), 1);
476 : }
477 :
478 :
479 95 : static int f_read (lua_State *L) {
480 95 : return g_read(L, tofile(L), 2);
481 : }
482 :
483 :
484 174 : static int io_readline (lua_State *L) {
485 174 : LStream *p = (LStream *)lua_touserdata(L, lua_upvalueindex(1));
486 : int i;
487 174 : int n = (int)lua_tointeger(L, lua_upvalueindex(2));
488 174 : if (isclosed(p)) /* file is already closed? */
489 0 : return luaL_error(L, "file is already closed");
490 174 : lua_settop(L , 1);
491 175 : for (i = 1; i <= n; i++) /* push arguments to 'g_read' */
492 1 : lua_pushvalue(L, lua_upvalueindex(3 + i));
493 174 : n = g_read(L, p->f, 2); /* 'n' is number of results */
494 : lua_assert(n > 0); /* should return at least a nil */
495 174 : if (!lua_isnil(L, -n)) /* read at least one value? */
496 170 : return n; /* return them */
497 : else { /* first result is nil: EOF or error */
498 4 : if (n > 1) { /* is there error information? */
499 : /* 2nd result is error message */
500 0 : return luaL_error(L, "%s", lua_tostring(L, -n + 1));
501 : }
502 4 : if (lua_toboolean(L, lua_upvalueindex(3))) { /* generator created file? */
503 1 : lua_settop(L, 0);
504 1 : lua_pushvalue(L, lua_upvalueindex(1));
505 1 : aux_close(L); /* close it */
506 : }
507 4 : return 0;
508 : }
509 : }
510 :
511 : /* }====================================================== */
512 :
513 :
514 39 : static int g_write (lua_State *L, FILE *f, int arg) {
515 39 : int nargs = lua_gettop(L) - arg;
516 39 : int status = 1;
517 79 : for (; nargs--; arg++) {
518 40 : if (lua_type(L, arg) == LUA_TNUMBER) {
519 : /* optimization: could be done exactly as for strings */
520 2 : status = status &&
521 1 : fprintf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0;
522 : }
523 : else {
524 : size_t l;
525 39 : const char *s = luaL_checklstring(L, arg, &l);
526 39 : status = status && (fwrite(s, sizeof(char), l, f) == l);
527 : }
528 : }
529 39 : if (status) return 1; /* file handle already on stack top */
530 0 : else return luaL_fileresult(L, status, NULL);
531 : }
532 :
533 :
534 2 : static int io_write (lua_State *L) {
535 2 : return g_write(L, getiofile(L, IO_OUTPUT), 1);
536 : }
537 :
538 :
539 38 : static int f_write (lua_State *L) {
540 38 : FILE *f = tofile(L);
541 37 : lua_pushvalue(L, 1); /* push file at the stack top (to be returned) */
542 37 : return g_write(L, f, 2);
543 : }
544 :
545 :
546 3 : static int f_seek (lua_State *L) {
547 : static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END};
548 : static const char *const modenames[] = {"set", "cur", "end", NULL};
549 3 : FILE *f = tofile(L);
550 2 : int op = luaL_checkoption(L, 2, "cur", modenames);
551 1 : lua_Number p3 = luaL_optnumber(L, 3, 0);
552 1 : l_seeknum offset = (l_seeknum)p3;
553 1 : luaL_argcheck(L, (lua_Number)offset == p3, 3,
554 : "not an integer in proper range");
555 1 : op = l_fseek(f, offset, mode[op]);
556 1 : if (op)
557 0 : return luaL_fileresult(L, 0, NULL); /* error */
558 : else {
559 1 : lua_pushnumber(L, (lua_Number)l_ftell(f));
560 1 : return 1;
561 : }
562 : }
563 :
564 :
565 3 : static int f_setvbuf (lua_State *L) {
566 : static const int mode[] = {_IONBF, _IOFBF, _IOLBF};
567 : static const char *const modenames[] = {"no", "full", "line", NULL};
568 3 : FILE *f = tofile(L);
569 3 : int op = luaL_checkoption(L, 2, NULL, modenames);
570 3 : lua_Integer sz = luaL_optinteger(L, 3, LUAL_BUFFERSIZE);
571 3 : int res = setvbuf(f, NULL, mode[op], sz);
572 3 : return luaL_fileresult(L, res == 0, NULL);
573 : }
574 :
575 :
576 :
577 1 : static int io_flush (lua_State *L) {
578 1 : return luaL_fileresult(L, fflush(getiofile(L, IO_OUTPUT)) == 0, NULL);
579 : }
580 :
581 :
582 2 : static int f_flush (lua_State *L) {
583 2 : return luaL_fileresult(L, fflush(tofile(L)) == 0, NULL);
584 : }
585 :
586 :
587 : /*
588 : ** functions for 'io' library
589 : */
590 : static const luaL_Reg iolib[] = {
591 : {"close", io_close},
592 : {"flush", io_flush},
593 : {"input", io_input},
594 : {"lines", io_lines},
595 : {"open", io_open},
596 : {"output", io_output},
597 : {"popen", io_popen},
598 : {"read", io_read},
599 : {"tmpfile", io_tmpfile},
600 : {"type", io_type},
601 : {"write", io_write},
602 : {NULL, NULL}
603 : };
604 :
605 :
606 : /*
607 : ** methods for file handles
608 : */
609 : static const luaL_Reg flib[] = {
610 : {"close", io_close},
611 : {"flush", f_flush},
612 : {"lines", f_lines},
613 : {"read", f_read},
614 : {"seek", f_seek},
615 : {"setvbuf", f_setvbuf},
616 : {"write", f_write},
617 : {"__gc", f_gc},
618 : {"__tostring", f_tostring},
619 : {NULL, NULL}
620 : };
621 :
622 :
623 86 : static void createmeta (lua_State *L) {
624 86 : luaL_newmetatable(L, LUA_FILEHANDLE); /* create metatable for file handles */
625 86 : lua_pushvalue(L, -1); /* push metatable */
626 86 : lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */
627 86 : luaL_setfuncs(L, flib, 0); /* add file methods to new metatable */
628 86 : lua_pop(L, 1); /* pop new metatable */
629 86 : }
630 :
631 :
632 : /*
633 : ** function to (not) close the standard files stdin, stdout, and stderr
634 : */
635 234 : static int io_noclose (lua_State *L) {
636 234 : LStream *p = tolstream(L);
637 234 : p->closef = &io_noclose; /* keep file opened */
638 234 : lua_pushnil(L);
639 234 : lua_pushliteral(L, "cannot close standard file");
640 234 : return 2;
641 : }
642 :
643 :
644 258 : static void createstdfile (lua_State *L, FILE *f, const char *k,
645 : const char *fname) {
646 258 : LStream *p = newprefile(L);
647 258 : p->f = f;
648 258 : p->closef = &io_noclose;
649 258 : if (k != NULL) {
650 172 : lua_pushvalue(L, -1);
651 172 : lua_setfield(L, LUA_REGISTRYINDEX, k); /* add file to registry */
652 : }
653 258 : lua_setfield(L, -2, fname); /* add file to module */
654 258 : }
655 :
656 :
657 86 : LUAMOD_API int luaopen_io (lua_State *L) {
658 86 : luaL_newlib(L, iolib); /* new module */
659 86 : createmeta(L);
660 : /* create (and set) default files */
661 86 : createstdfile(L, stdin, IO_INPUT, "stdin");
662 86 : createstdfile(L, stdout, IO_OUTPUT, "stdout");
663 86 : createstdfile(L, stderr, NULL, "stderr");
664 86 : return 1;
665 : }
666 :
|