From 5cc5b2714e61b1d64d463328308fbe231ab8387f Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Mon, 19 Jun 2017 19:45:39 +0200 Subject: pkg/fileutil: improve CopyFile Make CopyFile atomic and preserve permissions. --- pkg/fileutil/fileutil.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'pkg') 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. -- cgit mrf-deployment