package app import ( "fmt" "os" "path/filepath" ) func atomicWriteFile(path string, data []byte, perm os.FileMode) error { if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil { return fmt.Errorf("mkdir %s: %w", filepath.Dir(path), err) } tmpPath := path + ".tmp" f, err := os.OpenFile(tmpPath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, perm) if err != nil { return fmt.Errorf("open temp %s: %w", tmpPath, err) } success := false defer func() { _ = f.Close() if !success { _ = os.Remove(tmpPath) } }() if _, err := f.Write(data); err != nil { return fmt.Errorf("write temp %s: %w", tmpPath, err) } if err := f.Sync(); err != nil { return fmt.Errorf("sync temp %s: %w", tmpPath, err) } if err := f.Close(); err != nil { return fmt.Errorf("close temp %s: %w", tmpPath, err) } if err := os.Rename(tmpPath, path); err != nil { return fmt.Errorf("rename %s -> %s: %w", tmpPath, path, err) } if dir, err := os.Open(filepath.Dir(path)); err == nil { _ = dir.Sync() _ = dir.Close() } success = true return nil }