summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2016-07-04 23:59:59 +0800
committerruki <[email protected]>2016-07-04 23:59:59 +0800
commit1589758d311b92b6e19592768613ebd773bb94f0 (patch)
tree4071c7a178978bf39b246e7b84f38cfabae69381
parent0bb5ee3e8b5ee719c1bada87be11baca81722afd (diff)
add os.execv
-rwxr-xr-xcore/src/xmake/machine.c2
-rwxr-xr-xcore/src/xmake/makefile1
-rwxr-xr-xcore/src/xmake/process/open.c2
-rwxr-xr-xcore/src/xmake/process/openv.c133
-rwxr-xr-xxmake/actions/run/main.lua4
-rw-r--r--xmake/core/base/os.lua71
-rw-r--r--xmake/core/sandbox/modules/os.lua19
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