Browse Source

unix: add Major, Minor and Mkdev functions on Solaris

Add Major, Minor and Mkdev functions for converting device numbers to
their major/minor components and vice versa.

Use the respective functions provided by the Solaris libc instead of
reimplementing them.

Test the conversion function with some well-known static device numbers
for devices which should be present on any Solaris system.

Re-generated files on OpenIndiana Hipster 2017.04 (SunOS 5.11) which
also added some previously missing error constants.

Change-Id: Ief9ea973d91c24956571eb8fafc8a4525b0f5b90
Reviewed-on: https://go-review.googlesource.com/64390
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Tobias Klauser 8 years ago
parent
commit
1f337fdb7f

+ 49 - 0
unix/dev_solaris_test.go

@@ -0,0 +1,49 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package unix_test
+
+import (
+	"fmt"
+	"testing"
+
+	"golang.org/x/sys/unix"
+)
+
+func TestDevices(t *testing.T) {
+	testCases := []struct {
+		path  string
+		major uint32
+		minor uint32
+	}{
+		// Well-known major/minor numbers on OpenSolaris according to
+		// /etc/name_to_major
+		{"/dev/zero", 134, 12},
+		{"/dev/null", 134, 2},
+		{"/dev/ptyp0", 172, 0},
+		{"/dev/ttyp0", 175, 0},
+		{"/dev/ttyp1", 175, 1},
+	}
+	for _, tc := range testCases {
+		t.Run(fmt.Sprintf("%s %v:%v", tc.path, tc.major, tc.minor), func(t *testing.T) {
+			var stat unix.Stat_t
+			err := unix.Stat(tc.path, &stat)
+			if err != nil {
+				t.Errorf("failed to stat device: %v", err)
+				return
+			}
+
+			dev := uint64(stat.Rdev)
+			if unix.Major(dev) != tc.major {
+				t.Errorf("for %s Major(%#x) == %d, want %d", tc.path, dev, unix.Major(dev), tc.major)
+			}
+			if unix.Minor(dev) != tc.minor {
+				t.Errorf("for %s Minor(%#x) == %d, want %d", tc.path, dev, unix.Minor(dev), tc.minor)
+			}
+			if unix.Mkdev(tc.major, tc.minor) != dev {
+				t.Errorf("for %s Mkdev(%d, %d) == %#x, want %#x", tc.path, tc.major, tc.minor, unix.Mkdev(tc.major, tc.minor), dev)
+			}
+		})
+	}
+}

+ 2 - 0
unix/mkerrors.sh

@@ -283,6 +283,7 @@ includes_SunOS='
 #include <sys/mman.h>
 #include <sys/wait.h>
 #include <sys/ioctl.h>
+#include <sys/mkdev.h>
 #include <net/bpf.h>
 #include <net/if.h>
 #include <net/if_arp.h>
@@ -347,6 +348,7 @@ ccflags="$@"
 		$2 !~ /^EXPR_/ &&
 		$2 ~ /^E[A-Z0-9_]+$/ ||
 		$2 ~ /^B[0-9_]+$/ ||
+		$2 ~ /^(OLD|NEW)DEV$/ ||
 		$2 == "BOTHER" ||
 		$2 ~ /^CI?BAUD(EX)?$/ ||
 		$2 == "IBSHIFT" ||

+ 18 - 0
unix/syscall_solaris.go

@@ -514,6 +514,24 @@ func Acct(path string) (err error) {
 	return acct(pathp)
 }
 
+//sys	__makedev(version int, major uint, minor uint) (val uint64)
+
+func Mkdev(major, minor uint32) uint64 {
+	return __makedev(NEWDEV, uint(major), uint(minor))
+}
+
+//sys	__major(version int, dev uint64) (val uint)
+
+func Major(dev uint64) uint32 {
+	return uint32(__major(NEWDEV, dev))
+}
+
+//sys	__minor(version int, dev uint64) (val uint)
+
+func Minor(dev uint64) uint32 {
+	return uint32(__minor(NEWDEV, dev))
+}
+
 /*
  * Expose the ioctl function
  */

