syscall: support Getwd on all BSDs

All supported BSDs provide the SYS___GETCWD syscall which can be used to
implement syscall.Getwd. With this change os.Getwd can use a single
syscall instead of falling back to the current kludge solution on the
BSDs.

This doesn't add any new exported functions to the frozen syscall
package, only ImplementsGetwd changes to true for dragonfly, freebsd,
netbsd and openbsd.

As suggested by Ian, this follows CL 83755 which did the same for
golang.org/x/sys/unix.

Also, an entry for netbsd/arm is added to mkall.sh which was used to
generate the syscall wrappers there.

Change-Id: I84da1ec61a6b8625443699a63cde556b6442ad41
Reviewed-on: https://go-review.googlesource.com/84484
Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
Tobias Klauser 2017-12-14 11:59:33 +01:00 committed by Tobias Klauser
parent dc27d68936
commit acd17e9b2b
34 changed files with 292 additions and 20 deletions

View file

@ -15,25 +15,30 @@ pkg syscall (darwin-amd64-cgo), func Fchflags(string, int) error
pkg syscall (freebsd-386), const AF_MAX = 38
pkg syscall (freebsd-386), const DLT_MATCHING_MAX = 242
pkg syscall (freebsd-386), const ELAST = 94
pkg syscall (freebsd-386), const ImplementsGetwd = false
pkg syscall (freebsd-386), const O_CLOEXEC = 0
pkg syscall (freebsd-386), func Fchflags(string, int) error
pkg syscall (freebsd-386-cgo), const AF_MAX = 38
pkg syscall (freebsd-386-cgo), const DLT_MATCHING_MAX = 242
pkg syscall (freebsd-386-cgo), const ELAST = 94
pkg syscall (freebsd-386-cgo), const ImplementsGetwd = false
pkg syscall (freebsd-386-cgo), const O_CLOEXEC = 0
pkg syscall (freebsd-amd64), const AF_MAX = 38
pkg syscall (freebsd-amd64), const DLT_MATCHING_MAX = 242
pkg syscall (freebsd-amd64), const ELAST = 94
pkg syscall (freebsd-amd64), const ImplementsGetwd = false
pkg syscall (freebsd-amd64), const O_CLOEXEC = 0
pkg syscall (freebsd-amd64), func Fchflags(string, int) error
pkg syscall (freebsd-amd64-cgo), const AF_MAX = 38
pkg syscall (freebsd-amd64-cgo), const DLT_MATCHING_MAX = 242
pkg syscall (freebsd-amd64-cgo), const ELAST = 94
pkg syscall (freebsd-amd64-cgo), const ImplementsGetwd = false
pkg syscall (freebsd-amd64-cgo), const O_CLOEXEC = 0
pkg syscall (freebsd-arm), const AF_MAX = 38
pkg syscall (freebsd-arm), const BIOCGRTIMEOUT = 1074545262
pkg syscall (freebsd-arm), const BIOCSRTIMEOUT = 2148287085
pkg syscall (freebsd-arm), const ELAST = 94
pkg syscall (freebsd-arm), const ImplementsGetwd = false
pkg syscall (freebsd-arm), const O_CLOEXEC = 0
pkg syscall (freebsd-arm), const SIOCAIFADDR = 2151967019
pkg syscall (freebsd-arm), const SIOCGIFSTATUS = 3274991931
@ -65,6 +70,7 @@ pkg syscall (freebsd-arm-cgo), const AF_MAX = 38
pkg syscall (freebsd-arm-cgo), const BIOCGRTIMEOUT = 1074545262
pkg syscall (freebsd-arm-cgo), const BIOCSRTIMEOUT = 2148287085
pkg syscall (freebsd-arm-cgo), const ELAST = 94
pkg syscall (freebsd-arm-cgo), const ImplementsGetwd = false
pkg syscall (freebsd-arm-cgo), const O_CLOEXEC = 0
pkg syscall (freebsd-arm-cgo), const SIOCAIFADDR = 2151967019
pkg syscall (freebsd-arm-cgo), const SIOCGIFSTATUS = 3274991931
@ -98,6 +104,12 @@ pkg syscall (linux-amd64), type Cmsghdr struct, X__cmsg_data [0]uint8
pkg syscall (linux-amd64-cgo), type Cmsghdr struct, X__cmsg_data [0]uint8
pkg syscall (linux-arm), type Cmsghdr struct, X__cmsg_data [0]uint8
pkg syscall (linux-arm-cgo), type Cmsghdr struct, X__cmsg_data [0]uint8
pkg syscall (netbsd-386), const ImplementsGetwd = false
pkg syscall (netbsd-386-cgo), const ImplementsGetwd = false
pkg syscall (netbsd-amd64), const ImplementsGetwd = false
pkg syscall (netbsd-amd64-cgo), const ImplementsGetwd = false
pkg syscall (netbsd-arm), const ImplementsGetwd = false
pkg syscall (netbsd-arm-cgo), const ImplementsGetwd = false
pkg syscall (netbsd-arm), const SizeofIfData = 132
pkg syscall (netbsd-arm), func Fchflags(string, int) error
pkg syscall (netbsd-arm), type IfMsghdr struct, Pad_cgo_1 [4]uint8
@ -106,6 +118,7 @@ pkg syscall (netbsd-arm-cgo), func Fchflags(string, int) error
pkg syscall (netbsd-arm-cgo), type IfMsghdr struct, Pad_cgo_1 [4]uint8
pkg syscall (openbsd-386), const BIOCGRTIMEOUT = 1074283118
pkg syscall (openbsd-386), const BIOCSRTIMEOUT = 2148024941
pkg syscall (openbsd-386), const ImplementsGetwd = false
pkg syscall (openbsd-386), const RTF_FMASK = 63496
pkg syscall (openbsd-386), const RTM_VERSION = 4
pkg syscall (openbsd-386), const SIOCBRDGDADDR = 2150132039
@ -158,6 +171,7 @@ pkg syscall (openbsd-386), type Timespec struct, Sec int32
pkg syscall (openbsd-386), type Timeval struct, Sec int32
pkg syscall (openbsd-386-cgo), const BIOCGRTIMEOUT = 1074283118
pkg syscall (openbsd-386-cgo), const BIOCSRTIMEOUT = 2148024941
pkg syscall (openbsd-386-cgo), const ImplementsGetwd = false
pkg syscall (openbsd-386-cgo), const RTF_FMASK = 63496
pkg syscall (openbsd-386-cgo), const RTM_VERSION = 4
pkg syscall (openbsd-386-cgo), const SIOCBRDGDADDR = 2150132039
@ -220,6 +234,7 @@ pkg syscall (openbsd-amd64), const EFER_NXE = 2048
pkg syscall (openbsd-amd64), const EFER_NXE ideal-int
pkg syscall (openbsd-amd64), const EFER_SCE = 1
pkg syscall (openbsd-amd64), const EFER_SCE ideal-int
pkg syscall (openbsd-amd64), const ImplementsGetwd = false
pkg syscall (openbsd-amd64), const PMC5_PIPELINE_FLUSH = 21
pkg syscall (openbsd-amd64), const PMC5_PIPELINE_FLUSH ideal-int
pkg syscall (openbsd-amd64), const RTF_FMASK = 63496
@ -282,6 +297,7 @@ pkg syscall (openbsd-amd64-cgo), const EFER_NXE = 2048
pkg syscall (openbsd-amd64-cgo), const EFER_NXE ideal-int
pkg syscall (openbsd-amd64-cgo), const EFER_SCE = 1
pkg syscall (openbsd-amd64-cgo), const EFER_SCE ideal-int
pkg syscall (openbsd-amd64-cgo), const ImplementsGetwd = false
pkg syscall (openbsd-amd64-cgo), const PMC5_PIPELINE_FLUSH = 21
pkg syscall (openbsd-amd64-cgo), const PMC5_PIPELINE_FLUSH ideal-int
pkg syscall (openbsd-amd64-cgo), const RTF_FMASK = 63496

