Skip to content

Commit 59db8d7

Browse files
EdSchoutentklauser
authored andcommitted
unix: add bindings for kinfo_proc on Darwin
On Linux, we can extract a list of all the processes on the system by calling readdir() against /proc. On BSD-like systems, this information needs to be extracted from sysctl in the form of kinfo_proc structures. This change adds bindings for this structure and adds a method for reading an array of these structures from sysctl. Change-Id: Iaaed27cdbbf13d7c2cc6a6787667ac04d65bf41c GitHub-Last-Rev: 34926f8 GitHub-Pull-Request: #111 Reviewed-on: https://go-review.googlesource.com/c/sys/+/328169 Run-TryBot: Tobias Klauser <tobias.klauser@gmail.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Tobias Klauser <tobias.klauser@gmail.com> Reviewed-by: Ian Lance Taylor <iant@golang.org>
1 parent e2b7044 commit 59db8d7

File tree

5 files changed

+275
-0
lines changed

5 files changed

+275
-0
lines changed

unix/mkpost.go

+15
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,21 @@ func main() {
5050
b = sttimespec.ReplaceAll(b, []byte("Timespec"))
5151
}
5252

53+
if goos == "darwin" {
54+
// KinfoProc contains various pointers to objects stored
55+
// in kernel space. Replace these by uintptr to prevent
56+
// accidental dereferencing.
57+
kinfoProcPointerRegex := regexp.MustCompile(`\*_Ctype_struct_(pgrp|proc|session|sigacts|ucred|user|vnode)`)
58+
b = kinfoProcPointerRegex.ReplaceAll(b, []byte("uintptr"))
59+
60+
// ExternProc contains a p_un member that in kernel
61+
// space stores a pair of pointers and in user space
62+
// stores the process creation time. We only care about
63+
// the process creation time.
64+
externProcStarttimeRegex := regexp.MustCompile(`P_un\s*\[\d+\]byte`)
65+
b = externProcStarttimeRegex.ReplaceAll(b, []byte("P_starttime Timeval"))
66+
}
67+
5368
// Intentionally export __val fields in Fsid and Sigset_t
5469
valRegex := regexp.MustCompile(`type (Fsid|Sigset_t) struct {(\s+)X__(bits|val)(\s+\S+\s+)}`)
5570
b = valRegex.ReplaceAll(b, []byte("type $1 struct {${2}Val$4}"))

unix/syscall_darwin.go

+33
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
package unix
1414

1515
import (
16+
"fmt"
1617
"runtime"
1718
"syscall"
1819
"unsafe"
@@ -398,6 +399,38 @@ func GetsockoptXucred(fd, level, opt int) (*Xucred, error) {
398399
return x, err
399400
}
400401

402+
func SysctlKinfoProcSlice(name string) ([]KinfoProc, error) {
403+
mib, err := sysctlmib(name)
404+
if err != nil {
405+
return nil, err
406+
}
407+
408+
// Find size.
409+
n := uintptr(0)
410+
if err := sysctl(mib, nil, &n, nil, 0); err != nil {
411+
return nil, err
412+
}
413+
if n == 0 {
414+
return nil, nil
415+
}
416+
if n%SizeofKinfoProc != 0 {
417+
return nil, fmt.Errorf("sysctl() returned a size of %d, which is not a multiple of %d", n, SizeofKinfoProc)
418+
}
419+
420+
// Read into buffer of that size.
421+
buf := make([]KinfoProc, n/SizeofKinfoProc)
422+
if err := sysctl(mib, (*byte)(unsafe.Pointer(&buf[0])), &n, nil, 0); err != nil {
423+
return nil, err
424+
}
425+
if n%SizeofKinfoProc != 0 {
426+
return nil, fmt.Errorf("sysctl() returned a size of %d, which is not a multiple of %d", n, SizeofKinfoProc)
427+
}
428+
429+
// The actual call may return less than the original reported required
430+
// size so ensure we deal with that.
431+
return buf[:n/SizeofKinfoProc], nil
432+
}
433+
401434
//sys sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error)
402435

403436
/*

unix/types_darwin.go

+19
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ package unix
3737
#include <sys/signal.h>
3838
#include <sys/socket.h>
3939
#include <sys/stat.h>
40+
#include <sys/sysctl.h>
4041
#include <sys/time.h>
4142
#include <sys/types.h>
4243
#include <sys/ucred.h>
@@ -304,3 +305,21 @@ type Clockinfo C.struct_clockinfo
304305
// ctl_info
305306

306307
type CtlInfo C.struct_ctl_info
308+
309+
// KinfoProc
310+
311+
const SizeofKinfoProc = C.sizeof_struct_kinfo_proc
312+
313+
type Eproc C.struct_eproc
314+
315+
type ExternProc C.struct_extern_proc
316+
317+
type Itimerval C.struct_itimerval
318+
319+
type KinfoProc C.struct_kinfo_proc
320+
321+
type Vmspace C.struct_vmspace
322+
323+
type Pcred C.struct__pcred
324+
325+
type Ucred C.struct__ucred

unix/ztypes_darwin_amd64.go

+104
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

unix/ztypes_darwin_arm64.go

+104
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)