unix: retry fetching of lists through sysctl if the size changes

On macOS, the SysctlKinfoProcSlice() function may be used to fetch the contents of the process table. As the process table may grow between the first and second call to sysctl(), the second call may fail with ENOMEM. In that case we simply need to retry.

Change-Id: I40229653ed383603c33762f37b0dc2e7de47bcb6
GitHub-Last-Rev: b63b6b847122e058977934c5af7841f47485177d
GitHub-Pull-Request: golang/sys#169
Reviewed-on: https://go-review.googlesource.com/c/sys/+/513036
Run-TryBot: Ian Lance Taylor <iant@google.com>
Auto-Submit: Ian Lance Taylor <iant@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Ian Lance Taylor <iant@google.com>
This commit is contained in:
Ed Schouten
2023-07-26 11:12:51 +00:00
committed by Gopher Robot
parent ad7130c58d
commit 70f4e408de
+6
View File
@@ -510,6 +510,7 @@ func SysctlKinfoProcSlice(name string, args ...int) ([]KinfoProc, error) {
return nil, err return nil, err
} }
for {
// Find size. // Find size.
n := uintptr(0) n := uintptr(0)
if err := sysctl(mib, nil, &n, nil, 0); err != nil { if err := sysctl(mib, nil, &n, nil, 0); err != nil {
@@ -525,6 +526,10 @@ func SysctlKinfoProcSlice(name string, args ...int) ([]KinfoProc, error) {
// Read into buffer of that size. // Read into buffer of that size.
buf := make([]KinfoProc, n/SizeofKinfoProc) buf := make([]KinfoProc, n/SizeofKinfoProc)
if err := sysctl(mib, (*byte)(unsafe.Pointer(&buf[0])), &n, nil, 0); err != nil { if err := sysctl(mib, (*byte)(unsafe.Pointer(&buf[0])), &n, nil, 0); err != nil {
if err == ENOMEM {
// Process table grew. Try again.
continue
}
return nil, err return nil, err
} }
if n%SizeofKinfoProc != 0 { if n%SizeofKinfoProc != 0 {
@@ -535,6 +540,7 @@ func SysctlKinfoProcSlice(name string, args ...int) ([]KinfoProc, error) {
// size so ensure we deal with that. // size so ensure we deal with that.
return buf[:n/SizeofKinfoProc], nil return buf[:n/SizeofKinfoProc], nil
} }
}
//sys sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error) //sys sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error)