diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-10-16 17:41:35 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-10-16 17:41:35 -0300 |
commit | ec748fcb0a6913a814f106218e9fde3a73ffc014 (patch) | |
tree | ba0355be86136353a49dd6271e3d757600dc813c /lauxlib.c | |
parent | c196348717dfda116726145220e5d1311547980e (diff) | |
download | lua-ec748fcb0a6913a814f106218e9fde3a73ffc014.tar.gz lua-ec748fcb0a6913a814f106218e9fde3a73ffc014.tar.bz2 lua-ec748fcb0a6913a814f106218e9fde3a73ffc014.zip |
correct handling of opened files in presence of memory allocation
errors
Diffstat (limited to 'lauxlib.c')
-rw-r--r-- | lauxlib.c | 40 |
1 files changed, 22 insertions, 18 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lauxlib.c,v 1.86 2002/09/16 19:49:45 roberto Exp roberto $ | 2 | ** $Id: lauxlib.c,v 1.87 2002/10/04 14:31:40 roberto Exp roberto $ |
3 | ** Auxiliary functions for building Lua libraries | 3 | ** Auxiliary functions for building Lua libraries |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -345,38 +345,42 @@ static const char *getF (lua_State *L, void *ud, size_t *size) { | |||
345 | } | 345 | } |
346 | 346 | ||
347 | 347 | ||
348 | static int errfile (lua_State *L, const char *filename) { | 348 | static int errfile (lua_State *L, int fnameindex) { |
349 | if (filename == NULL) filename = "stdin"; | 349 | const char *filename = lua_tostring(L, fnameindex) + 1; |
350 | lua_pushfstring(L, "cannot read %s: %s", filename, strerror(errno)); | 350 | lua_pushfstring(L, "cannot read %s: %s", filename, strerror(errno)); |
351 | lua_remove(L, fnameindex); | ||
351 | return LUA_ERRFILE; | 352 | return LUA_ERRFILE; |
352 | } | 353 | } |
353 | 354 | ||
354 | 355 | ||
355 | LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) { | 356 | LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) { |
356 | LoadF lf; | 357 | LoadF lf; |
357 | int status; | 358 | int status, readstatus; |
358 | int c; | 359 | int c; |
359 | int old_top = lua_gettop(L); | 360 | int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */ |
360 | lf.f = (filename == NULL) ? stdin : fopen(filename, "r"); | 361 | if (filename == NULL) { |
361 | if (lf.f == NULL) return errfile(L, filename); /* unable to open file */ | 362 | lua_pushliteral(L, "=stdin"); |
363 | lf.f = stdin; | ||
364 | } | ||
365 | else { | ||
366 | lua_pushfstring(L, "@%s", filename); | ||
367 | lf.f = fopen(filename, "r"); | ||
368 | } | ||
369 | if (lf.f == NULL) return errfile(L, fnameindex); /* unable to open file */ | ||
362 | c = ungetc(getc(lf.f), lf.f); | 370 | c = ungetc(getc(lf.f), lf.f); |
363 | if (!(isspace(c) || isprint(c)) && lf.f != stdin) { /* binary file? */ | 371 | if (!(isspace(c) || isprint(c)) && lf.f != stdin) { /* binary file? */ |
364 | fclose(lf.f); | 372 | fclose(lf.f); |
365 | lf.f = fopen(filename, "rb"); /* reopen in binary mode */ | 373 | lf.f = fopen(filename, "rb"); /* reopen in binary mode */ |
366 | if (lf.f == NULL) return errfile(L, filename); /* unable to reopen file */ | 374 | if (lf.f == NULL) return errfile(L, fnameindex); /* unable to reopen file */ |
367 | } | 375 | } |
368 | if (filename == NULL) | ||
369 | lua_pushliteral(L, "=stdin"); | ||
370 | else | ||
371 | lua_pushfstring(L, "@%s", filename); | ||
372 | status = lua_load(L, getF, &lf, lua_tostring(L, -1)); | 376 | status = lua_load(L, getF, &lf, lua_tostring(L, -1)); |
373 | lua_remove(L, old_top+1); /* remove filename from stack */ | 377 | readstatus = ferror(lf.f); |
374 | if (ferror(lf.f)) { | 378 | if (lf.f != stdin) fclose(lf.f); /* close file (even in case of errors) */ |
375 | lua_settop(L, old_top); /* ignore results from `lua_load' */ | 379 | if (readstatus) { |
376 | return errfile(L, filename); | 380 | lua_settop(L, fnameindex); /* ignore results from `lua_load' */ |
381 | return errfile(L, fnameindex); | ||
377 | } | 382 | } |
378 | if (lf.f != stdin) | 383 | lua_remove(L, fnameindex); |
379 | fclose(lf.f); | ||
380 | return status; | 384 | return status; |
381 | } | 385 | } |
382 | 386 | ||