[project @ 2001-06-29 13:41:43 by simonmar]
authorsimonmar <unknown>
Fri, 29 Jun 2001 13:41:43 +0000 (13:41 +0000)
committersimonmar <unknown>
Fri, 29 Jun 2001 13:41:43 +0000 (13:41 +0000)
Fix bug where openFile in WriteMode truncates the file even if the
open fails because of a locking violation.

ghc/lib/std/PrelHandle.hsc
ghc/lib/std/PrelPosix.hsc

index a7e51d2..084a182 100644 (file)
@@ -4,7 +4,7 @@
 #undef DEBUG
 
 -- -----------------------------------------------------------------------------
--- $Id: PrelHandle.hsc,v 1.11 2001/06/29 12:45:39 simonmar Exp $
+-- $Id: PrelHandle.hsc,v 1.12 2001/06/29 13:41:43 simonmar Exp $
 --
 -- (c) The University of Glasgow, 1994-2001
 --
@@ -626,6 +626,9 @@ openFile' filepath ex_mode =
                  ReadWriteMode -> rw_flags    
                  AppendMode    -> append_flags
 
+      truncate | WriteMode <- mode = True
+              | otherwise         = False
+
       binary_flags
 #ifdef HAVE_O_BINARY
          | binary    = o_BINARY
@@ -644,21 +647,24 @@ openFile' filepath ex_mode =
              throwErrnoIfMinus1Retry "openFile"
                (c_open f (fromIntegral oflags) 0o666)
 
-    openFd fd filepath mode binary
+    openFd fd filepath mode binary truncate
+       -- ASSERT: if we just created the file, then openFd won't fail
+       -- (so we don't need to worry about removing the newly created file
+       --  in the event of an error).
 
 
 std_flags    = o_NONBLOCK   .|. o_NOCTTY
 output_flags = std_flags    .|. o_CREAT
 read_flags   = std_flags    .|. o_RDONLY 
-write_flags  = output_flags .|. o_WRONLY .|. o_TRUNC
+write_flags  = output_flags .|. o_WRONLY
 rw_flags     = output_flags .|. o_RDWR
-append_flags = output_flags .|. o_WRONLY .|. o_APPEND
+append_flags = write_flags  .|. o_APPEND
 
 -- ---------------------------------------------------------------------------
 -- openFd
 
-openFd :: FD -> FilePath -> IOMode -> Bool -> IO Handle
-openFd fd filepath mode binary = do
+openFd :: FD -> FilePath -> IOMode -> Bool -> Bool -> IO Handle
+openFd fd filepath mode binary truncate = do
     -- turn on non-blocking mode
     setNonBlockingFD fd
 
@@ -687,6 +693,10 @@ openFd fd filepath mode binary = do
           when (r == -1)  $
                ioException (IOError Nothing ResourceBusy "openFile"
                                   "file is locked" Nothing)
+
+          -- truncate the file if necessary
+          when truncate (fileTruncate filepath)
+
           mkFileHandle fd filepath ha_type binary
 
 
index 5dc6242..edb5107 100644 (file)
@@ -1,7 +1,7 @@
 {-# OPTIONS -fno-implicit-prelude -optc-DNON_POSIX_SOURCE #-}
 
 -- ---------------------------------------------------------------------------
--- $Id: PrelPosix.hsc,v 1.7 2001/06/22 12:36:34 rrt Exp $
+-- $Id: PrelPosix.hsc,v 1.8 2001/06/29 13:41:43 simonmar Exp $
 --
 -- POSIX support layer for the standard libraries
 --
@@ -106,6 +106,19 @@ foreign import "s_issock_wrap" s_issock :: CMode -> Bool
 s_issock :: CMode -> Bool
 s_issock cmode = False
 #endif
+
+-- It isn't clear whether ftruncate is POSIX or not (I've read several
+-- manpages and they seem to conflict), so we truncate using open/2.
+fileTruncate :: FilePath -> IO ()
+fileTruncate file = do
+  let flags = o_WRONLY .|. o_TRUNC
+  withCString file $ \file_cstr -> do
+    fd <- fromIntegral `liftM`
+           throwErrnoIfMinus1Retry "fileTruncate"
+               (c_open file_cstr (fromIntegral flags) 0o666)
+    c_close fd
+  return ()
+
 -- ---------------------------------------------------------------------------
 -- Terminal-related stuff
 
@@ -284,6 +297,9 @@ foreign import "tcgetattr" unsafe
 foreign import "tcsetattr" unsafe
    c_tcsetattr :: CInt -> CInt -> Ptr Termios -> IO CInt
 
+foreign import "unlink" unsafe 
+   c_unlink :: CString -> IO CInt
+
 foreign import "waitpid" unsafe
    c_waitpid :: CPid -> Ptr CInt -> CInt -> IO CPid
 #endif