View file

@ -234,6 +234,12 @@ netbsd_amd64)
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"
;;
netbsd_arm)
mkerrors="$mkerrors -m32"
mksyscall="./mksyscall.pl -l32 -netbsd -arm"
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"
;;
openbsd_386)
mkerrors="$mkerrors -m32"
mksyscall="./mksyscall.pl -l32 -openbsd"

View file

@ -216,6 +216,7 @@ func setattrlistTimes(path string, times []Timespec) error {
//sys writelen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_WRITE
//sys accept4(fd int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (nfd int, err error)
//sys utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error)
//sys getcwd(buf []byte) (n int, err error) = SYS___GETCWD
/*
* Unimplemented

View file

@ -220,6 +220,7 @@ func setattrlistTimes(path string, times []Timespec) error {
//sys writelen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_WRITE
//sys accept4(fd int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (nfd int, err error)
//sys utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error)
//sys getcwd(buf []byte) (n int, err error) = SYS___GETCWD
/*
* Unimplemented

View file

@ -0,0 +1,22 @@
// 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 dragonfly freebsd netbsd openbsd
package syscall
const ImplementsGetwd = true
func Getwd() (string, error) {
var buf [pathMax]byte
_, err := getcwd(buf[:])
if err != nil {
return "", err
}
n := clen(buf[:])
if n < 1 {
return "", EINVAL
}
return string(buf[:n]), nil
}

View file

@ -207,6 +207,7 @@ func setattrlistTimes(path string, times []Timespec) error {
//sys readlen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_READ
//sys writelen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_WRITE
//sys utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error)
//sys getcwd(buf []byte) (n int, err error) = SYS___GETCWD
/*
* Unimplemented

View file

@ -1,11 +0,0 @@
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build dragonfly freebsd netbsd openbsd
package syscall
const ImplementsGetwd = false
func Getwd() (string, error) { return "", ENOTSUP }

View file

@ -188,6 +188,7 @@ func setattrlistTimes(path string, times []Timespec) error {
//sys readlen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_READ
//sys writelen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_WRITE
//sys utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error)
//sys getcwd(buf []byte) (n int, err error) = SYS___GETCWD
/*
* Unimplemented

View file

@ -29,15 +29,6 @@ type SockaddrDatalink struct {
raw RawSockaddrDatalink
}
func clen(n []byte) int {
for i := 0; i < len(n); i++ {
if n[i] == 0 {
return i
}
}
return len(n)
}
func direntIno(buf []byte) (uint64, bool) {
return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino))
}

View file

@ -31,6 +31,16 @@ func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
// clen returns the index of the first NULL byte in n or len(n) if n contains no NULL byte.
func clen(n []byte) int {
for i := 0; i < len(n); i++ {
if n[i] == 0 {
return i
}
}
return len(n)
}
// Mmap manager, for use by operating system-specific implementations.
type mmapper struct {

View file

@ -125,6 +125,12 @@ type Dirent C.struct_dirent
type Fsid C.struct_fsid
// File system limits
const (
pathMax = C.PATH_MAX
)
// Sockets
type RawSockaddrInet4 C.struct_sockaddr_in

View file

@ -210,6 +210,12 @@ type Dirent C.struct_dirent
type Fsid C.struct_fsid
// File system limits
const (
pathMax = C.PATH_MAX
)
// Sockets
type RawSockaddrInet4 C.struct_sockaddr_in

View file

@ -110,6 +110,12 @@ type Dirent C.struct_dirent
type Fsid C.fsid_t
// File system limits
const (
pathMax = C.PATH_MAX
)
// Sockets
type RawSockaddrInet4 C.struct_sockaddr_in

View file

@ -126,6 +126,12 @@ type Dirent C.struct_dirent
type Fsid C.fsid_t
// File system limits
const (
pathMax = C.PATH_MAX
)
// Sockets
type RawSockaddrInet4 C.struct_sockaddr_in

View file

@ -1306,3 +1306,20 @@ func utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func getcwd(buf []byte) (n int, err error) {
var _p0 unsafe.Pointer
if len(buf) > 0 {
_p0 = unsafe.Pointer(&buf[0])
} else {
_p0 = unsafe.Pointer(&_zero)
}
r0, _, e1 := Syscall(SYS___GETCWD, uintptr(_p0), uintptr(len(buf)), 0)
n = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}

View file

@ -1304,3 +1304,20 @@ func utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func getcwd(buf []byte) (n int, err error) {
var _p0 unsafe.Pointer
if len(buf) > 0 {
_p0 = unsafe.Pointer(&buf[0])
} else {
_p0 = unsafe.Pointer(&_zero)
}
r0, _, e1 := Syscall(SYS___GETCWD, uintptr(_p0), uintptr(len(buf)), 0)
n = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}

View file

@ -1304,3 +1304,20 @@ func utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func getcwd(buf []byte) (n int, err error) {
var _p0 unsafe.Pointer
if len(buf) > 0 {
_p0 = unsafe.Pointer(&buf[0])
} else {
_p0 = unsafe.Pointer(&_zero)
}
r0, _, e1 := Syscall(SYS___GETCWD, uintptr(_p0), uintptr(len(buf)), 0)
n = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}

View file

@ -1304,3 +1304,20 @@ func utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func getcwd(buf []byte) (n int, err error) {
var _p0 unsafe.Pointer
if len(buf) > 0 {
_p0 = unsafe.Pointer(&buf[0])
} else {
_p0 = unsafe.Pointer(&_zero)
}
r0, _, e1 := Syscall(SYS___GETCWD, uintptr(_p0), uintptr(len(buf)), 0)
n = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}

View file

@ -1232,3 +1232,20 @@ func utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func getcwd(buf []byte) (n int, err error) {
var _p0 unsafe.Pointer
if len(buf) > 0 {
_p0 = unsafe.Pointer(&buf[0])
} else {
_p0 = unsafe.Pointer(&_zero)
}
r0, _, e1 := Syscall(SYS___GETCWD, uintptr(_p0), uintptr(len(buf)), 0)
n = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}

View file

@ -1232,3 +1232,20 @@ func utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func getcwd(buf []byte) (n int, err error) {
var _p0 unsafe.Pointer
if len(buf) > 0 {
_p0 = unsafe.Pointer(&buf[0])
} else {
_p0 = unsafe.Pointer(&_zero)
}
r0, _, e1 := Syscall(SYS___GETCWD, uintptr(_p0), uintptr(len(buf)), 0)
n = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}

View file

@ -1232,3 +1232,20 @@ func utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func getcwd(buf []byte) (n int, err error) {
var _p0 unsafe.Pointer
if len(buf) > 0 {
_p0 = unsafe.Pointer(&buf[0])
} else {
_p0 = unsafe.Pointer(&_zero)
}
r0, _, e1 := Syscall(SYS___GETCWD, uintptr(_p0), uintptr(len(buf)), 0)
n = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}

View file

@ -1270,3 +1270,20 @@ func utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func getcwd(buf []byte) (n int, err error) {
var _p0 unsafe.Pointer
if len(buf) > 0 {
_p0 = unsafe.Pointer(&buf[0])
} else {
_p0 = unsafe.Pointer(&_zero)
}
r0, _, e1 := Syscall(SYS___GETCWD, uintptr(_p0), uintptr(len(buf)), 0)
n = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}

View file

@ -1270,3 +1270,20 @@ func utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func getcwd(buf []byte) (n int, err error) {
var _p0 unsafe.Pointer
if len(buf) > 0 {
_p0 = unsafe.Pointer(&buf[0])
} else {
_p0 = unsafe.Pointer(&_zero)
}
r0, _, e1 := Syscall(SYS___GETCWD, uintptr(_p0), uintptr(len(buf)), 0)
n = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}

View file

@ -1270,3 +1270,20 @@ func utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func getcwd(buf []byte) (n int, err error) {
var _p0 unsafe.Pointer
if len(buf) > 0 {
_p0 = unsafe.Pointer(&buf[0])
} else {
_p0 = unsafe.Pointer(&_zero)
}
r0, _, e1 := Syscall(SYS___GETCWD, uintptr(_p0), uintptr(len(buf)), 0)
n = int(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}

View file

@ -143,6 +143,10 @@ type Fsid struct {
Val [2]int32
}
const (
pathMax = 0x400
)
type RawSockaddrInet4 struct {
Len uint8
Family uint8

View file

@ -140,6 +140,10 @@ type Fsid struct {
Val [2]int32
}
const (
pathMax = 0x400
)
type RawSockaddrInet4 struct {
Len uint8
Family uint8

View file

@ -140,6 +140,10 @@ type Fsid struct {
Val [2]int32
}
const (
pathMax = 0x400
)
type RawSockaddrInet4 struct {
Len uint8
Family uint8

View file

@ -142,6 +142,10 @@ type Fsid struct {
Val [2]int32
}
const (
pathMax = 0x400
)
type RawSockaddrInet4 struct {
Len uint8
Family uint8

View file

@ -99,6 +99,10 @@ type Fsid struct {
X__fsid_val [2]int32
}
const (
pathMax = 0x400
)
type RawSockaddrInet4 struct {
Len uint8
Family uint8

View file

@ -103,6 +103,10 @@ type Fsid struct {
X__fsid_val [2]int32
}
const (
pathMax = 0x400
)
type RawSockaddrInet4 struct {
Len uint8
Family uint8

View file

@ -104,6 +104,10 @@ type Fsid struct {
X__fsid_val [2]int32
}
const (
pathMax = 0x400
)
type RawSockaddrInet4 struct {
Len uint8
Family uint8

View file

@ -140,6 +140,10 @@ type Fsid struct {
Val [2]int32
}
const (
pathMax = 0x400
)
type RawSockaddrInet4 struct {
Len uint8
Family uint8

View file

@ -142,6 +142,10 @@ type Fsid struct {
Val [2]int32
}
const (
pathMax = 0x400
)
type RawSockaddrInet4 struct {
Len uint8
Family uint8

View file

@ -140,6 +140,10 @@ type Fsid struct {
Val [2]int32
}
const (
pathMax = 0x400
)
type RawSockaddrInet4 struct {
Len uint8
Family uint8