// Copyright 2015 syzkaller project authors. All rights reserved. // Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. package osutil import ( "fmt" "io" "io/ioutil" "os" ) // 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 { return err } defer oldf.Close() stat, err := oldf.Stat() if err != nil { return err } 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 } defer newf.Close() _, err = io.Copy(newf, oldf) if err != nil { return err } if err := newf.Close(); err != nil { return err } if err := os.Chtimes(tmpFile, stat.ModTime(), stat.ModTime()); err != nil { return err } return os.Rename(tmpFile, newFile) } // WriteTempFile writes data to a temp file and returns its name. func WriteTempFile(data []byte) (string, error) { // Note: pkg/report knows about "syzkaller" prefix as it appears in crashes as process name. f, err := ioutil.TempFile("", "syzkaller") if err != nil { return "", fmt.Errorf("failed to create a temp file: %v", err) } if _, err := f.Write(data); err != nil { f.Close() os.Remove(f.Name()) return "", fmt.Errorf("failed to write a temp file: %v", err) } f.Close() return f.Name(), nil }