diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2024-06-12 15:50:31 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2024-06-12 15:50:31 -0300 |
commit | bb7bb5944c9b3c868c6ab9cbe7d11b611251066b (patch) | |
tree | fe7f5e8def79d5a3c253a2f39c4557fc20d204e6 /lauxlib.c | |
parent | 94b503d95ef00f1e38b58b024ef45bf8973a8746 (diff) | |
download | lua-bb7bb5944c9b3c868c6ab9cbe7d11b611251066b.tar.gz lua-bb7bb5944c9b3c868c6ab9cbe7d11b611251066b.tar.bz2 lua-bb7bb5944c9b3c868c6ab9cbe7d11b611251066b.zip |
More disciplined use of 'errno'
Set errno to zero before calling any function where we may use its
errno, and check errno for zero before using it (as functions may not
set it even in error). The code assumes that no function will put
garbage on errno (although ISO C allows that): If any function during an
operation set errno, and the operation result in an error, assume that
errno has something to say.
Diffstat (limited to 'lauxlib.c')
-rw-r--r-- | lauxlib.c | 16 |
1 files changed, 12 insertions, 4 deletions
@@ -249,11 +249,13 @@ LUALIB_API int luaL_fileresult (lua_State *L, int stat, const char *fname) { | |||
249 | return 1; | 249 | return 1; |
250 | } | 250 | } |
251 | else { | 251 | else { |
252 | const char *msg; | ||
252 | luaL_pushfail(L); | 253 | luaL_pushfail(L); |
254 | msg = (en != 0) ? strerror(en) : "(no extra info)"; | ||
253 | if (fname) | 255 | if (fname) |
254 | lua_pushfstring(L, "%s: %s", fname, strerror(en)); | 256 | lua_pushfstring(L, "%s: %s", fname, msg); |
255 | else | 257 | else |
256 | lua_pushstring(L, strerror(en)); | 258 | lua_pushstring(L, msg); |
257 | lua_pushinteger(L, en); | 259 | lua_pushinteger(L, en); |
258 | return 3; | 260 | return 3; |
259 | } | 261 | } |
@@ -750,9 +752,12 @@ static const char *getF (lua_State *L, void *ud, size_t *size) { | |||
750 | 752 | ||
751 | 753 | ||
752 | static int errfile (lua_State *L, const char *what, int fnameindex) { | 754 | static int errfile (lua_State *L, const char *what, int fnameindex) { |
753 | const char *serr = strerror(errno); | 755 | int err = errno; |
754 | const char *filename = lua_tostring(L, fnameindex) + 1; | 756 | const char *filename = lua_tostring(L, fnameindex) + 1; |
755 | lua_pushfstring(L, "cannot %s %s: %s", what, filename, serr); | 757 | if (err != 0) |
758 | lua_pushfstring(L, "cannot %s %s: %s", what, filename, strerror(err)); | ||
759 | else | ||
760 | lua_pushfstring(L, "cannot %s %s", what, filename); | ||
756 | lua_remove(L, fnameindex); | 761 | lua_remove(L, fnameindex); |
757 | return LUA_ERRFILE; | 762 | return LUA_ERRFILE; |
758 | } | 763 | } |
@@ -805,6 +810,7 @@ LUALIB_API int luaL_loadfilex (lua_State *L, const char *filename, | |||
805 | } | 810 | } |
806 | else { | 811 | else { |
807 | lua_pushfstring(L, "@%s", filename); | 812 | lua_pushfstring(L, "@%s", filename); |
813 | errno = 0; | ||
808 | lf.f = fopen(filename, "r"); | 814 | lf.f = fopen(filename, "r"); |
809 | if (lf.f == NULL) return errfile(L, "open", fnameindex); | 815 | if (lf.f == NULL) return errfile(L, "open", fnameindex); |
810 | } | 816 | } |
@@ -814,6 +820,7 @@ LUALIB_API int luaL_loadfilex (lua_State *L, const char *filename, | |||
814 | if (c == LUA_SIGNATURE[0]) { /* binary file? */ | 820 | if (c == LUA_SIGNATURE[0]) { /* binary file? */ |
815 | lf.n = 0; /* remove possible newline */ | 821 | lf.n = 0; /* remove possible newline */ |
816 | if (filename) { /* "real" file? */ | 822 | if (filename) { /* "real" file? */ |
823 | errno = 0; | ||
817 | lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */ | 824 | lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */ |
818 | if (lf.f == NULL) return errfile(L, "reopen", fnameindex); | 825 | if (lf.f == NULL) return errfile(L, "reopen", fnameindex); |
819 | skipcomment(lf.f, &c); /* re-read initial portion */ | 826 | skipcomment(lf.f, &c); /* re-read initial portion */ |
@@ -823,6 +830,7 @@ LUALIB_API int luaL_loadfilex (lua_State *L, const char *filename, | |||
823 | lf.buff[lf.n++] = c; /* 'c' is the first character of the stream */ | 830 | lf.buff[lf.n++] = c; /* 'c' is the first character of the stream */ |
824 | status = lua_load(L, getF, &lf, lua_tostring(L, -1), mode); | 831 | status = lua_load(L, getF, &lf, lua_tostring(L, -1), mode); |
825 | readstatus = ferror(lf.f); | 832 | readstatus = ferror(lf.f); |
833 | errno = 0; /* no useful error number until here */ | ||
826 | if (filename) fclose(lf.f); /* close file (even in case of errors) */ | 834 | if (filename) fclose(lf.f); /* close file (even in case of errors) */ |
827 | if (readstatus) { | 835 | if (readstatus) { |
828 | lua_settop(L, fnameindex); /* ignore results from 'lua_load' */ | 836 | lua_settop(L, fnameindex); /* ignore results from 'lua_load' */ |