more on GHC 6.4 Debian packages
Ian Lynagh
igloo at earth.li
Fri Jul 29 16:59:43 EDT 2005
On Fri, Jul 29, 2005 at 09:27:08PM +0100, Simon Marlow wrote:
> On 28 July 2005 22:42, Ian Lynagh wrote:
>
> > However, the timeout program tickles known bugs in Linux 2.4 on hppa
> > (and possibly unknown bugs on ia64, as discussed briefly on ghc-cvs).
>
> I'd still like to get your souped-up timeout program into CVS. Would
> you like to post it?
Here's what I've currently got. I suspect the second forkIO should
really be forkOS, but it might not be necessary at all on non-buggy
systems (in which case the code can be simplified a bit).
Thanks
Ian
-------------- next part --------------
{-# OPTIONS -cpp #-}
import Control.Concurrent (forkIO, threadDelay)
import Control.Concurrent.MVar (putMVar, takeMVar, newEmptyMVar)
import Control.Exception (try)
import Data.Maybe (isNothing)
import System.Cmd (system)
import System.Environment (getArgs)
import System.Exit (exitWith, ExitCode(ExitFailure))
import System.IO (hPutStrLn, stderr)
import System.Process (waitForProcess, getProcessExitCode)
#if !defined(mingw32_HOST_OS)
import Control.Monad (when)
import System.Process.Internals (ProcessHandle(ProcessHandle))
import System.Posix.Process (forkProcess, createSession)
import System.Posix.Signals (installHandler, Handler(Catch),
signalProcessGroup, sigINT, sigTERM, sigKILL )
#endif
main = do
args <- getArgs
case args of
[secs,cmd] -> do
m <- newEmptyMVar
mp <- newEmptyMVar
#if !defined(mingw32_HOST_OS)
installHandler sigINT (Catch (putMVar m Nothing)) Nothing
#endif
forkIO (do threadDelay (read secs * 1000000)
putMVar m Nothing
)
forkIO (do try (do p <- forkProcess $ do
createSession
r <- system cmd
exitWith r
putMVar mp p
r <- waitForProcess (ProcessHandle p)
putMVar m (Just r))
return ())
p <- takeMVar mp
r <- takeMVar m
case r of
Nothing -> do
killProcess p
exitWith (ExitFailure 99)
Just r -> do
exitWith r
_other -> do hPutStrLn stderr "timeout: bad arguments"
exitWith (ExitFailure 1)
#if !defined(mingw32_HOST_OS)
killProcess p = do
try (signalProcessGroup sigTERM p)
checkReallyDead 10
where
checkReallyDead 0 = hPutStrLn stderr "checkReallyDead: Giving up"
checkReallyDead (n+1) =
do threadDelay (3*100000) -- 3/10 sec
m <- getProcessExitCode (ProcessHandle p)
when (isNothing m) $ do
try (signalProcessGroup sigKILL p)
checkReallyDead n
#else
killProcess p = do
terminateProcess p
threadDelay (3*100000) -- 3/10 sec
m <- getProcessExitCode p
when (isNothing m) $ killProcess p
#endif
More information about the Glasgow-haskell-users
mailing list