diff --git a/Distribution/Compat/TempFile.hs b/Distribution/Compat/TempFile.hs
index fc123e7211dc1a5bffda4caa3c253a1996c70079..5c5bb0c7f6da1722dfc57f17dffc2106f19b26e3 100644
--- a/Distribution/Compat/TempFile.hs
+++ b/Distribution/Compat/TempFile.hs
@@ -3,62 +3,42 @@
 {-# OPTIONS_NHC98 -cpp #-}
 {-# OPTIONS_JHC -fcpp #-}
 -- #hide
-module Distribution.Compat.TempFile (openTempFile, withTempFile) where
+module Distribution.Compat.TempFile (openTempFile) where
 
-import System.IO (openFile, Handle, IOMode(ReadWriteMode))
-import System.Directory (doesFileExist, removeFile)
-import Control.Exception (finally,try)
-
-import System.FilePath ( (</>), (<.>) )
-
-#if (__GLASGOW_HASKELL__ || __HUGS__)
+#if __NHC__ || __HUGS__
+import System.IO              (openFile, Handle, IOMode(ReadWriteMode))
+import System.Directory       (doesFileExist)
+import System.FilePath        ((</>))
 import System.Posix.Internals (c_getpid)
 #else
-import System.Posix.Types (CPid(..))
+import System.IO (openTempFile)
 #endif
 
-
 -- ------------------------------------------------------------
 -- * temporary files
 -- ------------------------------------------------------------
 
--- TODO: this function *really really really* should be
---       eliminated and replaced with System.IO.openTempFile,
---       except that is currently GHC-only for no valid reason.
+-- This is here for Haskell implementations that do not come with
+-- System.IO.openTempFile. This includes nhc-1.20, hugs-2006.9.
+-- TODO: Not sure about jhc
 
+#if __NHC__ || __HUGS__
 -- use a temporary filename that doesn't already exist.
 -- NB. *not* secure (we don't atomically lock the tmp file we get)
 openTempFile :: FilePath -> String -> IO (FilePath, Handle)
 openTempFile tmp_dir template
-  = do x <- getProcessID
-       findTempName x
-  where 
-    findTempName x
-      = do let filename = template ++ show x
-	       path = tmp_dir </> filename
-  	   b  <- doesFileExist path
-	   if b then findTempName (x+1)
-		else do hnd <- openFile path ReadWriteMode
-                        return (path, hnd)
-
-#if !(__GLASGOW_HASKELL__ || __HUGS__)
-foreign import ccall unsafe "getpid" c_getpid :: IO CPid
-#endif
-
-getProcessID :: IO Int
-getProcessID = c_getpid >>= return . fromIntegral
-
--- use a temporary filename that doesn't already exist.
--- NB. *not* secure (we don't atomically lock the tmp file we get)
-withTempFile :: FilePath -> String -> (FilePath -> IO a) -> IO a
-withTempFile tmp_dir extn action
   = do x <- getProcessID
        findTempName x
   where
+    (templateBase, templateExt) = splitExtension template
+    findTempName :: Int -> IO (FilePath, Handle)
     findTempName x
-      = do let filename = ("tmp" ++ show x) <.> extn
-               path = tmp_dir </> filename
+      = do let path = tmp_dir </> (templateBase ++ show x) <.> templateExt
            b  <- doesFileExist path
            if b then findTempName (x+1)
-                else action path `finally` try (removeFile path)
+                else do hnd <- openFile path ReadWriteMode
+                        return (path, hnd)
 
+    getProcessID :: IO Int
+    getProcessID = fmap fromIntegral c_getpid
+#endif
diff --git a/Distribution/Simple/GHC.hs b/Distribution/Simple/GHC.hs
index 2657a2b812ce2c75cc4088614855e6436c3f38a4..8c6c21584b6bdce3380e0b2bddb885b2fb7b4eba 100644
--- a/Distribution/Simple/GHC.hs
+++ b/Distribution/Simple/GHC.hs
@@ -84,7 +84,6 @@ import Data.List		( nub, isPrefixOf )
 import System.Directory		( removeFile, renameFile,
 				  getDirectoryContents, doesFileExist,
 				  getTemporaryDirectory )
-import Distribution.Compat.TempFile ( withTempFile )
 import System.FilePath          ( (</>), (<.>), takeExtension,
                                   takeDirectory, replaceExtension, splitExtension )
 import System.IO (openFile, IOMode(WriteMode), hClose, hPutStrLn)
@@ -131,13 +130,15 @@ configure verbosity hcPath hcPkgPath conf = do
   -- we need to find out if ld supports the -x flag
   (ldProg, conf''') <- requireProgram verbosity ldProgram' AnyVersion conf''
   tempDir <- getTemporaryDirectory
-  ldx <- withTempFile tempDir "c" $ \testcfile ->
-         withTempFile tempDir "o" $ \testofile -> do
-           writeFile testcfile "int foo() {}\n"
+  ldx <- withTempFile tempDir ".c" $ \testcfile testchnd ->
+         withTempFile tempDir ".o" $ \testofile testohnd -> do
+           hPutStrLn testchnd "int foo() {}"
+           hClose testchnd; hClose testohnd
            rawSystemProgram verbosity ghcProg ["-c", testcfile,
                                                "-o", testofile]
-           withTempFile tempDir "o" $ \testofile' ->
+           withTempFile tempDir ".o" $ \testofile' testohnd' ->
              handle (\_ -> return False) $ do
+               hClose testohnd'
                rawSystemProgramStdout verbosity ldProg
                  ["-x", "-r", testofile, "-o", testofile']
                return True
diff --git a/Distribution/Simple/Program.hs b/Distribution/Simple/Program.hs
index 18d2addaba95a0b79137a06ab8ee5fb59881f98a..ac7c77b6f893366c358ed045fb8c2f30bbb406a4 100644
--- a/Distribution/Simple/Program.hs
+++ b/Distribution/Simple/Program.hs
@@ -84,14 +84,15 @@ module Distribution.Simple.Program (
     ) where
 
 import qualified Data.Map as Map
-import Distribution.Compat.TempFile (withTempFile)
 import Distribution.Simple.Utils (die, debug, warn, rawSystemExit,
-                                  rawSystemStdout, rawSystemStdout')
+                                  rawSystemStdout, rawSystemStdout',
+                                  withTempFile)
 import Distribution.Version (Version(..), readVersion, showVersion,
                              VersionRange(..), withinRange, showVersionRange)
 import Distribution.Verbosity
 import System.Directory (doesFileExist, removeFile, findExecutable)
 import System.FilePath  (dropExtension)
+import System.IO (hClose)
 import System.IO.Error (try)
 import Control.Monad (join, foldM)
 import Control.Exception as Exception (catch)
@@ -570,8 +571,8 @@ hsc2hsProgram = (simpleProgram "hsc2hs") {
       case maybeVersion of
         Nothing -> return Nothing
 	Just version ->
-          withTempFile "dist" "hsc" $ \hsc -> do
-	    writeFile hsc ""
+          withTempFile "dist" ".hsc" $ \hsc hnd -> do
+	    hClose hnd
 	    (str, _) <- rawSystemStdout' verbosity path [hsc, "--cflag=--version"]
 	    try $ removeFile (dropExtension hsc ++ "_hsc_make.c")
 	    case words str of
diff --git a/Distribution/Simple/Utils.hs b/Distribution/Simple/Utils.hs
index 7b470553114eb7fb76373b95089fe660ca9067ab..7fb5a2d7002504179463f13399f89d8370ee920f 100644
--- a/Distribution/Simple/Utils.hs
+++ b/Distribution/Simple/Utils.hs
@@ -70,6 +70,7 @@ module Distribution.Simple.Utils (
         currentDir,
         dotToSep,
 	findFile,
+        withTempFile,
         defaultPackageDesc,
         findPackageDesc,
 	defaultHookedPackageDesc,
@@ -121,13 +122,9 @@ import System.Cmd (system)
 import Control.Exception (evaluate)
 import System.Process (runProcess, waitForProcess)
 #endif
-import System.IO (hClose)
+import System.IO (Handle, hClose)
 
-#if __GLASGOW_HASKELL__ >= 604
 import Distribution.Compat.TempFile (openTempFile)
-#else
-import Distribution.Compat.TempFile (withTempFile)
-#endif
 import Distribution.Verbosity
 
 #ifdef DEBUG
@@ -445,7 +442,15 @@ copyDirectoryRecursiveVerbose verbosity srcDir destDir = do
             fmap (filter (not . flip elem [".", ".."]))
           . getDirectoryContents
 
-
+-- | Use a temporary filename that doesn't already exist.
+--
+withTempFile :: FilePath -- ^ Temp dir to create the file in
+             -> String   -- ^ File name template. See 'openTempFile'.
+             -> (FilePath -> Handle -> IO a) -> IO a
+withTempFile tmpDir template action =
+  bracket (openTempFile tmpDir template)
+          (\(name, handle) -> hClose handle >> removeFile name)
+          (uncurry action)
 
 -- | The path name that represents the current directory.
 -- In Unix, it's @\".\"@, but this is system-specific.