Skip to content

Commit

Permalink
Fix bug in scratch file updates
Browse files Browse the repository at this point in the history
The system temp directory could be a different device (like a tmpfs),
which would cause renameFile to fail since we are attempting to rename
across device boundaries. To avoid this issue, create the temp file in
the same directory as the unison scratch file that we will update.
  • Loading branch information
tstat committed Nov 21, 2023
1 parent dce20da commit 599bd6e
Showing 1 changed file with 9 additions and 6 deletions.
15 changes: 9 additions & 6 deletions unison-cli/src/Unison/CommandLine/OutputMessages.hs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

module Unison.CommandLine.OutputMessages where

import Control.Exception (mask, onException)
import Control.Exception (catch, finally, mask, throwIO)
import Control.Lens hiding (at)
import Control.Monad.State
import Control.Monad.State.Strict qualified as State
Expand All @@ -31,8 +31,10 @@ import Network.HTTP.Types qualified as Http
import Servant.Client qualified as Servant
import System.Console.ANSI qualified as ANSI
import System.Console.Haskeline.Completion qualified as Completion
import System.Directory (canonicalizePath, doesFileExist, getHomeDirectory, getTemporaryDirectory, removeFile, renameFile)
import System.Directory (canonicalizePath, doesFileExist, getHomeDirectory, removeFile, renameFile)
import System.FilePath qualified as FilePath
import System.IO qualified as IO
import System.IO.Error (isDoesNotExistError)
import U.Codebase.Branch (NamespaceStats (..))
import U.Codebase.Branch.Diff (NameChanges (..))
import U.Codebase.HashTags (CausalHash (..))
Expand Down Expand Up @@ -2721,12 +2723,13 @@ displayDefinitionsString maybePath definitions =
copyLoop
IO.hClose tmpHandle
renameFile tmpFilePath path
tmpDir <- getTemporaryDirectory
mask \unmask -> do
(tmpFilePath, tmpHandle) <- IO.openTempFile tmpDir "unison-scratch"
unmask (withTempFile tmpFilePath tmpHandle) `onException` do
(tmpFilePath, tmpHandle) <- IO.openTempFile (FilePath.takeDirectory path) "unison-scratch"
unmask (withTempFile tmpFilePath tmpHandle) `finally` do
IO.hClose tmpHandle
removeFile tmpFilePath
removeFile tmpFilePath `catch` \case
e | isDoesNotExistError e -> pure ()
e -> throwIO e
pure mempty

displayTestResults ::
Expand Down

0 comments on commit 599bd6e

Please sign in to comment.