{-# LANGUAGE CPP #-} module IdeSession.Util.PortableProcess where import System.Process (ProcessHandle) #ifdef VERSION_unix import System.Posix.Signals import System.Posix.Types import System.Process.Internals (withProcessHandle, ProcessHandle__(..)) #else import System.Process import System.Process.Internals hiding (ProcessHandle) import System.Win32 hiding (ProcessHandle) #endif #ifdef VERSION_unix type Pid = ProcessID #else type Pid = ProcessId #endif -- Attempts to kill the process, on Unix using sigKILL sigKillProcess :: Pid -> IO () -- Attempts to terminate the process, on Unix using sigTERM sigTermProcess :: Pid -> IO () -- Raises a sigKILL raiseSigKill :: IO () -- The exit code for sigKILL sigKillExitCode :: Int -- If available sends a sigKill to the given process handle killProcessHandle :: ProcessHandle -> IO () #ifdef VERSION_unix sigKillProcess = signalProcess sigKILL sigTermProcess = signalProcess sigTERM raiseSigKill = raiseSignal sigKILL sigKillExitCode = -9 killProcessHandle ph = withProcessHandle ph $ \p_ -> case p_ of ClosedHandle _ -> leaveHandleAsIs p_ OpenHandle pID -> do signalProcess sigKILL pID leaveHandleAsIs p_ where leaveHandleAsIs _p = #if MIN_VERSION_process(1,2,0) return () #else return (_p, ()) #endif #else -- On Windows, we just terminate, no special support for sigKILL sigKillProcess = sigTermProcess sigTermProcess pid = do ptr <- openProcess pROCESS_TERMINATE False pid ph <- mkProcessHandle ptr terminateProcess ph sigKillExitCode = 1 -- On Windows, no special support for sigKill killProcessHandle = terminateProcess foreign import ccall unsafe "winbase.h GetCurrentProcessId" c_GetCurrentProcessId :: IO DWORD getCurrentPid :: IO Pid getCurrentPid = c_GetCurrentProcessId raiseSigKill = do pid <- getCurrentPid sigKillProcess pid #endif