github.com/LanceLRQ/deer-common@v0.0.9-0.20210319081233-e8222ac018a8/sandbox/process/wait_waitid.go (about) 1 // Copyright 2016 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 // We used to used this code for Darwin, but according to issue #19314 6 // waitid returns if the process is stopped, even when using WEXITED. 7 8 // +build linux 9 10 package process 11 12 import ( 13 "os" 14 "runtime" 15 "syscall" 16 "unsafe" 17 ) 18 19 const _P_PID = 1 20 21 // blockUntilWaitable attempts to block until a call to p.Wait will 22 // succeed immediately, and reports whether it has done so. 23 // It does not actually call p.Wait. 24 func (p *Process) blockUntilWaitable() (bool, error) { 25 // The waitid system call expects a pointer to a siginfo_t, 26 // which is 128 bytes on all GNU/Linux systems. 27 // On darwin/amd64, it requires 104 bytes. 28 // We don't care about the values it returns. 29 var siginfo [16]uint64 30 psig := &siginfo[0] 31 var e syscall.Errno 32 for { 33 _, _, e = syscall.Syscall6(syscall.SYS_WAITID, _P_PID, uintptr(p.Pid), uintptr(unsafe.Pointer(psig)), syscall.WEXITED|syscall.WNOWAIT, 0, 0) 34 if e != syscall.EINTR { 35 break 36 } 37 } 38 runtime.KeepAlive(p) 39 if e != 0 { 40 // waitid has been available since Linux 2.6.9, but 41 // reportedly is not available in Ubuntu on Windows. 42 // See issue 16610. 43 if e == syscall.ENOSYS { 44 return false, nil 45 } 46 return false, os.NewSyscallError("waitid", e) 47 } 48 return true, nil 49 }