Hi
The function errfile uses strerror(errno) to get the description of the last error:
static int errfile (lua_State *L, const char *what, int fnameindex) {
const char *serr = strerror(errno);
The function luaL_loadfilex ends with these lines:
readstatus = ferror(lf.f);
if (filename) fclose(lf.f); /* close file (even in case of errors) */
if (readstatus) {
lua_settop(L, fnameindex); /* ignore results from 'lua_load' */
return errfile(L, "read", fnameindex);
}
I give a candy to anyone who sees the bug ;-)
.
.
.
And now the explanation.
fclose does not guarantee to leave errno unaffected.
So, if readstatus is true, the code calls errfile to translate to get the error message.
In between there is the call to fclose... errno can change... so errfile could get the error message of fclose, not of the previous failure.
This is the easy fix of
luaL_loadfilex :
- int status, readstatus;
+ int status, readstatus, readstatus_errno;
- readstatus = ferror(lf.f);
+ readstatus = ferror(lf.f);
+ readstatus_errno = errno;
- return errfile(L, "read", fnameindex);
+ errno = readstatus_errno;
+ return errfile(L, "read", fnameindex);
If you don't like to set errno, it is necessary to rewrite errfile to accept errno as argument.
In luaL_loadfilex replace all the calls to errfile:
- errfile(L, "read", fnameindex)
+ errfile(L, "read", fnameindex, errno)
except the last one:
- errfile(L, "read", fnameindex)
+
errfile(L, "read", fnameindex, readstatus_errno)
M