summaryrefslogtreecommitdiff
path: root/liolib.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>1999-03-26 10:48:26 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>1999-03-26 10:48:26 -0300
commitbf7f85d609291023bcc53df862198f5877ca00d6 (patch)
tree3c5726b671d684e09064bb0e1df6b289fdc3a213 /liolib.c
parenta775a2d81ac31ae211a9682a2a57c6ca95e11115 (diff)
downloadlua-bf7f85d609291023bcc53df862198f5877ca00d6.tar.gz
lua-bf7f85d609291023bcc53df862198f5877ca00d6.tar.bz2
lua-bf7f85d609291023bcc53df862198f5877ca00d6.zip
GC of files is tricky when Lua is being closed...
Diffstat (limited to 'liolib.c')
-rw-r--r--liolib.c36
1 files changed, 27 insertions, 9 deletions
diff --git a/liolib.c b/liolib.c
index 730e2be2..df6d8c91 100644
--- a/liolib.c
+++ b/liolib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: liolib.c,v 1.34 1999/03/11 18:59:19 roberto Exp roberto $ 2** $Id: liolib.c,v 1.35 1999/03/16 20:07:54 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*/
@@ -74,7 +74,7 @@ static int gettag (void) {
74} 74}
75 75
76 76
77static int ishandler (lua_Object f) { 77static int ishandle (lua_Object f) {
78 if (lua_isuserdata(f)) { 78 if (lua_isuserdata(f)) {
79 int tag = gettag(); 79 int tag = gettag();
80 if (lua_tag(f) == CLOSEDTAG(tag)) 80 if (lua_tag(f) == CLOSEDTAG(tag))
@@ -87,7 +87,7 @@ static int ishandler (lua_Object f) {
87 87
88static FILE *getfilebyname (char *name) { 88static FILE *getfilebyname (char *name) {
89 lua_Object f = lua_getglobal(name); 89 lua_Object f = lua_getglobal(name);
90 if (!ishandler(f)) 90 if (!ishandle(f))
91 luaL_verror("global variable `%.50s' is not a file handle", name); 91 luaL_verror("global variable `%.50s' is not a file handle", name);
92 return lua_getuserdata(f); 92 return lua_getuserdata(f);
93} 93}
@@ -95,13 +95,13 @@ static FILE *getfilebyname (char *name) {
95 95
96static FILE *getfile (int arg) { 96static FILE *getfile (int arg) {
97 lua_Object f = lua_getparam(arg); 97 lua_Object f = lua_getparam(arg);
98 return (ishandler(f)) ? lua_getuserdata(f) : NULL; 98 return (ishandle(f)) ? lua_getuserdata(f) : NULL;
99} 99}
100 100
101 101
102static FILE *getnonullfile (int arg) { 102static FILE *getnonullfile (int arg) {
103 FILE *f = getfile(arg); 103 FILE *f = getfile(arg);
104 luaL_arg_check(f, arg, "invalid file handler"); 104 luaL_arg_check(f, arg, "invalid file handle");
105 return f; 105 return f;
106} 106}
107 107
@@ -117,11 +117,17 @@ static FILE *getfileparam (char *name, int *arg) {
117} 117}
118 118
119 119
120static void rawclose (FILE *f) {
121 if (f != stdin && f != stdout) {
122 if (pclose(f) == -1) fclose(f);
123 }
124}
125
126
120static void closefile (FILE *f) { 127static void closefile (FILE *f) {
121 if (f != stdin && f != stdout) { 128 if (f != stdin && f != stdout) {
122 int tag = gettag(); 129 int tag = gettag();
123 if (pclose(f) == -1) 130 rawclose(f);
124 fclose(f);
125 lua_pushusertag(f, tag); 131 lua_pushusertag(f, tag);
126 lua_settag(CLOSEDTAG(tag)); 132 lua_settag(CLOSEDTAG(tag));
127 } 133 }
@@ -133,6 +139,16 @@ static void io_close (void) {
133} 139}
134 140
135 141
142static void gc_close (void) {
143 int tag = luaL_check_int(1);
144 lua_Object fh = lua_getparam(2);
145 FILE *f = lua_getuserdata(fh);
146 luaL_arg_check(lua_isuserdata(fh) && lua_tag(fh) == tag, 2,
147 "invalid file handle for GC");
148 rawclose(f);
149}
150
151
136static void io_open (void) { 152static void io_open (void) {
137 FILE *f = fopen(luaL_check_string(1), luaL_check_string(2)); 153 FILE *f = fopen(luaL_check_string(1), luaL_check_string(2));
138 if (f) lua_pushusertag(f, gettag()); 154 if (f) lua_pushusertag(f, gettag());
@@ -364,7 +380,7 @@ static void io_seek (void) {
364static void io_flush (void) { 380static void io_flush (void) {
365 FILE *f = getfile(1); 381 FILE *f = getfile(1);
366 luaL_arg_check(f || lua_getparam(1) == LUA_NOOBJECT, 1, 382 luaL_arg_check(f || lua_getparam(1) == LUA_NOOBJECT, 1,
367 "invalid file handler"); 383 "invalid file handle");
368 pushresult(fflush(f) == 0); 384 pushresult(fflush(f) == 0);
369} 385}
370 386
@@ -550,7 +566,9 @@ void lua_iolibopen (void) {
550 /* make sure stdin (with its tag) won't be collected */ 566 /* make sure stdin (with its tag) won't be collected */
551 lua_pushusertag(stdin, iotag); lua_ref(1); 567 lua_pushusertag(stdin, iotag); lua_ref(1);
552 /* close file when collected */ 568 /* close file when collected */
553 lua_pushcfunction(io_close); lua_settagmethod(iotag, "gc"); 569 lua_pushnumber(iotag);
570 lua_pushcclosure(gc_close, 1);
571 lua_settagmethod(iotag, "gc");
554 /* register lib functions */ 572 /* register lib functions */
555 luaL_openlib(iolib, (sizeof(iolib)/sizeof(iolib[0]))); 573 luaL_openlib(iolib, (sizeof(iolib)/sizeof(iolib[0])));
556} 574}