diff options
Diffstat (limited to 'libgo/go/syscall')
32 files changed, 425 insertions, 83 deletions
diff --git a/libgo/go/syscall/const_plan9.go b/libgo/go/syscall/const_plan9.go index ba26f123dea..063d5dfd7c2 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/dir_plan9.go b/libgo/go/syscall/dir_plan9.go index 15b267411cb..4ed052de761 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 diff --git a/libgo/go/syscall/dirent.go b/libgo/go/syscall/dirent.go new file mode 100644 index 00000000000..4db2d4355b5 --- /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 00000000000..b96594ec280 --- /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 00000000000..b6c9ed0f9f7 --- /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_windows.go b/libgo/go/syscall/env_windows.go index 3f751678ccb..1606b424ca0 100644 --- a/libgo/go/syscall/env_windows.go +++ b/libgo/go/syscall/env_windows.go @@ -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/exec_linux.go b/libgo/go/syscall/exec_linux.go index 83d9c1ca2db..8d6467a8720 100644 --- a/libgo/go/syscall/exec_linux.go +++ b/libgo/go/syscall/exec_linux.go @@ -216,11 +216,11 @@ func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr 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 } diff --git a/libgo/go/syscall/exec_linux_test.go b/libgo/go/syscall/exec_linux_test.go index aaffa067bcf..7a4b5717600 100644 --- a/libgo/go/syscall/exec_linux_test.go +++ b/libgo/go/syscall/exec_linux_test.go @@ -162,6 +162,12 @@ func TestUnshare(t *testing.T) { 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, @@ -178,8 +184,8 @@ func TestUnshare(t *testing.T) { } lines := strings.Split(sout, "\n") - if len(lines) != 3 { - t.Fatalf("Expected 3 lines of output, got %d", len(lines)) + if len(lines) >= len(origLines) { + t.Fatalf("Got %d lines of output, want <%d", len(lines), len(origLines)) } } diff --git a/libgo/go/syscall/exec_unix.go b/libgo/go/syscall/exec_unix.go index 3018b43d72e..c04005cdd6e 100644 --- a/libgo/go/syscall/exec_unix.go +++ b/libgo/go/syscall/exec_unix.go @@ -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 5a01843d2be..cafce1eff69 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/libcall_linux.go b/libgo/go/syscall/libcall_linux.go index ff81f547102..b58b2ddd6ea 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_posix.go b/libgo/go/syscall/libcall_posix.go index 84bbeda4127..76941c89b6f 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) diff --git a/libgo/go/syscall/netlink_linux.go b/libgo/go/syscall/netlink_linux.go index 26b30403a1a..1cda8c7704e 100644 --- a/libgo/go/syscall/netlink_linux.go +++ b/libgo/go/syscall/netlink_linux.go @@ -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/setuidgid_32_linux.go b/libgo/go/syscall/setuidgid_32_linux.go new file mode 100644 index 00000000000..182f5d26a90 --- /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 00000000000..bf40d2d8829 --- /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/sockcmsg_linux.go b/libgo/go/syscall/sockcmsg_linux.go index 5a56b25bebb..4cb9075ba8c 100644 --- a/libgo/go/syscall/sockcmsg_linux.go +++ b/libgo/go/syscall/sockcmsg_linux.go @@ -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 b25f8476394..016169929b7 100644 --- a/libgo/go/syscall/sockcmsg_unix.go +++ b/libgo/go/syscall/sockcmsg_unix.go @@ -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, diff --git a/libgo/go/syscall/syscall.go b/libgo/go/syscall/syscall.go index bb63e227cf9..91dfa9a0493 100644 --- a/libgo/go/syscall/syscall.go +++ b/libgo/go/syscall/syscall.go @@ -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 00000000000..2847d2b8e3e --- /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_darwin_test.go b/libgo/go/syscall/syscall_darwin_test.go deleted file mode 100644 index cea5636d07d..00000000000 --- a/libgo/go/syscall/syscall_darwin_test.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build darwin -// +build amd64 386 arm arm64 - -package syscall_test - -import ( - "syscall" - "testing" -) - -func TestDarwinGettimeofday(t *testing.T) { - 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_dragonfly.go b/libgo/go/syscall/syscall_dragonfly.go new file mode 100644 index 00000000000..c2fc67f44a7 --- /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 00000000000..c67550a011d --- /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 00000000000..338a9717f01 --- /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 00000000000..af319ac345f --- /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 4cabf6c9c90..2c4d953561a 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 00000000000..c67550a011d --- /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 00000000000..c67550a011d --- /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 c1919171b7d..0b2d7483e42 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,19 @@ 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 +} diff --git a/libgo/go/syscall/syscall_test.go b/libgo/go/syscall/syscall_test.go index 0a0b8b7a26d..c3fffda2df5 100644 --- a/libgo/go/syscall/syscall_test.go +++ b/libgo/go/syscall/syscall_test.go @@ -8,6 +8,7 @@ import ( "fmt" "internal/testenv" "os" + "runtime" "syscall" "testing" ) @@ -59,3 +60,16 @@ func TestExecErrPermutedFds(t *testing.T) { 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 c47050d2ad7..ddf7303df14 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 80544f33192..2f25d18bca9 100644 --- a/libgo/go/syscall/syscall_unix_test.go +++ b/libgo/go/syscall/syscall_unix_test.go @@ -125,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" { diff --git a/libgo/go/syscall/timestruct.go b/libgo/go/syscall/timestruct.go new file mode 100644 index 00000000000..49c3383b4f7 --- /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) +} |