unix: add IoctlCtlInfo on darwin

For golang/go#41868

Change-Id: I0f4dbeacfe10b9614caf05633a1de3a98a1fc85f
Reviewed-on: https://go-review.googlesource.com/c/sys/+/262959
Trust: Tobias Klauser <tobias.klauser@gmail.com>
Run-TryBot: Tobias Klauser <tobias.klauser@gmail.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matt Layher <mdlayher@gmail.com>
diff --git a/unix/mkerrors.sh b/unix/mkerrors.sh
index 467c03d..2363df8 100755
--- a/unix/mkerrors.sh
+++ b/unix/mkerrors.sh
@@ -59,6 +59,7 @@
 #include <stdint.h>
 #include <sys/attr.h>
 #include <sys/clonefile.h>
+#include <sys/kern_control.h>
 #include <sys/types.h>
 #include <sys/event.h>
 #include <sys/ptrace.h>
@@ -519,6 +520,7 @@
 		$2 ~ /^CAP_/ ||
 		$2 ~ /^CP_/ ||
 		$2 ~ /^CPUSTATES$/ ||
+		$2 ~ /^CTLIOCGINFO$/ ||
 		$2 ~ /^ALG_/ ||
 		$2 ~ /^FI(CLONE|DEDUPERANGE)/ ||
 		$2 ~ /^FS_(POLICY_FLAGS|KEY_DESC|ENCRYPTION_MODE|[A-Z0-9_]+_KEY_SIZE)/ ||
diff --git a/unix/mkpost.go b/unix/mkpost.go
index d22b057..80309dc 100644
--- a/unix/mkpost.go
+++ b/unix/mkpost.go
@@ -94,6 +94,15 @@
 		b = bytes.Replace(b, s, newNames, 1)
 	}
 
+	// Convert []int8 to []byte in ctl_info ioctl interface
+	convertCtlInfoName := regexp.MustCompile(`(Name)(\s+)\[(\d+)\]int8`)
+	ctlInfoType := regexp.MustCompile(`type CtlInfo struct {[^}]*}`)
+	ctlInfoStructs := ctlInfoType.FindAll(b, -1)
+	for _, s := range ctlInfoStructs {
+		newNames := convertCtlInfoName.ReplaceAll(s, []byte("$1$2[$3]byte"))
+		b = bytes.Replace(b, s, newNames, 1)
+	}
+
 	// Convert [1024]int8 to [1024]byte in Ptmget members
 	convertPtmget := regexp.MustCompile(`([SC]n)(\s+)\[(\d+)\]u?int8`)
 	b = convertPtmget.ReplaceAll(b, []byte("$1[$3]byte"))
diff --git a/unix/syscall_darwin.go b/unix/syscall_darwin.go
index 21b8092..5b0e831 100644
--- a/unix/syscall_darwin.go
+++ b/unix/syscall_darwin.go
@@ -13,6 +13,7 @@
 package unix
 
 import (
+	"runtime"
 	"syscall"
 	"unsafe"
 )
@@ -257,6 +258,12 @@
 
 //sys	ioctl(fd int, req uint, arg uintptr) (err error)
 
