diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2017-10-16 12:18:50 +0200 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2017-10-16 14:21:54 +0200 |
| commit | 85b1f93f8dbbc767c564e494a6353aa3517d5d49 (patch) | |
| tree | 702d2318a2ddcf1a576294a6a4981c58abcfcf61 /pkg/osutil/osutil_unix.go | |
| parent | f78642861b4dbe396a67d5e2a750e22f83f3edd5 (diff) | |
executor, pkg/ipc: unify ipc protocol between linux and other OSes
We currently use more complex and functional protocol on linux,
and a simple ad-hoc protocol on other OSes.
This leads to code duplication in both ipc and executor.
Linux supports coverage, shared memory communication and fork server,
which would also be useful for most other OSes.
Unify communication protocol and parametrize it by
(1) use of shmem or only pipes, (2) use of fork server.
This reduces duplication in ipc and executor and will
allow to support the useful features for other OSes easily.
Finally, this fixes akaros support as it currently uses
syz-stress running on host (linux) and executor running on akaros.
Diffstat (limited to 'pkg/osutil/osutil_unix.go')
| -rw-r--r-- | pkg/osutil/osutil_unix.go | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/pkg/osutil/osutil_unix.go b/pkg/osutil/osutil_unix.go index 87dc6a729..2f6a9f327 100644 --- a/pkg/osutil/osutil_unix.go +++ b/pkg/osutil/osutil_unix.go @@ -90,3 +90,68 @@ func LongPipe() (io.ReadCloser, io.WriteCloser, error) { prolongPipe(r, w) return r, w, err } + +// CreateMemMappedFile creates a temp file with the requested size and maps it into memory. +func CreateMemMappedFile(size int) (f *os.File, mem []byte, err error) { + f, err = ioutil.TempFile("./", "syzkaller-shm") + if err != nil { + err = fmt.Errorf("failed to create temp file: %v", err) + return + } + if err = f.Truncate(int64(size)); err != nil { + err = fmt.Errorf("failed to truncate shm file: %v", err) + f.Close() + os.Remove(f.Name()) + return + } + f.Close() + fname := f.Name() + f, err = os.OpenFile(f.Name(), os.O_RDWR, DefaultFilePerm) + if err != nil { + err = fmt.Errorf("failed to open shm file: %v", err) + os.Remove(fname) + return + } + mem, err = syscall.Mmap(int(f.Fd()), 0, size, syscall.PROT_READ|syscall.PROT_WRITE, syscall.MAP_SHARED) + if err != nil { + err = fmt.Errorf("failed to mmap shm file: %v", err) + f.Close() + os.Remove(f.Name()) + return + } + return +} + +// CloseMemMappedFile destroys memory mapping created by CreateMemMappedFile. +func CloseMemMappedFile(f *os.File, mem []byte) error { + err1 := syscall.Munmap(mem) + err2 := f.Close() + err3 := os.Remove(f.Name()) + switch { + case err1 != nil: + return err1 + case err2 != nil: + return err2 + case err3 != nil: + return err3 + default: + return nil + } +} + +// ProcessExitStatus returns process exit status. +// This is here only because of fuchsia that does not implement WaitStatus. +func ProcessExitStatus(ps *os.ProcessState) int { + return ps.Sys().(syscall.WaitStatus).ExitStatus() +} + +// ProcessSignal sends signal sig to the process, returns true if the process was killed. +// Again, this is here only because of fuchsia. +func ProcessSignal(p *os.Process, sig int) bool { + SIGKILL := int(syscall.SIGKILL) + if sig <= 0 || sig >= 32 { + sig = SIGKILL + } + p.Signal(syscall.Signal(sig)) + return sig == SIGKILL +} |
