diff options
| author | Roman Smrž <roman.smrz@seznam.cz> | 2025-10-04 21:45:02 +0200 |
|---|---|---|
| committer | Roman Smrž <roman.smrz@seznam.cz> | 2025-10-05 21:24:13 +0200 |
| commit | 6ee42f58d7293d810a5406d06020e1fdc9bcdaf0 (patch) | |
| tree | cc23366a9d79c7b1dffb8599f103a5472bb80727 /src/Script | |
| parent | 11e04cd229c132ad7d79cbfd8319fb5a3d5f3cbb (diff) | |
Changelog: Implemented input/output redirection in shell scripts
Diffstat (limited to 'src/Script')
| -rw-r--r-- | src/Script/Shell.hs | 30 |
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 () |