[Haskell] Re: rawSystem unpredictable with signals

John Goerzen jgoerzen at complete.org
Thu Jul 6 17:06:59 EDT 2006


On Thu, Jul 06, 2006 at 11:42:13AM +0100, Simon Marlow wrote:
> Would you like to submit a bug report on this, I'll try to get to it 
> before GHC 6.6.

I can also send you the code that works for me on my own
reimplementation.

> The problem with this is that not all platforms are POSIX, and 
> System.Process is trying to be platform-independent.  Having a more 
> elaborate version of System.Process under System.Posix.Process would be 
> an option, though.  You can reuse some of the bits from 
> System.Process.Internals.

I believe that isn't actually necessary (at least, not directly).  My
code in MissingH is:


{- | Invokes the specified command in a subprocess, waiting for the result.
Return the result status.  Never raises an exception.  Only available
on POSIX platforms.

Like system(3), this command ignores SIGINT and SIGQUIT and blocks SIGCHLD
during its execution.

Logs as MissingH.Cmd.posixRawSystem -}
posixRawSystem :: FilePath -> [String] -> IO ProcessStatus
posixRawSystem program args =
    do debugM (logbase ++ ".posixRawSystem")
               ("Running: " ++ program ++ " " ++ (show args))
       oldint <- installHandler sigINT Ignore Nothing
       oldquit <- installHandler sigQUIT Ignore Nothing
       let sigset = addSignal sigCHLD emptySignalSet
       oldset <- getSignalMask
       blockSignals sigset
       childpid <- forkProcess (childaction oldint oldquit oldset)

       mps <- getProcessStatus True False childpid
       restoresignals oldint oldquit oldset
       let retval = case mps of
                      Just x -> x
                      Nothing -> error "Nothing returned from getProcessStatus"

       debugM (logbase ++ ".posixRawSystem")
              (program ++ ": exited with " ++ show retval)
       return retval

    where childaction oldint oldquit oldset =
              do restoresignals oldint oldquit oldset
                 executeFile program True args Nothing
          restoresignals oldint oldquit oldset =
              do installHandler sigINT oldint Nothing
                 installHandler sigQUIT oldquit Nothing
                 setSignalMask oldset



More information about the Haskell mailing list