mirror of
https://github.com/golang/go.git
synced 2025-05-07 16:43:03 +00:00
Use Process.handle field to store pidfd, and make use of it. Only use pidfd functionality if all the needed syscalls are available. 1. Add/use pidfdWorks, which checks that all needed pidfd-related functionality works. 2. os.StartProcess: obtain the pidfd from the kernel, if possible, using the functionality added by CL 520266. Note we could not modify syscall.StartProcess to return pidfd directly because it is a public API and its callers do not expect it, so we have to use ensurePidfd and getPidfd. 3. (*Process).Kill: use pidfdSendSignal, if available and the pidfd is known. Otherwise, fall back to the old implementation. 4. (*Process).Wait: use pidfdWait, if available, otherwise fall back to using waitid/wait4. This is more complicated than expected due to struct siginfo_t idiosyncrasy. NOTE pidfdSendSignal and pidfdWait are used without a race workaround (blockUntilWaitable and sigMu, added by CL 23967) because with pidfd, PID recycle issue doesn't exist (IOW, pidfd, unlike PID, is guaranteed to refer to one particular process) and thus the race doesn't exist either. Rework of CL 528438 (reverted in CL 566477 because of #65857). For #62654. Updates #13987. Change-Id: If5ef8920bd8619dc428b6282ffe4fb8c258ca224 Reviewed-on: https://go-review.googlesource.com/c/go/+/570036 TryBot-Result: Gopher Robot <gobot@golang.org> Run-TryBot: Kirill Kolyshkin <kolyshkin@gmail.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Cherry Mui <cherryyz@google.com> Reviewed-by: Cherry Mui <cherryyz@google.com> Reviewed-by: Michael Pratt <mpratt@google.com>
24 lines
591 B
Go
24 lines
591 B
Go
// Copyright 2023 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.
|
|
|
|
package unix
|
|
|
|
import "syscall"
|
|
|
|
func PidFDSendSignal(pidfd uintptr, s syscall.Signal) error {
|
|
_, _, errno := syscall.Syscall(pidfdSendSignalTrap, pidfd, uintptr(s), 0)
|
|
if errno != 0 {
|
|
return errno
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func PidFDOpen(pid, flags int) (uintptr, error) {
|
|
pidfd, _, errno := syscall.Syscall(pidfdOpenTrap, uintptr(pid), uintptr(flags), 0)
|
|
if errno != 0 {
|
|
return ^uintptr(0), errno
|
|
}
|
|
return uintptr(pidfd), nil
|
|
}
|