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 | ||
