mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-07 23:24:09 +00:00
From Lua 5.2: Extended results from os.execute() and pipe:close().
Needs -DLUAJIT_ENABLE_LUA52COMPAT.
This commit is contained in:
parent
125cc87988
commit
cfca926cc2
@ -76,6 +76,8 @@ LUALIB_API const char *(luaL_findtable) (lua_State *L, int idx,
|
||||
const char *fname, int szhint);
|
||||
|
||||
/* From Lua 5.2. */
|
||||
LUALIB_API int luaL_fileresult(lua_State *L, int stat, const char *fname);
|
||||
LUALIB_API int luaL_execresult(lua_State *L, int stat);
|
||||
LUALIB_API int (luaL_loadfilex) (lua_State *L, const char *filename,
|
||||
const char *mode);
|
||||
LUALIB_API int (luaL_loadbufferx) (lua_State *L, const char *buff, size_t sz,
|
||||
|
@ -19,8 +19,63 @@
|
||||
#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,
|
||||
|
56
src/lib_io.c
56
src/lib_io.c
@ -17,11 +17,9 @@
|
||||
#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. */
|
||||
@ -40,26 +38,6 @@ typedef struct IOFileUD {
|
||||
#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)
|
||||
@ -114,12 +92,20 @@ static int io_file_close(lua_State *L, IOFileUD *iof)
|
||||
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
|
||||
ok = 0;
|
||||
lua_assert(0);
|
||||
return 0;
|
||||
#endif
|
||||
#if LJ_52
|
||||
iof->fp = NULL;
|
||||
return luaL_execresult(L, stat);
|
||||
#else
|
||||
ok = (stat != -1);
|
||||
#endif
|
||||
} else {
|
||||
lua_assert((iof->type & IOFILE_TYPE_MASK) == IOFILE_TYPE_STDF);
|
||||
@ -128,7 +114,7 @@ static int io_file_close(lua_State *L, IOFileUD *iof)
|
||||
return 2;
|
||||
}
|
||||
iof->fp = NULL;
|
||||
return io_pushresult(L, ok, NULL);
|
||||
return luaL_fileresult(L, ok, NULL);
|
||||
}
|
||||
|
||||
/* -- Read/write helpers -------------------------------------------------- */
|
||||
@ -233,7 +219,7 @@ static int io_file_read(lua_State *L, FILE *fp, int start)
|
||||
}
|
||||
}
|
||||
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;
|
||||
@ -258,7 +244,7 @@ static int io_file_write(lua_State *L, FILE *fp, int 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 ---------------------------------------------------- */
|
||||
@ -284,7 +270,7 @@ LJLIB_CF(io_method_write) LJLIB_REC(io_write 0)
|
||||
|
||||
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)
|
||||
@ -316,7 +302,7 @@ 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
|
||||
@ -338,7 +324,7 @@ LJLIB_CF(io_method_setvbuf)
|
||||
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 */
|
||||
@ -386,7 +372,7 @@ LJLIB_CF(io_open)
|
||||
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)
|
||||
@ -403,7 +389,7 @@ 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
|
||||
@ -417,7 +403,7 @@ LJLIB_CF(io_tmpfile)
|
||||
#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)
|
||||
@ -437,7 +423,7 @@ LJLIB_CF(io_write) LJLIB_REC(io_write GCROOT_IO_OUTPUT)
|
||||
|
||||
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)
|
||||
|
36
src/lib_os.c
36
src/lib_os.c
@ -31,41 +31,41 @@
|
||||
|
||||
#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
|
||||
lua_pushinteger(L, -1);
|
||||
#if LJ_52
|
||||
errno = ENOSYS;
|
||||
return luaL_fileresult(L, 0, NULL);
|
||||
#else
|
||||
lua_pushinteger(L, system(luaL_optstring(L, 1, NULL)));
|
||||
lua_pushinteger(L, -1);
|
||||
return 1;
|
||||
#endif
|
||||
#else
|
||||
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)
|
||||
|
Loading…
Reference in New Issue
Block a user