unix: add Uname on dragonfly
The Utsname members are only 32 bytes on Dragonfly and the syscall
returns ENOMEM in case the value is longer than that. Like uname(3)
on Dragonfly, handle this case gracefully and just truncate the
value.
Change-Id: If617af1b6831cff6d4245f498dad9f264b8fd118
Reviewed-on: https://go-review.googlesource.com/82155
Run-TryBot: Tobias Klauser <tobias.klauser@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
diff --git a/unix/syscall_dragonfly.go b/unix/syscall_dragonfly.go
index 49c65ea..9f0143a 100644
--- a/unix/syscall_dragonfly.go
+++ b/unix/syscall_dragonfly.go
@@ -169,6 +169,69 @@
return &value, err
}
+func sysctlUname(mib []_C_int, old *byte, oldlen *uintptr) error {
+ err := sysctl(mib, old, oldlen, nil, 0)
+ if err != nil {
+ // Utsname members on Dragonfly are only 32 bytes and
+ // the syscall returns ENOMEM in case the actual value
+ // is longer.
+ if err == ENOMEM {
+ err = nil
+ }
+ }
+ return err
+}
+
+func Uname(uname *Utsname) error {
+ mib := []_C_int{CTL_KERN, KERN_OSTYPE}
+ n := unsafe.Sizeof(uname.Sysname)
+ if err := sysctlUname(mib, &uname.Sysname[0], &n); err != nil {
+ return err
+ }
+ uname.Sysname[unsafe.Sizeof(uname.Sysname)-1] = 0
+
+ mib = []_C_int{CTL_KERN, KERN_HOSTNAME}
+ n = unsafe.Sizeof(uname.Nodename)
+ if err := sysctlUname(mib, &uname.Nodename[0], &n); err != nil {
+ return err
+ }
+ uname.Nodename[unsafe.Sizeof(uname.Nodename)-1] = 0
+
+ mib = []_C_int{CTL_KERN, KERN_OSRELEASE}
+ n = unsafe.Sizeof(uname.Release)
+ if err := sysctlUname(mib, &uname.Release[0], &n); err != nil {
+ return err
+ }
+ uname.Release[unsafe.Sizeof(uname.Release)-1] = 0
+
+ mib = []_C_int{CTL_KERN, KERN_VERSION}
+ n = unsafe.Sizeof(uname.Version)
+ if err := sysctlUname(mib, &uname.Version[0], &n); err != nil {
+ return err
+ }
+
+ // The version might have newlines or tabs in it, convert them to
+ // spaces.
+ for i, b := range uname.Version {
+ if b == '\n' || b == '\t' {
+ if i == len(uname.Version)-1 {
+ uname.Version[i] = 0
+ } else {
+ uname.Version[i] = ' '
+ }
+ }
+ }
+
+ mib = []_C_int{CTL_HW, HW_MACHINE}
+ n = unsafe.Sizeof(uname.Machine)
+ if err := sysctlUname(mib, &uname.Machine[0], &n); err != nil {
+ return err
+ }
+ uname.Machine[unsafe.Sizeof(uname.Machine)-1] = 0
+
+ return nil
+}
+
/*
* Exposed directly
*/
diff --git a/unix/types_dragonfly.go b/unix/types_dragonfly.go
index 46d7da9..d6ccfba 100644
--- a/unix/types_dragonfly.go
+++ b/unix/types_dragonfly.go
@@ -35,6 +35,7 @@
#include <sys/time.h>
#include <sys/types.h>
#include <sys/un.h>
+#include <sys/utsname.h>
#include <sys/wait.h>
#include <net/bpf.h>
#include <net/if.h>
@@ -267,3 +268,7 @@
POLLWRBAND = C.POLLWRBAND
POLLWRNORM = C.POLLWRNORM
)
+
+// Uname
+
+type Utsname C.struct_utsname
diff --git a/unix/zerrors_dragonfly_amd64.go b/unix/zerrors_dragonfly_amd64.go
index 8f40598..d960155 100644
--- a/unix/zerrors_dragonfly_amd64.go
+++ b/unix/zerrors_dragonfly_amd64.go
@@ -168,6 +168,8 @@
CSTOP = 0x13
CSTOPB = 0x400
CSUSP = 0x1a
+ CTL_HW = 0x6
+ CTL_KERN = 0x1
CTL_MAXNAME = 0xc
CTL_NET = 0x4
DLT_A429 = 0xb8
@@ -353,6 +355,7 @@
F_UNLCK = 0x2
F_WRLCK = 0x3
HUPCL = 0x4000
+ HW_MACHINE = 0x1
ICANON = 0x100
ICMP6_FILTER = 0x12
ICRNL = 0x100
@@ -835,6 +838,10 @@
IXANY = 0x800
IXOFF = 0x400
IXON = 0x200
+ KERN_HOSTNAME = 0xa
+ KERN_OSRELEASE = 0x2
+ KERN_OSTYPE = 0x1
+ KERN_VERSION = 0x4
LOCK_EX = 0x2
LOCK_NB = 0x4
LOCK_SH = 0x1
diff --git a/unix/ztypes_dragonfly_amd64.go b/unix/ztypes_dragonfly_amd64.go
index 1ca0e3e..84c2d67 100644
--- a/unix/ztypes_dragonfly_amd64.go
+++ b/unix/ztypes_dragonfly_amd64.go
@@ -472,3 +472,11 @@
POLLWRBAND = 0x100
POLLWRNORM = 0x4
)
+
+type Utsname struct {
+ Sysname [32]byte
+ Nodename [32]byte
+ Release [32]byte
+ Version [32]byte
+ Machine [32]byte
+}