return m.cview.Context(m.tree, end)
}
-// writeFileAtomic replaces the file at path with data. A reader or a crash sees
-// the old file or the new file, never a part of one.
+// writeFileAtomic replaces the file at path with data through a temporary file
+// and a rename. A reader or a crash of the process sees the old file or the new
+// file, never a part of one.
func writeFileAtomic(path string, data []byte) error {
- dir := filepath.Dir(path)
- file, err := os.CreateTemp(dir, "."+filepath.Base(path)+".*")
+ file, err := os.CreateTemp(filepath.Dir(path), "."+filepath.Base(path)+".*")
if err != nil {
return fmt.Errorf("create temporary file: %w", err)
}
_, err = file.Write(data)
- if err == nil {
- err = file.Sync()
- }
-
err = errors.Join(err, file.Close())
if err == nil {
err = os.Rename(file.Name(), path)
return errors.Join(fmt.Errorf("replace file: %w", err), os.Remove(file.Name()))
}
- return syncDir(dir)
-}
-
-// syncDir flushes the entries of dir to the disk.
-func syncDir(dir string) (err error) {
- handle, err := os.Open(dir)
- if err != nil {
- return fmt.Errorf("open directory: %w", err)
- }
-
- defer func() {
- err = errors.Join(err, handle.Close())
- }()
-
- err = handle.Sync()
- if err != nil {
- return fmt.Errorf("flush directory: %w", err)
- }
-
return nil
}