mirror of
https://github.com/ipfs/kubo.git
synced 2026-02-21 10:27:46 +08:00
Some checks failed
CodeQL / codeql (push) Has been cancelled
Docker Build / docker-build (push) Has been cancelled
Gateway Conformance / gateway-conformance (push) Has been cancelled
Gateway Conformance / gateway-conformance-libp2p-experiment (push) Has been cancelled
Go Build / go-build (push) Has been cancelled
Go Check / go-check (push) Has been cancelled
Go Lint / go-lint (push) Has been cancelled
Go Test / go-test (push) Has been cancelled
Interop / interop-prep (push) Has been cancelled
Sharness / sharness-test (push) Has been cancelled
Spell Check / spellcheck (push) Has been cancelled
Interop / helia-interop (push) Has been cancelled
Interop / ipfs-webui (push) Has been cancelled
https://github.com/ipfs/kubo/pull/10883 https://github.com/ipshipyard/config.ipfs-mainnet.org/issues/3 --------- Co-authored-by: gammazero <gammazero@users.noreply.github.com>
60 lines
1.1 KiB
Go
60 lines
1.1 KiB
Go
package atomicfile
|
|
|
|
import (
|
|
"io"
|
|
"os"
|
|
"path/filepath"
|
|
)
|
|
|
|
// File represents an atomic file writer
|
|
type File struct {
|
|
*os.File
|
|
path string
|
|
}
|
|
|
|
// New creates a new atomic file writer
|
|
func New(path string, mode os.FileMode) (*File, error) {
|
|
dir := filepath.Dir(path)
|
|
tempFile, err := os.CreateTemp(dir, ".tmp-"+filepath.Base(path))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if err := tempFile.Chmod(mode); err != nil {
|
|
tempFile.Close()
|
|
os.Remove(tempFile.Name())
|
|
return nil, err
|
|
}
|
|
|
|
return &File{
|
|
File: tempFile,
|
|
path: path,
|
|
}, nil
|
|
}
|
|
|
|
// Close atomically replaces the target file with the temporary file
|
|
func (f *File) Close() error {
|
|
if err := f.File.Close(); err != nil {
|
|
os.Remove(f.File.Name())
|
|
return err
|
|
}
|
|
|
|
if err := os.Rename(f.File.Name(), f.path); err != nil {
|
|
os.Remove(f.File.Name())
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Abort removes the temporary file without replacing the target
|
|
func (f *File) Abort() error {
|
|
f.File.Close()
|
|
return os.Remove(f.File.Name())
|
|
}
|
|
|
|
// ReadFrom reads from the given reader into the atomic file
|
|
func (f *File) ReadFrom(r io.Reader) (int64, error) {
|
|
return io.Copy(f.File, r)
|
|
}
|