lvm: setupLV wait device + go mod

This commit is contained in:
Mikaël Cluseau
2019-02-05 09:36:11 +11:00
parent 10e72f18ae
commit c62ddaf2e0
134 changed files with 336 additions and 38985 deletions

3
vendor/golang.org/x/sys/AUTHORS generated vendored Normal file
View File

@ -0,0 +1,3 @@
# This source code refers to The Go Authors for copyright purposes.
# The master list of authors is in the main Go distribution,
# visible at http://tip.golang.org/AUTHORS.

3
vendor/golang.org/x/sys/CONTRIBUTORS generated vendored Normal file
View File

@ -0,0 +1,3 @@
# This source code was written by the Go contributors.
# The master list of contributors is in the main Go distribution,
# visible at http://tip.golang.org/CONTRIBUTORS.

27
vendor/golang.org/x/sys/LICENSE generated vendored Normal file
View File

@ -0,0 +1,27 @@
Copyright (c) 2009 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

22
vendor/golang.org/x/sys/PATENTS generated vendored Normal file
View File

@ -0,0 +1,22 @@
Additional IP Rights Grant (Patents)
"This implementation" means the copyrightable works distributed by
Google as part of the Go project.
Google hereby grants to You a perpetual, worldwide, non-exclusive,
no-charge, royalty-free, irrevocable (except as stated in this section)
patent license to make, have made, use, offer to sell, sell, import,
transfer and otherwise run, modify and propagate the contents of this
implementation of Go, where such license applies only to those patent
claims, both currently owned or controlled by Google and acquired in
the future, licensable by Google that are necessarily infringed by this
implementation of Go. This grant does not include claims that would be
infringed only as a consequence of further modification of this
implementation. If you or your agent or exclusive licensee institute or
order or agree to the institution of patent litigation against any
entity (including a cross-claim or counterclaim in a lawsuit) alleging
that this implementation of Go or any code incorporated within this
implementation of Go constitutes direct or contributory patent
infringement, or inducement of patent infringement, then any patent
rights granted to you under this License for this implementation of Go
shall terminate as of the date such litigation is filed.

View File

@ -1,134 +0,0 @@
// Copyright 2012 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.
// +build linux
package unix_test
import (
"bytes"
"go/build"
"net"
"os"
"testing"
"golang.org/x/sys/unix"
)
// TestSCMCredentials tests the sending and receiving of credentials
// (PID, UID, GID) in an ancillary message between two UNIX
// sockets. The SO_PASSCRED socket option is enabled on the sending
// socket for this to work.
func TestSCMCredentials(t *testing.T) {
socketTypeTests := []struct {
socketType int
dataLen int
}{
{
unix.SOCK_STREAM,
1,
}, {
unix.SOCK_DGRAM,
0,
},
}
for _, tt := range socketTypeTests {
if tt.socketType == unix.SOCK_DGRAM && !atLeast1p10() {
t.Log("skipping DGRAM test on pre-1.10")
continue
}
fds, err := unix.Socketpair(unix.AF_LOCAL, tt.socketType, 0)
if err != nil {
t.Fatalf("Socketpair: %v", err)
}
defer unix.Close(fds[0])
defer unix.Close(fds[1])
err = unix.SetsockoptInt(fds[0], unix.SOL_SOCKET, unix.SO_PASSCRED, 1)
if err != nil {
t.Fatalf("SetsockoptInt: %v", err)
}
srvFile := os.NewFile(uintptr(fds[0]), "server")
defer srvFile.Close()
srv, err := net.FileConn(srvFile)
if err != nil {
t.Errorf("FileConn: %v", err)
return
}
defer srv.Close()
cliFile := os.NewFile(uintptr(fds[1]), "client")
defer cliFile.Close()
cli, err := net.FileConn(cliFile)
if err != nil {
t.Errorf("FileConn: %v", err)
return
}
defer cli.Close()
var ucred unix.Ucred
ucred.Pid = int32(os.Getpid())
ucred.Uid = uint32(os.Getuid())
ucred.Gid = uint32(os.Getgid())
oob := unix.UnixCredentials(&ucred)
// On SOCK_STREAM, this is internally going to send a dummy byte
n, oobn, err := cli.(*net.UnixConn).WriteMsgUnix(nil, oob, nil)
if err != nil {
t.Fatalf("WriteMsgUnix: %v", err)
}
if n != 0 {
t.Fatalf("WriteMsgUnix n = %d, want 0", n)
}
if oobn != len(oob) {
t.Fatalf("WriteMsgUnix oobn = %d, want %d", oobn, len(oob))
}
oob2 := make([]byte, 10*len(oob))
n, oobn2, flags, _, err := srv.(*net.UnixConn).ReadMsgUnix(nil, oob2)
if err != nil {
t.Fatalf("ReadMsgUnix: %v", err)
}
if flags != 0 {
t.Fatalf("ReadMsgUnix flags = 0x%x, want 0", flags)
}
if n != tt.dataLen {
t.Fatalf("ReadMsgUnix n = %d, want %d", n, tt.dataLen)
}
if oobn2 != oobn {
// without SO_PASSCRED set on the socket, ReadMsgUnix will
// return zero oob bytes
t.Fatalf("ReadMsgUnix oobn = %d, want %d", oobn2, oobn)
}
oob2 = oob2[:oobn2]
if !bytes.Equal(oob, oob2) {
t.Fatal("ReadMsgUnix oob bytes don't match")
}
scm, err := unix.ParseSocketControlMessage(oob2)
if err != nil {
t.Fatalf("ParseSocketControlMessage: %v", err)
}
newUcred, err := unix.ParseUnixCredentials(&scm[0])
if err != nil {
t.Fatalf("ParseUnixCredentials: %v", err)
}
if *newUcred != ucred {
t.Fatalf("ParseUnixCredentials = %+v, want %+v", newUcred, ucred)
}
}
}
// atLeast1p10 reports whether we are running on Go 1.10 or later.
func atLeast1p10() bool {
for _, ver := range build.Default.ReleaseTags {
if ver == "go1.10" {
return true
}
}
return false
}

View File

@ -1,56 +0,0 @@
// 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.
// +build go1.7
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
// https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/admin-guide/devices.txt
{"/dev/null", 1, 3},
{"/dev/zero", 1, 5},
{"/dev/random", 1, 8},
{"/dev/full", 1, 7},
{"/dev/urandom", 1, 9},
{"/dev/tty", 5, 0},
}
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 {
if err == unix.EACCES {
t.Skip("no permission to stat device, skipping test")
}
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)
}
})
}
}

View File

@ -1,19 +0,0 @@
// Copyright 2018 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.
// +build darwin dragonfly freebsd linux netbsd openbsd solaris
package unix_test
import (
"log"
"os"
"golang.org/x/sys/unix"
)
func ExampleExec() {
err := unix.Exec("/bin/ls", []string{"ls", "-al"}, os.Environ())
log.Fatal(err)
}

View File

@ -1,9 +0,0 @@
// Copyright 2015 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.
// +build darwin dragonfly freebsd linux netbsd openbsd solaris
package unix
var Itoa = itoa

View File

@ -1,35 +0,0 @@
// Copyright 2014 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.
// +build darwin dragonfly freebsd linux netbsd openbsd solaris
package unix_test
import (
"testing"
"golang.org/x/sys/unix"
)
func TestMmap(t *testing.T) {
b, err := unix.Mmap(-1, 0, unix.Getpagesize(), unix.PROT_NONE, unix.MAP_ANON|unix.MAP_PRIVATE)
if err != nil {
t.Fatalf("Mmap: %v", err)
}
if err := unix.Mprotect(b, unix.PROT_READ|unix.PROT_WRITE); err != nil {
t.Fatalf("Mprotect: %v", err)
}
b[0] = 42
if err := unix.Msync(b, unix.MS_SYNC); err != nil {
t.Fatalf("Msync: %v", err)
}
if err := unix.Madvise(b, unix.MADV_DONTNEED); err != nil {
t.Fatalf("Madvise: %v", err)
}
if err := unix.Munmap(b); err != nil {
t.Fatalf("Munmap: %v", err)
}
}

