diff options
| author | ruki <[email protected]> | 2016-07-04 23:59:59 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2016-07-04 23:59:59 +0800 |
| commit | 1589758d311b92b6e19592768613ebd773bb94f0 (patch) | |
| tree | 4071c7a178978bf39b246e7b84f38cfabae69381 | |
| parent | 0bb5ee3e8b5ee719c1bada87be11baca81722afd (diff) | |
add os.execv
| -rwxr-xr-x | core/src/xmake/machine.c | 2 | ||||
| -rwxr-xr-x | core/src/xmake/makefile | 1 | ||||
| -rwxr-xr-x | core/src/xmake/process/open.c | 2 | ||||
| -rwxr-xr-x | core/src/xmake/process/openv.c | 133 | ||||
| -rwxr-xr-x | xmake/actions/run/main.lua | 4 | ||||
| -rw-r--r-- | xmake/core/base/os.lua | 71 | ||||
| -rw-r--r-- | xmake/core/sandbox/modules/os.lua | 19 |
7 files changed, 226 insertions, 6 deletions
diff --git a/core/src/xmake/machine.c b/core/src/xmake/machine.c index 616de4eec..597765209 100755 --- a/core/src/xmake/machine.c +++ b/core/src/xmake/machine.c @@ -83,6 +83,7 @@ tb_int_t xm_string_startswith(lua_State* lua); // the process functions tb_int_t xm_process_open(lua_State* lua); +tb_int_t xm_process_openv(lua_State* lua); tb_int_t xm_process_wait(lua_State* lua); tb_int_t xm_process_close(lua_State* lua); @@ -138,6 +139,7 @@ static luaL_Reg const g_string_functions[] = static luaL_Reg const g_process_functions[] = { { "open", xm_process_open } +, { "openv", xm_process_openv } , { "wait", xm_process_wait } , { "close", xm_process_close } , { tb_null, tb_null } diff --git a/core/src/xmake/makefile b/core/src/xmake/makefile index 77a12034b..32c3d903f 100755 --- a/core/src/xmake/makefile +++ b/core/src/xmake/makefile @@ -41,6 +41,7 @@ xmake_C_FILES += \ string/endswith \ string/startswith \ process/open \ + process/openv \ process/wait \ process/close diff --git a/core/src/xmake/process/open.c b/core/src/xmake/process/open.c index 3d8a63c98..2a2ee99af 100755 --- a/core/src/xmake/process/open.c +++ b/core/src/xmake/process/open.c @@ -36,7 +36,7 @@ * implementation */ -// p = process.open(command) +// p = process.open(command, outfile, errfile) tb_int_t xm_process_open(lua_State* lua) { // check diff --git a/core/src/xmake/process/openv.c b/core/src/xmake/process/openv.c new file mode 100755 index 000000000..8f99c4535 --- /dev/null +++ b/core/src/xmake/process/openv.c @@ -0,0 +1,133 @@ +/*!The Automatic Cross-platform Build Tool + * + * XMake is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or + * (at your option) any later version. + * + * XMake is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with XMake; + * If not, see <a href="http://www.gnu.org/licenses/"> http://www.gnu.org/licenses/</a> + * + * Copyright (C) 2015 - 2016, ruki All rights reserved. + * + * @author ruki + * @file openv.c + * + */ + +/* ////////////////////////////////////////////////////////////////////////////////////// + * trace + */ +#define TB_TRACE_MODULE_NAME "process.openv" +#define TB_TRACE_MODULE_DEBUG (0) + +/* ////////////////////////////////////////////////////////////////////////////////////// + * includes + */ +#include "prefix.h" + +/* ////////////////////////////////////////////////////////////////////////////////////// + * implementation + */ + +// p = process.openv(shellname, argv, outfile, errfile) +tb_int_t xm_process_openv(lua_State* lua) +{ + // check + tb_assert_and_check_return_val(lua, 0); + + // check table + if (!lua_istable(lua, 2)) + { + // error + lua_pushfstring(lua, "invalid argv type(%s) for process.openv", luaL_typename(lua, 2)); + lua_error(lua); + return 0; + } + + // get the output and error file + tb_char_t const* shellname = lua_tostring(lua, 1); + tb_char_t const* outfile = lua_tostring(lua, 3); + tb_char_t const* errfile = lua_tostring(lua, 4); + tb_check_return_val(shellname, 0); + + // get the arguments count + tb_long_t argn = lua_objlen(lua, 2); + tb_check_return_val(argn >= 0, 0); + + // get arguments + tb_size_t argi = 0; + tb_char_t const** argv = tb_nalloc0_type(1 + argn + 1, tb_char_t const*); + tb_check_return_val(argv, 0); + + // fill arguments + argv[0] = shellname; + for (argi = 0; argi < argn; argi++) + { + // get argv[i] + lua_pushinteger(lua, argi + 1); + lua_gettable(lua, 2); + + // is string? + if (lua_isstring(lua, -1)) + { + // pass this argument + argv[1 + argi] = lua_tostring(lua, -1); + } + else + { + // error + lua_pushfstring(lua, "invalid argv[%ld] type(%s) for process.openv", argi, luaL_typename(lua, -1)); + lua_error(lua); + } + + // pop it + lua_pop(lua, 1); + } + + // init attributes + tb_process_attr_t attr = {0}; + + // redirect stdout? + if (outfile) + { + // redirect stdout to file + attr.outfile = outfile; + attr.outmode = TB_FILE_MODE_RW | TB_FILE_MODE_CREAT | TB_FILE_MODE_APPEND; + + // remove the outfile first + if (tb_file_info(outfile, tb_null)) + tb_file_remove(outfile); + } + + // redirect stderr? + if (errfile) + { + // redirect stderr to file + attr.errfile = errfile; + attr.errmode = TB_FILE_MODE_RW | TB_FILE_MODE_CREAT | TB_FILE_MODE_APPEND; + + // remove the errfile first + if (tb_file_info(errfile, tb_null)) + tb_file_remove(errfile); + } + + // init process + tb_process_ref_t process = tb_process_init(shellname, argv, &attr); + + // save the process reference + lua_pushlightuserdata(lua, process); + + // exit argv + if (argv) tb_free(argv); + argv = tb_null; + + // ok + return 1; +} diff --git a/xmake/actions/run/main.lua b/xmake/actions/run/main.lua index 2f35ef2f0..84d516b40 100755 --- a/xmake/actions/run/main.lua +++ b/xmake/actions/run/main.lua @@ -31,8 +31,8 @@ import("core.platform.platform") -- run binary target function _run_binary(target) - -- run it - os.execute("%s %s", target:targetfile(), table.concat(option.get("arguments") or {}, " ")) + -- execute it + os.execv(target:targetfile(), option.get("arguments")) end -- run target diff --git a/xmake/core/base/os.lua b/xmake/core/base/os.lua index 41d291cef..92b37c708 100644 --- a/xmake/core/base/os.lua +++ b/xmake/core/base/os.lua @@ -291,6 +291,77 @@ function os.run(cmd) return true end +-- run shell with arguments list +function os.runv(shellname, argv) + + -- make temporary log file + local log = path.join(os.tmpdir(), "xmake.os.runv.log") + + -- execute it + local ok = os.execv(shellname, argv, log, log) + if ok ~= 0 then + + -- make errors + local errors = io.readall(log) + + -- remove the temporary log file + os.rm(log) + + -- failed + return false, errors + end + + -- remove the temporary log file + os.rm(log) + + -- ok + return true +end + +-- execute shell +function os.exec(cmd, outfile, errfile) + + -- open command + local ok = -1 + local proc = process.open(cmd, outfile, errfile) + if proc ~= nil then + + -- wait process + local waitok, status = process.wait(proc, -1) + if waitok > 0 then + ok = status + end + + -- close process + process.close(proc) + end + + -- ok? + return ok +end + +-- execute shell with arguments list +function os.execv(shellname, argv, outfile, errfile) + + -- open command + local ok = -1 + local proc = process.openv(shellname, argv, outfile, errfile) + if proc ~= nil then + + -- wait process + local waitok, status = process.wait(proc, -1) + if waitok > 0 then + ok = status + end + + -- close process + process.close(proc) + end + + -- ok? + return ok +end + -- run shell with io function os.iorun(cmd) diff --git a/xmake/core/sandbox/modules/os.lua b/xmake/core/sandbox/modules/os.lua index c8341a160..0c06d7dff 100644 --- a/xmake/core/sandbox/modules/os.lua +++ b/xmake/core/sandbox/modules/os.lua @@ -244,9 +244,22 @@ function sandbox_os.exec(cmd, ...) cmd = vformat(cmd, ...) -- run it - local retval = os.execute(cmd) - if retval ~= 0 then - os.raise("exec %s failed(%d)!", cmd, retval) + local ok = os.execute(cmd) + if ok ~= 0 then + os.raise("exec(%s) failed(%d)!", cmd, ok) + end +end + +-- execute shell with arguments list +function sandbox_os.execv(shellname, argv) + + -- make shellname + shellname = vformat(shellname) + + -- run it + local ok = os.execv(shellname, argv) + if ok ~= 0 then + os.raise("execv(%s) failed(%d)!", shellname, ok) end end |
