aboutsummaryrefslogtreecommitdiffstats
path: root/pkg
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2017-06-20 19:58:09 +0200
committerDmitry Vyukov <dvyukov@google.com>2017-06-20 19:59:47 +0200
commitfea266b33f5e4170b75d678d5e355f947aeb50cc (patch)
treef5e9a883ba45132da98bbbe92af75590206cc6c5 /pkg
parente39114dc0cfa7566dd2472e3e33a64586692d6cc (diff)
pkg/osutil: add FilesExist/CopyFiles/LinkFiles functions
Will be required by the new build system.
Diffstat (limited to 'pkg')
-rw-r--r--pkg/osutil/osutil.go70
1 files changed, 70 insertions, 0 deletions
diff --git a/pkg/osutil/osutil.go b/pkg/osutil/osutil.go
index b977ecebf..3d5a18a67 100644
--- a/pkg/osutil/osutil.go
+++ b/pkg/osutil/osutil.go
@@ -13,6 +13,13 @@ import (
"path/filepath"
"syscall"
"time"
+
+ "github.com/google/syzkaller/pkg/fileutil"
+)
+
+const (
+ DefaultDirPerm = 0755
+ DefaultFilePerm = 0644
)
// RunCmd runs "bin args..." in dir with timeout and returns its output.
@@ -94,3 +101,66 @@ func HandleInterrupts(shutdown chan struct{}) {
os.Exit(int(syscall.SIGINT))
}()
}
+
+// FilesExist returns true if all files exist in dir.
+// Files are assumed to be relative names in slash notation.
+func FilesExist(dir string, files []string) bool {
+ for _, f := range files {
+ if !IsExist(filepath.Join(dir, filepath.FromSlash(f))) {
+ return false
+ }
+ }
+ return true
+}
+
+// CopyFiles copies files from srcDir to dstDir as atomically as possible.
+// Files are assumed to be relative names in slash notation.
+// All other files in dstDir are removed.
+func CopyFiles(srcDir, dstDir string, files []string) error {
+ // Linux does not support atomic dir replace, so we copy to tmp dir first.
+ // Then remove dst dir and rename tmp to dst (as atomic as can get on Linux).
+ tmpDir := dstDir + ".tmp"
+ if err := os.RemoveAll(tmpDir); err != nil {
+ return err
+ }
+ if err := os.MkdirAll(tmpDir, DefaultDirPerm); err != nil {
+ return err
+ }
+ for _, f := range files {
+ src := filepath.Join(srcDir, filepath.FromSlash(f))
+ dst := filepath.Join(tmpDir, filepath.FromSlash(f))
+ if err := os.MkdirAll(filepath.Dir(dst), DefaultDirPerm); err != nil {
+ return err
+ }
+ if err := fileutil.CopyFile(src, dst); err != nil {
+ return err
+ }
+ }
+ if err := os.RemoveAll(dstDir); err != nil {
+ return err
+ }
+ return os.Rename(tmpDir, dstDir)
+}
+
+// LinkFiles creates hard links for files from dstDir to srcDir.
+// Files are assumed to be relative names in slash notation.
+// All other files in dstDir are removed.
+func LinkFiles(srcDir, dstDir string, files []string) error {
+ if err := os.RemoveAll(dstDir); err != nil {
+ return err
+ }
+ if err := os.MkdirAll(dstDir, DefaultDirPerm); err != nil {
+ return err
+ }
+ for _, f := range files {
+ src := filepath.Join(srcDir, filepath.FromSlash(f))
+ dst := filepath.Join(dstDir, filepath.FromSlash(f))
+ if err := os.MkdirAll(filepath.Dir(dst), DefaultDirPerm); err != nil {
+ return err
+ }
+ if err := os.Link(src, dst); err != nil {
+ return err
+ }
+ }
+ return nil
+}