mirror of
https://github.com/charmbracelet/crush.git
synced 2026-05-30 18:47:33 +00:00
39 lines
842 B
Go
39 lines
842 B
Go
package config
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
)
|
|
|
|
// atomicWriteFile writes data to a file atomically by writing to a unique
|
|
// temporary file in the same directory and renaming it into place. This
|
|
// prevents concurrent readers from observing a partially-written file.
|
|
func atomicWriteFile(path string, data []byte, perm os.FileMode) error {
|
|
path = filepath.Clean(path)
|
|
dir := filepath.Dir(path)
|
|
f, err := os.CreateTemp(dir, filepath.Base(path)+".*.tmp")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
tmp := f.Name()
|
|
if _, err := f.Write(data); err != nil {
|
|
f.Close()
|
|
os.Remove(tmp)
|
|
return err
|
|
}
|
|
if err := f.Chmod(perm); err != nil {
|
|
f.Close()
|
|
os.Remove(tmp)
|
|
return err
|
|
}
|
|
if err := f.Close(); err != nil {
|
|
os.Remove(tmp)
|
|
return err
|
|
}
|
|
if err := os.Rename(tmp, path); err != nil {
|
|
os.Remove(tmp)
|
|
return err
|
|
}
|
|
return nil
|
|
}
|