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