Glynn Clements writes: > Although, depending upon the OS, setting SIGCHLD to > SIG_IGN may cause processes to be reaped automatically > (i.e. not become zombies), so that's a possible > alternative.
I think I've got it under control now. I'm using this wrapper to make sure there are no unwaited-for child processes: type ExternHandle = MVar (Handle, Handle, Handle, ProcessHandle) -- |Run an external process and store its handle in an -- 'MVar' with a finalizer attached to it that will close -- the handles and kill the process when the MVar falls out -- of scope. extern :: FilePath -> [String] -> IO ExternHandle extern path args = do r <- runInteractiveProcess path args (Just "/") (Just []) mv <- newMVar r addMVarFinalizer mv (catch (cleanup r) (const (return ()))) return mv where cleanup (hin, hout, herr, pid) = do terminateProcess pid >> safeWaitForProcess pid hClose hin >> hClose hout >> hClose herr return () -- |Wait 10 seconds max. If the process hasn't terminated by -- then, throw an exception. If the child process has been -- terminated by a signal, return @ExitFailure [EMAIL PROTECTED] This is -- a kludge. So it will probably be in here forever. safeWaitForProcess :: ProcessHandle -> IO ExitCode safeWaitForProcess pid = timeout maxwait loop >>= maybe badluck return where loop = catch loop' (\_ -> return (ExitFailure 137)) loop' = wait >> getProcessExitCode pid >>= maybe loop' return wait = threadDelay 1000000 -- 1/10 second maxwait = 10000000 -- 10 seconds badluck = fail "timeout while waiting for external process" It's ugly, but it seems to work. Peter _______________________________________________ Glasgow-haskell-users mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/glasgow-haskell-users