Commit cc5fb5d9 authored by Joel Sing's avatar Joel Sing

cmd/vendor: update golang.org/x/sys/unix

Update golang.org/x/sys/unix to revision b05ddf57801d2239d6ab0ee35f9d981e0420f4ac.

Changes exist in upstream golang.org/x/sys/unix, which allow for code to work and
tests to pass on openbsd/arm.

Change-Id: Iecc8598681a23cb0466f94c914f0e605a6fc64d7
Reviewed-on: https://go-review.googlesource.com/c/153838Reviewed-by: default avatarBrad Fitzpatrick <bradfitz@golang.org>
parent bbae8d55
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
// +build go1.9
package unix
import "syscall"
type Signal = syscall.Signal
type Errno = syscall.Errno
type SysProcAttr = syscall.SysProcAttr
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build !gccgo
#include "textflag.h"
//
// System calls for ppc64, AIX are implemented in runtime/syscall_aix.go
//
TEXT ·syscall6(SB),NOSPLIT,$0-88
JMP syscall·syscall6(SB)
TEXT ·rawSyscall6(SB),NOSPLIT,$0-88
JMP syscall·rawSyscall6(SB)
...@@ -15,12 +15,6 @@ ...@@ -15,12 +15,6 @@
// Just jump to package syscall's implementation for all these functions. // Just jump to package syscall's implementation for all these functions.
// The runtime may know about them. // The runtime may know about them.
TEXT ·Syscall(SB),NOSPLIT,$0-56
BR syscall·Syscall(SB)
TEXT ·Syscall6(SB),NOSPLIT,$0-80
BR syscall·Syscall6(SB)
TEXT ·SyscallNoError(SB),NOSPLIT,$0-48 TEXT ·SyscallNoError(SB),NOSPLIT,$0-48
BL runtime·entersyscall(SB) BL runtime·entersyscall(SB)
MOVD a1+8(FP), R3 MOVD a1+8(FP), R3
...@@ -36,12 +30,6 @@ TEXT ·SyscallNoError(SB),NOSPLIT,$0-48 ...@@ -36,12 +30,6 @@ TEXT ·SyscallNoError(SB),NOSPLIT,$0-48
BL runtime·exitsyscall(SB) BL runtime·exitsyscall(SB)
RET RET
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
BR syscall·RawSyscall(SB)
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
BR syscall·RawSyscall6(SB)
TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-48 TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-48
MOVD a1+8(FP), R3 MOVD a1+8(FP), R3
MOVD a2+16(FP), R4 MOVD a2+16(FP), R4
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build darwin dragonfly freebsd linux netbsd openbsd solaris // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
package unix package unix
......
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build aix
// +build ppc
// Functions to access/create device major and minor numbers matching the
// encoding used by AIX.
package unix
// Major returns the major component of a Linux device number.
func Major(dev uint64) uint32 {
return uint32((dev >> 16) & 0xffff)
}
// Minor returns the minor component of a Linux device number.
func Minor(dev uint64) uint32 {
return uint32(dev & 0xffff)
}
// Mkdev returns a Linux device number generated from the given major and minor
// components.
func Mkdev(major, minor uint32) uint64 {
return uint64(((major) << 16) | (minor))
}
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build aix
// +build ppc64
// Functions to access/create device major and minor numbers matching the
// encoding used AIX.
package unix
// Major returns the major component of a Linux device number.
func Major(dev uint64) uint32 {
return uint32((dev & 0x3fffffff00000000) >> 32)
}
// Minor returns the minor component of a Linux device number.
func Minor(dev uint64) uint32 {
return uint32((dev & 0x00000000ffffffff) >> 0)
}
// Mkdev returns a Linux device number generated from the given major and minor
// components.
func Mkdev(major, minor uint32) uint64 {
var DEVNO64 uint64
DEVNO64 = 0x8000000000000000
return ((uint64(major) << 32) | (uint64(minor) & 0x00000000FFFFFFFF) | DEVNO64)
}
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris // +build aix darwin dragonfly freebsd linux nacl netbsd openbsd solaris
package unix package unix
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build darwin dragonfly freebsd linux netbsd openbsd solaris // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
// Unix environment variables. // Unix environment variables.
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build darwin dragonfly freebsd linux netbsd openbsd solaris // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
package unix_test package unix_test
...@@ -17,3 +17,14 @@ func ExampleExec() { ...@@ -17,3 +17,14 @@ func ExampleExec() {
err := unix.Exec("/bin/ls", []string{"ls", "-al"}, os.Environ()) err := unix.Exec("/bin/ls", []string{"ls", "-al"}, os.Environ())
log.Fatal(err) log.Fatal(err)
} }
func ExampleFlock() {
f, _ := os.Create("example.lock")
if err := unix.Flock(int(f.Fd()), unix.LOCK_EX); err != nil {
log.Fatal(err)
}
// Do work here that requires the lock. When finished, release the lock:
if err := unix.Flock(int(f.Fd()), unix.LOCK_UN); err != nil {
log.Fatal(err)
}
}
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build darwin dragonfly freebsd linux netbsd openbsd solaris // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
package unix package unix
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build gccgo // +build gccgo
// +build !aix
package unix package unix
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build gccgo // +build gccgo
// +build !aix
#include <errno.h> #include <errno.h>
#include <stdint.h> #include <stdint.h>
......
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
package unix
import "runtime"
// IoctlSetWinsize performs an ioctl on fd with a *Winsize argument.
//
// To change fd's window size, the req argument should be TIOCSWINSZ.
func IoctlSetWinsize(fd int, req uint, value *Winsize) error {
// TODO: if we get the chance, remove the req parameter and
// hardcode TIOCSWINSZ.
err := ioctlSetWinsize(fd, req, value)
runtime.KeepAlive(value)
return err
}
// IoctlSetTermios performs an ioctl on fd with a *Termios.
//
// The req value will usually be TCSETA or TIOCSETA.
func IoctlSetTermios(fd int, req uint, value *Termios) error {
// TODO: if we get the chance, remove the req parameter.
err := ioctlSetTermios(fd, req, value)
runtime.KeepAlive(value)
return err
}
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
GOOSARCH="${GOOS}_${GOARCH}" GOOSARCH="${GOOS}_${GOARCH}"
# defaults # defaults
mksyscall="./mksyscall.pl" mksyscall="go run mksyscall.go"
mkerrors="./mkerrors.sh" mkerrors="./mkerrors.sh"
zerrors="zerrors_$GOOSARCH.go" zerrors="zerrors_$GOOSARCH.go"
mksysctl="" mksysctl=""
...@@ -59,9 +59,19 @@ _* | *_ | _) ...@@ -59,9 +59,19 @@ _* | *_ | _)
echo 'undefined $GOOS_$GOARCH:' "$GOOSARCH" 1>&2 echo 'undefined $GOOS_$GOARCH:' "$GOOSARCH" 1>&2
exit 1 exit 1
;; ;;
aix_ppc)
mkerrors="$mkerrors -maix32"
mksyscall="./mksyscall_aix_ppc.pl -aix"
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
;;
aix_ppc64)
mkerrors="$mkerrors -maix64"
mksyscall="./mksyscall_aix_ppc64.pl -aix"
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
;;
darwin_386) darwin_386)
mkerrors="$mkerrors -m32" mkerrors="$mkerrors -m32"
mksyscall="./mksyscall.pl -l32" mksyscall="go run mksyscall.go -l32"
mksysnum="./mksysnum_darwin.pl $(xcrun --show-sdk-path --sdk macosx)/usr/include/sys/syscall.h" mksysnum="./mksysnum_darwin.pl $(xcrun --show-sdk-path --sdk macosx)/usr/include/sys/syscall.h"
mktypes="GOARCH=$GOARCH go tool cgo -godefs" mktypes="GOARCH=$GOARCH go tool cgo -godefs"
;; ;;
...@@ -82,13 +92,13 @@ darwin_arm64) ...@@ -82,13 +92,13 @@ darwin_arm64)
;; ;;
dragonfly_amd64) dragonfly_amd64)
mkerrors="$mkerrors -m64" mkerrors="$mkerrors -m64"
mksyscall="./mksyscall.pl -dragonfly" mksyscall="go run mksyscall.go -dragonfly"
mksysnum="curl -s 'http://gitweb.dragonflybsd.org/dragonfly.git/blob_plain/HEAD:/sys/kern/syscalls.master' | ./mksysnum_dragonfly.pl" mksysnum="curl -s 'http://gitweb.dragonflybsd.org/dragonfly.git/blob_plain/HEAD:/sys/kern/syscalls.master' | ./mksysnum_dragonfly.pl"
mktypes="GOARCH=$GOARCH go tool cgo -godefs" mktypes="GOARCH=$GOARCH go tool cgo -godefs"
;; ;;
freebsd_386) freebsd_386)
mkerrors="$mkerrors -m32" mkerrors="$mkerrors -m32"
mksyscall="./mksyscall.pl -l32" mksyscall="go run mksyscall.go -l32"
mksysnum="curl -s 'http://svn.freebsd.org/base/stable/10/sys/kern/syscalls.master' | ./mksysnum_freebsd.pl" mksysnum="curl -s 'http://svn.freebsd.org/base/stable/10/sys/kern/syscalls.master' | ./mksysnum_freebsd.pl"
mktypes="GOARCH=$GOARCH go tool cgo -godefs" mktypes="GOARCH=$GOARCH go tool cgo -godefs"
;; ;;
...@@ -99,7 +109,7 @@ freebsd_amd64) ...@@ -99,7 +109,7 @@ freebsd_amd64)
;; ;;
freebsd_arm) freebsd_arm)
mkerrors="$mkerrors" mkerrors="$mkerrors"
mksyscall="./mksyscall.pl -l32 -arm" mksyscall="go run mksyscall.go -l32 -arm"
mksysnum="curl -s 'http://svn.freebsd.org/base/stable/10/sys/kern/syscalls.master' | ./mksysnum_freebsd.pl" mksysnum="curl -s 'http://svn.freebsd.org/base/stable/10/sys/kern/syscalls.master' | ./mksysnum_freebsd.pl"
# Let the type of C char be signed for making the bare syscall # Let the type of C char be signed for making the bare syscall
# API consistent across platforms. # API consistent across platforms.
...@@ -114,19 +124,19 @@ linux_sparc64) ...@@ -114,19 +124,19 @@ linux_sparc64)
;; ;;
netbsd_386) netbsd_386)
mkerrors="$mkerrors -m32" mkerrors="$mkerrors -m32"
mksyscall="./mksyscall.pl -l32 -netbsd" mksyscall="go run mksyscall.go -l32 -netbsd"
mksysnum="curl -s 'http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_netbsd.pl" mksysnum="curl -s 'http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_netbsd.pl"
mktypes="GOARCH=$GOARCH go tool cgo -godefs" mktypes="GOARCH=$GOARCH go tool cgo -godefs"
;; ;;
netbsd_amd64) netbsd_amd64)
mkerrors="$mkerrors -m64" mkerrors="$mkerrors -m64"
mksyscall="./mksyscall.pl -netbsd" mksyscall="go run mksyscall.go -netbsd"
mksysnum="curl -s 'http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_netbsd.pl" mksysnum="curl -s 'http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_netbsd.pl"
mktypes="GOARCH=$GOARCH go tool cgo -godefs" mktypes="GOARCH=$GOARCH go tool cgo -godefs"
;; ;;
netbsd_arm) netbsd_arm)
mkerrors="$mkerrors" mkerrors="$mkerrors"
mksyscall="./mksyscall.pl -l32 -netbsd -arm" mksyscall="go run mksyscall.go -l32 -netbsd -arm"
mksysnum="curl -s 'http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_netbsd.pl" mksysnum="curl -s 'http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_netbsd.pl"
# Let the type of C char be signed for making the bare syscall # Let the type of C char be signed for making the bare syscall
# API consistent across platforms. # API consistent across platforms.
...@@ -134,21 +144,21 @@ netbsd_arm) ...@@ -134,21 +144,21 @@ netbsd_arm)
;; ;;
openbsd_386) openbsd_386)
mkerrors="$mkerrors -m32" mkerrors="$mkerrors -m32"
mksyscall="./mksyscall.pl -l32 -openbsd" mksyscall="go run mksyscall.go -l32 -openbsd"
mksysctl="./mksysctl_openbsd.pl" mksysctl="./mksysctl_openbsd.pl"
mksysnum="curl -s 'http://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_openbsd.pl" mksysnum="curl -s 'http://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_openbsd.pl"
mktypes="GOARCH=$GOARCH go tool cgo -godefs" mktypes="GOARCH=$GOARCH go tool cgo -godefs"
;; ;;
openbsd_amd64) openbsd_amd64)
mkerrors="$mkerrors -m64" mkerrors="$mkerrors -m64"
mksyscall="./mksyscall.pl -openbsd" mksyscall="go run mksyscall.go -openbsd"
mksysctl="./mksysctl_openbsd.pl" mksysctl="./mksysctl_openbsd.pl"
mksysnum="curl -s 'http://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_openbsd.pl" mksysnum="curl -s 'http://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_openbsd.pl"
mktypes="GOARCH=$GOARCH go tool cgo -godefs" mktypes="GOARCH=$GOARCH go tool cgo -godefs"
;; ;;
openbsd_arm) openbsd_arm)
mkerrors="$mkerrors" mkerrors="$mkerrors"
mksyscall="./mksyscall.pl -l32 -openbsd -arm" mksyscall="go run mksyscall.go -l32 -openbsd -arm"
mksysctl="./mksysctl_openbsd.pl" mksysctl="./mksysctl_openbsd.pl"
mksysnum="curl -s 'http://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_openbsd.pl" mksysnum="curl -s 'http://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_openbsd.pl"
# Let the type of C char be signed for making the bare syscall # Let the type of C char be signed for making the bare syscall
...@@ -177,8 +187,14 @@ esac ...@@ -177,8 +187,14 @@ esac
syscall_goos="syscall_bsd.go $syscall_goos" syscall_goos="syscall_bsd.go $syscall_goos"
;; ;;
esac esac
if [ -n "$mksyscall" ]; then echo "$mksyscall -tags $GOOS,$GOARCH $syscall_goos $GOOSARCH_in |gofmt >zsyscall_$GOOSARCH.go"; fi if [ -n "$mksyscall" ]; then
;; if [ "$GOOSARCH" == "aix_ppc64" ]; then
# aix/ppc64 script generates files instead of writing to stdin.
echo "$mksyscall -tags $GOOS,$GOARCH $syscall_goos $GOOSARCH_in && gofmt -w zsyscall_$GOOSARCH.go && gofmt -w zsyscall_"$GOOSARCH"_gccgo.go && gofmt -w zsyscall_"$GOOSARCH"_gc.go " ;
else
echo "$mksyscall -tags $GOOS,$GOARCH $syscall_goos $GOOSARCH_in |gofmt >zsyscall_$GOOSARCH.go";
fi
fi
esac esac
if [ -n "$mksysctl" ]; then echo "$mksysctl |gofmt >$zsysctl"; fi if [ -n "$mksysctl" ]; then echo "$mksysctl |gofmt >$zsysctl"; fi
if [ -n "$mksysnum" ]; then echo "$mksysnum |gofmt >zsysnum_$GOOSARCH.go"; fi if [ -n "$mksysnum" ]; then echo "$mksysnum |gofmt >zsysnum_$GOOSARCH.go"; fi
......
...@@ -25,7 +25,11 @@ if [[ "$GOOS" = "linux" ]] && [[ "$GOARCH" != "sparc64" ]]; then ...@@ -25,7 +25,11 @@ if [[ "$GOOS" = "linux" ]] && [[ "$GOARCH" != "sparc64" ]]; then
fi fi
fi fi
CC=${CC:-cc} if [[ "$GOOS" = "aix" ]]; then
CC=${CC:-gcc}
else
CC=${CC:-cc}
fi
if [[ "$GOOS" = "solaris" ]]; then if [[ "$GOOS" = "solaris" ]]; then
# Assumes GNU versions of utilities in PATH. # Assumes GNU versions of utilities in PATH.
...@@ -34,6 +38,21 @@ fi ...@@ -34,6 +38,21 @@ fi
uname=$(uname) uname=$(uname)
includes_AIX='
#include <net/if.h>
#include <net/netopt.h>
#include <netinet/ip_mroute.h>
#include <sys/protosw.h>
#include <sys/stropts.h>
#include <sys/mman.h>
#include <sys/poll.h>
#include <sys/termio.h>
#include <termios.h>
#include <fcntl.h>
#define AF_LOCAL AF_UNIX
'
includes_Darwin=' includes_Darwin='
#define _DARWIN_C_SOURCE #define _DARWIN_C_SOURCE
#define KERNEL #define KERNEL
...@@ -65,8 +84,10 @@ includes_DragonFly=' ...@@ -65,8 +84,10 @@ includes_DragonFly='
#include <sys/event.h> #include <sys/event.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/sockio.h> #include <sys/sockio.h>
#include <sys/stat.h>
#include <sys/sysctl.h> #include <sys/sysctl.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <sys/mount.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <net/bpf.h> #include <net/bpf.h>
...@@ -80,12 +101,13 @@ includes_DragonFly=' ...@@ -80,12 +101,13 @@ includes_DragonFly='
' '
includes_FreeBSD=' includes_FreeBSD='
#include <sys/capability.h> #include <sys/capsicum.h>
#include <sys/param.h> #include <sys/param.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/event.h> #include <sys/event.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/sockio.h> #include <sys/sockio.h>
#include <sys/stat.h>
#include <sys/sysctl.h> #include <sys/sysctl.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <sys/mount.h> #include <sys/mount.h>
...@@ -165,16 +187,21 @@ struct ltchars { ...@@ -165,16 +187,21 @@ struct ltchars {
#include <linux/if_alg.h> #include <linux/if_alg.h>
#include <linux/if_arp.h> #include <linux/if_arp.h>
#include <linux/if_ether.h> #include <linux/if_ether.h>
#include <linux/if_ppp.h>
#include <linux/if_tun.h> #include <linux/if_tun.h>
#include <linux/if_packet.h> #include <linux/if_packet.h>
#include <linux/if_addr.h> #include <linux/if_addr.h>
#include <linux/falloc.h> #include <linux/falloc.h>
#include <linux/filter.h> #include <linux/filter.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/kexec.h>
#include <linux/keyctl.h> #include <linux/keyctl.h>
#include <linux/magic.h> #include <linux/magic.h>
#include <linux/memfd.h>
#include <linux/module.h>
#include <linux/netfilter/nfnetlink.h> #include <linux/netfilter/nfnetlink.h>
#include <linux/netlink.h> #include <linux/netlink.h>
#include <linux/net_namespace.h>
#include <linux/perf_event.h> #include <linux/perf_event.h>
#include <linux/random.h> #include <linux/random.h>
#include <linux/reboot.h> #include <linux/reboot.h>
...@@ -190,10 +217,11 @@ struct ltchars { ...@@ -190,10 +217,11 @@ struct ltchars {
#include <linux/vm_sockets.h> #include <linux/vm_sockets.h>
#include <linux/taskstats.h> #include <linux/taskstats.h>
#include <linux/genetlink.h> #include <linux/genetlink.h>
#include <linux/stat.h>
#include <linux/watchdog.h> #include <linux/watchdog.h>
#include <linux/hdreg.h> #include <linux/hdreg.h>
#include <linux/rtc.h> #include <linux/rtc.h>
#include <linux/if_xdp.h>
#include <mtd/ubi-user.h>
#include <net/route.h> #include <net/route.h>
#include <asm/termbits.h> #include <asm/termbits.h>
...@@ -223,13 +251,25 @@ struct ltchars { ...@@ -223,13 +251,25 @@ struct ltchars {
#define FS_KEY_DESC_PREFIX "fscrypt:" #define FS_KEY_DESC_PREFIX "fscrypt:"
#define FS_KEY_DESC_PREFIX_SIZE 8 #define FS_KEY_DESC_PREFIX_SIZE 8
#define FS_MAX_KEY_SIZE 64 #define FS_MAX_KEY_SIZE 64
// XDP socket constants do not appear to be picked up otherwise.
// Copied from samples/bpf/xdpsock_user.c.
#ifndef SOL_XDP
#define SOL_XDP 283
#endif
#ifndef AF_XDP
#define AF_XDP 44
#endif
' '
includes_NetBSD=' includes_NetBSD='
#include <sys/types.h> #include <sys/types.h>
#include <sys/param.h> #include <sys/param.h>
#include <sys/event.h> #include <sys/event.h>
#include <sys/extattr.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <sys/mount.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/sockio.h> #include <sys/sockio.h>
#include <sys/sysctl.h> #include <sys/sysctl.h>
...@@ -255,11 +295,14 @@ includes_OpenBSD=' ...@@ -255,11 +295,14 @@ includes_OpenBSD='
#include <sys/param.h> #include <sys/param.h>
#include <sys/event.h> #include <sys/event.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <sys/mount.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/sockio.h> #include <sys/sockio.h>
#include <sys/stat.h>
#include <sys/sysctl.h> #include <sys/sysctl.h>
#include <sys/termios.h> #include <sys/termios.h>
#include <sys/ttycom.h> #include <sys/ttycom.h>
#include <sys/unistd.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <net/bpf.h> #include <net/bpf.h>
#include <net/if.h> #include <net/if.h>
...@@ -291,6 +334,7 @@ includes_SunOS=' ...@@ -291,6 +334,7 @@ includes_SunOS='
#include <sys/types.h> #include <sys/types.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/sockio.h> #include <sys/sockio.h>
#include <sys/stat.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
...@@ -353,6 +397,7 @@ ccflags="$@" ...@@ -353,6 +397,7 @@ ccflags="$@"
$2 ~ /^EXTATTR_NAMESPACE_NAMES/ || $2 ~ /^EXTATTR_NAMESPACE_NAMES/ ||
$2 ~ /^EXTATTR_NAMESPACE_[A-Z]+_STRING/ {next} $2 ~ /^EXTATTR_NAMESPACE_[A-Z]+_STRING/ {next}
$2 !~ /^ECCAPBITS/ &&
$2 !~ /^ETH_/ && $2 !~ /^ETH_/ &&
$2 !~ /^EPROC_/ && $2 !~ /^EPROC_/ &&
$2 !~ /^EQUIV_/ && $2 !~ /^EQUIV_/ &&
...@@ -388,7 +433,7 @@ ccflags="$@" ...@@ -388,7 +433,7 @@ ccflags="$@"
$2 ~ /^TC[IO](ON|OFF)$/ || $2 ~ /^TC[IO](ON|OFF)$/ ||
$2 ~ /^IN_/ || $2 ~ /^IN_/ ||
$2 ~ /^LOCK_(SH|EX|NB|UN)$/ || $2 ~ /^LOCK_(SH|EX|NB|UN)$/ ||
$2 ~ /^(AF|SOCK|SO|SOL|IPPROTO|IP|IPV6|ICMP6|TCP|EVFILT|NOTE|EV|SHUT|PROT|MAP|T?PACKET|MSG|SCM|MCL|DT|MADV|PR)_/ || $2 ~ /^(AF|SOCK|SO|SOL|IPPROTO|IP|IPV6|ICMP6|TCP|EVFILT|NOTE|EV|SHUT|PROT|MAP|MFD|T?PACKET|MSG|SCM|MCL|DT|MADV|PR)_/ ||
$2 ~ /^TP_STATUS_/ || $2 ~ /^TP_STATUS_/ ||
$2 ~ /^FALLOC_/ || $2 ~ /^FALLOC_/ ||
$2 == "ICMPV6_FILTER" || $2 == "ICMPV6_FILTER" ||
...@@ -399,13 +444,16 @@ ccflags="$@" ...@@ -399,13 +444,16 @@ ccflags="$@"
$2 ~ /^KERN_(HOSTNAME|OS(RELEASE|TYPE)|VERSION)$/ || $2 ~ /^KERN_(HOSTNAME|OS(RELEASE|TYPE)|VERSION)$/ ||
$2 ~ /^HW_MACHINE$/ || $2 ~ /^HW_MACHINE$/ ||
$2 ~ /^SYSCTL_VERS/ || $2 ~ /^SYSCTL_VERS/ ||
$2 !~ "MNT_BITS" &&
$2 ~ /^(MS|MNT|UMOUNT)_/ || $2 ~ /^(MS|MNT|UMOUNT)_/ ||
$2 ~ /^TUN(SET|GET|ATTACH|DETACH)/ || $2 ~ /^TUN(SET|GET|ATTACH|DETACH)/ ||
$2 ~ /^(O|F|E?FD|NAME|S|PTRACE|PT)_/ || $2 ~ /^(O|F|E?FD|NAME|S|PTRACE|PT)_/ ||
$2 ~ /^KEXEC_/ ||
$2 ~ /^LINUX_REBOOT_CMD_/ || $2 ~ /^LINUX_REBOOT_CMD_/ ||
$2 ~ /^LINUX_REBOOT_MAGIC[12]$/ || $2 ~ /^LINUX_REBOOT_MAGIC[12]$/ ||
$2 ~ /^MODULE_INIT_/ ||
$2 !~ "NLA_TYPE_MASK" && $2 !~ "NLA_TYPE_MASK" &&
$2 ~ /^(NETLINK|NLM|NLMSG|NLA|IFA|IFAN|RT|RTC|RTCF|RTN|RTPROT|RTNH|ARPHRD|ETH_P)_/ || $2 ~ /^(NETLINK|NLM|NLMSG|NLA|IFA|IFAN|RT|RTC|RTCF|RTN|RTPROT|RTNH|ARPHRD|ETH_P|NETNSA)_/ ||
$2 ~ /^SIOC/ || $2 ~ /^SIOC/ ||
$2 ~ /^TIOC/ || $2 ~ /^TIOC/ ||
$2 ~ /^TCGET/ || $2 ~ /^TCGET/ ||
...@@ -431,23 +479,29 @@ ccflags="$@" ...@@ -431,23 +479,29 @@ ccflags="$@"
$2 ~ /^PERF_EVENT_IOC_/ || $2 ~ /^PERF_EVENT_IOC_/ ||
$2 ~ /^SECCOMP_MODE_/ || $2 ~ /^SECCOMP_MODE_/ ||
$2 ~ /^SPLICE_/ || $2 ~ /^SPLICE_/ ||
$2 ~ /^SYNC_FILE_RANGE_/ ||
$2 !~ /^AUDIT_RECORD_MAGIC/ && $2 !~ /^AUDIT_RECORD_MAGIC/ &&
$2 ~ /^[A-Z0-9_]+_MAGIC2?$/ || $2 !~ /IOC_MAGIC/ &&
$2 ~ /^[A-Z][A-Z0-9_]+_MAGIC2?$/ ||
$2 ~ /^(VM|VMADDR)_/ || $2 ~ /^(VM|VMADDR)_/ ||
$2 ~ /^IOCTL_VM_SOCKETS_/ || $2 ~ /^IOCTL_VM_SOCKETS_/ ||
$2 ~ /^(TASKSTATS|TS)_/ || $2 ~ /^(TASKSTATS|TS)_/ ||
$2 ~ /^CGROUPSTATS_/ || $2 ~ /^CGROUPSTATS_/ ||
$2 ~ /^GENL_/ || $2 ~ /^GENL_/ ||
$2 ~ /^STATX_/ || $2 ~ /^STATX_/ ||
$2 ~ /^RENAME/ ||
$2 ~ /^UBI_IOC[A-Z]/ ||
$2 ~ /^UTIME_/ || $2 ~ /^UTIME_/ ||
$2 ~ /^XATTR_(CREATE|REPLACE|NO(DEFAULT|FOLLOW|SECURITY)|SHOWCOMPRESSION)/ || $2 ~ /^XATTR_(CREATE|REPLACE|NO(DEFAULT|FOLLOW|SECURITY)|SHOWCOMPRESSION)/ ||
$2 ~ /^ATTR_(BIT_MAP_COUNT|(CMN|VOL|FILE)_)/ || $2 ~ /^ATTR_(BIT_MAP_COUNT|(CMN|VOL|FILE)_)/ ||
$2 ~ /^FSOPT_/ || $2 ~ /^FSOPT_/ ||
$2 ~ /^WDIOC_/ || $2 ~ /^WDIOC_/ ||
$2 ~ /^NFN/ || $2 ~ /^NFN/ ||
$2 ~ /^XDP_/ ||
$2 ~ /^(HDIO|WIN|SMART)_/ || $2 ~ /^(HDIO|WIN|SMART)_/ ||
$2 !~ "WMESGLEN" && $2 !~ "WMESGLEN" &&
$2 ~ /^W[A-Z0-9]+$/ || $2 ~ /^W[A-Z0-9]+$/ ||
$2 ~/^PPPIOC/ ||
$2 ~ /^BLK[A-Z]*(GET$|SET$|BUF$|PART$|SIZE)/ {printf("\t%s = C.%s\n", $2, $2)} $2 ~ /^BLK[A-Z]*(GET$|SET$|BUF$|PART$|SIZE)/ {printf("\t%s = C.%s\n", $2, $2)}
$2 ~ /^__WCOREFLAG$/ {next} $2 ~ /^__WCOREFLAG$/ {next}
$2 ~ /^__W[A-Z0-9]+$/ {printf("\t%s = C.%s\n", substr($2,3), $2)} $2 ~ /^__W[A-Z0-9]+$/ {printf("\t%s = C.%s\n", substr($2,3), $2)}
...@@ -469,7 +523,7 @@ errors=$( ...@@ -469,7 +523,7 @@ errors=$(
signals=$( signals=$(
echo '#include <signal.h>' | $CC -x c - -E -dM $ccflags | echo '#include <signal.h>' | $CC -x c - -E -dM $ccflags |
awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print $2 }' | awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print $2 }' |
egrep -v '(SIGSTKSIZE|SIGSTKSZ|SIGRT)' | egrep -v '(SIGSTKSIZE|SIGSTKSZ|SIGRT|SIGMAX64)' |
sort sort
) )
...@@ -479,7 +533,7 @@ echo '#include <errno.h>' | $CC -x c - -E -dM $ccflags | ...@@ -479,7 +533,7 @@ echo '#include <errno.h>' | $CC -x c - -E -dM $ccflags |
sort >_error.grep sort >_error.grep
echo '#include <signal.h>' | $CC -x c - -E -dM $ccflags | echo '#include <signal.h>' | $CC -x c - -E -dM $ccflags |
awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print "^\t" $2 "[ \t]*=" }' | awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print "^\t" $2 "[ \t]*=" }' |
egrep -v '(SIGSTKSIZE|SIGSTKSZ|SIGRT)' | egrep -v '(SIGSTKSIZE|SIGSTKSZ|SIGRT|SIGMAX64)' |
sort >_signal.grep sort >_signal.grep
echo '// mkerrors.sh' "$@" echo '// mkerrors.sh' "$@"
......
#!/usr/bin/env perl
# Copyright 2018 The Go Authors. All rights reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.
# This program reads a file containing function prototypes
# (like syscall_aix.go) and generates system call bodies.
# The prototypes are marked by lines beginning with "//sys"
# and read like func declarations if //sys is replaced by func, but:
# * The parameter lists must give a name for each argument.
# This includes return parameters.
# * The parameter lists must give a type for each argument:
# the (x, y, z int) shorthand is not allowed.
# * If the return parameter is an error number, it must be named err.
# * If go func name needs to be different than its libc name,
# * or the function is not in libc, name could be specified
# * at the end, after "=" sign, like
# //sys getsockopt(s int, level int, name int, val uintptr, vallen *_Socklen) (err error) = libsocket.getsockopt
use strict;
my $cmdline = "mksyscall_aix_ppc.pl " . join(' ', @ARGV);
my $errors = 0;
my $_32bit = "";
my $tags = ""; # build tags
my $aix = 0;
my $solaris = 0;
binmode STDOUT;
if($ARGV[0] eq "-b32") {
$_32bit = "big-endian";
shift;
} elsif($ARGV[0] eq "-l32") {
$_32bit = "little-endian";
shift;
}
if($ARGV[0] eq "-aix") {
$aix = 1;
shift;
}
if($ARGV[0] eq "-tags") {
shift;
$tags = $ARGV[0];
shift;
}
if($ARGV[0] =~ /^-/) {
print STDERR "usage: mksyscall_aix.pl [-b32 | -l32] [-tags x,y] [file ...]\n";
exit 1;
}
sub parseparamlist($) {
my ($list) = @_;
$list =~ s/^\s*//;
$list =~ s/\s*$//;
if($list eq "") {
return ();
}
return split(/\s*,\s*/, $list);
}
sub parseparam($) {
my ($p) = @_;
if($p !~ /^(\S*) (\S*)$/) {
print STDERR "$ARGV:$.: malformed parameter: $p\n";
$errors = 1;
return ("xx", "int");
}
return ($1, $2);
}
my $package = "";
my $text = "";
my $c_extern = "/*\n#include <stdint.h>\n#include <stddef.h>\n";
my @vars = ();
while(<>) {
chomp;
s/\s+/ /g;
s/^\s+//;
s/\s+$//;
$package = $1 if !$package && /^package (\S+)$/;
my $nonblock = /^\/\/sysnb /;
next if !/^\/\/sys / && !$nonblock;
# Line must be of the form
# func Open(path string, mode int, perm int) (fd int, err error)
# Split into name, in params, out params.
if(!/^\/\/sys(nb)? (\w+)\(([^()]*)\)\s*(?:\(([^()]+)\))?\s*(?:=\s*(?:(\w*)\.)?(\w*))?$/) {
print STDERR "$ARGV:$.: malformed //sys declaration\n";
$errors = 1;
next;
}
my ($nb, $func, $in, $out, $modname, $sysname) = ($1, $2, $3, $4, $5, $6);
# Split argument lists on comma.
my @in = parseparamlist($in);
my @out = parseparamlist($out);
$in = join(', ', @in);
$out = join(', ', @out);
# Try in vain to keep people from editing this file.
# The theory is that they jump into the middle of the file
# without reading the header.
$text .= "// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\n";
# Check if value return, err return available
my $errvar = "";
my $retvar = "";
my $rettype = "";
foreach my $p (@out) {
my ($name, $type) = parseparam($p);
if($type eq "error") {
$errvar = $name;
} else {
$retvar = $name;
$rettype = $type;
}
}
# System call name.
#if($func ne "fcntl") {
if($sysname eq "") {
$sysname = "$func";
}
$sysname =~ s/([a-z])([A-Z])/${1}_$2/g;
$sysname =~ y/A-Z/a-z/; # All libc functions are lowercase.
my $C_rettype = "";
if($rettype eq "unsafe.Pointer") {
$C_rettype = "uintptr_t";
} elsif($rettype eq "uintptr") {
$C_rettype = "uintptr_t";
} elsif($rettype =~ /^_/) {
$C_rettype = "uintptr_t";
} elsif($rettype eq "int") {
$C_rettype = "int";
} elsif($rettype eq "int32") {
$C_rettype = "int";
} elsif($rettype eq "int64") {
$C_rettype = "long long";
} elsif($rettype eq "uint32") {
$C_rettype = "unsigned int";
} elsif($rettype eq "uint64") {
$C_rettype = "unsigned long long";
} else {
$C_rettype = "int";
}
if($sysname eq "exit") {
$C_rettype = "void";
}
# Change types to c
my @c_in = ();
foreach my $p (@in) {
my ($name, $type) = parseparam($p);
if($type =~ /^\*/) {
push @c_in, "uintptr_t";
} elsif($type eq "string") {
push @c_in, "uintptr_t";
} elsif($type =~ /^\[\](.*)/) {
push @c_in, "uintptr_t", "size_t";
} elsif($type eq "unsafe.Pointer") {
push @c_in, "uintptr_t";
} elsif($type eq "uintptr") {
push @c_in, "uintptr_t";
} elsif($type =~ /^_/) {
push @c_in, "uintptr_t";
} elsif($type eq "int") {
push @c_in, "int";
} elsif($type eq "int32") {
push @c_in, "int";
} elsif($type eq "int64") {
push @c_in, "long long";
} elsif($type eq "uint32") {
push @c_in, "unsigned int";
} elsif($type eq "uint64") {
push @c_in, "unsigned long long";
} else {
push @c_in, "int";
}
}
if ($func ne "fcntl" && $func ne "FcntlInt" && $func ne "readlen" && $func ne "writelen") {
# Imports of system calls from libc
$c_extern .= "$C_rettype $sysname";
my $c_in = join(', ', @c_in);
$c_extern .= "($c_in);\n";
}
# So file name.
if($aix) {
if($modname eq "") {
$modname = "libc.a/shr_64.o";
} else {
print STDERR "$func: only syscall using libc are available\n";
$errors = 1;
next;
}
}
my $strconvfunc = "C.CString";
my $strconvtype = "*byte";
# Go function header.
if($out ne "") {
$out = " ($out)";
}
if($text ne "") {
$text .= "\n"
}
$text .= sprintf "func %s(%s)%s {\n", $func, join(', ', @in), $out ;
# Prepare arguments to call.
my @args = ();
my $n = 0;
my $arg_n = 0;
foreach my $p (@in) {
my ($name, $type) = parseparam($p);
if($type =~ /^\*/) {
push @args, "C.uintptr_t(uintptr(unsafe.Pointer($name)))";
} elsif($type eq "string" && $errvar ne "") {
$text .= "\t_p$n := uintptr(unsafe.Pointer($strconvfunc($name)))\n";
push @args, "C.uintptr_t(_p$n)";
$n++;
} elsif($type eq "string") {
print STDERR "$ARGV:$.: $func uses string arguments, but has no error return\n";
$text .= "\t_p$n := uintptr(unsafe.Pointer($strconvfunc($name)))\n";
push @args, "C.uintptr_t(_p$n)";
$n++;
} elsif($type =~ /^\[\](.*)/) {
# Convert slice into pointer, length.
# Have to be careful not to take address of &a[0] if len == 0:
# pass nil in that case.
$text .= "\tvar _p$n *$1\n";
$text .= "\tif len($name) > 0 {\n\t\t_p$n = \&$name\[0]\n\t}\n";
push @args, "C.uintptr_t(uintptr(unsafe.Pointer(_p$n)))";
$n++;
$text .= "\tvar _p$n int\n";
$text .= "\t_p$n = len($name)\n";
push @args, "C.size_t(_p$n)";
$n++;
} elsif($type eq "int64" && $_32bit ne "") {
if($_32bit eq "big-endian") {
push @args, "uintptr($name >> 32)", "uintptr($name)";
} else {
push @args, "uintptr($name)", "uintptr($name >> 32)";
}
$n++;
} elsif($type eq "bool") {
$text .= "\tvar _p$n uint32\n";
$text .= "\tif $name {\n\t\t_p$n = 1\n\t} else {\n\t\t_p$n = 0\n\t}\n";
push @args, "_p$n";
$n++;
} elsif($type =~ /^_/) {
push @args, "C.uintptr_t(uintptr($name))";
} elsif($type eq "unsafe.Pointer") {
push @args, "C.uintptr_t(uintptr($name))";
} elsif($type eq "int") {
if (($arg_n == 2) && (($func eq "readlen") || ($func eq "writelen"))) {
push @args, "C.size_t($name)";
} elsif ($arg_n == 0 && $func eq "fcntl") {
push @args, "C.uintptr_t($name)";
} elsif (($arg_n == 2) && (($func eq "fcntl") || ($func eq "FcntlInt"))) {
push @args, "C.uintptr_t($name)";
} else {
push @args, "C.int($name)";
}
} elsif($type eq "int32") {
push @args, "C.int($name)";
} elsif($type eq "int64") {
push @args, "C.longlong($name)";
} elsif($type eq "uint32") {
push @args, "C.uint($name)";
} elsif($type eq "uint64") {
push @args, "C.ulonglong($name)";
} elsif($type eq "uintptr") {
push @args, "C.uintptr_t($name)";
} else {
push @args, "C.int($name)";
}
$arg_n++;
}
my $nargs = @args;
# Determine which form to use; pad args with zeros.
if ($nonblock) {
}
my $args = join(', ', @args);
my $call = "";
if ($sysname eq "exit") {
if ($errvar ne "") {
$call .= "er :=";
} else {
$call .= "";
}
} elsif ($errvar ne "") {
$call .= "r0,er :=";
} elsif ($retvar ne "") {
$call .= "r0,_ :=";
} else {
$call .= ""
}
$call .= "C.$sysname($args)";
# Assign return values.
my $body = "";
my $failexpr = "";
for(my $i=0; $i<@out; $i++) {
my $p = $out[$i];
my ($name, $type) = parseparam($p);
my $reg = "";
if($name eq "err") {
$reg = "e1";
} else {
$reg = "r0";
}
if($reg ne "e1" ) {
$body .= "\t$name = $type($reg)\n";
}
}
# verify return
if ($sysname ne "exit" && $errvar ne "") {
if ($C_rettype =~ /^uintptr/) {
$body .= "\tif \(uintptr\(r0\) ==\^uintptr\(0\) && er != nil\) {\n";
$body .= "\t\t$errvar = er\n";
$body .= "\t}\n";
} else {
$body .= "\tif \(r0 ==-1 && er != nil\) {\n";
$body .= "\t\t$errvar = er\n";
$body .= "\t}\n";
}
} elsif ($errvar ne "") {
$body .= "\tif \(er != nil\) {\n";
$body .= "\t\t$errvar = er\n";
$body .= "\t}\n";
}
$text .= "\t$call\n";
$text .= $body;
$text .= "\treturn\n";
$text .= "}\n";
}
if($errors) {
exit 1;
}
print <<EOF;
// $cmdline
// Code generated by the command above; see README.md. DO NOT EDIT.
// +build $tags
package $package
$c_extern
*/
import "C"
import (
"unsafe"
)
EOF
print "import \"golang.org/x/sys/unix\"\n" if $package ne "unix";
chomp($_=<<EOF);
$text
EOF
print $_;
exit 0;
This diff is collapsed.
...@@ -92,6 +92,11 @@ while(<>) { ...@@ -92,6 +92,11 @@ while(<>) {
my @in = parseparamlist($in); my @in = parseparamlist($in);
my @out = parseparamlist($out); my @out = parseparamlist($out);
# Try in vain to keep people from editing this file.
# The theory is that they jump into the middle of the file
# without reading the header.
$text .= "// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\n";
# So file name. # So file name.
if($modname eq "") { if($modname eq "") {
$modname = "libc"; $modname = "libc";
......
...@@ -32,6 +32,7 @@ my @headers = qw ( ...@@ -32,6 +32,7 @@ my @headers = qw (
sys/sem.h sys/sem.h
sys/shm.h sys/shm.h
sys/vmmeter.h sys/vmmeter.h
uvm/uvmexp.h
uvm/uvm_param.h uvm/uvm_param.h
uvm/uvm_swap_encrypt.h uvm/uvm_swap_encrypt.h
ddb/db_var.h ddb/db_var.h
......
...@@ -27,7 +27,7 @@ const ( ...@@ -27,7 +27,7 @@ const (
EOF EOF
while(<>){ while(<>){
if(/^([0-9]+)\s+\S+\s+STD\s+({ \S+\s+(\w+).*)$/){ if(/^([0-9]+)\s+\S+\s+(?:NO)?STD\s+({ \S+\s+(\w+).*)$/){
my $num = $1; my $num = $1;
my $proto = $2; my $proto = $2;
my $name = "SYS_$3"; my $name = "SYS_$3";
......
...@@ -2,11 +2,12 @@ ...@@ -2,11 +2,12 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build darwin dragonfly freebsd linux netbsd openbsd solaris // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
package unix_test package unix_test
import ( import (
"runtime"
"testing" "testing"
"golang.org/x/sys/unix" "golang.org/x/sys/unix"
...@@ -23,9 +24,14 @@ func TestMmap(t *testing.T) { ...@@ -23,9 +24,14 @@ func TestMmap(t *testing.T) {
b[0] = 42 b[0] = 42
if runtime.GOOS == "aix" {
t.Skip("msync returns invalid argument for AIX, skipping msync test")
} else {
if err := unix.Msync(b, unix.MS_SYNC); err != nil { if err := unix.Msync(b, unix.MS_SYNC); err != nil {
t.Fatalf("Msync: %v", err) t.Fatalf("Msync: %v", err)
} }
}
if err := unix.Madvise(b, unix.MADV_DONTNEED); err != nil { if err := unix.Madvise(b, unix.MADV_DONTNEED); err != nil {
t.Fatalf("Madvise: %v", err) t.Fatalf("Madvise: %v", err)
} }
......
...@@ -8,31 +8,159 @@ ...@@ -8,31 +8,159 @@
package unix package unix
import ( import (
"errors"
"fmt"
"strconv"
"syscall" "syscall"
"unsafe" "unsafe"
) )
const ( // Pledge implements the pledge syscall.
_SYS_PLEDGE = 108 //
) // The pledge syscall does not accept execpromises on OpenBSD releases
// before 6.3.
//
// execpromises must be empty when Pledge is called on OpenBSD
// releases predating 6.3, otherwise an error will be returned.
//
// For more information see pledge(2).
func Pledge(promises, execpromises string) error {
maj, min, err := majmin()
if err != nil {
return err
}
err = pledgeAvailable(maj, min, execpromises)
if err != nil {
return err
}
pptr, err := syscall.BytePtrFromString(promises)
if err != nil {
return err
}
// This variable will hold either a nil unsafe.Pointer or
// an unsafe.Pointer to a string (execpromises).
var expr unsafe.Pointer
// If we're running on OpenBSD > 6.2, pass execpromises to the syscall.
if maj > 6 || (maj == 6 && min > 2) {
exptr, err := syscall.BytePtrFromString(execpromises)
if err != nil {
return err
}
expr = unsafe.Pointer(exptr)
}
// Pledge implements the pledge syscall. For more information see pledge(2). _, _, e := syscall.Syscall(SYS_PLEDGE, uintptr(unsafe.Pointer(pptr)), uintptr(expr), 0)
func Pledge(promises string, paths []string) error { if e != 0 {
promisesPtr, err := syscall.BytePtrFromString(promises) return e
}
return nil
}
// PledgePromises implements the pledge syscall.
//
// This changes the promises and leaves the execpromises untouched.
//
// For more information see pledge(2).
func PledgePromises(promises string) error {
maj, min, err := majmin()
if err != nil { if err != nil {
return err return err
} }
promisesUnsafe, pathsUnsafe := unsafe.Pointer(promisesPtr), unsafe.Pointer(nil)
if paths != nil { err = pledgeAvailable(maj, min, "")
var pathsPtr []*byte if err != nil {
if pathsPtr, err = syscall.SlicePtrFromStrings(paths); err != nil {
return err return err
} }
pathsUnsafe = unsafe.Pointer(&pathsPtr[0])
// This variable holds the execpromises and is always nil.
var expr unsafe.Pointer
pptr, err := syscall.BytePtrFromString(promises)
if err != nil {
return err
} }
_, _, e := syscall.Syscall(_SYS_PLEDGE, uintptr(promisesUnsafe), uintptr(pathsUnsafe), 0)
_, _, e := syscall.Syscall(SYS_PLEDGE, uintptr(unsafe.Pointer(pptr)), uintptr(expr), 0)
if e != 0 { if e != 0 {
return e return e
} }
return nil
}
// PledgeExecpromises implements the pledge syscall.
//
// This changes the execpromises and leaves the promises untouched.
//
// For more information see pledge(2).
func PledgeExecpromises(execpromises string) error {
maj, min, err := majmin()
if err != nil {
return err
}
err = pledgeAvailable(maj, min, execpromises)
if err != nil {
return err
}
// This variable holds the promises and is always nil.
var pptr unsafe.Pointer
exptr, err := syscall.BytePtrFromString(execpromises)
if err != nil {
return err
}
_, _, e := syscall.Syscall(SYS_PLEDGE, uintptr(pptr), uintptr(unsafe.Pointer(exptr)), 0)
if e != 0 {
return e
}
return nil
}
// majmin returns major and minor version number for an OpenBSD system.
func majmin() (major int, minor int, err error) {
var v Utsname
err = Uname(&v)
if err != nil {
return
}
major, err = strconv.Atoi(string(v.Release[0]))
if err != nil {
err = errors.New("cannot parse major version number returned by uname")
return
}
minor, err = strconv.Atoi(string(v.Release[2]))
if err != nil {
err = errors.New("cannot parse minor version number returned by uname")
return
}
return
}
// pledgeAvailable checks for availability of the pledge(2) syscall
// based on the running OpenBSD version.
func pledgeAvailable(maj, min int, execpromises string) error {
// If OpenBSD <= 5.9, pledge is not available.
if (maj == 5 && min != 9) || maj < 5 {
return fmt.Errorf("pledge syscall is not available on OpenBSD %d.%d", maj, min)
}
// If OpenBSD <= 6.2 and execpromises is not empty,
// return an error - execpromises is not available before 6.3
if (maj < 6 || (maj == 6 && min <= 2)) && execpromises != "" {
return fmt.Errorf("cannot use execpromises on OpenBSD %d.%d", maj, min)
}
return nil return nil
} }
...@@ -87,7 +87,7 @@ func TestMain(m *testing.M) { ...@@ -87,7 +87,7 @@ func TestMain(m *testing.M) {
func init() { func init() {
testProcs["pledge"] = testProc{ testProcs["pledge"] = testProc{
func() { func() {
fmt.Println(unix.Pledge("", nil)) fmt.Println(unix.Pledge("", ""))
os.Exit(0) os.Exit(0)
}, },
func() error { func() error {
......
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build openbsd
package unix
import (
"syscall"
"unsafe"
)
// Unveil implements the unveil syscall.
// For more information see unveil(2).
// Note that the special case of blocking further
// unveil calls is handled by UnveilBlock.
func Unveil(path string, flags string) error {
pathPtr, err := syscall.BytePtrFromString(path)
if err != nil {
return err
}
flagsPtr, err := syscall.BytePtrFromString(flags)
if err != nil {
return err
}
_, _, e := syscall.Syscall(SYS_UNVEIL, uintptr(unsafe.Pointer(pathPtr)), uintptr(unsafe.Pointer(flagsPtr)), 0)
if e != 0 {
return e
}
return nil
}
// UnveilBlock blocks future unveil calls.
// For more information see unveil(2).
func UnveilBlock() error {
// Both pointers must be nil.
var pathUnsafe, flagsUnsafe unsafe.Pointer
_, _, e := syscall.Syscall(SYS_UNVEIL, uintptr(pathUnsafe), uintptr(flagsUnsafe), 0)
if e != 0 {
return e
}
return nil
}
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build darwin dragonfly freebsd linux netbsd openbsd solaris // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
// For Unix, get the pagesize from the runtime. // For Unix, get the pagesize from the runtime.
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build darwin,!race linux,!race freebsd,!race netbsd openbsd solaris dragonfly // +build aix darwin,!race linux,!race freebsd,!race netbsd openbsd solaris dragonfly
package unix package unix
......
...@@ -2,24 +2,39 @@ ...@@ -2,24 +2,39 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build darwin dragonfly freebsd linux netbsd openbsd solaris // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
// Socket control messages // Socket control messages
package unix package unix
import "unsafe" import (
"runtime"
"unsafe"
)
// Round the length of a raw sockaddr up to align it properly. var cmsgAlign = SizeofPtr
func cmsgAlignOf(salen int) int {
salign := sizeofPtr func init() {
switch runtime.GOOS {
case "darwin", "dragonfly", "solaris":
// NOTE: It seems like 64-bit Darwin, DragonFly BSD and // NOTE: It seems like 64-bit Darwin, DragonFly BSD and
// Solaris kernels still require 32-bit aligned access to // Solaris kernels still require 32-bit aligned access to
// network subsystem. // network subsystem.
if darwin64Bit || dragonfly64Bit || solaris64Bit { if SizeofPtr == 8 {
salign = 4 cmsgAlign = 4
}
case "openbsd":
// OpenBSD armv7 requires 64-bit alignment.
if runtime.GOARCH == "arm" {
cmsgAlign = 8
}
} }
return (salen + salign - 1) & ^(salign - 1) }
// Round the length of a raw sockaddr up to align it properly.
func cmsgAlignOf(salen int) int {
return (salen + cmsgAlign - 1) & ^(cmsgAlign - 1)
} }
// CmsgLen returns the value to store in the Len field of the Cmsghdr // CmsgLen returns the value to store in the Len field of the Cmsghdr
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build darwin dragonfly freebsd linux netbsd openbsd solaris // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
package unix package unix
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build darwin dragonfly freebsd linux netbsd openbsd solaris // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
// Package unix contains an interface to the low-level operating system // Package unix contains an interface to the low-level operating system
// primitives. OS details vary depending on the underlying system, and // primitives. OS details vary depending on the underlying system, and
......
This diff is collapsed.
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build aix
// +build ppc
package unix
//sysnb Getrlimit(resource int, rlim *Rlimit) (err error) = getrlimit64
//sysnb Setrlimit(resource int, rlim *Rlimit) (err error) = setrlimit64
//sys Seek(fd int, offset int64, whence int) (off int64, err error) = lseek64
//sys mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error)
func setTimespec(sec, nsec int64) Timespec {
return Timespec{Sec: int32(sec), Nsec: int32(nsec)}
}
func setTimeval(sec, usec int64) Timeval {
return Timeval{Sec: int32(sec), Usec: int32(usec)}
}
func (iov *Iovec) SetLen(length int) {
iov.Len = uint32(length)
}
func (msghdr *Msghdr) SetControllen(length int) {
msghdr.Controllen = uint32(length)
}
func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint32(length)
}
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build aix
// +build ppc64
package unix
//sysnb Getrlimit(resource int, rlim *Rlimit) (err error)
//sysnb Setrlimit(resource int, rlim *Rlimit) (err error)
//sys Seek(fd int, offset int64, whence int) (off int64, err error) = lseek
//sys mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) = mmap64
func setTimespec(sec, nsec int64) Timespec {
return Timespec{Sec: sec, Nsec: nsec}
}
func setTimeval(sec, usec int64) Timeval {
return Timeval{Sec: int64(sec), Usec: int32(usec)}
}
func (iov *Iovec) SetLen(length int) {
iov.Len = uint64(length)
}
func (msghdr *Msghdr) SetControllen(length int) {
msghdr.Controllen = uint32(length)
}
func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint32(length)
}
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build aix
package unix_test
import (
"os"
"runtime"
"testing"
"time"
"golang.org/x/sys/unix"
)
func TestIoctlGetInt(t *testing.T) {
f, err := os.Open("/dev/random")
if err != nil {
t.Fatalf("failed to open device: %v", err)
}
defer f.Close()
v, err := unix.IoctlGetInt(int(f.Fd()), unix.RNDGETENTCNT)
if err != nil {
t.Fatalf("failed to perform ioctl: %v", err)
}
t.Logf("%d bits of entropy available", v)
}
func TestTime(t *testing.T) {
var ut unix.Time_t
ut2, err := unix.Time(&ut)
if err != nil {
t.Fatalf("Time: %v", err)
}
if ut != ut2 {
t.Errorf("Time: return value %v should be equal to argument %v", ut2, ut)
}
var now time.Time
for i := 0; i < 10; i++ {
ut, err = unix.Time(nil)
if err != nil {
t.Fatalf("Time: %v", err)
}
now = time.Now()
if int64(ut) == now.Unix() {
return
}
}
t.Errorf("Time: return value %v should be nearly equal to time.Now().Unix() %v", ut, now.Unix())
}
func TestUtime(t *testing.T) {
defer chtmpdir(t)()
touch(t, "file1")
buf := &unix.Utimbuf{
Modtime: 12345,
}
err := unix.Utime("file1", buf)
if err != nil {
t.Fatalf("Utime: %v", err)
}
fi, err := os.Stat("file1")
if err != nil {
t.Fatal(err)
}
if fi.ModTime().Unix() != 12345 {
t.Errorf("Utime: failed to change modtime: expected %v, got %v", 12345, fi.ModTime().Unix())
}
}
func TestUtimesNanoAt(t *testing.T) {
defer chtmpdir(t)()
symlink := "symlink1"
defer os.Remove(symlink)
err := os.Symlink("nonexisting", symlink)
if err != nil {
t.Fatal(err)
}
ts := []unix.Timespec{
{Sec: 1111, Nsec: 2222},
{Sec: 3333, Nsec: 4444},
}
err = unix.UtimesNanoAt(unix.AT_FDCWD, symlink, ts, unix.AT_SYMLINK_NOFOLLOW)
if err != nil {
t.Fatalf("UtimesNanoAt: %v", err)
}
var st unix.Stat_t
err = unix.Lstat(symlink, &st)
if err != nil {
t.Fatalf("Lstat: %v", err)
}
if runtime.GOARCH == "ppc64" {
if int64(st.Atim.Sec) != int64(ts[0].Sec) || st.Atim.Nsec != int32(ts[0].Nsec) {
t.Errorf("UtimesNanoAt: wrong atime: %v", st.Atim)
}
if int64(st.Mtim.Sec) != int64(ts[1].Sec) || st.Mtim.Nsec != int32(ts[1].Nsec) {
t.Errorf("UtimesNanoAt: wrong mtime: %v", st.Mtim)
}
} else {
if int32(st.Atim.Sec) != int32(ts[0].Sec) || int32(st.Atim.Nsec) != int32(ts[0].Nsec) {
t.Errorf("UtimesNanoAt: wrong atime: %v", st.Atim)
}
if int32(st.Mtim.Sec) != int32(ts[1].Sec) || int32(st.Mtim.Nsec) != int32(ts[1].Nsec) {
t.Errorf("UtimesNanoAt: wrong mtime: %v", st.Mtim)
}
}
}
func TestPselect(t *testing.T) {
if runtime.GOARCH == "ppc64" {
t.Skip("pselect issue with structure timespec on AIX 7.2 tl0, skipping test")
}
_, err := unix.Pselect(0, nil, nil, nil, &unix.Timespec{Sec: 0, Nsec: 0}, nil)
if err != nil {
t.Fatalf("Pselect: %v", err)
}
dur := 2500 * time.Microsecond
ts := unix.NsecToTimespec(int64(dur))
start := time.Now()
_, err = unix.Pselect(0, nil, nil, nil, &ts, nil)
took := time.Since(start)
if err != nil {
t.Fatalf("Pselect: %v", err)
}
if took < dur {
t.Errorf("Pselect: timeout should have been at least %v, got %v", dur, took)
}
}
// stringsFromByteSlice converts a sequence of attributes to a []string.
// On Linux, each entry is a NULL-terminated string.
func stringsFromByteSlice(buf []byte) []string {
var result []string
off := 0
for i, b := range buf {
if b == 0 {
result = append(result, string(buf[off:i]))
off = i + 1
}
}
return result
}
...@@ -206,7 +206,7 @@ func (sa *SockaddrDatalink) sockaddr() (unsafe.Pointer, _Socklen, error) { ...@@ -206,7 +206,7 @@ func (sa *SockaddrDatalink) sockaddr() (unsafe.Pointer, _Socklen, error) {
return unsafe.Pointer(&sa.raw), SizeofSockaddrDatalink, nil return unsafe.Pointer(&sa.raw), SizeofSockaddrDatalink, nil
} }
func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, error) { func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
switch rsa.Addr.Family { switch rsa.Addr.Family {
case AF_LINK: case AF_LINK:
pp := (*RawSockaddrDatalink)(unsafe.Pointer(rsa)) pp := (*RawSockaddrDatalink)(unsafe.Pointer(rsa))
...@@ -286,7 +286,7 @@ func Accept(fd int) (nfd int, sa Sockaddr, err error) { ...@@ -286,7 +286,7 @@ func Accept(fd int) (nfd int, sa Sockaddr, err error) {
Close(nfd) Close(nfd)
return 0, nil, ECONNABORTED return 0, nil, ECONNABORTED
} }
sa, err = anyToSockaddr(&rsa) sa, err = anyToSockaddr(fd, &rsa)
if err != nil { if err != nil {
Close(nfd) Close(nfd)
nfd = 0 nfd = 0
...@@ -306,7 +306,7 @@ func Getsockname(fd int) (sa Sockaddr, err error) { ...@@ -306,7 +306,7 @@ func Getsockname(fd int) (sa Sockaddr, err error) {
rsa.Addr.Family = AF_UNIX rsa.Addr.Family = AF_UNIX
rsa.Addr.Len = SizeofSockaddrUnix rsa.Addr.Len = SizeofSockaddrUnix
} }
return anyToSockaddr(&rsa) return anyToSockaddr(fd, &rsa)
} }
//sysnb socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) //sysnb socketpair(domain int, typ int, proto int, fd *[2]int32) (err error)
...@@ -356,7 +356,7 @@ func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from ...@@ -356,7 +356,7 @@ func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from
recvflags = int(msg.Flags) recvflags = int(msg.Flags)
// source address is only specified if the socket is unconnected // source address is only specified if the socket is unconnected
if rsa.Addr.Family != AF_UNSPEC { if rsa.Addr.Family != AF_UNSPEC {
from, err = anyToSockaddr(&rsa) from, err = anyToSockaddr(fd, &rsa)
} }
return return
} }
......
...@@ -15,18 +15,14 @@ import ( ...@@ -15,18 +15,14 @@ import (
"golang.org/x/sys/unix" "golang.org/x/sys/unix"
) )
const MNT_WAIT = 1
const MNT_NOWAIT = 2
func TestGetfsstat(t *testing.T) { func TestGetfsstat(t *testing.T) {
const flags = MNT_NOWAIT // see golang.org/issue/16937 n, err := unix.Getfsstat(nil, unix.MNT_NOWAIT)
n, err := unix.Getfsstat(nil, flags)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
data := make([]unix.Statfs_t, n) data := make([]unix.Statfs_t, n)
n2, err := unix.Getfsstat(data, flags) n2, err := unix.Getfsstat(data, unix.MNT_NOWAIT)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
......
...@@ -199,6 +199,12 @@ func Lgetxattr(link string, attr string, dest []byte) (sz int, err error) { ...@@ -199,6 +199,12 @@ func Lgetxattr(link string, attr string, dest []byte) (sz int, err error) {
return getxattr(link, attr, xattrPointer(dest), len(dest), 0, XATTR_NOFOLLOW) return getxattr(link, attr, xattrPointer(dest), len(dest), 0, XATTR_NOFOLLOW)
} }
//sys fgetxattr(fd int, attr string, dest *byte, size int, position uint32, options int) (sz int, err error)
func Fgetxattr(fd int, attr string, dest []byte) (sz int, err error) {
return fgetxattr(fd, attr, xattrPointer(dest), len(dest), 0, 0)
}
//sys setxattr(path string, attr string, data *byte, size int, position uint32, options int) (err error) //sys setxattr(path string, attr string, data *byte, size int, position uint32, options int) (err error)
func Setxattr(path string, attr string, data []byte, flags int) (err error) { func Setxattr(path string, attr string, data []byte, flags int) (err error) {
...@@ -235,6 +241,12 @@ func Lsetxattr(link string, attr string, data []byte, flags int) (err error) { ...@@ -235,6 +241,12 @@ func Lsetxattr(link string, attr string, data []byte, flags int) (err error) {
return setxattr(link, attr, xattrPointer(data), len(data), 0, flags|XATTR_NOFOLLOW) return setxattr(link, attr, xattrPointer(data), len(data), 0, flags|XATTR_NOFOLLOW)
} }
//sys fsetxattr(fd int, attr string, data *byte, size int, position uint32, options int) (err error)
func Fsetxattr(fd int, attr string, data []byte, flags int) (err error) {
return fsetxattr(fd, attr, xattrPointer(data), len(data), 0, 0)
}
//sys removexattr(path string, attr string, options int) (err error) //sys removexattr(path string, attr string, options int) (err error)
func Removexattr(path string, attr string) (err error) { func Removexattr(path string, attr string) (err error) {
...@@ -248,6 +260,12 @@ func Lremovexattr(link string, attr string) (err error) { ...@@ -248,6 +260,12 @@ func Lremovexattr(link string, attr string) (err error) {
return removexattr(link, attr, XATTR_NOFOLLOW) return removexattr(link, attr, XATTR_NOFOLLOW)
} }
//sys fremovexattr(fd int, attr string, options int) (err error)
func Fremovexattr(fd int, attr string) (err error) {
return fremovexattr(fd, attr, 0)
}
//sys listxattr(path string, dest *byte, size int, options int) (sz int, err error) //sys listxattr(path string, dest *byte, size int, options int) (sz int, err error)
func Listxattr(path string, dest []byte) (sz int, err error) { func Listxattr(path string, dest []byte) (sz int, err error) {
...@@ -258,6 +276,12 @@ func Llistxattr(link string, dest []byte) (sz int, err error) { ...@@ -258,6 +276,12 @@ func Llistxattr(link string, dest []byte) (sz int, err error) {
return listxattr(link, xattrPointer(dest), len(dest), XATTR_NOFOLLOW) return listxattr(link, xattrPointer(dest), len(dest), XATTR_NOFOLLOW)
} }
//sys flistxattr(fd int, dest *byte, size int, options int) (sz int, err error)
func Flistxattr(fd int, dest []byte) (sz int, err error) {
return flistxattr(fd, xattrPointer(dest), len(dest), 0)
}
func setattrlistTimes(path string, times []Timespec, flags int) error { func setattrlistTimes(path string, times []Timespec, flags int) error {
_p0, err := BytePtrFromString(path) _p0, err := BytePtrFromString(path)
if err != nil { if err != nil {
...@@ -313,11 +337,11 @@ func IoctlSetInt(fd int, req uint, value int) error { ...@@ -313,11 +337,11 @@ func IoctlSetInt(fd int, req uint, value int) error {
return ioctl(fd, req, uintptr(value)) return ioctl(fd, req, uintptr(value))
} }
func IoctlSetWinsize(fd int, req uint, value *Winsize) error { func ioctlSetWinsize(fd int, req uint, value *Winsize) error {
return ioctl(fd, req, uintptr(unsafe.Pointer(value))) return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
} }
func IoctlSetTermios(fd int, req uint, value *Termios) error { func ioctlSetTermios(fd int, req uint, value *Termios) error {
return ioctl(fd, req, uintptr(unsafe.Pointer(value))) return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
} }
...@@ -529,10 +553,6 @@ func Uname(uname *Utsname) error { ...@@ -529,10 +553,6 @@ func Uname(uname *Utsname) error {
// Watchevent // Watchevent
// Waitevent // Waitevent
// Modwatch // Modwatch
// Fgetxattr
// Fsetxattr
// Fremovexattr
// Flistxattr
// Fsctl // Fsctl
// Initgroups // Initgroups
// Posix_spawn // Posix_spawn
......
...@@ -4,6 +4,13 @@ ...@@ -4,6 +4,13 @@
package unix_test package unix_test
import (
"os"
"testing"
"golang.org/x/sys/unix"
)
// stringsFromByteSlice converts a sequence of attributes to a []string. // stringsFromByteSlice converts a sequence of attributes to a []string.
// On Darwin, each entry is a NULL-terminated string. // On Darwin, each entry is a NULL-terminated string.
func stringsFromByteSlice(buf []byte) []string { func stringsFromByteSlice(buf []byte) []string {
...@@ -17,3 +24,40 @@ func stringsFromByteSlice(buf []byte) []string { ...@@ -17,3 +24,40 @@ func stringsFromByteSlice(buf []byte) []string {
} }
return result return result
} }
func TestUtimesNanoAt(t *testing.T) {
defer chtmpdir(t)()
symlink := "symlink1"
os.Remove(symlink)
err := os.Symlink("nonexisting", symlink)
if err != nil {
t.Fatal(err)
}
ts := []unix.Timespec{
{Sec: 1111, Nsec: 2222},
{Sec: 3333, Nsec: 4444},
}
err = unix.UtimesNanoAt(unix.AT_FDCWD, symlink, ts, unix.AT_SYMLINK_NOFOLLOW)
if err != nil {
t.Fatalf("UtimesNanoAt: %v", err)
}
var st unix.Stat_t
err = unix.Lstat(symlink, &st)
if err != nil {
t.Fatalf("Lstat: %v", err)
}
// Only check Mtimespec, Atimespec might not be supported by the underlying filesystem
expected := ts[1]
if st.Mtimespec.Nsec == 0 {
// Some filesystems only support 1-second time stamp resolution
// and will always set Nsec to 0.
expected.Nsec = 0
}
if st.Mtimespec != expected {
t.Errorf("UtimesNanoAt: wrong mtime: got %v, expected %v", st.Mtimespec, expected)
}
}
...@@ -87,7 +87,7 @@ func Accept4(fd, flags int) (nfd int, sa Sockaddr, err error) { ...@@ -87,7 +87,7 @@ func Accept4(fd, flags int) (nfd int, sa Sockaddr, err error) {
if len > SizeofSockaddrAny { if len > SizeofSockaddrAny {
panic("RawSockaddrAny too small") panic("RawSockaddrAny too small")
} }
sa, err = anyToSockaddr(&rsa) sa, err = anyToSockaddr(fd, &rsa)
if err != nil { if err != nil {
Close(nfd) Close(nfd)
nfd = 0 nfd = 0
...@@ -143,11 +143,11 @@ func IoctlSetInt(fd int, req uint, value int) error { ...@@ -143,11 +143,11 @@ func IoctlSetInt(fd int, req uint, value int) error {
return ioctl(fd, req, uintptr(value)) return ioctl(fd, req, uintptr(value))
} }
func IoctlSetWinsize(fd int, req uint, value *Winsize) error { func ioctlSetWinsize(fd int, req uint, value *Winsize) error {
return ioctl(fd, req, uintptr(unsafe.Pointer(value))) return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
} }
func IoctlSetTermios(fd int, req uint, value *Termios) error { func ioctlSetTermios(fd int, req uint, value *Termios) error {
return ioctl(fd, req, uintptr(unsafe.Pointer(value))) return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
} }
...@@ -248,11 +248,13 @@ func Uname(uname *Utsname) error { ...@@ -248,11 +248,13 @@ func Uname(uname *Utsname) error {
//sys Dup(fd int) (nfd int, err error) //sys Dup(fd int) (nfd int, err error)
//sys Dup2(from int, to int) (err error) //sys Dup2(from int, to int) (err error)
//sys Exit(code int) //sys Exit(code int)
//sys Faccessat(dirfd int, path string, mode uint32, flags int) (err error)
//sys Fchdir(fd int) (err error) //sys Fchdir(fd int) (err error)
//sys Fchflags(fd int, flags int) (err error) //sys Fchflags(fd int, flags int) (err error)
//sys Fchmod(fd int, mode uint32) (err error) //sys Fchmod(fd int, mode uint32) (err error)
//sys Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) //sys Fchmodat(dirfd int, path string, mode uint32, flags int) (err error)
//sys Fchown(fd int, uid int, gid int) (err error) //sys Fchown(fd int, uid int, gid int) (err error)
//sys Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error)
//sys Flock(fd int, how int) (err error) //sys Flock(fd int, how int) (err error)
//sys Fpathconf(fd int, name int) (val int, err error) //sys Fpathconf(fd int, name int) (val int, err error)
//sys Fstat(fd int, stat *Stat_t) (err error) //sys Fstat(fd int, stat *Stat_t) (err error)
...@@ -280,13 +282,17 @@ func Uname(uname *Utsname) error { ...@@ -280,13 +282,17 @@ func Uname(uname *Utsname) error {
//sys Kqueue() (fd int, err error) //sys Kqueue() (fd int, err error)
//sys Lchown(path string, uid int, gid int) (err error) //sys Lchown(path string, uid int, gid int) (err error)
//sys Link(path string, link string) (err error) //sys Link(path string, link string) (err error)
//sys Linkat(pathfd int, path string, linkfd int, link string, flags int) (err error)
//sys Listen(s int, backlog int) (err error) //sys Listen(s int, backlog int) (err error)
//sys Lstat(path string, stat *Stat_t) (err error) //sys Lstat(path string, stat *Stat_t) (err error)
//sys Mkdir(path string, mode uint32) (err error) //sys Mkdir(path string, mode uint32) (err error)
//sys Mkdirat(dirfd int, path string, mode uint32) (err error)
//sys Mkfifo(path string, mode uint32) (err error) //sys Mkfifo(path string, mode uint32) (err error)
//sys Mknod(path string, mode uint32, dev int) (err error) //sys Mknod(path string, mode uint32, dev int) (err error)
//sys Mknodat(fd int, path string, mode uint32, dev int) (err error)
//sys Nanosleep(time *Timespec, leftover *Timespec) (err error) //sys Nanosleep(time *Timespec, leftover *Timespec) (err error)
//sys Open(path string, mode int, perm uint32) (fd int, err error) //sys Open(path string, mode int, perm uint32) (fd int, err error)
//sys Openat(dirfd int, path string, mode int, perm uint32) (fd int, err error)
//sys Pathconf(path string, name int) (val int, err error) //sys Pathconf(path string, name int) (val int, err error)
//sys read(fd int, p []byte) (n int, err error) //sys read(fd int, p []byte) (n int, err error)
//sys Readlink(path string, buf []byte) (n int, err error) //sys Readlink(path string, buf []byte) (n int, err error)
...@@ -312,11 +318,13 @@ func Uname(uname *Utsname) error { ...@@ -312,11 +318,13 @@ func Uname(uname *Utsname) error {
//sys Stat(path string, stat *Stat_t) (err error) //sys Stat(path string, stat *Stat_t) (err error)
//sys Statfs(path string, stat *Statfs_t) (err error) //sys Statfs(path string, stat *Statfs_t) (err error)
//sys Symlink(path string, link string) (err error) //sys Symlink(path string, link string) (err error)
//sys Symlinkat(oldpath string, newdirfd int, newpath string) (err error)
//sys Sync() (err error) //sys Sync() (err error)
//sys Truncate(path string, length int64) (err error) //sys Truncate(path string, length int64) (err error)
//sys Umask(newmask int) (oldmask int) //sys Umask(newmask int) (oldmask int)
//sys Undelete(path string) (err error) //sys Undelete(path string) (err error)
//sys Unlink(path string) (err error) //sys Unlink(path string) (err error)
//sys Unlinkat(dirfd int, path string, flags int) (err error)
//sys Unmount(path string, flags int) (err error) //sys Unmount(path string, flags int) (err error)
//sys write(fd int, p []byte) (n int, err error) //sys write(fd int, p []byte) (n int, err error)
//sys mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) //sys mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error)
......
...@@ -20,12 +20,26 @@ package unix ...@@ -20,12 +20,26 @@ package unix
//sysnb Getgid() (gid int) //sysnb Getgid() (gid int)
//sysnb Getrlimit(resource int, rlim *Rlimit) (err error) //sysnb Getrlimit(resource int, rlim *Rlimit) (err error)
//sysnb Getuid() (uid int) //sysnb Getuid() (uid int)
//sysnb InotifyInit() (fd int, err error) //sysnb inotifyInit() (fd int, err error)
func InotifyInit() (fd int, err error) {
// First try inotify_init1, because Android's seccomp policy blocks the latter.
fd, err = InotifyInit1(0)
if err == ENOSYS {
fd, err = inotifyInit()
}
return
}
//sys Ioperm(from int, num int, on int) (err error) //sys Ioperm(from int, num int, on int) (err error)
//sys Iopl(level int) (err error) //sys Iopl(level int) (err error)
//sys Lchown(path string, uid int, gid int) (err error) //sys Lchown(path string, uid int, gid int) (err error)
//sys Listen(s int, n int) (err error) //sys Listen(s int, n int) (err error)
//sys Lstat(path string, stat *Stat_t) (err error)
func Lstat(path string, stat *Stat_t) (err error) {
return Fstatat(AT_FDCWD, path, stat, AT_SYMLINK_NOFOLLOW)
}
//sys Pause() (err error) //sys Pause() (err error)
//sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64 //sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
//sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64 //sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
...@@ -160,3 +174,16 @@ func Poll(fds []PollFd, timeout int) (n int, err error) { ...@@ -160,3 +174,16 @@ func Poll(fds []PollFd, timeout int) (n int, err error) {
} }
return poll(&fds[0], len(fds), timeout) return poll(&fds[0], len(fds), timeout)
} }
//sys kexecFileLoad(kernelFd int, initrdFd int, cmdlineLen int, cmdline string, flags int) (err error)
func KexecFileLoad(kernelFd int, initrdFd int, cmdline string, flags int) error {
cmdlineLen := len(cmdline)
if cmdlineLen > 0 {
// Account for the additional NULL byte added by
// BytePtrFromString in kexecFileLoad. The kexec_file_load
// syscall expects a NULL-terminated string.
cmdlineLen++
}
return kexecFileLoad(kernelFd, initrdFd, cmdlineLen, cmdline, flags)
}
...@@ -191,12 +191,9 @@ func Dup2(oldfd int, newfd int) (err error) { ...@@ -191,12 +191,9 @@ func Dup2(oldfd int, newfd int) (err error) {
return Dup3(oldfd, newfd, 0) return Dup3(oldfd, newfd, 0)
} }
func Pause() (err error) { func Pause() error {
_, _, e1 := Syscall6(SYS_PPOLL, 0, 0, 0, 0, 0, 0) _, err := ppoll(nil, 0, nil, nil)
if e1 != 0 { return err
err = errnoErr(e1)
}
return
} }
func Poll(fds []PollFd, timeout int) (n int, err error) { func Poll(fds []PollFd, timeout int) (n int, err error) {
......
...@@ -124,14 +124,13 @@ func Pipe2(p []int, flags int) (err error) { ...@@ -124,14 +124,13 @@ func Pipe2(p []int, flags int) (err error) {
return return
} }
//sysnb pipe() (p1 int, p2 int, err error)
func Pipe(p []int) (err error) { func Pipe(p []int) (err error) {
if len(p) != 2 { if len(p) != 2 {
return EINVAL return EINVAL
} }
var pp [2]_C_int p[0], p[1], err = pipe()
err = pipe2(&pp, 0)
p[0] = int(pp[0])
p[1] = int(pp[1])
return return
} }
......
...@@ -44,7 +44,6 @@ package unix ...@@ -44,7 +44,6 @@ package unix
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error) //sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
//sys Stat(path string, stat *Stat_t) (err error) //sys Stat(path string, stat *Stat_t) (err error)
//sys Statfs(path string, buf *Statfs_t) (err error) //sys Statfs(path string, buf *Statfs_t) (err error)
//sys SyncFileRange(fd int, off int64, n int64, flags int) (err error) = SYS_SYNC_FILE_RANGE2
//sys Truncate(path string, length int64) (err error) //sys Truncate(path string, length int64) (err error)
//sys Ustat(dev int, ubuf *Ustat_t) (err error) //sys Ustat(dev int, ubuf *Ustat_t) (err error)
//sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) //sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error)
...@@ -129,3 +128,24 @@ func Poll(fds []PollFd, timeout int) (n int, err error) { ...@@ -129,3 +128,24 @@ func Poll(fds []PollFd, timeout int) (n int, err error) {
} }
return poll(&fds[0], len(fds), timeout) return poll(&fds[0], len(fds), timeout)
} }
//sys syncFileRange2(fd int, flags int, off int64, n int64) (err error) = SYS_SYNC_FILE_RANGE2
func SyncFileRange(fd int, off int64, n int64, flags int) error {
// The sync_file_range and sync_file_range2 syscalls differ only in the
// order of their arguments.
return syncFileRange2(fd, flags, off, n)
}
//sys kexecFileLoad(kernelFd int, initrdFd int, cmdlineLen int, cmdline string, flags int) (err error)
func KexecFileLoad(kernelFd int, initrdFd int, cmdline string, flags int) error {
cmdlineLen := len(cmdline)
if cmdlineLen > 0 {
// Account for the additional NULL byte added by
// BytePtrFromString in kexecFileLoad. The kexec_file_load
// syscall expects a NULL-terminated string.
cmdlineLen++
}
return kexecFileLoad(kernelFd, initrdFd, cmdlineLen, cmdline, flags)
}
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build riscv64,linux
package unix
import "unsafe"
func EpollCreate(size int) (fd int, err error) {
if size <= 0 {
return -1, EINVAL
}
return EpollCreate1(0)
}
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) = SYS_EPOLL_PWAIT
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64
//sys Fchown(fd int, uid int, gid int) (err error)
//sys Fstat(fd int, stat *Stat_t) (err error)
//sys Fstatat(fd int, path string, stat *Stat_t, flags int) (err error)
//sys Fstatfs(fd int, buf *Statfs_t) (err error)
//sys Ftruncate(fd int, length int64) (err error)
//sysnb Getegid() (egid int)
//sysnb Geteuid() (euid int)
//sysnb Getgid() (gid int)
//sysnb Getrlimit(resource int, rlim *Rlimit) (err error)
//sysnb Getuid() (uid int)
//sys Listen(s int, n int) (err error)
//sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
//sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
//sys Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK
func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) {
var ts *Timespec
if timeout != nil {
ts = &Timespec{Sec: timeout.Sec, Nsec: timeout.Usec * 1000}
}
return Pselect(nfd, r, w, e, ts, nil)
}
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
//sys Setfsgid(gid int) (err error)
//sys Setfsuid(uid int) (err error)
//sysnb Setregid(rgid int, egid int) (err error)
//sysnb Setresgid(rgid int, egid int, sgid int) (err error)
//sysnb Setresuid(ruid int, euid int, suid int) (err error)
//sysnb Setrlimit(resource int, rlim *Rlimit) (err error)
//sysnb Setreuid(ruid int, euid int) (err error)
//sys Shutdown(fd int, how int) (err error)
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
func Stat(path string, stat *Stat_t) (err error) {
return Fstatat(AT_FDCWD, path, stat, 0)
}
func Lchown(path string, uid int, gid int) (err error) {
return Fchownat(AT_FDCWD, path, uid, gid, AT_SYMLINK_NOFOLLOW)
}
func Lstat(path string, stat *Stat_t) (err error) {
return Fstatat(AT_FDCWD, path, stat, AT_SYMLINK_NOFOLLOW)
}
//sys Statfs(path string, buf *Statfs_t) (err error)
//sys SyncFileRange(fd int, off int64, n int64, flags int) (err error)
//sys Truncate(path string, length int64) (err error)
func Ustat(dev int, ubuf *Ustat_t) (err error) {
return ENOSYS
}
//sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error)
//sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error)
//sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
//sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
//sysnb getgroups(n int, list *_Gid_t) (nn int, err error)
//sysnb setgroups(n int, list *_Gid_t) (err error)
//sys getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error)
//sys setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error)
//sysnb socket(domain int, typ int, proto int) (fd int, err error)
//sysnb socketpair(domain int, typ int, proto int, fd *[2]int32) (err error)
//sysnb getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)
//sysnb getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)
//sys recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error)
//sys sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error)
//sys recvmsg(s int, msg *Msghdr, flags int) (n int, err error)
//sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error)
//sys mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error)
//sysnb Gettimeofday(tv *Timeval) (err error)
func setTimespec(sec, nsec int64) Timespec {
return Timespec{Sec: sec, Nsec: nsec}
}
func setTimeval(sec, usec int64) Timeval {
return Timeval{Sec: sec, Usec: usec}
}
func futimesat(dirfd int, path string, tv *[2]Timeval) (err error) {
if tv == nil {
return utimensat(dirfd, path, nil, 0)
}
ts := []Timespec{
NsecToTimespec(TimevalToNsec(tv[0])),
NsecToTimespec(TimevalToNsec(tv[1])),
}
return utimensat(dirfd, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
}
func Time(t *Time_t) (Time_t, error) {
var tv Timeval
err := Gettimeofday(&tv)
if err != nil {
return 0, err
}
if t != nil {
*t = Time_t(tv.Sec)
}
return Time_t(tv.Sec), nil
}
func Utime(path string, buf *Utimbuf) error {
tv := []Timeval{
{Sec: buf.Actime},
{Sec: buf.Modtime},
}
return Utimes(path, tv)
}
func utimes(path string, tv *[2]Timeval) (err error) {
if tv == nil {
return utimensat(AT_FDCWD, path, nil, 0)
}
ts := []Timespec{
NsecToTimespec(TimevalToNsec(tv[0])),
NsecToTimespec(TimevalToNsec(tv[1])),
}
return utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
}
func Pipe(p []int) (err error) {
if len(p) != 2 {
return EINVAL
}
var pp [2]_C_int
err = pipe2(&pp, 0)
p[0] = int(pp[0])
p[1] = int(pp[1])
return
}
//sysnb pipe2(p *[2]_C_int, flags int) (err error)
func Pipe2(p []int, flags int) (err error) {
if len(p) != 2 {
return EINVAL
}
var pp [2]_C_int
err = pipe2(&pp, flags)
p[0] = int(pp[0])
p[1] = int(pp[1])
return
}
func (r *PtraceRegs) PC() uint64 { return r.Pc }
func (r *PtraceRegs) SetPC(pc uint64) { r.Pc = pc }
func (iov *Iovec) SetLen(length int) {
iov.Len = uint64(length)
}
func (msghdr *Msghdr) SetControllen(length int) {
msghdr.Controllen = uint64(length)
}
func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint64(length)
}
func InotifyInit() (fd int, err error) {
return InotifyInit1(0)
}
func Dup2(oldfd int, newfd int) (err error) {
return Dup3(oldfd, newfd, 0)
}
func Pause() error {
_, err := ppoll(nil, 0, nil, nil)
return err
}
func Poll(fds []PollFd, timeout int) (n int, err error) {
var ts *Timespec
if timeout >= 0 {
ts = new(Timespec)
*ts = NsecToTimespec(int64(timeout) * 1e6)
}
if len(fds) == 0 {
return ppoll(nil, 0, ts, nil)
}
return ppoll(&fds[0], len(fds), ts, nil)
}
...@@ -322,3 +322,16 @@ func Poll(fds []PollFd, timeout int) (n int, err error) { ...@@ -322,3 +322,16 @@ func Poll(fds []PollFd, timeout int) (n int, err error) {
} }
return poll(&fds[0], len(fds), timeout) return poll(&fds[0], len(fds), timeout)
} }
//sys kexecFileLoad(kernelFd int, initrdFd int, cmdlineLen int, cmdline string, flags int) (err error)
func KexecFileLoad(kernelFd int, initrdFd int, cmdline string, flags int) error {
cmdlineLen := len(cmdline)
if cmdlineLen > 0 {
// Account for the additional NULL byte added by
// BytePtrFromString in kexecFileLoad. The kexec_file_load
// syscall expects a NULL-terminated string.
cmdlineLen++
}
return kexecFileLoad(kernelFd, initrdFd, cmdlineLen, cmdline, flags)
}
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
package unix_test package unix_test
import ( import (
"io/ioutil"
"os" "os"
"runtime" "runtime"
"runtime/debug" "runtime/debug"
...@@ -177,7 +178,7 @@ func TestRlimitAs(t *testing.T) { ...@@ -177,7 +178,7 @@ func TestRlimitAs(t *testing.T) {
// should fail. See 'man 2 getrlimit'. // should fail. See 'man 2 getrlimit'.
_, err = unix.Mmap(-1, 0, 2*unix.Getpagesize(), unix.PROT_NONE, unix.MAP_ANON|unix.MAP_PRIVATE) _, err = unix.Mmap(-1, 0, 2*unix.Getpagesize(), unix.PROT_NONE, unix.MAP_ANON|unix.MAP_PRIVATE)
if err == nil { if err == nil {
t.Fatal("Mmap: unexpectedly suceeded after setting RLIMIT_AS") t.Fatal("Mmap: unexpectedly succeeded after setting RLIMIT_AS")
} }
err = unix.Setrlimit(unix.RLIMIT_AS, &rlim) err = unix.Setrlimit(unix.RLIMIT_AS, &rlim)
...@@ -272,6 +273,23 @@ func TestSchedSetaffinity(t *testing.T) { ...@@ -272,6 +273,23 @@ func TestSchedSetaffinity(t *testing.T) {
t.Skip("skipping setaffinity tests on android") t.Skip("skipping setaffinity tests on android")
} }
// On a system like ppc64x where some cores can be disabled using ppc64_cpu,
// setaffinity should only be called with enabled cores. The valid cores
// are found from the oldMask, but if none are found then the setaffinity
// tests are skipped. Issue #27875.
if !oldMask.IsSet(cpu) {
newMask.Zero()
for i := 0; i < len(oldMask); i++ {
if oldMask.IsSet(i) {
newMask.Set(i)
break
}
}
if newMask.Count() == 0 {
t.Skip("skipping setaffinity tests if CPU not available")
}
}
err = unix.SchedSetaffinity(0, &newMask) err = unix.SchedSetaffinity(0, &newMask)
if err != nil { if err != nil {
t.Fatalf("SchedSetaffinity: %v", err) t.Fatalf("SchedSetaffinity: %v", err)
...@@ -394,19 +412,19 @@ func TestFaccessat(t *testing.T) { ...@@ -394,19 +412,19 @@ func TestFaccessat(t *testing.T) {
defer chtmpdir(t)() defer chtmpdir(t)()
touch(t, "file1") touch(t, "file1")
err := unix.Faccessat(unix.AT_FDCWD, "file1", unix.O_RDONLY, 0) err := unix.Faccessat(unix.AT_FDCWD, "file1", unix.R_OK, 0)
if err != nil { if err != nil {
t.Errorf("Faccessat: unexpected error: %v", err) t.Errorf("Faccessat: unexpected error: %v", err)
} }
err = unix.Faccessat(unix.AT_FDCWD, "file1", unix.O_RDONLY, 2) err = unix.Faccessat(unix.AT_FDCWD, "file1", unix.R_OK, 2)
if err != unix.EINVAL { if err != unix.EINVAL {
t.Errorf("Faccessat: unexpected error: %v, want EINVAL", err) t.Errorf("Faccessat: unexpected error: %v, want EINVAL", err)
} }
err = unix.Faccessat(unix.AT_FDCWD, "file1", unix.O_RDONLY, unix.AT_EACCESS) err = unix.Faccessat(unix.AT_FDCWD, "file1", unix.R_OK, unix.AT_EACCESS)
if err != unix.EOPNOTSUPP { if err != nil {
t.Errorf("Faccessat: unexpected error: %v, want EOPNOTSUPP", err) t.Errorf("Faccessat: unexpected error: %v", err)
} }
err = os.Symlink("file1", "symlink1") err = os.Symlink("file1", "symlink1")
...@@ -414,8 +432,53 @@ func TestFaccessat(t *testing.T) { ...@@ -414,8 +432,53 @@ func TestFaccessat(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
err = unix.Faccessat(unix.AT_FDCWD, "symlink1", unix.O_RDONLY, unix.AT_SYMLINK_NOFOLLOW) err = unix.Faccessat(unix.AT_FDCWD, "symlink1", unix.R_OK, unix.AT_SYMLINK_NOFOLLOW)
if err != unix.EOPNOTSUPP { if err != nil {
t.Errorf("Faccessat: unexpected error: %v, want EOPNOTSUPP", err) t.Errorf("Faccessat SYMLINK_NOFOLLOW: unexpected error %v", err)
}
// We can't really test AT_SYMLINK_NOFOLLOW, because there
// doesn't seem to be any way to change the mode of a symlink.
// We don't test AT_EACCESS because such tests are only
// meaningful if run as root.
err = unix.Fchmodat(unix.AT_FDCWD, "file1", 0, 0)
if err != nil {
t.Errorf("Fchmodat: unexpected error %v", err)
}
err = unix.Faccessat(unix.AT_FDCWD, "file1", unix.F_OK, unix.AT_SYMLINK_NOFOLLOW)
if err != nil {
t.Errorf("Faccessat: unexpected error: %v", err)
}
err = unix.Faccessat(unix.AT_FDCWD, "file1", unix.R_OK, unix.AT_SYMLINK_NOFOLLOW)
if err != unix.EACCES {
if unix.Getuid() != 0 {
t.Errorf("Faccessat: unexpected error: %v, want EACCES", err)
}
}
}
func TestSyncFileRange(t *testing.T) {
file, err := ioutil.TempFile("", "TestSyncFileRange")
if err != nil {
t.Fatal(err)
}
defer os.Remove(file.Name())
defer file.Close()
err = unix.SyncFileRange(int(file.Fd()), 0, 0, 0)
if err == unix.ENOSYS || err == unix.EPERM {
t.Skip("sync_file_range syscall is not available, skipping test")
} else if err != nil {
t.Fatalf("SyncFileRange: %v", err)
}
// invalid flags
flags := 0xf00
err = unix.SyncFileRange(int(file.Fd()), 0, 0, flags)
if err != unix.EINVAL {
t.Fatalf("SyncFileRange: unexpected error: %v, want EINVAL", err)
} }
} }
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
package unix package unix
import ( import (
"runtime"
"syscall" "syscall"
"unsafe" "unsafe"
) )
...@@ -93,6 +94,23 @@ func nametomib(name string) (mib []_C_int, err error) { ...@@ -93,6 +94,23 @@ func nametomib(name string) (mib []_C_int, err error) {
return mib, nil return mib, nil
} }
func SysctlClockinfo(name string) (*Clockinfo, error) {
mib, err := sysctlmib(name)
if err != nil {
return nil, err
}
n := uintptr(SizeofClockinfo)
var ci Clockinfo
if err := sysctl(mib, (*byte)(unsafe.Pointer(&ci)), &n, nil, 0); err != nil {
return nil, err
}
if n != SizeofClockinfo {
return nil, EIO
}
return &ci, nil
}
//sysnb pipe() (fd1 int, fd2 int, err error) //sysnb pipe() (fd1 int, fd2 int, err error)
func Pipe(p []int) (err error) { func Pipe(p []int) (err error) {
if len(p) != 2 { if len(p) != 2 {
...@@ -145,11 +163,11 @@ func IoctlSetInt(fd int, req uint, value int) error { ...@@ -145,11 +163,11 @@ func IoctlSetInt(fd int, req uint, value int) error {
return ioctl(fd, req, uintptr(value)) return ioctl(fd, req, uintptr(value))
} }
func IoctlSetWinsize(fd int, req uint, value *Winsize) error { func ioctlSetWinsize(fd int, req uint, value *Winsize) error {
return ioctl(fd, req, uintptr(unsafe.Pointer(value))) return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
} }
func IoctlSetTermios(fd int, req uint, value *Termios) error { func ioctlSetTermios(fd int, req uint, value *Termios) error {
return ioctl(fd, req, uintptr(unsafe.Pointer(value))) return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
} }
...@@ -173,6 +191,13 @@ func IoctlGetTermios(fd int, req uint) (*Termios, error) { ...@@ -173,6 +191,13 @@ func IoctlGetTermios(fd int, req uint) (*Termios, error) {
return &value, err return &value, err
} }
func IoctlGetPtmget(fd int, req uint) (*Ptmget, error) {
var value Ptmget
err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
runtime.KeepAlive(value)
return &value, err
}
func Uname(uname *Utsname) error { func Uname(uname *Utsname) error {
mib := []_C_int{CTL_KERN, KERN_OSTYPE} mib := []_C_int{CTL_KERN, KERN_OSTYPE}
n := unsafe.Sizeof(uname.Sysname) n := unsafe.Sizeof(uname.Sysname)
...@@ -233,6 +258,18 @@ func Uname(uname *Utsname) error { ...@@ -233,6 +258,18 @@ func Uname(uname *Utsname) error {
//sys Dup(fd int) (nfd int, err error) //sys Dup(fd int) (nfd int, err error)
//sys Dup2(from int, to int) (err error) //sys Dup2(from int, to int) (err error)
//sys Exit(code int) //sys Exit(code int)
//sys ExtattrGetFd(fd int, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error)
//sys ExtattrSetFd(fd int, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error)
//sys ExtattrDeleteFd(fd int, attrnamespace int, attrname string) (err error)
//sys ExtattrListFd(fd int, attrnamespace int, data uintptr, nbytes int) (ret int, err error)
//sys ExtattrGetFile(file string, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error)
//sys ExtattrSetFile(file string, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error)
//sys ExtattrDeleteFile(file string, attrnamespace int, attrname string) (err error)
//sys ExtattrListFile(file string, attrnamespace int, data uintptr, nbytes int) (ret int, err error)
//sys ExtattrGetLink(link string, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error)
//sys ExtattrSetLink(link string, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error)
//sys ExtattrDeleteLink(link string, attrnamespace int, attrname string) (err error)
//sys ExtattrListLink(link string, attrnamespace int, data uintptr, nbytes int) (ret int, err error)
//sys Faccessat(dirfd int, path string, mode uint32, flags int) (err error) //sys Faccessat(dirfd int, path string, mode uint32, flags int) (err error)
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_POSIX_FADVISE //sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_POSIX_FADVISE
//sys Fchdir(fd int) (err error) //sys Fchdir(fd int) (err error)
...@@ -240,6 +277,7 @@ func Uname(uname *Utsname) error { ...@@ -240,6 +277,7 @@ func Uname(uname *Utsname) error {
//sys Fchmod(fd int, mode uint32) (err error) //sys Fchmod(fd int, mode uint32) (err error)
//sys Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) //sys Fchmodat(dirfd int, path string, mode uint32, flags int) (err error)
//sys Fchown(fd int, uid int, gid int) (err error) //sys Fchown(fd int, uid int, gid int) (err error)
//sys Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error)
//sys Flock(fd int, how int) (err error) //sys Flock(fd int, how int) (err error)
//sys Fpathconf(fd int, name int) (val int, err error) //sys Fpathconf(fd int, name int) (val int, err error)
//sys Fstat(fd int, stat *Stat_t) (err error) //sys Fstat(fd int, stat *Stat_t) (err error)
...@@ -264,19 +302,26 @@ func Uname(uname *Utsname) error { ...@@ -264,19 +302,26 @@ func Uname(uname *Utsname) error {
//sys Kqueue() (fd int, err error) //sys Kqueue() (fd int, err error)
//sys Lchown(path string, uid int, gid int) (err error) //sys Lchown(path string, uid int, gid int) (err error)
//sys Link(path string, link string) (err error) //sys Link(path string, link string) (err error)
//sys Linkat(pathfd int, path string, linkfd int, link string, flags int) (err error)
//sys Listen(s int, backlog int) (err error) //sys Listen(s int, backlog int) (err error)
//sys Lstat(path string, stat *Stat_t) (err error) //sys Lstat(path string, stat *Stat_t) (err error)
//sys Mkdir(path string, mode uint32) (err error) //sys Mkdir(path string, mode uint32) (err error)
//sys Mkdirat(dirfd int, path string, mode uint32) (err error)
//sys Mkfifo(path string, mode uint32) (err error) //sys Mkfifo(path string, mode uint32) (err error)
//sys Mkfifoat(dirfd int, path string, mode uint32) (err error)
//sys Mknod(path string, mode uint32, dev int) (err error) //sys Mknod(path string, mode uint32, dev int) (err error)
//sys Mknodat(dirfd int, path string, mode uint32, dev int) (err error)
//sys Nanosleep(time *Timespec, leftover *Timespec) (err error) //sys Nanosleep(time *Timespec, leftover *Timespec) (err error)
//sys Open(path string, mode int, perm uint32) (fd int, err error) //sys Open(path string, mode int, perm uint32) (fd int, err error)
//sys Openat(dirfd int, path string, mode int, perm uint32) (fd int, err error)
//sys Pathconf(path string, name int) (val int, err error) //sys Pathconf(path string, name int) (val int, err error)
//sys Pread(fd int, p []byte, offset int64) (n int, err error) //sys Pread(fd int, p []byte, offset int64) (n int, err error)
//sys Pwrite(fd int, p []byte, offset int64) (n int, err error) //sys Pwrite(fd int, p []byte, offset int64) (n int, err error)
//sys read(fd int, p []byte) (n int, err error) //sys read(fd int, p []byte) (n int, err error)
//sys Readlink(path string, buf []byte) (n int, err error) //sys Readlink(path string, buf []byte) (n int, err error)
//sys Readlinkat(dirfd int, path string, buf []byte) (n int, err error)
//sys Rename(from string, to string) (err error) //sys Rename(from string, to string) (err error)
//sys Renameat(fromfd int, from string, tofd int, to string) (err error)
//sys Revoke(path string) (err error) //sys Revoke(path string) (err error)
//sys Rmdir(path string) (err error) //sys Rmdir(path string) (err error)
//sys Seek(fd int, offset int64, whence int) (newoffset int64, err error) = SYS_LSEEK //sys Seek(fd int, offset int64, whence int) (newoffset int64, err error) = SYS_LSEEK
...@@ -294,10 +339,12 @@ func Uname(uname *Utsname) error { ...@@ -294,10 +339,12 @@ func Uname(uname *Utsname) error {
//sysnb Setuid(uid int) (err error) //sysnb Setuid(uid int) (err error)
//sys Stat(path string, stat *Stat_t) (err error) //sys Stat(path string, stat *Stat_t) (err error)
//sys Symlink(path string, link string) (err error) //sys Symlink(path string, link string) (err error)
//sys Symlinkat(oldpath string, newdirfd int, newpath string) (err error)
//sys Sync() (err error) //sys Sync() (err error)
//sys Truncate(path string, length int64) (err error) //sys Truncate(path string, length int64) (err error)
//sys Umask(newmask int) (oldmask int) //sys Umask(newmask int) (oldmask int)
//sys Unlink(path string) (err error) //sys Unlink(path string) (err error)
//sys Unlinkat(dirfd int, path string, flags int) (err error)
//sys Unmount(path string, flags int) (err error) //sys Unmount(path string, flags int) (err error)
//sys write(fd int, p []byte) (n int, err error) //sys write(fd int, p []byte) (n int, err error)
//sys mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) //sys mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error)
......
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package unix_test
import (
"bytes"
"testing"
"golang.org/x/sys/unix"
)
// stringsFromByteSlice converts a sequence of attributes to a []string.
// On NetBSD, each entry consists of a single byte containing the length
// of the attribute name, followed by the attribute name.
// The name is _not_ NULL-terminated.
func stringsFromByteSlice(buf []byte) []string {
var result []string
i := 0
for i < len(buf) {
next := i + 1 + int(buf[i])
result = append(result, string(buf[i+1:next]))
i = next
}
return result
}
func TestSysctlClockinfo(t *testing.T) {
ci, err := unix.SysctlClockinfo("kern.clockrate")
if err != nil {
t.Fatal(err)
}
t.Logf("tick = %v, tickadj = %v, hz = %v, profhz = %v, stathz = %v",
ci.Tick, ci.Tickadj, ci.Hz, ci.Profhz, ci.Stathz)
}
func TestIoctlPtmget(t *testing.T) {
fd, err := unix.Open("/dev/ptmx", unix.O_NOCTTY|unix.O_RDWR, 0666)
if err != nil {
t.Skip("failed to open /dev/ptmx, skipping test")
}
defer unix.Close(fd)
ptm, err := unix.IoctlGetPtmget(fd, unix.TIOCPTSNAME)
if err != nil {
t.Fatalf("IoctlGetPtmget: %v\n", err)
}
t.Logf("sfd = %v, ptsname = %v", ptm.Sfd, string(ptm.Sn[:bytes.IndexByte(ptm.Sn[:], 0)]))
}
...@@ -43,6 +43,23 @@ func nametomib(name string) (mib []_C_int, err error) { ...@@ -43,6 +43,23 @@ func nametomib(name string) (mib []_C_int, err error) {
return nil, EINVAL return nil, EINVAL
} }
func SysctlUvmexp(name string) (*Uvmexp, error) {
mib, err := sysctlmib(name)
if err != nil {
return nil, err
}
n := uintptr(SizeofUvmexp)
var u Uvmexp
if err := sysctl(mib, (*byte)(unsafe.Pointer(&u)), &n, nil, 0); err != nil {
return nil, err
}
if n != SizeofUvmexp {
return nil, EIO
}
return &u, nil
}
//sysnb pipe(p *[2]_C_int) (err error) //sysnb pipe(p *[2]_C_int) (err error)
func Pipe(p []int) (err error) { func Pipe(p []int) (err error) {
if len(p) != 2 { if len(p) != 2 {
...@@ -113,11 +130,11 @@ func IoctlSetInt(fd int, req uint, value int) error { ...@@ -113,11 +130,11 @@ func IoctlSetInt(fd int, req uint, value int) error {
return ioctl(fd, req, uintptr(value)) return ioctl(fd, req, uintptr(value))
} }
func IoctlSetWinsize(fd int, req uint, value *Winsize) error { func ioctlSetWinsize(fd int, req uint, value *Winsize) error {
return ioctl(fd, req, uintptr(unsafe.Pointer(value))) return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
} }
func IoctlSetTermios(fd int, req uint, value *Termios) error { func ioctlSetTermios(fd int, req uint, value *Termios) error {
return ioctl(fd, req, uintptr(unsafe.Pointer(value))) return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
} }
...@@ -141,6 +158,15 @@ func IoctlGetTermios(fd int, req uint) (*Termios, error) { ...@@ -141,6 +158,15 @@ func IoctlGetTermios(fd int, req uint) (*Termios, error) {
return &value, err return &value, err
} }
//sys ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error)
func Ppoll(fds []PollFd, timeout *Timespec, sigmask *Sigset_t) (n int, err error) {
if len(fds) == 0 {
return ppoll(nil, 0, timeout, sigmask)
}
return ppoll(&fds[0], len(fds), timeout, sigmask)
}
func Uname(uname *Utsname) error { func Uname(uname *Utsname) error {
mib := []_C_int{CTL_KERN, KERN_OSTYPE} mib := []_C_int{CTL_KERN, KERN_OSTYPE}
n := unsafe.Sizeof(uname.Sysname) n := unsafe.Sizeof(uname.Sysname)
...@@ -207,6 +233,7 @@ func Uname(uname *Utsname) error { ...@@ -207,6 +233,7 @@ func Uname(uname *Utsname) error {
//sys Fchmod(fd int, mode uint32) (err error) //sys Fchmod(fd int, mode uint32) (err error)
//sys Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) //sys Fchmodat(dirfd int, path string, mode uint32, flags int) (err error)
//sys Fchown(fd int, uid int, gid int) (err error) //sys Fchown(fd int, uid int, gid int) (err error)
//sys Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error)
//sys Flock(fd int, how int) (err error) //sys Flock(fd int, how int) (err error)
//sys Fpathconf(fd int, name int) (val int, err error) //sys Fpathconf(fd int, name int) (val int, err error)
//sys Fstat(fd int, stat *Stat_t) (err error) //sys Fstat(fd int, stat *Stat_t) (err error)
...@@ -233,19 +260,26 @@ func Uname(uname *Utsname) error { ...@@ -233,19 +260,26 @@ func Uname(uname *Utsname) error {
//sys Kqueue() (fd int, err error) //sys Kqueue() (fd int, err error)
//sys Lchown(path string, uid int, gid int) (err error) //sys Lchown(path string, uid int, gid int) (err error)
//sys Link(path string, link string) (err error) //sys Link(path string, link string) (err error)
//sys Linkat(pathfd int, path string, linkfd int, link string, flags int) (err error)
//sys Listen(s int, backlog int) (err error) //sys Listen(s int, backlog int) (err error)
//sys Lstat(path string, stat *Stat_t) (err error) //sys Lstat(path string, stat *Stat_t) (err error)
//sys Mkdir(path string, mode uint32) (err error) //sys Mkdir(path string, mode uint32) (err error)
//sys Mkdirat(dirfd int, path string, mode uint32) (err error)
//sys Mkfifo(path string, mode uint32) (err error) //sys Mkfifo(path string, mode uint32) (err error)
//sys Mkfifoat(dirfd int, path string, mode uint32) (err error)
//sys Mknod(path string, mode uint32, dev int) (err error) //sys Mknod(path string, mode uint32, dev int) (err error)
//sys Mknodat(dirfd int, path string, mode uint32, dev int) (err error)
//sys Nanosleep(time *Timespec, leftover *Timespec) (err error) //sys Nanosleep(time *Timespec, leftover *Timespec) (err error)
//sys Open(path string, mode int, perm uint32) (fd int, err error) //sys Open(path string, mode int, perm uint32) (fd int, err error)
//sys Openat(dirfd int, path string, mode int, perm uint32) (fd int, err error)
//sys Pathconf(path string, name int) (val int, err error) //sys Pathconf(path string, name int) (val int, err error)
//sys Pread(fd int, p []byte, offset int64) (n int, err error) //sys Pread(fd int, p []byte, offset int64) (n int, err error)
//sys Pwrite(fd int, p []byte, offset int64) (n int, err error) //sys Pwrite(fd int, p []byte, offset int64) (n int, err error)
//sys read(fd int, p []byte) (n int, err error) //sys read(fd int, p []byte) (n int, err error)
//sys Readlink(path string, buf []byte) (n int, err error) //sys Readlink(path string, buf []byte) (n int, err error)
//sys Readlinkat(dirfd int, path string, buf []byte) (n int, err error)
//sys Rename(from string, to string) (err error) //sys Rename(from string, to string) (err error)
//sys Renameat(fromfd int, from string, tofd int, to string) (err error)
//sys Revoke(path string) (err error) //sys Revoke(path string) (err error)
//sys Rmdir(path string) (err error) //sys Rmdir(path string) (err error)
//sys Seek(fd int, offset int64, whence int) (newoffset int64, err error) = SYS_LSEEK //sys Seek(fd int, offset int64, whence int) (newoffset int64, err error) = SYS_LSEEK
...@@ -268,10 +302,12 @@ func Uname(uname *Utsname) error { ...@@ -268,10 +302,12 @@ func Uname(uname *Utsname) error {
//sys Stat(path string, stat *Stat_t) (err error) //sys Stat(path string, stat *Stat_t) (err error)
//sys Statfs(path string, stat *Statfs_t) (err error) //sys Statfs(path string, stat *Statfs_t) (err error)
//sys Symlink(path string, link string) (err error) //sys Symlink(path string, link string) (err error)
//sys Symlinkat(oldpath string, newdirfd int, newpath string) (err error)
//sys Sync() (err error) //sys Sync() (err error)
//sys Truncate(path string, length int64) (err error) //sys Truncate(path string, length int64) (err error)
//sys Umask(newmask int) (oldmask int) //sys Umask(newmask int) (oldmask int)
//sys Unlink(path string) (err error) //sys Unlink(path string) (err error)
//sys Unlinkat(dirfd int, path string, flags int) (err error)
//sys Unmount(path string, flags int) (err error) //sys Unmount(path string, flags int) (err error)
//sys write(fd int, p []byte) (n int, err error) //sys write(fd int, p []byte) (n int, err error)
//sys mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) //sys mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error)
...@@ -294,15 +330,11 @@ func Uname(uname *Utsname) error { ...@@ -294,15 +330,11 @@ func Uname(uname *Utsname) error {
// clock_settime // clock_settime
// closefrom // closefrom
// execve // execve
// faccessat
// fchmodat
// fchownat
// fcntl // fcntl
// fhopen // fhopen
// fhstat // fhstat
// fhstatfs // fhstatfs
// fork // fork
// fstatat
// futimens // futimens
// getfh // getfh
// getgid // getgid
...@@ -316,12 +348,8 @@ func Uname(uname *Utsname) error { ...@@ -316,12 +348,8 @@ func Uname(uname *Utsname) error {
// lfs_markv // lfs_markv
// lfs_segclean // lfs_segclean
// lfs_segwait // lfs_segwait
// linkat
// mincore // mincore
// minherit // minherit
// mkdirat
// mkfifoat
// mknodat
// mount // mount
// mquery // mquery
// msgctl // msgctl
...@@ -330,12 +358,10 @@ func Uname(uname *Utsname) error { ...@@ -330,12 +358,10 @@ func Uname(uname *Utsname) error {
// msgsnd // msgsnd
// nfssvc // nfssvc
// nnpfspioctl // nnpfspioctl
// openat
// preadv // preadv
// profil // profil
// pwritev // pwritev
// quotactl // quotactl
// readlinkat
// readv // readv
// reboot // reboot
// renameat // renameat
...@@ -356,13 +382,11 @@ func Uname(uname *Utsname) error { ...@@ -356,13 +382,11 @@ func Uname(uname *Utsname) error {
// sigprocmask // sigprocmask
// sigreturn // sigreturn
// sigsuspend // sigsuspend
// symlinkat
// sysarch // sysarch
// syscall // syscall
// threxit // threxit
// thrsigdivert // thrsigdivert
// thrsleep // thrsleep
// thrwakeup // thrwakeup
// unlinkat
// vfork // vfork
// writev // writev
...@@ -31,3 +31,7 @@ func (msghdr *Msghdr) SetControllen(length int) { ...@@ -31,3 +31,7 @@ func (msghdr *Msghdr) SetControllen(length int) {
func (cmsg *Cmsghdr) SetLen(length int) { func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint32(length) cmsg.Len = uint32(length)
} }
// SYS___SYSCTL is used by syscall_bsd.go for all BSDs, but in modern versions
// of openbsd/386 the syscall is called sysctl instead of __sysctl.
const SYS___SYSCTL = SYS_SYSCTL
...@@ -31,3 +31,7 @@ func (msghdr *Msghdr) SetControllen(length int) { ...@@ -31,3 +31,7 @@ func (msghdr *Msghdr) SetControllen(length int) {
func (cmsg *Cmsghdr) SetLen(length int) { func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint32(length) cmsg.Len = uint32(length)
} }
// SYS___SYSCTL is used by syscall_bsd.go for all BSDs, but in modern versions
// of openbsd/arm the syscall is called sysctl instead of __sysctl.
const SYS___SYSCTL = SYS_SYSCTL
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package unix_test
import (
"testing"
"time"
"golang.org/x/sys/unix"
)
func TestPpoll(t *testing.T) {
f, cleanup := mktmpfifo(t)
defer cleanup()
const timeout = 100 * time.Millisecond
ok := make(chan bool, 1)
go func() {
select {
case <-time.After(10 * timeout):
t.Errorf("Ppoll: failed to timeout after %d", 10*timeout)
case <-ok:
}
}()
fds := []unix.PollFd{{Fd: int32(f.Fd()), Events: unix.POLLIN}}
timeoutTs := unix.NsecToTimespec(int64(timeout))
n, err := unix.Ppoll(fds, &timeoutTs, nil)
ok <- true
if err != nil {
t.Errorf("Ppoll: unexpected error: %v", err)
return
}
if n != 0 {
t.Errorf("Ppoll: wrong number of events: got %v, expected %v", n, 0)
return
}
}
func TestSysctlUvmexp(t *testing.T) {
uvm, err := unix.SysctlUvmexp("vm.uvmexp")
if err != nil {
t.Fatal(err)
}
t.Logf("free = %v", uvm.Free)
}
...@@ -112,7 +112,7 @@ func Getsockname(fd int) (sa Sockaddr, err error) { ...@@ -112,7 +112,7 @@ func Getsockname(fd int) (sa Sockaddr, err error) {
if err = getsockname(fd, &rsa, &len); err != nil { if err = getsockname(fd, &rsa, &len); err != nil {
return return
} }
return anyToSockaddr(&rsa) return anyToSockaddr(fd, &rsa)
} }
// GetsockoptString returns the string value of the socket option opt for the // GetsockoptString returns the string value of the socket option opt for the
...@@ -360,7 +360,7 @@ func Futimes(fd int, tv []Timeval) error { ...@@ -360,7 +360,7 @@ func Futimes(fd int, tv []Timeval) error {
return futimesat(fd, nil, (*[2]Timeval)(unsafe.Pointer(&tv[0]))) return futimesat(fd, nil, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
} }
func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, error) { func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
switch rsa.Addr.Family { switch rsa.Addr.Family {
case AF_UNIX: case AF_UNIX:
pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa)) pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))
...@@ -411,7 +411,7 @@ func Accept(fd int) (nfd int, sa Sockaddr, err error) { ...@@ -411,7 +411,7 @@ func Accept(fd int) (nfd int, sa Sockaddr, err error) {
if nfd == -1 { if nfd == -1 {
return return
} }
sa, err = anyToSockaddr(&rsa) sa, err = anyToSockaddr(fd, &rsa)
if err != nil { if err != nil {
Close(nfd) Close(nfd)
nfd = 0 nfd = 0
...@@ -448,7 +448,7 @@ func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from ...@@ -448,7 +448,7 @@ func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from
oobn = int(msg.Accrightslen) oobn = int(msg.Accrightslen)
// source address is only specified if the socket is unconnected // source address is only specified if the socket is unconnected
if rsa.Addr.Family != AF_UNSPEC { if rsa.Addr.Family != AF_UNSPEC {
from, err = anyToSockaddr(&rsa) from, err = anyToSockaddr(fd, &rsa)
} }
return return
} }
...@@ -540,11 +540,11 @@ func IoctlSetInt(fd int, req uint, value int) (err error) { ...@@ -540,11 +540,11 @@ func IoctlSetInt(fd int, req uint, value int) (err error) {
return ioctl(fd, req, uintptr(value)) return ioctl(fd, req, uintptr(value))
} }
func IoctlSetWinsize(fd int, req uint, value *Winsize) (err error) { func ioctlSetWinsize(fd int, req uint, value *Winsize) (err error) {
return ioctl(fd, req, uintptr(unsafe.Pointer(value))) return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
} }
func IoctlSetTermios(fd int, req uint, value *Termios) (err error) { func ioctlSetTermios(fd int, req uint, value *Termios) (err error) {
return ioctl(fd, req, uintptr(unsafe.Pointer(value))) return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
} }
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build darwin dragonfly freebsd linux netbsd openbsd solaris // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
package unix_test package unix_test
......
...@@ -2,13 +2,12 @@ ...@@ -2,13 +2,12 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build darwin dragonfly freebsd linux netbsd openbsd solaris // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
package unix package unix
import ( import (
"bytes" "bytes"
"runtime"
"sort" "sort"
"sync" "sync"
"syscall" "syscall"
...@@ -21,13 +20,6 @@ var ( ...@@ -21,13 +20,6 @@ var (
Stderr = 2 Stderr = 2
) )
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 the interface allocations only once for common // Do the interface allocations only once for common
// Errno values. // Errno values.
var ( var (
...@@ -219,7 +211,7 @@ func Getpeername(fd int) (sa Sockaddr, err error) { ...@@ -219,7 +211,7 @@ func Getpeername(fd int) (sa Sockaddr, err error) {
if err = getpeername(fd, &rsa, &len); err != nil { if err = getpeername(fd, &rsa, &len); err != nil {
return return
} }
return anyToSockaddr(&rsa) return anyToSockaddr(fd, &rsa)
} }
func GetsockoptByte(fd, level, opt int) (value byte, err error) { func GetsockoptByte(fd, level, opt int) (value byte, err error) {
...@@ -291,7 +283,7 @@ func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) { ...@@ -291,7 +283,7 @@ func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) {
return return
} }
if rsa.Addr.Family != AF_UNSPEC { if rsa.Addr.Family != AF_UNSPEC {
from, err = anyToSockaddr(&rsa) from, err = anyToSockaddr(fd, &rsa)
} }
return return
} }
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build darwin dragonfly freebsd linux netbsd openbsd solaris // +build darwin dragonfly freebsd linux netbsd openbsd solaris
// +build !gccgo // +build !gccgo,!ppc64le,!ppc64
package unix package unix
......
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build linux
// +build ppc64le ppc64
// +build !gccgo
package unix
import "syscall"
func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno) {
return syscall.Syscall(trap, a1, a2, a3)
}
func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno) {
return syscall.Syscall6(trap, a1, a2, a3, a4, a5, a6)
}
func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno) {
return syscall.RawSyscall(trap, a1, a2, a3)
}
func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno) {
return syscall.RawSyscall6(trap, a1, a2, a3, a4, a5, a6)
}
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build darwin dragonfly freebsd linux netbsd openbsd solaris // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
package unix_test package unix_test
...@@ -146,6 +146,9 @@ func TestPassFD(t *testing.T) { ...@@ -146,6 +146,9 @@ func TestPassFD(t *testing.T) {
if runtime.GOOS == "darwin" && (runtime.GOARCH == "arm" || runtime.GOARCH == "arm64") { if runtime.GOOS == "darwin" && (runtime.GOARCH == "arm" || runtime.GOARCH == "arm64") {
t.Skip("cannot exec subprocess on iOS, skipping test") t.Skip("cannot exec subprocess on iOS, skipping test")
} }
if runtime.GOOS == "aix" {
t.Skip("getsockname issue on AIX 7.2 tl1, skipping test")
}
if os.Getenv("GO_WANT_HELPER_PROCESS") == "1" { if os.Getenv("GO_WANT_HELPER_PROCESS") == "1" {
passFDChild() passFDChild()
...@@ -450,9 +453,9 @@ func TestGetwd(t *testing.T) { ...@@ -450,9 +453,9 @@ func TestGetwd(t *testing.T) {
t.Fatalf("Open .: %s", err) t.Fatalf("Open .: %s", err)
} }
defer fd.Close() defer fd.Close()
// These are chosen carefully not to be symlinks on a Mac // Directory list for test. Do not worry if any are symlinks or do not
// (unlike, say, /var, /etc) // exist on some common unix desktop environments. That will be checked.
dirs := []string{"/", "/usr/bin"} dirs := []string{"/", "/usr/bin", "/etc", "/var", "/opt"}
switch runtime.GOOS { switch runtime.GOOS {
case "android": case "android":
dirs = []string{"/", "/system/bin"} dirs = []string{"/", "/system/bin"}
...@@ -472,6 +475,17 @@ func TestGetwd(t *testing.T) { ...@@ -472,6 +475,17 @@ func TestGetwd(t *testing.T) {
} }
oldwd := os.Getenv("PWD") oldwd := os.Getenv("PWD")
for _, d := range dirs { for _, d := range dirs {
// Check whether d exists, is a dir and that d's path does not contain a symlink
fi, err := os.Stat(d)
if err != nil || !fi.IsDir() {
t.Logf("Test dir %s stat error (%v) or not a directory, skipping", d, err)
continue
}
check, err := filepath.EvalSymlinks(d)
if err != nil || check != d {
t.Logf("Test dir %s (%s) is symlink or other error (%v), skipping", d, check, err)
continue
}
err = os.Chdir(d) err = os.Chdir(d)
if err != nil { if err != nil {
t.Fatalf("Chdir: %v", err) t.Fatalf("Chdir: %v", err)
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment