diff options
-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); |