+func IoctlCtlInfo(fd int, ctlInfo *CtlInfo) error {
+	err := ioctl(fd, CTLIOCGINFO, uintptr(unsafe.Pointer(ctlInfo)))
+	runtime.KeepAlive(ctlInfo)
+	return err
+}
+
 //sys   sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) = SYS_SYSCTL
 
 func Uname(uname *Utsname) error {
diff --git a/unix/types_darwin.go b/unix/types_darwin.go
index c3bb627..95b89ea 100644
--- a/unix/types_darwin.go
+++ b/unix/types_darwin.go
@@ -26,6 +26,7 @@
 #include <mach/mach.h>
 #include <mach/message.h>
 #include <sys/event.h>
+#include <sys/kern_control.h>
 #include <sys/mman.h>
 #include <sys/mount.h>
 #include <sys/param.h>
@@ -287,3 +288,7 @@
 const SizeofClockinfo = C.sizeof_struct_clockinfo
 
 type Clockinfo C.struct_clockinfo
+
+// ctl_info
+
+type CtlInfo C.struct_ctl_info
diff --git a/unix/zerrors_darwin_386.go b/unix/zerrors_darwin_386.go
index 6f33359..c8f9f7a 100644
--- a/unix/zerrors_darwin_386.go
+++ b/unix/zerrors_darwin_386.go
@@ -251,6 +251,7 @@
 	CSTOP                             = 0x13
 	CSTOPB                            = 0x400
 	CSUSP                             = 0x1a
+	CTLIOCGINFO                       = 0xc0644e03
 	CTL_HW                            = 0x6
 	CTL_KERN                          = 0x1
 	CTL_MAXNAME                       = 0xc
diff --git a/unix/zerrors_darwin_amd64.go b/unix/zerrors_darwin_amd64.go
index db767eb..7180064 100644
--- a/unix/zerrors_darwin_amd64.go
+++ b/unix/zerrors_darwin_amd64.go
@@ -251,6 +251,7 @@
 	CSTOP                             = 0x13
 	CSTOPB                            = 0x400
 	CSUSP                             = 0x1a
+	CTLIOCGINFO                       = 0xc0644e03
 	CTL_HW                            = 0x6
 	CTL_KERN                          = 0x1
 	CTL_MAXNAME                       = 0xc
diff --git a/unix/zerrors_darwin_arm.go b/unix/zerrors_darwin_arm.go
index ddc5d00..3b9ca75 100644
--- a/unix/zerrors_darwin_arm.go
+++ b/unix/zerrors_darwin_arm.go
@@ -251,6 +251,7 @@
 	CSTOP                             = 0x13
 	CSTOPB                            = 0x400
 	CSUSP                             = 0x1a
+	CTLIOCGINFO                       = 0xc0644e03
 	CTL_HW                            = 0x6
 	CTL_KERN                          = 0x1
 	CTL_MAXNAME                       = 0xc
diff --git a/unix/zerrors_darwin_arm64.go b/unix/zerrors_darwin_arm64.go
index 0614d26..4687c73 100644
--- a/unix/zerrors_darwin_arm64.go
+++ b/unix/zerrors_darwin_arm64.go
@@ -251,6 +251,7 @@
 	CSTOP                             = 0x13
 	CSTOPB                            = 0x400
 	CSUSP                             = 0x1a
+	CTLIOCGINFO                       = 0xc0644e03
 	CTL_HW                            = 0x6
 	CTL_KERN                          = 0x1
 	CTL_MAXNAME                       = 0xc
diff --git a/unix/ztypes_darwin_386.go b/unix/ztypes_darwin_386.go
index dd56ab8..9ea0293 100644
--- a/unix/ztypes_darwin_386.go
+++ b/unix/ztypes_darwin_386.go
@@ -498,3 +498,8 @@
 	Stathz  int32
 	Profhz  int32
 }
+
+type CtlInfo struct {
+	Id   uint32
+	Name [96]byte
+}
diff --git a/unix/ztypes_darwin_amd64.go b/unix/ztypes_darwin_amd64.go
index 1f82f2b..255e6cb 100644
--- a/unix/ztypes_darwin_amd64.go
+++ b/unix/ztypes_darwin_amd64.go
@@ -503,3 +503,8 @@
 	Stathz  int32
 	Profhz  int32
 }
+
+type CtlInfo struct {
+	Id   uint32
+	Name [96]byte
+}
diff --git a/unix/ztypes_darwin_arm.go b/unix/ztypes_darwin_arm.go
index 3af01a4..e21c828 100644
--- a/unix/ztypes_darwin_arm.go
+++ b/unix/ztypes_darwin_arm.go
@@ -498,3 +498,8 @@
 	Stathz  int32
 	Profhz  int32
 }
+
+type CtlInfo struct {
+	Id   uint32
+	Name [96]byte
+}
diff --git a/unix/ztypes_darwin_arm64.go b/unix/ztypes_darwin_arm64.go
index ff43738..5eff2c1 100644
--- a/unix/ztypes_darwin_arm64.go
+++ b/unix/ztypes_darwin_arm64.go
@@ -503,3 +503,8 @@
 	Stathz  int32
 	Profhz  int32
 }
+
+type CtlInfo struct {
+	Id   uint32
+	Name [96]byte
+}