diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-05-02 14:43:35 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-05-02 14:43:35 +0000 |
commit | 34efdaf078b01a7387007c4e6bde6db86384c4b7 (patch) | |
tree | d503eaf41d085669d1481bb46ec038bc866fece6 /libgo/go/syscall | |
parent | f733cf303bcdc952c92b81dd62199a40a1f555ec (diff) | |
download | gcc-tarball-master.tar.gz |
gcc-7.1.0gcc-7.1.0
Diffstat (limited to 'libgo/go/syscall')
75 files changed, 886 insertions, 654 deletions
diff --git a/libgo/go/syscall/bpf_bsd.go b/libgo/go/syscall/bpf_bsd.go index cc6c1e77c5..8b587559ed 100644 --- a/libgo/go/syscall/bpf_bsd.go +++ b/libgo/go/syscall/bpf_bsd.go @@ -1,4 +1,4 @@ -// Copyright 2011 The Go Authors. All rights reserved. +// Copyright 2011 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. @@ -12,14 +12,17 @@ import ( "unsafe" ) +// Deprecated: Use golang.org/x/net/bpf instead. func BpfStmt(code, k int) *BpfInsn { return &BpfInsn{Code: uint16(code), K: uint32(k)} } +// Deprecated: Use golang.org/x/net/bpf instead. func BpfJump(code, k, jt, jf int) *BpfInsn { return &BpfInsn{Code: uint16(code), Jt: uint8(jt), Jf: uint8(jf), K: uint32(k)} } +// Deprecated: Use golang.org/x/net/bpf instead. func BpfBuflen(fd int) (int, error) { var l int _, _, err := Syscall(SYS_IOCTL, uintptr(fd), BIOCGBLEN, uintptr(unsafe.Pointer(&l))) @@ -29,6 +32,7 @@ func BpfBuflen(fd int) (int, error) { return l, nil } +// Deprecated: Use golang.org/x/net/bpf instead. func SetBpfBuflen(fd, l int) (int, error) { _, _, err := Syscall(SYS_IOCTL, uintptr(fd), BIOCSBLEN, uintptr(unsafe.Pointer(&l))) if err != 0 { @@ -37,6 +41,7 @@ func SetBpfBuflen(fd, l int) (int, error) { return l, nil } +// Deprecated: Use golang.org/x/net/bpf instead. func BpfDatalink(fd int) (int, error) { var t int _, _, err := Syscall(SYS_IOCTL, uintptr(fd), BIOCGDLT, uintptr(unsafe.Pointer(&t))) @@ -46,6 +51,7 @@ func BpfDatalink(fd int) (int, error) { return t, nil } +// Deprecated: Use golang.org/x/net/bpf instead. func SetBpfDatalink(fd, t int) (int, error) { _, _, err := Syscall(SYS_IOCTL, uintptr(fd), BIOCSDLT, uintptr(unsafe.Pointer(&t))) if err != 0 { @@ -54,6 +60,7 @@ func SetBpfDatalink(fd, t int) (int, error) { return t, nil } +// Deprecated: Use golang.org/x/net/bpf instead. func SetBpfPromisc(fd, m int) error { _, _, err := Syscall(SYS_IOCTL, uintptr(fd), BIOCPROMISC, uintptr(unsafe.Pointer(&m))) if err != 0 { @@ -62,6 +69,7 @@ func SetBpfPromisc(fd, m int) error { return nil } +// Deprecated: Use golang.org/x/net/bpf instead. func FlushBpf(fd int) error { _, _, err := Syscall(SYS_IOCTL, uintptr(fd), BIOCFLUSH, 0) if err != 0 { @@ -75,6 +83,7 @@ type ivalue struct { value int16 } +// Deprecated: Use golang.org/x/net/bpf instead. func BpfInterface(fd int, name string) (string, error) { var iv ivalue _, _, err := Syscall(SYS_IOCTL, uintptr(fd), BIOCGETIF, uintptr(unsafe.Pointer(&iv))) @@ -84,6 +93,7 @@ func BpfInterface(fd int, name string) (string, error) { return name, nil } +// Deprecated: Use golang.org/x/net/bpf instead. func SetBpfInterface(fd int, name string) error { var iv ivalue copy(iv.name[:], []byte(name)) @@ -94,6 +104,7 @@ func SetBpfInterface(fd int, name string) error { return nil } +// Deprecated: Use golang.org/x/net/bpf instead. func BpfTimeout(fd int) (*Timeval, error) { var tv Timeval _, _, err := Syscall(SYS_IOCTL, uintptr(fd), BIOCGRTIMEOUT, uintptr(unsafe.Pointer(&tv))) @@ -103,6 +114,7 @@ func BpfTimeout(fd int) (*Timeval, error) { return &tv, nil } +// Deprecated: Use golang.org/x/net/bpf instead. func SetBpfTimeout(fd int, tv *Timeval) error { _, _, err := Syscall(SYS_IOCTL, uintptr(fd), BIOCSRTIMEOUT, uintptr(unsafe.Pointer(tv))) if err != 0 { @@ -111,6 +123,7 @@ func SetBpfTimeout(fd int, tv *Timeval) error { return nil } +// Deprecated: Use golang.org/x/net/bpf instead. func BpfStats(fd int) (*BpfStat, error) { var s BpfStat _, _, err := Syscall(SYS_IOCTL, uintptr(fd), BIOCGSTATS, uintptr(unsafe.Pointer(&s))) @@ -120,6 +133,7 @@ func BpfStats(fd int) (*BpfStat, error) { return &s, nil } +// Deprecated: Use golang.org/x/net/bpf instead. func SetBpfImmediate(fd, m int) error { _, _, err := Syscall(SYS_IOCTL, uintptr(fd), BIOCIMMEDIATE, uintptr(unsafe.Pointer(&m))) if err != 0 { @@ -128,6 +142,7 @@ func SetBpfImmediate(fd, m int) error { return nil } +// Deprecated: Use golang.org/x/net/bpf instead. func SetBpf(fd int, i []BpfInsn) error { var p BpfProgram p.Len = uint32(len(i)) @@ -139,6 +154,7 @@ func SetBpf(fd int, i []BpfInsn) error { return nil } +// Deprecated: Use golang.org/x/net/bpf instead. func CheckBpfVersion(fd int) error { var v BpfVersion _, _, err := Syscall(SYS_IOCTL, uintptr(fd), BIOCVERSION, uintptr(unsafe.Pointer(&v))) @@ -151,6 +167,7 @@ func CheckBpfVersion(fd int) error { return nil } +// Deprecated: Use golang.org/x/net/bpf instead. func BpfHeadercmpl(fd int) (int, error) { var f int _, _, err := Syscall(SYS_IOCTL, uintptr(fd), BIOCGHDRCMPLT, uintptr(unsafe.Pointer(&f))) @@ -160,6 +177,7 @@ func BpfHeadercmpl(fd int) (int, error) { return f, nil } +// Deprecated: Use golang.org/x/net/bpf instead. func SetBpfHeadercmpl(fd, f int) error { _, _, err := Syscall(SYS_IOCTL, uintptr(fd), BIOCSHDRCMPLT, uintptr(unsafe.Pointer(&f))) if err != 0 { diff --git a/libgo/go/syscall/clone_linux.c b/libgo/go/syscall/clone_linux.c new file mode 100644 index 0000000000..30753e6269 --- /dev/null +++ b/libgo/go/syscall/clone_linux.c @@ -0,0 +1,102 @@ +/* clone_linux.c -- consistent wrapper around Linux clone syscall + + 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. */ + +#include <errno.h> +#include <sys/syscall.h> + +#include "runtime.h" + +long rawClone (unsigned long flags, void *child_stack, void *ptid, + void *ctid, void *regs) + __asm__ (GOSYM_PREFIX "syscall.rawClone") + __attribute__ ((no_split_stack)); + +long +rawClone (unsigned long flags, void *child_stack, void *ptid, void *ctid, void *regs) +{ +#if defined(__arc__) || defined(__aarch64__) || defined(__arm__) || defined(__mips__) || defined(__hppa__) || defined(__powerpc__) || defined(__score__) || defined(__i386__) || defined(__xtensa__) + // CLONE_BACKWARDS + return syscall(__NR_clone, flags, child_stack, ptid, regs, ctid); +#elif defined(__s390__) || defined(__cris__) + // CLONE_BACKWARDS2 + return syscall(__NR_clone, child_stack, flags, ptid, ctid, regs); +#elif defined(__microblaze__) + // CLONE_BACKWARDS3 + return syscall(__NR_clone, flags, child_stack, 0, ptid, ctid, regs); +#elif defined(__sparc__) + + /* SPARC has a unique return value convention: + + Parent --> %o0 == child's pid, %o1 == 0 + Child --> %o0 == parent's pid, %o1 == 1 + + Translate this to look like a normal clone. */ + +# if defined(__arch64__) + +# define SYSCALL_STRING \ + "ta 0x6d;" \ + "bcc,pt %%xcc, 1f;" \ + " mov 0, %%g1;" \ + "sub %%g0, %%o0, %%o0;" \ + "mov 1, %%g1;" \ + "1:" + +# define SYSCALL_CLOBBERS \ + "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \ + "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \ + "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", \ + "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", \ + "f32", "f34", "f36", "f38", "f40", "f42", "f44", "f46", \ + "f48", "f50", "f52", "f54", "f56", "f58", "f60", "f62", \ + "cc", "memory" + +# else /* __arch64__ */ + +# define SYSCALL_STRING \ + "ta 0x10;" \ + "bcc 1f;" \ + " mov 0, %%g1;" \ + "sub %%g0, %%o0, %%o0;" \ + "mov 1, %%g1;" \ + "1:" + +# define SYSCALL_CLOBBERS \ + "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \ + "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \ + "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", \ + "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", \ + "cc", "memory" + +# endif /* __arch64__ */ + + register long o0 __asm__ ("o0") = (long)flags; + register long o1 __asm__ ("o1") = (long)child_stack; + register long o2 __asm__ ("o2") = (long)ptid; + register long o3 __asm__ ("o3") = (long)ctid; + register long o4 __asm__ ("o4") = (long)regs; + register long g1 __asm__ ("g1") = __NR_clone; + + __asm __volatile (SYSCALL_STRING : + "=r" (g1), "=r" (o0), "=r" (o1) : + "0" (g1), "1" (o0), "2" (o1), + "r" (o2), "r" (o3), "r" (o4) : + SYSCALL_CLOBBERS); + + if (__builtin_expect(g1 != 0, 0)) + { + errno = -o0; + o0 = -1L; + } + else + o0 &= (o1 - 1); + + return o0; + +#else + return syscall(__NR_clone, flags, child_stack, ptid, ctid, regs); +#endif +} diff --git a/libgo/go/syscall/const_plan9.go b/libgo/go/syscall/const_plan9.go index ba26f123de..063d5dfd7c 100644 --- a/libgo/go/syscall/const_plan9.go +++ b/libgo/go/syscall/const_plan9.go @@ -12,6 +12,17 @@ const ( O_EXCL = 0x1000 ) +// Bind flags +const ( + MORDER = 0x0003 // mask for bits defining order of mounting + MREPL = 0x0000 // mount replaces object + MBEFORE = 0x0001 // mount goes before others in union directory + MAFTER = 0x0002 // mount goes after others in union directory + MCREATE = 0x0004 // permit creation in mounted directory + MCACHE = 0x0010 // cache some data + MMASK = 0x0017 // all bits on +) + // Rfork flags const ( RFNAMEG = 1 << 0 diff --git a/libgo/go/syscall/creds_test.go b/libgo/go/syscall/creds_test.go index b4a14ff4dd..7c6ab1de1d 100644 --- a/libgo/go/syscall/creds_test.go +++ b/libgo/go/syscall/creds_test.go @@ -1,4 +1,4 @@ -// Copyright 2012 The Go Authors. All rights reserved. +// 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. diff --git a/libgo/go/syscall/dir_plan9.go b/libgo/go/syscall/dir_plan9.go index 697bf5499c..4ed052de76 100644 --- a/libgo/go/syscall/dir_plan9.go +++ b/libgo/go/syscall/dir_plan9.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// Plan 9 directory marshalling. See intro(5). +// Plan 9 directory marshaling. See intro(5). package syscall @@ -184,6 +184,7 @@ func gbit8(b []byte) (uint8, []byte) { } // gbit16 reads a 16-bit number in little-endian order from b and returns it with the remaining slice of b. +//go:nosplit func gbit16(b []byte) (uint16, []byte) { return uint16(b[0]) | uint16(b[1])<<8, b[2:] } diff --git a/libgo/go/syscall/dirent.go b/libgo/go/syscall/dirent.go new file mode 100644 index 0000000000..4db2d4355b --- /dev/null +++ b/libgo/go/syscall/dirent.go @@ -0,0 +1,102 @@ +// Copyright 2009 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 nacl netbsd openbsd solaris + +package syscall + +import "unsafe" + +// readInt returns the size-bytes unsigned integer in native byte order at offset off. +func readInt(b []byte, off, size uintptr) (u uint64, ok bool) { + if len(b) < int(off+size) { + return 0, false + } + if isBigEndian { + return readIntBE(b[off:], size), true + } + return readIntLE(b[off:], size), true +} + +func readIntBE(b []byte, size uintptr) uint64 { + switch size { + case 1: + return uint64(b[0]) + case 2: + _ = b[1] // bounds check hint to compiler; see golang.org/issue/14808 + return uint64(b[1]) | uint64(b[0])<<8 + case 4: + _ = b[3] // bounds check hint to compiler; see golang.org/issue/14808 + return uint64(b[3]) | uint64(b[2])<<8 | uint64(b[1])<<16 | uint64(b[0])<<24 + case 8: + _ = b[7] // bounds check hint to compiler; see golang.org/issue/14808 + return uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 | + uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56 + default: + panic("syscall: readInt with unsupported size") + } +} + +func readIntLE(b []byte, size uintptr) uint64 { + switch size { + case 1: + return uint64(b[0]) + case 2: + _ = b[1] // bounds check hint to compiler; see golang.org/issue/14808 + return uint64(b[0]) | uint64(b[1])<<8 + case 4: + _ = b[3] // bounds check hint to compiler; see golang.org/issue/14808 + return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 + case 8: + _ = b[7] // bounds check hint to compiler; see golang.org/issue/14808 + return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | + uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56 + default: + panic("syscall: readInt with unsupported size") + } +} + +// ParseDirent parses up to max directory entries in buf, +// appending the names to names. It returns the number of +// bytes consumed from buf, the number of entries added +// to names, and the new names slice. +func ParseDirent(buf []byte, max int, names []string) (consumed int, count int, newnames []string) { + origlen := len(buf) + count = 0 + for max != 0 && len(buf) > 0 { + reclen, ok := direntReclen(buf) + if !ok || reclen > uint64(len(buf)) { + return origlen, count, names + } + rec := buf[:reclen] + buf = buf[reclen:] + ino, ok := direntIno(rec) + if !ok { + break + } + if ino == 0 { // File absent in directory. + continue + } + const namoff = uint64(unsafe.Offsetof(Dirent{}.Name)) + namlen, ok := direntNamlen(rec) + if !ok || namoff+namlen > uint64(len(rec)) { + break + } + name := rec[namoff : namoff+namlen] + for i, c := range name { + if c == 0 { + name = name[:i] + break + } + } + // Check for useless names before allocating a string. + if string(name) == "." || string(name) == ".." { + continue + } + max-- + count++ + names = append(names, string(name)) + } + return origlen - len(buf), count, names +} diff --git a/libgo/go/syscall/endian_big.go b/libgo/go/syscall/endian_big.go new file mode 100644 index 0000000000..b96594ec28 --- /dev/null +++ b/libgo/go/syscall/endian_big.go @@ -0,0 +1,9 @@ +// 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 ppc64 s390x mips mips64 armbe arm64be m68k ppc mipso32 mipsn32 mipso64 mipsn64 mips64p32 s390 sparc sparc64 + +package syscall + +const isBigEndian = true diff --git a/libgo/go/syscall/endian_little.go b/libgo/go/syscall/endian_little.go new file mode 100644 index 0000000000..b6c9ed0f9f --- /dev/null +++ b/libgo/go/syscall/endian_little.go @@ -0,0 +1,9 @@ +// 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 386 amd64 amd64p32 arm arm64 ppc64le mips64le mipsle alpha ia64 mips64p32le + +package syscall + +const isBigEndian = false diff --git a/libgo/go/syscall/env_plan9.go b/libgo/go/syscall/env_plan9.go index cbf7f41092..9a8a837e7d 100644 --- a/libgo/go/syscall/env_plan9.go +++ b/libgo/go/syscall/env_plan9.go @@ -1,4 +1,4 @@ -// Copyright 2011 The Go Authors. All rights reserved. +// Copyright 2011 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. diff --git a/libgo/go/syscall/env_unix.go b/libgo/go/syscall/env_unix.go index b5ded9c763..5bf3336ce5 100644 --- a/libgo/go/syscall/env_unix.go +++ b/libgo/go/syscall/env_unix.go @@ -1,4 +1,4 @@ -// Copyright 2010 The Go Authors. All rights reserved. +// Copyright 2010 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. diff --git a/libgo/go/syscall/env_windows.go b/libgo/go/syscall/env_windows.go index 1cb475428d..1606b424ca 100644 --- a/libgo/go/syscall/env_windows.go +++ b/libgo/go/syscall/env_windows.go @@ -1,4 +1,4 @@ -// Copyright 2010 The Go Authors. All rights reserved. +// Copyright 2010 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. @@ -60,7 +60,7 @@ func Clearenv() { // http://blogs.msdn.com/b/oldnewthing/archive/2010/05/06/10008132.aspx for j := 1; j < len(s); j++ { if s[j] == '=' { - Setenv(s[0:j], "") + Unsetenv(s[0:j]) break } } diff --git a/libgo/go/syscall/errors_plan9.go b/libgo/go/syscall/errors_plan9.go index d7634c995e..6952562c69 100644 --- a/libgo/go/syscall/errors_plan9.go +++ b/libgo/go/syscall/errors_plan9.go @@ -1,4 +1,4 @@ -// Copyright 2011 The Go Authors. All rights reserved. +// Copyright 2011 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. diff --git a/libgo/go/syscall/errstr.go b/libgo/go/syscall/errstr.go index aa656ca7cb..25b0063e76 100644 --- a/libgo/go/syscall/errstr.go +++ b/libgo/go/syscall/errstr.go @@ -4,6 +4,8 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +// +build !linux + package syscall //sysnb strerror_r(errnum int, buf []byte) (err Errno) diff --git a/libgo/go/syscall/errstr_linux.go b/libgo/go/syscall/errstr_linux.go index d10476d3cb..7156b790da 100644 --- a/libgo/go/syscall/errstr_linux.go +++ b/libgo/go/syscall/errstr_linux.go @@ -1,9 +1,12 @@ -// errstr_rtems.go -- RTEMS specific error strings. +// errstr_linux.go -- GNU/Linux specific error strings. // Copyright 2010 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. +// We use this rather than errstr.go because on GNU/Linux sterror_r +// returns a pointer to the error message, and may not use buf at all. + package syscall import "unsafe" diff --git a/libgo/go/syscall/errstr_nor.go b/libgo/go/syscall/errstr_nor.go deleted file mode 100644 index 796561adda..0000000000 --- a/libgo/go/syscall/errstr_nor.go +++ /dev/null @@ -1,41 +0,0 @@ -// errstr.go -- Error strings when there is no strerror_r. - -// Copyright 2011 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 syscall - -import ( - "sync" - "unsafe" -) - -//sysnb strerror(errnum int) (buf *byte) -//strerror(errnum _C_int) *byte - -var errstr_lock sync.Mutex - -func Errstr(errno int) string { - errstr_lock.Lock() - - bp := strerror(errno) - b := (*[1000]byte)(unsafe.Pointer(bp)) - i := 0 - for b[i] != 0 { - i++ - } - - // Lowercase first letter: Bad -> bad, but STREAM -> STREAM. - var s string - if i > 1 && 'A' <= b[0] && b[0] <= 'Z' && 'a' <= b[1] && b[1] <= 'z' { - c := b[0] + 'a' - 'A' - s = string(c) + string(b[1:i]) - } else { - s = string(b[:i]) - } - - errstr_lock.Unlock() - - return s -} diff --git a/libgo/go/syscall/exec_bsd.go b/libgo/go/syscall/exec_bsd.go index 75126730f5..af025e4c04 100644 --- a/libgo/go/syscall/exec_bsd.go +++ b/libgo/go/syscall/exec_bsd.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build darwin dragonfly freebsd netbsd openbsd +// +build darwin dragonfly freebsd netbsd openbsd solaris package syscall @@ -31,7 +31,7 @@ func runtime_AfterFork() // If a dup or exec fails, write the errno error to pipe. // (Pipe is close-on-exec so if exec succeeds, it will be closed.) // In the child, this function must not acquire any locks, because -// they might have been locked at the time of the fork. This means +// they might have been locked at the time of the fork. This means // no rescheduling, no malloc calls, and no new stack segments. // For the same reason compiler does not race instrument it. // The calls to RawSyscall are okay because they are assembly @@ -181,6 +181,9 @@ func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr } for i = 0; i < len(fd); i++ { if fd[i] >= 0 && fd[i] < int(i) { + if nextfd == pipe { // don't stomp on pipe + nextfd++ + } err1 = raw_dup2(fd[i], nextfd) if err1 != 0 { goto childerror @@ -188,9 +191,6 @@ func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr raw_fcntl(nextfd, F_SETFD, FD_CLOEXEC) fd[i] = nextfd nextfd++ - if nextfd == pipe { // don't stomp on pipe - nextfd++ - } } } diff --git a/libgo/go/syscall/exec_linux.go b/libgo/go/syscall/exec_linux.go index 6987bc1f4e..8d6467a872 100644 --- a/libgo/go/syscall/exec_linux.go +++ b/libgo/go/syscall/exec_linux.go @@ -7,7 +7,6 @@ package syscall import ( - "runtime" "unsafe" ) @@ -23,20 +22,21 @@ type SysProcIDMap struct { } type SysProcAttr struct { - Chroot string // Chroot. - Credential *Credential // Credential. - Ptrace bool // Enable tracing. - Setsid bool // Create session. - Setpgid bool // Set process group ID to Pgid, or, if Pgid == 0, to new pid. - Setctty bool // Set controlling terminal to fd Ctty (only meaningful if Setsid is set) - Noctty bool // Detach fd 0 from controlling terminal - Ctty int // Controlling TTY fd - Foreground bool // Place child's process group in foreground. (Implies Setpgid. Uses Ctty as fd of controlling TTY) - Pgid int // Child's process group ID if Setpgid. - Pdeathsig Signal // Signal that the process will get when its parent dies (Linux only) - Cloneflags uintptr // Flags for clone calls (Linux only) - UidMappings []SysProcIDMap // User ID mappings for user namespaces. - GidMappings []SysProcIDMap // Group ID mappings for user namespaces. + Chroot string // Chroot. + Credential *Credential // Credential. + Ptrace bool // Enable tracing. + Setsid bool // Create session. + Setpgid bool // Set process group ID to Pgid, or, if Pgid == 0, to new pid. + Setctty bool // Set controlling terminal to fd Ctty (only meaningful if Setsid is set) + Noctty bool // Detach fd 0 from controlling terminal + Ctty int // Controlling TTY fd + Foreground bool // Place child's process group in foreground. (Implies Setpgid. Uses Ctty as fd of controlling TTY) + Pgid int // Child's process group ID if Setpgid. + Pdeathsig Signal // Signal that the process will get when its parent dies (Linux only) + Cloneflags uintptr // Flags for clone calls (Linux only) + Unshareflags uintptr // Flags for unshare calls (Linux only) + UidMappings []SysProcIDMap // User ID mappings for user namespaces. + GidMappings []SysProcIDMap // Group ID mappings for user namespaces. // GidMappingsEnableSetgroups enabling setgroups syscall. // If false, then setgroups syscall will be disabled for the child process. // This parameter is no-op if GidMappings == nil. Otherwise for unprivileged @@ -48,11 +48,14 @@ type SysProcAttr struct { func runtime_BeforeFork() func runtime_AfterFork() +// Implemented in clone_linux.c +func rawClone(flags _C_ulong, child_stack *byte, ptid *Pid_t, ctid *Pid_t, regs unsafe.Pointer) _C_long + // Fork, dup fd onto 0..len(fd), and exec(argv0, argvv, envv) in child. // If a dup or exec fails, write the errno error to pipe. // (Pipe is close-on-exec so if exec succeeds, it will be closed.) // In the child, this function must not acquire any locks, because -// they might have been locked at the time of the fork. This means +// they might have been locked at the time of the fork. This means // no rescheduling, no malloc calls, and no new stack segments. // For the same reason compiler does not race instrument it. // The calls to RawSyscall are okay because they are assembly @@ -63,6 +66,7 @@ func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr // declarations require heap allocation (e.g., err1). var ( r1 uintptr + r2 _C_long err1 Errno err2 Errno nextfd int @@ -97,20 +101,16 @@ func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr // About to call fork. // No more allocation or calls of non-assembly functions. runtime_BeforeFork() - if runtime.GOARCH == "s390x" || runtime.GOARCH == "s390" { - r1, _, err1 = RawSyscall6(SYS_CLONE, 0, uintptr(SIGCHLD)|sys.Cloneflags, 0, 0, 0, 0) - } else { - r1, _, err1 = RawSyscall6(SYS_CLONE, uintptr(SIGCHLD)|sys.Cloneflags, 0, 0, 0, 0, 0) - } - if err1 != 0 { + r2 = rawClone(_C_ulong(uintptr(SIGCHLD)|sys.Cloneflags), nil, nil, nil, unsafe.Pointer(nil)) + if r2 < 0 { runtime_AfterFork() - return 0, err1 + return 0, GetErrno() } - if r1 != 0 { + if r2 != 0 { // parent; return PID runtime_AfterFork() - pid = int(r1) + pid = int(r2) if sys.UidMappings != nil || sys.GidMappings != nil { Close(p[0]) @@ -192,21 +192,35 @@ func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr } } + // Unshare + if sys.Unshareflags != 0 { + _, _, err1 = RawSyscall(SYS_UNSHARE, sys.Unshareflags, 0, 0) + if err1 != 0 { + goto childerror + } + } + // User and groups if cred := sys.Credential; cred != nil { ngroups := len(cred.Groups) + var groups unsafe.Pointer if ngroups > 0 { - groups := unsafe.Pointer(&cred.Groups[0]) + groups = unsafe.Pointer(&cred.Groups[0]) + } + // Don't call setgroups in case of user namespace, gid mappings + // and disabled setgroups, because otherwise unprivileged user namespace + // will fail with any non-empty SysProcAttr.Credential. + if !(sys.GidMappings != nil && !sys.GidMappingsEnableSetgroups && ngroups == 0) { err1 = raw_setgroups(ngroups, groups) if err1 != 0 { goto childerror } } - _, _, err1 = RawSyscall(SYS_SETGID, uintptr(cred.Gid), 0, 0) + _, _, err1 = RawSyscall(sys_SETGID, uintptr(cred.Gid), 0, 0) if err1 != 0 { goto childerror } - _, _, err1 = RawSyscall(SYS_SETUID, uintptr(cred.Uid), 0, 0) + _, _, err1 = RawSyscall(sys_SETUID, uintptr(cred.Uid), 0, 0) if err1 != 0 { goto childerror } @@ -253,6 +267,9 @@ func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr } for i = 0; i < len(fd); i++ { if fd[i] >= 0 && fd[i] < int(i) { + if nextfd == pipe { // don't stomp on pipe + nextfd++ + } err1 = raw_dup2(fd[i], nextfd) if err1 != 0 { goto childerror @@ -260,9 +277,6 @@ func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr raw_fcntl(nextfd, F_SETFD, FD_CLOEXEC) fd[i] = nextfd nextfd++ - if nextfd == pipe { // don't stomp on pipe - nextfd++ - } } } diff --git a/libgo/go/syscall/exec_linux_test.go b/libgo/go/syscall/exec_linux_test.go index 6d31941184..7a4b571760 100644 --- a/libgo/go/syscall/exec_linux_test.go +++ b/libgo/go/syscall/exec_linux_test.go @@ -26,11 +26,14 @@ func isChrooted(t *testing.T) bool { return root.Sys().(*syscall.Stat_t).Ino != 2 } -func whoamiCmd(t *testing.T, uid, gid int, setgroups bool) *exec.Cmd { +func checkUserNS(t *testing.T) { if _, err := os.Stat("/proc/self/ns/user"); err != nil { if os.IsNotExist(err) { t.Skip("kernel doesn't support user namespaces") } + if os.IsPermission(err) { + t.Skip("unable to test user namespaces due to permissions") + } t.Fatalf("Failed to stat /proc/self/ns/user: %v", err) } if isChrooted(t) { @@ -53,6 +56,10 @@ func whoamiCmd(t *testing.T, uid, gid int, setgroups bool) *exec.Cmd { if os.Getenv("GO_BUILDER_NAME") != "" && os.Getenv("IN_KUBERNETES") == "1" { t.Skip("skipping test on Kubernetes-based builders; see Issue 12815") } +} + +func whoamiCmd(t *testing.T, uid, gid int, setgroups bool) *exec.Cmd { + checkUserNS(t) cmd := exec.Command("whoami") cmd.SysProcAttr = &syscall.SysProcAttr{ Cloneflags: syscall.CLONE_NEWUSER, @@ -122,3 +129,127 @@ func TestEmptyCredGroupsDisableSetgroups(t *testing.T) { t.Fatal(err) } } + +func TestUnshare(t *testing.T) { + // Make sure we are running as root so we have permissions to use unshare + // and create a network namespace. + if os.Getuid() != 0 { + t.Skip("kernel prohibits unshare in unprivileged process, unless using user namespace") + } + + // When running under the Go continuous build, skip tests for + // now when under Kubernetes. (where things are root but not quite) + // Both of these are our own environment variables. + // See Issue 12815. + if os.Getenv("GO_BUILDER_NAME") != "" && os.Getenv("IN_KUBERNETES") == "1" { + t.Skip("skipping test on Kubernetes-based builders; see Issue 12815") + } + + path := "/proc/net/dev" + if _, err := os.Stat(path); err != nil { + if os.IsNotExist(err) { + t.Skip("kernel doesn't support proc filesystem") + } + if os.IsPermission(err) { + t.Skip("unable to test proc filesystem due to permissions") + } + t.Fatal(err) + } + if _, err := os.Stat("/proc/self/ns/net"); err != nil { + if os.IsNotExist(err) { + t.Skip("kernel doesn't support net namespace") + } + t.Fatal(err) + } + + orig, err := ioutil.ReadFile(path) + if err != nil { + t.Fatal(err) + } + origLines := strings.Split(strings.TrimSpace(string(orig)), "\n") + + cmd := exec.Command("cat", path) + cmd.SysProcAttr = &syscall.SysProcAttr{ + Unshareflags: syscall.CLONE_NEWNET, + } + out, err := cmd.CombinedOutput() + if err != nil { + t.Fatalf("Cmd failed with err %v, output: %s", err, out) + } + + // Check there is only the local network interface + sout := strings.TrimSpace(string(out)) + if !strings.Contains(sout, "lo:") { + t.Fatalf("Expected lo network interface to exist, got %s", sout) + } + + lines := strings.Split(sout, "\n") + if len(lines) >= len(origLines) { + t.Fatalf("Got %d lines of output, want <%d", len(lines), len(origLines)) + } +} + +func TestGroupCleanup(t *testing.T) { + if os.Getuid() != 0 { + t.Skip("we need root for credential") + } + cmd := exec.Command("id") + cmd.SysProcAttr = &syscall.SysProcAttr{ + Credential: &syscall.Credential{ + Uid: 0, + Gid: 0, + }, + } + out, err := cmd.CombinedOutput() + if err != nil { + t.Fatalf("Cmd failed with err %v, output: %s", err, out) + } + strOut := strings.TrimSpace(string(out)) + expected := "uid=0(root) gid=0(root) groups=0(root)" + // Just check prefix because some distros reportedly output a + // context parameter; see https://golang.org/issue/16224. + if !strings.HasPrefix(strOut, expected) { + t.Errorf("id command output: %q, expected prefix: %q", strOut, expected) + } +} + +func TestGroupCleanupUserNamespace(t *testing.T) { + if os.Getuid() != 0 { + t.Skip("we need root for credential") + } + checkUserNS(t) + cmd := exec.Command("id") + uid, gid := os.Getuid(), os.Getgid() + cmd.SysProcAttr = &syscall.SysProcAttr{ + Cloneflags: syscall.CLONE_NEWUSER, + Credential: &syscall.Credential{ + Uid: uint32(uid), + Gid: uint32(gid), + }, + UidMappings: []syscall.SysProcIDMap{ + {ContainerID: 0, HostID: uid, Size: 1}, + }, + GidMappings: []syscall.SysProcIDMap{ + {ContainerID: 0, HostID: gid, Size: 1}, + }, + } + out, err := cmd.CombinedOutput() + if err != nil { + t.Fatalf("Cmd failed with err %v, output: %s", err, out) + } + strOut := strings.TrimSpace(string(out)) + + // Strings we've seen in the wild. + expected := []string{ + "uid=0(root) gid=0(root) groups=0(root)", + "uid=0(root) gid=0(root) groups=0(root),65534(nobody)", + "uid=0(root) gid=0(root) groups=0(root),65534(nogroup)", + "uid=0(root) gid=0(root) groups=0(root),65534", + } + for _, e := range expected { + if strOut == e { + return + } + } + t.Errorf("id command output: %q, expected one of %q", strOut, expected) +} diff --git a/libgo/go/syscall/exec_solaris_test.go b/libgo/go/syscall/exec_solaris_test.go deleted file mode 100644 index 6b8f1ad383..0000000000 --- a/libgo/go/syscall/exec_solaris_test.go +++ /dev/null @@ -1,37 +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 solaris - -package syscall - -import "unsafe" - -//go:cgo_import_dynamic libc_Getpgid getpgid "libc.so" -//go:cgo_import_dynamic libc_Getpgrp getpgrp "libc.so" - -//go:linkname libc_Getpgid libc_Getpgid -//go:linkname libc_Getpgrp libc_Getpgrp - -var ( - libc_Getpgid, - libc_Getpgrp libcFunc -) - -func Getpgid(pid int) (pgid int, err error) { - r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&libc_Getpgid)), 1, uintptr(pid), 0, 0, 0, 0, 0) - pgid = int(r0) - if e1 != 0 { - err = e1 - } - return -} - -func Getpgrp() (pgrp int) { - r0, _, _ := sysvicall6(uintptr(unsafe.Pointer(&libc_Getpgrp)), 0, 0, 0, 0, 0, 0, 0) - pgrp = int(r0) - return -} - -var Ioctl = ioctl diff --git a/libgo/go/syscall/exec_stubs.go b/libgo/go/syscall/exec_stubs.go index 35bb17487b..e95b4158e1 100644 --- a/libgo/go/syscall/exec_stubs.go +++ b/libgo/go/syscall/exec_stubs.go @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +// +build rtems + // Stubs for fork, exec and wait. package syscall diff --git a/libgo/go/syscall/exec_unix.go b/libgo/go/syscall/exec_unix.go index 3b772e6ddb..c04005cdd6 100644 --- a/libgo/go/syscall/exec_unix.go +++ b/libgo/go/syscall/exec_unix.go @@ -68,31 +68,31 @@ import ( // Lock synchronizing creation of new file descriptors with fork. // // We want the child in a fork/exec sequence to inherit only the -// file descriptors we intend. To do that, we mark all file +// file descriptors we intend. To do that, we mark all file // descriptors close-on-exec and then, in the child, explicitly // unmark the ones we want the exec'ed program to keep. // Unix doesn't make this easy: there is, in general, no way to -// allocate a new file descriptor close-on-exec. Instead you +// allocate a new file descriptor close-on-exec. Instead you // have to allocate the descriptor and then mark it close-on-exec. // If a fork happens between those two events, the child's exec // will inherit an unwanted file descriptor. // // This lock solves that race: the create new fd/mark close-on-exec // operation is done holding ForkLock for reading, and the fork itself -// is done holding ForkLock for writing. At least, that's the idea. +// is done holding ForkLock for writing. At least, that's the idea. // There are some complications. // // Some system calls that create new file descriptors can block // for arbitrarily long times: open on a hung NFS server or named -// pipe, accept on a socket, and so on. We can't reasonably grab +// pipe, accept on a socket, and so on. We can't reasonably grab // the lock across those operations. // // It is worse to inherit some file descriptors than others. // If a non-malicious child accidentally inherits an open ordinary file, -// that's not a big deal. On the other hand, if a long-lived child +// that's not a big deal. On the other hand, if a long-lived child // accidentally inherits the write end of a pipe, then the reader // of that pipe will not see EOF until that child exits, potentially -// causing the parent program to hang. This is a common problem +// causing the parent program to hang. This is a common problem // in threaded C programs that use popen. // // Luckily, the file descriptors that are most important not to @@ -102,13 +102,13 @@ import ( // The rules for which file descriptor-creating operations use the // ForkLock are as follows: // -// 1) Pipe. Does not block. Use the ForkLock. -// 2) Socket. Does not block. Use the ForkLock. -// 3) Accept. If using non-blocking mode, use the ForkLock. +// 1) Pipe. Does not block. Use the ForkLock. +// 2) Socket. Does not block. Use the ForkLock. +// 3) Accept. If using non-blocking mode, use the ForkLock. // Otherwise, live with the race. -// 4) Open. Can block. Use O_CLOEXEC if available (GNU/Linux). +// 4) Open. Can block. Use O_CLOEXEC if available (GNU/Linux). // Otherwise, live with the race. -// 5) Dup. Does not block. Use the ForkLock. +// 5) Dup. Does not block. Use the ForkLock. // On GNU/Linux, could use fcntl F_DUPFD_CLOEXEC // instead of the ForkLock, but only for dup(fd, -1). @@ -154,7 +154,7 @@ func SetNonblock(fd int, nonblocking bool) (err error) { if nonblocking { flag |= O_NONBLOCK } else { - flag &= ^O_NONBLOCK + flag &^= O_NONBLOCK } _, err = fcntl(fd, F_SETFL, flag) return err @@ -292,7 +292,7 @@ func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid int, handle return pid, 0, err } -// Ordinary exec. +// Exec invokes the execve(2) system call. func Exec(argv0 string, argv []string, envv []string) (err error) { argv0p, err := BytePtrFromString(argv0) if err != nil { diff --git a/libgo/go/syscall/exec_windows.go b/libgo/go/syscall/exec_windows.go index 5a01843d2b..cafce1eff6 100644 --- a/libgo/go/syscall/exec_windows.go +++ b/libgo/go/syscall/exec_windows.go @@ -209,8 +209,6 @@ func joinExeDirAndFName(dir, p string) (name string, err error) { return FullPath(d + "\\" + p) } } - // we shouldn't be here - return "", EINVAL } type ProcAttr struct { diff --git a/libgo/go/syscall/export_test.go b/libgo/go/syscall/export_test.go index c9774622c8..55c09e667e 100644 --- a/libgo/go/syscall/export_test.go +++ b/libgo/go/syscall/export_test.go @@ -1,4 +1,4 @@ -// Copyright 2014 The Go Authors. All rights reserved. +// 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. diff --git a/libgo/go/syscall/export_unix_test.go b/libgo/go/syscall/export_unix_test.go index b41fe2f86b..47ec544339 100644 --- a/libgo/go/syscall/export_unix_test.go +++ b/libgo/go/syscall/export_unix_test.go @@ -2,7 +2,7 @@ // 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 +// +build darwin dragonfly freebsd linux netbsd openbsd solaris package syscall diff --git a/libgo/go/syscall/libcall_bsd.go b/libgo/go/syscall/libcall_bsd.go index fe6a3e3a27..9a4b2d6582 100644 --- a/libgo/go/syscall/libcall_bsd.go +++ b/libgo/go/syscall/libcall_bsd.go @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +// +build darwin dragonfly freebsd netbsd openbsd solaris + // BSD library calls. package syscall diff --git a/libgo/go/syscall/libcall_irix.go b/libgo/go/syscall/libcall_irix.go index 50863fadf1..9b6cdcca2c 100644 --- a/libgo/go/syscall/libcall_irix.go +++ b/libgo/go/syscall/libcall_irix.go @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +// +build irix + package syscall //sysnb raw_ptrace(request int, pid int, addr *byte, data *byte) (err Errno) diff --git a/libgo/go/syscall/libcall_linux.go b/libgo/go/syscall/libcall_linux.go index ff81f54710..b58b2ddd6e 100644 --- a/libgo/go/syscall/libcall_linux.go +++ b/libgo/go/syscall/libcall_linux.go @@ -251,27 +251,6 @@ func ReadDirent(fd int, buf []byte) (n int, err error) { return Getdents(fd, buf) } -func ParseDirent(buf []byte, max int, names []string) (consumed int, count int, newnames []string) { - origlen := len(buf) - count = 0 - for max != 0 && len(buf) > 0 { - dirent := (*Dirent)(unsafe.Pointer(&buf[0])) - buf = buf[dirent.Reclen:] - if dirent.Ino == 0 { // File absent in directory. - continue - } - bytes := (*[10000]byte)(unsafe.Pointer(&dirent.Name[0])) - var name = string(bytes[0:clen(bytes[:])]) - if name == "." || name == ".." { // Useless names - continue - } - max-- - count++ - names = append(names, name) - } - return origlen - len(buf), count, names -} - //sys Getxattr(path string, attr string, dest []byte) (sz int, err error) //getxattr(path *byte, attr *byte, buf *byte, count Size_t) Ssize_t diff --git a/libgo/go/syscall/libcall_linux_ustat.go b/libgo/go/syscall/libcall_linux_ustat.go index f7f3406a6a..261f086f47 100644 --- a/libgo/go/syscall/libcall_linux_ustat.go +++ b/libgo/go/syscall/libcall_linux_ustat.go @@ -4,6 +4,7 @@ // GNU/Linux library ustat call. // This is not supported on some kernels, such as arm64. +// +build !arm64 package syscall diff --git a/libgo/go/syscall/libcall_posix.go b/libgo/go/syscall/libcall_posix.go index d3580a1bc0..76941c89b6 100644 --- a/libgo/go/syscall/libcall_posix.go +++ b/libgo/go/syscall/libcall_posix.go @@ -226,9 +226,6 @@ func FDZero(set *FdSet) { //sysnb Getgid() (gid int) //getgid() Gid_t -//sysnb Getpagesize() (pagesize int) -//getpagesize() _C_int - //sysnb Getpgid(pid int) (pgid int, err error) //getpgid(pid Pid_t) Pid_t @@ -377,21 +374,12 @@ func Settimeofday(tv *Timeval) (err error) { //sys Munlockall() (err error) //munlockall() _C_int -func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } - -func NsecToTimespec(nsec int64) (ts Timespec) { - ts.Sec = Timespec_sec_t(nsec / 1e9) - ts.Nsec = Timespec_nsec_t(nsec % 1e9) - return +func setTimespec(sec, nsec int64) Timespec { + return Timespec{Sec: Timespec_sec_t(sec), Nsec: Timespec_nsec_t(nsec)} } -func TimevalToNsec(tv Timeval) int64 { return int64(tv.Sec)*1e9 + int64(tv.Usec)*1e3 } - -func NsecToTimeval(nsec int64) (tv Timeval) { - nsec += 999 // round up to microsecond - tv.Sec = Timeval_sec_t(nsec / 1e9) - tv.Usec = Timeval_usec_t(nsec % 1e9 / 1e3) - return +func setTimeval(sec, usec int64) Timeval { + return Timeval{Sec: Timeval_sec_t(sec), Usec: Timeval_usec_t(usec)} } //sysnb Tcgetattr(fd int, p *Termios) (err error) @@ -399,3 +387,17 @@ func NsecToTimeval(nsec int64) (tv Timeval) { //sys Tcsetattr(fd int, actions int, p *Termios) (err error) //tcsetattr(fd _C_int, actions _C_int, p *Termios) _C_int + +//sys sysconf(name int) (ret int64, err error) +//sysconf(name _C_int) _C_long + +func Sysconf(name int) (ret int64, err error) { + // If an option is not available, sysconf returns -1 without + // changing errno. Detect this case and return err == nil. + SetErrno(0) + ret, err = sysconf(name) + if err == Errno(0) { + err = nil + } + return ret, err +} diff --git a/libgo/go/syscall/libcall_posix_largefile.go b/libgo/go/syscall/libcall_posix_largefile.go index c05d3d2a5e..1f437b41fb 100644 --- a/libgo/go/syscall/libcall_posix_largefile.go +++ b/libgo/go/syscall/libcall_posix_largefile.go @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +// +build linux solaris,386 solaris,sparc + // POSIX library calls on systems which use the largefile interface. package syscall diff --git a/libgo/go/syscall/libcall_posix_regfile.go b/libgo/go/syscall/libcall_posix_regfile.go index 7de5800939..d106a7b6f6 100644 --- a/libgo/go/syscall/libcall_posix_regfile.go +++ b/libgo/go/syscall/libcall_posix_regfile.go @@ -2,6 +2,10 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +// +build !linux +// +build !solaris !386 +// +build !solaris !sparc + // POSIX library calls on systems which do not use the largefile // interface. diff --git a/libgo/go/syscall/libcall_posix_utimesnano.go b/libgo/go/syscall/libcall_posix_utimesnano.go index e0751f5467..5d9d02eba3 100644 --- a/libgo/go/syscall/libcall_posix_utimesnano.go +++ b/libgo/go/syscall/libcall_posix_utimesnano.go @@ -2,6 +2,8 @@ // 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 netbsd solaris + // General POSIX version of UtimesNano. package syscall diff --git a/libgo/go/syscall/libcall_uname.go b/libgo/go/syscall/libcall_uname.go index 1e164ef1a5..165b3251b6 100644 --- a/libgo/go/syscall/libcall_uname.go +++ b/libgo/go/syscall/libcall_uname.go @@ -2,6 +2,10 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +// Build on all systems other than solaris/386. +// 32-bit Solaris 2/x86 needs _nuname, handled in libcall_solaris_386.go. +// +build !386 !solaris + package syscall //sysnb Uname(buf *Utsname) (err error) diff --git a/libgo/go/syscall/libcall_waitpid.go b/libgo/go/syscall/libcall_waitpid.go deleted file mode 100644 index b0e04b5bab..0000000000 --- a/libgo/go/syscall/libcall_waitpid.go +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2009 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. - -// For systems with the waitpid library call. - -package syscall - -//sys waitpid(pid Pid_t, status *_C_int, options int) (wpid Pid_t, err error) -//waitpid(pid Pid_t, status *_C_int, options _C_int) Pid_t - -func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) { - var status _C_int - r, err := waitpid(Pid_t(pid), &status, options) - wpid = int(r) - if wstatus != nil { - *wstatus = WaitStatus(status) - } - return -} diff --git a/libgo/go/syscall/lsf_linux.go b/libgo/go/syscall/lsf_linux.go index 48ba191c6d..16b702a984 100644 --- a/libgo/go/syscall/lsf_linux.go +++ b/libgo/go/syscall/lsf_linux.go @@ -1,4 +1,4 @@ -// Copyright 2011 The Go Authors. All rights reserved. +// Copyright 2011 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. @@ -10,14 +10,17 @@ import ( "unsafe" ) +// Deprecated: Use golang.org/x/net/bpf instead. func LsfStmt(code, k int) *SockFilter { return &SockFilter{Code: uint16(code), K: uint32(k)} } +// Deprecated: Use golang.org/x/net/bpf instead. func LsfJump(code, k, jt, jf int) *SockFilter { return &SockFilter{Code: uint16(code), Jt: uint8(jt), Jf: uint8(jf), K: uint32(k)} } +// Deprecated: Use golang.org/x/net/bpf instead. func LsfSocket(ifindex, proto int) (int, error) { var lsall SockaddrLinklayer s, e := Socket(AF_PACKET, SOCK_RAW, proto) @@ -41,6 +44,7 @@ type iflags struct { flags uint16 } +// Deprecated: Use golang.org/x/net/bpf instead. func SetLsfPromisc(name string, m bool) error { s, e := Socket(AF_INET, SOCK_DGRAM, 0) if e != nil { @@ -56,7 +60,7 @@ func SetLsfPromisc(name string, m bool) error { if m { ifl.flags |= uint16(IFF_PROMISC) } else { - ifl.flags &= ^uint16(IFF_PROMISC) + ifl.flags &^= uint16(IFF_PROMISC) } _, _, ep = Syscall(SYS_IOCTL, uintptr(s), SIOCSIFFLAGS, uintptr(unsafe.Pointer(&ifl))) if ep != 0 { @@ -65,6 +69,7 @@ func SetLsfPromisc(name string, m bool) error { return nil } +// Deprecated: Use golang.org/x/net/bpf instead. func AttachLsf(fd int, i []SockFilter) error { var p SockFprog p.Len = uint16(len(i)) @@ -72,6 +77,7 @@ func AttachLsf(fd int, i []SockFilter) error { return setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, unsafe.Pointer(&p), Socklen_t(unsafe.Sizeof(p))) } +// Deprecated: Use golang.org/x/net/bpf instead. func DetachLsf(fd int) error { var dummy int return setsockopt(fd, SOL_SOCKET, SO_DETACH_FILTER, unsafe.Pointer(&dummy), Socklen_t(unsafe.Sizeof(dummy))) diff --git a/libgo/go/syscall/msan.go b/libgo/go/syscall/msan.go deleted file mode 100644 index edd8d1ebd5..0000000000 --- a/libgo/go/syscall/msan.go +++ /dev/null @@ -1,22 +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 msan - -package syscall - -import ( - "runtime" - "unsafe" -) - -const msanenabled = true - -func msanRead(addr unsafe.Pointer, len int) { - runtime.MSanRead(addr, len) -} - -func msanWrite(addr unsafe.Pointer, len int) { - runtime.MSanWrite(addr, len) -} diff --git a/libgo/go/syscall/msan0.go b/libgo/go/syscall/msan0.go index 7617494e86..ff10be9d25 100644 --- a/libgo/go/syscall/msan0.go +++ b/libgo/go/syscall/msan0.go @@ -1,4 +1,4 @@ -// Copyright 2015 The Go Authors. All rights reserved. +// 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. diff --git a/libgo/go/syscall/netlink_linux.go b/libgo/go/syscall/netlink_linux.go index 1b73dce827..1cda8c7704 100644 --- a/libgo/go/syscall/netlink_linux.go +++ b/libgo/go/syscall/netlink_linux.go @@ -1,4 +1,4 @@ -// Copyright 2011 The Go Authors. All rights reserved. +// Copyright 2011 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. @@ -129,10 +129,11 @@ func ParseNetlinkMessage(b []byte) ([]NetlinkMessage, error) { func netlinkMessageHeaderAndData(b []byte) (*NlMsghdr, []byte, int, error) { h := (*NlMsghdr)(unsafe.Pointer(&b[0])) - if int(h.Len) < NLMSG_HDRLEN || int(h.Len) > len(b) { + l := nlmAlignOf(int(h.Len)) + if int(h.Len) < NLMSG_HDRLEN || l > len(b) { return nil, nil, 0, EINVAL } - return h, b[NLMSG_HDRLEN:], nlmAlignOf(int(h.Len)), nil + return h, b[NLMSG_HDRLEN:], l, nil } // NetlinkRouteAttr represents a netlink route attribute. diff --git a/libgo/go/syscall/route_bsd.go b/libgo/go/syscall/route_bsd.go index c635a1385e..b364eeaba5 100644 --- a/libgo/go/syscall/route_bsd.go +++ b/libgo/go/syscall/route_bsd.go @@ -1,4 +1,4 @@ -// Copyright 2011 The Go Authors. All rights reserved. +// Copyright 2011 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. @@ -138,7 +138,7 @@ func parseNetworkLayerAddr(b []byte, family byte) (Sockaddr, error) { // // - The kernel form appends leading bytes to the prefix field // to make the <length, prefix> tuple to be conformed with - // the routing messeage boundary + // the routing message boundary l := int(rsaAlignOf(int(b[0]))) if len(b) < l { return nil, EINVAL @@ -176,6 +176,8 @@ func parseNetworkLayerAddr(b []byte, family byte) (Sockaddr, error) { // RouteRIB returns routing information base, as known as RIB, // which consists of network facility information, states and // parameters. +// +// Deprecated: Use golang.org/x/net/route instead. func RouteRIB(facility, param int) ([]byte, error) { mib := []_C_int{CTL_NET, AF_ROUTE, 0, 0, _C_int(facility), _C_int(param)} // Find size. @@ -194,6 +196,8 @@ func RouteRIB(facility, param int) ([]byte, error) { } // RoutingMessage represents a routing message. +// +// Deprecated: Use golang.org/x/net/route instead. type RoutingMessage interface { sockaddr() ([]Sockaddr, error) } @@ -208,6 +212,8 @@ type anyMessage struct { // RouteMessage represents a routing message containing routing // entries. +// +// Deprecated: Use golang.org/x/net/route instead. type RouteMessage struct { Header RtMsghdr Data []byte @@ -252,6 +258,8 @@ func (m *RouteMessage) sockaddr() ([]Sockaddr, error) { // InterfaceMessage represents a routing message containing // network interface entries. +// +// Deprecated: Use golang.org/x/net/route instead. type InterfaceMessage struct { Header IfMsghdr Data []byte @@ -272,6 +280,8 @@ func (m *InterfaceMessage) sockaddr() ([]Sockaddr, error) { // InterfaceAddrMessage represents a routing message containing // network interface address entries. +// +// Deprecated: Use golang.org/x/net/route instead. type InterfaceAddrMessage struct { Header IfaMsghdr Data []byte @@ -316,6 +326,8 @@ func (m *InterfaceAddrMessage) sockaddr() ([]Sockaddr, error) { // ParseRoutingMessage parses b as routing messages and returns the // slice containing the RoutingMessage interfaces. +// +// Deprecated: Use golang.org/x/net/route instead. func ParseRoutingMessage(b []byte) (msgs []RoutingMessage, err error) { nmsgs, nskips := 0, 0 for len(b) >= anyMessageLen { @@ -341,6 +353,8 @@ func ParseRoutingMessage(b []byte) (msgs []RoutingMessage, err error) { // ParseRoutingSockaddr parses msg's payload as raw sockaddrs and // returns the slice containing the Sockaddr interfaces. +// +// Deprecated: Use golang.org/x/net/route instead. func ParseRoutingSockaddr(msg RoutingMessage) ([]Sockaddr, error) { sas, err := msg.sockaddr() if err != nil { diff --git a/libgo/go/syscall/route_bsd_test.go b/libgo/go/syscall/route_bsd_test.go deleted file mode 100644 index 74d11f9f0a..0000000000 --- a/libgo/go/syscall/route_bsd_test.go +++ /dev/null @@ -1,260 +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 netbsd openbsd - -package syscall_test - -import ( - "fmt" - "net" - "os" - "syscall" - "testing" - "time" -) - -func TestRouteRIB(t *testing.T) { - for _, facility := range []int{syscall.NET_RT_DUMP, syscall.NET_RT_IFLIST} { - for _, param := range []int{syscall.AF_UNSPEC, syscall.AF_INET, syscall.AF_INET6} { - var err error - var b []byte - // The VM allocator wrapper functions can - // return ENOMEM easily. - for i := 0; i < 3; i++ { - b, err = syscall.RouteRIB(facility, param) - if err != nil { - time.Sleep(5 * time.Millisecond) - continue - } - break - } - if err != nil { - t.Error(facility, param, err) - continue - } - msgs, err := syscall.ParseRoutingMessage(b) - if err != nil { - t.Error(facility, param, err) - continue - } - var ipv4loopback, ipv6loopback bool - for _, m := range msgs { - flags, err := parseRoutingMessageHeader(m) - if err != nil { - t.Error(err) - continue - } - sas, err := parseRoutingSockaddrs(m) - if err != nil { - t.Error(err) - continue - } - if flags&(syscall.RTA_DST|syscall.RTA_IFA) != 0 { - sa := sas[syscall.RTAX_DST] - if sa == nil { - sa = sas[syscall.RTAX_IFA] - } - switch sa := sa.(type) { - case *syscall.SockaddrInet4: - if net.IP(sa.Addr[:]).IsLoopback() { - ipv4loopback = true - } - case *syscall.SockaddrInet6: - if net.IP(sa.Addr[:]).IsLoopback() { - ipv6loopback = true - } - } - } - t.Log(facility, param, flags, sockaddrs(sas)) - } - if param == syscall.AF_UNSPEC && len(msgs) > 0 && !ipv4loopback && !ipv6loopback { - t.Errorf("no loopback facility found: ipv4/ipv6=%v/%v, %v", ipv4loopback, ipv6loopback, len(msgs)) - continue - } - } - } -} - -func TestRouteMonitor(t *testing.T) { - if testing.Short() || os.Getuid() != 0 { - t.Skip("must be root") - } - - s, err := syscall.Socket(syscall.AF_ROUTE, syscall.SOCK_RAW, syscall.AF_UNSPEC) - if err != nil { - t.Fatal(err) - } - defer syscall.Close(s) - - tmo := time.After(30 * time.Second) - go func() { - b := make([]byte, os.Getpagesize()) - for { - n, err := syscall.Read(s, b) - if err != nil { - return - } - msgs, err := syscall.ParseRoutingMessage(b[:n]) - if err != nil { - t.Error(err) - return - } - for _, m := range msgs { - flags, err := parseRoutingMessageHeader(m) - if err != nil { - t.Error(err) - continue - } - sas, err := parseRoutingSockaddrs(m) - if err != nil { - t.Error(err) - continue - } - t.Log(flags, sockaddrs(sas)) - } - } - }() - <-tmo -} - -var parseInterfaceMessageTests = []*syscall.InterfaceMessage{ - // with link-layer address - { - Header: syscall.IfMsghdr{Version: syscall.RTM_VERSION, Addrs: syscall.RTA_IFP}, - Data: []uint8{ - 0x11, 0x12, 0x2, 0x0, 0x6, 0x3, 0x6, 0x0, - 0x77, 0x6d, 0x31, 0x01, 0x23, 0x45, 0xab, 0xcd, - 0xef, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - }, - }, - // without link-layer address - { - Header: syscall.IfMsghdr{Version: syscall.RTM_VERSION, Addrs: syscall.RTA_IFP}, - Data: []uint8{ - 0xe, 0x12, 0x4, 0x0, 0xf5, 0x6, 0x0, 0x0, - 0x70, 0x66, 0x6c, 0x6f, 0x67, 0x30, 0x0, 0x0, - }, - }, - // no data - { - Header: syscall.IfMsghdr{Version: syscall.RTM_VERSION, Addrs: syscall.RTA_IFP}, - Data: []uint8{ - 0x8, 0xa, 0xb, 0xc, 0xd, 0x0, 0x0, 0x0, - }, - }, -} - -func TestParseInterfaceMessage(t *testing.T) { - for i, tt := range parseInterfaceMessageTests { - if _, err := syscall.ParseRoutingSockaddr(tt); err != nil { - t.Errorf("#%d: %v", i, err) - } - } -} - -type addrFamily byte - -func (f addrFamily) String() string { - switch f { - case syscall.AF_UNSPEC: - return "unspec" - case syscall.AF_LINK: - return "link" - case syscall.AF_INET: - return "inet4" - case syscall.AF_INET6: - return "inet6" - default: - return fmt.Sprintf("unknown %d", f) - } -} - -type addrFlags uint32 - -var addrFlagNames = [...]string{ - "dst", - "gateway", - "netmask", - "genmask", - "ifp", - "ifa", - "author", - "brd", - "mpls1,tag,src", // sockaddr_mpls=dragonfly,netbsd, sockaddr_in/in6=openbsd - "mpls2,srcmask", // sockaddr_mpls=dragonfly, sockaddr_in/in6=openbsd - "mpls3,label", // sockaddr_mpls=dragonfly, sockaddr_rtlabel=openbsd -} - -func (f addrFlags) String() string { - var s string - for i, name := range addrFlagNames { - if f&(1<<uint(i)) != 0 { - if s != "" { - s += "|" - } - s += name - } - } - if s == "" { - return "<nil>" - } - return s -} - -type sockaddrs []syscall.Sockaddr - -func (sas sockaddrs) String() string { - var s string - for _, sa := range sas { - if sa == nil { - continue - } - if len(s) > 0 { - s += " " - } - switch sa := sa.(type) { - case *syscall.SockaddrDatalink: - s += fmt.Sprintf("[%v/%v/%v t/n/a/s=%v/%v/%v/%v]", sa.Len, addrFamily(sa.Family), sa.Index, sa.Type, sa.Nlen, sa.Alen, sa.Slen) - case *syscall.SockaddrInet4: - s += fmt.Sprintf("%v", net.IP(sa.Addr[:]).To4()) - case *syscall.SockaddrInet6: - s += fmt.Sprintf("%v", net.IP(sa.Addr[:]).To16()) - } - } - if s == "" { - return "<nil>" - } - return s -} - -func (sas sockaddrs) match(flags addrFlags) error { - var f addrFlags - family := syscall.AF_UNSPEC - for i := range sas { - if sas[i] != nil { - f |= 1 << uint(i) - } - switch sas[i].(type) { - case *syscall.SockaddrInet4: - if family == syscall.AF_UNSPEC { - family = syscall.AF_INET - } - if family != syscall.AF_INET { - return fmt.Errorf("got %v; want %v", sockaddrs(sas), family) - } - case *syscall.SockaddrInet6: - if family == syscall.AF_UNSPEC { - family = syscall.AF_INET6 - } - if family != syscall.AF_INET6 { - return fmt.Errorf("got %v; want %v", sockaddrs(sas), family) - } - } - } - if f != flags { - return fmt.Errorf("got %v; want %v", f, flags) - } - return nil -} diff --git a/libgo/go/syscall/route_darwin.go b/libgo/go/syscall/route_darwin.go index 89bca12f3e..b0636ed07c 100644 --- a/libgo/go/syscall/route_darwin.go +++ b/libgo/go/syscall/route_darwin.go @@ -1,4 +1,4 @@ -// Copyright 2011 The Go Authors. All rights reserved. +// Copyright 2011 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. @@ -26,6 +26,8 @@ func (any *anyMessage) toRoutingMessage(b []byte) RoutingMessage { // InterfaceMulticastAddrMessage represents a routing message // containing network interface address entries. +// +// Deprecated: Use golang.org/x/net/route instead. type InterfaceMulticastAddrMessage struct { Header IfmaMsghdr2 Data []byte diff --git a/libgo/go/syscall/route_dragonfly.go b/libgo/go/syscall/route_dragonfly.go index 5226f7f2e4..b562400be8 100644 --- a/libgo/go/syscall/route_dragonfly.go +++ b/libgo/go/syscall/route_dragonfly.go @@ -1,4 +1,4 @@ -// Copyright 2011 The Go Authors. All rights reserved. +// Copyright 2011 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. @@ -31,6 +31,8 @@ func (any *anyMessage) toRoutingMessage(b []byte) RoutingMessage { // InterfaceAnnounceMessage represents a routing message containing // network interface arrival and departure information. +// +// Deprecated: Use golang.org/x/net/route instead. type InterfaceAnnounceMessage struct { Header IfAnnounceMsghdr } @@ -39,6 +41,8 @@ func (m *InterfaceAnnounceMessage) sockaddr() ([]Sockaddr, error) { return nil, // InterfaceMulticastAddrMessage represents a routing message // containing network interface address entries. +// +// Deprecated: Use golang.org/x/net/route instead. type InterfaceMulticastAddrMessage struct { Header IfmaMsghdr Data []byte diff --git a/libgo/go/syscall/route_freebsd.go b/libgo/go/syscall/route_freebsd.go index 0e18103855..2c2de7474a 100644 --- a/libgo/go/syscall/route_freebsd.go +++ b/libgo/go/syscall/route_freebsd.go @@ -1,4 +1,4 @@ -// Copyright 2011 The Go Authors. All rights reserved. +// Copyright 2011 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. @@ -53,6 +53,8 @@ func (any *anyMessage) toRoutingMessage(b []byte) RoutingMessage { // InterfaceAnnounceMessage represents a routing message containing // network interface arrival and departure information. +// +// Deprecated: Use golang.org/x/net/route instead. type InterfaceAnnounceMessage struct { Header IfAnnounceMsghdr } @@ -61,6 +63,8 @@ func (m *InterfaceAnnounceMessage) sockaddr() ([]Sockaddr, error) { return nil, // InterfaceMulticastAddrMessage represents a routing message // containing network interface address entries. +// +// Deprecated: Use golang.org/x/net/route instead. type InterfaceMulticastAddrMessage struct { Header IfmaMsghdr Data []byte diff --git a/libgo/go/syscall/route_ifma_test.go b/libgo/go/syscall/route_ifma_test.go deleted file mode 100644 index af2b67dc24..0000000000 --- a/libgo/go/syscall/route_ifma_test.go +++ /dev/null @@ -1,74 +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 - -package syscall_test - -import ( - "fmt" - "syscall" -) - -func parseRoutingMessageHeader(m syscall.RoutingMessage) (addrFlags, error) { - switch m := m.(type) { - case *syscall.RouteMessage: - errno := syscall.Errno(uintptr(m.Header.Errno)) - if errno != 0 { - return 0, fmt.Errorf("%T: %v, %#v", m, errno, m.Header) - } - return addrFlags(m.Header.Addrs), nil - case *syscall.InterfaceMessage: - return addrFlags(m.Header.Addrs), nil - case *syscall.InterfaceAddrMessage: - return addrFlags(m.Header.Addrs), nil - case *syscall.InterfaceMulticastAddrMessage: - return addrFlags(m.Header.Addrs), nil - default: - panic(fmt.Sprintf("unknown routing message type: %T", m)) - } -} - -func parseRoutingSockaddrs(m syscall.RoutingMessage) ([]syscall.Sockaddr, error) { - switch m := m.(type) { - case *syscall.RouteMessage: - sas, err := syscall.ParseRoutingSockaddr(m) - if err != nil { - return nil, fmt.Errorf("%T: %v, %#v", m, err, m.Data) - } - if err = sockaddrs(sas).match(addrFlags(m.Header.Addrs)); err != nil { - return nil, err - } - return sas, nil - case *syscall.InterfaceMessage: - sas, err := syscall.ParseRoutingSockaddr(m) - if err != nil { - return nil, fmt.Errorf("%T: %v, %#v", m, err, m.Data) - } - if err = sockaddrs(sas).match(addrFlags(m.Header.Addrs)); err != nil { - return nil, err - } - return sas, nil - case *syscall.InterfaceAddrMessage: - sas, err := syscall.ParseRoutingSockaddr(m) - if err != nil { - return nil, fmt.Errorf("%T: %v, %#v", m, err, m.Data) - } - if err = sockaddrs(sas).match(addrFlags(m.Header.Addrs)); err != nil { - return nil, err - } - return sas, nil - case *syscall.InterfaceMulticastAddrMessage: - sas, err := syscall.ParseRoutingSockaddr(m) - if err != nil { - return nil, fmt.Errorf("%T: %v, %#v", m, err, m.Data) - } - if err = sockaddrs(sas).match(addrFlags(m.Header.Addrs)); err != nil { - return nil, err - } - return sas, nil - default: - panic(fmt.Sprintf("unknown routing message type: %T", m)) - } -} diff --git a/libgo/go/syscall/route_netbsd.go b/libgo/go/syscall/route_netbsd.go index d605ffa30f..a10c8b65d9 100644 --- a/libgo/go/syscall/route_netbsd.go +++ b/libgo/go/syscall/route_netbsd.go @@ -1,4 +1,4 @@ -// Copyright 2011 The Go Authors. All rights reserved. +// Copyright 2011 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. @@ -28,6 +28,8 @@ func (any *anyMessage) toRoutingMessage(b []byte) RoutingMessage { // InterfaceAnnounceMessage represents a routing message containing // network interface arrival and departure information. +// +// Deprecated: Use golang.org/x/net/route instead. type InterfaceAnnounceMessage struct { Header IfAnnounceMsghdr } diff --git a/libgo/go/syscall/route_noifma_test.go b/libgo/go/syscall/route_noifma_test.go deleted file mode 100644 index 19d5d8ebbf..0000000000 --- a/libgo/go/syscall/route_noifma_test.go +++ /dev/null @@ -1,63 +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 netbsd openbsd - -package syscall_test - -import ( - "fmt" - "syscall" -) - -func parseRoutingMessageHeader(m syscall.RoutingMessage) (addrFlags, error) { - switch m := m.(type) { - case *syscall.RouteMessage: - errno := syscall.Errno(uintptr(m.Header.Errno)) - if errno != 0 { - return 0, fmt.Errorf("%T: %v, %#v", m, errno, m.Header) - } - return addrFlags(m.Header.Addrs), nil - case *syscall.InterfaceMessage: - return addrFlags(m.Header.Addrs), nil - case *syscall.InterfaceAddrMessage: - return addrFlags(m.Header.Addrs), nil - default: - panic(fmt.Sprintf("unknown routing message type: %T", m)) - } -} - -func parseRoutingSockaddrs(m syscall.RoutingMessage) ([]syscall.Sockaddr, error) { - switch m := m.(type) { - case *syscall.RouteMessage: - sas, err := syscall.ParseRoutingSockaddr(m) - if err != nil { - return nil, fmt.Errorf("%T: %v, %#v", m, err, m.Data) - } - if err = sockaddrs(sas).match(addrFlags(m.Header.Addrs)); err != nil { - return nil, err - } - return sas, nil - case *syscall.InterfaceMessage: - sas, err := syscall.ParseRoutingSockaddr(m) - if err != nil { - return nil, fmt.Errorf("%T: %v, %#v", m, err, m.Data) - } - if err = sockaddrs(sas).match(addrFlags(m.Header.Addrs)); err != nil { - return nil, err - } - return sas, nil - case *syscall.InterfaceAddrMessage: - sas, err := syscall.ParseRoutingSockaddr(m) - if err != nil { - return nil, fmt.Errorf("%T: %v, %#v", m, err, m.Data) - } - if err = sockaddrs(sas).match(addrFlags(m.Header.Addrs)); err != nil { - return nil, err - } - return sas, nil - default: - panic(fmt.Sprintf("unknown routing message type: %T", m)) - } -} diff --git a/libgo/go/syscall/route_openbsd.go b/libgo/go/syscall/route_openbsd.go index 7804a08910..fe173adda8 100644 --- a/libgo/go/syscall/route_openbsd.go +++ b/libgo/go/syscall/route_openbsd.go @@ -1,4 +1,4 @@ -// Copyright 2011 The Go Authors. All rights reserved. +// Copyright 2011 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. @@ -28,6 +28,8 @@ func (any *anyMessage) toRoutingMessage(b []byte) RoutingMessage { // InterfaceAnnounceMessage represents a routing message containing // network interface arrival and departure information. +// +// Deprecated: Use golang.org/x/net/route instead. type InterfaceAnnounceMessage struct { Header IfAnnounceMsghdr } diff --git a/libgo/go/syscall/security_windows.go b/libgo/go/syscall/security_windows.go index 1625b07ae4..e2a9dc5f9d 100644 --- a/libgo/go/syscall/security_windows.go +++ b/libgo/go/syscall/security_windows.go @@ -1,4 +1,4 @@ -// Copyright 2012 The Go Authors. All rights reserved. +// 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. diff --git a/libgo/go/syscall/setuidgid_32_linux.go b/libgo/go/syscall/setuidgid_32_linux.go new file mode 100644 index 0000000000..182f5d26a9 --- /dev/null +++ b/libgo/go/syscall/setuidgid_32_linux.go @@ -0,0 +1,13 @@ +// 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 +// +build 386 arm + +package syscall + +const ( + sys_SETGID = SYS_SETGID32 + sys_SETUID = SYS_SETUID32 +) diff --git a/libgo/go/syscall/setuidgid_linux.go b/libgo/go/syscall/setuidgid_linux.go new file mode 100644 index 0000000000..bf40d2d882 --- /dev/null +++ b/libgo/go/syscall/setuidgid_linux.go @@ -0,0 +1,13 @@ +// 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 +// +build !386,!arm + +package syscall + +const ( + sys_SETGID = SYS_SETGID + sys_SETUID = SYS_SETUID +) diff --git a/libgo/go/syscall/sleep_rtems.go b/libgo/go/syscall/sleep_rtems.go index 9d72203e8e..480c775565 100644 --- a/libgo/go/syscall/sleep_rtems.go +++ b/libgo/go/syscall/sleep_rtems.go @@ -4,6 +4,8 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +// +build rtems + package syscall func Sleep(nsec int64) (err error) { diff --git a/libgo/go/syscall/sleep_select.go b/libgo/go/syscall/sleep_select.go index 533f554da0..bb1694fcee 100644 --- a/libgo/go/syscall/sleep_select.go +++ b/libgo/go/syscall/sleep_select.go @@ -4,10 +4,12 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +// +build !rtems + package syscall func Sleep(nsec int64) (err error) { - tv := NsecToTimeval(nsec); - _, err = Select(0, nil, nil, nil, &tv); - return err; + tv := NsecToTimeval(nsec) + _, err = Select(0, nil, nil, nil, &tv) + return err } diff --git a/libgo/go/syscall/sockcmsg_linux.go b/libgo/go/syscall/sockcmsg_linux.go index a2e26a1f47..4cb9075ba8 100644 --- a/libgo/go/syscall/sockcmsg_linux.go +++ b/libgo/go/syscall/sockcmsg_linux.go @@ -1,4 +1,4 @@ -// Copyright 2011 The Go Authors. All rights reserved. +// Copyright 2011 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. @@ -31,6 +31,9 @@ func ParseUnixCredentials(m *SocketControlMessage) (*Ucred, error) { if m.Header.Type != SCM_CREDENTIALS { return nil, EINVAL } + if uintptr(len(m.Data)) < unsafe.Sizeof(Ucred{}) { + return nil, EINVAL + } ucred := *(*Ucred)(unsafe.Pointer(&m.Data[0])) return &ucred, nil } diff --git a/libgo/go/syscall/sockcmsg_unix.go b/libgo/go/syscall/sockcmsg_unix.go index bf32c987a9..016169929b 100644 --- a/libgo/go/syscall/sockcmsg_unix.go +++ b/libgo/go/syscall/sockcmsg_unix.go @@ -1,4 +1,4 @@ -// Copyright 2011 The Go Authors. All rights reserved. +// Copyright 2011 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. @@ -16,9 +16,10 @@ import ( // Round the length of a raw sockaddr up to align it properly. func cmsgAlignOf(salen int) int { salign := int(sizeofPtr) - // NOTE: It seems like 64-bit Darwin and DragonFly BSD kernels - // still require 32-bit aligned access to network subsystem. - if darwin64Bit || dragonfly64Bit { + // NOTE: It seems like 64-bit Darwin, DragonFly BSD and + // Solaris kernels still require 32-bit aligned access to + // network subsystem. + if darwin64Bit || dragonfly64Bit || solaris64Bit { salign = 4 } // NOTE: Solaris always uses 32-bit alignment, @@ -70,7 +71,7 @@ func ParseSocketControlMessage(b []byte) ([]SocketControlMessage, error) { func socketControlMessageHeaderAndData(b []byte) (*Cmsghdr, []byte, error) { h := (*Cmsghdr)(unsafe.Pointer(&b[0])) - if h.Len < SizeofCmsghdr || int(h.Len) > len(b) { + if h.Len < SizeofCmsghdr || uint64(h.Len) > uint64(len(b)) { return nil, nil, EINVAL } return h, b[cmsgAlignOf(SizeofCmsghdr):h.Len], nil diff --git a/libgo/go/syscall/socket_bsd.go b/libgo/go/syscall/socket_bsd.go index c8da102221..0f0962729e 100644 --- a/libgo/go/syscall/socket_bsd.go +++ b/libgo/go/syscall/socket_bsd.go @@ -4,6 +4,8 @@ // 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 netbsd + package syscall const SizeofSockaddrInet4 = 16 diff --git a/libgo/go/syscall/socket_irix.go b/libgo/go/syscall/socket_irix.go index bcd1781d57..dc50fdd24f 100644 --- a/libgo/go/syscall/socket_irix.go +++ b/libgo/go/syscall/socket_irix.go @@ -4,6 +4,8 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +// +build irix + package syscall const SizeofSockaddrInet4 = 16 diff --git a/libgo/go/syscall/socket_linux_ppc64x_type.go b/libgo/go/syscall/socket_linux_ppc64x_type.go index 8a707ce49d..96afdeb85f 100644 --- a/libgo/go/syscall/socket_linux_ppc64x_type.go +++ b/libgo/go/syscall/socket_linux_ppc64x_type.go @@ -4,6 +4,8 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +// +build linux,ppc64 linux,ppc64le + package syscall // Type needed on ppc64le & ppc64 diff --git a/libgo/go/syscall/socket_linux_type.go b/libgo/go/syscall/socket_linux_type.go index 45b8c6ec1d..190c11cc27 100644 --- a/libgo/go/syscall/socket_linux_type.go +++ b/libgo/go/syscall/socket_linux_type.go @@ -4,6 +4,10 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +// +build linux +// +build !ppc64 +// +build !ppc64le + package syscall // Type needed if not on ppc64le or ppc64 diff --git a/libgo/go/syscall/socket_posix.go b/libgo/go/syscall/socket_posix.go index fda7dc65e4..fe835d3c43 100644 --- a/libgo/go/syscall/socket_posix.go +++ b/libgo/go/syscall/socket_posix.go @@ -4,6 +4,8 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +// +build !solaris + package syscall //sys bind(fd int, sa *RawSockaddrAny, len Socklen_t) (err error) diff --git a/libgo/go/syscall/socket_xnet.go b/libgo/go/syscall/socket_xnet.go index 3c5b6b4180..c0699c44a8 100644 --- a/libgo/go/syscall/socket_xnet.go +++ b/libgo/go/syscall/socket_xnet.go @@ -5,6 +5,8 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +// +build solaris + package syscall //sys bind(fd int, sa *RawSockaddrAny, len Socklen_t) (err error) diff --git a/libgo/go/syscall/syscall.go b/libgo/go/syscall/syscall.go index 7d42ad5dce..91dfa9a049 100644 --- a/libgo/go/syscall/syscall.go +++ b/libgo/go/syscall/syscall.go @@ -3,10 +3,10 @@ // license that can be found in the LICENSE file. // Package syscall contains an interface to the low-level operating system -// primitives. The details vary depending on the underlying system, and +// primitives. The details vary depending on the underlying system, and // by default, godoc will display the syscall documentation for the current -// system. If you want godoc to display syscall documentation for another -// system, set $GOOS and $GOARCH to the desired system. For example, if +// system. If you want godoc to display syscall documentation for another +// system, set $GOOS and $GOARCH to the desired system. For example, if // you want to view documentation for freebsd/arm on linux/amd64, set $GOOS // to freebsd and $GOARCH to arm. // The primary use of syscall is inside other packages that provide a more @@ -28,6 +28,8 @@ package syscall import "unsafe" +//go:generate go run mksyscall_windows.go -systemdll -output zsyscall_windows.go syscall_windows.go security_windows.go + // StringByteSlice converts a string to a NUL-terminated []byte, // If s contains a NUL byte this function panics instead of // returning an error. @@ -97,6 +99,10 @@ func (tv *Timeval) Nano() int64 { return int64(tv.Sec)*1e9 + int64(tv.Usec)*1000 } +// Getpagesize is provided by the runtime. + +func Getpagesize() int + // use is a no-op, but the compiler cannot see that it is. // Calling use(p) ensures that p is kept live until that point. // This was needed until Go 1.6 to call syscall.Syscall correctly. diff --git a/libgo/go/syscall/syscall_darwin.go b/libgo/go/syscall/syscall_darwin.go new file mode 100644 index 0000000000..2847d2b8e3 --- /dev/null +++ b/libgo/go/syscall/syscall_darwin.go @@ -0,0 +1,19 @@ +// Copyright 2009,2010 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 syscall + +import "unsafe" + +func direntIno(buf []byte) (uint64, bool) { + return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino)) +} + +func direntReclen(buf []byte) (uint64, bool) { + return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen)) +} + +func direntNamlen(buf []byte) (uint64, bool) { + return readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen)) +} diff --git a/libgo/go/syscall/syscall_dragonfly.go b/libgo/go/syscall/syscall_dragonfly.go new file mode 100644 index 0000000000..c2fc67f44a --- /dev/null +++ b/libgo/go/syscall/syscall_dragonfly.go @@ -0,0 +1,23 @@ +// Copyright 2009,2010 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 syscall + +import "unsafe" + +func direntIno(buf []byte) (uint64, bool) { + return readInt(buf, unsafe.Offsetof(Dirent{}.Fileno), unsafe.Sizeof(Dirent{}.Fileno)) +} + +func direntReclen(buf []byte) (uint64, bool) { + namlen, ok := direntNamlen(buf) + if !ok { + return 0, false + } + return (16 + namlen + 1 + 7) & ^uint64(7), true +} + +func direntNamlen(buf []byte) (uint64, bool) { + return readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen)) +} diff --git a/libgo/go/syscall/syscall_freebsd.go b/libgo/go/syscall/syscall_freebsd.go new file mode 100644 index 0000000000..c67550a011 --- /dev/null +++ b/libgo/go/syscall/syscall_freebsd.go @@ -0,0 +1,19 @@ +// Copyright 2009,2010 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 syscall + +import "unsafe" + +func direntIno(buf []byte) (uint64, bool) { + return readInt(buf, unsafe.Offsetof(Dirent{}.Fileno), unsafe.Sizeof(Dirent{}.Fileno)) +} + +func direntReclen(buf []byte) (uint64, bool) { + return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen)) +} + +func direntNamlen(buf []byte) (uint64, bool) { + return readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen)) +} diff --git a/libgo/go/syscall/syscall_linux.go b/libgo/go/syscall/syscall_linux.go new file mode 100644 index 0000000000..338a9717f0 --- /dev/null +++ b/libgo/go/syscall/syscall_linux.go @@ -0,0 +1,23 @@ +// Copyright 2009 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 syscall + +import "unsafe" + +func direntIno(buf []byte) (uint64, bool) { + return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino)) +} + +func direntReclen(buf []byte) (uint64, bool) { + return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen)) +} + +func direntNamlen(buf []byte) (uint64, bool) { + reclen, ok := direntReclen(buf) + if !ok { + return 0, false + } + return reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true +} diff --git a/libgo/go/syscall/syscall_linux_mipsx.go b/libgo/go/syscall/syscall_linux_mipsx.go new file mode 100644 index 0000000000..af319ac345 --- /dev/null +++ b/libgo/go/syscall/syscall_linux_mipsx.go @@ -0,0 +1,12 @@ +// 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 +// +build mips mipsle + +package syscall + +func (r *PtraceRegs) PC() uint64 { return uint64(r.Regs[64]) } + +func (r *PtraceRegs) SetPC(pc uint64) { r.Regs[64] = uint32(pc) } diff --git a/libgo/go/syscall/syscall_linux_test.go b/libgo/go/syscall/syscall_linux_test.go index 4cabf6c9c9..2c4d953561 100644 --- a/libgo/go/syscall/syscall_linux_test.go +++ b/libgo/go/syscall/syscall_linux_test.go @@ -138,3 +138,31 @@ func deathSignalChild() { fmt.Println("not ok") os.Exit(1) } + +func TestParseNetlinkMessage(t *testing.T) { + for i, b := range [][]byte{ + {103, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 2, 11, 0, 1, 0, 0, 0, 0, 5, 8, 0, 3, + 0, 8, 0, 6, 0, 0, 0, 0, 1, 63, 0, 10, 0, 69, 16, 0, 59, 39, 82, 64, 0, 64, 6, 21, 89, 127, 0, 0, + 1, 127, 0, 0, 1, 230, 228, 31, 144, 32, 186, 155, 211, 185, 151, 209, 179, 128, 24, 1, 86, + 53, 119, 0, 0, 1, 1, 8, 10, 0, 17, 234, 12, 0, 17, 189, 126, 107, 106, 108, 107, 106, 13, 10, + }, + {106, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 2, 11, 0, 1, 0, 0, 0, 0, 3, 8, 0, 3, + 0, 8, 0, 6, 0, 0, 0, 0, 1, 66, 0, 10, 0, 69, 0, 0, 62, 230, 255, 64, 0, 64, 6, 85, 184, 127, 0, 0, + 1, 127, 0, 0, 1, 237, 206, 31, 144, 73, 197, 128, 65, 250, 60, 192, 97, 128, 24, 1, 86, 253, 21, 0, + 0, 1, 1, 8, 10, 0, 51, 106, 89, 0, 51, 102, 198, 108, 104, 106, 108, 107, 104, 108, 107, 104, 10, + }, + {102, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 2, 11, 0, 1, 0, 0, 0, 0, 1, 8, 0, 3, 0, + 8, 0, 6, 0, 0, 0, 0, 1, 62, 0, 10, 0, 69, 0, 0, 58, 231, 2, 64, 0, 64, 6, 85, 185, 127, 0, 0, 1, 127, + 0, 0, 1, 237, 206, 31, 144, 73, 197, 128, 86, 250, 60, 192, 97, 128, 24, 1, 86, 104, 64, 0, 0, 1, 1, 8, + 10, 0, 52, 198, 200, 0, 51, 135, 232, 101, 115, 97, 103, 103, 10, + }, + } { + m, err := syscall.ParseNetlinkMessage(b) + if err != syscall.EINVAL { + t.Errorf("#%d: got %v; want EINVAL", i, err) + } + if m != nil { + t.Errorf("#%d: got %v; want nil", i, m) + } + } +} diff --git a/libgo/go/syscall/syscall_netbsd.go b/libgo/go/syscall/syscall_netbsd.go new file mode 100644 index 0000000000..c67550a011 --- /dev/null +++ b/libgo/go/syscall/syscall_netbsd.go @@ -0,0 +1,19 @@ +// Copyright 2009,2010 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 syscall + +import "unsafe" + +func direntIno(buf []byte) (uint64, bool) { + return readInt(buf, unsafe.Offsetof(Dirent{}.Fileno), unsafe.Sizeof(Dirent{}.Fileno)) +} + +func direntReclen(buf []byte) (uint64, bool) { + return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen)) +} + +func direntNamlen(buf []byte) (uint64, bool) { + return readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen)) +} diff --git a/libgo/go/syscall/syscall_openbsd.go b/libgo/go/syscall/syscall_openbsd.go new file mode 100644 index 0000000000..c67550a011 --- /dev/null +++ b/libgo/go/syscall/syscall_openbsd.go @@ -0,0 +1,19 @@ +// Copyright 2009,2010 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 syscall + +import "unsafe" + +func direntIno(buf []byte) (uint64, bool) { + return readInt(buf, unsafe.Offsetof(Dirent{}.Fileno), unsafe.Sizeof(Dirent{}.Fileno)) +} + +func direntReclen(buf []byte) (uint64, bool) { + return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen)) +} + +func direntNamlen(buf []byte) (uint64, bool) { + return readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen)) +} diff --git a/libgo/go/syscall/syscall_solaris.go b/libgo/go/syscall/syscall_solaris.go index c1919171b7..673ba8223f 100644 --- a/libgo/go/syscall/syscall_solaris.go +++ b/libgo/go/syscall/syscall_solaris.go @@ -4,6 +4,8 @@ package syscall +import "unsafe" + func (ts *Timestruc) Unix() (sec int64, nsec int64) { return int64(ts.Sec), int64(ts.Nsec) } @@ -11,3 +13,36 @@ func (ts *Timestruc) Unix() (sec int64, nsec int64) { func (ts *Timestruc) Nano() int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } + +func direntIno(buf []byte) (uint64, bool) { + return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino)) +} + +func direntReclen(buf []byte) (uint64, bool) { + return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen)) +} + +func direntNamlen(buf []byte) (uint64, bool) { + reclen, ok := direntReclen(buf) + if !ok { + return 0, false + } + return reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true +} + +//sysnb getexecname() (execname unsafe.Pointer, err error) +//getexecname() *byte + +func Getexecname() (path string, err error) { + ptr, err := getexecname() + if err != nil { + return "", err + } + bytes := (*[1 << 29]byte)(ptr)[:] + for i, b := range bytes { + if b == 0 { + return string(bytes[:i]), nil + } + } + panic("unreachable") +} diff --git a/libgo/go/syscall/syscall_stubs.go b/libgo/go/syscall/syscall_stubs.go index 76c05cb546..00288ee5ea 100644 --- a/libgo/go/syscall/syscall_stubs.go +++ b/libgo/go/syscall/syscall_stubs.go @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +// +build rtems + // These are stubs. package syscall diff --git a/libgo/go/syscall/syscall_test.go b/libgo/go/syscall/syscall_test.go index 846c4873d2..c3fffda2df 100644 --- a/libgo/go/syscall/syscall_test.go +++ b/libgo/go/syscall/syscall_test.go @@ -6,6 +6,9 @@ package syscall_test import ( "fmt" + "internal/testenv" + "os" + "runtime" "syscall" "testing" ) @@ -45,3 +48,28 @@ func TestItoa(t *testing.T) { t.Fatalf("itoa(%d) = %s, want %s", i, s, f) } } + +// Check that permuting child process fds doesn't interfere with +// reporting of fork/exec status. See Issue 14979. +func TestExecErrPermutedFds(t *testing.T) { + testenv.MustHaveExec(t) + + attr := &os.ProcAttr{Files: []*os.File{os.Stdin, os.Stderr, os.Stdout}} + _, err := os.StartProcess("/", []string{"/"}, attr) + if err == nil { + t.Fatalf("StartProcess of invalid program returned err = nil") + } +} + +func TestGettimeofday(t *testing.T) { + if runtime.GOOS == "nacl" { + t.Skip("not implemented on nacl") + } + tv := &syscall.Timeval{} + if err := syscall.Gettimeofday(tv); err != nil { + t.Fatal(err) + } + if tv.Sec == 0 && tv.Usec == 0 { + t.Fatal("Sec and Usec both zero") + } +} diff --git a/libgo/go/syscall/syscall_unix.go b/libgo/go/syscall/syscall_unix.go index c47050d2ad..ddf7303df1 100644 --- a/libgo/go/syscall/syscall_unix.go +++ b/libgo/go/syscall/syscall_unix.go @@ -29,6 +29,7 @@ const ( darwin64Bit = runtime.GOOS == "darwin" && sizeofPtr == 8 dragonfly64Bit = runtime.GOOS == "dragonfly" && sizeofPtr == 8 netbsd32Bit = runtime.GOOS == "netbsd" && sizeofPtr == 4 + solaris64Bit = runtime.GOOS == "solaris" && sizeofPtr == 8 ) // Do a system call. We look at the size of uintptr to see how to pass diff --git a/libgo/go/syscall/syscall_unix_test.go b/libgo/go/syscall/syscall_unix_test.go index c7b4560b76..2f25d18bca 100644 --- a/libgo/go/syscall/syscall_unix_test.go +++ b/libgo/go/syscall/syscall_unix_test.go @@ -10,6 +10,7 @@ import ( "flag" "fmt" "internal/testenv" + "io" "io/ioutil" "net" "os" @@ -124,15 +125,6 @@ func TestFcntlFlock(t *testing.T) { // "-test.run=^TestPassFD$" and an environment variable used to signal // that the test should become the child process instead. func TestPassFD(t *testing.T) { - switch runtime.GOOS { - case "dragonfly": - // TODO(jsing): Figure out why sendmsg is returning EINVAL. - t.Skip("skipping test on dragonfly") - case "solaris": - // TODO(aram): Figure out why ReadMsgUnix is returning empty message. - t.Skip("skipping test on solaris, see issue 7402") - } - testenv.MustHaveExec(t) if os.Getenv("GO_WANT_HELPER_PROCESS") == "1" { @@ -244,7 +236,7 @@ func passFDChild() { } f.Write([]byte("Hello from child process!\n")) - f.Seek(0, 0) + f.Seek(0, io.SeekStart) rights := syscall.UnixRights(int(f.Fd())) dummyByte := []byte("x") @@ -344,7 +336,7 @@ func TestRlimit(t *testing.T) { } func TestSeekFailure(t *testing.T) { - _, err := syscall.Seek(-1, 0, 0) + _, err := syscall.Seek(-1, 0, io.SeekStart) if err == nil { t.Fatalf("Seek(-1, 0, 0) did not fail") } diff --git a/libgo/go/syscall/timestruct.go b/libgo/go/syscall/timestruct.go new file mode 100644 index 0000000000..49c3383b4f --- /dev/null +++ b/libgo/go/syscall/timestruct.go @@ -0,0 +1,40 @@ +// 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 darwin dragonfly freebsd linux nacl netbsd openbsd solaris + +package syscall + +// TimespecToNsec converts a Timespec value into a number of +// nanoseconds since the Unix epoch. +func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } + +// NsecToTimespec takes a number of nanoseconds since the Unix epoch +// and returns the corresponding Timespec value. +func NsecToTimespec(nsec int64) Timespec { + sec := nsec / 1e9 + nsec = nsec % 1e9 + if nsec < 0 { + nsec += 1e9 + sec-- + } + return setTimespec(sec, nsec) +} + +// TimevalToNsec converts a Timeval value into a number of nanoseconds +// since the Unix epoch. +func TimevalToNsec(tv Timeval) int64 { return int64(tv.Sec)*1e9 + int64(tv.Usec)*1e3 } + +// NsecToTimeval takes a number of nanoseconds since the Unix epoch +// and returns the corresponding Timeval value. +func NsecToTimeval(nsec int64) Timeval { + nsec += 999 // round up to microsecond + usec := nsec % 1e9 / 1e3 + sec := nsec / 1e9 + if usec < 0 { + usec += 1e6 + sec-- + } + return setTimeval(sec, usec) +} |