author | Alberto Bertogli
<albertito@blitiri.com.ar> 2016-10-16 13:19:41 UTC |
committer | Alberto Bertogli
<albertito@blitiri.com.ar> 2016-10-21 21:18:53 UTC |
parent | ac7f32c2ced97915badb864bf7df69c539e5340e |
internal/safeio/safeio.go | +24 | -1 |
diff --git a/internal/safeio/safeio.go b/internal/safeio/safeio.go index e8cce16..8eba2a6 100644 --- a/internal/safeio/safeio.go +++ b/internal/safeio/safeio.go @@ -6,6 +6,7 @@ import ( "io/ioutil" "os" "path" + "syscall" ) // WriteFile writes data to a file named by filename, atomically. @@ -24,12 +25,20 @@ func WriteFile(filename string, data []byte, perm os.FileMode) error { return err } - if err = os.Chmod(tmpf.Name(), perm); err != nil { + if err = tmpf.Chmod(perm); err != nil { tmpf.Close() os.Remove(tmpf.Name()) return err } + if uid, gid := getOwner(filename); uid >= 0 { + if err = tmpf.Chown(uid, gid); err != nil { + tmpf.Close() + os.Remove(tmpf.Name()) + return err + } + } + if _, err = tmpf.Write(data); err != nil { tmpf.Close() os.Remove(tmpf.Name()) @@ -43,3 +52,17 @@ func WriteFile(filename string, data []byte, perm os.FileMode) error { return os.Rename(tmpf.Name(), filename) } + +func getOwner(fname string) (uid, gid int) { + uid = -1 + gid = -1 + stat, err := os.Stat(fname) + if err == nil { + if sysstat, ok := stat.Sys().(*syscall.Stat_t); ok { + uid = int(sysstat.Uid) + gid = int(sysstat.Gid) + } + } + + return +}