unix: add Xucred, GetsockoptXucred on freebsd

Follow CL 292330 which added these on darwin.

Generated on FreeBSD 13.0BETA3

For golang/go#41659

Change-Id: I30eeef43c4f61a9449f3fe8b5cc0033f46dfe822
Reviewed-on: https://go-review.googlesource.com/c/sys/+/294989
Trust: Tobias Klauser <tobias.klauser@gmail.com>
Run-TryBot: Tobias Klauser <tobias.klauser@gmail.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
diff --git a/unix/mkerrors.sh b/unix/mkerrors.sh
index 809ab06..60ffa48 100755
--- a/unix/mkerrors.sh
+++ b/unix/mkerrors.sh
@@ -115,6 +115,7 @@
 #include <sys/sched.h>
 #include <sys/select.h>
 #include <sys/socket.h>
+#include <sys/un.h>
 #include <sys/sockio.h>
 #include <sys/stat.h>
 #include <sys/sysctl.h>
diff --git a/unix/syscall_darwin.go b/unix/syscall_darwin.go
index e771a3c..1223d7a 100644
--- a/unix/syscall_darwin.go
+++ b/unix/syscall_darwin.go
@@ -382,7 +382,7 @@
 // The usual level and opt are SOL_LOCAL and LOCAL_PEERCRED, respectively.
 func GetsockoptXucred(fd, level, opt int) (*Xucred, error) {
 	x := new(Xucred)
-	vallen := _Socklen(unsafe.Sizeof(Xucred{}))
+	vallen := _Socklen(SizeofXucred)
 	err := getsockopt(fd, level, opt, unsafe.Pointer(x), &vallen)
 	return x, err
 }
diff --git a/unix/syscall_freebsd.go b/unix/syscall_freebsd.go
index 15af63d..18c392c 100644
--- a/unix/syscall_freebsd.go
+++ b/unix/syscall_freebsd.go
@@ -126,6 +126,15 @@
 	return setsockopt(fd, level, opt, unsafe.Pointer(mreq), unsafe.Sizeof(*mreq))
 }
 
+// GetsockoptXucred is a getsockopt wrapper that returns an Xucred struct.
+// The usual level and opt are SOL_LOCAL and LOCAL_PEERCRED, respectively.
+func GetsockoptXucred(fd, level, opt int) (*Xucred, error) {
+	x := new(Xucred)
+	vallen := _Socklen(SizeofXucred)
+	err := getsockopt(fd, level, opt, unsafe.Pointer(x), &vallen)
+	return x, err
+}
+
 func Accept4(fd, flags int) (nfd int, sa Sockaddr, err error) {
 	var rsa RawSockaddrAny
 	var len _Socklen = SizeofSockaddrAny
diff --git a/unix/syscall_freebsd_test.go b/unix/syscall_freebsd_test.go
index f1b9257..f56d9bc 100644
--- a/unix/syscall_freebsd_test.go
+++ b/unix/syscall_freebsd_test.go
@@ -11,6 +11,7 @@
 	"flag"
 	"fmt"
 	"io/ioutil"
+	"net"
 	"os"
 	"os/exec"
 	"path"
@@ -297,6 +298,42 @@
 	}
 }
 
+func TestGetsockoptXucred(t *testing.T) {
+	fds, err := unix.Socketpair(unix.AF_LOCAL, unix.SOCK_STREAM, 0)
+	if err != nil {
+		t.Fatalf("Socketpair: %v", err)
+	}
+	defer unix.Close(fds[0])
+	defer unix.Close(fds[1])
+
+	srvFile := os.NewFile(uintptr(fds[0]), "server")
+	defer srvFile.Close()
+	srv, err := net.FileConn(srvFile)
+	if err != nil {
+		t.Fatalf("FileConn: %v", err)
+	}
+	defer srv.Close()
+
+	cliFile := os.NewFile(uintptr(fds[1]), "client")
+	defer cliFile.Close()
+	cli, err := net.FileConn(cliFile)
+	if err != nil {
+		t.Fatalf("FileConn: %v", err)
+	}
+	defer cli.Close()
+
+	cred, err := unix.GetsockoptXucred(fds[1], unix.SOL_LOCAL, unix.LOCAL_PEERCRED)
+	if err == unix.ENOTCONN {
+		t.Skip("GetsockoptXucred not supported with Socketpair on FreeBSD 11 and earlier")
+	} else if err != nil {
+		t.Fatal(err)
+	}
+	t.Logf("got: %+v", cred)
+	if got, want := cred.Uid, os.Getuid(); int(got) != int(want) {
+		t.Errorf("uid = %v; want %v", got, want)
+	}
+}
+
 // stringsFromByteSlice converts a sequence of attributes to a []string.
 // On FreeBSD, each entry consists of a single byte containing the length
 // of the attribute name, followed by the attribute name.
