aboutsummaryrefslogtreecommitdiffstats
path: root/pkg
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2017-06-19 19:45:39 +0200
committerDmitry Vyukov <dvyukov@google.com>2017-06-20 19:53:13 +0200
commit5cc5b2714e61b1d64d463328308fbe231ab8387f (patch)
tree43a4ca51676bfbf4da71f1a319f5f6da49657b8b /pkg
parent99d2454c57e2b4761d667f265ec24122e40cd514 (diff)
pkg/fileutil: improve CopyFile
Make CopyFile atomic and preserve permissions.
Diffstat (limited to 'pkg')
-rw-r--r--pkg/fileutil/fileutil.go9
1 files changed, 5 insertions, 4 deletions
diff --git a/pkg/fileutil/fileutil.go b/pkg/fileutil/fileutil.go
index eae069e01..dbc9366de 100644
--- a/pkg/fileutil/fileutil.go
+++ b/pkg/fileutil/fileutil.go
@@ -14,7 +14,7 @@ import (
"unsafe"
)
-// CopyFile copies oldFile to newFile.
+// CopyFile atomically copies oldFile to newFile preserving permissions and modification time.
func CopyFile(oldFile, newFile string) error {
oldf, err := os.Open(oldFile)
if err != nil {
@@ -25,7 +25,8 @@ func CopyFile(oldFile, newFile string) error {
if err != nil {
return err
}
- newf, err := os.Create(newFile)
+ tmpFile := newFile + ".tmp"
+ newf, err := os.OpenFile(tmpFile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, stat.Mode()&os.ModePerm)
if err != nil {
return err
}
@@ -37,10 +38,10 @@ func CopyFile(oldFile, newFile string) error {
if err := newf.Close(); err != nil {
return err
}
- if err := os.Chtimes(newFile, stat.ModTime(), stat.ModTime()); err != nil {
+ if err := os.Chtimes(tmpFile, stat.ModTime(), stat.ModTime()); err != nil {
return err
}
- return nil
+ return os.Rename(tmpFile, newFile)
}
// WriteTempFile writes data to a temp file and returns its name.