View File

@ -1,113 +0,0 @@
// Copyright 2016 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.
// +build openbsd
// This, on the face of it, bizarre testing mechanism is necessary because
// the only reliable way to gauge whether or not a pledge(2) call has succeeded
// is that the program has been killed as a result of breaking its pledge.
package unix_test
import (
"flag"
"fmt"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
"testing"
"golang.org/x/sys/unix"
)
type testProc struct {
fn func() // should always exit instead of returning
cleanup func() error // for instance, delete coredumps from testing pledge
success bool // whether zero-exit means success or failure
}
var (
testProcs = map[string]testProc{}
procName = ""
)
const (
optName = "sys-unix-internal-procname"
)
func init() {
flag.StringVar(&procName, optName, "", "internal use only")
}
// testCmd generates a proper command that, when executed, runs the test
// corresponding to the given key.
func testCmd(procName string) (*exec.Cmd, error) {
exe, err := filepath.Abs(os.Args[0])
if err != nil {
return nil, err
}
cmd := exec.Command(exe, "-"+optName+"="+procName)
cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr
return cmd, nil
}
// ExitsCorrectly is a comprehensive, one-line-of-use wrapper for testing
// a testProc with a key.
func ExitsCorrectly(procName string, t *testing.T) {
s := testProcs[procName]
c, err := testCmd(procName)
defer func() {
if s.cleanup() != nil {
t.Fatalf("Failed to run cleanup for %s", procName)
}
}()
if err != nil {
t.Fatalf("Failed to construct command for %s", procName)
}
if (c.Run() == nil) != s.success {
result := "succeed"
if !s.success {
result = "fail"
}
t.Fatalf("Process did not %s when it was supposed to", result)
}
}
func TestMain(m *testing.M) {
flag.Parse()
if procName != "" {
testProcs[procName].fn()
}
os.Exit(m.Run())
}
// For example, add a test for pledge.
func init() {
testProcs["pledge"] = testProc{
func() {
fmt.Println(unix.Pledge("", nil))
os.Exit(0)
},
func() error {
files, err := ioutil.ReadDir(".")
if err != nil {
return err
}
for _, file := range files {
if filepath.Ext(file.Name()) == ".core" {
if err := os.Remove(file.Name()); err != nil {
return err
}
}
}
return nil
},
false,
}
}
func TestPledge(t *testing.T) {
ExitsCorrectly("pledge", t)
}

View File

@ -1,93 +0,0 @@
// Copyright 2014 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.
// +build darwin dragonfly freebsd openbsd
package unix_test
import (
"os/exec"
"runtime"
"testing"
"time"
"golang.org/x/sys/unix"
)
const MNT_WAIT = 1
const MNT_NOWAIT = 2
func TestGetfsstat(t *testing.T) {
const flags = MNT_NOWAIT // see golang.org/issue/16937
n, err := unix.Getfsstat(nil, flags)
if err != nil {
t.Fatal(err)
}
data := make([]unix.Statfs_t, n)
n2, err := unix.Getfsstat(data, flags)
if err != nil {
t.Fatal(err)
}
if n != n2 {
t.Errorf("Getfsstat(nil) = %d, but subsequent Getfsstat(slice) = %d", n, n2)
}
for i, stat := range data {
if stat == (unix.Statfs_t{}) {
t.Errorf("index %v is an empty Statfs_t struct", i)
}
}
if t.Failed() {
for i, stat := range data[:n2] {
t.Logf("data[%v] = %+v", i, stat)
}
mount, err := exec.Command("mount").CombinedOutput()
if err != nil {
t.Logf("mount: %v\n%s", err, mount)
} else {
t.Logf("mount: %s", mount)
}
}
}
func TestSelect(t *testing.T) {
err := unix.Select(0, nil, nil, nil, &unix.Timeval{Sec: 0, Usec: 0})
if err != nil {
t.Fatalf("Select: %v", err)
}
dur := 250 * time.Millisecond
tv := unix.NsecToTimeval(int64(dur))
start := time.Now()
err = unix.Select(0, nil, nil, nil, &tv)
took := time.Since(start)
if err != nil {
t.Fatalf("Select: %v", err)
}
// On some BSDs the actual timeout might also be slightly less than the requested.
// Add an acceptable margin to avoid flaky tests.
if took < dur*2/3 {
t.Errorf("Select: timeout should have been at least %v, got %v", dur, took)
}
}
func TestSysctlRaw(t *testing.T) {
if runtime.GOOS == "openbsd" {
t.Skip("kern.proc.pid does not exist on OpenBSD")
}
_, err := unix.SysctlRaw("kern.proc.pid", unix.Getpid())
if err != nil {
t.Fatal(err)
}
}
func TestSysctlUint32(t *testing.T) {
maxproc, err := unix.SysctlUint32("kern.maxproc")
if err != nil {
t.Fatal(err)
}
t.Logf("kern.maxproc: %v", maxproc)
}

View File

@ -1,19 +0,0 @@
// Copyright 2018 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
// stringsFromByteSlice converts a sequence of attributes to a []string.
// On Darwin, each entry is a NULL-terminated string.
func stringsFromByteSlice(buf []byte) []string {
var result []string
off := 0
for i, b := range buf {
if b == 0 {
result = append(result, string(buf[off:i]))
off = i + 1
}
}
return result
}

View File

