diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2024-06-04 12:48:29 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2024-06-04 12:48:29 -0300 |
commit | d5212c13b081ed62d8e1ae436779e79c79edf564 (patch) | |
tree | 936ac196173318f51bec43077a2006ef48a88813 | |
parent | e0efebdbe4e4053c6fb78588c546f1dc23aa964a (diff) | |
download | lua-d5212c13b081ed62d8e1ae436779e79c79edf564.tar.gz lua-d5212c13b081ed62d8e1ae436779e79c79edf564.tar.bz2 lua-d5212c13b081ed62d8e1ae436779e79c79edf564.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).
-rw-r--r-- | lauxlib.c | 18 | ||||
-rw-r--r-- | liolib.c | 31 | ||||
-rw-r--r-- | loslib.c | 2 |
3 files changed, 38 insertions, 13 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 | } |
@@ -732,9 +734,12 @@ static const char *getF (lua_State *L, void *ud, size_t *size) { | |||
732 | 734 | ||
733 | 735 | ||
734 | static int errfile (lua_State *L, const char *what, int fnameindex) { | 736 | static int errfile (lua_State *L, const char *what, int fnameindex) { |
735 | const char *serr = strerror(errno); | 737 | int err = errno; |
736 | const char *filename = lua_tostring(L, fnameindex) + 1; | 738 | const char *filename = lua_tostring(L, fnameindex) + 1; |
737 | lua_pushfstring(L, "cannot %s %s: %s", what, filename, serr); | 739 | if (err != 0) |
740 | lua_pushfstring(L, "cannot %s %s: %s", what, filename, strerror(err)); | ||
741 | else | ||
742 | lua_pushfstring(L, "cannot %s %s", what, filename); | ||
738 | lua_remove(L, fnameindex); | 743 | lua_remove(L, fnameindex); |
739 | return LUA_ERRFILE; | 744 | return LUA_ERRFILE; |
740 | } | 745 | } |
@@ -787,6 +792,7 @@ LUALIB_API int luaL_loadfilex (lua_State *L, const char *filename, | |||
787 | } | 792 | } |
788 | else { | 793 | else { |
789 | lua_pushfstring(L, "@%s", filename); | 794 | lua_pushfstring(L, "@%s", filename); |
795 | errno = 0; | ||
790 | lf.f = fopen(filename, "r"); | 796 | lf.f = fopen(filename, "r"); |
791 | if (lf.f == NULL) return errfile(L, "open", fnameindex); | 797 | if (lf.f == NULL) return errfile(L, "open", fnameindex); |
792 | } | 798 | } |
@@ -796,6 +802,7 @@ LUALIB_API int luaL_loadfilex (lua_State *L, const char *filename, | |||
796 | if (c == LUA_SIGNATURE[0]) { /* binary file? */ | 802 | if (c == LUA_SIGNATURE[0]) { /* binary file? */ |
797 | lf.n = 0; /* remove possible newline */ | 803 | lf.n = 0; /* remove possible newline */ |
798 | if (filename) { /* "real" file? */ | 804 | if (filename) { /* "real" file? */ |
805 | errno = 0; | ||
799 | lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */ | 806 | lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */ |
800 | if (lf.f == NULL) return errfile(L, "reopen", fnameindex); | 807 | if (lf.f == NULL) return errfile(L, "reopen", fnameindex); |
801 | skipcomment(lf.f, &c); /* re-read initial portion */ | 808 | skipcomment(lf.f, &c); /* re-read initial portion */ |
@@ -805,6 +812,7 @@ LUALIB_API int luaL_loadfilex (lua_State *L, const char *filename, | |||
805 | lf.buff[lf.n++] = c; /* 'c' is the first character of the stream */ | 812 | lf.buff[lf.n++] = c; /* 'c' is the first character of the stream */ |
806 | status = lua_load(L, getF, &lf, lua_tostring(L, -1), mode); | 813 | status = lua_load(L, getF, &lf, lua_tostring(L, -1), mode); |
807 | readstatus = ferror(lf.f); | 814 | readstatus = ferror(lf.f); |
815 | errno = 0; /* no useful error number until here */ | ||
808 | if (filename) fclose(lf.f); /* close file (even in case of errors) */ | 816 | if (filename) fclose(lf.f); /* close file (even in case of errors) */ |
809 | if (readstatus) { | 817 | if (readstatus) { |
810 | lua_settop(L, fnameindex); /* ignore results from 'lua_load' */ | 818 | lua_settop(L, fnameindex); /* ignore results from 'lua_load' */ |
@@ -933,7 +941,7 @@ LUALIB_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len) { | |||
933 | LUALIB_API void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) { | 941 | LUALIB_API void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) { |
934 | luaL_checkstack(L, nup, "too many upvalues"); | 942 | luaL_checkstack(L, nup, "too many upvalues"); |
935 | for (; l->name != NULL; l++) { /* fill the table with given functions */ | 943 | for (; l->name != NULL; l++) { /* fill the table with given functions */ |
936 | if (l->func == NULL) /* place holder? */ | 944 | if (l->func == NULL) /* placeholder? */ |
937 | lua_pushboolean(L, 0); | 945 | lua_pushboolean(L, 0); |
938 | else { | 946 | else { |
939 | int i; | 947 | int i; |
@@ -245,8 +245,8 @@ static int f_gc (lua_State *L) { | |||
245 | */ | 245 | */ |
246 | static int io_fclose (lua_State *L) { | 246 | static int io_fclose (lua_State *L) { |
247 | LStream *p = tolstream(L); | 247 | LStream *p = tolstream(L); |
248 | int res = fclose(p->f); | 248 | errno = 0; |
249 | return luaL_fileresult(L, (res == 0), NULL); | 249 | return luaL_fileresult(L, (fclose(p->f) == 0), NULL); |
250 | } | 250 | } |
251 | 251 | ||
252 | 252 | ||
@@ -272,6 +272,7 @@ static int io_open (lua_State *L) { | |||
272 | LStream *p = newfile(L); | 272 | LStream *p = newfile(L); |
273 | const char *md = mode; /* to traverse/check mode */ | 273 | const char *md = mode; /* to traverse/check mode */ |
274 | luaL_argcheck(L, l_checkmode(md), 2, "invalid mode"); | 274 | luaL_argcheck(L, l_checkmode(md), 2, "invalid mode"); |
275 | errno = 0; | ||
275 | p->f = fopen(filename, mode); | 276 | p->f = fopen(filename, mode); |
276 | return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1; | 277 | return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1; |
277 | } | 278 | } |
@@ -292,6 +293,7 @@ static int io_popen (lua_State *L) { | |||
292 | const char *mode = luaL_optstring(L, 2, "r"); | 293 | const char *mode = luaL_optstring(L, 2, "r"); |
293 | LStream *p = newprefile(L); | 294 | LStream *p = newprefile(L); |
294 | luaL_argcheck(L, l_checkmodep(mode), 2, "invalid mode"); | 295 | luaL_argcheck(L, l_checkmodep(mode), 2, "invalid mode"); |
296 | errno = 0; | ||
295 | p->f = l_popen(L, filename, mode); | 297 | p->f = l_popen(L, filename, mode); |
296 | p->closef = &io_pclose; | 298 | p->closef = &io_pclose; |
297 | return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1; | 299 | return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1; |
@@ -300,6 +302,7 @@ static int io_popen (lua_State *L) { | |||
300 | 302 | ||
301 | static int io_tmpfile (lua_State *L) { | 303 | static int io_tmpfile (lua_State *L) { |
302 | LStream *p = newfile(L); | 304 | LStream *p = newfile(L); |
305 | errno = 0; | ||
303 | p->f = tmpfile(); | 306 | p->f = tmpfile(); |
304 | return (p->f == NULL) ? luaL_fileresult(L, 0, NULL) : 1; | 307 | return (p->f == NULL) ? luaL_fileresult(L, 0, NULL) : 1; |
305 | } | 308 | } |
@@ -603,8 +606,10 @@ static int g_read (lua_State *L, FILE *f, int first) { | |||
603 | } | 606 | } |
604 | } | 607 | } |
605 | } | 608 | } |
606 | if (ferror(f)) | 609 | if (ferror(f)) { |
610 | errno = 0; /* no relevant errno here */ | ||
607 | return luaL_fileresult(L, 0, NULL); | 611 | return luaL_fileresult(L, 0, NULL); |
612 | } | ||
608 | if (!success) { | 613 | if (!success) { |
609 | lua_pop(L, 1); /* remove last result */ | 614 | lua_pop(L, 1); /* remove last result */ |
610 | luaL_pushfail(L); /* push nil instead */ | 615 | luaL_pushfail(L); /* push nil instead */ |
@@ -678,7 +683,10 @@ static int g_write (lua_State *L, FILE *f, int arg) { | |||
678 | } | 683 | } |
679 | if (l_likely(status)) | 684 | if (l_likely(status)) |
680 | return 1; /* file handle already on stack top */ | 685 | return 1; /* file handle already on stack top */ |
681 | else return luaL_fileresult(L, status, NULL); | 686 | else { |
687 | errno = 0; /* no relevant errno here */ | ||
688 | return luaL_fileresult(L, status, NULL); | ||
689 | } | ||
682 | } | 690 | } |
683 | 691 | ||
684 | 692 | ||
@@ -703,6 +711,7 @@ static int f_seek (lua_State *L) { | |||
703 | l_seeknum offset = (l_seeknum)p3; | 711 | l_seeknum offset = (l_seeknum)p3; |
704 | luaL_argcheck(L, (lua_Integer)offset == p3, 3, | 712 | luaL_argcheck(L, (lua_Integer)offset == p3, 3, |
705 | "not an integer in proper range"); | 713 | "not an integer in proper range"); |
714 | errno = 0; | ||
706 | op = l_fseek(f, offset, mode[op]); | 715 | op = l_fseek(f, offset, mode[op]); |
707 | if (l_unlikely(op)) | 716 | if (l_unlikely(op)) |
708 | return luaL_fileresult(L, 0, NULL); /* error */ | 717 | return luaL_fileresult(L, 0, NULL); /* error */ |
@@ -719,19 +728,25 @@ static int f_setvbuf (lua_State *L) { | |||
719 | FILE *f = tofile(L); | 728 | FILE *f = tofile(L); |
720 | int op = luaL_checkoption(L, 2, NULL, modenames); | 729 | int op = luaL_checkoption(L, 2, NULL, modenames); |
721 | lua_Integer sz = luaL_optinteger(L, 3, LUAL_BUFFERSIZE); | 730 | lua_Integer sz = luaL_optinteger(L, 3, LUAL_BUFFERSIZE); |
722 | int res = setvbuf(f, NULL, mode[op], (size_t)sz); | 731 | int res; |
732 | errno = 0; | ||
733 | res = setvbuf(f, NULL, mode[op], (size_t)sz); | ||
723 | return luaL_fileresult(L, res == 0, NULL); | 734 | return luaL_fileresult(L, res == 0, NULL); |
724 | } | 735 | } |
725 | 736 | ||
726 | 737 | ||
727 | 738 | ||
728 | static int io_flush (lua_State *L) { | 739 | static int io_flush (lua_State *L) { |
729 | return luaL_fileresult(L, fflush(getiofile(L, IO_OUTPUT)) == 0, NULL); | 740 | FILE *f = getiofile(L, IO_OUTPUT); |
741 | errno = 0; | ||
742 | return luaL_fileresult(L, fflush(f) == 0, NULL); | ||
730 | } | 743 | } |
731 | 744 | ||
732 | 745 | ||
733 | static int f_flush (lua_State *L) { | 746 | static int f_flush (lua_State *L) { |
734 | return luaL_fileresult(L, fflush(tofile(L)) == 0, NULL); | 747 | FILE *f = tofile(L); |
748 | errno = 0; | ||
749 | return luaL_fileresult(L, fflush(f) == 0, NULL); | ||
735 | } | 750 | } |
736 | 751 | ||
737 | 752 | ||
@@ -773,7 +788,7 @@ static const luaL_Reg meth[] = { | |||
773 | ** metamethods for file handles | 788 | ** metamethods for file handles |
774 | */ | 789 | */ |
775 | static const luaL_Reg metameth[] = { | 790 | static const luaL_Reg metameth[] = { |
776 | {"__index", NULL}, /* place holder */ | 791 | {"__index", NULL}, /* placeholder */ |
777 | {"__gc", f_gc}, | 792 | {"__gc", f_gc}, |
778 | {"__close", f_gc}, | 793 | {"__close", f_gc}, |
779 | {"__tostring", f_tostring}, | 794 | {"__tostring", f_tostring}, |
@@ -155,6 +155,7 @@ static int os_execute (lua_State *L) { | |||
155 | 155 | ||
156 | static int os_remove (lua_State *L) { | 156 | static int os_remove (lua_State *L) { |
157 | const char *filename = luaL_checkstring(L, 1); | 157 | const char *filename = luaL_checkstring(L, 1); |
158 | errno = 0; | ||
158 | return luaL_fileresult(L, remove(filename) == 0, filename); | 159 | return luaL_fileresult(L, remove(filename) == 0, filename); |
159 | } | 160 | } |
160 | 161 | ||
@@ -162,6 +163,7 @@ static int os_remove (lua_State *L) { | |||
162 | static int os_rename (lua_State *L) { | 163 | static int os_rename (lua_State *L) { |
163 | const char *fromname = luaL_checkstring(L, 1); | 164 | const char *fromname = luaL_checkstring(L, 1); |
164 | const char *toname = luaL_checkstring(L, 2); | 165 | const char *toname = luaL_checkstring(L, 2); |
166 | errno = 0; | ||
165 | return luaL_fileresult(L, rename(fromname, toname) == 0, NULL); | 167 | return luaL_fileresult(L, rename(fromname, toname) == 0, NULL); |
166 | } | 168 | } |
167 | 169 | ||