From 033028a6b48fc0a55d5e5b4465cba74afb6d7fee Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Tue, 12 Sep 2017 11:07:14 +0200 Subject: [PATCH] unix: add Major, Minor and Mkdev functions on OpenBSD 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 OpenBSD'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: Ia50b7ccab18ff7c7e9dd77ddc7e4aa6cf5c79963 Reviewed-on: https://go-review.googlesource.com/63070 Reviewed-by: Ian Lance Taylor Run-TryBot: Ian Lance Taylor TryBot-Result: Gobot Gobot --- unix/dev_openbsd.go | 29 ++++++++++++++++++++++ unix/dev_openbsd_test.go | 52 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+) create mode 100644 unix/dev_openbsd.go create mode 100644 unix/dev_openbsd_test.go diff --git a/unix/dev_openbsd.go b/unix/dev_openbsd.go new file mode 100644 index 00000000..f3430c42 --- /dev/null +++ b/unix/dev_openbsd.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 OpenBSD's sys/types.h header. + +package unix + +// Major returns the major component of an OpenBSD device number. +func Major(dev uint64) uint32 { + return uint32((dev & 0x0000ff00) >> 8) +} + +// Minor returns the minor component of an OpenBSD device number. +func Minor(dev uint64) uint32 { + minor := uint32((dev & 0x000000ff) >> 0) + minor |= uint32((dev & 0xffff0000) >> 8) + return minor +} + +// Mkdev returns an OpenBSD device number generated from the given major and minor +// components. +func Mkdev(major, minor uint32) uint64 { + dev := (uint64(major) << 8) & 0x0000ff00 + dev |= (uint64(minor) << 8) & 0xffff0000 + dev |= (uint64(minor) << 0) & 0x000000ff + return dev +} diff --git a/unix/dev_openbsd_test.go b/unix/dev_openbsd_test.go new file mode 100644 index 00000000..5635d271 --- /dev/null +++ b/unix/dev_openbsd_test.go @@ -0,0 +1,52 @@ +// 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 + // OpenBSD 6.0 + {"/dev/null", 2, 2}, + {"/dev/zero", 2, 12}, + {"/dev/ttyp0", 5, 0}, + {"/dev/ttyp1", 5, 1}, + {"/dev/random", 45, 0}, + {"/dev/srandom", 45, 1}, + {"/dev/urandom", 45, 2}, + {"/dev/arandom", 45, 3}, + } + 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) + } + }) + } +}