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 ( ...@@ -14,6 +14,7 @@ module Posix (
module PosixTTY, module PosixTTY,
runProcess, runProcess,
exec,
ByteCount, ByteCount,
Fd, intToFd, Fd, intToFd,
...@@ -48,6 +49,26 @@ import PosixUtil ...@@ -48,6 +49,26 @@ import PosixUtil
-- [OLD COMMENT:] -- [OLD COMMENT:]
-- runProcess is our candidate for the high-level OS-independent primitive -- runProcess is our candidate for the high-level OS-independent primitive
-- If accepted, it will be moved out of Posix into LibSystem. -- 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 ) import Directory ( setCurrentDirectory )
...@@ -60,19 +81,19 @@ runProcess :: FilePath -- Command ...@@ -60,19 +81,19 @@ runProcess :: FilePath -- Command
-> Maybe Handle -- stdout -> Maybe Handle -- stdout
-> Maybe Handle -- stderr -> Maybe Handle -- stderr
-> IO () -> IO ()
runProcess path args env dir stdin stdout stderr = runProcess path args env dir stdin stdout stderr = do
forkProcess >>= \ pid -> pid <- forkProcess
case pid of case pid of
Nothing -> doTheBusiness Nothing -> doTheBusiness
Just x -> return () Just x -> return ()
where where
doTheBusiness :: IO () doTheBusiness :: IO ()
doTheBusiness = doTheBusiness = do
maybeChangeWorkingDirectory >> maybeChangeWorkingDirectory
maybeDup2 0 stdin >> maybeDup2 0 stdin
maybeDup2 1 stdout >> maybeDup2 1 stdout
maybeDup2 2 stderr >> maybeDup2 2 stderr
executeFile path True args env >> executeFile path True args env
syserr "runProcess" syserr "runProcess"
maybeChangeWorkingDirectory :: IO () maybeChangeWorkingDirectory :: IO ()
...@@ -84,8 +105,9 @@ runProcess path args env dir stdin stdout stderr = ...@@ -84,8 +105,9 @@ runProcess path args env dir stdin stdout stderr =
maybeDup2 :: Int -> Maybe Handle -> IO () maybeDup2 :: Int -> Maybe Handle -> IO ()
maybeDup2 dest h = maybeDup2 dest h =
case h of Nothing -> return () case h of Nothing -> return ()
Just x -> handleToFd x >>= \ src -> Just x -> do
dupTo src (intToFd dest) >> src <- handleToFd x
return () dupTo src (intToFd dest)
return ()
\end{code} \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