diff --git a/unix/types_freebsd.go b/unix/types_freebsd.go
index 573f9d8..968c3b0 100644
--- a/unix/types_freebsd.go
+++ b/unix/types_freebsd.go
@@ -40,6 +40,7 @@
 #include <sys/stat.h>
 #include <sys/time.h>
 #include <sys/types.h>
+#include <sys/ucred.h>
 #include <sys/un.h>
 #include <sys/utsname.h>
 #include <sys/wait.h>
@@ -204,6 +205,8 @@
 
 type _Socklen C.socklen_t
 
+type Xucred C.struct_xucred
+
 type Linger C.struct_linger
 
 type Iovec C.struct_iovec
@@ -230,6 +233,7 @@
 	SizeofSockaddrAny      = C.sizeof_struct_sockaddr_any
 	SizeofSockaddrUnix     = C.sizeof_struct_sockaddr_un
 	SizeofSockaddrDatalink = C.sizeof_struct_sockaddr_dl
+	SizeofXucred           = C.sizeof_struct_xucred
 	SizeofLinger           = C.sizeof_struct_linger
 	SizeofIovec            = C.sizeof_struct_iovec
 	SizeofIPMreq           = C.sizeof_struct_ip_mreq
diff --git a/unix/zerrors_freebsd_386.go b/unix/zerrors_freebsd_386.go
index 24fdef1..9c7c5e1 100644
--- a/unix/zerrors_freebsd_386.go
+++ b/unix/zerrors_freebsd_386.go
@@ -998,6 +998,11 @@
 	KERN_OSRELEASE                 = 0x2
 	KERN_OSTYPE                    = 0x1
 	KERN_VERSION                   = 0x4
+	LOCAL_CONNWAIT                 = 0x4
+	LOCAL_CREDS                    = 0x2
+	LOCAL_CREDS_PERSISTENT         = 0x3
+	LOCAL_PEERCRED                 = 0x1
+	LOCAL_VENDOR                   = 0x80000000
 	LOCK_EX                        = 0x2
 	LOCK_NB                        = 0x4
 	LOCK_SH                        = 0x1
@@ -1376,6 +1381,7 @@
 	SOCK_RDM                       = 0x4
 	SOCK_SEQPACKET                 = 0x5
 	SOCK_STREAM                    = 0x1
+	SOL_LOCAL                      = 0x0
 	SOL_SOCKET                     = 0xffff
 	SOMAXCONN                      = 0x80
 	SO_ACCEPTCONN                  = 0x2
diff --git a/unix/zerrors_freebsd_amd64.go b/unix/zerrors_freebsd_amd64.go
index fede889..b265abb 100644
--- a/unix/zerrors_freebsd_amd64.go
+++ b/unix/zerrors_freebsd_amd64.go
@@ -998,6 +998,11 @@
 	KERN_OSRELEASE                 = 0x2
 	KERN_OSTYPE                    = 0x1
 	KERN_VERSION                   = 0x4
+	LOCAL_CONNWAIT                 = 0x4
+	LOCAL_CREDS                    = 0x2
+	LOCAL_CREDS_PERSISTENT         = 0x3
+	LOCAL_PEERCRED                 = 0x1
+	LOCAL_VENDOR                   = 0x80000000
 	LOCK_EX                        = 0x2
 	LOCK_NB                        = 0x4
 	LOCK_SH                        = 0x1
@@ -1377,6 +1382,7 @@
 	SOCK_RDM                       = 0x4
 	SOCK_SEQPACKET                 = 0x5
 	SOCK_STREAM                    = 0x1
+	SOL_LOCAL                      = 0x0
 	SOL_SOCKET                     = 0xffff
 	SOMAXCONN                      = 0x80
 	SO_ACCEPTCONN                  = 0x2
diff --git a/unix/zerrors_freebsd_arm.go b/unix/zerrors_freebsd_arm.go
index 6430180..0326a6b 100644
--- a/unix/zerrors_freebsd_arm.go
+++ b/unix/zerrors_freebsd_arm.go
@@ -981,6 +981,11 @@
 	KERN_OSRELEASE                 = 0x2
 	KERN_OSTYPE                    = 0x1
 	KERN_VERSION                   = 0x4
+	LOCAL_CONNWAIT                 = 0x4
+	LOCAL_CREDS                    = 0x2
+	LOCAL_CREDS_PERSISTENT         = 0x3
+	LOCAL_PEERCRED                 = 0x1
+	LOCAL_VENDOR                   = 0x80000000
 	LOCK_EX                        = 0x2
 	LOCK_NB                        = 0x4
 	LOCK_SH                        = 0x1
@@ -1342,6 +1347,7 @@
 	SOCK_RDM                       = 0x4
 	SOCK_SEQPACKET                 = 0x5
 	SOCK_STREAM                    = 0x1
+	SOL_LOCAL                      = 0x0
 	SOL_SOCKET                     = 0xffff
 	SOMAXCONN                      = 0x80
 	SO_ACCEPTCONN                  = 0x2
