diff --git a/ghc/lib/std/Directory.lhs b/ghc/lib/std/Directory.lhs
index edd0e7ba3ab5a0833b2f1595d5e8e4fdeef264a3..e3bb80cda0e683fffb8aa42eb04e9abf3a6287ef 100644
--- a/ghc/lib/std/Directory.lhs
+++ b/ghc/lib/std/Directory.lhs
@@ -133,7 +133,7 @@ The path refers to an existing non-directory object.
 createDirectory path = do
     rc <- _ccall_ createDirectory path
     if rc == 0 then return () else
-        constructErrorAndFail "createDirectory"
+        constructErrorAndFailWithInfo "createDirectory" path
 \end{code}
 
 @removeDirectory dir@ removes an existing directory {\em dir}.  The
@@ -176,7 +176,7 @@ removeDirectory path = do
     if rc == 0 then 
 	return ()
      else 
-        constructErrorAndFail "removeDirectory"
+        constructErrorAndFailWithInfo "removeDirectory" path
 \end{code}
 
 @removeFile file@ removes the directory entry for an existing file
@@ -213,7 +213,7 @@ removeFile path = do
     if rc == 0 then
         return ()
      else
-        constructErrorAndFail "removeFile"
+        constructErrorAndFailWithInfo "removeFile" path
 \end{code}
 
 @renameDirectory old@ {\em new} changes the name of an existing
@@ -260,7 +260,7 @@ renameDirectory opath npath = do
     if rc == 0 then
         return ()
      else
-        constructErrorAndFail "renameDirectory"
+        constructErrorAndFailWithInfo "renameDirectory" opath
 \end{code}
 
 @renameFile old@ {\em new} changes the name of an existing file system
@@ -305,7 +305,7 @@ renameFile opath npath = do
     if rc == 0 then
         return ()
      else
-        constructErrorAndFail	"renameFile"
+        constructErrorAndFailWithInfo	"renameFile" opath
 \end{code}
 
 @getDirectoryContents dir@ returns a list of {\em all} entries
@@ -338,7 +338,7 @@ The path refers to an existing non-directory object.
 getDirectoryContents path = do
     dir <- _ccall_ openDir__ path
     if dir == ``NULL'' 
-	then constructErrorAndFail "getDirectoryContents"
+	then constructErrorAndFailWithInfo "getDirectoryContents" path
      	else loop dir
   where
     loop :: Addr -> IO [String]
@@ -346,6 +346,8 @@ getDirectoryContents path = do
       dirent_ptr <- _ccall_ readDir__ dir
       if (dirent_ptr::Addr) == ``NULL'' 
        then do
+	  -- readDir__ implicitly performs closedir() when the
+	  -- end is reached.
 	  return [] 
        else do
           str     <- _casm_ `` %r=(char*)((struct dirent*)%0)->d_name; '' dirent_ptr
@@ -423,7 +425,7 @@ setCurrentDirectory path = do
     rc <- _ccall_ setCurrentDirectory path
     if rc == 0 
 	then return ()
-	else constructErrorAndFail "setCurrentDirectory"
+	else constructErrorAndFailWithInfo "setCurrentDirectory" path
 \end{code}
 
 
diff --git a/ghc/lib/std/PrelHandle.lhs b/ghc/lib/std/PrelHandle.lhs
index bf3416dd8606ffbdd839a39bf31823b61e58be9a..c80b941f4607c39bb721c102bc22c8c6552da65a 100644
--- a/ghc/lib/std/PrelHandle.lhs
+++ b/ghc/lib/std/PrelHandle.lhs
@@ -206,15 +206,7 @@ openFileEx f m = do
 	newHandle (htype ptr Nothing False)
 #endif
       else do
