From acf37abcd5d48b74c2cd9285a69eb35bd6959b10 Mon Sep 17 00:00:00 2001 From: simonmar Date: Fri, 29 Jun 2001 13:41:43 +0000 Subject: [PATCH] [project @ 2001-06-29 13:41:43 by simonmar] Fix bug where openFile in WriteMode truncates the file even if the open fails because of a locking violation. --- ghc/lib/std/PrelHandle.hsc | 22 ++++++++++++++++------ ghc/lib/std/PrelPosix.hsc | 18 +++++++++++++++++- 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/ghc/lib/std/PrelHandle.hsc b/ghc/lib/std/PrelHandle.hsc index a7e51d2..084a182 100644 --- a/ghc/lib/std/PrelHandle.hsc +++ b/ghc/lib/std/PrelHandle.hsc @@ -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 diff --git a/ghc/lib/std/PrelPosix.hsc b/ghc/lib/std/PrelPosix.hsc index 5dc6242..edb5107 100644 --- a/ghc/lib/std/PrelPosix.hsc +++ b/ghc/lib/std/PrelPosix.hsc @@ -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 -- 1.7.10.4