More stuff
This commit is contained in:
@@ -25,6 +25,7 @@ import "unix" System.Posix.IO.ByteString
|
||||
import qualified System.Posix.Process.ByteString
|
||||
as SPPB
|
||||
import System.Posix.Directory.ByteString
|
||||
import System.Posix.Process ( ProcessStatus(..) )
|
||||
import System.Posix.Types
|
||||
|
||||
import qualified Streamly.Internal.Memory.ArrayStream
|
||||
@@ -42,10 +43,17 @@ import Control.Concurrent
|
||||
import System.Posix.FD as FD
|
||||
|
||||
|
||||
data ProcessError = NonZeroExit Int
|
||||
| PTerminated
|
||||
| PStopped
|
||||
| NoSuchPid
|
||||
deriving Show
|
||||
|
||||
|
||||
data CapturedProcess = CapturedProcess {
|
||||
_exitCode :: ExitCode
|
||||
, _stdOut :: L.ByteString
|
||||
, _stdErr :: L.ByteString
|
||||
, _stdOut :: ByteString
|
||||
, _stdErr :: ByteString
|
||||
} deriving (Eq, Show)
|
||||
|
||||
makeLenses ''CapturedProcess
|
||||
@@ -92,10 +100,9 @@ executeOut :: Path Rel -- ^ command as filename, e.g. 'ls'
|
||||
-> [ByteString] -- ^ arguments to the command
|
||||
-> Maybe (Path Abs) -- ^ chdir to this path
|
||||
-> IO (Maybe CapturedProcess)
|
||||
executeOut path args chdir = withRelPath path
|
||||
$ \fp -> captureOutStreams $ do
|
||||
maybe (pure ()) (changeWorkingDirectory . toFilePath) chdir
|
||||
SPPB.executeFile fp True args Nothing
|
||||
executeOut path args chdir = withRelPath path $ \fp -> captureOutStreams $ do
|
||||
maybe (pure ()) (changeWorkingDirectory . toFilePath) chdir
|
||||
SPPB.executeFile fp True args Nothing
|
||||
|
||||
|
||||
-- | Capture the stdout and stderr of the given action, which
|
||||
@@ -108,9 +115,6 @@ captureOutStreams action =
|
||||
actionWithPipes $ \(parentStdoutRead, childStdoutWrite) ->
|
||||
actionWithPipes $ \(parentStderrRead, childStderrWrite) -> do
|
||||
pid <- SPPB.forkProcess $ do
|
||||
-- don't mess up stdin from the parent
|
||||
closeFd stdInput
|
||||
|
||||
-- dup stdout
|
||||
void $ dupTo childStdoutWrite stdOutput
|
||||
closeFd childStdoutWrite
|
||||
@@ -131,8 +135,8 @@ captureOutStreams action =
|
||||
SPPB.getProcessStatus True True pid >>= \case
|
||||
-- readFd will take care of closing the fd
|
||||
Just (SPPB.Exited es) -> do
|
||||
stdout' <- readFd parentStdoutRead
|
||||
stderr' <- readFd parentStderrRead
|
||||
stdout' <- L.toStrict <$> readFd parentStdoutRead
|
||||
stderr' <- L.toStrict <$> readFd parentStderrRead
|
||||
pure $ Just $ CapturedProcess { _exitCode = es
|
||||
, _stdOut = stdout'
|
||||
, _stdErr = stderr'
|
||||
@@ -153,3 +157,26 @@ captureOutStreams action =
|
||||
createRegularFileFd :: FileMode -> Path b -> IO Fd
|
||||
createRegularFileFd fm dest =
|
||||
FD.openFd (toFilePath dest) WriteOnly [oExcl] (Just fm)
|
||||
|
||||
|
||||
exe :: ByteString
|
||||
-> [ByteString]
|
||||
-> Bool
|
||||
-> Maybe (Path Abs)
|
||||
-> IO (Either ProcessError ())
|
||||
exe exe' args spath chdir = do
|
||||
pid <- SPPB.forkProcess $ do
|
||||
maybe (pure ()) (changeWorkingDirectory . toFilePath) chdir
|
||||
SPPB.executeFile exe' spath args Nothing
|
||||
|
||||
fmap toProcessError $ SPPB.getProcessStatus True True pid
|
||||
|
||||
|
||||
toProcessError :: Maybe ProcessStatus -> Either ProcessError ()
|
||||
toProcessError mps = case mps of
|
||||
Just (SPPB.Exited (ExitFailure i)) -> Left $ NonZeroExit i
|
||||
Just (SPPB.Exited ExitSuccess ) -> Right ()
|
||||
Just (Terminated _ _ ) -> Left $ PTerminated
|
||||
Just (Stopped _ ) -> Left $ PStopped
|
||||
Nothing -> Left $ NoSuchPid
|
||||
|
||||
|
||||
Reference in New Issue
Block a user