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
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.