summaryrefslogtreecommitdiff
path: root/libgo/go/syscall
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2017-05-02 14:43:35 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2017-05-02 14:43:35 +0000
commit34efdaf078b01a7387007c4e6bde6db86384c4b7 (patch)
treed503eaf41d085669d1481bb46ec038bc866fece6 /libgo/go/syscall
parentf733cf303bcdc952c92b81dd62199a40a1f555ec (diff)
downloadgcc-tarball-master.tar.gz
gcc-7.1.0gcc-7.1.0
Diffstat (limited to 'libgo/go/syscall')
-rw-r--r--libgo/go/syscall/bpf_bsd.go20
-rw-r--r--libgo/go/syscall/clone_linux.c102
-rw-r--r--libgo/go/syscall/const_plan9.go11
-rw-r--r--libgo/go/syscall/creds_test.go2
-rw-r--r--libgo/go/syscall/dir_plan9.go3
-rw-r--r--libgo/go/syscall/dirent.go102
-rw-r--r--libgo/go/syscall/endian_big.go9
-rw-r--r--libgo/go/syscall/endian_little.go9
-rw-r--r--libgo/go/syscall/env_plan9.go2
-rw-r--r--libgo/go/syscall/env_unix.go2
-rw-r--r--libgo/go/syscall/env_windows.go4
-rw-r--r--libgo/go/syscall/errors_plan9.go2
-rw-r--r--libgo/go/syscall/errstr.go2
-rw-r--r--libgo/go/syscall/errstr_linux.go5
-rw-r--r--libgo/go/syscall/errstr_nor.go41
-rw-r--r--libgo/go/syscall/exec_bsd.go10
-rw-r--r--libgo/go/syscall/exec_linux.go76
-rw-r--r--libgo/go/syscall/exec_linux_test.go133
-rw-r--r--libgo/go/syscall/exec_solaris_test.go37
-rw-r--r--libgo/go/syscall/exec_stubs.go2
-rw-r--r--libgo/go/syscall/exec_unix.go26
-rw-r--r--libgo/go/syscall/exec_windows.go2
-rw-r--r--libgo/go/syscall/export_test.go2
-rw-r--r--libgo/go/syscall/export_unix_test.go2
-rw-r--r--libgo/go/syscall/libcall_bsd.go2
-rw-r--r--libgo/go/syscall/libcall_irix.go2
-rw-r--r--libgo/go/syscall/libcall_linux.go21
-rw-r--r--libgo/go/syscall/libcall_linux_ustat.go1
-rw-r--r--libgo/go/syscall/libcall_posix.go34
-rw-r--r--libgo/go/syscall/libcall_posix_largefile.go2
-rw-r--r--libgo/go/syscall/libcall_posix_regfile.go4
-rw-r--r--libgo/go/syscall/libcall_posix_utimesnano.go2
-rw-r--r--libgo/go/syscall/libcall_uname.go4
-rw-r--r--libgo/go/syscall/libcall_waitpid.go20
-rw-r--r--libgo/go/syscall/lsf_linux.go10
-rw-r--r--libgo/go/syscall/msan.go22
-rw-r--r--libgo/go/syscall/msan0.go2
-rw-r--r--libgo/go/syscall/netlink_linux.go7
-rw-r--r--libgo/go/syscall/route_bsd.go18
-rw-r--r--libgo/go/syscall/route_bsd_test.go260
-rw-r--r--libgo/go/syscall/route_darwin.go4
-rw-r--r--libgo/go/syscall/route_dragonfly.go6
-rw-r--r--libgo/go/syscall/route_freebsd.go6
-rw-r--r--libgo/go/syscall/route_ifma_test.go74
-rw-r--r--libgo/go/syscall/route_netbsd.go4
-rw-r--r--libgo/go/syscall/route_noifma_test.go63
-rw-r--r--libgo/go/syscall/route_openbsd.go4
-rw-r--r--libgo/go/syscall/security_windows.go2
-rw-r--r--libgo/go/syscall/setuidgid_32_linux.go13
-rw-r--r--libgo/go/syscall/setuidgid_linux.go13
-rw-r--r--libgo/go/syscall/sleep_rtems.go2
-rw-r--r--libgo/go/syscall/sleep_select.go8
-rw-r--r--libgo/go/syscall/sockcmsg_linux.go5
-rw-r--r--libgo/go/syscall/sockcmsg_unix.go11
-rw-r--r--libgo/go/syscall/socket_bsd.go2
-rw-r--r--libgo/go/syscall/socket_irix.go2
-rw-r--r--libgo/go/syscall/socket_linux_ppc64x_type.go2
-rw-r--r--libgo/go/syscall/socket_linux_type.go4
-rw-r--r--libgo/go/syscall/socket_posix.go2
-rw-r--r--libgo/go/syscall/socket_xnet.go2
-rw-r--r--libgo/go/syscall/syscall.go12
-rw-r--r--libgo/go/syscall/syscall_darwin.go19
-rw-r--r--libgo/go/syscall/syscall_dragonfly.go23
-rw-r--r--libgo/go/syscall/syscall_freebsd.go19
-rw-r--r--libgo/go/syscall/syscall_linux.go23
-rw-r--r--libgo/go/syscall/syscall_linux_mipsx.go12
-rw-r--r--libgo/go/syscall/syscall_linux_test.go28
-rw-r--r--libgo/go/syscall/syscall_netbsd.go19
-rw-r--r--libgo/go/syscall/syscall_openbsd.go19
-rw-r--r--libgo/go/syscall/syscall_solaris.go35
-rw-r--r--libgo/go/syscall/syscall_stubs.go2
-rw-r--r--libgo/go/syscall/syscall_test.go28
-rw-r--r--libgo/go/syscall/syscall_unix.go1
-rw-r--r--libgo/go/syscall/syscall_unix_test.go14
-rw-r--r--libgo/go/syscall/timestruct.go40
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)
+}