mirror of
https://github.com/tailscale/tailscale.git
synced 2025-02-20 11:58:39 +00:00

I moved the actual rename into separate, GOOS-specific files. On non-Windows, we do a simple os.Rename. On Windows, we first try ReplaceFile with a fallback to os.Rename if the target file does not exist. ReplaceFile is the recommended way to rename the file in this use case, as it preserves attributes and ACLs set on the target file. Updates #14428 Signed-off-by: Aaron Klotz <aaron@tailscale.com>
34 lines
782 B
Go
34 lines
782 B
Go
// Copyright (c) Tailscale Inc & AUTHORS
|
|
// SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
package atomicfile
|
|
|
|
import (
|
|
"os"
|
|
|
|
"golang.org/x/sys/windows"
|
|
)
|
|
|
|
func rename(srcFile, destFile string) error {
|
|
// Use replaceFile when possible to preserve the original file's attributes and ACLs.
|
|
if err := replaceFile(destFile, srcFile); err == nil || err != windows.ERROR_FILE_NOT_FOUND {
|
|
return err
|
|
}
|
|
// destFile doesn't exist. Just do a normal rename.
|
|
return os.Rename(srcFile, destFile)
|
|
}
|
|
|
|
func replaceFile(destFile, srcFile string) error {
|
|
destFile16, err := windows.UTF16PtrFromString(destFile)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
srcFile16, err := windows.UTF16PtrFromString(srcFile)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return replaceFileW(destFile16, srcFile16, nil, 0, nil, nil)
|
|
}
|