packages feed

Conscript-0.1.0.0: Conscript.hs

import System.Environment
import System.Process
import System.Exit
import System.IO
import Control.Monad
import Control.Concurrent

main :: IO ()
main = getArgs >>= options

options :: [String] -> IO ()
options []           = help
options ("-h"    :_) = help
options ("--help":_) = help
options args         = run args

run :: [String] -> IO ()
run args = do
  hSetBuffering stdin  LineBuffering
  hSetBuffering stdout LineBuffering
  blocker <- newEmptyMVar
  running <- newEmptyMVar
  void $ forkIO $ forever $ starter args blocker running
  mapM_ (killer blocker running) . lines =<< getContents

killer :: MVar () -> MVar ProcessHandle -> String -> IO ()
killer blocker running _input = void $ takeMVar running >>= terminateProcess >> takeMVar blocker

starter :: [String] -> MVar () -> MVar ProcessHandle -> IO ()
starter args blocker running = do
  putMVar blocker ()
  p <- startProcess args
  putMVar running p
  code <- waitForProcess p
  case code of ExitFailure 15 -> return () -- Killed!
               ExitFailure i  -> putStrLn $ "Process [" ++ unwords args ++ "] failed with exit-status [" ++ show i ++ "]"
               ExitSuccess    -> return ()

startProcess :: [String] -> IO ProcessHandle
startProcess (h:t) = (\(_,_,_,ph) -> ph) `fmap` createProcess (proc h t)
startProcess []    = help >> exitFailure

help :: IO ()
help = putStrLn "Usage: conscript command [args*]"