summaryrefslogtreecommitdiff
path: root/liolib.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2002-10-16 17:41:35 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2002-10-16 17:41:35 -0300
commitec748fcb0a6913a814f106218e9fde3a73ffc014 (patch)
treeba0355be86136353a49dd6271e3d757600dc813c /liolib.c
parentc196348717dfda116726145220e5d1311547980e (diff)
downloadlua-ec748fcb0a6913a814f106218e9fde3a73ffc014.tar.gz
lua-ec748fcb0a6913a814f106218e9fde3a73ffc014.tar.bz2
lua-ec748fcb0a6913a814f106218e9fde3a73ffc014.zip
correct handling of opened files in presence of memory allocation
errors
Diffstat (limited to 'liolib.c')
-rw-r--r--liolib.c56
1 files changed, 31 insertions, 25 deletions
diff --git a/liolib.c b/liolib.c
index 13d63d33..c3981247 100644
--- a/liolib.c
+++ b/liolib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: liolib.c,v 2.19 2002/09/19 20:12:47 roberto Exp roberto $ 2** $Id: liolib.c,v 2.20 2002/10/11 20:40:32 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*/
@@ -68,18 +68,25 @@ static FILE *tofile (lua_State *L, int findex) {
68} 68}
69 69
70 70
71static void newfile (lua_State *L, FILE *f) { 71/*
72 lua_boxpointer(L, f); 72** When creating file handles, always creates a `closed' file handle
73** before opening the actual file; so, if there is a memory error, the
74** file is not left opened.
75*/
76static FILE **newfile (lua_State *L) {
77 FILE **pf = (FILE **)lua_newuserdata(L, sizeof(FILE *));
78 *pf = NULL; /* file handle is currently `closed' */
73 lua_pushliteral(L, FILEHANDLE); 79 lua_pushliteral(L, FILEHANDLE);
74 lua_rawget(L, LUA_REGISTRYINDEX); 80 lua_rawget(L, LUA_REGISTRYINDEX);
75 lua_setmetatable(L, -2); 81 lua_setmetatable(L, -2);
82 return pf;
76} 83}
77 84
78 85
79static void registerfile (lua_State *L, FILE *f, const char *name, 86static void registerfile (lua_State *L, FILE *f, const char *name,
80 const char *impname) { 87 const char *impname) {
81 lua_pushstring(L, name); 88 lua_pushstring(L, name);
82 newfile(L, f); 89 *newfile(L) = f;
83 if (impname) { 90 if (impname) {
84 lua_pushstring(L, impname); 91 lua_pushstring(L, impname);
85 lua_pushvalue(L, -2); 92 lua_pushvalue(L, -2);
@@ -89,16 +96,6 @@ static void registerfile (lua_State *L, FILE *f, const char *name,
89} 96}
90 97
91 98
92static int setnewfile (lua_State *L, FILE *f) {
93 if (f == NULL)
94 return pushresult(L, 0);
95 else {
96 newfile(L, f);
97 return 1;
98 }
99}
100
101
102static int aux_close (lua_State *L) { 99static int aux_close (lua_State *L) {
103 FILE *f = tofile(L, 1); 100 FILE *f = tofile(L, 1);
104 if (f == stdin || f == stdout || f == stderr) 101 if (f == stdin || f == stdout || f == stderr)
@@ -126,8 +123,11 @@ static int io_gc (lua_State *L) {
126 123
127 124
128static int io_open (lua_State *L) { 125static int io_open (lua_State *L) {
129 FILE *f = fopen(luaL_check_string(L, 1), luaL_opt_string(L, 2, "r")); 126 const char *filename = luaL_check_string(L, 1);
130 return setnewfile(L, f); 127 const char *mode = luaL_opt_string(L, 2, "r");
128 FILE **pf = newfile(L);
129 *pf = fopen(filename, mode);
130 return (*pf == NULL) ? pushresult(L, 0) : 1;
131} 131}
132 132
133 133
@@ -136,14 +136,19 @@ static int io_popen (lua_State *L) {
136 luaL_error(L, "`popen' not supported"); 136 luaL_error(L, "`popen' not supported");
137 return 0; 137 return 0;
138#else 138#else
139 FILE *f = popen(luaL_check_string(L, 1), luaL_opt_string(L, 2, "r")); 139 const char *filename = luaL_check_string(L, 1);
140 return setnewfile(L, f); 140 const char *mode = luaL_opt_string(L, 2, "r");
141 FILE **pf = newfile(L);
142 *pf = popen(filename, mode);
143 return (*pf == NULL) ? pushresult(L, 0) : 1;
141#endif 144#endif
142} 145}
143 146
144 147
145static int io_tmpfile (lua_State *L) { 148static int io_tmpfile (lua_State *L) {
146 return setnewfile(L, tmpfile()); 149 FILE **pf = newfile(L);
150 *pf = tmpfile();
151 return (*pf == NULL) ? pushresult(L, 0) : 1;
147} 152}
148 153
149 154
@@ -168,9 +173,9 @@ static int g_iofile (lua_State *L, const char *name, const char *mode) {
168 const char *filename = lua_tostring(L, 1); 173 const char *filename = lua_tostring(L, 1);
169 lua_pushstring(L, name); 174 lua_pushstring(L, name);
170 if (filename) { 175 if (filename) {
171 FILE *f = fopen(filename, mode); 176 FILE **pf = newfile(L);
172 luaL_arg_check(L, f, 1, strerror(errno)); 177 *pf = fopen(filename, mode);
173 newfile(L, f); 178 luaL_arg_check(L, *pf, 1, strerror(errno));
174 } 179 }
175 else { 180 else {
176 tofile(L, 1); /* check that it's a valid file handle */ 181 tofile(L, 1); /* check that it's a valid file handle */
@@ -218,9 +223,10 @@ static int io_lines (lua_State *L) {
218 return f_lines(L); 223 return f_lines(L);
219 } 224 }
220 else { 225 else {
221 FILE *f = fopen(luaL_check_string(L, 1), "r"); 226 const char *filename = luaL_check_string(L, 1);
222 luaL_arg_check(L, f, 1, strerror(errno)); 227 FILE **pf = newfile(L);
223 newfile(L, f); 228 *pf = fopen(filename, "r");
229 luaL_arg_check(L, *pf, 1, strerror(errno));
224 aux_lines(L, lua_gettop(L), 1); 230 aux_lines(L, lua_gettop(L), 1);
225 return 1; 231 return 1;
226 } 232 }