diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1999-03-26 10:48:26 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1999-03-26 10:48:26 -0300 |
commit | bf7f85d609291023bcc53df862198f5877ca00d6 (patch) | |
tree | 3c5726b671d684e09064bb0e1df6b289fdc3a213 /liolib.c | |
parent | a775a2d81ac31ae211a9682a2a57c6ca95e11115 (diff) | |
download | lua-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.c | 36 |
1 files changed, 27 insertions, 9 deletions
@@ -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 | ||
77 | static int ishandler (lua_Object f) { | 77 | static 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 | ||
88 | static FILE *getfilebyname (char *name) { | 88 | static 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 | ||
96 | static FILE *getfile (int arg) { | 96 | static 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 | ||
102 | static FILE *getnonullfile (int arg) { | 102 | static 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 | ||
120 | static void rawclose (FILE *f) { | ||
121 | if (f != stdin && f != stdout) { | ||
122 | if (pclose(f) == -1) fclose(f); | ||
123 | } | ||
124 | } | ||
125 | |||
126 | |||
120 | static void closefile (FILE *f) { | 127 | static 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 | ||
142 | static 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 | |||
136 | static void io_open (void) { | 152 | static 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) { | |||
364 | static void io_flush (void) { | 380 | static 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 | } |