Skip to content
Snippets Groups Projects
Commit 581039a0 authored by sof's avatar sof
Browse files

[project @ 1998-05-16 20:03:02 by sof]

Added comment on the vagaries of combining runProcess and lazy file I/O
parent 47e446c7
No related merge requests found
......@@ -14,6 +14,7 @@ module Posix (
module PosixTTY,
runProcess,
exec,
ByteCount,
Fd, intToFd,
......@@ -48,6 +49,26 @@ import PosixUtil
-- [OLD COMMENT:]
-- runProcess is our candidate for the high-level OS-independent primitive
-- If accepted, it will be moved out of Posix into LibSystem.
--
-- ***NOTE***: make sure you completely force the evaluation of the path
-- and arguments to the child before calling runProcess. If you don't do
-- this *and* the arguments from runProcess are read in from a file lazily,
-- be prepared for some rather weird parent-child file I/O behaviour.
--
-- [If you don't force the args, consider the case where the
-- arguments emanate from a file that is read lazily, using hGetContents
-- or some such. Since a child of a fork() inherits the opened files of
-- the parent, the child can force the evaluation of the arguments and
-- read them off the file without any problems. The problem is that
-- while the child share a file table with the parent, it has
-- separate buffers, so a child may fill up its (copy of) the buffer, but
-- only read it partially. When the *parent* tries to read from the shared file again,
-- the (shared) file offset will have been stepped on by whatever number of chars
-- that was copied into the file buffer of the child. i.e., the unused parts of the
-- buffer will *not* be seen, resulting in random/unpredicatable results.
--
-- Based on a true (, debugged :-) story.
-- ]
import Directory ( setCurrentDirectory )
......@@ -60,19 +81,19 @@ runProcess :: FilePath -- Command
-> Maybe Handle -- stdout
-> Maybe Handle -- stderr
-> IO ()
runProcess path args env dir stdin stdout stderr =
forkProcess >>= \ pid ->
runProcess path args env dir stdin stdout stderr = do
pid <- forkProcess
case pid of
Nothing -> doTheBusiness
Just x -> return ()
where
doTheBusiness :: IO ()
doTheBusiness =
maybeChangeWorkingDirectory >>
maybeDup2 0 stdin >>
maybeDup2 1 stdout >>
maybeDup2 2 stderr >>
executeFile path True args env >>
doTheBusiness = do
maybeChangeWorkingDirectory
maybeDup2 0 stdin
maybeDup2 1 stdout
maybeDup2 2 stderr
executeFile path True args env
syserr "runProcess"
maybeChangeWorkingDirectory :: IO ()
......@@ -84,8 +105,9 @@ runProcess path args env dir stdin stdout stderr =
maybeDup2 :: Int -> Maybe Handle -> IO ()
maybeDup2 dest h =
case h of Nothing -> return ()
Just x -> handleToFd x >>= \ src ->
dupTo src (intToFd dest) >>
return ()
Just x -> do
src <- handleToFd x
dupTo src (intToFd dest)
return ()
\end{code}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment