summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2020-02-03 22:51:06 +0800
committerruki <[email protected]>2020-02-07 22:45:56 +0800
commitcf9970fddd580f8b9bb8ed25d6d9cfa67a607b69 (patch)
tree57dda8e994431a59f96f44fec83d416fb4db0db6
parentccfe7ed01bd603f4435ce6463ecf267f49ddd6fe (diff)
improve to open process and support pipe
-rw-r--r--core/src/xmake/process/open.c32
-rw-r--r--core/src/xmake/process/openv.c46
-rw-r--r--tests/modules/process/test.lua2
-rw-r--r--xmake/actions/build/cleaner.lua2
-rw-r--r--xmake/actions/build/statistics.lua2
-rw-r--r--xmake/core/base/io.lua42
-rw-r--r--xmake/core/base/os.lua14
-rw-r--r--xmake/core/base/pipe.lua2
-rw-r--r--xmake/core/base/process.lua56
9 files changed, 156 insertions, 42 deletions
diff --git a/core/src/xmake/process/open.c b/core/src/xmake/process/open.c
index 45892fefd..2f45b5c6f 100644
--- a/core/src/xmake/process/open.c
+++ b/core/src/xmake/process/open.c
@@ -35,7 +35,9 @@
* implementation
*/
-// p = process.open(command, {outpath = "", errpath = "", envs = {"PATH=xxx", "XXX=yyy"}})
+/* p = process.open(command,
+ * {outpath = "", errpath = "", outfile = "", errfile = "", outpipe = "", errpipe = "", envs = {"PATH=xxx", "XXX=yyy"}})
+ */
tb_int_t xm_process_open(lua_State* lua)
{
// check
@@ -88,6 +90,24 @@ tb_int_t xm_process_open(lua_State* lua)
lua_pop(lua, 1);
}
+ // get outpipe
+ if (!outpath && !outfile)
+ {
+ lua_pushstring(lua, "outpipe");
+ lua_gettable(lua, 3);
+ outpipe = (tb_pipe_file_ref_t)lua_touserdata(lua, -1);
+ lua_pop(lua, 1);
+ }
+
+ // get errpipe
+ if (!errpath && !errfile)
+ {
+ lua_pushstring(lua, "errpipe");
+ lua_gettable(lua, 3);
+ errpipe = (tb_pipe_file_ref_t)lua_touserdata(lua, -1);
+ lua_pop(lua, 1);
+ }
+
// get environments
lua_pushstring(lua, "envs");
lua_gettable(lua, 2);
@@ -148,6 +168,11 @@ tb_int_t xm_process_open(lua_State* lua)
attr.outtype = TB_PROCESS_REDIRECT_TYPE_FILE;
}
}
+ else if (outpipe)
+ {
+ attr.outpipe = outpipe;
+ attr.outtype = TB_PROCESS_REDIRECT_TYPE_PIPE;
+ }
// redirect stderr?
if (errpath)
@@ -166,6 +191,11 @@ tb_int_t xm_process_open(lua_State* lua)
attr.errtype = TB_PROCESS_REDIRECT_TYPE_FILE;
}
}
+ else if (errpipe)
+ {
+ attr.errpipe = errpipe;
+ attr.errtype = TB_PROCESS_REDIRECT_TYPE_PIPE;
+ }
// 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 5e0af8d9c..69557aa69 100644
--- a/core/src/xmake/process/openv.c
+++ b/core/src/xmake/process/openv.c
@@ -35,7 +35,9 @@
* implementation
*/
-// p = process.openv(shellname, argv, {outpath = "", errpath = "", outfile = , errfile = , envs = {"PATH=xxx", "XXX=yyy"})
+/* p = process.openv(shellname, argv,
+ * {outpath = "", errpath = "", outfile = , errfile = , outpipe = , errpipe, envs = {"PATH=xxx", "XXX=yyy"})
+ */
tb_int_t xm_process_openv(lua_State* lua)
{
// check
@@ -92,12 +94,14 @@ tb_int_t xm_process_openv(lua_State* lua)
tb_process_attr_t attr = {0};
// get option arguments
- tb_size_t envn = 0;
- tb_char_t const* envs[256] = {0};
- tb_char_t const* outpath = tb_null;
- tb_char_t const* errpath = tb_null;
- xm_io_file_t* outfile = tb_null;
- xm_io_file_t* errfile = tb_null;
+ tb_size_t envn = 0;
+ tb_char_t const* envs[256] = {0};
+ tb_char_t const* outpath = tb_null;
+ tb_char_t const* errpath = tb_null;
+ xm_io_file_t* outfile = tb_null;
+ xm_io_file_t* errfile = tb_null;
+ tb_pipe_file_ref_t outpipe = tb_null;
+ tb_pipe_file_ref_t errpipe = tb_null;
if (lua_istable(lua, 3))
{
// get outpath
@@ -130,6 +134,24 @@ tb_int_t xm_process_openv(lua_State* lua)
lua_pop(lua, 1);
}
+ // get outpipe
+ if (!outpath && !outfile)
+ {
+ lua_pushstring(lua, "outpipe");
+ lua_gettable(lua, 3);
+ outpipe = (tb_pipe_file_ref_t)lua_touserdata(lua, -1);
+ lua_pop(lua, 1);
+ }
+
+ // get errpipe
+ if (!errpath && !errfile)
+ {
+ lua_pushstring(lua, "errpipe");
+ lua_gettable(lua, 3);
+ errpipe = (tb_pipe_file_ref_t)lua_touserdata(lua, -1);
+ lua_pop(lua, 1);
+ }
+
// get environments
lua_pushstring(lua, "envs");
lua_gettable(lua, 3);
@@ -190,6 +212,11 @@ tb_int_t xm_process_openv(lua_State* lua)
attr.outtype = TB_PROCESS_REDIRECT_TYPE_FILE;
}
}
+ else if (outpipe)
+ {
+ attr.outpipe = outpipe;
+ attr.outtype = TB_PROCESS_REDIRECT_TYPE_PIPE;
+ }
// redirect stderr?
if (errpath)
@@ -208,6 +235,11 @@ tb_int_t xm_process_openv(lua_State* lua)
attr.errtype = TB_PROCESS_REDIRECT_TYPE_FILE;
}
}
+ else if (errpipe)
+ {
+ attr.errpipe = errpipe;
+ attr.errtype = TB_PROCESS_REDIRECT_TYPE_PIPE;
+ }
// set the new environments
if (envn > 0) attr.envp = envs;
diff --git a/tests/modules/process/test.lua b/tests/modules/process/test.lua
index 24846fd02..8e9e45bd8 100644
--- a/tests/modules/process/test.lua
+++ b/tests/modules/process/test.lua
@@ -7,7 +7,7 @@ function test_single_process(t)
local stdout = os.tmpfile()
local stderr = os.tmpfile()
for i = 1, 2 do
- local proc = process.open("echo -n awd", {outpath = stdout, errpath = stderr})
+ local proc = process.open("echo -n awd", {stdout = stdout, stderr = stderr})
proc:wait(inftimeout)
proc:close()
t:are_equal(io.readfile(stdout), "awd")
diff --git a/xmake/actions/build/cleaner.lua b/xmake/actions/build/cleaner.lua
index f128e7a7d..7d629b978 100644
--- a/xmake/actions/build/cleaner.lua
+++ b/xmake/actions/build/cleaner.lua
@@ -53,7 +53,7 @@ function cleanup()
try
{
function ()
- local proc = process.openv("xmake", argv, {outpath = path.join(os.tmpdir(), "cleaner.log")})
+ local proc = process.openv("xmake", argv, {stdout = path.join(os.tmpdir(), "cleaner.log")})
if proc ~= nil then
proc:close()
end
diff --git a/xmake/actions/build/statistics.lua b/xmake/actions/build/statistics.lua
index 996295de6..1e29cb666 100644
--- a/xmake/actions/build/statistics.lua
+++ b/xmake/actions/build/statistics.lua
@@ -88,7 +88,7 @@ function post()
try
{
function ()
- local proc = process.openv("xmake", argv, {outpath = path.join(os.tmpdir(), projectname .. ".stats.log")})
+ local proc = process.openv("xmake", argv, {stdout = path.join(os.tmpdir(), projectname .. ".stats.log")})
if proc ~= nil then
proc:close()
end
diff --git a/xmake/core/base/io.lua b/xmake/core/base/io.lua
index d950c07b0..ee1553d2d 100644
--- a/xmake/core/base/io.lua
+++ b/xmake/core/base/io.lua
@@ -64,7 +64,7 @@ function _file:close()
end
-- close file
- ok, errors = io.file_close(self._FILE)
+ ok, errors = io.file_close(self:cdata())
if ok then
self._FILE = nil
end
@@ -106,7 +106,7 @@ end
-- gc(file)
function _file:__gc()
- if self._FILE and io.file_close(self._FILE) then
+ if self:cdata() and io.file_close(self:cdata()) then
self._FILE = nil
end
end
@@ -116,6 +116,11 @@ function _file:__len()
return _file.size(self)
end
+-- get cdata
+function _file:cdata()
+ return self._FILE
+end
+
-- get file rawfd
function _file:rawfd()
@@ -126,7 +131,7 @@ function _file:rawfd()
end
-- get file rawfd
- local result, errors = io.file_rawfd(self._FILE)
+ local result, errors = io.file_rawfd(self:cdata())
if not result and errors then
errors = string.format("%s: %s", self, errors)
end
@@ -143,7 +148,7 @@ function _file:size()
end
-- get file size
- local result, errors = io.file_size(self._FILE)
+ local result, errors = io.file_size(self:cdata())
if not result and errors then
errors = string.format("%s: %s", self, errors)
end
@@ -161,7 +166,7 @@ function _file:read(fmt, opt)
-- read file
opt = opt or {}
- local result, errors = io.file_read(self._FILE, fmt, opt.continuation)
+ local result, errors = io.file_read(self:cdata(), fmt, opt.continuation)
if errors then
errors = string.format("%s: %s", self, errors)
end
@@ -178,7 +183,7 @@ function _file:write(...)
end
-- write file
- ok, errors = io.file_write(self._FILE, ...)
+ ok, errors = io.file_write(self:cdata(), ...)
if not ok and errors then
errors = string.format("%s: %s", self, errors)
end
@@ -195,7 +200,7 @@ function _file:seek(whence, offset)
end
-- seek file
- local result, errors = io.file_seek(self._FILE, whence, offset)
+ local result, errors = io.file_seek(self:cdata(), whence, offset)
if not result and errors then
errors = string.format("%s: %s", self, errors)
end
@@ -212,7 +217,7 @@ function _file:flush()
end
-- flush file
- ok, errors = io.file_flush(self._FILE)
+ ok, errors = io.file_flush(self:cdata())
if not ok and errors then
errors = string.format("%s: %s", self, errors)
end
@@ -229,7 +234,7 @@ function _file:isatty()
end
-- is a tty?
- ok, errors = io.file_isatty(self._FILE)
+ ok, errors = io.file_isatty(self:cdata())
if ok == nil and errors then
errors = string.format("%s: %s", self, errors)
end
@@ -238,7 +243,7 @@ end
-- ensure the file is opened
function _file:_ensure_opened()
- if not self._FILE then
+ if not self:cdata() then
return false, string.format("%s: has been closed!", self)
end
return true
@@ -308,6 +313,11 @@ function _filelock:path()
return self._PATH
end
+-- get the cdata
+function _filelock:cdata()
+ return self._LOCK
+end
+
-- is locked?
function _filelock:islocked()
return self._LOCKED_NUM > 0
@@ -328,7 +338,7 @@ function _filelock:lock(opt)
end
-- lock it
- if self._LOCKED_NUM > 0 or io.filelock_lock(self._LOCK, opt) then
+ if self._LOCKED_NUM > 0 or io.filelock_lock(self:cdata(), opt) then
self._LOCKED_NUM = self._LOCKED_NUM + 1
return true
else
@@ -351,7 +361,7 @@ function _filelock:trylock(opt)
end
-- try lock it
- if self._LOCKED_NUM > 0 or io.filelock_trylock(self._LOCK, opt) then
+ if self._LOCKED_NUM > 0 or io.filelock_trylock(self:cdata(), opt) then
self._LOCKED_NUM = self._LOCKED_NUM + 1
return true
else
@@ -369,7 +379,7 @@ function _filelock:unlock(opt)
end
-- unlock it
- if self._LOCKED_NUM > 1 or (self._LOCKED_NUM > 0 and io.filelock_unlock(self._LOCK)) then
+ if self._LOCKED_NUM > 1 or (self._LOCKED_NUM > 0 and io.filelock_unlock(self:cdata())) then
if self._LOCKED_NUM > 0 then
self._LOCKED_NUM = self._LOCKED_NUM - 1
else
@@ -391,7 +401,7 @@ function _filelock:close()
end
-- close it
- ok = io.filelock_close(self._LOCK)
+ ok = io.filelock_close(self:cdata())
if ok then
self._LOCK = nil
self._LOCKED_NUM = 0
@@ -401,7 +411,7 @@ end
-- ensure the file is opened
function _filelock:_ensure_opened()
- if not self._LOCK then
+ if not self:cdata() then
return false, string.format("%s: has been closed!", self)
end
return true
@@ -424,7 +434,7 @@ end
-- gc(filelock)
function _filelock:__gc()
- if self._LOCK and io.filelock_close(self._LOCK) then
+ if self:cdata() and io.filelock_close(self:cdata()) then
self._LOCK = nil
self._LOCKED_NUM = 0
end
diff --git a/xmake/core/base/os.lua b/xmake/core/base/os.lua
index 4a31db46c..46a0ad1a1 100644
--- a/xmake/core/base/os.lua
+++ b/xmake/core/base/os.lua
@@ -608,7 +608,7 @@ end
-- @param program "clang", "xcrun -sdk macosx clang", "~/dir/test\ xxx/clang"
-- filename "clang", "xcrun"", "~/dir/test\ xxx/clang"
-- @param argv the arguments
--- @param opt the options, e.g. {wildcards = false, stdout = outfile, stderr = errfile,
+-- @param opt the options, e.g. {wildcards = false, stdout = filepath/file/pipe, stderr = filepath/file/pipe,
-- envs = {PATH = "xxx;xx", CFLAGS = "xx"}}
--
function os.execv(program, argv, opt)
@@ -651,17 +651,7 @@ function os.execv(program, argv, opt)
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
+ local openopt = {envs = envs, stdout = opt.stdout, stderr = opt.stderr}
-- open command
local ok = -1
diff --git a/xmake/core/base/pipe.lua b/xmake/core/base/pipe.lua
index be798a606..3252ef5e4 100644
--- a/xmake/core/base/pipe.lua
+++ b/xmake/core/base/pipe.lua
@@ -48,7 +48,7 @@ function _instance:name()
return self._NAME
end
--- get poller object type, poller.OT_instance
+-- get poller object type, poller.OT_PIPE
function _instance:otype()
return 2
end
diff --git a/xmake/core/base/process.lua b/xmake/core/base/process.lua
index 99f756fdc..aa442f6d7 100644
--- a/xmake/core/base/process.lua
+++ b/xmake/core/base/process.lua
@@ -140,11 +140,37 @@ end
-- open a subprocess
--
-- @param command the process command
--- @param opt the option arguments, e.g. {outpath = "", errpath = "", envs = {"PATH=xxx", "XXX=yyy"}})
+-- @param opt the option arguments, e.g. {stdout = filepath/file/pipe, stderr = filepath/file/pipe, envs = {"PATH=xxx", "XXX=yyy"}})
--
-- @return the subprocess
--
function process.open(command, opt)
+
+ -- get stdout and pass to subprocess
+ local stdout = opt.stdout
+ if type(stdout) == "string" then
+ opt.outpath = stdout
+ elseif type(stdout) == "table" then
+ if stdout.otype and stdout:otype() == 2 then
+ opt.outpipe = stdout:cdata()
+ else
+ opt.outfile = stdout:cdata()
+ end
+ end
+
+ -- get stderr and pass to subprocess
+ local stderr = opt.stderr
+ if type(stderr) == "string" then
+ opt.errpath = stderr
+ elseif type(stderr) == "table" then
+ if stderr.otype and stderr:otype() == 2 then
+ opt.errpipe = stderr:cdata()
+ else
+ opt.errfile = stderr:cdata()
+ end
+ end
+
+ -- open subprocess
local proc = process._open(command, opt)
if proc then
return _subprocess.new(path.filename(command:split(' ', {plain = true})[1]), proc)
@@ -157,11 +183,37 @@ end
--
-- @param shellname the shell name
-- @param argv the arguments list
--- @param opt the option arguments, e.g. {outpath = "", errpath = "", envs = {"PATH=xxx", "XXX=yyy"}})
+-- @param opt the option arguments, e.g. {stdout = filepath/file/pipe, stderr = filepath/file/pipe, envs = {"PATH=xxx", "XXX=yyy"}})
--
-- @return the subprocess
--
function process.openv(shellname, argv, opt)
+
+ -- get stdout and pass to subprocess
+ local stdout = opt.stdout
+ if type(stdout) == "string" then
+ opt.outpath = stdout
+ elseif type(stdout) == "table" then
+ if stdout.otype and stdout:otype() == 2 then
+ opt.outpipe = stdout:cdata()
+ else
+ opt.outfile = stdout:cdata()
+ end
+ end
+
+ -- get stderr and pass to subprocess
+ local stderr = opt.stderr
+ if type(stderr) == "string" then
+ opt.errpath = stderr
+ elseif type(stderr) == "table" then
+ if stderr.otype and stderr:otype() == 2 then
+ opt.errpipe = stderr:cdata()
+ else
+ opt.errfile = stderr:cdata()
+ end
+ end
+
+ -- open subprocess
local proc = process._openv(shellname, argv, opt)
if proc then
return _subprocess.new(path.filename(shellname), proc)