+ 6 - 0
unix/zerrors_solaris_amd64.go

@@ -664,6 +664,8 @@ const (
 	MS_OLDSYNC                    = 0x0
 	MS_SYNC                       = 0x4
 	M_FLUSH                       = 0x86
+	NAME_MAX                      = 0xff
+	NEWDEV                        = 0x1
 	NL0                           = 0x0
 	NL1                           = 0x100
 	NLDLY                         = 0x100
@@ -672,6 +674,9 @@ const (
 	OFDEL                         = 0x80
 	OFILL                         = 0x40
 	OLCUC                         = 0x2
+	OLDDEV                        = 0x0
+	ONBITSMAJOR                   = 0x7
+	ONBITSMINOR                   = 0x8
 	ONLCR                         = 0x4
 	ONLRET                        = 0x20
 	ONOCR                         = 0x10
@@ -1105,6 +1110,7 @@ const (
 	VEOL                          = 0x5
 	VEOL2                         = 0x6
 	VERASE                        = 0x2
+	VERASE2                       = 0x11
 	VINTR                         = 0x0
 	VKILL                         = 0x3
 	VLNEXT                        = 0xf

+ 27 - 0
unix/zsyscall_solaris_amd64.go

@@ -25,6 +25,9 @@ import (
 //go:cgo_import_dynamic libc___xnet_recvmsg __xnet_recvmsg "libsocket.so"
 //go:cgo_import_dynamic libc___xnet_sendmsg __xnet_sendmsg "libsocket.so"
 //go:cgo_import_dynamic libc_acct acct "libc.so"
+//go:cgo_import_dynamic libc___makedev __makedev "libc.so"
+//go:cgo_import_dynamic libc___major __major "libc.so"
+//go:cgo_import_dynamic libc___minor __minor "libc.so"
 //go:cgo_import_dynamic libc_ioctl ioctl "libc.so"
 //go:cgo_import_dynamic libc_access access "libc.so"
 //go:cgo_import_dynamic libc_adjtime adjtime "libc.so"
@@ -146,6 +149,9 @@ import (
 //go:linkname proc__xnet_recvmsg libc___xnet_recvmsg
 //go:linkname proc__xnet_sendmsg libc___xnet_sendmsg
 //go:linkname procacct libc_acct
+//go:linkname proc__makedev libc___makedev
+//go:linkname proc__major libc___major
+//go:linkname proc__minor libc___minor
 //go:linkname procioctl libc_ioctl
 //go:linkname procAccess libc_access
 //go:linkname procAdjtime libc_adjtime
@@ -268,6 +274,9 @@ var (
 	proc__xnet_recvmsg,
 	proc__xnet_sendmsg,
 	procacct,
+	proc__makedev,
+	proc__major,
+	proc__minor,
 	procioctl,
 	procAccess,
 	procAdjtime,
@@ -522,6 +531,24 @@ func acct(path *byte) (err error) {
 	return
 }
 
+func __makedev(version int, major uint, minor uint) (val uint64) {
+	r0, _, _ := sysvicall6(uintptr(unsafe.Pointer(&proc__makedev)), 3, uintptr(version), uintptr(major), uintptr(minor), 0, 0, 0)
+	val = uint64(r0)
+	return
+}
+
+func __major(version int, dev uint64) (val uint) {
+	r0, _, _ := sysvicall6(uintptr(unsafe.Pointer(&proc__major)), 2, uintptr(version), uintptr(dev), 0, 0, 0, 0)
+	val = uint(r0)
+	return
+}
+
+func __minor(version int, dev uint64) (val uint) {
+	r0, _, _ := sysvicall6(uintptr(unsafe.Pointer(&proc__minor)), 2, uintptr(version), uintptr(dev), 0, 0, 0, 0)
+	val = uint(r0)
+	return
+}
+
 func ioctl(fd int, req uint, arg uintptr) (err error) {
 	_, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procioctl)), 3, uintptr(fd), uintptr(req), uintptr(arg), 0, 0, 0)
 	if e1 != 0 {