mirror of
https://github.com/xmonad/xmonad-contrib.git
synced 2025-07-31 20:21:51 -07:00
91 lines
3.0 KiB
Haskell
91 lines
3.0 KiB
Haskell
-----------------------------------------------------------------------------
|
|
-- |
|
|
-- Module : XMonadContrib.Run
|
|
-- Copyright : (C) 2007 Spencer Janssen, Andrea Rossato, glasser@mit.edu
|
|
-- License : BSD-style (see LICENSE)
|
|
--
|
|
-- Maintainer : Christian Thiemann <mail@christian-thiemann.de>
|
|
-- Stability : unstable
|
|
-- Portability : unportable
|
|
--
|
|
-- This modules provides several commands to run an external process.
|
|
-- It is composed of functions formerly defined in XMonadContrib.Dmenu (by
|
|
-- Spenver Jannsen), XMonadContrib.Dzen (by glasser@mit.edu) and
|
|
-- XMonadContrib.RunInXTerm (by Andrea Rossato).
|
|
--
|
|
-----------------------------------------------------------------------------
|
|
|
|
module XMonadContrib.Run (
|
|
-- * Usage
|
|
-- $usage
|
|
runInXTerm,
|
|
runProcessWithInput,
|
|
runProcessWithInputAndWait,
|
|
seconds
|
|
) where
|
|
|
|
import XMonad
|
|
import Control.Concurrent (threadDelay)
|
|
import Control.Monad.State
|
|
import System.Environment
|
|
import System.Exit
|
|
import System.IO
|
|
import System.Posix.Process (forkProcess, getProcessStatus, createSession)
|
|
import System.Process
|
|
|
|
|
|
-- $usage
|
|
-- For an example usage of runInXTerm see XMonadContrib.SshPrompt
|
|
--
|
|
-- For an example usage of runProcessWithInput see
|
|
-- XMonadContrib.{DirectoryPrompt,Dmenu,ShellPrompt,WmiiActions,WorkspaceDir}
|
|
--
|
|
-- For an example usage of runProcessWithInputAndWait see XMonadContrib.Dzen
|
|
|
|
-- | Returns Just output if the command succeeded, and Nothing if it didn't.
|
|
-- This corresponds to dmenu's notion of exit code 1 for a cancelled invocation.
|
|
runProcessWithInput :: FilePath -> [String] -> String -> IO String
|
|
runProcessWithInput cmd args input = do
|
|
(pin, pout, perr, ph) <- runInteractiveProcess cmd args Nothing Nothing
|
|
hPutStr pin input
|
|
hClose pin
|
|
output <- hGetContents pout
|
|
when (output==output) $ return ()
|
|
hClose pout
|
|
hClose perr
|
|
waitForProcess ph
|
|
return output
|
|
|
|
-- wait is in us
|
|
runProcessWithInputAndWait :: FilePath -> [String] -> String -> Int -> IO ()
|
|
runProcessWithInputAndWait cmd args input timeout = do
|
|
pid <- forkProcess $ do
|
|
forkProcess $ do -- double fork it over to init
|
|
createSession
|
|
(pin, pout, perr, ph) <- runInteractiveProcess cmd args Nothing Nothing
|
|
hPutStr pin input
|
|
hFlush pin
|
|
threadDelay timeout
|
|
hClose pin
|
|
-- output <- hGetContents pout
|
|
-- when (output==output) $ return ()
|
|
hClose pout
|
|
hClose perr
|
|
waitForProcess ph
|
|
return ()
|
|
exitWith ExitSuccess
|
|
return ()
|
|
getProcessStatus True False pid
|
|
return ()
|
|
|
|
runInXTerm :: String -> X ()
|
|
runInXTerm com = do
|
|
c <- io $ catch (getEnv "XTERMCMD") (const $ return "xterm")
|
|
spawn ("exec " ++ c ++ " -e " ++ com)
|
|
|
|
-- | Multiplies by ONE MILLION, for use with runProcessWithInputAndWait.
|
|
-- Use like:
|
|
-- > (5.5 `seconds`)
|
|
seconds :: Rational -> Int
|
|
seconds = fromEnum . (* 1000000)
|