mirror of
https://github.com/golang/go
synced 2024-11-06 08:26:12 -07:00
e69912e6f4
The os package sets a finalizer on *Process. I looked through all the uses of *Process in the package, looking for each case where a *Process was passed as an argument and the final reference to the argument was not a function or method call. I added a call to runtime.KeepAlive after each such final reference (there were only three). The code is safe today without the KeepAlive calls because the compiler keeps arguments alive for the duration of the function. However, that is not a language requirement, so adding the KeepAlive calls ensures that this code remains safe even if the compiler changes in the future. I also removed an existing unnecessry call to runtime.KeepAlive. The syscall.Syscall function is handled specially by the compiler to keep its arguments alive. Change-Id: Ibd2ff20b31ed3de4f6a59dd1633c1b44001d91d9 Reviewed-on: https://go-review.googlesource.com/27637 Run-TryBot: Ian Lance Taylor <iant@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
41 lines
1.2 KiB
Go
41 lines
1.2 KiB
Go
// Copyright 2016 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
// +build darwin linux
|
|
|
|
package os
|
|
|
|
import (
|
|
"runtime"
|
|
"syscall"
|
|
"unsafe"
|
|
)
|
|
|
|
const _P_PID = 1
|
|
|
|
// blockUntilWaitable attempts to block until a call to p.Wait will
|
|
// succeed immediately, and returns whether it has done so.
|
|
// It does not actually call p.Wait.
|
|
func (p *Process) blockUntilWaitable() (bool, error) {
|
|
// The waitid system call expects a pointer to a siginfo_t,
|
|
// which is 128 bytes on all GNU/Linux systems.
|
|
// On Darwin, it requires greater than or equal to 64 bytes
|
|
// for darwin/{386,arm} and 104 bytes for darwin/amd64.
|
|
// We don't care about the values it returns.
|
|
var siginfo [128]byte
|
|
psig := &siginfo[0]
|
|
_, _, e := syscall.Syscall6(syscall.SYS_WAITID, _P_PID, uintptr(p.Pid), uintptr(unsafe.Pointer(psig)), syscall.WEXITED|syscall.WNOWAIT, 0, 0)
|
|
runtime.KeepAlive(p)
|
|
if e != 0 {
|
|
// waitid has been available since Linux 2.6.9, but
|
|
// reportedly is not available in Ubuntu on Windows.
|
|
// See issue 16610.
|
|
if e == syscall.ENOSYS {
|
|
return false, nil
|
|
}
|
|
return false, NewSyscallError("waitid", e)
|
|
}
|
|
return true, nil
|
|
}
|