diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2011-02-21 16:12:54 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2011-02-21 16:12:54 -0300 |
| commit | 03b769053a4288742fb4739fa47508ec735e2036 (patch) | |
| tree | 9cbcfbcbb70cb9901e936545257a6aad206b4bd0 /liolib.c | |
| parent | 3c710f056b683136a342bc5bf88d852717cd0d33 (diff) | |
| download | lua-03b769053a4288742fb4739fa47508ec735e2036.tar.gz lua-03b769053a4288742fb4739fa47508ec735e2036.tar.bz2 lua-03b769053a4288742fb4739fa47508ec735e2036.zip | |
correct interpretation of return value from pclose
Diffstat (limited to 'liolib.c')
| -rw-r--r-- | liolib.c | 62 |
1 files changed, 34 insertions, 28 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: liolib.c,v 2.96 2011/01/26 16:30:02 roberto Exp roberto $ | 2 | ** $Id: liolib.c,v 2.97 2011/02/10 15:35:50 roberto Exp roberto $ |
| 3 | ** Standard I/O (and system) library | 3 | ** Standard I/O (and system) library |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -31,40 +31,42 @@ | |||
| 31 | #if defined(LUA_USE_POPEN) /* { */ | 31 | #if defined(LUA_USE_POPEN) /* { */ |
| 32 | 32 | ||
| 33 | #define lua_popen(L,c,m) ((void)L, fflush(NULL), popen(c,m)) | 33 | #define lua_popen(L,c,m) ((void)L, fflush(NULL), popen(c,m)) |
| 34 | #define lua_pclose(L,file) ((void)L, pclose(file)) | ||
| 35 | |||
| 34 | 36 | ||
| 35 | #if defined(LUA_USE_POSIX) /* { */ | 37 | #if defined(LUA_USE_POSIX) /* { */ |
| 36 | 38 | ||
| 37 | #include <sys/wait.h> | 39 | #include <sys/wait.h> |
| 38 | 40 | ||
| 39 | #define lua_pclose(L,file,stat,tp) \ | 41 | /* |
| 40 | {(void)L; \ | 42 | ** use appropriate macros to interpret 'pclose' return status |
| 41 | stat = pclose(file); \ | 43 | */ |
| 42 | if (stat == -1) { /* keep this value */ } \ | 44 | #define inspectstat(stat,what) \ |
| 43 | else if (WIFEXITED(stat)) { stat = WEXITSTATUS(stat); tp = "exit"; } \ | 45 | if (WIFEXITED(stat)) { stat = WEXITSTATUS(stat); } \ |
| 44 | else if (WIFSIGNALED(stat)) { stat = WTERMSIG(stat); tp = "signal"; } \ | 46 | else if (WIFSIGNALED(stat)) { stat = WTERMSIG(stat); what = "signal"; } |
| 45 | else if (WIFSTOPPED(stat)) { stat = WSTOPSIG(stat); tp = "stop"; } } | ||
| 46 | |||
| 47 | #else /* }{ */ | ||
| 48 | |||
| 49 | #define lua_pclose(L,file,stat,tp) {(void)L; stat = pclose(file);} | ||
| 50 | 47 | ||
| 51 | #endif /* } */ | 48 | #endif /* } */ |
| 52 | 49 | ||
| 53 | #elif defined(LUA_WIN) /* }{ */ | 50 | #elif defined(LUA_WIN) /* }{ */ |
| 54 | 51 | ||
| 55 | #define lua_popen(L,c,m) ((void)L, _popen(c,m)) | 52 | #define lua_popen(L,c,m) ((void)L, _popen(c,m)) |
| 56 | #define lua_pclose(L,file,stat,tp) {(void)L; stat = _pclose(file);} | 53 | #define lua_pclose(L,file) ((void)L, _pclose(file)) |
| 54 | |||
| 57 | 55 | ||
| 58 | #else /* }{ */ | 56 | #else /* }{ */ |
| 59 | 57 | ||
| 60 | #define lua_popen(L,c,m) ((void)((void)c, m), \ | 58 | #define lua_popen(L,c,m) ((void)((void)c, m), \ |
| 61 | luaL_error(L, LUA_QL("popen") " not supported"), (FILE*)0) | 59 | luaL_error(L, LUA_QL("popen") " not supported"), (FILE*)0) |
| 62 | #define lua_pclose(L,file,stat,tp) {(void)L; (void)file; stat = -1;} | 60 | #define lua_pclose(L,file) ((void)((void)L, file), -1) |
| 61 | |||
| 63 | 62 | ||
| 64 | #endif /* } */ | 63 | #endif /* } */ |
| 65 | 64 | ||
| 66 | #endif /* } */ | 65 | #endif /* } */ |
| 67 | 66 | ||
| 67 | #if !defined(inspectstat) | ||
| 68 | #define inspectstat(stat,what) /* no op */ | ||
| 69 | #endif | ||
| 68 | 70 | ||
| 69 | 71 | ||
| 70 | #define IO_INPUT 1 | 72 | #define IO_INPUT 1 |
| @@ -159,16 +161,21 @@ static int io_noclose (lua_State *L) { | |||
| 159 | */ | 161 | */ |
| 160 | static int io_pclose (lua_State *L) { | 162 | static int io_pclose (lua_State *L) { |
| 161 | FILE **p = tofilep(L); | 163 | FILE **p = tofilep(L); |
| 162 | int stat; | 164 | int stat = lua_pclose(L, *p); |
| 163 | const char *tp = NULL; /* type of termination (when available) */ | 165 | const char *what = "exit"; /* type of termination */ |
| 164 | lua_pclose(L, *p, stat, tp); | 166 | *p = NULL; /* mark stream as closed (for GC) */ |
| 165 | *p = NULL; | ||
| 166 | if (stat == -1) /* error? */ | 167 | if (stat == -1) /* error? */ |
| 167 | return pushresult(L, 0, NULL); | 168 | return pushresult(L, 0, NULL); |
| 168 | else { | 169 | else { |
| 169 | lua_pushinteger(L, stat); | 170 | inspectstat(stat, what); /* interpret result from 'pclose' */ |
| 170 | lua_pushstring(L, tp); | 171 | if (*what == 'e' && stat == 0) /* successful termination? */ |
| 171 | return 2; /* return status and type */ | 172 | return pushresult(L, 1, NULL); |
| 173 | else { /* return nil,what,code */ | ||
| 174 | lua_pushnil(L); | ||
| 175 | lua_pushstring(L, what); | ||
| 176 | lua_pushinteger(L, stat); | ||
| 177 | return 3; | ||
| 178 | } | ||
| 172 | } | 179 | } |
| 173 | } | 180 | } |
| 174 | 181 | ||
| @@ -179,7 +186,7 @@ static int io_pclose (lua_State *L) { | |||
| 179 | static int io_fclose (lua_State *L) { | 186 | static int io_fclose (lua_State *L) { |
| 180 | FILE **p = tofilep(L); | 187 | FILE **p = tofilep(L); |
| 181 | int ok = (fclose(*p) == 0); | 188 | int ok = (fclose(*p) == 0); |
| 182 | *p = NULL; | 189 | *p = NULL; /* mark stream as closed (for GC) */ |
| 183 | return pushresult(L, ok, NULL); | 190 | return pushresult(L, ok, NULL); |
| 184 | } | 191 | } |
| 185 | 192 | ||
| @@ -201,8 +208,7 @@ static int io_close (lua_State *L) { | |||
| 201 | 208 | ||
| 202 | static int io_gc (lua_State *L) { | 209 | static int io_gc (lua_State *L) { |
| 203 | FILE *f = *tofilep(L); | 210 | FILE *f = *tofilep(L); |
| 204 | /* ignore closed files */ | 211 | if (f != NULL) /* ignore closed files */ |
| 205 | if (f != NULL) | ||
| 206 | aux_close(L); | 212 | aux_close(L); |
| 207 | return 0; | 213 | return 0; |
| 208 | } | 214 | } |
| @@ -225,8 +231,8 @@ static int io_open (lua_State *L) { | |||
| 225 | int i = 0; | 231 | int i = 0; |
| 226 | /* check whether 'mode' matches '[rwa]%+?b?' */ | 232 | /* check whether 'mode' matches '[rwa]%+?b?' */ |
| 227 | if (!(mode[i] != '\0' && strchr("rwa", mode[i++]) != NULL && | 233 | if (!(mode[i] != '\0' && strchr("rwa", mode[i++]) != NULL && |
| 228 | (mode[i] != '+' || ++i) && /* skip if char is '+' */ | 234 | (mode[i] != '+' || ++i) && /* skip if char is '+' */ |
| 229 | (mode[i] != 'b' || ++i) && /* skip if char is 'b' */ | 235 | (mode[i] != 'b' || ++i) && /* skip if char is 'b' */ |
| 230 | (mode[i] == '\0'))) | 236 | (mode[i] == '\0'))) |
| 231 | luaL_error(L, "invalid mode " LUA_QL("%s") | 237 | luaL_error(L, "invalid mode " LUA_QL("%s") |
| 232 | " (should match " LUA_QL("[rwa]%%+?b?") ")", mode); | 238 | " (should match " LUA_QL("[rwa]%%+?b?") ")", mode); |
| @@ -325,7 +331,7 @@ static int io_lines (lua_State *L) { | |||
| 325 | if (lua_isnone(L, 1)) lua_pushnil(L); /* at least one argument */ | 331 | if (lua_isnone(L, 1)) lua_pushnil(L); /* at least one argument */ |
| 326 | if (lua_isnil(L, 1)) { /* no file name? */ | 332 | if (lua_isnil(L, 1)) { /* no file name? */ |
| 327 | lua_rawgeti(L, lua_upvalueindex(1), IO_INPUT); /* get default input */ | 333 | lua_rawgeti(L, lua_upvalueindex(1), IO_INPUT); /* get default input */ |
| 328 | lua_replace(L, 1); /* put it at index 1 */ | 334 | lua_replace(L, 1); /* put it at index 1 */ |
| 329 | tofile(L); /* check that it's a valid file handle */ | 335 | tofile(L); /* check that it's a valid file handle */ |
| 330 | toclose = 0; /* do not close it after iteration */ | 336 | toclose = 0; /* do not close it after iteration */ |
| 331 | } | 337 | } |
| @@ -335,7 +341,7 @@ static int io_lines (lua_State *L) { | |||
| 335 | *pf = fopen(filename, "r"); | 341 | *pf = fopen(filename, "r"); |
| 336 | if (*pf == NULL) | 342 | if (*pf == NULL) |
| 337 | fileerror(L, 1, filename); | 343 | fileerror(L, 1, filename); |
| 338 | lua_replace(L, 1); /* put file at index 1 */ | 344 | lua_replace(L, 1); /* put file at index 1 */ |
| 339 | toclose = 1; /* close it after iteration */ | 345 | toclose = 1; /* close it after iteration */ |
| 340 | } | 346 | } |
| 341 | aux_lines(L, toclose); | 347 | aux_lines(L, toclose); |
