From 7ddbeae9ae08c6a06a59597f0c9edbc5ff2444ce Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Fri, 1 Sep 2017 18:16:44 +0200 Subject: [PATCH] unix: add Major, Minor and Mkdev functions on NetBSD Add Major, Minor and Mkdev functions for converting devices numbers to their major/minor components and vice versa. The functions follow the behavior of the macros defined in NetBSD's sys/types.h header. However, the parameter and return types are changed to match the existing implementations of these functions. Test the conversion macros with some well-known device numbers. Updates golang/go#8106 Change-Id: I536d6d2622f6fe9be3c1ed3beb266745fe4bfb6e Reviewed-on: https://go-review.googlesource.com/60970 Reviewed-by: Ian Lance Taylor Run-TryBot: Ian Lance Taylor TryBot-Result: Gobot Gobot --- unix/dev_netbsd.go | 29 ++++++++++++++++++++++++ unix/dev_netbsd_test.go | 50 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+) create mode 100644 unix/dev_netbsd.go create mode 100644 unix/dev_netbsd_test.go diff --git a/unix/dev_netbsd.go b/unix/dev_netbsd.go new file mode 100644 index 00000000..08db58ee --- /dev/null +++ b/unix/dev_netbsd.go @@ -0,0 +1,29 @@ +// 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. + +// Functions to access/create device major and minor numbers matching the +// encoding used in NetBSD's sys/types.h header. + +package unix + +// Major returns the major component of a NetBSD device number. +func Major(dev uint64) uint32 { + return uint32((dev & 0x000fff00) >> 8) +} + +// Minor returns the minor component of a NetBSD device number. +func Minor(dev uint64) uint32 { + minor := uint32((dev & 0x000000ff) >> 0) + minor |= uint32((dev & 0xfff00000) >> 12) + return minor +} + +// Mkdev returns a NetBSD device number generated from the given major and minor +// components. +func Mkdev(major, minor uint32) uint64 { + dev := uint64((major << 8) & 0x000fff00) + dev |= uint64((minor << 12) & 0xfff00000) + dev |= uint64((minor << 0) & 0x000000ff) + return dev +} diff --git a/unix/dev_netbsd_test.go b/unix/dev_netbsd_test.go new file mode 100644 index 00000000..c39a80a4 --- /dev/null +++ b/unix/dev_netbsd_test.go @@ -0,0 +1,50 @@ +// 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 according to /dev/MAKEDEV on + // NetBSD 7.0 + {"/dev/null", 2, 2}, + {"/dev/zero", 2, 12}, + {"/dev/ttyp0", 5, 0}, + {"/dev/ttyp1", 5, 1}, + {"/dev/random", 46, 0}, + {"/dev/urandom", 46, 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) + } + }) + } +}