Reticulum-Go/internal/storage/atomic.go
2026-07-13 08:56:23 -05:00

47 lines
1.1 KiB
Go

// SPDX-License-Identifier: Apache-2.0
// Copyright (c) 2024-2026 Quad4.io
package storage
import (
"fmt"
"os"
"path/filepath"
)
// AtomicWriteFile writes data to path using a temporary file and rename.
func AtomicWriteFile(path string, data []byte, perm os.FileMode) error {
dir := filepath.Dir(path)
if err := os.MkdirAll(dir, 0o700); err != nil {
return fmt.Errorf("create directory %q: %w", dir, err)
}
tmp, err := os.CreateTemp(dir, filepath.Base(path)+".tmp.*")
if err != nil {
return fmt.Errorf("create temp file: %w", err)
}
tmpName := tmp.Name()
cleanup := func() {
_ = tmp.Close()
_ = os.Remove(tmpName)
}
if _, err := tmp.Write(data); err != nil {
cleanup()
return fmt.Errorf("write temp file: %w", err)
}
if err := tmp.Chmod(perm); err != nil {
cleanup()
return fmt.Errorf("chmod temp file: %w", err)
}
if err := tmp.Close(); err != nil {
cleanup()
return fmt.Errorf("close temp file: %w", err)
}
if err := os.Rename(tmpName, path); err != nil {
_ = os.Remove(tmpName)
return fmt.Errorf("rename temp file: %w", err)
}
return nil
}