Hi Volker,

Volker Wysk <[EMAIL PROTECTED]> writes:

> On Mit, 2002-03-20 at 07:00, Jens Petersen wrote:
> > Jens Petersen <[EMAIL PROTECTED]> writes:
> > 
> > > > The problem is that the child process doesn't
> > > > receive all the data which the parent sends. It's as
> > > > if "hPutStr vonh txt" sends the data lazily somehow,
> > > > and "hClose vonh" closes the pipe prematurely.
> > > > 
> > > > It varies from run to run exactly which data gets
> > > > through. If I cause the child process to read all
> > > > its input immediately, the problem doesn't seem to
> > > > occur. Normally, it does so gradually, which takes a
> > > > few seconds.
> > > > 
> > > > I'm using GHC 5.02.2
> > > 
> > > Quite possibly could be a bug.  Lazy IO is rather subtle I
> > > think, specially when done across pipes.  I faced some
> > > similar problem with in POpen recently.  You can see how I
> > > solved it (worked round it?) by comparing the latest release
> > > 1.00 with the previous one 0.00.1:
> > > 
> > >         http://www.01.246.ne.jp/~juhp/haskell/popenhs/
> 
> POpen-1.0.0 contains the same bug which I made. It doesn't ensure that
> the values which are needed after the call of forkProcess, before that
> of executeFile, are fully evaluated. So, if they are read lazily from a
> stream, the newly spawned child process reads data from a stream which
> it shares with its parent, making it disappear from the parent's input.
> In this situation, this sure isn't intended.

Perhaps you could give an explicit example?

> Inserting the following lines just before the line "pid <- forkProcess",
> in POpen.hs, would force the corresponding values to be evaluated, so no
> data will be lost.
> 
>     seq (length path) $ seq (sum (map length args)) $ return ()
>     when (isJust env) $ seq (sum (map (\(a,b) -> length a + length b) 
>                                       (fromJust env))) $ return ()
>     when (isJust dir) $ seq (length (fromJust dir)) $ return ()

Hmmm, I don't really see why this is necessary.  Don't the
lazy values of "path", "env" and "dir" just get evaluated
when they're needed here as normal?  (If what you say is
true though it would be simpler just to use "$!" or "!"s for
strict evaluation I guess.)

I would be more worried about the input stream string not
being complete when the input handle is closed.

> I'm also not sure what this part is supposed to do:
> 
>     inr <- if (isJust inpt) then
>            do
>            (inr', inw) <- createPipe
>            hin <- fdToHandle inw
>            hPutStr hin $ fromJust inpt
>            hClose hin
>            return $ Just inr'
>           else
>           return Nothing

It returns the output end of a pipe containing the input
string if one is given.

> Doesn't it write the input data to a pipe which no process reads
> from..??

Nope, "doTheBusiness" dup2's it to the stdin of the subprocess:

      (outr, outw) <- createPipe
      (errr, errw) <- createPipe
      pid <- forkProcess
      case pid of
        Nothing -> doTheBusiness inr outw errw   -- ***
        Just p -> 
          do
          -- close other end of pipes in here
          when (isJust inr) $
               fdClose $ fromJust inr
          fdClose outw
          fdClose errw
          hout <- fdToHandle outr
          outstrm <- hGetContents hout
          herr <- fdToHandle errr
          errstrm <- hGetContents herr
          return (outstrm, errstrm , p)
    where
    doTheBusiness :: 
        Maybe Fd            -- stdin
        -> Fd               -- stdout
        -> Fd               -- stderr
        -> IO (String, String, ProcessID)    -- (stdout, stderr)
    doTheBusiness inr outw errw = 
        do
        maybeChangeWorkingDirectory dir
        when (isJust inr) $
             dupTo (fromJust inr) stdInput   -- ***
        dupTo outw stdOutput
        dupTo errw stdError
        executeFile path True args env
        -- for typing, should never actually run
        error "executeFile failed!"

Jens
_______________________________________________
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell

Reply via email to