{-# LANGUAGE CPP #-}
module Effectful.Process
(
Process
, runProcess
, createProcess
, createProcess_
, P.shell
, P.proc
, P.CreateProcess(..)
, P.CmdSpec(..)
, P.StdStream(..)
, P.ProcessHandle
, callProcess
, callCommand
, spawnProcess
, spawnCommand
, readCreateProcess
, readProcess
, readCreateProcessWithExitCode
, readProcessWithExitCode
, withCreateProcess
, cleanupProcess
, P.showCommandForUser
, P.Pid
, getPid
#if MIN_VERSION_process(1,6,12)
, getCurrentPid
#endif
, waitForProcess
, getProcessExitCode
, terminateProcess
, interruptProcessGroupOf
, createPipe
, createPipeFd
) where
import System.Exit (ExitCode)
import System.IO (Handle)
import System.Posix.Internals (FD)
import System.Process qualified as P
import Effectful
import Effectful.Dispatch.Static
data Process :: Effect
type instance DispatchOf Process = Static WithSideEffects
data instance StaticRep Process = Process
runProcess :: (HasCallStack, IOE :> es) => Eff (Process : es) a -> Eff es a
runProcess :: forall (es :: [Effect]) a.
(HasCallStack, IOE :> es) =>
Eff (Process : es) a -> Eff es a
runProcess = StaticRep Process -> Eff (Process : es) a -> Eff es a
forall (e :: Effect) (sideEffects :: SideEffects) (es :: [Effect])
a.
(HasCallStack, DispatchOf e ~ 'Static sideEffects,
MaybeIOE sideEffects es) =>
StaticRep e -> Eff (e : es) a -> Eff es a
evalStaticRep StaticRep Process
Process
createProcess
:: Process :> es
=> P.CreateProcess
-> Eff es (Maybe Handle, Maybe Handle, Maybe Handle, P.ProcessHandle)
createProcess :: forall (es :: [Effect]).
(Process :> es) =>
CreateProcess
-> Eff es (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle)
createProcess = IO (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle)
-> Eff es (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle)
forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ (IO (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle)
-> Eff
es (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle))
-> (CreateProcess
-> IO (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle))
-> CreateProcess
-> Eff es (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CreateProcess
-> IO (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle)
P.createProcess
createProcess_
:: Process :> es
=> String
-> P.CreateProcess
-> Eff es (Maybe Handle, Maybe Handle, Maybe Handle, P.ProcessHandle)
createProcess_ :: forall (es :: [Effect]).
(Process :> es) =>
String
-> CreateProcess
-> Eff es (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle)
createProcess_ String
msg = IO (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle)
-> Eff es (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle)
forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ (IO (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle)
-> Eff
es (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle))
-> (CreateProcess
-> IO (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle))
-> CreateProcess
-> Eff es (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String
-> CreateProcess
-> IO (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle)
P.createProcess_ String
msg
callProcess :: Process :> es => FilePath -> [String] -> Eff es ()
callProcess :: forall (es :: [Effect]).
(Process :> es) =>
String -> [String] -> Eff es ()
callProcess String
fp = IO () -> Eff es ()
forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ (IO () -> Eff es ())
-> ([String] -> IO ()) -> [String] -> Eff es ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [String] -> IO ()
P.callProcess String
fp
callCommand :: Process :> es => String -> Eff es ()
callCommand :: forall (es :: [Effect]). (Process :> es) => String -> Eff es ()
callCommand = IO () -> Eff es ()
forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ (IO () -> Eff es ()) -> (String -> IO ()) -> String -> Eff es ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> IO ()
P.callCommand
spawnProcess :: Process :> es => FilePath -> [String] -> Eff es P.ProcessHandle
spawnProcess :: forall (es :: [Effect]).
(Process :> es) =>
String -> [String] -> Eff es ProcessHandle
spawnProcess String
fp = IO ProcessHandle -> Eff es ProcessHandle
forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ (IO ProcessHandle -> Eff es ProcessHandle)
-> ([String] -> IO ProcessHandle)
-> [String]
-> Eff es ProcessHandle
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [String] -> IO ProcessHandle
P.spawnProcess String
fp
spawnCommand :: Process :> es => String -> Eff es P.ProcessHandle
spawnCommand :: forall (es :: [Effect]).
(Process :> es) =>
String -> Eff es ProcessHandle
spawnCommand = IO ProcessHandle -> Eff es ProcessHandle
forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ (IO ProcessHandle -> Eff es ProcessHandle)
-> (String -> IO ProcessHandle) -> String -> Eff es ProcessHandle
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> IO ProcessHandle
P.spawnCommand
readCreateProcess :: Process :> es => P.CreateProcess -> String -> Eff es String
readCreateProcess :: forall (es :: [Effect]).
(Process :> es) =>
CreateProcess -> String -> Eff es String
readCreateProcess CreateProcess
cp = IO String -> Eff es String
forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ (IO String -> Eff es String)
-> (String -> IO String) -> String -> Eff es String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CreateProcess -> String -> IO String
P.readCreateProcess CreateProcess
cp
readProcess :: Process :> es => FilePath -> [String] -> String -> Eff es String
readProcess :: forall (es :: [Effect]).
(Process :> es) =>
String -> [String] -> String -> Eff es String
readProcess String
fp [String]
args = IO String -> Eff es String
forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ (IO String -> Eff es String)
-> (String -> IO String) -> String -> Eff es String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [String] -> String -> IO String
P.readProcess String
fp [String]
args
readCreateProcessWithExitCode
:: Process :> es
=> P.CreateProcess
-> String
-> Eff es (ExitCode, String, String)
readCreateProcessWithExitCode :: forall (es :: [Effect]).
(Process :> es) =>
CreateProcess -> String -> Eff es (ExitCode, String, String)
readCreateProcessWithExitCode CreateProcess
cp = IO (ExitCode, String, String) -> Eff es (ExitCode, String, String)
forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ (IO (ExitCode, String, String)
-> Eff es (ExitCode, String, String))
-> (String -> IO (ExitCode, String, String))
-> String
-> Eff es (ExitCode, String, String)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CreateProcess -> String -> IO (ExitCode, String, String)
P.readCreateProcessWithExitCode CreateProcess
cp
readProcessWithExitCode
:: Process :> es
=> FilePath
-> [String]
-> String
-> Eff es (ExitCode, String, String)
readProcessWithExitCode :: forall (es :: [Effect]).
(Process :> es) =>
String -> [String] -> String -> Eff es (ExitCode, String, String)
readProcessWithExitCode String
fp [String]
args = IO (ExitCode, String, String) -> Eff es (ExitCode, String, String)
forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ (IO (ExitCode, String, String)
-> Eff es (ExitCode, String, String))
-> (String -> IO (ExitCode, String, String))
-> String
-> Eff es (ExitCode, String, String)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [String] -> String -> IO (ExitCode, String, String)
P.readProcessWithExitCode String
fp [String]
args
withCreateProcess
:: Process :> es
=> P.CreateProcess
-> (Maybe Handle -> Maybe Handle -> Maybe Handle -> P.ProcessHandle -> Eff es a)
-> Eff es a
withCreateProcess :: forall (es :: [Effect]) a.
(Process :> es) =>
CreateProcess
-> (Maybe Handle
-> Maybe Handle -> Maybe Handle -> ProcessHandle -> Eff es a)
-> Eff es a
withCreateProcess CreateProcess
cp Maybe Handle
-> Maybe Handle -> Maybe Handle -> ProcessHandle -> Eff es a
cb = ((forall r. Eff es r -> IO r) -> IO a) -> Eff es a
forall (es :: [Effect]) a.
HasCallStack =>
((forall r. Eff es r -> IO r) -> IO a) -> Eff es a
unsafeSeqUnliftIO (((forall r. Eff es r -> IO r) -> IO a) -> Eff es a)
-> ((forall r. Eff es r -> IO r) -> IO a) -> Eff es a
forall a b. (a -> b) -> a -> b
$ \forall r. Eff es r -> IO r
unlift -> do
CreateProcess
-> (Maybe Handle
-> Maybe Handle -> Maybe Handle -> ProcessHandle -> IO a)
-> IO a
forall a.
CreateProcess
-> (Maybe Handle
-> Maybe Handle -> Maybe Handle -> ProcessHandle -> IO a)
-> IO a
P.withCreateProcess CreateProcess
cp ((Maybe Handle
-> Maybe Handle -> Maybe Handle -> ProcessHandle -> IO a)
-> IO a)
-> (Maybe Handle
-> Maybe Handle -> Maybe Handle -> ProcessHandle -> IO a)
-> IO a
forall a b. (a -> b) -> a -> b
$ \Maybe Handle
inh Maybe Handle
outh Maybe Handle
errh ProcessHandle
ph -> Eff es a -> IO a
forall r. Eff es r -> IO r
unlift (Eff es a -> IO a) -> Eff es a -> IO a
forall a b. (a -> b) -> a -> b
$ Maybe Handle
-> Maybe Handle -> Maybe Handle -> ProcessHandle -> Eff es a
cb Maybe Handle
inh Maybe Handle
outh Maybe Handle
errh ProcessHandle
ph
cleanupProcess
:: Process :> es
=> (Maybe Handle, Maybe Handle, Maybe Handle, P.ProcessHandle)
-> Eff es ()
cleanupProcess :: forall (es :: [Effect]).
(Process :> es) =>
(Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle)
-> Eff es ()
cleanupProcess = IO () -> Eff es ()
forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ (IO () -> Eff es ())
-> ((Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle)
-> IO ())
-> (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle)
-> Eff es ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle) -> IO ()
P.cleanupProcess
getPid :: Process :> es => P.ProcessHandle -> Eff es (Maybe P.Pid)
getPid :: forall (es :: [Effect]).
(Process :> es) =>
ProcessHandle -> Eff es (Maybe Pid)
getPid = IO (Maybe Pid) -> Eff es (Maybe Pid)
forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ (IO (Maybe Pid) -> Eff es (Maybe Pid))
-> (ProcessHandle -> IO (Maybe Pid))
-> ProcessHandle
-> Eff es (Maybe Pid)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ProcessHandle -> IO (Maybe Pid)
P.getPid
#if MIN_VERSION_process(1,6,12)
getCurrentPid :: Process :> es => Eff es P.Pid
getCurrentPid :: forall (es :: [Effect]). (Process :> es) => Eff es Pid
getCurrentPid = IO Pid -> Eff es Pid
forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ IO Pid
P.getCurrentPid
#endif
waitForProcess :: Process :> es => P.ProcessHandle -> Eff es ExitCode
waitForProcess :: forall (es :: [Effect]).
(Process :> es) =>
ProcessHandle -> Eff es ExitCode
waitForProcess = IO ExitCode -> Eff es ExitCode
forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ (IO ExitCode -> Eff es ExitCode)
-> (ProcessHandle -> IO ExitCode)
-> ProcessHandle
-> Eff es ExitCode
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ProcessHandle -> IO ExitCode
P.waitForProcess
getProcessExitCode :: Process :> es => P.ProcessHandle -> Eff es (Maybe ExitCode)
getProcessExitCode :: forall (es :: [Effect]).
(Process :> es) =>
ProcessHandle -> Eff es (Maybe ExitCode)
getProcessExitCode = IO (Maybe ExitCode) -> Eff es (Maybe ExitCode)
forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ (IO (Maybe ExitCode) -> Eff es (Maybe ExitCode))
-> (ProcessHandle -> IO (Maybe ExitCode))
-> ProcessHandle
-> Eff es (Maybe ExitCode)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ProcessHandle -> IO (Maybe ExitCode)
P.getProcessExitCode
terminateProcess :: Process :> es => P.ProcessHandle -> Eff es ()
terminateProcess :: forall (es :: [Effect]).
(Process :> es) =>
ProcessHandle -> Eff es ()
terminateProcess = IO () -> Eff es ()
forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ (IO () -> Eff es ())
-> (ProcessHandle -> IO ()) -> ProcessHandle -> Eff es ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ProcessHandle -> IO ()
P.terminateProcess
interruptProcessGroupOf :: Process :> es => P.ProcessHandle -> Eff es ()
interruptProcessGroupOf :: forall (es :: [Effect]).
(Process :> es) =>
ProcessHandle -> Eff es ()
interruptProcessGroupOf = IO () -> Eff es ()
forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ (IO () -> Eff es ())
-> (ProcessHandle -> IO ()) -> ProcessHandle -> Eff es ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ProcessHandle -> IO ()
P.interruptProcessGroupOf
createPipe :: Process :> es => Eff es (Handle, Handle)
createPipe :: forall (es :: [Effect]). (Process :> es) => Eff es (Handle, Handle)
createPipe = IO (Handle, Handle) -> Eff es (Handle, Handle)
forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ IO (Handle, Handle)
P.createPipe
createPipeFd :: Process :> es => Eff es (FD, FD)
createPipeFd :: forall (es :: [Effect]). (Process :> es) => Eff es (FD, FD)
createPipeFd = IO (FD, FD) -> Eff es (FD, FD)
forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ IO (FD, FD)
P.createPipeFd