-	ioError@(IOError hn iot msg) <- constructError "openFile"
-	let
-	    improved_error -- a HACK, I guess
-	      = case iot of
-		  AlreadyExists    -> IOError hn AlreadyExists    (msg ++ ": " ++ f)
-		  NoSuchThing      -> IOError hn NoSuchThing      (msg ++ ": " ++ f)
-		  PermissionDenied -> IOError hn PermissionDenied (msg ++ ": " ++ f)
-		  _		   -> ioError
-        fail improved_error
+	constructErrorAndFailWithInfo "openFile" f
   where
     imo = case m of
            BinaryMode imo -> imo
diff --git a/ghc/lib/std/PrelIOBase.lhs b/ghc/lib/std/PrelIOBase.lhs
index bcf6d7dec9e2659c8ea3891e0754541fe5c346e4..f8c8cf81817516f1e820f0c52f944adebcc34722 100644
--- a/ghc/lib/std/PrelIOBase.lhs
+++ b/ghc/lib/std/PrelIOBase.lhs
@@ -20,7 +20,7 @@ import PrelMaybe
 import PrelAddr
 import PrelPack	( unpackCString )
 import PrelBase
-import PrelArr	( ByteArray(..), MutableVar(..) )
+import PrelArr	( ByteArray(..), MutableVar )
 import PrelGHC
 
 \end{code}
@@ -216,17 +216,17 @@ the exact strings to be used for particular errors.  For errors not
 explicitly mentioned in the standard, any descriptive string may be
 used.
 
-\begin{change}
-SOF & 4/96 & added argument to indicate function that flagged error
-\end{change}
-% Hmm..does these envs work?!...SOF
-
 \begin{code}
 constructErrorAndFail :: String -> IO a
 constructErrorAndFail call_site
   = constructError call_site >>= \ io_error ->
     fail io_error
 
+constructErrorAndFailWithInfo :: String -> String -> IO a
+constructErrorAndFailWithInfo call_site reason
+  = constructErrorMsg call_site (Just reason) >>= \ io_error ->
+    fail io_error
+
 \end{code}
 
 This doesn't seem to be documented/spelled out anywhere,
@@ -243,7 +243,10 @@ information.
 
 \begin{code}
 constructError	      :: String -> IO IOError
-constructError call_site =
+constructError call_site = constructErrorMsg call_site Nothing
+
+constructErrorMsg	      :: String -> Maybe String -> IO IOError
+constructErrorMsg call_site reason =
  _casm_ ``%r = ghc_errtype;''    >>= \ (I# errtype#) ->
  _casm_ ``%r = ghc_errstr;''	 >>= \ str ->
  let
@@ -271,9 +274,12 @@ constructError call_site =
 
   msg = 
    call_site ++ ':' : ' ' : unpackCString str ++
-   case iot of
+   (case iot of
      OtherError -> "(error code: " ++ show (I# errtype#) ++ ")"
-     _ -> ""
+     _ -> "") ++
+   (case reason of
+      Nothing -> ""
+      Just m  -> ' ':m)
  in
  return (IOError Nothing iot msg)
 \end{code}
diff --git a/ghc/lib/std/System.lhs b/ghc/lib/std/System.lhs
index ad0b66c6cfd81f34edbefa4adee9e409189d7a57..096a860d6ba6c5c72a96187ffbdf0b5359aff2ae 100644
--- a/ghc/lib/std/System.lhs
+++ b/ghc/lib/std/System.lhs
@@ -12,7 +12,7 @@ module System (
 
 import Prelude
 import PrelAddr
-import PrelIOBase	( IOError(..), IOErrorType(..), constructErrorAndFail )
+import PrelIOBase	( IOError(..), IOErrorType(..), constructErrorAndFailWithInfo )
 import PrelArr		( indexAddrOffAddr )
 import PrelPack    	( unpackCString )
 
@@ -103,7 +103,7 @@ system cmd = do
     status <- _ccall_ systemCmd cmd
     case status of
         0  -> return ExitSuccess
-        -1 -> constructErrorAndFail "system"
+        -1 -> constructErrorAndFailWithInfo "system" cmd
         n  -> return (ExitFailure n)
 
 \end{code}