aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2024-06-04 12:48:29 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2024-06-04 12:48:29 -0300
commitd5212c13b081ed62d8e1ae436779e79c79edf564 (patch)
tree936ac196173318f51bec43077a2006ef48a88813
parente0efebdbe4e4053c6fb78588c546f1dc23aa964a (diff)
downloadlua-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.c18
-rw-r--r--liolib.c31
-rw-r--r--loslib.c2
3 files changed, 38 insertions, 13 deletions
diff --git a/lauxlib.c b/lauxlib.c
index 1c9082e6..28bff274 100644
--- a/lauxlib.c
+++ b/lauxlib.c
@@ -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
734static int errfile (lua_State *L, const char *what, int fnameindex) { 736static 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) {
933LUALIB_API void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) { 941LUALIB_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;
diff --git a/liolib.c b/liolib.c
index b08397da..82f444b0 100644
--- a/liolib.c
+++ b/liolib.c
@@ -245,8 +245,8 @@ static int f_gc (lua_State *L) {
245*/ 245*/
246static int io_fclose (lua_State *L) { 246static 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
301static int io_tmpfile (lua_State *L) { 303static 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
728static int io_flush (lua_State *L) { 739static 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
733static int f_flush (lua_State *L) { 746static 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*/
775static const luaL_Reg metameth[] = { 790static 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},
diff --git a/loslib.c b/loslib.c
index ad5a9276..ba80d72c 100644
--- a/loslib.c
+++ b/loslib.c
@@ -155,6 +155,7 @@ static int os_execute (lua_State *L) {
155 155
156static int os_remove (lua_State *L) { 156static 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) {
162static int os_rename (lua_State *L) { 163static 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