summaryrefslogtreecommitdiff
path: root/xmake
diff options
context:
space:
mode:
Diffstat (limited to 'xmake')
-rw-r--r--xmake/core/base/os.lua45
-rw-r--r--xmake/core/sandbox/modules/os.lua6
2 files changed, 51 insertions, 0 deletions
diff --git a/xmake/core/base/os.lua b/xmake/core/base/os.lua
index 9332f2c61..86f04e35d 100644
--- a/xmake/core/base/os.lua
+++ b/xmake/core/base/os.lua
@@ -1106,6 +1106,51 @@ function os.iorunv(program, argv, opt)
return ok == 0, outdata, errdata, errors
end
+-- run command in the given shell and return output and error data
+--
+-- @param shell the shell name (e.g. sh, bash, zsh, cmd, pwsh, powershell)
+-- @param cmd the command string
+-- @param opt the options
+--
+-- @return ok, stdout, stderr, errors
+--
+function os.iorun_in_shell(shell, cmd, opt)
+
+ -- check
+ if not shell or not cmd then
+ return false, nil, nil, "invalid arguments"
+ end
+
+ -- run in pwsh/powershell
+ if shell == "pwsh" or shell == "powershell" then
+ local shell_cmd = string.format("& { %s; exit $LASTEXITCODE }", cmd)
+ return os.iorunv(shell, {"-c", shell_cmd}, opt)
+
+ -- run in cmd
+ elseif shell == "cmd" then
+
+ -- use batfile to robust pipe handling
+ local batfile = os.tmpfile() .. ".bat"
+ local batch_content = "@echo off\n"
+
+ -- append command
+ batch_content = batch_content .. cmd .. "\n"
+
+ -- append exit code check
+ batch_content = batch_content .. "if %errorlevel% neq 0 exit /b %errorlevel%\n"
+
+ io.writefile(batfile, batch_content)
+
+ local ok, out, err, errors = os.iorunv(batfile, {}, opt)
+ os.rm(batfile)
+ return ok, out, err, errors
+
+ -- run in sh/bash/zsh...
+ else
+ return os.iorunv(shell, {"-c", cmd}, opt)
+ end
+end
+
-- raise an exception and abort the current script
--
-- the parent function will capture it if we uses pcall or xpcall
diff --git a/xmake/core/sandbox/modules/os.lua b/xmake/core/sandbox/modules/os.lua
index aebb3cfb0..ec5cb0e1e 100644
--- a/xmake/core/sandbox/modules/os.lua
+++ b/xmake/core/sandbox/modules/os.lua
@@ -324,6 +324,12 @@ function sandbox_os.iorunv(program, argv, opt)
return outdata, errdata
end
+-- run command in shell with io redirection and return (ok, out, err)
+function sandbox_os.iorun_in_shell(shell, cmd, ...)
+ cmd = vformat(cmd, ...)
+ return os.iorun_in_shell(shell, cmd)
+end
+
-- execute command
function sandbox_os.exec(cmd, ...)
cmd = vformat(cmd, ...)