diff --git a/unix/zerrors_freebsd_arm64.go b/unix/zerrors_freebsd_arm64.go
index 5a9c21b..218d399 100644
--- a/unix/zerrors_freebsd_arm64.go
+++ b/unix/zerrors_freebsd_arm64.go
@@ -998,6 +998,11 @@
 	KERN_OSRELEASE                 = 0x2
 	KERN_OSTYPE                    = 0x1
 	KERN_VERSION                   = 0x4
+	LOCAL_CONNWAIT                 = 0x4
+	LOCAL_CREDS                    = 0x2
+	LOCAL_CREDS_PERSISTENT         = 0x3
+	LOCAL_PEERCRED                 = 0x1
+	LOCAL_VENDOR                   = 0x80000000
 	LOCK_EX                        = 0x2
 	LOCK_NB                        = 0x4
 	LOCK_SH                        = 0x1
@@ -1377,6 +1382,7 @@
 	SOCK_RDM                       = 0x4
 	SOCK_SEQPACKET                 = 0x5
 	SOCK_STREAM                    = 0x1
+	SOL_LOCAL                      = 0x0
 	SOL_SOCKET                     = 0xffff
 	SOMAXCONN                      = 0x80
 	SO_ACCEPTCONN                  = 0x2
diff --git a/unix/ztypes_freebsd_386.go b/unix/ztypes_freebsd_386.go
index a70d2e2..c51bc88 100644
--- a/unix/ztypes_freebsd_386.go
+++ b/unix/ztypes_freebsd_386.go
@@ -251,6 +251,14 @@
 
 type _Socklen uint32
 
+type Xucred struct {
+	Version uint32
+	Uid     uint32
+	Ngroups int16
+	Groups  [16]uint32
+	_       *byte
+}
+
 type Linger struct {
 	Onoff  int32
 	Linger int32
@@ -313,6 +321,7 @@
 	SizeofSockaddrAny      = 0x6c
 	SizeofSockaddrUnix     = 0x6a
 	SizeofSockaddrDatalink = 0x36
+	SizeofXucred           = 0x50
 	SizeofLinger           = 0x8
 	SizeofIovec            = 0x8
 	SizeofIPMreq           = 0x8
diff --git a/unix/ztypes_freebsd_amd64.go b/unix/ztypes_freebsd_amd64.go
index 00ce929..395b691 100644
--- a/unix/ztypes_freebsd_amd64.go
+++ b/unix/ztypes_freebsd_amd64.go
@@ -247,6 +247,14 @@
 
 type _Socklen uint32
 
+type Xucred struct {
+	Version uint32
+	Uid     uint32
+	Ngroups int16
+	Groups  [16]uint32
+	_       *byte
+}
+
 type Linger struct {
 	Onoff  int32
 	Linger int32
@@ -309,6 +317,7 @@
 	SizeofSockaddrAny      = 0x6c
 	SizeofSockaddrUnix     = 0x6a
 	SizeofSockaddrDatalink = 0x36
+	SizeofXucred           = 0x58
 	SizeofLinger           = 0x8
 	SizeofIovec            = 0x10
 	SizeofIPMreq           = 0x8
diff --git a/unix/ztypes_freebsd_arm.go b/unix/ztypes_freebsd_arm.go
index 28694e5..d3f9d25 100644
--- a/unix/ztypes_freebsd_arm.go
+++ b/unix/ztypes_freebsd_arm.go
@@ -249,6 +249,14 @@
 
 type _Socklen uint32
 
+type Xucred struct {
+	Version uint32
+	Uid     uint32
+	Ngroups int16
+	Groups  [16]uint32
+	_       *byte
+}
+
 type Linger struct {
 	Onoff  int32
 	Linger int32
@@ -311,6 +319,7 @@
 	SizeofSockaddrAny      = 0x6c
 	SizeofSockaddrUnix     = 0x6a
 	SizeofSockaddrDatalink = 0x36
+	SizeofXucred           = 0x50
 	SizeofLinger           = 0x8
 	SizeofIovec            = 0x8
 	SizeofIPMreq           = 0x8
diff --git a/unix/ztypes_freebsd_arm64.go b/unix/ztypes_freebsd_arm64.go
index cb74994..434d6e8 100644
--- a/unix/ztypes_freebsd_arm64.go
+++ b/unix/ztypes_freebsd_arm64.go
@@ -247,6 +247,14 @@
 
 type _Socklen uint32
 
+type Xucred struct {
+	Version uint32
+	Uid     uint32
+	Ngroups int16
+	Groups  [16]uint32
+	_       *byte
+}
+
 type Linger struct {
 	Onoff  int32
 	Linger int32
@@ -309,6 +317,7 @@
 	SizeofSockaddrAny      = 0x6c
 	SizeofSockaddrUnix     = 0x6a
 	SizeofSockaddrDatalink = 0x36
+	SizeofXucred           = 0x58
 	SizeofLinger           = 0x8
 	SizeofIovec            = 0x10
 	SizeofIPMreq           = 0x8