From e3f065ad54be58eeef7ac91aef391b2d9891bdd5 Mon Sep 17 00:00:00 2001 From: Michael Eischer Date: Mon, 11 May 2026 22:42:51 +0200 Subject: [PATCH 1/2] windows: ignore temporary access denied error on temp file creation --- internal/fs/file_windows.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/internal/fs/file_windows.go b/internal/fs/file_windows.go index 2aa050d2c..f756d4aea 100644 --- a/internal/fs/file_windows.go +++ b/internal/fs/file_windows.go @@ -76,6 +76,10 @@ func TempFile(dir, prefix string) (f *os.File, err error) { if os.IsExist(err) { continue } + // Access denied error can occur if the tmp files conflict with each other. + if isAccessDeniedError(err) { + continue + } return os.NewFile(uintptr(h), path), err } From a213daef299ca7b39fe89e501ef25fc30c1d8320 Mon Sep 17 00:00:00 2001 From: Michael Eischer Date: Mon, 11 May 2026 22:50:39 +0200 Subject: [PATCH 2/2] windows: improve randomness of temp file name Creating two temporary files at nearly the same time could result in a filename collision. --- internal/fs/file_windows.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/internal/fs/file_windows.go b/internal/fs/file_windows.go index f756d4aea..30cb75da5 100644 --- a/internal/fs/file_windows.go +++ b/internal/fs/file_windows.go @@ -6,7 +6,6 @@ import ( "path/filepath" "strconv" "strings" - "time" "github.com/restic/restic/internal/data" "golang.org/x/sys/windows" @@ -63,9 +62,8 @@ func TempFile(dir, prefix string) (f *os.File, err error) { share := uint32(0) // prevent other processes from accessing the file flags := uint32(windows.FILE_ATTRIBUTE_TEMPORARY | windows.FILE_FLAG_DELETE_ON_CLOSE) - rnd := rand.New(rand.NewSource(time.Now().UnixNano())) for i := 0; i < 10000; i++ { - randSuffix := strconv.Itoa(int(1e9 + rnd.Intn(1e9)%1e9))[1:] + randSuffix := strconv.Itoa(int(1e9 + rand.Intn(1e9)%1e9))[1:] path := filepath.Join(dir, prefix+randSuffix) ptr, err := windows.UTF16PtrFromString(path)