#include "lj_obj.h"
#include "lj_err.h"
#include "lj_state.h"
+#include "lj_trace.h"
#include "lj_lib.h"
+#if LJ_TARGET_POSIX
+#include <sys/wait.h>
+#endif
+
+/* -- I/O error handling -------------------------------------------------- */
+
+LUALIB_API int luaL_fileresult(lua_State *L, int stat, const char *fname)
+{
+ if (stat) {
+ setboolV(L->top++, 1);
+ return 1;
+ } else {
+ int en = errno; /* Lua API calls may change this value. */
+ setnilV(L->top++);
+ if (fname)
+ lua_pushfstring(L, "%s: %s", fname, strerror(en));
+ else
+ lua_pushfstring(L, "%s", strerror(en));
+ setintV(L->top++, en);
+ lj_trace_abort(G(L));
+ return 3;
+ }
+}
+
+LUALIB_API int luaL_execresult(lua_State *L, int stat)
+{
+ if (stat != -1) {
+#if LJ_TARGET_POSIX
+ if (WIFSIGNALED(stat)) {
+ stat = WTERMSIG(stat);
+ setnilV(L->top++);
+ lua_pushliteral(L, "signal");
+ } else {
+ if (WIFEXITED(stat))
+ stat = WEXITSTATUS(stat);
+ if (stat == 0)
+ setboolV(L->top++, 1);
+ else
+ setnilV(L->top++);
+ lua_pushliteral(L, "exit");
+ }
+#else
+ if (stat == 0)
+ setboolV(L->top++, 1);
+ else
+ setnilV(L->top++);
+ lua_pushliteral(L, "exit");
+#endif
+ setintV(L->top++, stat);
+ return 3;
+ }
+ return luaL_fileresult(L, 0, NULL);
+}
+
/* -- Module registration ------------------------------------------------- */
LUALIB_API const char *luaL_findtable(lua_State *L, int idx,
#include "lualib.h"
#include "lj_obj.h"
-#include "lj_gc.h"
#include "lj_err.h"
#include "lj_str.h"
#include "lj_ff.h"
-#include "lj_trace.h"
#include "lj_lib.h"
/* Userdata payload for I/O file. */
#define IOSTDF_UD(L, id) (&gcref(G(L)->gcroot[(id)])->ud)
#define IOSTDF_IOF(L, id) ((IOFileUD *)uddata(IOSTDF_UD(L, (id))))
-/* -- Error handling ------------------------------------------------------ */
-
-static int io_pushresult(lua_State *L, int ok, const char *fname)
-{
- if (ok) {
- setboolV(L->top++, 1);
- return 1;
- } else {
- int en = errno; /* Lua API calls may change this value. */
- setnilV(L->top++);
- if (fname)
- lua_pushfstring(L, "%s: %s", fname, strerror(en));
- else
- lua_pushfstring(L, "%s", strerror(en));
- setintV(L->top++, en);
- lj_trace_abort(G(L));
- return 3;
- }
-}
-
/* -- Open/close helpers -------------------------------------------------- */
static IOFileUD *io_tofilep(lua_State *L)
if ((iof->type & IOFILE_TYPE_MASK) == IOFILE_TYPE_FILE) {
ok = (fclose(iof->fp) == 0);
} else if ((iof->type & IOFILE_TYPE_MASK) == IOFILE_TYPE_PIPE) {
+ int stat = -1;
#if LJ_TARGET_POSIX
- ok = (pclose(iof->fp) != -1);
+ stat = pclose(iof->fp);
#elif LJ_TARGET_WINDOWS
- ok = (_pclose(iof->fp) != -1);
+ stat = _pclose(iof->fp);
+#else
+ lua_assert(0);
+ return 0;
+#endif
+#if LJ_52
+ iof->fp = NULL;
+ return luaL_execresult(L, stat);
#else
- ok = 0;
+ ok = (stat != -1);
#endif
} else {
lua_assert((iof->type & IOFILE_TYPE_MASK) == IOFILE_TYPE_STDF);
return 2;
}
iof->fp = NULL;
- return io_pushresult(L, ok, NULL);
+ return luaL_fileresult(L, ok, NULL);
}
/* -- Read/write helpers -------------------------------------------------- */
}
}
if (ferror(fp))
- return io_pushresult(L, 0, NULL);
+ return luaL_fileresult(L, 0, NULL);
if (!ok)
setnilV(L->top-1); /* Replace last result with nil. */
return n - start;
lj_err_argt(L, (int)(tv - L->base) + 1, LUA_TSTRING);
}
}
- return io_pushresult(L, status, NULL);
+ return luaL_fileresult(L, status, NULL);
}
/* -- I/O file methods ---------------------------------------------------- */
LJLIB_CF(io_method_flush) LJLIB_REC(io_flush 0)
{
- return io_pushresult(L, fflush(io_tofile(L)->fp) == 0, NULL);
+ return luaL_fileresult(L, fflush(io_tofile(L)->fp) == 0, NULL);
}
LJLIB_CF(io_method_seek)
res = fseek(fp, (long)ofs, opt);
#endif
if (res)
- return io_pushresult(L, 0, NULL);
+ return luaL_fileresult(L, 0, NULL);
#if LJ_TARGET_POSIX
ofs = ftello(fp);
#elif _MSC_VER >= 1400
if (opt == 0) opt = _IOFBF;
else if (opt == 1) opt = _IOLBF;
else if (opt == 2) opt = _IONBF;
- return io_pushresult(L, setvbuf(fp, NULL, opt, sz) == 0, NULL);
+ return luaL_fileresult(L, setvbuf(fp, NULL, opt, sz) == 0, NULL);
}
LJLIB_PUSH(top-2) /* io_lines_iter */
const char *mode = s ? strdata(s) : "r";
IOFileUD *iof = io_file_new(L);
iof->fp = fopen(fname, mode);
- return iof->fp != NULL ? 1 : io_pushresult(L, 0, fname);
+ return iof->fp != NULL ? 1 : luaL_fileresult(L, 0, fname);
}
LJLIB_CF(io_popen)
#else
iof->fp = _popen(fname, mode);
#endif
- return iof->fp != NULL ? 1 : io_pushresult(L, 0, fname);
+ return iof->fp != NULL ? 1 : luaL_fileresult(L, 0, fname);
#else
return luaL_error(L, LUA_QL("popen") " not supported");
#endif
#else
iof->fp = tmpfile();
#endif
- return iof->fp != NULL ? 1 : io_pushresult(L, 0, NULL);
+ return iof->fp != NULL ? 1 : luaL_fileresult(L, 0, NULL);
}
LJLIB_CF(io_close)
LJLIB_CF(io_flush) LJLIB_REC(io_flush GCROOT_IO_OUTPUT)
{
- return io_pushresult(L, fflush(io_stdfile(L, GCROOT_IO_OUTPUT)) == 0, NULL);
+ return luaL_fileresult(L, fflush(io_stdfile(L, GCROOT_IO_OUTPUT)) == 0, NULL);
}
static int io_std_getset(lua_State *L, ptrdiff_t id, const char *mode)
#define LJLIB_MODULE_os
-static int os_pushresult(lua_State *L, int i, const char *filename)
-{
- int en = errno; /* calls to Lua API may change this value */
- if (i) {
- setboolV(L->top-1, 1);
- return 1;
- } else {
- setnilV(L->top-1);
- lua_pushfstring(L, "%s: %s", filename, strerror(en));
- lua_pushinteger(L, en);
- return 3;
- }
-}
-
LJLIB_CF(os_execute)
{
#if LJ_TARGET_CONSOLE
+#if LJ_52
+ errno = ENOSYS;
+ return luaL_fileresult(L, 0, NULL);
+#else
lua_pushinteger(L, -1);
+ return 1;
+#endif
#else
- lua_pushinteger(L, system(luaL_optstring(L, 1, NULL)));
+ const char *cmd = luaL_optstring(L, 1, NULL);
+ int stat = system(cmd);
+#if LJ_52
+ if (cmd)
+ return luaL_execresult(L, stat);
+ setboolV(L->top++, 1);
+#else
+ setintV(L->top++, stat);
#endif
return 1;
+#endif
}
LJLIB_CF(os_remove)
{
const char *filename = luaL_checkstring(L, 1);
- return os_pushresult(L, remove(filename) == 0, filename);
+ return luaL_fileresult(L, remove(filename) == 0, filename);
}
LJLIB_CF(os_rename)
{
const char *fromname = luaL_checkstring(L, 1);
const char *toname = luaL_checkstring(L, 2);
- return os_pushresult(L, rename(fromname, toname) == 0, fromname);
+ return luaL_fileresult(L, rename(fromname, toname) == 0, fromname);
}
LJLIB_CF(os_tmpname)