From 9167dbfd0f8e88b731dd88cbf73a270701a37bb4 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Wed, 6 Dec 2017 08:53:10 +0000 Subject: [PATCH] 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 TryBot-Result: Gobot Gobot Reviewed-by: Ian Lance Taylor --- unix/syscall_dragonfly.go | 63 +++++++++++++++++++++++++++++++++ unix/types_dragonfly.go | 5 +++ unix/zerrors_dragonfly_amd64.go | 7 ++++ unix/ztypes_dragonfly_amd64.go | 8 +++++ 4 files changed, 83 insertions(+) diff --git a/unix/syscall_dragonfly.go b/unix/syscall_dragonfly.go index 49c65ea6..9f0143aa 100644 --- a/unix/syscall_dragonfly.go +++ b/unix/syscall_dragonfly.go @@ -169,6 +169,69 @@ func IoctlGetTermios(fd int, req uint) (*Termios, error) { 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 46d7da96..d6ccfba2 100644 --- a/unix/types_dragonfly.go +++ b/unix/types_dragonfly.go @@ -35,6 +35,7 @@ package unix #include #include #include +#include #include #include #include @@ -267,3 +268,7 @@ const ( 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 8f40598b..d9601550 100644 --- a/unix/zerrors_dragonfly_amd64.go +++ b/unix/zerrors_dragonfly_amd64.go @@ -168,6 +168,8 @@ const ( 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 @@ const ( F_UNLCK = 0x2 F_WRLCK = 0x3 HUPCL = 0x4000 + HW_MACHINE = 0x1 ICANON = 0x100 ICMP6_FILTER = 0x12 ICRNL = 0x100 @@ -835,6 +838,10 @@ const ( 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 1ca0e3ee..84c2d67b 100644 --- a/unix/ztypes_dragonfly_amd64.go +++ b/unix/ztypes_dragonfly_amd64.go @@ -472,3 +472,11 @@ const ( POLLWRBAND = 0x100 POLLWRNORM = 0x4 ) + +type Utsname struct { + Sysname [32]byte + Nodename [32]byte + Release [32]byte + Version [32]byte + Machine [32]byte +}