@ -1,312 +0,0 @@
// Copyright 2014 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.
// +build freebsd
package unix_test
import (
"flag"
"fmt"
"io/ioutil"
"os"
"os/exec"
"path"
"path/filepath"
"runtime"
"testing"
"golang.org/x/sys/unix"
)
func TestSysctlUint64(t *testing.T) {
_, err := unix.SysctlUint64("vm.swap_total")
if err != nil {
t.Fatal(err)
}
}
// FIXME: Infrastructure for launching tests in subprocesses stolen from openbsd_test.go - refactor?
// testCmd generates a proper command that, when executed, runs the test
// corresponding to the given key.
type testProc struct {
fn func() // should always exit instead of returning
arg func(t *testing.T) string // generate argument for test
cleanup func(arg string) error // for instance, delete coredumps from testing pledge
success bool // whether zero-exit means success or failure
}
var (
testProcs = map[string]testProc{}
procName = ""
procArg = ""
)
const (
optName = "sys-unix-internal-procname"
optArg = "sys-unix-internal-arg"
)
func init() {
flag.StringVar(&procName, optName, "", "internal use only")
flag.StringVar(&procArg, optArg, "", "internal use only")
}
func testCmd(procName string, procArg string) (*exec.Cmd, error) {
exe, err := filepath.Abs(os.Args[0])
if err != nil {
return nil, err
}
cmd := exec.Command(exe, "-"+optName+"="+procName, "-"+optArg+"="+procArg)
cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr
return cmd, nil
}
// ExitsCorrectly is a comprehensive, one-line-of-use wrapper for testing
// a testProc with a key.
func ExitsCorrectly(t *testing.T, procName string) {
s := testProcs[procName]
arg := "-"
if s.arg != nil {
arg = s.arg(t)
}
c, err := testCmd(procName, arg)
defer func(arg string) {
if err := s.cleanup(arg); err != nil {
t.Fatalf("Failed to run cleanup for %s %s %#v", procName, err, err)
}
}(arg)
if err != nil {
t.Fatalf("Failed to construct command for %s", procName)
}
if (c.Run() == nil) != s.success {
result := "succeed"
if !s.success {
result = "fail"
}
t.Fatalf("Process did not %s when it was supposed to", result)
}
}
func TestMain(m *testing.M) {
flag.Parse()
if procName != "" {
t := testProcs[procName]
t.fn()
os.Stderr.WriteString("test function did not exit\n")
if t.success {
os.Exit(1)
} else {
os.Exit(0)
}
}
os.Exit(m.Run())
}
// end of infrastructure
const testfile = "gocapmodetest"
const testfile2 = testfile + "2"
func CapEnterTest() {
_, err := os.OpenFile(path.Join(procArg, testfile), os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
if err != nil {
panic(fmt.Sprintf("OpenFile: %s", err))
}
err = unix.CapEnter()
if err != nil {
panic(fmt.Sprintf("CapEnter: %s", err))
}
_, err = os.OpenFile(path.Join(procArg, testfile2), os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
if err == nil {
panic("OpenFile works!")
}
if err.(*os.PathError).Err != unix.ECAPMODE {
panic(fmt.Sprintf("OpenFile failed wrong: %s %#v", err, err))
}
os.Exit(0)
}
func makeTempDir(t *testing.T) string {
d, err := ioutil.TempDir("", "go_openat_test")
if err != nil {
t.Fatalf("TempDir failed: %s", err)
}
return d
}
func removeTempDir(arg string) error {
err := os.RemoveAll(arg)
if err != nil && err.(*os.PathError).Err == unix.ENOENT {
return nil
}
return err
}
func init() {
testProcs["cap_enter"] = testProc{
CapEnterTest,
makeTempDir,
removeTempDir,
true,
}
}
func TestCapEnter(t *testing.T) {
if runtime.GOARCH != "amd64" {
t.Skipf("skipping test on %s", runtime.GOARCH)
}
ExitsCorrectly(t, "cap_enter")
}
func OpenatTest() {
f, err := os.Open(procArg)
if err != nil {
panic(err)
}
err = unix.CapEnter()
if err != nil {
panic(fmt.Sprintf("CapEnter: %s", err))
}
fxx, err := unix.Openat(int(f.Fd()), "xx", os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
if err != nil {
panic(err)
}
unix.Close(fxx)
// The right to open BASE/xx is not ambient
_, err = os.OpenFile(procArg+"/xx", os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
if err == nil {
panic("OpenFile succeeded")
}
if err.(*os.PathError).Err != unix.ECAPMODE {
panic(fmt.Sprintf("OpenFile failed wrong: %s %#v", err, err))
}
// Can't make a new directory either
err = os.Mkdir(procArg+"2", 0777)
if err == nil {
panic("MKdir succeeded")
}
if err.(*os.PathError).Err != unix.ECAPMODE {
panic(fmt.Sprintf("Mkdir failed wrong: %s %#v", err, err))
}
// Remove all caps except read and lookup.
r, err := unix.CapRightsInit([]uint64{unix.CAP_READ, unix.CAP_LOOKUP})
if err != nil {
panic(fmt.Sprintf("CapRightsInit failed: %s %#v", err, err))
}
err = unix.CapRightsLimit(f.Fd(), r)
if err != nil {
panic(fmt.Sprintf("CapRightsLimit failed: %s %#v", err, err))
}
// Check we can get the rights back again
r, err = unix.CapRightsGet(f.Fd())
if err != nil {
panic(fmt.Sprintf("CapRightsGet failed: %s %#v", err, err))
}
b, err := unix.CapRightsIsSet(r, []uint64{unix.CAP_READ, unix.CAP_LOOKUP})
if err != nil {
panic(fmt.Sprintf("CapRightsIsSet failed: %s %#v", err, err))
}
if !b {
panic(fmt.Sprintf("Unexpected rights"))
}
b, err = unix.CapRightsIsSet(r, []uint64{unix.CAP_READ, unix.CAP_LOOKUP, unix.CAP_WRITE})
if err != nil {
panic(fmt.Sprintf("CapRightsIsSet failed: %s %#v", err, err))
}
if b {
panic(fmt.Sprintf("Unexpected rights (2)"))
}
// Can no longer create a file
_, err = unix.Openat(int(f.Fd()), "xx2", os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
if err == nil {
panic("Openat succeeded")
}
if err != unix.ENOTCAPABLE {
panic(fmt.Sprintf("OpenFileAt failed wrong: %s %#v", err, err))
}
// But can read an existing one
_, err = unix.Openat(int(f.Fd()), "xx", os.O_RDONLY, 0666)
if err != nil {
panic(fmt.Sprintf("Openat failed: %s %#v", err, err))
}
os.Exit(0)
}
func init() {
testProcs["openat"] = testProc{
OpenatTest,
makeTempDir,
removeTempDir,
true,
}
}
func TestOpenat(t *testing.T) {
if runtime.GOARCH != "amd64" {
t.Skipf("skipping test on %s", runtime.GOARCH)
}
ExitsCorrectly(t, "openat")
}
func TestCapRightsSetAndClear(t *testing.T) {
r, err := unix.CapRightsInit([]uint64{unix.CAP_READ, unix.CAP_WRITE, unix.CAP_PDWAIT})
if err != nil {
t.Fatalf("CapRightsInit failed: %s", err)
}
err = unix.CapRightsSet(r, []uint64{unix.CAP_EVENT, unix.CAP_LISTEN})
if err != nil {
t.Fatalf("CapRightsSet failed: %s", err)
}
b, err := unix.CapRightsIsSet(r, []uint64{unix.CAP_READ, unix.CAP_WRITE, unix.CAP_PDWAIT, unix.CAP_EVENT, unix.CAP_LISTEN})
if err != nil {
t.Fatalf("CapRightsIsSet failed: %s", err)
}
if !b {
t.Fatalf("Wrong rights set")
}
err = unix.CapRightsClear(r, []uint64{unix.CAP_READ, unix.CAP_PDWAIT})
if err != nil {
t.Fatalf("CapRightsClear failed: %s", err)
}
b, err = unix.CapRightsIsSet(r, []uint64{unix.CAP_WRITE, unix.CAP_EVENT, unix.CAP_LISTEN})
if err != nil {
t.Fatalf("CapRightsIsSet failed: %s", err)
}
if !b {
t.Fatalf("Wrong rights set")
}
}
// stringsFromByteSlice converts a sequence of attributes to a []string.
// On FreeBSD, each entry consists of a single byte containing the length
// of the attribute name, followed by the attribute name.
// The name is _not_ NULL-terminated.
func stringsFromByteSlice(buf []byte) []string {
var result []string
i := 0
for i < len(buf) {
next := i + 1 + int(buf[i])
result = append(result, string(buf[i+1:next]))
i = next
}
return result
}

View File

@ -1,421 +0,0 @@
// Copyright 2016 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.
// +build linux
package unix_test
import (
"os"
"runtime"
"runtime/debug"
"testing"
"time"
"golang.org/x/sys/unix"
)
func TestIoctlGetInt(t *testing.T) {
f, err := os.Open("/dev/random")
if err != nil {
t.Fatalf("failed to open device: %v", err)
}
defer f.Close()
v, err := unix.IoctlGetInt(int(f.Fd()), unix.RNDGETENTCNT)
if err != nil {
t.Fatalf("failed to perform ioctl: %v", err)
}
t.Logf("%d bits of entropy available", v)
}
func TestPpoll(t *testing.T) {
if runtime.GOOS == "android" {
t.Skip("mkfifo syscall is not available on android, skipping test")
}
f, cleanup := mktmpfifo(t)
defer cleanup()
const timeout = 100 * time.Millisecond
ok := make(chan bool, 1)
go func() {
select {
case <-time.After(10 * timeout):
t.Errorf("Ppoll: failed to timeout after %d", 10*timeout)
case <-ok:
}
}()
fds := []unix.PollFd{{Fd: int32(f.Fd()), Events: unix.POLLIN}}
timeoutTs := unix.NsecToTimespec(int64(timeout))
n, err := unix.Ppoll(fds, &timeoutTs, nil)
ok <- true
if err != nil {
t.Errorf("Ppoll: unexpected error: %v", err)
return
}
if n != 0 {
t.Errorf("Ppoll: wrong number of events: got %v, expected %v", n, 0)
return
}
}
func TestTime(t *testing.T) {
var ut unix.Time_t
ut2, err := unix.Time(&ut)
if err != nil {
t.Fatalf("Time: %v", err)
}
if ut != ut2 {
t.Errorf("Time: return value %v should be equal to argument %v", ut2, ut)
}
var now time.Time
for i := 0; i < 10; i++ {
ut, err = unix.Time(nil)
if err != nil {
t.Fatalf("Time: %v", err)
}
now = time.Now()
if int64(ut) == now.Unix() {
return
}
}
t.Errorf("Time: return value %v should be nearly equal to time.Now().Unix() %v", ut, now.Unix())
}
func TestUtime(t *testing.T) {
defer chtmpdir(t)()
touch(t, "file1")
buf := &unix.Utimbuf{
Modtime: 12345,
}
err := unix.Utime("file1", buf)
if err != nil {
t.Fatalf("Utime: %v", err)
}
fi, err := os.Stat("file1")
if err != nil {
t.Fatal(err)
}
if fi.ModTime().Unix() != 12345 {
t.Errorf("Utime: failed to change modtime: expected %v, got %v", 12345, fi.ModTime().Unix())
}
}
func TestUtimesNanoAt(t *testing.T) {
defer chtmpdir(t)()
symlink := "symlink1"
os.Remove(symlink)
err := os.Symlink("nonexisting", symlink)
if err != nil {
t.Fatal(err)
}
ts := []unix.Timespec{
{Sec: 1111, Nsec: 2222},
{Sec: 3333, Nsec: 4444},
}
err = unix.UtimesNanoAt(unix.AT_FDCWD, symlink, ts, unix.AT_SYMLINK_NOFOLLOW)
if err != nil {
t.Fatalf("UtimesNanoAt: %v", err)
}
var st unix.Stat_t
err = unix.Lstat(symlink, &st)
if err != nil {
t.Fatalf("Lstat: %v", err)
}
// Only check Mtim, Atim might not be supported by the underlying filesystem
expected := ts[1]
if st.Mtim.Nsec == 0 {
// Some filesystems only support 1-second time stamp resolution
// and will always set Nsec to 0.
expected.Nsec = 0
}
if st.Mtim != expected {
t.Errorf("UtimesNanoAt: wrong mtime: expected %v, got %v", expected, st.Mtim)
}
}
func TestRlimitAs(t *testing.T) {
// disable GC during to avoid flaky test
defer debug.SetGCPercent(debug.SetGCPercent(-1))
var rlim unix.Rlimit
err := unix.Getrlimit(unix.RLIMIT_AS, &rlim)
if err != nil {
t.Fatalf("Getrlimit: %v", err)
}
var zero unix.Rlimit
if zero == rlim {
t.Fatalf("Getrlimit: got zero value %#v", rlim)
}
set := rlim
set.Cur = uint64(unix.Getpagesize())
err = unix.Setrlimit(unix.RLIMIT_AS, &set)
if err != nil {
t.Fatalf("Setrlimit: set failed: %#v %v", set, err)
}
// RLIMIT_AS was set to the page size, so mmap()'ing twice the page size
// should fail. See 'man 2 getrlimit'.
_, err = unix.Mmap(-1, 0, 2*unix.Getpagesize(), unix.PROT_NONE, unix.MAP_ANON|unix.MAP_PRIVATE)
if err == nil {
t.Fatal("Mmap: unexpectedly suceeded after setting RLIMIT_AS")
}
err = unix.Setrlimit(unix.RLIMIT_AS, &rlim)
if err != nil {
t.Fatalf("Setrlimit: restore failed: %#v %v", rlim, err)
}
b, err := unix.Mmap(-1, 0, 2*unix.Getpagesize(), unix.PROT_NONE, unix.MAP_ANON|unix.MAP_PRIVATE)
if err != nil {
t.Fatalf("Mmap: %v", err)
}
err = unix.Munmap(b)
if err != nil {
t.Fatalf("Munmap: %v", err)
}
}
func TestSelect(t *testing.T) {
_, err := unix.Select(0, nil, nil, nil, &unix.Timeval{Sec: 0, Usec: 0})
if err != nil {
t.Fatalf("Select: %v", err)
}
dur := 150 * time.Millisecond
tv := unix.NsecToTimeval(int64(dur))
start := time.Now()
_, err = unix.Select(0, nil, nil, nil, &tv)
took := time.Since(start)
if err != nil {
t.Fatalf("Select: %v", err)
}
if took < dur {
t.Errorf("Select: timeout should have been at least %v, got %v", dur, took)
}
}
func TestPselect(t *testing.T) {
_, err := unix.Pselect(0, nil, nil, nil, &unix.Timespec{Sec: 0, Nsec: 0}, nil)
if err != nil {
t.Fatalf("Pselect: %v", err)
}
dur := 2500 * time.Microsecond
ts := unix.NsecToTimespec(int64(dur))
start := time.Now()
_, err = unix.Pselect(0, nil, nil, nil, &ts, nil)
took := time.Since(start)
if err != nil {
t.Fatalf("Pselect: %v", err)
}
if took < dur {
t.Errorf("Pselect: timeout should have been at least %v, got %v", dur, took)
}
}
func TestSchedSetaffinity(t *testing.T) {
runtime.LockOSThread()
defer runtime.UnlockOSThread()
var oldMask unix.CPUSet
err := unix.SchedGetaffinity(0, &oldMask)
if err != nil {
t.Fatalf("SchedGetaffinity: %v", err)
}
var newMask unix.CPUSet
newMask.Zero()
if newMask.Count() != 0 {
t.Errorf("CpuZero: didn't zero CPU set: %v", newMask)
}
cpu := 1
newMask.Set(cpu)
if newMask.Count() != 1 || !newMask.IsSet(cpu) {
t.Errorf("CpuSet: didn't set CPU %d in set: %v", cpu, newMask)
}
cpu = 5
newMask.Set(cpu)
if newMask.Count() != 2 || !newMask.IsSet(cpu) {
t.Errorf("CpuSet: didn't set CPU %d in set: %v", cpu, newMask)
}
newMask.Clear(cpu)
if newMask.Count() != 1 || newMask.IsSet(cpu) {
t.Errorf("CpuClr: didn't clear CPU %d in set: %v", cpu, newMask)
}
if runtime.NumCPU() < 2 {
t.Skip("skipping setaffinity tests on single CPU system")
}
if runtime.GOOS == "android" {
t.Skip("skipping setaffinity tests on android")
}
err = unix.SchedSetaffinity(0, &newMask)
if err != nil {
t.Fatalf("SchedSetaffinity: %v", err)
}
var gotMask unix.CPUSet
err = unix.SchedGetaffinity(0, &gotMask)
if err != nil {
t.Fatalf("SchedGetaffinity: %v", err)
}
if gotMask != newMask {
t.Errorf("SchedSetaffinity: returned affinity mask does not match set affinity mask")
}
// Restore old mask so it doesn't affect successive tests
err = unix.SchedSetaffinity(0, &oldMask)
if err != nil {
t.Fatalf("SchedSetaffinity: %v", err)
}
}
func TestStatx(t *testing.T) {
var stx unix.Statx_t
err := unix.Statx(unix.AT_FDCWD, ".", 0, 0, &stx)
if err == unix.ENOSYS || err == unix.EPERM {
t.Skip("statx syscall is not available, skipping test")
} else if err != nil {
t.Fatalf("Statx: %v", err)
}
defer chtmpdir(t)()
touch(t, "file1")
var st unix.Stat_t
err = unix.Stat("file1", &st)
if err != nil {
t.Fatalf("Stat: %v", err)
}
flags := unix.AT_STATX_SYNC_AS_STAT
err = unix.Statx(unix.AT_FDCWD, "file1", flags, unix.STATX_ALL, &stx)
if err != nil {
t.Fatalf("Statx: %v", err)
}
if uint32(stx.Mode) != st.Mode {
t.Errorf("Statx: returned stat mode does not match Stat")
}
ctime := unix.StatxTimestamp{Sec: int64(st.Ctim.Sec), Nsec: uint32(st.Ctim.Nsec)}
mtime := unix.StatxTimestamp{Sec: int64(st.Mtim.Sec), Nsec: uint32(st.Mtim.Nsec)}
if stx.Ctime != ctime {
t.Errorf("Statx: returned stat ctime does not match Stat")
}
if stx.Mtime != mtime {
t.Errorf("Statx: returned stat mtime does not match Stat")
}
err = os.Symlink("file1", "symlink1")
if err != nil {
t.Fatal(err)
}
err = unix.Lstat("symlink1", &st)
if err != nil {
t.Fatalf("Lstat: %v", err)
}
err = unix.Statx(unix.AT_FDCWD, "symlink1", flags, unix.STATX_BASIC_STATS, &stx)
if err != nil {
t.Fatalf("Statx: %v", err)
}
// follow symlink, expect a regulat file
if stx.Mode&unix.S_IFREG == 0 {
t.Errorf("Statx: didn't follow symlink")
}
err = unix.Statx(unix.AT_FDCWD, "symlink1", flags|unix.AT_SYMLINK_NOFOLLOW, unix.STATX_ALL, &stx)
if err != nil {
t.Fatalf("Statx: %v", err)
}
// follow symlink, expect a symlink
if stx.Mode&unix.S_IFLNK == 0 {
t.Errorf("Statx: unexpectedly followed symlink")
}
if uint32(stx.Mode) != st.Mode {
t.Errorf("Statx: returned stat mode does not match Lstat")
}
ctime = unix.StatxTimestamp{Sec: int64(st.Ctim.Sec), Nsec: uint32(st.Ctim.Nsec)}
mtime = unix.StatxTimestamp{Sec: int64(st.Mtim.Sec), Nsec: uint32(st.Mtim.Nsec)}
if stx.Ctime != ctime {
t.Errorf("Statx: returned stat ctime does not match Lstat")
}
if stx.Mtime != mtime {
t.Errorf("Statx: returned stat mtime does not match Lstat")
}
}
// stringsFromByteSlice converts a sequence of attributes to a []string.
// On Linux, each entry is a NULL-terminated string.
func stringsFromByteSlice(buf []byte) []string {
var result []string
off := 0
for i, b := range buf {
if b == 0 {
result = append(result, string(buf[off:i]))
off = i + 1
}
}
return result
}
func TestFaccessat(t *testing.T) {
defer chtmpdir(t)()
touch(t, "file1")
err := unix.Faccessat(unix.AT_FDCWD, "file1", unix.O_RDONLY, 0)
if err != nil {
t.Errorf("Faccessat: unexpected error: %v", err)
}
err = unix.Faccessat(unix.AT_FDCWD, "file1", unix.O_RDONLY, 2)
if err != unix.EINVAL {
t.Errorf("Faccessat: unexpected error: %v, want EINVAL", err)
}
err = unix.Faccessat(unix.AT_FDCWD, "file1", unix.O_RDONLY, unix.AT_EACCESS)
if err != unix.EOPNOTSUPP {
t.Errorf("Faccessat: unexpected error: %v, want EOPNOTSUPP", err)
}
err = os.Symlink("file1", "symlink1")
if err != nil {
t.Fatal(err)
}
err = unix.Faccessat(unix.AT_FDCWD, "symlink1", unix.O_RDONLY, unix.AT_SYMLINK_NOFOLLOW)
if err != unix.EOPNOTSUPP {
t.Errorf("Faccessat: unexpected error: %v, want EOPNOTSUPP", err)
}
}

View File

@ -1,55 +0,0 @@
// 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.
// +build solaris
package unix_test
import (
"os/exec"
"testing"
"time"
"golang.org/x/sys/unix"
)
func TestSelect(t *testing.T) {
err := unix.Select(0, nil, nil, nil, &unix.Timeval{Sec: 0, Usec: 0})
if err != nil {
t.Fatalf("Select: %v", err)
}
dur := 150 * time.Millisecond
tv := unix.NsecToTimeval(int64(dur))
start := time.Now()
err = unix.Select(0, nil, nil, nil, &tv)
took := time.Since(start)
if err != nil {
t.Fatalf("Select: %v", err)
}
if took < dur {
t.Errorf("Select: timeout should have been at least %v, got %v", dur, took)
}
}
func TestStatvfs(t *testing.T) {
if err := unix.Statvfs("", nil); err == nil {
t.Fatal(`Statvfs("") expected failure`)
}
statvfs := unix.Statvfs_t{}
if err := unix.Statvfs("/", &statvfs); err != nil {
t.Errorf(`Statvfs("/") failed: %v`, err)
}
if t.Failed() {
mount, err := exec.Command("mount").CombinedOutput()
if err != nil {
t.Logf("mount: %v\n%s", err, mount)
} else {
t.Logf("mount: %s", mount)
}
}
}

View File

@ -1,60 +0,0 @@
// Copyright 2013 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.
// +build darwin dragonfly freebsd linux netbsd openbsd solaris
package unix_test
import (
"fmt"
"testing"
"golang.org/x/sys/unix"
)
func testSetGetenv(t *testing.T, key, value string) {
err := unix.Setenv(key, value)
if err != nil {
t.Fatalf("Setenv failed to set %q: %v", value, err)
}
newvalue, found := unix.Getenv(key)
if !found {
t.Fatalf("Getenv failed to find %v variable (want value %q)", key, value)
}
if newvalue != value {
t.Fatalf("Getenv(%v) = %q; want %q", key, newvalue, value)
}
}
func TestEnv(t *testing.T) {
testSetGetenv(t, "TESTENV", "AVALUE")
// make sure TESTENV gets set to "", not deleted
testSetGetenv(t, "TESTENV", "")
}
func TestItoa(t *testing.T) {
// Make most negative integer: 0x8000...
i := 1
for i<<1 != 0 {
i <<= 1
}
if i >= 0 {
t.Fatal("bad math")
}
s := unix.Itoa(i)
f := fmt.Sprint(i)
if s != f {
t.Fatalf("itoa(%d) = %s, want %s", i, s, f)
}
}
func TestUname(t *testing.T) {
var utsname unix.Utsname
err := unix.Uname(&utsname)
if err != nil {
t.Fatalf("Uname: %v", err)
}
t.Logf("OS: %s/%s %s", utsname.Sysname[:], utsname.Machine[:], utsname.Release[:])
}

View File

@ -1,657 +0,0 @@
// Copyright 2013 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.
// +build darwin dragonfly freebsd linux netbsd openbsd solaris
package unix_test
import (
"flag"
"fmt"
"io/ioutil"
"net"
"os"
"os/exec"
"path/filepath"
"runtime"
"syscall"
"testing"
"time"
"golang.org/x/sys/unix"
)
// Tests that below functions, structures and constants are consistent
// on all Unix-like systems.
func _() {
// program scheduling priority functions and constants
var (
_ func(int, int, int) error = unix.Setpriority
_ func(int, int) (int, error) = unix.Getpriority
)
const (
_ int = unix.PRIO_USER
_ int = unix.PRIO_PROCESS
_ int = unix.PRIO_PGRP
)
// termios constants
const (
_ int = unix.TCIFLUSH
_ int = unix.TCIOFLUSH
_ int = unix.TCOFLUSH
)
// fcntl file locking structure and constants
var (
_ = unix.Flock_t{
Type: int16(0),
Whence: int16(0),
Start: int64(0),
Len: int64(0),
Pid: int32(0),
}
)
const (
_ = unix.F_GETLK
_ = unix.F_SETLK
_ = unix.F_SETLKW
)
}
func TestErrnoSignalName(t *testing.T) {
testErrors := []struct {
num syscall.Errno
name string
}{
{syscall.EPERM, "EPERM"},
{syscall.EINVAL, "EINVAL"},
{syscall.ENOENT, "ENOENT"},
}
for _, te := range testErrors {
t.Run(fmt.Sprintf("%d/%s", te.num, te.name), func(t *testing.T) {
e := unix.ErrnoName(te.num)
if e != te.name {
t.Errorf("ErrnoName(%d) returned %s, want %s", te.num, e, te.name)
}
})
}
testSignals := []struct {
num syscall.Signal
name string
}{
{syscall.SIGHUP, "SIGHUP"},
{syscall.SIGPIPE, "SIGPIPE"},
{syscall.SIGSEGV, "SIGSEGV"},
}
for _, ts := range testSignals {
t.Run(fmt.Sprintf("%d/%s", ts.num, ts.name), func(t *testing.T) {
s := unix.SignalName(ts.num)
if s != ts.name {
t.Errorf("SignalName(%d) returned %s, want %s", ts.num, s, ts.name)
}
})
}
}
func TestFcntlInt(t *testing.T) {
t.Parallel()
file, err := ioutil.TempFile("", "TestFnctlInt")
if err != nil {
t.Fatal(err)
}
defer os.Remove(file.Name())
defer file.Close()
f := file.Fd()
flags, err := unix.FcntlInt(f, unix.F_GETFD, 0)
if err != nil {
t.Fatal(err)
}
if flags&unix.FD_CLOEXEC == 0 {
t.Errorf("flags %#x do not include FD_CLOEXEC", flags)
}
}
// TestFcntlFlock tests whether the file locking structure matches
// the calling convention of each kernel.
func TestFcntlFlock(t *testing.T) {
name := filepath.Join(os.TempDir(), "TestFcntlFlock")
fd, err := unix.Open(name, unix.O_CREAT|unix.O_RDWR|unix.O_CLOEXEC, 0)
if err != nil {
t.Fatalf("Open failed: %v", err)
}
defer unix.Unlink(name)
defer unix.Close(fd)
flock := unix.Flock_t{
Type: unix.F_RDLCK,
Start: 0, Len: 0, Whence: 1,
}
if err := unix.FcntlFlock(uintptr(fd), unix.F_GETLK, &flock); err != nil {
t.Fatalf("FcntlFlock failed: %v", err)
}
}
// TestPassFD tests passing a file descriptor over a Unix socket.
//
// This test involved both a parent and child process. The parent
// process is invoked as a normal test, with "go test", which then
// runs the child process by running the current test binary with args
// "-test.run=^TestPassFD$" and an environment variable used to signal
// that the test should become the child process instead.
func TestPassFD(t *testing.T) {
if runtime.GOOS == "darwin" && (runtime.GOARCH == "arm" || runtime.GOARCH == "arm64") {
t.Skip("cannot exec subprocess on iOS, skipping test")
}
if os.Getenv("GO_WANT_HELPER_PROCESS") == "1" {
passFDChild()
return
}
tempDir, err := ioutil.TempDir("", "TestPassFD")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(tempDir)
fds, err := unix.Socketpair(unix.AF_LOCAL, unix.SOCK_STREAM, 0)
if err != nil {
t.Fatalf("Socketpair: %v", err)
}
defer unix.Close(fds[0])
defer unix.Close(fds[1])
writeFile := os.NewFile(uintptr(fds[0]), "child-writes")
readFile := os.NewFile(uintptr(fds[1]), "parent-reads")
defer writeFile.Close()
defer readFile.Close()
cmd := exec.Command(os.Args[0], "-test.run=^TestPassFD$", "--", tempDir)
cmd.Env = []string{"GO_WANT_HELPER_PROCESS=1"}
if lp := os.Getenv("LD_LIBRARY_PATH"); lp != "" {
cmd.Env = append(cmd.Env, "LD_LIBRARY_PATH="+lp)
}
cmd.ExtraFiles = []*os.File{writeFile}
out, err := cmd.CombinedOutput()
if len(out) > 0 || err != nil {
t.Fatalf("child process: %q, %v", out, err)
}
c, err := net.FileConn(readFile)
if err != nil {
t.Fatalf("FileConn: %v", err)
}
defer c.Close()
uc, ok := c.(*net.UnixConn)
if !ok {
t.Fatalf("unexpected FileConn type; expected UnixConn, got %T", c)
}
buf := make([]byte, 32) // expect 1 byte
oob := make([]byte, 32) // expect 24 bytes
closeUnix := time.AfterFunc(5*time.Second, func() {
t.Logf("timeout reading from unix socket")
uc.Close()
})
_, oobn, _, _, err := uc.ReadMsgUnix(buf, oob)
if err != nil {
t.Fatalf("ReadMsgUnix: %v", err)
}
closeUnix.Stop()
scms, err := unix.ParseSocketControlMessage(oob[:oobn])
if err != nil {
t.Fatalf("ParseSocketControlMessage: %v", err)
}
if len(scms) != 1 {
t.Fatalf("expected 1 SocketControlMessage; got scms = %#v", scms)
}
scm := scms[0]
gotFds, err := unix.ParseUnixRights(&scm)
if err != nil {
t.Fatalf("unix.ParseUnixRights: %v", err)
}
if len(gotFds) != 1 {
t.Fatalf("wanted 1 fd; got %#v", gotFds)
}
f := os.NewFile(uintptr(gotFds[0]), "fd-from-child")
defer f.Close()
got, err := ioutil.ReadAll(f)
want := "Hello from child process!\n"
if string(got) != want {
t.Errorf("child process ReadAll: %q, %v; want %q", got, err, want)
}
}
// passFDChild is the child process used by TestPassFD.
func passFDChild() {
defer os.Exit(0)
// Look for our fd. It should be fd 3, but we work around an fd leak
// bug here (http://golang.org/issue/2603) to let it be elsewhere.
var uc *net.UnixConn
for fd := uintptr(3); fd <= 10; fd++ {
f := os.NewFile(fd, "unix-conn")
var ok bool
netc, _ := net.FileConn(f)
uc, ok = netc.(*net.UnixConn)
if ok {
break
}
}
if uc == nil {
fmt.Println("failed to find unix fd")
return
}
// Make a file f to send to our parent process on uc.
// We make it in tempDir, which our parent will clean up.
flag.Parse()
tempDir := flag.Arg(0)
f, err := ioutil.TempFile(tempDir, "")
if err != nil {
fmt.Printf("TempFile: %v", err)
return
}
f.Write([]byte("Hello from child process!\n"))
f.Seek(0, 0)
rights := unix.UnixRights(int(f.Fd()))
dummyByte := []byte("x")
n, oobn, err := uc.WriteMsgUnix(dummyByte, rights, nil)
if err != nil {
fmt.Printf("WriteMsgUnix: %v", err)
return
}
if n != 1 || oobn != len(rights) {
fmt.Printf("WriteMsgUnix = %d, %d; want 1, %d", n, oobn, len(rights))
return
}
}
// TestUnixRightsRoundtrip tests that UnixRights, ParseSocketControlMessage,
// and ParseUnixRights are able to successfully round-trip lists of file descriptors.
func TestUnixRightsRoundtrip(t *testing.T) {
testCases := [...][][]int{
{{42}},
{{1, 2}},
{{3, 4, 5}},
{{}},
{{1, 2}, {3, 4, 5}, {}, {7}},
}
for _, testCase := range testCases {
b := []byte{}
var n int
for _, fds := range testCase {
// Last assignment to n wins
n = len(b) + unix.CmsgLen(4*len(fds))
b = append(b, unix.UnixRights(fds...)...)
}
// Truncate b
b = b[:n]
scms, err := unix.ParseSocketControlMessage(b)
if err != nil {
t.Fatalf("ParseSocketControlMessage: %v", err)
}
if len(scms) != len(testCase) {
t.Fatalf("expected %v SocketControlMessage; got scms = %#v", len(testCase), scms)
}
for i, scm := range scms {
gotFds, err := unix.ParseUnixRights(&scm)
if err != nil {
t.Fatalf("ParseUnixRights: %v", err)
}
wantFds := testCase[i]
if len(gotFds) != len(wantFds) {
t.Fatalf("expected %v fds, got %#v", len(wantFds), gotFds)
}
for j, fd := range gotFds {
if fd != wantFds[j] {
t.Fatalf("expected fd %v, got %v", wantFds[j], fd)
}
}
}
}
}
func TestRlimit(t *testing.T) {
var rlimit, zero unix.Rlimit
err := unix.Getrlimit(unix.RLIMIT_NOFILE, &rlimit)
if err != nil {
t.Fatalf("Getrlimit: save failed: %v", err)
}
if zero == rlimit {
t.Fatalf("Getrlimit: save failed: got zero value %#v", rlimit)
}
set := rlimit
set.Cur = set.Max - 1
err = unix.Setrlimit(unix.RLIMIT_NOFILE, &set)
if err != nil {
t.Fatalf("Setrlimit: set failed: %#v %v", set, err)
}
var get unix.Rlimit
err = unix.Getrlimit(unix.RLIMIT_NOFILE, &get)
if err != nil {
t.Fatalf("Getrlimit: get failed: %v", err)
}
set = rlimit
set.Cur = set.Max - 1
if set != get {
// Seems like Darwin requires some privilege to
// increase the soft limit of rlimit sandbox, though
// Setrlimit never reports an error.
switch runtime.GOOS {
case "darwin":
default:
t.Fatalf("Rlimit: change failed: wanted %#v got %#v", set, get)
}
}
err = unix.Setrlimit(unix.RLIMIT_NOFILE, &rlimit)
if err != nil {
t.Fatalf("Setrlimit: restore failed: %#v %v", rlimit, err)
}
}
func TestSeekFailure(t *testing.T) {
_, err := unix.Seek(-1, 0, 0)
if err == nil {
t.Fatalf("Seek(-1, 0, 0) did not fail")
}
str := err.Error() // used to crash on Linux
t.Logf("Seek: %v", str)
if str == "" {
t.Fatalf("Seek(-1, 0, 0) return error with empty message")
}
}
func TestDup(t *testing.T) {
file, err := ioutil.TempFile("", "TestDup")
if err != nil {
t.Fatalf("Tempfile failed: %v", err)
}
defer os.Remove(file.Name())
defer file.Close()
f := int(file.Fd())
newFd, err := unix.Dup(f)
if err != nil {
t.Fatalf("Dup: %v", err)
}
err = unix.Dup2(newFd, newFd+1)
if err != nil {
t.Fatalf("Dup2: %v", err)
}
b1 := []byte("Test123")
b2 := make([]byte, 7)
_, err = unix.Write(newFd+1, b1)
if err != nil {
t.Fatalf("Write to dup2 fd failed: %v", err)
}
_, err = unix.Seek(f, 0, 0)
if err != nil {
t.Fatalf("Seek failed: %v", err)
}
_, err = unix.Read(f, b2)
if err != nil {
t.Fatalf("Read back failed: %v", err)
}
if string(b1) != string(b2) {
t.Errorf("Dup: stdout write not in file, expected %v, got %v", string(b1), string(b2))
}
}
func TestPoll(t *testing.T) {
if runtime.GOOS == "android" ||
(runtime.GOOS == "darwin" && (runtime.GOARCH == "arm" || runtime.GOARCH == "arm64")) {
t.Skip("mkfifo syscall is not available on android and iOS, skipping test")
}
f, cleanup := mktmpfifo(t)
defer cleanup()
const timeout = 100
ok := make(chan bool, 1)
go func() {
select {
case <-time.After(10 * timeout * time.Millisecond):
t.Errorf("Poll: failed to timeout after %d milliseconds", 10*timeout)
case <-ok:
}
}()
fds := []unix.PollFd{{Fd: int32(f.Fd()), Events: unix.POLLIN}}
n, err := unix.Poll(fds, timeout)
ok <- true
if err != nil {
t.Errorf("Poll: unexpected error: %v", err)
return
}
if n != 0 {
t.Errorf("Poll: wrong number of events: got %v, expected %v", n, 0)
return
}
}
func TestGetwd(t *testing.T) {
fd, err := os.Open(".")
if err != nil {
t.Fatalf("Open .: %s", err)
}
defer fd.Close()
// These are chosen carefully not to be symlinks on a Mac
// (unlike, say, /var, /etc)
dirs := []string{"/", "/usr/bin"}
switch runtime.GOOS {
case "android":
dirs = []string{"/", "/system/bin"}
case "darwin":
switch runtime.GOARCH {
case "arm", "arm64":
d1, err := ioutil.TempDir("", "d1")
if err != nil {
t.Fatalf("TempDir: %v", err)
}
d2, err := ioutil.TempDir("", "d2")
if err != nil {
t.Fatalf("TempDir: %v", err)
}
dirs = []string{d1, d2}
}
}
oldwd := os.Getenv("PWD")
for _, d := range dirs {
err = os.Chdir(d)
if err != nil {
t.Fatalf("Chdir: %v", err)
}
pwd, err := unix.Getwd()
if err != nil {
t.Fatalf("Getwd in %s: %s", d, err)
}
os.Setenv("PWD", oldwd)
err = fd.Chdir()
if err != nil {
// We changed the current directory and cannot go back.
// Don't let the tests continue; they'll scribble
// all over some other directory.
fmt.Fprintf(os.Stderr, "fchdir back to dot failed: %s\n", err)
os.Exit(1)
}
if pwd != d {
t.Fatalf("Getwd returned %q want %q", pwd, d)
}
}
}
func TestFstatat(t *testing.T) {
defer chtmpdir(t)()
touch(t, "file1")
var st1 unix.Stat_t
err := unix.Stat("file1", &st1)
if err != nil {
t.Fatalf("Stat: %v", err)
}
var st2 unix.Stat_t
err = unix.Fstatat(unix.AT_FDCWD, "file1", &st2, 0)
if err != nil {
t.Fatalf("Fstatat: %v", err)
}
if st1 != st2 {
t.Errorf("Fstatat: returned stat does not match Stat")
}
err = os.Symlink("file1", "symlink1")
if err != nil {
t.Fatal(err)
}
err = unix.Lstat("symlink1", &st1)
if err != nil {
t.Fatalf("Lstat: %v", err)
}
err = unix.Fstatat(unix.AT_FDCWD, "symlink1", &st2, unix.AT_SYMLINK_NOFOLLOW)
if err != nil {
t.Fatalf("Fstatat: %v", err)
}
if st1 != st2 {
t.Errorf("Fstatat: returned stat does not match Lstat")
}
}
func TestFchmodat(t *testing.T) {
defer chtmpdir(t)()
touch(t, "file1")
err := os.Symlink("file1", "symlink1")
if err != nil {
t.Fatal(err)
}
mode := os.FileMode(0444)
err = unix.Fchmodat(unix.AT_FDCWD, "symlink1", uint32(mode), 0)
if err != nil {
t.Fatalf("Fchmodat: unexpected error: %v", err)
}
fi, err := os.Stat("file1")
if err != nil {
t.Fatal(err)
}
if fi.Mode() != mode {
t.Errorf("Fchmodat: failed to change file mode: expected %v, got %v", mode, fi.Mode())
}
mode = os.FileMode(0644)
didChmodSymlink := true
err = unix.Fchmodat(unix.AT_FDCWD, "symlink1", uint32(mode), unix.AT_SYMLINK_NOFOLLOW)
if err != nil {
if (runtime.GOOS == "android" || runtime.GOOS == "linux" || runtime.GOOS == "solaris") && err == unix.EOPNOTSUPP {
// Linux and Illumos don't support flags != 0
didChmodSymlink = false
} else {
t.Fatalf("Fchmodat: unexpected error: %v", err)
}
}
if !didChmodSymlink {
// Didn't change mode of the symlink. On Linux, the permissions
// of a symbolic link are always 0777 according to symlink(7)
mode = os.FileMode(0777)
}
var st unix.Stat_t
err = unix.Lstat("symlink1", &st)
if err != nil {
t.Fatal(err)
}
got := os.FileMode(st.Mode & 0777)
if got != mode {
t.Errorf("Fchmodat: failed to change symlink mode: expected %v, got %v", mode, got)
}
}
func TestMkdev(t *testing.T) {
major := uint32(42)
minor := uint32(7)
dev := unix.Mkdev(major, minor)
if unix.Major(dev) != major {
t.Errorf("Major(%#x) == %d, want %d", dev, unix.Major(dev), major)
}
if unix.Minor(dev) != minor {
t.Errorf("Minor(%#x) == %d, want %d", dev, unix.Minor(dev), minor)
}
}
// mktmpfifo creates a temporary FIFO and provides a cleanup function.
func mktmpfifo(t *testing.T) (*os.File, func()) {
err := unix.Mkfifo("fifo", 0666)
if err != nil {
t.Fatalf("mktmpfifo: failed to create FIFO: %v", err)
}
f, err := os.OpenFile("fifo", os.O_RDWR, 0666)
if err != nil {
os.Remove("fifo")
t.Fatalf("mktmpfifo: failed to open FIFO: %v", err)
}
return f, func() {
f.Close()
os.Remove("fifo")
}
}
// utilities taken from os/os_test.go
func touch(t *testing.T, name string) {
f, err := os.Create(name)
if err != nil {
t.Fatal(err)
}
if err := f.Close(); err != nil {
t.Fatal(err)
}
}
// chtmpdir changes the working directory to a new temporary directory and
// provides a cleanup function. Used when PWD is read-only.
func chtmpdir(t *testing.T) func() {
oldwd, err := os.Getwd()
if err != nil {
t.Fatalf("chtmpdir: %v", err)
}
d, err := ioutil.TempDir("", "test")
if err != nil {
t.Fatalf("chtmpdir: %v", err)
}
if err := os.Chdir(d); err != nil {
t.Fatalf("chtmpdir: %v", err)
}
return func() {
if err := os.Chdir(oldwd); err != nil {
t.Fatalf("chtmpdir: %v", err)
}
os.RemoveAll(d)
}
}

View File

@ -1,54 +0,0 @@
// Copyright 2017 The Go Authors. All right reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build darwin dragonfly freebsd linux netbsd openbsd solaris
package unix_test
import (
"testing"
"time"
"unsafe"
"golang.org/x/sys/unix"
)
func TestTimeToTimespec(t *testing.T) {
timeTests := []struct {
time time.Time
valid bool
}{
{time.Unix(0, 0), true},
{time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC), true},
{time.Date(2262, time.December, 31, 23, 0, 0, 0, time.UTC), false},
{time.Unix(0x7FFFFFFF, 0), true},
{time.Unix(0x80000000, 0), false},
{time.Unix(0x7FFFFFFF, 1000000000), false},
{time.Unix(0x7FFFFFFF, 999999999), true},
{time.Unix(-0x80000000, 0), true},
{time.Unix(-0x80000001, 0), false},
{time.Date(2038, time.January, 19, 3, 14, 7, 0, time.UTC), true},
{time.Date(2038, time.January, 19, 3, 14, 8, 0, time.UTC), false},
{time.Date(1901, time.December, 13, 20, 45, 52, 0, time.UTC), true},
{time.Date(1901, time.December, 13, 20, 45, 51, 0, time.UTC), false},
}
// Currently all targets have either int32 or int64 for Timespec.Sec.
// If there were a new target with unsigned or floating point type for
// it, this test must be adjusted.
have64BitTime := (unsafe.Sizeof(unix.Timespec{}.Sec) == 8)
for _, tt := range timeTests {
ts, err := unix.TimeToTimespec(tt.time)
tt.valid = tt.valid || have64BitTime
if tt.valid && err != nil {
t.Errorf("TimeToTimespec(%v): %v", tt.time, err)
}
if err == nil {
tstime := time.Unix(int64(ts.Sec), int64(ts.Nsec))
if !tstime.Equal(tt.time) {
t.Errorf("TimeToTimespec(%v) is the time %v", tt.time, tstime)
}
}
}
}

View File

@ -1,119 +0,0 @@
// Copyright 2018 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.
// +build darwin freebsd linux
package unix_test
import (
"os"
"runtime"
"strings"
"testing"
"golang.org/x/sys/unix"
)
func TestXattr(t *testing.T) {
defer chtmpdir(t)()
f := "xattr1"
touch(t, f)
xattrName := "user.test"
xattrDataSet := "gopher"
err := unix.Setxattr(f, xattrName, []byte(xattrDataSet), 0)
if err == unix.ENOTSUP || err == unix.EOPNOTSUPP {
t.Skip("filesystem does not support extended attributes, skipping test")
} else if err != nil {
t.Fatalf("Setxattr: %v", err)
}
// find size
size, err := unix.Listxattr(f, nil)
if err != nil {
t.Fatalf("Listxattr: %v", err)
}
if size <= 0 {
t.Fatalf("Listxattr returned an empty list of attributes")
}
buf := make([]byte, size)
read, err := unix.Listxattr(f, buf)
if err != nil {
t.Fatalf("Listxattr: %v", err)
}
xattrs := stringsFromByteSlice(buf[:read])
xattrWant := xattrName
if runtime.GOOS == "freebsd" {
// On FreeBSD, the namespace is stored separately from the xattr
// name and Listxattr doesn't return the namespace prefix.
xattrWant = strings.TrimPrefix(xattrWant, "user.")
}
found := false
for _, name := range xattrs {
if name == xattrWant {
found = true
}
}
if !found {
t.Errorf("Listxattr did not return previously set attribute '%s'", xattrName)
}
// find size
size, err = unix.Getxattr(f, xattrName, nil)
if err != nil {
t.Fatalf("Getxattr: %v", err)
}
if size <= 0 {
t.Fatalf("Getxattr returned an empty attribute")
}
xattrDataGet := make([]byte, size)
_, err = unix.Getxattr(f, xattrName, xattrDataGet)
if err != nil {
t.Fatalf("Getxattr: %v", err)
}
got := string(xattrDataGet)
if got != xattrDataSet {
t.Errorf("Getxattr: expected attribute value %s, got %s", xattrDataSet, got)
}
err = unix.Removexattr(f, xattrName)
if err != nil {
t.Fatalf("Removexattr: %v", err)
}
n := "nonexistent"
err = unix.Lsetxattr(n, xattrName, []byte(xattrDataSet), 0)
if err != unix.ENOENT {
t.Errorf("Lsetxattr: expected %v on non-existent file, got %v", unix.ENOENT, err)
}
_, err = unix.Lgetxattr(n, xattrName, nil)
if err != unix.ENOENT {
t.Errorf("Lgetxattr: %v", err)
}
s := "symlink1"
err = os.Symlink(n, s)
if err != nil {
t.Fatal(err)
}
err = unix.Lsetxattr(s, xattrName, []byte(xattrDataSet), 0)
if err != nil {
// Linux and Android doen't support xattrs on symlinks according
// to xattr(7), so just test that we get the proper error.
if (runtime.GOOS != "linux" && runtime.GOOS != "android") || err != unix.EPERM {
t.Fatalf("Lsetxattr: %v", err)
}
}
}