summaryrefslogtreecommitdiff
path: root/src/Script
diff options
context:
space:
mode:
authorRoman Smrž <roman.smrz@seznam.cz>2025-10-04 21:45:02 +0200
committerRoman Smrž <roman.smrz@seznam.cz>2025-10-05 21:24:13 +0200
commit6ee42f58d7293d810a5406d06020e1fdc9bcdaf0 (patch)
treecc23366a9d79c7b1dffb8599f103a5472bb80727 /src/Script
parent11e04cd229c132ad7d79cbfd8319fb5a3d5f3cbb (diff)
Redirection in shell scriptsHEADmaster
Changelog: Implemented input/output redirection in shell scripts
Diffstat (limited to 'src/Script')
-rw-r--r--src/Script/Shell.hs30
1 files changed, 25 insertions, 5 deletions
diff --git a/src/Script/Shell.hs b/src/Script/Shell.hs
index d53fe2e..15c0c2c 100644
--- a/src/Script/Shell.hs
+++ b/src/Script/Shell.hs
@@ -24,6 +24,7 @@ import Foreign.Marshal.Array
import Foreign.Storable
import System.Exit
+import System.FilePath
import System.IO
import System.Posix.IO qualified as P
import System.Posix.Process
@@ -59,9 +60,12 @@ data ShellCommand = ShellCommand
data ShellArgument
= ShellArgument Text
+ | ShellRedirectStdin Text
+ | ShellRedirectStdout Bool Text
+ | ShellRedirectStderr Bool Text
cmdArguments :: ShellCommand -> [ Text ]
-cmdArguments = catMaybes . map (\case ShellArgument x -> Just x) . cmdExtArguments
+cmdArguments = catMaybes . map (\case ShellArgument x -> Just x; _ -> Nothing) . cmdExtArguments
instance ExprType ShellScript where
textExprType _ = T.pack "ShellScript"
@@ -107,19 +111,35 @@ handledHandle (KeepHandle h) = h
executeCommand :: ShellExecInfo -> HandleHandling -> HandleHandling -> HandleHandling -> ShellCommand -> TestRun ()
executeCommand ShellExecInfo {..} pstdin pstdout pstderr scmd@ShellCommand {..} = do
let args = cmdArguments scmd
+ ( pstdin', pstdout', pstderr' ) <- (\f -> foldM f ( pstdin, pstdout, pstderr ) cmdExtArguments) $ \cur@( cin, cout, cerr ) -> \case
+ ShellRedirectStdin path -> do
+ closeIfRequested cin
+ h <- liftIO $ openBinaryFile (nodeDir seiNode </> T.unpack path) ReadMode
+ return ( CloseHandle h, cout, cerr )
+ ShellRedirectStdout append path -> do
+ closeIfRequested cout
+ h <- liftIO $ openBinaryFile (nodeDir seiNode </> T.unpack path) $ if append then AppendMode else WriteMode
+ return ( cin, CloseHandle h, cerr )
+ ShellRedirectStderr append path -> do
+ closeIfRequested cerr
+ h <- liftIO $ openBinaryFile (nodeDir seiNode </> T.unpack path) $ if append then AppendMode else WriteMode
+ return ( cin, cout, CloseHandle h )
+ _ -> do
+ return cur
+
pid <- liftIO $ do
(_, _, _, phandle) <- createProcess_ "shell"
(proc (T.unpack cmdCommand) (map T.unpack args))
- { std_in = UseHandle $ handledHandle pstdin
- , std_out = UseHandle $ handledHandle pstdout
- , std_err = UseHandle $ handledHandle pstderr
+ { std_in = UseHandle $ handledHandle pstdin'
+ , std_out = UseHandle $ handledHandle pstdout'
+ , std_err = UseHandle $ handledHandle pstderr'
, cwd = Just (nodeDir seiNode)
, env = Just []
}
Just pid <- getPid phandle
return pid
- mapM_ closeIfRequested [ pstdin, pstdout, pstderr ]
+ mapM_ closeIfRequested [ pstdin', pstdout', pstderr' ]
liftIO (getProcessStatus True False pid) >>= \case
Just (Exited ExitSuccess) -> do
return ()