summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2019-08-20 23:27:16 +0800
committerruki <[email protected]>2019-08-20 14:43:42 +0800
commitda11852ee8510e46ba0436ab125d0d89d6c1f728 (patch)
tree1a0cf14cbb81d471a2eb52c0cc82d35944142b40
parent22a22766a667c3273fc4a4a2e58ce55aba8466b3 (diff)
pass stdout and stderr file to os.execv
-rw-r--r--core/src/xmake/process/close.c20
-rw-r--r--core/src/xmake/process/open.c116
-rw-r--r--core/src/xmake/process/openv.c119
-rw-r--r--core/src/xmake/process/prefix.h37
-rw-r--r--xmake/core/base/os.lua23
5 files changed, 119 insertions, 196 deletions
diff --git a/core/src/xmake/process/close.c b/core/src/xmake/process/close.c
index 94de9b33d..dc1a465a3 100644
--- a/core/src/xmake/process/close.c
+++ b/core/src/xmake/process/close.c
@@ -48,26 +48,6 @@ tb_int_t xm_process_close(lua_State* lua)
tb_process_ref_t process = (tb_process_ref_t)lua_touserdata(lua, 1);
tb_check_return_val(process, 0);
- // exit subprocess
- xm_subprocess_t* subprocess = (xm_subprocess_t*)tb_process_priv(process);
- if (subprocess)
- {
- if (subprocess->outtype == TB_PROCESS_REDIRECT_TYPE_FILE && subprocess->outfile)
- {
- tb_file_exit(subprocess->outfile);
- subprocess->outfile = tb_null;
- }
-
- if (subprocess->errtype == TB_PROCESS_REDIRECT_TYPE_FILE && subprocess->errfile)
- {
- tb_file_exit(subprocess->errfile);
- subprocess->errfile = tb_null;
- }
-
- tb_string_exit(&subprocess->vs_unicode_output);
- tb_free(subprocess);
- }
-
// exit process
tb_process_exit(process);
diff --git a/core/src/xmake/process/open.c b/core/src/xmake/process/open.c
index bc1b35607..9d4765e7c 100644
--- a/core/src/xmake/process/open.c
+++ b/core/src/xmake/process/open.c
@@ -29,6 +29,7 @@
* includes
*/
#include "prefix.h"
+#include "../io/prefix.h"
/* //////////////////////////////////////////////////////////////////////////////////////
* implementation
@@ -53,7 +54,8 @@ tb_int_t xm_process_open(lua_State* lua)
tb_char_t const* envs[256] = {0};
tb_char_t const* outpath = tb_null;
tb_char_t const* errpath = tb_null;
- tb_bool_t vs_unicode_output = tb_false;
+ xm_io_file_t* outfile = tb_null;
+ xm_io_file_t* errfile = tb_null;
if (lua_istable(lua, 2))
{
// get outpath
@@ -68,77 +70,24 @@ tb_int_t xm_process_open(lua_State* lua)
errpath = lua_tostring(lua, -1);
lua_pop(lua, 1);
- // enable vs_unicode_output?
- lua_pushstring(lua, "vs_unicode_output");
- lua_gettable(lua, 2);
- vs_unicode_output = lua_toboolean(lua, -1);
- lua_pop(lua, 1);
- }
-
- // enable vs_unicode_output? @see https://github.com/xmake-io/xmake/issues/528
- if (vs_unicode_output)
- {
- xm_subprocess_t* subprocess = tb_malloc0_type(xm_subprocess_t);
- if (subprocess)
- {
- // init vs_unicode_output
- tb_string_init(&subprocess->vs_unicode_output);
-
- // redirect stdout?
- if (outpath)
- {
- // redirect stdout to file
- subprocess->outfile = tb_file_init(outpath, TB_FILE_MODE_RW | TB_FILE_MODE_TRUNC | TB_FILE_MODE_CREAT);
- subprocess->outtype = TB_PROCESS_REDIRECT_TYPE_FILE;
- attr.outfile = subprocess->outfile;
- attr.outtype = subprocess->outtype;
-
-#ifdef TB_CONFIG_OS_WINDOWS
- /* add environment value of vs_unicode_output
- *
- * @note we have to set it at the beginning, because opt.envs might also have this value.
- */
- if (envn + 1 < tb_arrayn(envs))
- envs[envn++] = tb_string_cstrfcpy(&subprocess->vs_unicode_output, "VS_UNICODE_OUTPUT=%zu", (tb_size_t)subprocess->outfile);
-#endif
- }
-
- // redirect stderr?
- if (errpath)
- {
- // redirect stderr to file
- subprocess->errfile = tb_file_init(errpath, TB_FILE_MODE_RW | TB_FILE_MODE_TRUNC | TB_FILE_MODE_CREAT);
- subprocess->errtype = TB_PROCESS_REDIRECT_TYPE_FILE;
- attr.errfile = subprocess->errfile;
- attr.errtype = subprocess->errtype;
- }
- attr.priv = subprocess;
- }
- }
- else
- {
- // redirect stdout?
- if (outpath)
+ // get outfile
+ if (!outpath)
{
- // redirect stdout to file
- attr.outpath = outpath;
- attr.outmode = TB_FILE_MODE_RW | TB_FILE_MODE_TRUNC | TB_FILE_MODE_CREAT;
- attr.outtype = TB_PROCESS_REDIRECT_TYPE_FILEPATH;
+ lua_pushstring(lua, "outfile");
+ lua_gettable(lua, 3);
+ outfile = (xm_io_file_t*)lua_touserdata(lua, -1);
+ lua_pop(lua, 1);
}
- // redirect stderr?
- if (errpath)
+ // get errfile
+ if (!errpath)
{
- // redirect stderr to file
- attr.errpath = errpath;
- attr.errmode = TB_FILE_MODE_RW | TB_FILE_MODE_TRUNC | TB_FILE_MODE_CREAT;
- attr.errtype = TB_PROCESS_REDIRECT_TYPE_FILEPATH;
+ lua_pushstring(lua, "errfile");
+ lua_gettable(lua, 3);
+ errfile = (xm_io_file_t*)lua_touserdata(lua, -1);
+ lua_pop(lua, 1);
}
- }
- // append other environments after setting VS_UNICODE_OUTPUT
- if (lua_istable(lua, 2))
- {
// get environments
lua_pushstring(lua, "envs");
lua_gettable(lua, 2);
@@ -182,6 +131,41 @@ tb_int_t xm_process_open(lua_State* lua)
lua_pop(lua, 1);
}
+ // redirect stdout?
+ if (outpath)
+ {
+ // redirect stdout to file
+ attr.outpath = outpath;
+ attr.outmode = TB_FILE_MODE_RW | TB_FILE_MODE_TRUNC | TB_FILE_MODE_CREAT;
+ attr.outtype = TB_PROCESS_REDIRECT_TYPE_FILEPATH;
+ }
+ else if (outfile && xm_io_file_is_file(outfile))
+ {
+ tb_file_ref_t rawfile = tb_null;
+ if (tb_stream_ctrl(outfile->stream, TB_STREAM_CTRL_FILE_GET_FILE, &rawfile) && rawfile)
+ {
+ attr.outfile = rawfile;
+ attr.outtype = TB_PROCESS_REDIRECT_TYPE_FILE;
+ }
+ }
+
+ // redirect stderr?
+ if (errpath)
+ {
+ // redirect stderr to file
+ attr.errpath = errpath;
+ attr.errmode = TB_FILE_MODE_RW | TB_FILE_MODE_TRUNC | TB_FILE_MODE_CREAT;
+ attr.errtype = TB_PROCESS_REDIRECT_TYPE_FILEPATH;
+ }
+ else if (errfile && xm_io_file_is_file(errfile))
+ {
+ tb_file_ref_t rawfile = tb_null;
+ if (tb_stream_ctrl(errfile->stream, TB_STREAM_CTRL_FILE_GET_FILE, &rawfile) && rawfile)
+ {
+ attr.errfile = rawfile;
+ attr.errtype = TB_PROCESS_REDIRECT_TYPE_FILE;
+ }
+ }
// set the new environments
if (envn > 0) attr.envp = envs;
diff --git a/core/src/xmake/process/openv.c b/core/src/xmake/process/openv.c
index e329f9898..57dbe559d 100644
--- a/core/src/xmake/process/openv.c
+++ b/core/src/xmake/process/openv.c
@@ -29,12 +29,13 @@
* includes
*/
#include "prefix.h"
+#include "../io/prefix.h"
/* //////////////////////////////////////////////////////////////////////////////////////
* implementation
*/
-// p = process.openv(shellname, argv, {outpath = "", errpath = "", envs = {"PATH=xxx", "XXX=yyy"})
+// p = process.openv(shellname, argv, {outpath = "", errpath = "", outfile = , errfile = , envs = {"PATH=xxx", "XXX=yyy"})
tb_int_t xm_process_openv(lua_State* lua)
{
// check
@@ -95,7 +96,8 @@ tb_int_t xm_process_openv(lua_State* lua)
tb_char_t const* envs[256] = {0};
tb_char_t const* outpath = tb_null;
tb_char_t const* errpath = tb_null;
- tb_bool_t vs_unicode_output = tb_false;
+ xm_io_file_t* outfile = tb_null;
+ xm_io_file_t* errfile = tb_null;
if (lua_istable(lua, 3))
{
// get outpath
@@ -110,77 +112,24 @@ tb_int_t xm_process_openv(lua_State* lua)
errpath = lua_tostring(lua, -1);
lua_pop(lua, 1);
- // enable vs_unicode_output?
- lua_pushstring(lua, "vs_unicode_output");
- lua_gettable(lua, 3);
- vs_unicode_output = lua_toboolean(lua, -1);
- lua_pop(lua, 1);
- }
-
- // enable vs_unicode_output? @see https://github.com/xmake-io/xmake/issues/528
- if (vs_unicode_output)
- {
- xm_subprocess_t* subprocess = tb_malloc0_type(xm_subprocess_t);
- if (subprocess)
- {
- // init vs_unicode_output
- tb_string_init(&subprocess->vs_unicode_output);
-
- // redirect stdout?
- if (outpath)
- {
- // redirect stdout to file
- subprocess->outfile = tb_file_init(outpath, TB_FILE_MODE_RW | TB_FILE_MODE_TRUNC | TB_FILE_MODE_CREAT);
- subprocess->outtype = TB_PROCESS_REDIRECT_TYPE_FILE;
- attr.outfile = subprocess->outfile;
- attr.outtype = subprocess->outtype;
-
-#ifdef TB_CONFIG_OS_WINDOWS
- /* add environment value of vs_unicode_output
- *
- * @note we have to set it at the beginning, because opt.envs might also have this value.
- */
- if (envn + 1 < tb_arrayn(envs))
- envs[envn++] = tb_string_cstrfcpy(&subprocess->vs_unicode_output, "VS_UNICODE_OUTPUT=%zu", (tb_size_t)subprocess->outfile);
-#endif
- }
-
- // redirect stderr?
- if (errpath)
- {
- // redirect stderr to file
- subprocess->errfile = tb_file_init(errpath, TB_FILE_MODE_RW | TB_FILE_MODE_TRUNC | TB_FILE_MODE_CREAT);
- subprocess->errtype = TB_PROCESS_REDIRECT_TYPE_FILE;
- attr.errfile = subprocess->errfile;
- attr.errtype = subprocess->errtype;
- }
- attr.priv = subprocess;
- }
- }
- else
- {
- // redirect stdout?
- if (outpath)
+ // get outfile
+ if (!outpath)
{
- // redirect stdout to file
- attr.outpath = outpath;
- attr.outmode = TB_FILE_MODE_RW | TB_FILE_MODE_TRUNC | TB_FILE_MODE_CREAT;
- attr.outtype = TB_PROCESS_REDIRECT_TYPE_FILEPATH;
+ lua_pushstring(lua, "outfile");
+ lua_gettable(lua, 3);
+ outfile = (xm_io_file_t*)lua_touserdata(lua, -1);
+ lua_pop(lua, 1);
}
- // redirect stderr?
- if (errpath)
+ // get errfile
+ if (!errpath)
{
- // redirect stderr to file
- attr.errpath = errpath;
- attr.errmode = TB_FILE_MODE_RW | TB_FILE_MODE_TRUNC | TB_FILE_MODE_CREAT;
- attr.errtype = TB_PROCESS_REDIRECT_TYPE_FILEPATH;
+ lua_pushstring(lua, "errfile");
+ lua_gettable(lua, 3);
+ errfile = (xm_io_file_t*)lua_touserdata(lua, -1);
+ lua_pop(lua, 1);
}
- }
- // append other environments after setting VS_UNICODE_OUTPUT
- if (lua_istable(lua, 3))
- {
// get environments
lua_pushstring(lua, "envs");
lua_gettable(lua, 3);
@@ -223,6 +172,42 @@ tb_int_t xm_process_openv(lua_State* lua)
}
lua_pop(lua, 1);
}
+
+ // redirect stdout?
+ if (outpath)
+ {
+ // redirect stdout to file
+ attr.outpath = outpath;
+ attr.outmode = TB_FILE_MODE_RW | TB_FILE_MODE_TRUNC | TB_FILE_MODE_CREAT;
+ attr.outtype = TB_PROCESS_REDIRECT_TYPE_FILEPATH;
+ }
+ else if (outfile && xm_io_file_is_file(outfile))
+ {
+ tb_file_ref_t rawfile = tb_null;
+ if (tb_stream_ctrl(outfile->stream, TB_STREAM_CTRL_FILE_GET_FILE, &rawfile) && rawfile)
+ {
+ attr.outfile = rawfile;
+ attr.outtype = TB_PROCESS_REDIRECT_TYPE_FILE;
+ }
+ }
+
+ // redirect stderr?
+ if (errpath)
+ {
+ // redirect stderr to file
+ attr.errpath = errpath;
+ attr.errmode = TB_FILE_MODE_RW | TB_FILE_MODE_TRUNC | TB_FILE_MODE_CREAT;
+ attr.errtype = TB_PROCESS_REDIRECT_TYPE_FILEPATH;
+ }
+ else if (errfile && xm_io_file_is_file(errfile))
+ {
+ tb_file_ref_t rawfile = tb_null;
+ if (tb_stream_ctrl(errfile->stream, TB_STREAM_CTRL_FILE_GET_FILE, &rawfile) && rawfile)
+ {
+ attr.errfile = rawfile;
+ attr.errtype = TB_PROCESS_REDIRECT_TYPE_FILE;
+ }
+ }
// set the new environments
if (envn > 0) attr.envp = envs;
diff --git a/core/src/xmake/process/prefix.h b/core/src/xmake/process/prefix.h
index 3ec32f792..4e3f4b3b4 100644
--- a/core/src/xmake/process/prefix.h
+++ b/core/src/xmake/process/prefix.h
@@ -26,43 +26,6 @@
*/
#include "../prefix.h"
-/* //////////////////////////////////////////////////////////////////////////////////////
- * types
- */
-
-// the subprocess type
-typedef struct __xm_subprocess_t
-{
- /// the stdout redirect type
- tb_uint16_t outtype;
-
- /// the stderr redirect type
- tb_uint16_t errtype;
-
- union
- {
- /// the stdout pipe
- tb_pipe_file_ref_t outpipe;
-
- /// the stdout file
- tb_file_ref_t outfile;
- };
-
- union
- {
- /// the strerr pipe
- tb_pipe_file_ref_t errpipe;
-
- /// the stderr file
- tb_file_ref_t errfile;
- };
-
- // vs unicode output environment variable
- tb_string_t vs_unicode_output;
-
-}xm_subprocess_t;
-
-
#endif
diff --git a/xmake/core/base/os.lua b/xmake/core/base/os.lua
index 506cd7da2..5626c0c5d 100644
--- a/xmake/core/base/os.lua
+++ b/xmake/core/base/os.lua
@@ -638,12 +638,10 @@ function os.execv(program, argv, opt)
-- uses the given environments?
local envs = nil
- if opt.envs or opt.vs_unicode_output then
+ if opt.envs then
local envars = os.getenvs()
- if opt.envs then
- for k, v in pairs(opt.envs) do
- envars[k] = v
- end
+ for k, v in pairs(opt.envs) do
+ envars[k] = v
end
envs = {}
for k, v in pairs(envars) do
@@ -651,9 +649,22 @@ function os.execv(program, argv, opt)
end
end
+ -- init open options
+ local openopt = {envs = envs}
+ if type(opt.stdout) == "table" then
+ openopt.outfile = opt.stdout._FILE
+ else
+ openopt.outpath = opt.stdout
+ end
+ if type(opt.stderr) == "table" then
+ openopt.errfile = opt.stderr._FILE
+ else
+ openopt.errpath = opt.stderr
+ end
+
-- open command
local ok = -1
- local proc = process.openv(filename, argv, {outpath = opt.stdout, errpath = opt.stderr, envs = envs, vs_unicode_output = opt.vs_unicode_output})
+ local proc = process.openv(filename, argv, openopt)
if proc ~= nil then
-- wait process