From 1572c460e86a048e9f2419a42646898b7982d5af Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Mon, 3 Feb 2014 10:16:05 -0400 Subject: [PATCH] avoid using openFile when withFile can be used Potentially fixes some FD leak if an action on an opened file handle fails for some reason. There have been some hard to reproduce reports of git-annex leaking FDs, and this may solve them. --- Annex/Content/Direct.hs | 3 +-- Annex/Link.hs | 10 +++------- Command/Fsck.hs | 7 +++---- Logs/Transfer.hs | 13 ++++--------- Remote/Bup.hs | 5 ++--- Utility/FileMode.hs | 4 +--- 6 files changed, 14 insertions(+), 28 deletions(-) diff --git a/Annex/Content/Direct.hs b/Annex/Content/Direct.hs index 35d2c9b8db..f897cca6ae 100644 --- a/Annex/Content/Direct.hs +++ b/Annex/Content/Direct.hs @@ -52,8 +52,7 @@ associatedFiles key = do associatedFilesRelative :: Key -> Annex [FilePath] associatedFilesRelative key = do mapping <- calcRepo $ gitAnnexMapping key - liftIO $ catchDefaultIO [] $ do - h <- openFile mapping ReadMode + liftIO $ catchDefaultIO [] $ withFile mapping ReadMode $ \h -> do fileEncoding h lines <$> hGetContents h diff --git a/Annex/Link.hs b/Annex/Link.hs index 30d8c2ae8c..234e4cb2a8 100644 --- a/Annex/Link.hs +++ b/Annex/Link.hs @@ -51,19 +51,15 @@ getAnnexLinkTarget file = ifM (coreSymlinks <$> Annex.getGitConfig) | otherwise -> return Nothing Nothing -> fallback - probefilecontent f = do - h <- openFile f ReadMode + probefilecontent f = withFile f ReadMode $ \h -> do fileEncoding h -- The first 8k is more than enough to read; link -- files are small. s <- take 8192 <$> hGetContents h -- If we got the full 8k, the file is too large if length s == 8192 - then do - hClose h - return "" - else do - hClose h + then return "" + else -- If there are any NUL or newline -- characters, or whitespace, we -- certianly don't have a link to a diff --git a/Command/Fsck.hs b/Command/Fsck.hs index f6e4fe2733..dfe1a9ab64 100644 --- a/Command/Fsck.hs +++ b/Command/Fsck.hs @@ -478,10 +478,9 @@ recordStartTime = do createAnnexDirectory $ parentDir f liftIO $ do nukeFile f - h <- openFile f WriteMode - t <- modificationTime <$> getFileStatus f - hPutStr h $ showTime $ realToFrac t - hClose h + withFile f WriteMode $ \h -> do + t <- modificationTime <$> getFileStatus f + hPutStr h $ showTime $ realToFrac t where showTime :: POSIXTime -> String showTime = show diff --git a/Logs/Transfer.hs b/Logs/Transfer.hs index fbfd0a4270..e998a56b14 100644 --- a/Logs/Transfer.hs +++ b/Logs/Transfer.hs @@ -340,11 +340,8 @@ parseTransferFile file bits = splitDirectories file writeTransferInfoFile :: TransferInfo -> FilePath -> IO () -writeTransferInfoFile info tfile = do - h <- openFile tfile WriteMode - fileEncoding h - hPutStr h $ writeTransferInfo info - hClose h +writeTransferInfoFile info tfile = writeFileAnyEncoding tfile $ + writeTransferInfo info {- File format is a header line containing the startedTime and any - bytesComplete value. Followed by a newline and the associatedFile. @@ -365,10 +362,8 @@ writeTransferInfo info = unlines ] readTransferInfoFile :: Maybe PID -> FilePath -> IO (Maybe TransferInfo) -readTransferInfoFile mpid tfile = catchDefaultIO Nothing $ do - h <- openFile tfile ReadMode - fileEncoding h - hClose h `after` (readTransferInfo mpid <$> hGetContentsStrict h) +readTransferInfoFile mpid tfile = catchDefaultIO Nothing $ + readTransferInfo mpid <$> readFileStrictAnyEncoding tfile readTransferInfo :: Maybe PID -> String -> Maybe TransferInfo readTransferInfo mpid s = TransferInfo diff --git a/Remote/Bup.hs b/Remote/Bup.hs index 370cbc1c02..7395b74288 100644 --- a/Remote/Bup.hs +++ b/Remote/Bup.hs @@ -145,9 +145,8 @@ storeEncrypted r buprepo (cipher, enck) k _p = retrieve :: BupRepo -> Key -> AssociatedFile -> FilePath -> MeterUpdate -> Annex Bool retrieve buprepo k _f d _p = do let params = bupParams "join" buprepo [Param $ bupRef k] - liftIO $ catchBoolIO $ do - tofile <- openFile d WriteMode - pipeBup params Nothing (Just tofile) + liftIO $ catchBoolIO $ withFIle d WriteMode $ + pipeBup params Nothing . Just retrieveCheap :: BupRepo -> Key -> FilePath -> Annex Bool retrieveCheap _ _ _ = return False diff --git a/Utility/FileMode.hs b/Utility/FileMode.hs index 46c6a31f5f..b17cadc3bc 100644 --- a/Utility/FileMode.hs +++ b/Utility/FileMode.hs @@ -133,10 +133,8 @@ setSticky f = modifyFileMode f $ addModes [stickyMode] - as writeFile. -} writeFileProtected :: FilePath -> String -> IO () -writeFileProtected file content = do - h <- openFile file WriteMode +writeFileProtected file content = withFile file WriteMode $ \h -> do void $ tryIO $ modifyFileMode file $ removeModes [groupReadMode, otherReadMode] hPutStr h content - hClose h