From a07a691ac871746ae690ccf3ab217363b2144531 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Wed, 30 Aug 2017 11:57:17 +0200 Subject: [PATCH] unix: add Major, Minor and Mkdev functions on Darwin 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 Darwin's sys/types.h header. However, the parameter and return types are changed to match the respective Linux implementation of these functions. Test the conversion macros with some well-known static device numbers for devices which should be present on any Darwin system. Updates golang/go#8106 Change-Id: I1862be64684cc1b5a53e15a883819571e368cb2b Reviewed-on: https://go-review.googlesource.com/60610 Reviewed-by: Ian Lance Taylor Run-TryBot: Ian Lance Taylor TryBot-Result: Gobot Gobot --- unix/dev_darwin.go | 24 ++++++++++++++++++++ unix/dev_darwin_test.go | 49 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 unix/dev_darwin.go create mode 100644 unix/dev_darwin_test.go diff --git a/unix/dev_darwin.go b/unix/dev_darwin.go new file mode 100644 index 00000000..7d101d52 --- /dev/null +++ b/unix/dev_darwin.go @@ -0,0 +1,24 @@ +// 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 Darwin's sys/types.h header. + +package unix + +// Major returns the major component of a Darwin device number. +func Major(dev uint64) uint32 { + return uint32((dev >> 24) & 0xff) +} + +// Minor returns the minor component of a Darwin device number. +func Minor(dev uint64) uint32 { + return uint32(dev & 0xffffff) +} + +// Mkdev returns a Darwin device number generated from the given major and minor +// components. +func Mkdev(major, minor uint32) uint64 { + return uint64((major << 24) | minor) +} diff --git a/unix/dev_darwin_test.go b/unix/dev_darwin_test.go new file mode 100644 index 00000000..48d04486 --- /dev/null +++ b/unix/dev_darwin_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 + }{ + // Most of the device major/minor numbers on Darwin are + // dynamically generated by devfs. These are some well-known + // static numbers. + {"/dev/ttyp0", 4, 0}, + {"/dev/ttys0", 4, 48}, + {"/dev/ptyp0", 5, 0}, + {"/dev/ptyr0", 5, 32}, + } + 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) + } + }) + } +}