github.com/LanceLRQ/deer-common@v0.0.9-0.20210319081233-e8222ac018a8/sandbox/process/exec_unix.go (about) 1 // Copyright 2009 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // +build aix darwin dragonfly freebsd js,wasm linux netbsd openbsd solaris 6 7 package process 8 9 import ( 10 "errors" 11 "os" 12 "runtime" 13 "syscall" 14 "time" 15 ) 16 17 func (p *Process) wait() (ps *ProcessState, err error) { 18 if p.Pid == -1 { 19 return nil, syscall.EINVAL 20 } 21 22 // If we can block until Wait4 will succeed immediately, do so. 23 ready, err := p.blockUntilWaitable() 24 if err != nil { 25 return nil, err 26 } 27 if ready { 28 // Mark the process done now, before the call to Wait4, 29 // so that Process.signal will not send a signal. 30 p.setDone() 31 // Acquire a write lock on sigMu to wait for any 32 // active call to the signal method to complete. 33 p.sigMu.Lock() 34 p.sigMu.Unlock() 35 } 36 37 var ( 38 status syscall.WaitStatus 39 rusage syscall.Rusage 40 pid1 int 41 e error 42 ) 43 for { 44 pid1, e = syscall.Wait4(p.Pid, &status, 0, &rusage) 45 if e != syscall.EINTR { 46 break 47 } 48 } 49 if e != nil { 50 return nil, os.NewSyscallError("wait", e) 51 } 52 if pid1 != 0 { 53 p.setDone() 54 } 55 ps = &ProcessState{ 56 pid: pid1, 57 status: status, 58 rusage: &rusage, 59 } 60 return ps, nil 61 } 62 63 func (p *Process) signal(sig Signal) error { 64 if p.Pid == -1 { 65 return errors.New("os: process already released") 66 } 67 if p.Pid == 0 { 68 return errors.New("os: process not initialized") 69 } 70 p.sigMu.RLock() 71 defer p.sigMu.RUnlock() 72 if p.done() { 73 return ErrProcessDone 74 } 75 s, ok := sig.(syscall.Signal) 76 if !ok { 77 return errors.New("os: unsupported signal type") 78 } 79 if e := syscall.Kill(p.Pid, s); e != nil { 80 if e == syscall.ESRCH { 81 return ErrProcessDone 82 } 83 return e 84 } 85 return nil 86 } 87 88 func (p *Process) release() error { 89 // NOOP for unix. 90 p.Pid = -1 91 // no need for a finalizer anymore 92 runtime.SetFinalizer(p, nil) 93 return nil 94 } 95 96 func findProcess(pid int) (p *Process, err error) { 97 // NOOP for unix. 98 return newProcess(pid, 0), nil 99 } 100 101 func (p *ProcessState) userTime() time.Duration { 102 return time.Duration(p.rusage.Utime.Nano()) * time.Nanosecond 103 } 104 105 func (p *ProcessState) systemTime() time.Duration { 106 return time.Duration(p.rusage.Stime.Nano()) * time.Nanosecond 107 }