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 /liolib.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 'liolib.c')
-rw-r--r-- | liolib.c | 25 |
1 files changed, 19 insertions, 6 deletions
@@ -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 | } |
@@ -567,6 +570,7 @@ static int g_read (lua_State *L, FILE *f, int first) { | |||
567 | int nargs = lua_gettop(L) - 1; | 570 | int nargs = lua_gettop(L) - 1; |
568 | int n, success; | 571 | int n, success; |
569 | clearerr(f); | 572 | clearerr(f); |
573 | errno = 0; | ||
570 | if (nargs == 0) { /* no arguments? */ | 574 | if (nargs == 0) { /* no arguments? */ |
571 | success = read_line(L, f, 1); | 575 | success = read_line(L, f, 1); |
572 | n = first + 1; /* to return 1 result */ | 576 | n = first + 1; /* to return 1 result */ |
@@ -660,6 +664,7 @@ static int io_readline (lua_State *L) { | |||
660 | static int g_write (lua_State *L, FILE *f, int arg) { | 664 | static int g_write (lua_State *L, FILE *f, int arg) { |
661 | int nargs = lua_gettop(L) - arg; | 665 | int nargs = lua_gettop(L) - arg; |
662 | int status = 1; | 666 | int status = 1; |
667 | errno = 0; | ||
663 | for (; nargs--; arg++) { | 668 | for (; nargs--; arg++) { |
664 | if (lua_type(L, arg) == LUA_TNUMBER) { | 669 | if (lua_type(L, arg) == LUA_TNUMBER) { |
665 | /* optimization: could be done exactly as for strings */ | 670 | /* optimization: could be done exactly as for strings */ |
@@ -678,7 +683,8 @@ 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 | return luaL_fileresult(L, status, NULL); | ||
682 | } | 688 | } |
683 | 689 | ||
684 | 690 | ||
@@ -703,6 +709,7 @@ static int f_seek (lua_State *L) { | |||
703 | l_seeknum offset = (l_seeknum)p3; | 709 | l_seeknum offset = (l_seeknum)p3; |
704 | luaL_argcheck(L, (lua_Integer)offset == p3, 3, | 710 | luaL_argcheck(L, (lua_Integer)offset == p3, 3, |
705 | "not an integer in proper range"); | 711 | "not an integer in proper range"); |
712 | errno = 0; | ||
706 | op = l_fseek(f, offset, mode[op]); | 713 | op = l_fseek(f, offset, mode[op]); |
707 | if (l_unlikely(op)) | 714 | if (l_unlikely(op)) |
708 | return luaL_fileresult(L, 0, NULL); /* error */ | 715 | return luaL_fileresult(L, 0, NULL); /* error */ |
@@ -719,19 +726,25 @@ static int f_setvbuf (lua_State *L) { | |||
719 | FILE *f = tofile(L); | 726 | FILE *f = tofile(L); |
720 | int op = luaL_checkoption(L, 2, NULL, modenames); | 727 | int op = luaL_checkoption(L, 2, NULL, modenames); |
721 | lua_Integer sz = luaL_optinteger(L, 3, LUAL_BUFFERSIZE); | 728 | lua_Integer sz = luaL_optinteger(L, 3, LUAL_BUFFERSIZE); |
722 | int res = setvbuf(f, NULL, mode[op], (size_t)sz); | 729 | int res; |
730 | errno = 0; | ||
731 | res = setvbuf(f, NULL, mode[op], (size_t)sz); | ||
723 | return luaL_fileresult(L, res == 0, NULL); | 732 | return luaL_fileresult(L, res == 0, NULL); |
724 | } | 733 | } |
725 | 734 | ||
726 | 735 | ||
727 | 736 | ||
728 | static int io_flush (lua_State *L) { | 737 | static int io_flush (lua_State *L) { |
729 | return luaL_fileresult(L, fflush(getiofile(L, IO_OUTPUT)) == 0, NULL); | 738 | FILE *f = getiofile(L, IO_OUTPUT); |
739 | errno = 0; | ||
740 | return luaL_fileresult(L, fflush(f) == 0, NULL); | ||
730 | } | 741 | } |
731 | 742 | ||
732 | 743 | ||
733 | static int f_flush (lua_State *L) { | 744 | static int f_flush (lua_State *L) { |
734 | return luaL_fileresult(L, fflush(tofile(L)) == 0, NULL); | 745 | FILE *f = tofile(L); |
746 | errno = 0; | ||
747 | return luaL_fileresult(L, fflush(f) == 0, NULL); | ||
735 | } | 748 | } |
736 | 749 | ||
737 | 750 | ||