ioutils.go 771 B

12345678910111213141516171819202122232425262728293031323334353637383940
  1. package ioutils
  2. import (
  3. "io"
  4. "io/ioutil"
  5. "os"
  6. "path/filepath"
  7. )
  8. // todo: split docker/pkg/ioutils into a separate repo
  9. // AtomicWriteFile atomically writes data to a file specified by filename.
  10. func AtomicWriteFile(filename string, data []byte, perm os.FileMode) error {
  11. f, err := ioutil.TempFile(filepath.Dir(filename), ".tmp-"+filepath.Base(filename))
  12. if err != nil {
  13. return err
  14. }
  15. err = os.Chmod(f.Name(), perm)
  16. if err != nil {
  17. f.Close()
  18. return err
  19. }
  20. n, err := f.Write(data)
  21. if err == nil && n < len(data) {
  22. f.Close()
  23. return io.ErrShortWrite
  24. }
  25. if err != nil {
  26. f.Close()
  27. return err
  28. }
  29. if err := f.Sync(); err != nil {
  30. f.Close()
  31. return err
  32. }
  33. if err := f.Close(); err != nil {
  34. return err
  35. }
  36. return os.Rename(f.Name(), filename)
  37. }