From: Simon Ruderich Date: Sun, 4 Apr 2021 08:50:05 +0000 (+0200) Subject: sync: refactor temporary file creation into WriteTemp() X-Git-Url: https://ruderich.org/simon/gitweb/?p=safcm%2Fsafcm.git;a=commitdiff_plain;h=4914f4548a82ae6c4851680d0140d6b572d56e8e sync: refactor temporary file creation into WriteTemp() Make it public because it will be used by other packages in the near future. --- diff --git a/cmd/safcm-remote/sync/files.go b/cmd/safcm-remote/sync/files.go index 158b553..6e001a8 100644 --- a/cmd/safcm-remote/sync/files.go +++ b/cmd/safcm-remote/sync/files.go @@ -337,43 +337,11 @@ reopen: case 0: // regular file debugf("creating temporary file %q", filepath.Join(dir, base+"*")) - newFh, err := os.CreateTemp(dir, base) + tmpPath, err = WriteTemp(dir, base, file.Data, + file.Uid, file.Gid, file.Mode) if err != nil { return err } - tmpPath = newFh.Name() - - _, err = newFh.Write(file.Data) - if err != nil { - newFh.Close() - os.Remove(tmpPath) - return err - } - // CreateTemp() creates the file with 0600 - err = newFh.Chown(file.Uid, file.Gid) - if err != nil { - newFh.Close() - os.Remove(tmpPath) - return err - } - err = newFh.Chmod(file.Mode) - if err != nil { - newFh.Close() - os.Remove(tmpPath) - return err - } - err = newFh.Sync() - if err != nil { - newFh.Close() - os.Remove(tmpPath) - return err - } - err = newFh.Close() - if err != nil { - newFh.Close() - os.Remove(tmpPath) - return err - } case fs.ModeSymlink: i := 0 @@ -505,6 +473,50 @@ func OpenFileNoFollow(path string) (*os.File, error) { os.O_RDONLY|syscall.O_NOFOLLOW|syscall.O_NONBLOCK, 0) } +func WriteTemp(dir, base string, data []byte, uid, gid int, mode fs.FileMode) ( + string, error) { + + fh, err := os.CreateTemp(dir, base) + if err != nil { + return "", err + } + tmpPath := fh.Name() + + _, err = fh.Write(data) + if err != nil { + fh.Close() + os.Remove(tmpPath) + return "", err + } + // CreateTemp() creates the file with 0600 + err = fh.Chown(uid, gid) + if err != nil { + fh.Close() + os.Remove(tmpPath) + return "", err + } + err = fh.Chmod(mode) + if err != nil { + fh.Close() + os.Remove(tmpPath) + return "", err + } + err = fh.Sync() + if err != nil { + fh.Close() + os.Remove(tmpPath) + return "", err + } + err = fh.Close() + if err != nil { + fh.Close() + os.Remove(tmpPath) + return "", err + } + + return tmpPath, nil +} + // syncPath syncs path, which should be a directory. To guarantee durability // it must be called on a parent directory after adding, renaming or removing // files therein.