lambdabot-utils 4.2 → 4.2.1
raw patch · 4 files changed
+22/−30 lines, 4 filesdep +sybdep ~basedep ~tagsoup
Dependencies added: syb
Dependency ranges changed: base, tagsoup
Files
- Lambdabot/Process.hs +18/−25
- Lambdabot/Signals.hs +1/−1
- Lambdabot/Url.hs +0/−1
- lambdabot-utils.cabal +3/−3
Lambdabot/Process.hs view
@@ -7,9 +7,9 @@ import System.Exit import System.IO import System.Process-import Control.Concurrent (forkIO, newEmptyMVar, putMVar, takeMVar)--import qualified Control.Exception+import Control.Concurrent (forkIO, newEmptyMVar, putMVar, takeMVar, killThread)+import Control.Monad+import qualified Control.Exception as E run :: FilePath -> String -> (String -> String) -> IO String run binary src scrub = do@@ -22,30 +22,24 @@ | otherwise -> o } ------ Ignoring exit status for now.------ You have to ignore SIGPIPE, otherwise popening a non-existing executable--- will result in an attempt to write to a closed pipe and crash the wholw--- program.------ XXX there are still issues. Large amounts of output can cause what--- seems to be a dead lock on the pipe write from runplugs, for example.--- Posix.popen doesn't have this problem, so maybe we can reproduce its--- pipe handling somehow. -- | popen lets you run a binary with specified arguments. This bypasses the shell.+-- | It'll also terminate (SIGTERM) the spawned process in case of+-- | exception, this is very important if the timeout for a Plugin+-- | expires while it is waiting for the result of a looping process.+-- | It's fundamental to link the final executable with -threaded. popen :: FilePath -- ^ The binary to execute -> [String] -- ^ A list of arguments to pass to the binary. No need to -- space separate them -> Maybe String -- ^ stdin -> IO (String,String,ExitCode) popen file args minput =- Control.Exception.handle (\e -> return ([],show e,error (show e))) $ do-- (inp,out,err,pid) <- runInteractiveProcess file args Nothing Nothing+ E.handle (\(E.SomeException e) -> return ([],show e,error (show e))) $ + E.bracketOnError (runInteractiveProcess file args Nothing Nothing) (\(_,_,_,pid) -> terminateProcess pid) $+ \(inp,out,err,pid) -> do case minput of- Just input -> hPutStr inp input >> hClose inp -- importante!+ Just input -> hPutStr inp input >> E.catch (hClose inp)+ (\(E.SomeException e) -> return ()) Nothing -> return () -- Now, grab the input@@ -65,15 +59,14 @@ outMVar <- newEmptyMVar errMVar <- newEmptyMVar - forkIO (Control.Exception.evaluate (length output) >> putMVar outMVar ())- forkIO (Control.Exception.evaluate (length errput) >> putMVar errMVar ())-- takeMVar outMVar- takeMVar errMVar+ E.bracketOnError (do t1 <- forkIO (E.evaluate (length output) >> putMVar outMVar ())+ t2 <- forkIO (E.evaluate (length errput) >> putMVar errMVar ())+ return (t1,t2))+ (\(t1,t2) -> killThread t1 >> killThread t2 )+ (\_ -> takeMVar outMVar >> takeMVar errMVar) -- And now we wait. We must wait after we read, unsurprisingly. -- blocks without -threaded, you're warned. -- and maybe the process has already completed..- e <- Control.Exception.catch (waitForProcess pid) (\_ -> return ExitSuccess)-+ e <- waitForProcess pid return (output,errput,e)
Lambdabot/Signals.hs view
@@ -30,7 +30,7 @@ import Data.Typeable import Control.Concurrent (myThreadId, newEmptyMVar, putMVar, MVar, ThreadId)-import Control.Exception+import Control.OldException (throwDynTo) import Control.Monad.Error import System.IO.Unsafe
Lambdabot/Url.hs view
@@ -16,7 +16,6 @@ import Lambdabot.MiniHTTP import Control.Monad.Reader-import Text.HTML.TagSoup.Parser import Text.HTML.TagSoup.Match import Text.HTML.TagSoup import Codec.Binary.UTF8.String
lambdabot-utils.cabal view
@@ -1,5 +1,5 @@ Name: lambdabot-utils-Version: 4.2+Version: 4.2.1 License: GPL License-file: LICENSE Author: Don Stewart@@ -25,8 +25,8 @@ Homepage: http://haskell.org/haskellwiki/Lambdabot build-type: Simple -Build-depends: base, haskell-src, containers, zlib, bytestring, mtl,- regex-compat, regex-posix, process, network, old-time, binary, unix, random, tagsoup, utf8-string+Build-depends: base >= 4 && < 5, haskell-src, containers, zlib, bytestring, mtl, syb,+ regex-compat, regex-posix, process, network, old-time, binary, unix, random, tagsoup>0.6, utf8-string Exposed-modules: Lambdabot.FixPrecedence, Lambdabot.Serial, Lambdabot.Error, Lambdabot.Url, Lambdabot.Process, Lambdabot.Regex, Lambdabot.MiniHTTP, Lambdabot.AltTime,