diff options
Diffstat (limited to 'liolib.c')
| -rw-r--r-- | liolib.c | 97 |
1 files changed, 52 insertions, 45 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: liolib.c,v 1.35 1999/03/16 20:07:54 roberto Exp roberto $ | 2 | ** $Id: liolib.c,v 1.36 1999/03/26 13:48:26 roberto Exp roberto $ |
| 3 | ** Standard I/O (and system) library | 3 | ** Standard I/O (and system) library |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -32,21 +32,25 @@ | |||
| 32 | #endif | 32 | #endif |
| 33 | 33 | ||
| 34 | 34 | ||
| 35 | #define CLOSEDTAG(tag) ((tag)-1) | 35 | #define IOTAG 1 |
| 36 | |||
| 37 | #define FIRSTARG 2 /* 1st is upvalue */ | ||
| 38 | |||
| 39 | #define CLOSEDTAG(tag) ((tag)-1) /* assume that CLOSEDTAG = iotag-1 */ | ||
| 36 | 40 | ||
| 37 | 41 | ||
| 38 | #define FINPUT "_INPUT" | 42 | #define FINPUT "_INPUT" |
| 39 | #define FOUTPUT "_OUTPUT" | 43 | #define FOUTPUT "_OUTPUT" |
| 40 | 44 | ||
| 41 | #define MODESIZE 3 /* string for file mode */ | ||
| 42 | 45 | ||
| 43 | #ifdef POPEN | 46 | #ifdef POPEN |
| 44 | FILE *popen(); | 47 | FILE *popen(); |
| 45 | int pclose(); | 48 | int pclose(); |
| 49 | #define CLOSEFILE(f) {if (pclose(f) == -1) fclose(f);} | ||
| 46 | #else | 50 | #else |
| 47 | /* no support for popen */ | 51 | /* no support for popen */ |
| 48 | #define popen(x,y) NULL /* that is, popen always fails */ | 52 | #define popen(x,y) NULL /* that is, popen always fails */ |
| 49 | #define pclose(x) (-1) | 53 | #define CLOSEFILE(f) {fclose(f);} |
| 50 | #endif | 54 | #endif |
| 51 | 55 | ||
| 52 | 56 | ||
| @@ -69,8 +73,7 @@ static void pushresult (int i) { | |||
| 69 | */ | 73 | */ |
| 70 | 74 | ||
| 71 | static int gettag (void) { | 75 | static int gettag (void) { |
| 72 | lua_pushusertag(stdin, LUA_ANYTAG); | 76 | return (int)lua_getnumber(lua_getparam(IOTAG)); |
| 73 | return lua_tag(lua_pop()); /* get the tag of stdin */ | ||
| 74 | } | 77 | } |
| 75 | 78 | ||
| 76 | 79 | ||
| @@ -117,17 +120,10 @@ static FILE *getfileparam (char *name, int *arg) { | |||
| 117 | } | 120 | } |
| 118 | 121 | ||
| 119 | 122 | ||
| 120 | static void rawclose (FILE *f) { | ||
| 121 | if (f != stdin && f != stdout) { | ||
| 122 | if (pclose(f) == -1) fclose(f); | ||
| 123 | } | ||
| 124 | } | ||
| 125 | |||
| 126 | |||
| 127 | static void closefile (FILE *f) { | 123 | static void closefile (FILE *f) { |
| 128 | if (f != stdin && f != stdout) { | 124 | if (f != stdin && f != stdout) { |
| 129 | int tag = gettag(); | 125 | int tag = gettag(); |
| 130 | rawclose(f); | 126 | CLOSEFILE(f); |
| 131 | lua_pushusertag(f, tag); | 127 | lua_pushusertag(f, tag); |
| 132 | lua_settag(CLOSEDTAG(tag)); | 128 | lua_settag(CLOSEDTAG(tag)); |
| 133 | } | 129 | } |
| @@ -135,22 +131,20 @@ static void closefile (FILE *f) { | |||
| 135 | 131 | ||
| 136 | 132 | ||
| 137 | static void io_close (void) { | 133 | static void io_close (void) { |
| 138 | closefile(getnonullfile(1)); | 134 | closefile(getnonullfile(FIRSTARG)); |
| 139 | } | 135 | } |
| 140 | 136 | ||
| 141 | 137 | ||
| 142 | static void gc_close (void) { | 138 | static void gc_close (void) { |
| 143 | int tag = luaL_check_int(1); | 139 | FILE *f = getnonullfile(FIRSTARG); |
| 144 | lua_Object fh = lua_getparam(2); | 140 | if (f != stdin && f != stdout && f != stderr) { |
| 145 | FILE *f = lua_getuserdata(fh); | 141 | CLOSEFILE(f); |
| 146 | luaL_arg_check(lua_isuserdata(fh) && lua_tag(fh) == tag, 2, | 142 | } |
| 147 | "invalid file handle for GC"); | ||
| 148 | rawclose(f); | ||
| 149 | } | 143 | } |
| 150 | 144 | ||
| 151 | 145 | ||
| 152 | static void io_open (void) { | 146 | static void io_open (void) { |
| 153 | FILE *f = fopen(luaL_check_string(1), luaL_check_string(2)); | 147 | FILE *f = fopen(luaL_check_string(FIRSTARG), luaL_check_string(FIRSTARG+1)); |
| 154 | if (f) lua_pushusertag(f, gettag()); | 148 | if (f) lua_pushusertag(f, gettag()); |
| 155 | else pushresult(0); | 149 | else pushresult(0); |
| 156 | } | 150 | } |
| @@ -171,7 +165,7 @@ static void setreturn (FILE *f, char *name) { | |||
| 171 | 165 | ||
| 172 | static void io_readfrom (void) { | 166 | static void io_readfrom (void) { |
| 173 | FILE *current; | 167 | FILE *current; |
| 174 | lua_Object f = lua_getparam(1); | 168 | lua_Object f = lua_getparam(FIRSTARG); |
| 175 | if (f == LUA_NOOBJECT) { | 169 | if (f == LUA_NOOBJECT) { |
| 176 | closefile(getfilebyname(FINPUT)); | 170 | closefile(getfilebyname(FINPUT)); |
| 177 | current = stdin; | 171 | current = stdin; |
| @@ -179,7 +173,7 @@ static void io_readfrom (void) { | |||
| 179 | else if (lua_tag(f) == gettag()) /* deprecated option */ | 173 | else if (lua_tag(f) == gettag()) /* deprecated option */ |
| 180 | current = lua_getuserdata(f); | 174 | current = lua_getuserdata(f); |
| 181 | else { | 175 | else { |
| 182 | char *s = luaL_check_string(1); | 176 | char *s = luaL_check_string(FIRSTARG); |
| 183 | current = (*s == '|') ? popen(s+1, "r") : fopen(s, "r"); | 177 | current = (*s == '|') ? popen(s+1, "r") : fopen(s, "r"); |
| 184 | if (current == NULL) { | 178 | if (current == NULL) { |
| 185 | pushresult(0); | 179 | pushresult(0); |
| @@ -192,7 +186,7 @@ static void io_readfrom (void) { | |||
| 192 | 186 | ||
| 193 | static void io_writeto (void) { | 187 | static void io_writeto (void) { |
| 194 | FILE *current; | 188 | FILE *current; |
| 195 | lua_Object f = lua_getparam(1); | 189 | lua_Object f = lua_getparam(FIRSTARG); |
| 196 | if (f == LUA_NOOBJECT) { | 190 | if (f == LUA_NOOBJECT) { |
| 197 | closefile(getfilebyname(FOUTPUT)); | 191 | closefile(getfilebyname(FOUTPUT)); |
| 198 | current = stdout; | 192 | current = stdout; |
| @@ -200,7 +194,7 @@ static void io_writeto (void) { | |||
| 200 | else if (lua_tag(f) == gettag()) /* deprecated option */ | 194 | else if (lua_tag(f) == gettag()) /* deprecated option */ |
| 201 | current = lua_getuserdata(f); | 195 | current = lua_getuserdata(f); |
| 202 | else { | 196 | else { |
| 203 | char *s = luaL_check_string(1); | 197 | char *s = luaL_check_string(FIRSTARG); |
| 204 | current = (*s == '|') ? popen(s+1,"w") : fopen(s, "w"); | 198 | current = (*s == '|') ? popen(s+1,"w") : fopen(s, "w"); |
| 205 | if (current == NULL) { | 199 | if (current == NULL) { |
| 206 | pushresult(0); | 200 | pushresult(0); |
| @@ -212,7 +206,7 @@ static void io_writeto (void) { | |||
| 212 | 206 | ||
| 213 | 207 | ||
| 214 | static void io_appendto (void) { | 208 | static void io_appendto (void) { |
| 215 | FILE *fp = fopen(luaL_check_string(1), "a"); | 209 | FILE *fp = fopen(luaL_check_string(FIRSTARG), "a"); |
| 216 | if (fp != NULL) | 210 | if (fp != NULL) |
| 217 | setreturn(fp, FOUTPUT); | 211 | setreturn(fp, FOUTPUT); |
| 218 | else | 212 | else |
| @@ -317,7 +311,7 @@ static void read_file (FILE *f) { | |||
| 317 | 311 | ||
| 318 | static void io_read (void) { | 312 | static void io_read (void) { |
| 319 | static char *options[] = {"*n", "*l", "*a", ".*", "*w", NULL}; | 313 | static char *options[] = {"*n", "*l", "*a", ".*", "*w", NULL}; |
| 320 | int arg = 1; | 314 | int arg = FIRSTARG; |
| 321 | FILE *f = getfileparam(FINPUT, &arg); | 315 | FILE *f = getfileparam(FINPUT, &arg); |
| 322 | char *p = luaL_opt_string(arg++, "*l"); | 316 | char *p = luaL_opt_string(arg++, "*l"); |
| 323 | do { /* repeat for each part */ | 317 | do { /* repeat for each part */ |
| @@ -351,7 +345,7 @@ static void io_read (void) { | |||
| 351 | 345 | ||
| 352 | 346 | ||
| 353 | static void io_write (void) { | 347 | static void io_write (void) { |
| 354 | int arg = 1; | 348 | int arg = FIRSTARG; |
| 355 | FILE *f = getfileparam(FOUTPUT, &arg); | 349 | FILE *f = getfileparam(FOUTPUT, &arg); |
| 356 | int status = 1; | 350 | int status = 1; |
| 357 | char *s; | 351 | char *s; |
| @@ -365,10 +359,10 @@ static void io_write (void) { | |||
| 365 | static void io_seek (void) { | 359 | static void io_seek (void) { |
| 366 | static int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END}; | 360 | static int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END}; |
| 367 | static char *modenames[] = {"set", "cur", "end", NULL}; | 361 | static char *modenames[] = {"set", "cur", "end", NULL}; |
| 368 | FILE *f = getnonullfile(1); | 362 | FILE *f = getnonullfile(FIRSTARG); |
| 369 | int op = luaL_findstring(luaL_opt_string(2, "cur"), modenames); | 363 | int op = luaL_findstring(luaL_opt_string(FIRSTARG+1, "cur"), modenames); |
| 370 | long offset = luaL_opt_long(3, 0); | 364 | long offset = luaL_opt_long(FIRSTARG+2, 0); |
| 371 | luaL_arg_check(op != -1, 2, "invalid mode"); | 365 | luaL_arg_check(op != -1, FIRSTARG+1, "invalid mode"); |
| 372 | op = fseek(f, offset, mode[op]); | 366 | op = fseek(f, offset, mode[op]); |
| 373 | if (op) | 367 | if (op) |
| 374 | pushresult(0); /* error */ | 368 | pushresult(0); /* error */ |
| @@ -378,8 +372,8 @@ static void io_seek (void) { | |||
| 378 | 372 | ||
| 379 | 373 | ||
| 380 | static void io_flush (void) { | 374 | static void io_flush (void) { |
| 381 | FILE *f = getfile(1); | 375 | FILE *f = getfile(FIRSTARG); |
| 382 | luaL_arg_check(f || lua_getparam(1) == LUA_NOOBJECT, 1, | 376 | luaL_arg_check(f || lua_getparam(FIRSTARG) == LUA_NOOBJECT, FIRSTARG, |
| 383 | "invalid file handle"); | 377 | "invalid file handle"); |
| 384 | pushresult(fflush(f) == 0); | 378 | pushresult(fflush(f) == 0); |
| 385 | } | 379 | } |
| @@ -532,44 +526,57 @@ static void errorfb (void) { | |||
| 532 | 526 | ||
| 533 | static struct luaL_reg iolib[] = { | 527 | static struct luaL_reg iolib[] = { |
| 534 | {"_ERRORMESSAGE", errorfb}, | 528 | {"_ERRORMESSAGE", errorfb}, |
| 535 | {"appendto", io_appendto}, | ||
| 536 | {"clock", io_clock}, | 529 | {"clock", io_clock}, |
| 537 | {"closefile", io_close}, | ||
| 538 | {"date", io_date}, | 530 | {"date", io_date}, |
| 539 | {"debug", io_debug}, | 531 | {"debug", io_debug}, |
| 540 | {"execute", io_execute}, | 532 | {"execute", io_execute}, |
| 541 | {"exit", io_exit}, | 533 | {"exit", io_exit}, |
| 542 | {"flush", io_flush}, | ||
| 543 | {"getenv", io_getenv}, | 534 | {"getenv", io_getenv}, |
| 535 | {"remove", io_remove}, | ||
| 536 | {"rename", io_rename}, | ||
| 537 | {"setlocale", setloc}, | ||
| 538 | {"tmpname", io_tmpname} | ||
| 539 | }; | ||
| 540 | |||
| 541 | |||
| 542 | static struct luaL_reg iolibtag[] = { | ||
| 543 | {"appendto", io_appendto}, | ||
| 544 | {"closefile", io_close}, | ||
| 545 | {"flush", io_flush}, | ||
| 544 | {"openfile", io_open}, | 546 | {"openfile", io_open}, |
| 545 | {"read", io_read}, | 547 | {"read", io_read}, |
| 546 | {"readfrom", io_readfrom}, | 548 | {"readfrom", io_readfrom}, |
| 547 | {"remove", io_remove}, | ||
| 548 | {"rename", io_rename}, | ||
| 549 | {"seek", io_seek}, | 549 | {"seek", io_seek}, |
| 550 | {"setlocale", setloc}, | ||
| 551 | {"tmpname", io_tmpname}, | ||
| 552 | {"write", io_write}, | 550 | {"write", io_write}, |
| 553 | {"writeto", io_writeto} | 551 | {"writeto", io_writeto} |
| 554 | }; | 552 | }; |
| 555 | 553 | ||
| 556 | 554 | ||
| 557 | void lua_iolibopen (void) { | 555 | static void openwithtags (void) { |
| 556 | int i; | ||
| 558 | int iotag = lua_newtag(); | 557 | int iotag = lua_newtag(); |
| 559 | lua_newtag(); /* alloc CLOSEDTAG: assume that CLOSEDTAG = iotag-1 */ | 558 | lua_newtag(); /* alloc CLOSEDTAG: assume that CLOSEDTAG = iotag-1 */ |
| 559 | for (i=0; i<sizeof(iolibtag)/sizeof(iolibtag[0]); i++) { | ||
| 560 | /* put iotag as upvalue for these functions */ | ||
| 561 | lua_pushnumber(iotag); | ||
| 562 | lua_pushcclosure(iolibtag[i].func, 1); | ||
| 563 | lua_setglobal(iolibtag[i].name); | ||
| 564 | } | ||
| 560 | /* predefined file handles */ | 565 | /* predefined file handles */ |
| 561 | setfile(stdin, FINPUT, iotag); | 566 | setfile(stdin, FINPUT, iotag); |
| 562 | setfile(stdout, FOUTPUT, iotag); | 567 | setfile(stdout, FOUTPUT, iotag); |
| 563 | setfile(stdin, "_STDIN", iotag); | 568 | setfile(stdin, "_STDIN", iotag); |
| 564 | setfile(stdout, "_STDOUT", iotag); | 569 | setfile(stdout, "_STDOUT", iotag); |
| 565 | setfile(stderr, "_STDERR", iotag); | 570 | setfile(stderr, "_STDERR", iotag); |
| 566 | /* make sure stdin (with its tag) won't be collected */ | ||
| 567 | lua_pushusertag(stdin, iotag); lua_ref(1); | ||
| 568 | /* close file when collected */ | 571 | /* close file when collected */ |
| 569 | lua_pushnumber(iotag); | 572 | lua_pushnumber(iotag); |
| 570 | lua_pushcclosure(gc_close, 1); | 573 | lua_pushcclosure(gc_close, 1); |
| 571 | lua_settagmethod(iotag, "gc"); | 574 | lua_settagmethod(iotag, "gc"); |
| 575 | } | ||
| 576 | |||
| 577 | void lua_iolibopen (void) { | ||
| 572 | /* register lib functions */ | 578 | /* register lib functions */ |
| 573 | luaL_openlib(iolib, (sizeof(iolib)/sizeof(iolib[0]))); | 579 | luaL_openlib(iolib, (sizeof(iolib)/sizeof(iolib[0]))); |
| 580 | openwithtags(); | ||
| 574 | } | 581 | } |
| 575 | 582 | ||
