Something went wrong. Try again.
forked from tailscale/tailscale
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657// Copyright (c) Tailscale Inc & contributors// SPDX-License-Identifier: BSD-3-Clause
// Package atomicfile contains code related to writing to filesystems// atomically.//// This package should be considered internal; its API is not stable.package atomicfile // import "tailscale.com/atomicfile"
import ( "fmt" "os" "path/filepath" "runtime")
// WriteFile writes data to filename+some suffix, then renames it into filename.// The perm argument is ignored on Windows, but if the target filename already// exists then the target file's attributes and ACLs are preserved. If the target// filename already exists but is not a regular file, WriteFile returns an error.func WriteFile(filename string, data []byte, perm os.FileMode) (err error) { fi, err := os.Stat(filename) if err == nil && !fi.Mode().IsRegular() { return fmt.Errorf("%s already exists and is not a regular file", filename) } f, err := os.CreateTemp(filepath.Dir(filename), filepath.Base(filename)+".tmp") if err != nil { return err } tmpName := f.Name() defer func() { if err != nil { f.Close() os.Remove(tmpName) } }() if _, err := f.Write(data); err != nil { return err } if runtime.GOOS != "windows" { if err := f.Chmod(perm); err != nil { return err } } if err := f.Sync(); err != nil { return err } if err := f.Close(); err != nil { return err } return Rename(tmpName, filename)}
// Rename srcFile to dstFile, similar to [os.Rename] but preserving file// attributes and ACLs on Windows.func Rename(srcFile, dstFile string) error { return rename(srcFile, dstFile) }