mirror of
https://blitiri.com.ar/repos/chasquid
synced 2025-12-23 15:37:01 +00:00
Add a new internal/safeio package for safer I/O functions
This patch adds a new internal/safeio package, which is meant to implement safer version of some I/O related functions. For now, only an atomic version of ioutil.WriteFile is implemented. More may be added later if there's a need for them.
This commit is contained in:
43
internal/safeio/safeio.go
Normal file
43
internal/safeio/safeio.go
Normal file
@@ -0,0 +1,43 @@
|
||||
// Package safeio implements convenient I/O routines that provide additional
|
||||
// levels of safety in the presence of unexpected failures.
|
||||
package safeio
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
)
|
||||
|
||||
// WriteFile writes data to a file named by filename, atomically.
|
||||
// It's a wrapper to ioutil.WriteFile, but provides atomicity (and increased
|
||||
// safety) by writing to a temporary file and renaming it at the end.
|
||||
//
|
||||
// Note this relies on same-directory Rename being atomic, which holds in most
|
||||
// reasonably modern filesystems.
|
||||
func WriteFile(filename string, data []byte, perm os.FileMode) error {
|
||||
// Note we create the temporary file in the same directory, otherwise we
|
||||
// would have no expectation of Rename being atomic.
|
||||
tmpf, err := ioutil.TempFile(path.Dir(filename), path.Base(filename))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = os.Chmod(tmpf.Name(), perm); err != nil {
|
||||
tmpf.Close()
|
||||
os.Remove(tmpf.Name())
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err = tmpf.Write(data); err != nil {
|
||||
tmpf.Close()
|
||||
os.Remove(tmpf.Name())
|
||||
return err
|
||||
}
|
||||
|
||||
if err = tmpf.Close(); err != nil {
|
||||
os.Remove(tmpf.Name())
|
||||
return err
|
||||
}
|
||||
|
||||
return os.Rename(tmpf.Name(), filename)
|
||||
}
|
||||
Reference in New Issue
Block a user