diff --git a/ghc/lib/posix/Posix.lhs b/ghc/lib/posix/Posix.lhs
index fa3c233592bd79be7eed64ef93731952456c6998..8eeb0f7b4856d34e7ddf2ac34001adcba3f5b1c2 100644
--- a/ghc/lib/posix/Posix.lhs
+++ b/ghc/lib/posix/Posix.lhs
@@ -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}