From 2181ef35e17d97286cfe7edad5d4d68c225922d9 Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Mon, 3 Jul 2017 14:43:37 +0200 Subject: pkg/osutil: don't depend on syscall in appengine build Dashboard app now depends on osutil through config package. Reshuffle functions so that the package does not depend on syscall in appengine build. --- pkg/osutil/fileutil.go | 51 ------------------------ pkg/osutil/fileutil_linux.go | 2 + pkg/osutil/osutil.go | 30 --------------- pkg/osutil/osutil_linux.go | 2 + pkg/osutil/osutil_unix.go | 92 ++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 96 insertions(+), 81 deletions(-) create mode 100644 pkg/osutil/osutil_unix.go (limited to 'pkg/osutil') diff --git a/pkg/osutil/fileutil.go b/pkg/osutil/fileutil.go index 801453326..5ef79e1b6 100644 --- a/pkg/osutil/fileutil.go +++ b/pkg/osutil/fileutil.go @@ -8,9 +8,6 @@ import ( "io" "io/ioutil" "os" - "path/filepath" - "strconv" - "syscall" ) // CopyFile atomically copies oldFile to newFile preserving permissions and modification time. @@ -57,51 +54,3 @@ func WriteTempFile(data []byte) (string, error) { f.Close() return f.Name(), nil } - -// ProcessTempDir creates a new temp dir in where and returns its path and an unique index. -// It also cleans up old, unused temp dirs after dead processes. -func ProcessTempDir(where string) (string, error) { - lk := filepath.Join(where, "instance-lock") - lkf, err := syscall.Open(lk, syscall.O_RDWR|syscall.O_CREAT, DefaultFilePerm) - if err != nil { - return "", err - } - defer syscall.Close(lkf) - if err := syscall.Flock(lkf, syscall.LOCK_EX); err != nil { - return "", err - } - defer syscall.Flock(lkf, syscall.LOCK_UN) - - for i := 0; i < 1e3; i++ { - path := filepath.Join(where, fmt.Sprintf("instance-%v", i)) - pidfile := filepath.Join(path, ".pid") - err := os.Mkdir(path, DefaultDirPerm) - if os.IsExist(err) { - // Try to clean up. - data, err := ioutil.ReadFile(pidfile) - if err == nil && len(data) > 0 { - pid, err := strconv.Atoi(string(data)) - if err == nil && pid > 1 { - if err := syscall.Kill(pid, 0); err == syscall.ESRCH { - if os.Remove(pidfile) == nil { - if os.RemoveAll(path) == nil { - i-- - continue - } - } - } - } - } - // If err != nil, assume that the pid file is not created yet. - continue - } - if err != nil { - return "", err - } - if err := WriteFile(pidfile, []byte(strconv.Itoa(syscall.Getpid()))); err != nil { - return "", err - } - return path, nil - } - return "", fmt.Errorf("too many live instances") -} diff --git a/pkg/osutil/fileutil_linux.go b/pkg/osutil/fileutil_linux.go index 415c00353..f1a0c1b66 100644 --- a/pkg/osutil/fileutil_linux.go +++ b/pkg/osutil/fileutil_linux.go @@ -1,6 +1,8 @@ // Copyright 2017 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. +// +build !appengine + package osutil import ( diff --git a/pkg/osutil/osutil.go b/pkg/osutil/osutil.go index 4a411c38e..99ab41780 100644 --- a/pkg/osutil/osutil.go +++ b/pkg/osutil/osutil.go @@ -6,13 +6,10 @@ package osutil import ( "bytes" "fmt" - "io" "io/ioutil" "os" "os/exec" - "os/signal" "path/filepath" - "syscall" "time" ) @@ -47,15 +44,6 @@ func RunCmd(timeout time.Duration, dir, bin string, args ...string) ([]byte, err return output.Bytes(), nil } -func LongPipe() (io.ReadCloser, io.WriteCloser, error) { - r, w, err := os.Pipe() - if err != nil { - return nil, nil, fmt.Errorf("failed to create pipe: %v", err) - } - prolongPipe(r, w) - return r, w, err -} - var wd string func init() { @@ -82,24 +70,6 @@ func IsExist(name string) bool { return err == nil } -// HandleInterrupts closes shutdown chan on first SIGINT -// (expecting that the program will gracefully shutdown and exit) -// and terminates the process on third SIGINT. -func HandleInterrupts(shutdown chan struct{}) { - go func() { - c := make(chan os.Signal, 3) - signal.Notify(c, syscall.SIGINT) - <-c - close(shutdown) - fmt.Fprint(os.Stderr, "SIGINT: shutting down...\n") - <-c - fmt.Fprint(os.Stderr, "SIGINT: shutting down harder...\n") - <-c - fmt.Fprint(os.Stderr, "SIGINT: terminating\n") - 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 { diff --git a/pkg/osutil/osutil_linux.go b/pkg/osutil/osutil_linux.go index 320f06fc3..b31905599 100644 --- a/pkg/osutil/osutil_linux.go +++ b/pkg/osutil/osutil_linux.go @@ -1,6 +1,8 @@ // Copyright 2017 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. +// +build !appengine + package osutil import ( diff --git a/pkg/osutil/osutil_unix.go b/pkg/osutil/osutil_unix.go new file mode 100644 index 000000000..01eabc15b --- /dev/null +++ b/pkg/osutil/osutil_unix.go @@ -0,0 +1,92 @@ +// Copyright 2017 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. + +// +build linux,!appengine darwin,!appengine + +package osutil + +import ( + "fmt" + "io" + "io/ioutil" + "os" + "os/signal" + "path/filepath" + "strconv" + "syscall" +) + +// ProcessTempDir creates a new temp dir in where and returns its path and an unique index. +// It also cleans up old, unused temp dirs after dead processes. +func ProcessTempDir(where string) (string, error) { + lk := filepath.Join(where, "instance-lock") + lkf, err := syscall.Open(lk, syscall.O_RDWR|syscall.O_CREAT, DefaultFilePerm) + if err != nil { + return "", err + } + defer syscall.Close(lkf) + if err := syscall.Flock(lkf, syscall.LOCK_EX); err != nil { + return "", err + } + defer syscall.Flock(lkf, syscall.LOCK_UN) + + for i := 0; i < 1e3; i++ { + path := filepath.Join(where, fmt.Sprintf("instance-%v", i)) + pidfile := filepath.Join(path, ".pid") + err := os.Mkdir(path, DefaultDirPerm) + if os.IsExist(err) { + // Try to clean up. + data, err := ioutil.ReadFile(pidfile) + if err == nil && len(data) > 0 { + pid, err := strconv.Atoi(string(data)) + if err == nil && pid > 1 { + if err := syscall.Kill(pid, 0); err == syscall.ESRCH { + if os.Remove(pidfile) == nil { + if os.RemoveAll(path) == nil { + i-- + continue + } + } + } + } + } + // If err != nil, assume that the pid file is not created yet. + continue + } + if err != nil { + return "", err + } + if err := WriteFile(pidfile, []byte(strconv.Itoa(syscall.Getpid()))); err != nil { + return "", err + } + return path, nil + } + return "", fmt.Errorf("too many live instances") +} + +// HandleInterrupts closes shutdown chan on first SIGINT +// (expecting that the program will gracefully shutdown and exit) +// and terminates the process on third SIGINT. +func HandleInterrupts(shutdown chan struct{}) { + go func() { + c := make(chan os.Signal, 3) + signal.Notify(c, syscall.SIGINT) + <-c + close(shutdown) + fmt.Fprint(os.Stderr, "SIGINT: shutting down...\n") + <-c + fmt.Fprint(os.Stderr, "SIGINT: shutting down harder...\n") + <-c + fmt.Fprint(os.Stderr, "SIGINT: terminating\n") + os.Exit(int(syscall.SIGINT)) + }() +} + +func LongPipe() (io.ReadCloser, io.WriteCloser, error) { + r, w, err := os.Pipe() + if err != nil { + return nil, nil, fmt.Errorf("failed to create pipe: %v", err) + } + prolongPipe(r, w) + return r, w, err +} -- cgit mrf-deployment