aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2002-11-25 13:05:39 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2002-11-25 13:05:39 -0200
commitd9340154accd593984fa0d2101fe5f3b63f4c3a2 (patch)
tree9ca9227a2027acef0a507b27be77718f7b7e6260
parente47baca75a3854c9f3065c554d6758bd23c5d73f (diff)
downloadlua-d9340154accd593984fa0d2101fe5f3b63f4c3a2.tar.gz
lua-d9340154accd593984fa0d2101fe5f3b63f4c3a2.tar.bz2
lua-d9340154accd593984fa0d2101fe5f3b63f4c3a2.zip
`__tostring' for files + small bug (could do invalid read inside
a userdata when it was not a file)
-rw-r--r--liolib.c55
1 files changed, 35 insertions, 20 deletions
diff --git a/liolib.c b/liolib.c
index 0ee9f94f..79855608 100644
--- a/liolib.c
+++ b/liolib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: liolib.c,v 2.23 2002/11/14 15:41:38 roberto Exp roberto $ 2** $Id: liolib.c,v 2.24 2002/11/18 16:53:19 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*/
@@ -54,23 +54,26 @@ static int pushresult (lua_State *L, int i, const char *filename) {
54} 54}
55 55
56 56
57static FILE *tofile (lua_State *L, int findex) { 57static FILE **topfile (lua_State *L, int findex) {
58 FILE **f = (FILE **)lua_touserdata(L, findex); 58 FILE **f = (FILE **)lua_touserdata(L, findex);
59 if (f && *f && lua_getmetatable(L, findex) && 59 if (f == NULL || !lua_getmetatable(L, findex) ||
60 lua_rawequal(L, -1, lua_upvalueindex(1))) { 60 !lua_rawequal(L, -1, lua_upvalueindex(1))) {
61 lua_pop(L, 1); 61 luaL_argerror(L, findex, "bad file");
62 return *f;
63 }
64 if (findex > 0) {
65 if (f && *f == NULL)
66 luaL_error(L, "attempt to use a closed file");
67 else
68 luaL_argerror(L, findex, "bad file");
69 } 62 }
70 return NULL; 63 lua_pop(L, 1);
64 return f;
65}
66
67
68static FILE *tofile (lua_State *L, int findex) {
69 FILE **f = topfile(L, findex);
70 if (*f == NULL)
71 luaL_error(L, "attempt to use a closed file");
72 return *f;
71} 73}
72 74
73 75
76
74/* 77/*
75** When creating file handles, always creates a `closed' file handle 78** When creating file handles, always creates a `closed' file handle
76** before opening the actual file; so, if there is a memory error, the 79** before opening the actual file; so, if there is a memory error, the
@@ -126,13 +129,25 @@ static int io_close (lua_State *L) {
126 129
127 130
128static int io_gc (lua_State *L) { 131static int io_gc (lua_State *L) {
129 FILE **f = (FILE **)lua_touserdata(L, 1); 132 FILE **f = topfile(L, 1);
130 if (!(f && *f == NULL)) /* ignore closed files */ 133 if (*f != NULL) /* ignore closed files */
131 aux_close(L); 134 aux_close(L);
132 return 0; 135 return 0;
133} 136}
134 137
135 138
139static int io_tostring (lua_State *L) {
140 char buff[32];
141 FILE **f = topfile(L, 1);
142 if (*f == NULL)
143 strcpy(buff, "closed");
144 else
145 sprintf(buff, "%p", lua_touserdata(L, 1));
146 lua_pushfstring(L, "file (%s)", buff);
147 return 1;
148}
149
150
136static int io_open (lua_State *L) { 151static int io_open (lua_State *L) {
137 const char *filename = luaL_checkstring(L, 1); 152 const char *filename = luaL_checkstring(L, 1);
138 const char *mode = luaL_optstring(L, 2, "r"); 153 const char *mode = luaL_optstring(L, 2, "r");
@@ -164,13 +179,9 @@ static int io_tmpfile (lua_State *L) {
164 179
165 180
166static FILE *getiofile (lua_State *L, const char *name) { 181static FILE *getiofile (lua_State *L, const char *name) {
167 FILE *f;
168 lua_pushstring(L, name); 182 lua_pushstring(L, name);
169 lua_rawget(L, lua_upvalueindex(1)); 183 lua_rawget(L, lua_upvalueindex(1));
170 f = tofile(L, -1); 184 return tofile(L, -1);
171 if (f == NULL)
172 luaL_error(L, "%s is closed", name);
173 return f;
174} 185}
175 186
176 187
@@ -478,6 +489,10 @@ static void createmeta (lua_State *L) {
478 lua_pushvalue(L, -2); /* push metatable (will be upvalue for `gc' method) */ 489 lua_pushvalue(L, -2); /* push metatable (will be upvalue for `gc' method) */
479 lua_pushcclosure(L, io_gc, 1); 490 lua_pushcclosure(L, io_gc, 1);
480 lua_rawset(L, -3); /* metatable.__gc = io_gc */ 491 lua_rawset(L, -3); /* metatable.__gc = io_gc */
492 lua_pushliteral(L, "__tostring");
493 lua_pushvalue(L, -2); /* push metatable */
494 lua_pushcclosure(L, io_tostring, 1);
495 lua_rawset(L, -3);
481 /* file methods */ 496 /* file methods */
482 lua_pushliteral(L, "__index"); 497 lua_pushliteral(L, "__index");
483 lua_pushvalue(L, -2); /* push metatable */ 498 lua_pushvalue(L, -2); /* push metatable */