Bumps [golang.org/x/sys](https://github.com/golang/sys) from 0.0.0-20181213200352-4d1cda033e06 to 0.1.0. - [Release notes](https://github.com/golang/sys/releases) - [Commits](https://github.com/golang/sys/commits/v0.1.0) --- updated-dependencies: - dependency-name: golang.org/x/sys dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com>dependabot/go_modules/golang.org/x/sys-0.1.0
@@ -19,7 +19,7 @@ require ( | |||
github.com/writeas/web-core v0.0.0-20181111165528-05f387ffa1b3 | |||
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9 // indirect | |||
golang.org/x/net v0.0.0-20181217023233-e147a9138326 // indirect | |||
golang.org/x/sys v0.0.0-20181213200352-4d1cda033e06 // indirect | |||
golang.org/x/sys v0.1.0 // indirect | |||
gopkg.in/ini.v1 v1.39.3 | |||
gopkg.in/urfave/cli.v1 v1.20.0 | |||
) | |||
@@ -1,5 +1,3 @@ | |||
code.as/core/socks v0.0.0-20180906144846-5be269b4e664 h1:zWSFbwkYSuZ2PjvHqYDE/dhd9CCcsbSvUIRx8hIed3I= | |||
code.as/core/socks v0.0.0-20180906144846-5be269b4e664/go.mod h1:BAXBy5O9s2gmw6UxLqNJcVbWY7C/UPs+801CcSsfWOY= | |||
code.as/core/socks v1.0.0 h1:SPQXNp4SbEwjOAP9VzUahLHak8SDqy5n+9cm9tpjZOs= | |||
code.as/core/socks v1.0.0/go.mod h1:BAXBy5O9s2gmw6UxLqNJcVbWY7C/UPs+801CcSsfWOY= | |||
github.com/atotto/clipboard v0.1.1 h1:WSoEbAS70E5gw8FbiqFlp69MGsB6dUb4l+0AGGLiVGw= | |||
@@ -39,8 +37,6 @@ github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c h1:Ho+uVpke | |||
github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s= | |||
github.com/writeas/go-writeas/v2 v2.0.2 h1:akvdMg89U5oBJiCkBwOXljVLTqP354uN6qnG2oOMrbk= | |||
github.com/writeas/go-writeas/v2 v2.0.2/go.mod h1:9sjczQJKmru925fLzg0usrU1R1tE4vBmQtGnItUMR0M= | |||
github.com/writeas/impart v0.0.0-20180808220913-fef51864677b h1:vsZIsYneuNwXMsnh0lKviEVc8WeIqBG4RTmGWU86HpI= | |||
github.com/writeas/impart v0.0.0-20180808220913-fef51864677b/go.mod h1:sUkQZZHJfrVNsoD4QbkrYrRSQtCN3SaUPWKdohmFKT8= | |||
github.com/writeas/impart v1.1.0 h1:nPnoO211VscNkp/gnzir5UwCDEvdHThL5uELU60NFSE= | |||
github.com/writeas/impart v1.1.0/go.mod h1:g0MpxdnTOHHrl+Ca/2oMXUHJ0PcRAEWtkCzYCJUXC9Y= | |||
github.com/writeas/saturday v0.0.0-20170402010311-f455b05c043f h1:yyFguE0EopK8e7I7/AB1JWM925OFOI1uFhTM/SwXAnQ= | |||
@@ -55,8 +51,8 @@ golang.org/x/net v0.0.0-20181217023233-e147a9138326/go.mod h1:mL1N/T3taQHkDXs73r | |||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA= | |||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | |||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | |||
golang.org/x/sys v0.0.0-20181213200352-4d1cda033e06 h1:0oC8rFnE+74kEmuHZ46F6KHsMr5Gx2gUQPuNz28iQZM= | |||
golang.org/x/sys v0.0.0-20181213200352-4d1cda033e06/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | |||
golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U= | |||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | |||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= | |||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= | |||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= | |||
@@ -1,3 +0,0 @@ | |||
# This source code refers to The Go Authors for copyright purposes. | |||
# The master list of authors is in the main Go distribution, | |||
# visible at http://tip.golang.org/AUTHORS. |
@@ -1,3 +0,0 @@ | |||
# This source code was written by the Go contributors. | |||
# The master list of contributors is in the main Go distribution, | |||
# visible at http://tip.golang.org/CONTRIBUTORS. |
@@ -0,0 +1,30 @@ | |||
// Copyright 2020 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 unsafeheader contains header declarations for the Go runtime's | |||
// slice and string implementations. | |||
// | |||
// This package allows x/sys to use types equivalent to | |||
// reflect.SliceHeader and reflect.StringHeader without introducing | |||
// a dependency on the (relatively heavy) "reflect" package. | |||
package unsafeheader | |||
import ( | |||
"unsafe" | |||
) | |||
// Slice is the runtime representation of a slice. | |||
// It cannot be used safely or portably and its representation may change in a later release. | |||
type Slice struct { | |||
Data unsafe.Pointer | |||
Len int | |||
Cap int | |||
} | |||
// String is the runtime representation of a string. | |||
// It cannot be used safely or portably and its representation may change in a later release. | |||
type String struct { | |||
Data unsafe.Pointer | |||
Len int | |||
} |
@@ -14,7 +14,7 @@ migrating the build system to use containers so the builds are reproducible. | |||
This is being done on an OS-by-OS basis. Please update this documentation as | |||
components of the build system change. | |||
### Old Build System (currently for `GOOS != "Linux" || GOARCH == "sparc64"`) | |||
### Old Build System (currently for `GOOS != "linux"`) | |||
The old build system generates the Go files based on the C header files | |||
present on your system. This means that files | |||
@@ -32,9 +32,9 @@ To build the files for your current OS and architecture, make sure GOOS and | |||
GOARCH are set correctly and run `mkall.sh`. This will generate the files for | |||
your specific system. Running `mkall.sh -n` shows the commands that will be run. | |||
Requirements: bash, perl, go | |||
Requirements: bash, go | |||
### New Build System (currently for `GOOS == "Linux" && GOARCH != "sparc64"`) | |||
### New Build System (currently for `GOOS == "linux"`) | |||
The new build system uses a Docker container to generate the go files directly | |||
from source checkouts of the kernel and various system libraries. This means | |||
@@ -52,14 +52,14 @@ system and have your GOOS and GOARCH set accordingly. Running `mkall.sh` will | |||
then generate all of the files for all of the GOOS/GOARCH pairs in the new build | |||
system. Running `mkall.sh -n` shows the commands that will be run. | |||
Requirements: bash, perl, go, docker | |||
Requirements: bash, go, docker | |||
## Component files | |||
This section describes the various files used in the code generation process. | |||
It also contains instructions on how to modify these files to add a new | |||
architecture/OS or to add additional syscalls, types, or constants. Note that | |||
if you are using the new build system, the scripts cannot be called normally. | |||
if you are using the new build system, the scripts/programs cannot be called normally. | |||
They must be called from within the docker container. | |||
### asm files | |||
@@ -76,30 +76,30 @@ arguments can be passed to the kernel. The third is for low-level use by the | |||
ForkExec wrapper. Unlike the first two, it does not call into the scheduler to | |||
let it know that a system call is running. | |||
When porting Go to an new architecture/OS, this file must be implemented for | |||
When porting Go to a new architecture/OS, this file must be implemented for | |||
each GOOS/GOARCH pair. | |||
### mksysnum | |||
Mksysnum is a script located at `${GOOS}/mksysnum.pl` (or `mksysnum_${GOOS}.pl` | |||
for the old system). This script takes in a list of header files containing the | |||
Mksysnum is a Go program located at `${GOOS}/mksysnum.go` (or `mksysnum_${GOOS}.go` | |||
for the old system). This program takes in a list of header files containing the | |||
syscall number declarations and parses them to produce the corresponding list of | |||
Go numeric constants. See `zsysnum_${GOOS}_${GOARCH}.go` for the generated | |||
constants. | |||
Adding new syscall numbers is mostly done by running the build on a sufficiently | |||
new installation of the target OS (or updating the source checkouts for the | |||
new build system). However, depending on the OS, you make need to update the | |||
new build system). However, depending on the OS, you may need to update the | |||
parsing in mksysnum. | |||
### mksyscall.pl | |||
### mksyscall.go | |||
The `syscall.go`, `syscall_${GOOS}.go`, `syscall_${GOOS}_${GOARCH}.go` are | |||
hand-written Go files which implement system calls (for unix, the specific OS, | |||
or the specific OS/Architecture pair respectively) that need special handling | |||
and list `//sys` comments giving prototypes for ones that can be generated. | |||
The mksyscall.pl script takes the `//sys` and `//sysnb` comments and converts | |||
The mksyscall.go program takes the `//sys` and `//sysnb` comments and converts | |||
them into syscalls. This requires the name of the prototype in the comment to | |||
match a syscall number in the `zsysnum_${GOOS}_${GOARCH}.go` file. The function | |||
prototype can be exported (capitalized) or not. | |||
@@ -107,7 +107,7 @@ prototype can be exported (capitalized) or not. | |||
Adding a new syscall often just requires adding a new `//sys` function prototype | |||
with the desired arguments and a capitalized name so it is exported. However, if | |||
you want the interface to the syscall to be different, often one will make an | |||
unexported `//sys` prototype, an then write a custom wrapper in | |||
unexported `//sys` prototype, and then write a custom wrapper in | |||
`syscall_${GOOS}.go`. | |||
### types files | |||
@@ -137,7 +137,7 @@ some `#if/#elif` macros in your include statements. | |||
This script is used to generate the system's various constants. This doesn't | |||
just include the error numbers and error strings, but also the signal numbers | |||
an a wide variety of miscellaneous constants. The constants come from the list | |||
and a wide variety of miscellaneous constants. The constants come from the list | |||
of include files in the `includes_${uname}` variable. A regex then picks out | |||
the desired `#define` statements, and generates the corresponding Go constants. | |||
The error numbers and strings are generated from `#include <errno.h>`, and the | |||
@@ -149,10 +149,21 @@ To add a constant, add the header that includes it to the appropriate variable. | |||
Then, edit the regex (if necessary) to match the desired constant. Avoid making | |||
the regex too broad to avoid matching unintended constants. | |||
### internal/mkmerge | |||
This program is used to extract duplicate const, func, and type declarations | |||
from the generated architecture-specific files listed below, and merge these | |||
into a common file for each OS. | |||
The merge is performed in the following steps: | |||
1. Construct the set of common code that is idential in all architecture-specific files. | |||
2. Write this common code to the merged file. | |||
3. Remove the common code from all architecture-specific files. | |||
## Generated files | |||
### `zerror_${GOOS}_${GOARCH}.go` | |||
### `zerrors_${GOOS}_${GOARCH}.go` | |||
A file containing all of the system's generated error numbers, error strings, | |||
signal numbers, and constants. Generated by `mkerrors.sh` (see above). | |||
@@ -160,7 +171,7 @@ signal numbers, and constants. Generated by `mkerrors.sh` (see above). | |||
### `zsyscall_${GOOS}_${GOARCH}.go` | |||
A file containing all the generated syscalls for a specific GOOS and GOARCH. | |||
Generated by `mksyscall.pl` (see above). | |||
Generated by `mksyscall.go` (see above). | |||
### `zsysnum_${GOOS}_${GOARCH}.go` | |||
@@ -7,6 +7,7 @@ | |||
package unix | |||
import ( | |||
"math/bits" | |||
"unsafe" | |||
) | |||
@@ -79,46 +80,7 @@ func (s *CPUSet) IsSet(cpu int) bool { | |||
func (s *CPUSet) Count() int { | |||
c := 0 | |||
for _, b := range s { | |||
c += onesCount64(uint64(b)) | |||
c += bits.OnesCount64(uint64(b)) | |||
} | |||
return c | |||
} | |||
// onesCount64 is a copy of Go 1.9's math/bits.OnesCount64. | |||
// Once this package can require Go 1.9, we can delete this | |||
// and update the caller to use bits.OnesCount64. | |||
func onesCount64(x uint64) int { | |||
const m0 = 0x5555555555555555 // 01010101 ... | |||
const m1 = 0x3333333333333333 // 00110011 ... | |||
const m2 = 0x0f0f0f0f0f0f0f0f // 00001111 ... | |||
const m3 = 0x00ff00ff00ff00ff // etc. | |||
const m4 = 0x0000ffff0000ffff | |||
// Implementation: Parallel summing of adjacent bits. | |||
// See "Hacker's Delight", Chap. 5: Counting Bits. | |||
// The following pattern shows the general approach: | |||
// | |||
// x = x>>1&(m0&m) + x&(m0&m) | |||
// x = x>>2&(m1&m) + x&(m1&m) | |||
// x = x>>4&(m2&m) + x&(m2&m) | |||
// x = x>>8&(m3&m) + x&(m3&m) | |||
// x = x>>16&(m4&m) + x&(m4&m) | |||
// x = x>>32&(m5&m) + x&(m5&m) | |||
// return int(x) | |||
// | |||
// Masking (& operations) can be left away when there's no | |||
// danger that a field's sum will carry over into the next | |||
// field: Since the result cannot be > 64, 8 bits is enough | |||
// and we can ignore the masks for the shifts by 8 and up. | |||
// Per "Hacker's Delight", the first line can be simplified | |||
// more, but it saves at best one instruction, so we leave | |||
// it alone for clarity. | |||
const m = 1<<64 - 1 | |||
x = x>>1&(m0&m) + x&(m0&m) | |||
x = x>>2&(m1&m) + x&(m1&m) | |||
x = (x>>4 + x) & (m2 & m) | |||
x += x >> 8 | |||
x += x >> 16 | |||
x += x >> 32 | |||
return int(x) & (1<<7 - 1) | |||
} |
@@ -2,7 +2,8 @@ | |||
// 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 | |||
//go:build (aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos) && go1.9 | |||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos | |||
// +build go1.9 | |||
package unix | |||
@@ -2,7 +2,8 @@ | |||
// Use of this source code is governed by a BSD-style | |||
// license that can be found in the LICENSE file. | |||
// +build !gccgo | |||
//go:build gc | |||
// +build gc | |||
#include "textflag.h" | |||
@@ -1,14 +1,14 @@ | |||
// Copyright 2009 The Go Authors. All rights reserved. | |||
// Copyright 2021 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 | |||
//go:build (freebsd || netbsd || openbsd) && gc | |||
// +build freebsd netbsd openbsd | |||
// +build gc | |||
#include "textflag.h" | |||
// | |||
// System call support for 386, NetBSD | |||
// | |||
// System call support for 386 BSD | |||
// Just jump to package syscall's implementation for all these functions. | |||
// The runtime may know about them. | |||
@@ -22,7 +22,7 @@ TEXT ·Syscall6(SB),NOSPLIT,$0-40 | |||
TEXT ·Syscall9(SB),NOSPLIT,$0-52 | |||
JMP syscall·Syscall9(SB) | |||
TEXT ·RawSyscall(SB),NOSPLIT,$0-28 | |||
TEXT ·RawSyscall(SB),NOSPLIT,$0-28 | |||
JMP syscall·RawSyscall(SB) | |||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40 |
@@ -0,0 +1,29 @@ | |||
// Copyright 2021 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. | |||
//go:build (darwin || dragonfly || freebsd || netbsd || openbsd) && gc | |||
// +build darwin dragonfly freebsd netbsd openbsd | |||
// +build gc | |||
#include "textflag.h" | |||
// System call support for AMD64 BSD | |||
// Just jump to package syscall's implementation for all these functions. | |||
// The runtime may know about them. | |||
TEXT ·Syscall(SB),NOSPLIT,$0-56 | |||
JMP syscall·Syscall(SB) | |||
TEXT ·Syscall6(SB),NOSPLIT,$0-80 | |||
JMP syscall·Syscall6(SB) | |||
TEXT ·Syscall9(SB),NOSPLIT,$0-104 | |||
JMP syscall·Syscall9(SB) | |||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56 | |||
JMP syscall·RawSyscall(SB) | |||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 | |||
JMP syscall·RawSyscall6(SB) |
@@ -1,15 +1,14 @@ | |||
// Copyright 2015 The Go Authors. All rights reserved. | |||
// Copyright 2021 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 | |||
// +build arm,darwin | |||
//go:build (freebsd || netbsd || openbsd) && gc | |||
// +build freebsd netbsd openbsd | |||
// +build gc | |||
#include "textflag.h" | |||
// | |||
// System call support for ARM, Darwin | |||
// | |||
// System call support for ARM BSD | |||
// Just jump to package syscall's implementation for all these functions. | |||
// The runtime may know about them. |
@@ -1,14 +1,14 @@ | |||
// Copyright 2009 The Go Authors. All rights reserved. | |||
// Copyright 2021 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 | |||
//go:build (darwin || freebsd || netbsd || openbsd) && gc | |||
// +build darwin freebsd netbsd openbsd | |||
// +build gc | |||
#include "textflag.h" | |||
// | |||
// System call support for AMD64, Darwin | |||
// | |||
// System call support for ARM64 BSD | |||
// Just jump to package syscall's implementation for all these functions. | |||
// The runtime may know about them. |
@@ -1,13 +1,15 @@ | |||
// Copyright 2009 The Go Authors. All rights reserved. | |||
// Copyright 2022 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 | |||
//go:build (darwin || freebsd || netbsd || openbsd) && gc | |||
// +build darwin freebsd netbsd openbsd | |||
// +build gc | |||
#include "textflag.h" | |||
// | |||
// System call support for AMD64, NetBSD | |||
// System call support for ppc64, BSD | |||
// | |||
// Just jump to package syscall's implementation for all these functions. |
@@ -1,14 +1,14 @@ | |||
// Copyright 2009 The Go Authors. All rights reserved. | |||
// Copyright 2021 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 | |||
//go:build (darwin || freebsd || netbsd || openbsd) && gc | |||
// +build darwin freebsd netbsd openbsd | |||
// +build gc | |||
#include "textflag.h" | |||
// | |||
// System call support for AMD64, FreeBSD | |||
// | |||
// System call support for RISCV64 BSD | |||
// Just jump to package syscall's implementation for all these functions. | |||
// The runtime may know about them. | |||
@@ -22,7 +22,7 @@ TEXT ·Syscall6(SB),NOSPLIT,$0-80 | |||
TEXT ·Syscall9(SB),NOSPLIT,$0-104 | |||
JMP syscall·Syscall9(SB) | |||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56 | |||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56 | |||
JMP syscall·RawSyscall(SB) | |||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 |
@@ -1,29 +0,0 @@ | |||
// Copyright 2009 The Go Authors. All rights reserved. | |||
// Use of this source code is governed by a BSD-style | |||
// license that can be found in the LICENSE file. | |||
// +build !gccgo | |||
#include "textflag.h" | |||
// | |||
// System call support for 386, Darwin | |||
// | |||
// Just jump to package syscall's implementation for all these functions. | |||
// The runtime may know about them. | |||
TEXT ·Syscall(SB),NOSPLIT,$0-28 | |||
JMP syscall·Syscall(SB) | |||
TEXT ·Syscall6(SB),NOSPLIT,$0-40 | |||
JMP syscall·Syscall6(SB) | |||
TEXT ·Syscall9(SB),NOSPLIT,$0-52 | |||
JMP syscall·Syscall9(SB) | |||
TEXT ·RawSyscall(SB),NOSPLIT,$0-28 | |||
JMP syscall·RawSyscall(SB) | |||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40 | |||
JMP syscall·RawSyscall6(SB) |
@@ -1,30 +0,0 @@ | |||
// Copyright 2015 The Go Authors. All rights reserved. | |||
// Use of this source code is governed by a BSD-style | |||
// license that can be found in the LICENSE file. | |||
// +build !gccgo | |||
// +build arm64,darwin | |||
#include "textflag.h" | |||
// | |||
// System call support for AMD64, Darwin | |||
// | |||
// Just jump to package syscall's implementation for all these functions. | |||
// The runtime may know about them. | |||
TEXT ·Syscall(SB),NOSPLIT,$0-56 | |||
B syscall·Syscall(SB) | |||
TEXT ·Syscall6(SB),NOSPLIT,$0-80 | |||
B syscall·Syscall6(SB) | |||
TEXT ·Syscall9(SB),NOSPLIT,$0-104 | |||
B syscall·Syscall9(SB) | |||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56 | |||
B syscall·RawSyscall(SB) | |||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 | |||
B syscall·RawSyscall6(SB) |
@@ -1,29 +0,0 @@ | |||
// Copyright 2009 The Go Authors. All rights reserved. | |||
// Use of this source code is governed by a BSD-style | |||
// license that can be found in the LICENSE file. | |||
// +build !gccgo | |||
#include "textflag.h" | |||
// | |||
// System call support for AMD64, DragonFly | |||
// | |||
// Just jump to package syscall's implementation for all these functions. | |||
// The runtime may know about them. | |||
TEXT ·Syscall(SB),NOSPLIT,$0-56 | |||
JMP syscall·Syscall(SB) | |||
TEXT ·Syscall6(SB),NOSPLIT,$0-80 | |||
JMP syscall·Syscall6(SB) | |||
TEXT ·Syscall9(SB),NOSPLIT,$0-104 | |||
JMP syscall·Syscall9(SB) | |||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56 | |||
JMP syscall·RawSyscall(SB) | |||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 | |||
JMP syscall·RawSyscall6(SB) |
@@ -1,29 +0,0 @@ | |||
// Copyright 2009 The Go Authors. All rights reserved. | |||
// Use of this source code is governed by a BSD-style | |||
// license that can be found in the LICENSE file. | |||
// +build !gccgo | |||
#include "textflag.h" | |||
// | |||
// System call support for 386, FreeBSD | |||
// | |||
// Just jump to package syscall's implementation for all these functions. | |||
// The runtime may know about them. | |||
TEXT ·Syscall(SB),NOSPLIT,$0-28 | |||
JMP syscall·Syscall(SB) | |||
TEXT ·Syscall6(SB),NOSPLIT,$0-40 | |||
JMP syscall·Syscall6(SB) | |||
TEXT ·Syscall9(SB),NOSPLIT,$0-52 | |||
JMP syscall·Syscall9(SB) | |||
TEXT ·RawSyscall(SB),NOSPLIT,$0-28 | |||
JMP syscall·RawSyscall(SB) | |||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40 | |||
JMP syscall·RawSyscall6(SB) |
@@ -1,29 +0,0 @@ | |||
// Copyright 2012 The Go Authors. All rights reserved. | |||
// Use of this source code is governed by a BSD-style | |||
// license that can be found in the LICENSE file. | |||
// +build !gccgo | |||
#include "textflag.h" | |||
// | |||
// System call support for ARM, FreeBSD | |||
// | |||
// Just jump to package syscall's implementation for all these functions. | |||
// The runtime may know about them. | |||
TEXT ·Syscall(SB),NOSPLIT,$0-28 | |||
B syscall·Syscall(SB) | |||
TEXT ·Syscall6(SB),NOSPLIT,$0-40 | |||
B syscall·Syscall6(SB) | |||
TEXT ·Syscall9(SB),NOSPLIT,$0-52 | |||
B syscall·Syscall9(SB) | |||
TEXT ·RawSyscall(SB),NOSPLIT,$0-28 | |||
B syscall·RawSyscall(SB) | |||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40 | |||
B syscall·RawSyscall6(SB) |
@@ -2,7 +2,8 @@ | |||
// Use of this source code is governed by a BSD-style | |||
// license that can be found in the LICENSE file. | |||
// +build !gccgo | |||
//go:build gc | |||
// +build gc | |||
#include "textflag.h" | |||
@@ -2,7 +2,8 @@ | |||
// Use of this source code is governed by a BSD-style | |||
// license that can be found in the LICENSE file. | |||
// +build !gccgo | |||
//go:build gc | |||
// +build gc | |||
#include "textflag.h" | |||
@@ -2,7 +2,8 @@ | |||
// Use of this source code is governed by a BSD-style | |||
// license that can be found in the LICENSE file. | |||
// +build !gccgo | |||
//go:build gc | |||
// +build gc | |||
#include "textflag.h" | |||
@@ -2,9 +2,10 @@ | |||
// Use of this source code is governed by a BSD-style | |||
// license that can be found in the LICENSE file. | |||
//go:build linux && arm64 && gc | |||
// +build linux | |||
// +build arm64 | |||
// +build !gccgo | |||
// +build gc | |||
#include "textflag.h" | |||
@@ -0,0 +1,54 @@ | |||
// Copyright 2022 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. | |||
//go:build linux && loong64 && gc | |||
// +build linux | |||
// +build loong64 | |||
// +build gc | |||
#include "textflag.h" | |||
// Just jump to package syscall's implementation for all these functions. | |||
// The runtime may know about them. | |||
TEXT ·Syscall(SB),NOSPLIT,$0-56 | |||
JMP syscall·Syscall(SB) | |||
TEXT ·Syscall6(SB),NOSPLIT,$0-80 | |||
JMP syscall·Syscall6(SB) | |||
TEXT ·SyscallNoError(SB),NOSPLIT,$0-48 | |||
JAL runtime·entersyscall(SB) | |||
MOVV a1+8(FP), R4 | |||
MOVV a2+16(FP), R5 | |||
MOVV a3+24(FP), R6 | |||
MOVV R0, R7 | |||
MOVV R0, R8 | |||
MOVV R0, R9 | |||
MOVV trap+0(FP), R11 // syscall entry | |||
SYSCALL | |||
MOVV R4, r1+32(FP) | |||
MOVV R0, r2+40(FP) // r2 is not used. Always set to 0 | |||
JAL runtime·exitsyscall(SB) | |||
RET | |||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56 | |||
JMP syscall·RawSyscall(SB) | |||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 | |||
JMP syscall·RawSyscall6(SB) | |||
TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-48 | |||
MOVV a1+8(FP), R4 | |||
MOVV a2+16(FP), R5 | |||
MOVV a3+24(FP), R6 | |||
MOVV R0, R7 | |||
MOVV R0, R8 | |||
MOVV R0, R9 | |||
MOVV trap+0(FP), R11 // syscall entry | |||
SYSCALL | |||
MOVV R4, r1+32(FP) | |||
MOVV R0, r2+40(FP) // r2 is not used. Always set to 0 | |||
RET |
@@ -2,9 +2,10 @@ | |||
// Use of this source code is governed by a BSD-style | |||
// license that can be found in the LICENSE file. | |||
//go:build linux && (mips64 || mips64le) && gc | |||
// +build linux | |||
// +build mips64 mips64le | |||
// +build !gccgo | |||
// +build gc | |||
#include "textflag.h" | |||
@@ -2,9 +2,10 @@ | |||
// Use of this source code is governed by a BSD-style | |||
// license that can be found in the LICENSE file. | |||
//go:build linux && (mips || mipsle) && gc | |||
// +build linux | |||
// +build mips mipsle | |||
// +build !gccgo | |||
// +build gc | |||
#include "textflag.h" | |||
@@ -2,9 +2,10 @@ | |||
// Use of this source code is governed by a BSD-style | |||
// license that can be found in the LICENSE file. | |||
//go:build linux && (ppc64 || ppc64le) && gc | |||
// +build linux | |||
// +build ppc64 ppc64le | |||
// +build !gccgo | |||
// +build gc | |||
#include "textflag.h" | |||
@@ -0,0 +1,49 @@ | |||
// Copyright 2019 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. | |||
//go:build riscv64 && gc | |||
// +build riscv64 | |||
// +build gc | |||
#include "textflag.h" | |||
// | |||
// System calls for linux/riscv64. | |||
// | |||
// Where available, just jump to package syscall's implementation of | |||
// these functions. | |||
TEXT ·Syscall(SB),NOSPLIT,$0-56 | |||
JMP syscall·Syscall(SB) | |||
TEXT ·Syscall6(SB),NOSPLIT,$0-80 | |||
JMP syscall·Syscall6(SB) | |||
TEXT ·SyscallNoError(SB),NOSPLIT,$0-48 | |||
CALL runtime·entersyscall(SB) | |||
MOV a1+8(FP), A0 | |||
MOV a2+16(FP), A1 | |||
MOV a3+24(FP), A2 | |||
MOV trap+0(FP), A7 // syscall entry | |||
ECALL | |||
MOV A0, r1+32(FP) // r1 | |||
MOV A1, r2+40(FP) // r2 | |||
CALL runtime·exitsyscall(SB) | |||
RET | |||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56 | |||
JMP syscall·RawSyscall(SB) | |||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 | |||
JMP syscall·RawSyscall6(SB) | |||
TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-48 | |||
MOV a1+8(FP), A0 | |||
MOV a2+16(FP), A1 | |||
MOV a3+24(FP), A2 | |||
MOV trap+0(FP), A7 // syscall entry | |||
ECALL | |||
MOV A0, r1+32(FP) | |||
MOV A1, r2+40(FP) | |||
RET |
@@ -2,9 +2,10 @@ | |||
// Use of this source code is governed by a BSD-style | |||
// license that can be found in the LICENSE file. | |||
// +build s390x | |||
//go:build linux && s390x && gc | |||
// +build linux | |||
// +build !gccgo | |||
// +build s390x | |||
// +build gc | |||
#include "textflag.h" | |||
@@ -1,29 +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 !gccgo | |||
#include "textflag.h" | |||
// | |||
// System call support for ARM, NetBSD | |||
// | |||
// Just jump to package syscall's implementation for all these functions. | |||
// The runtime may know about them. | |||
TEXT ·Syscall(SB),NOSPLIT,$0-28 | |||
B syscall·Syscall(SB) | |||
TEXT ·Syscall6(SB),NOSPLIT,$0-40 | |||
B syscall·Syscall6(SB) | |||
TEXT ·Syscall9(SB),NOSPLIT,$0-52 | |||
B syscall·Syscall9(SB) | |||
TEXT ·RawSyscall(SB),NOSPLIT,$0-28 | |||
B syscall·RawSyscall(SB) | |||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40 | |||
B syscall·RawSyscall6(SB) |
@@ -1,29 +0,0 @@ | |||
// Copyright 2009 The Go Authors. All rights reserved. | |||
// Use of this source code is governed by a BSD-style | |||
// license that can be found in the LICENSE file. | |||
// +build !gccgo | |||
#include "textflag.h" | |||
// | |||
// System call support for 386, OpenBSD | |||
// | |||
// Just jump to package syscall's implementation for all these functions. | |||
// The runtime may know about them. | |||
TEXT ·Syscall(SB),NOSPLIT,$0-28 | |||
JMP syscall·Syscall(SB) | |||
TEXT ·Syscall6(SB),NOSPLIT,$0-40 | |||
JMP syscall·Syscall6(SB) | |||
TEXT ·Syscall9(SB),NOSPLIT,$0-52 | |||
JMP syscall·Syscall9(SB) | |||
TEXT ·RawSyscall(SB),NOSPLIT,$0-28 | |||
JMP syscall·RawSyscall(SB) | |||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40 | |||
JMP syscall·RawSyscall6(SB) |
@@ -1,29 +0,0 @@ | |||
// Copyright 2017 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 call support for ARM, OpenBSD | |||
// | |||
// Just jump to package syscall's implementation for all these functions. | |||
// The runtime may know about them. | |||
TEXT ·Syscall(SB),NOSPLIT,$0-28 | |||
B syscall·Syscall(SB) | |||
TEXT ·Syscall6(SB),NOSPLIT,$0-40 | |||
B syscall·Syscall6(SB) | |||
TEXT ·Syscall9(SB),NOSPLIT,$0-52 | |||
B syscall·Syscall9(SB) | |||
TEXT ·RawSyscall(SB),NOSPLIT,$0-28 | |||
B syscall·RawSyscall(SB) | |||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40 | |||
B syscall·RawSyscall6(SB) |
@@ -1,13 +1,14 @@ | |||
// Copyright 2009 The Go Authors. All rights reserved. | |||
// Copyright 2019 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 | |||
//go:build gc | |||
// +build gc | |||
#include "textflag.h" | |||
// | |||
// System call support for AMD64, OpenBSD | |||
// System call support for mips64, OpenBSD | |||
// | |||
// Just jump to package syscall's implementation for all these functions. |
@@ -2,7 +2,8 @@ | |||
// Use of this source code is governed by a BSD-style | |||
// license that can be found in the LICENSE file. | |||
// +build !gccgo | |||
//go:build gc | |||
// +build gc | |||
#include "textflag.h" | |||
@@ -0,0 +1,426 @@ | |||
// Copyright 2020 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. | |||
//go:build zos && s390x && gc | |||
// +build zos | |||
// +build s390x | |||
// +build gc | |||
#include "textflag.h" | |||
#define PSALAA 1208(R0) | |||
#define GTAB64(x) 80(x) | |||
#define LCA64(x) 88(x) | |||
#define CAA(x) 8(x) | |||
#define EDCHPXV(x) 1016(x) // in the CAA | |||
#define SAVSTACK_ASYNC(x) 336(x) // in the LCA | |||
// SS_*, where x=SAVSTACK_ASYNC | |||
#define SS_LE(x) 0(x) | |||
#define SS_GO(x) 8(x) | |||
#define SS_ERRNO(x) 16(x) | |||
#define SS_ERRNOJR(x) 20(x) | |||
#define LE_CALL BYTE $0x0D; BYTE $0x76; // BL R7, R6 | |||
TEXT ·clearErrno(SB),NOSPLIT,$0-0 | |||
BL addrerrno<>(SB) | |||
MOVD $0, 0(R3) | |||
RET | |||
// Returns the address of errno in R3. | |||
TEXT addrerrno<>(SB),NOSPLIT|NOFRAME,$0-0 | |||
// Get library control area (LCA). | |||
MOVW PSALAA, R8 | |||
MOVD LCA64(R8), R8 | |||
// Get __errno FuncDesc. | |||
MOVD CAA(R8), R9 | |||
MOVD EDCHPXV(R9), R9 | |||
ADD $(0x156*16), R9 | |||
LMG 0(R9), R5, R6 | |||
// Switch to saved LE stack. | |||
MOVD SAVSTACK_ASYNC(R8), R9 | |||
MOVD 0(R9), R4 | |||
MOVD $0, 0(R9) | |||
// Call __errno function. | |||
LE_CALL | |||
NOPH | |||
// Switch back to Go stack. | |||
XOR R0, R0 // Restore R0 to $0. | |||
MOVD R4, 0(R9) // Save stack pointer. | |||
RET | |||
TEXT ·syscall_syscall(SB),NOSPLIT,$0-56 | |||
BL runtime·entersyscall(SB) | |||
MOVD a1+8(FP), R1 | |||
MOVD a2+16(FP), R2 | |||
MOVD a3+24(FP), R3 | |||
// Get library control area (LCA). | |||
MOVW PSALAA, R8 | |||
MOVD LCA64(R8), R8 | |||
// Get function. | |||
MOVD CAA(R8), R9 | |||
MOVD EDCHPXV(R9), R9 | |||
MOVD trap+0(FP), R5 | |||
SLD $4, R5 | |||
ADD R5, R9 | |||
LMG 0(R9), R5, R6 | |||
// Restore LE stack. | |||
MOVD SAVSTACK_ASYNC(R8), R9 | |||
MOVD 0(R9), R4 | |||
MOVD $0, 0(R9) | |||
// Call function. | |||
LE_CALL | |||
NOPH | |||
XOR R0, R0 // Restore R0 to $0. | |||
MOVD R4, 0(R9) // Save stack pointer. | |||
MOVD R3, r1+32(FP) | |||
MOVD R0, r2+40(FP) | |||
MOVD R0, err+48(FP) | |||
MOVW R3, R4 | |||
CMP R4, $-1 | |||
BNE done | |||
BL addrerrno<>(SB) | |||
MOVWZ 0(R3), R3 | |||
MOVD R3, err+48(FP) | |||
done: | |||
BL runtime·exitsyscall(SB) | |||
RET | |||
TEXT ·syscall_rawsyscall(SB),NOSPLIT,$0-56 | |||
MOVD a1+8(FP), R1 | |||
MOVD a2+16(FP), R2 | |||
MOVD a3+24(FP), R3 | |||
// Get library control area (LCA). | |||
MOVW PSALAA, R8 | |||
MOVD LCA64(R8), R8 | |||
// Get function. | |||
MOVD CAA(R8), R9 | |||
MOVD EDCHPXV(R9), R9 | |||
MOVD trap+0(FP), R5 | |||
SLD $4, R5 | |||
ADD R5, R9 | |||
LMG 0(R9), R5, R6 | |||
// Restore LE stack. | |||
MOVD SAVSTACK_ASYNC(R8), R9 | |||
MOVD 0(R9), R4 | |||
MOVD $0, 0(R9) | |||
// Call function. | |||
LE_CALL | |||
NOPH | |||
XOR R0, R0 // Restore R0 to $0. | |||
MOVD R4, 0(R9) // Save stack pointer. | |||
MOVD R3, r1+32(FP) | |||
MOVD R0, r2+40(FP) | |||
MOVD R0, err+48(FP) | |||
MOVW R3, R4 | |||
CMP R4, $-1 | |||
BNE done | |||
BL addrerrno<>(SB) | |||
MOVWZ 0(R3), R3 | |||
MOVD R3, err+48(FP) | |||
done: | |||
RET | |||
TEXT ·syscall_syscall6(SB),NOSPLIT,$0-80 | |||
BL runtime·entersyscall(SB) | |||
MOVD a1+8(FP), R1 | |||
MOVD a2+16(FP), R2 | |||
MOVD a3+24(FP), R3 | |||
// Get library control area (LCA). | |||
MOVW PSALAA, R8 | |||
MOVD LCA64(R8), R8 | |||
// Get function. | |||
MOVD CAA(R8), R9 | |||
MOVD EDCHPXV(R9), R9 | |||
MOVD trap+0(FP), R5 | |||
SLD $4, R5 | |||
ADD R5, R9 | |||
LMG 0(R9), R5, R6 | |||
// Restore LE stack. | |||
MOVD SAVSTACK_ASYNC(R8), R9 | |||
MOVD 0(R9), R4 | |||
MOVD $0, 0(R9) | |||
// Fill in parameter list. | |||
MOVD a4+32(FP), R12 | |||
MOVD R12, (2176+24)(R4) | |||
MOVD a5+40(FP), R12 | |||
MOVD R12, (2176+32)(R4) | |||
MOVD a6+48(FP), R12 | |||
MOVD R12, (2176+40)(R4) | |||
// Call function. | |||
LE_CALL | |||
NOPH | |||
XOR R0, R0 // Restore R0 to $0. | |||
MOVD R4, 0(R9) // Save stack pointer. | |||
MOVD R3, r1+56(FP) | |||
MOVD R0, r2+64(FP) | |||
MOVD R0, err+72(FP) | |||
MOVW R3, R4 | |||
CMP R4, $-1 | |||
BNE done | |||
BL addrerrno<>(SB) | |||
MOVWZ 0(R3), R3 | |||
MOVD R3, err+72(FP) | |||
done: | |||
BL runtime·exitsyscall(SB) | |||
RET | |||
TEXT ·syscall_rawsyscall6(SB),NOSPLIT,$0-80 | |||
MOVD a1+8(FP), R1 | |||
MOVD a2+16(FP), R2 | |||
MOVD a3+24(FP), R3 | |||
// Get library control area (LCA). | |||
MOVW PSALAA, R8 | |||
MOVD LCA64(R8), R8 | |||
// Get function. | |||
MOVD CAA(R8), R9 | |||
MOVD EDCHPXV(R9), R9 | |||
MOVD trap+0(FP), R5 | |||
SLD $4, R5 | |||
ADD R5, R9 | |||
LMG 0(R9), R5, R6 | |||
// Restore LE stack. | |||
MOVD SAVSTACK_ASYNC(R8), R9 | |||
MOVD 0(R9), R4 | |||
MOVD $0, 0(R9) | |||
// Fill in parameter list. | |||
MOVD a4+32(FP), R12 | |||
MOVD R12, (2176+24)(R4) | |||
MOVD a5+40(FP), R12 | |||
MOVD R12, (2176+32)(R4) | |||
MOVD a6+48(FP), R12 | |||
MOVD R12, (2176+40)(R4) | |||
// Call function. | |||
LE_CALL | |||
NOPH | |||
XOR R0, R0 // Restore R0 to $0. | |||
MOVD R4, 0(R9) // Save stack pointer. | |||
MOVD R3, r1+56(FP) | |||
MOVD R0, r2+64(FP) | |||
MOVD R0, err+72(FP) | |||
MOVW R3, R4 | |||
CMP R4, $-1 | |||
BNE done | |||
BL ·rrno<>(SB) | |||
MOVWZ 0(R3), R3 | |||
MOVD R3, err+72(FP) | |||
done: | |||
RET | |||
TEXT ·syscall_syscall9(SB),NOSPLIT,$0 | |||
BL runtime·entersyscall(SB) | |||
MOVD a1+8(FP), R1 | |||
MOVD a2+16(FP), R2 | |||
MOVD a3+24(FP), R3 | |||
// Get library control area (LCA). | |||
MOVW PSALAA, R8 | |||
MOVD LCA64(R8), R8 | |||
// Get function. | |||
MOVD CAA(R8), R9 | |||
MOVD EDCHPXV(R9), R9 | |||
MOVD trap+0(FP), R5 | |||
SLD $4, R5 | |||
ADD R5, R9 | |||
LMG 0(R9), R5, R6 | |||
// Restore LE stack. | |||
MOVD SAVSTACK_ASYNC(R8), R9 | |||
MOVD 0(R9), R4 | |||
MOVD $0, 0(R9) | |||
// Fill in parameter list. | |||
MOVD a4+32(FP), R12 | |||
MOVD R12, (2176+24)(R4) | |||
MOVD a5+40(FP), R12 | |||
MOVD R12, (2176+32)(R4) | |||
MOVD a6+48(FP), R12 | |||
MOVD R12, (2176+40)(R4) | |||
MOVD a7+56(FP), R12 | |||
MOVD R12, (2176+48)(R4) | |||
MOVD a8+64(FP), R12 | |||
MOVD R12, (2176+56)(R4) | |||
MOVD a9+72(FP), R12 | |||
MOVD R12, (2176+64)(R4) | |||
// Call function. | |||
LE_CALL | |||
NOPH | |||
XOR R0, R0 // Restore R0 to $0. | |||
MOVD R4, 0(R9) // Save stack pointer. | |||
MOVD R3, r1+80(FP) | |||
MOVD R0, r2+88(FP) | |||
MOVD R0, err+96(FP) | |||
MOVW R3, R4 | |||
CMP R4, $-1 | |||
BNE done | |||
BL addrerrno<>(SB) | |||
MOVWZ 0(R3), R3 | |||
MOVD R3, err+96(FP) | |||
done: | |||
BL runtime·exitsyscall(SB) | |||
RET | |||
TEXT ·syscall_rawsyscall9(SB),NOSPLIT,$0 | |||
MOVD a1+8(FP), R1 | |||
MOVD a2+16(FP), R2 | |||
MOVD a3+24(FP), R3 | |||
// Get library control area (LCA). | |||
MOVW PSALAA, R8 | |||
MOVD LCA64(R8), R8 | |||
// Get function. | |||
MOVD CAA(R8), R9 | |||
MOVD EDCHPXV(R9), R9 | |||
MOVD trap+0(FP), R5 | |||
SLD $4, R5 | |||
ADD R5, R9 | |||
LMG 0(R9), R5, R6 | |||
// Restore LE stack. | |||
MOVD SAVSTACK_ASYNC(R8), R9 | |||
MOVD 0(R9), R4 | |||
MOVD $0, 0(R9) | |||
// Fill in parameter list. | |||
MOVD a4+32(FP), R12 | |||
MOVD R12, (2176+24)(R4) | |||
MOVD a5+40(FP), R12 | |||
MOVD R12, (2176+32)(R4) | |||
MOVD a6+48(FP), R12 | |||
MOVD R12, (2176+40)(R4) | |||
MOVD a7+56(FP), R12 | |||
MOVD R12, (2176+48)(R4) | |||
MOVD a8+64(FP), R12 | |||
MOVD R12, (2176+56)(R4) | |||
MOVD a9+72(FP), R12 | |||
MOVD R12, (2176+64)(R4) | |||
// Call function. | |||
LE_CALL | |||
NOPH | |||
XOR R0, R0 // Restore R0 to $0. | |||
MOVD R4, 0(R9) // Save stack pointer. | |||
MOVD R3, r1+80(FP) | |||
MOVD R0, r2+88(FP) | |||
MOVD R0, err+96(FP) | |||
MOVW R3, R4 | |||
CMP R4, $-1 | |||
BNE done | |||
BL addrerrno<>(SB) | |||
MOVWZ 0(R3), R3 | |||
MOVD R3, err+96(FP) | |||
done: | |||
RET | |||
// func svcCall(fnptr unsafe.Pointer, argv *unsafe.Pointer, dsa *uint64) | |||
TEXT ·svcCall(SB),NOSPLIT,$0 | |||
BL runtime·save_g(SB) // Save g and stack pointer | |||
MOVW PSALAA, R8 | |||
MOVD LCA64(R8), R8 | |||
MOVD SAVSTACK_ASYNC(R8), R9 | |||
MOVD R15, 0(R9) | |||
MOVD argv+8(FP), R1 // Move function arguments into registers | |||
MOVD dsa+16(FP), g | |||
MOVD fnptr+0(FP), R15 | |||
BYTE $0x0D // Branch to function | |||
BYTE $0xEF | |||
BL runtime·load_g(SB) // Restore g and stack pointer | |||
MOVW PSALAA, R8 | |||
MOVD LCA64(R8), R8 | |||
MOVD SAVSTACK_ASYNC(R8), R9 | |||
MOVD 0(R9), R15 | |||
RET | |||
// func svcLoad(name *byte) unsafe.Pointer | |||
TEXT ·svcLoad(SB),NOSPLIT,$0 | |||
MOVD R15, R2 // Save go stack pointer | |||
MOVD name+0(FP), R0 // Move SVC args into registers | |||
MOVD $0x80000000, R1 | |||
MOVD $0, R15 | |||
BYTE $0x0A // SVC 08 LOAD | |||
BYTE $0x08 | |||
MOVW R15, R3 // Save return code from SVC | |||
MOVD R2, R15 // Restore go stack pointer | |||
CMP R3, $0 // Check SVC return code | |||
BNE error | |||
MOVD $-2, R3 // Reset last bit of entry point to zero | |||
AND R0, R3 | |||
MOVD R3, addr+8(FP) // Return entry point returned by SVC | |||
CMP R0, R3 // Check if last bit of entry point was set | |||
BNE done | |||
MOVD R15, R2 // Save go stack pointer | |||
MOVD $0, R15 // Move SVC args into registers (entry point still in r0 from SVC 08) | |||
BYTE $0x0A // SVC 09 DELETE | |||
BYTE $0x09 | |||
MOVD R2, R15 // Restore go stack pointer | |||
error: | |||
MOVD $0, addr+8(FP) // Return 0 on failure | |||
done: | |||
XOR R0, R0 // Reset r0 to 0 | |||
RET | |||
// func svcUnload(name *byte, fnptr unsafe.Pointer) int64 | |||
TEXT ·svcUnload(SB),NOSPLIT,$0 | |||
MOVD R15, R2 // Save go stack pointer | |||
MOVD name+0(FP), R0 // Move SVC args into registers | |||
MOVD addr+8(FP), R15 | |||
BYTE $0x0A // SVC 09 | |||
BYTE $0x09 | |||
XOR R0, R0 // Reset r0 to 0 | |||
MOVD R15, R1 // Save SVC return code | |||
MOVD R2, R15 // Restore go stack pointer | |||
MOVD R1, rc+0(FP) // Return SVC return code | |||
RET | |||
// func gettid() uint64 | |||
TEXT ·gettid(SB), NOSPLIT, $0 | |||
// Get library control area (LCA). | |||
MOVW PSALAA, R8 | |||
MOVD LCA64(R8), R8 | |||
// Get CEECAATHDID | |||
MOVD CAA(R8), R9 | |||
MOVD 0x3D0(R9), R9 | |||
MOVD R9, ret+0(FP) | |||
RET |
@@ -23,6 +23,7 @@ const ( | |||
HCI_CHANNEL_USER = 1 | |||
HCI_CHANNEL_MONITOR = 2 | |||
HCI_CHANNEL_CONTROL = 3 | |||
HCI_CHANNEL_LOGGING = 4 | |||
) | |||
// Socketoption Level | |||
@@ -2,6 +2,7 @@ | |||
// Use of this source code is governed by a BSD-style | |||
// license that can be found in the LICENSE file. | |||
//go:build freebsd | |||
// +build freebsd | |||
package unix | |||
@@ -2,7 +2,8 @@ | |||
// 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 | |||
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos | |||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos | |||
package unix | |||
@@ -2,8 +2,8 @@ | |||
// Use of this source code is governed by a BSD-style | |||
// license that can be found in the LICENSE file. | |||
// +build aix | |||
// +build ppc | |||
//go:build aix && ppc | |||
// +build aix,ppc | |||
// Functions to access/create device major and minor numbers matching the | |||
// encoding used by AIX. | |||
@@ -2,8 +2,8 @@ | |||
// Use of this source code is governed by a BSD-style | |||
// license that can be found in the LICENSE file. | |||
// +build aix | |||
// +build ppc64 | |||
//go:build aix && ppc64 | |||
// +build aix,ppc64 | |||
// Functions to access/create device major and minor numbers matching the | |||
// encoding used AIX. | |||
@@ -0,0 +1,29 @@ | |||
// Copyright 2020 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. | |||
//go:build zos && s390x | |||
// +build zos,s390x | |||
// Functions to access/create device major and minor numbers matching the | |||
// encoding used by z/OS. | |||
// | |||
// The information below is extracted and adapted from <sys/stat.h> macros. | |||
package unix | |||
// Major returns the major component of a z/OS device number. | |||
func Major(dev uint64) uint32 { | |||
return uint32((dev >> 16) & 0x0000FFFF) | |||
} | |||
// Minor returns the minor component of a z/OS device number. | |||
func Minor(dev uint64) uint32 { | |||
return uint32(dev & 0x0000FFFF) | |||
} | |||
// Mkdev returns a z/OS device number generated from the given major and minor | |||
// components. | |||
func Mkdev(major, minor uint32) uint64 { | |||
return (uint64(major) << 16) | uint64(minor) | |||
} |
@@ -2,16 +2,102 @@ | |||
// 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 nacl netbsd openbsd solaris | |||
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos | |||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos | |||
package unix | |||
import "syscall" | |||
import "unsafe" | |||
// readInt returns the size-bytes unsigned integer in native byte order at offset off. | |||
func readInt(b []byte, off, size uintptr) (u uint64, ok bool) { | |||
if len(b) < int(off+size) { | |||
return 0, false | |||
} | |||
if isBigEndian { | |||
return readIntBE(b[off:], size), true | |||
} | |||
return readIntLE(b[off:], size), true | |||
} | |||
func readIntBE(b []byte, size uintptr) uint64 { | |||
switch size { | |||
case 1: | |||
return uint64(b[0]) | |||
case 2: | |||
_ = b[1] // bounds check hint to compiler; see golang.org/issue/14808 | |||
return uint64(b[1]) | uint64(b[0])<<8 | |||
case 4: | |||
_ = b[3] // bounds check hint to compiler; see golang.org/issue/14808 | |||
return uint64(b[3]) | uint64(b[2])<<8 | uint64(b[1])<<16 | uint64(b[0])<<24 | |||
case 8: | |||
_ = b[7] // bounds check hint to compiler; see golang.org/issue/14808 | |||
return uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 | | |||
uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56 | |||
default: | |||
panic("syscall: readInt with unsupported size") | |||
} | |||
} | |||
func readIntLE(b []byte, size uintptr) uint64 { | |||
switch size { | |||
case 1: | |||
return uint64(b[0]) | |||
case 2: | |||
_ = b[1] // bounds check hint to compiler; see golang.org/issue/14808 | |||
return uint64(b[0]) | uint64(b[1])<<8 | |||
case 4: | |||
_ = b[3] // bounds check hint to compiler; see golang.org/issue/14808 | |||
return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | |||
case 8: | |||
_ = b[7] // bounds check hint to compiler; see golang.org/issue/14808 | |||
return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | | |||
uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56 | |||
default: | |||
panic("syscall: readInt with unsupported size") | |||
} | |||
} | |||
// ParseDirent parses up to max directory entries in buf, | |||
// appending the names to names. It returns the number of | |||
// bytes consumed from buf, the number of entries added | |||
// to names, and the new names slice. | |||
func ParseDirent(buf []byte, max int, names []string) (consumed int, count int, newnames []string) { | |||
return syscall.ParseDirent(buf, max, names) | |||
origlen := len(buf) | |||
count = 0 | |||
for max != 0 && len(buf) > 0 { | |||
reclen, ok := direntReclen(buf) | |||
if !ok || reclen > uint64(len(buf)) { | |||
return origlen, count, names | |||
} | |||
rec := buf[:reclen] | |||
buf = buf[reclen:] | |||
ino, ok := direntIno(rec) | |||
if !ok { | |||
break | |||
} | |||
if ino == 0 { // File absent in directory. | |||
continue | |||
} | |||
const namoff = uint64(unsafe.Offsetof(Dirent{}.Name)) | |||
namlen, ok := direntNamlen(rec) | |||
if !ok || namoff+namlen > uint64(len(rec)) { | |||
break | |||
} | |||
name := rec[namoff : namoff+namlen] | |||
for i, c := range name { | |||
if c == 0 { | |||
name = name[:i] | |||
break | |||
} | |||
} | |||
// Check for useless names before allocating a string. | |||
if string(name) == "." || string(name) == ".." { | |||
continue | |||
} | |||
max-- | |||
count++ | |||
names = append(names, string(name)) | |||
} | |||
return origlen - len(buf), count, names | |||
} |
@@ -2,7 +2,8 @@ | |||
// Use of this source code is governed by a BSD-style | |||
// license that can be found in the LICENSE file. | |||
// | |||
// +build ppc64 s390x mips mips64 | |||
//go:build armbe || arm64be || m68k || mips || mips64 || mips64p32 || ppc || ppc64 || s390 || s390x || shbe || sparc || sparc64 | |||
// +build armbe arm64be m68k mips mips64 mips64p32 ppc ppc64 s390 s390x shbe sparc sparc64 | |||
package unix | |||
@@ -2,7 +2,8 @@ | |||
// Use of this source code is governed by a BSD-style | |||
// license that can be found in the LICENSE file. | |||
// | |||
// +build 386 amd64 amd64p32 arm arm64 ppc64le mipsle mips64le | |||
//go:build 386 || amd64 || amd64p32 || alpha || arm || arm64 || loong64 || mipsle || mips64le || mips64p32le || nios2 || ppc64le || riscv || riscv64 || sh | |||
// +build 386 amd64 amd64p32 alpha arm arm64 loong64 mipsle mips64le mips64p32le nios2 ppc64le riscv riscv64 sh | |||
package unix | |||
@@ -2,7 +2,8 @@ | |||
// 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 | |||
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos | |||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos | |||
// Unix environment variables. | |||
@@ -0,0 +1,221 @@ | |||
// Copyright 2020 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. | |||
//go:build zos && s390x | |||
// +build zos,s390x | |||
package unix | |||
import ( | |||
"sync" | |||
) | |||
// This file simulates epoll on z/OS using poll. | |||
// Analogous to epoll_event on Linux. | |||
// TODO(neeilan): Pad is because the Linux kernel expects a 96-bit struct. We never pass this to the kernel; remove? | |||
type EpollEvent struct { | |||
Events uint32 | |||
Fd int32 | |||
Pad int32 | |||
} | |||
const ( | |||
EPOLLERR = 0x8 | |||
EPOLLHUP = 0x10 | |||
EPOLLIN = 0x1 | |||
EPOLLMSG = 0x400 | |||
EPOLLOUT = 0x4 | |||
EPOLLPRI = 0x2 | |||
EPOLLRDBAND = 0x80 | |||
EPOLLRDNORM = 0x40 | |||
EPOLLWRBAND = 0x200 | |||
EPOLLWRNORM = 0x100 | |||
EPOLL_CTL_ADD = 0x1 | |||
EPOLL_CTL_DEL = 0x2 | |||
EPOLL_CTL_MOD = 0x3 | |||
// The following constants are part of the epoll API, but represent | |||
// currently unsupported functionality on z/OS. | |||
// EPOLL_CLOEXEC = 0x80000 | |||
// EPOLLET = 0x80000000 | |||
// EPOLLONESHOT = 0x40000000 | |||
// EPOLLRDHUP = 0x2000 // Typically used with edge-triggered notis | |||
// EPOLLEXCLUSIVE = 0x10000000 // Exclusive wake-up mode | |||
// EPOLLWAKEUP = 0x20000000 // Relies on Linux's BLOCK_SUSPEND capability | |||
) | |||
// TODO(neeilan): We can eliminate these epToPoll / pToEpoll calls by using identical mask values for POLL/EPOLL | |||
// constants where possible The lower 16 bits of epoll events (uint32) can fit any system poll event (int16). | |||
// epToPollEvt converts epoll event field to poll equivalent. | |||
// In epoll, Events is a 32-bit field, while poll uses 16 bits. | |||
func epToPollEvt(events uint32) int16 { | |||
var ep2p = map[uint32]int16{ | |||
EPOLLIN: POLLIN, | |||
EPOLLOUT: POLLOUT, | |||
EPOLLHUP: POLLHUP, | |||
EPOLLPRI: POLLPRI, | |||
EPOLLERR: POLLERR, | |||
} | |||
var pollEvts int16 = 0 | |||
for epEvt, pEvt := range ep2p { | |||
if (events & epEvt) != 0 { | |||
pollEvts |= pEvt | |||
} | |||
} | |||
return pollEvts | |||
} | |||
// pToEpollEvt converts 16 bit poll event bitfields to 32-bit epoll event fields. | |||
func pToEpollEvt(revents int16) uint32 { | |||
var p2ep = map[int16]uint32{ | |||
POLLIN: EPOLLIN, | |||
POLLOUT: EPOLLOUT, | |||
POLLHUP: EPOLLHUP, | |||
POLLPRI: EPOLLPRI, | |||
POLLERR: EPOLLERR, | |||
} | |||
var epollEvts uint32 = 0 | |||
for pEvt, epEvt := range p2ep { | |||
if (revents & pEvt) != 0 { | |||
epollEvts |= epEvt | |||
} | |||
} | |||
return epollEvts | |||
} | |||
// Per-process epoll implementation. | |||
type epollImpl struct { | |||
mu sync.Mutex | |||
epfd2ep map[int]*eventPoll | |||
nextEpfd int | |||
} | |||
// eventPoll holds a set of file descriptors being watched by the process. A process can have multiple epoll instances. | |||
// On Linux, this is an in-kernel data structure accessed through a fd. | |||
type eventPoll struct { | |||
mu sync.Mutex | |||
fds map[int]*EpollEvent | |||
} | |||
// epoll impl for this process. | |||
var impl epollImpl = epollImpl{ | |||
epfd2ep: make(map[int]*eventPoll), | |||
nextEpfd: 0, | |||
} | |||
func (e *epollImpl) epollcreate(size int) (epfd int, err error) { | |||
e.mu.Lock() | |||
defer e.mu.Unlock() | |||
epfd = e.nextEpfd | |||
e.nextEpfd++ | |||
e.epfd2ep[epfd] = &eventPoll{ | |||
fds: make(map[int]*EpollEvent), | |||
} | |||
return epfd, nil | |||
} | |||
func (e *epollImpl) epollcreate1(flag int) (fd int, err error) { | |||
return e.epollcreate(4) | |||
} | |||
func (e *epollImpl) epollctl(epfd int, op int, fd int, event *EpollEvent) (err error) { | |||
e.mu.Lock() | |||
defer e.mu.Unlock() | |||
ep, ok := e.epfd2ep[epfd] | |||
if !ok { | |||
return EBADF | |||
} | |||
switch op { | |||
case EPOLL_CTL_ADD: | |||
// TODO(neeilan): When we make epfds and fds disjoint, detect epoll | |||
// loops here (instances watching each other) and return ELOOP. | |||
if _, ok := ep.fds[fd]; ok { | |||
return EEXIST | |||
} | |||
ep.fds[fd] = event | |||
case EPOLL_CTL_MOD: | |||
if _, ok := ep.fds[fd]; !ok { | |||
return ENOENT | |||
} | |||
ep.fds[fd] = event | |||
case EPOLL_CTL_DEL: | |||
if _, ok := ep.fds[fd]; !ok { | |||
return ENOENT | |||
} | |||
delete(ep.fds, fd) | |||
} | |||
return nil | |||
} | |||
// Must be called while holding ep.mu | |||
func (ep *eventPoll) getFds() []int { | |||
fds := make([]int, len(ep.fds)) | |||
for fd := range ep.fds { | |||
fds = append(fds, fd) | |||
} | |||
return fds | |||
} | |||
func (e *epollImpl) epollwait(epfd int, events []EpollEvent, msec int) (n int, err error) { | |||
e.mu.Lock() // in [rare] case of concurrent epollcreate + epollwait | |||
ep, ok := e.epfd2ep[epfd] | |||
if !ok { | |||
e.mu.Unlock() | |||
return 0, EBADF | |||
} | |||
pollfds := make([]PollFd, 4) | |||
for fd, epollevt := range ep.fds { | |||
pollfds = append(pollfds, PollFd{Fd: int32(fd), Events: epToPollEvt(epollevt.Events)}) | |||
} | |||
e.mu.Unlock() | |||
n, err = Poll(pollfds, msec) | |||
if err != nil { | |||
return n, err | |||
} | |||
i := 0 | |||
for _, pFd := range pollfds { | |||
if pFd.Revents != 0 { | |||
events[i] = EpollEvent{Fd: pFd.Fd, Events: pToEpollEvt(pFd.Revents)} | |||
i++ | |||
} | |||
if i == n { | |||
break | |||
} | |||
} | |||
return n, nil | |||
} | |||
func EpollCreate(size int) (fd int, err error) { | |||
return impl.epollcreate(size) | |||
} | |||
func EpollCreate1(flag int) (fd int, err error) { | |||
return impl.epollcreate1(flag) | |||
} | |||
func EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error) { | |||
return impl.epollctl(epfd, op, fd, event) | |||
} | |||
// Because EpollWait mutates events, the caller is expected to coordinate | |||
// concurrent access if calling with the same epfd from multiple goroutines. | |||
func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) { | |||
return impl.epollwait(epfd, events, msec) | |||
} |
@@ -1,227 +0,0 @@ | |||
// Copyright 2017 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. | |||
// Constants that were deprecated or moved to enums in the FreeBSD headers. Keep | |||
// them here for backwards compatibility. | |||
package unix | |||
const ( | |||
IFF_SMART = 0x20 | |||
IFT_1822 = 0x2 | |||
IFT_A12MPPSWITCH = 0x82 | |||
IFT_AAL2 = 0xbb | |||
IFT_AAL5 = 0x31 | |||
IFT_ADSL = 0x5e | |||
IFT_AFLANE8023 = 0x3b | |||
IFT_AFLANE8025 = 0x3c | |||
IFT_ARAP = 0x58 | |||
IFT_ARCNET = 0x23 | |||
IFT_ARCNETPLUS = 0x24 | |||
IFT_ASYNC = 0x54 | |||
IFT_ATM = 0x25 | |||
IFT_ATMDXI = 0x69 | |||
IFT_ATMFUNI = 0x6a | |||
IFT_ATMIMA = 0x6b | |||
IFT_ATMLOGICAL = 0x50 | |||
IFT_ATMRADIO = 0xbd | |||
IFT_ATMSUBINTERFACE = 0x86 | |||
IFT_ATMVCIENDPT = 0xc2 | |||
IFT_ATMVIRTUAL = 0x95 | |||
IFT_BGPPOLICYACCOUNTING = 0xa2 | |||
IFT_BSC = 0x53 | |||
IFT_CCTEMUL = 0x3d | |||
IFT_CEPT = 0x13 | |||
IFT_CES = 0x85 | |||
IFT_CHANNEL = 0x46 | |||
IFT_CNR = 0x55 | |||
IFT_COFFEE = 0x84 | |||
IFT_COMPOSITELINK = 0x9b | |||
IFT_DCN = 0x8d | |||
IFT_DIGITALPOWERLINE = 0x8a | |||
IFT_DIGITALWRAPPEROVERHEADCHANNEL = 0xba | |||
IFT_DLSW = 0x4a | |||
IFT_DOCSCABLEDOWNSTREAM = 0x80 | |||
IFT_DOCSCABLEMACLAYER = 0x7f | |||
IFT_DOCSCABLEUPSTREAM = 0x81 | |||
IFT_DS0 = 0x51 | |||
IFT_DS0BUNDLE = 0x52 | |||
IFT_DS1FDL = 0xaa | |||
IFT_DS3 = 0x1e | |||
IFT_DTM = 0x8c | |||
IFT_DVBASILN = 0xac | |||
IFT_DVBASIOUT = 0xad | |||
IFT_DVBRCCDOWNSTREAM = 0x93 | |||
IFT_DVBRCCMACLAYER = 0x92 | |||
IFT_DVBRCCUPSTREAM = 0x94 | |||
IFT_ENC = 0xf4 | |||
IFT_EON = 0x19 | |||
IFT_EPLRS = 0x57 | |||
IFT_ESCON = 0x49 | |||
IFT_ETHER = 0x6 | |||
IFT_FAITH = 0xf2 | |||
IFT_FAST = 0x7d | |||
IFT_FASTETHER = 0x3e | |||
IFT_FASTETHERFX = 0x45 | |||
IFT_FDDI = 0xf | |||
IFT_FIBRECHANNEL = 0x38 | |||
IFT_FRAMERELAYINTERCONNECT = 0x3a | |||
IFT_FRAMERELAYMPI = 0x5c | |||
IFT_FRDLCIENDPT = 0xc1 | |||
IFT_FRELAY = 0x20 | |||
IFT_FRELAYDCE = 0x2c | |||
IFT_FRF16MFRBUNDLE = 0xa3 | |||
IFT_FRFORWARD = 0x9e | |||
IFT_G703AT2MB = 0x43 | |||
IFT_G703AT64K = 0x42 | |||
IFT_GIF = 0xf0 | |||
IFT_GIGABITETHERNET = 0x75 | |||
IFT_GR303IDT = 0xb2 | |||
IFT_GR303RDT = 0xb1 | |||
IFT_H323GATEKEEPER = 0xa4 | |||
IFT_H323PROXY = 0xa5 | |||
IFT_HDH1822 = 0x3 | |||
IFT_HDLC = 0x76 | |||
IFT_HDSL2 = 0xa8 | |||
IFT_HIPERLAN2 = 0xb7 | |||
IFT_HIPPI = 0x2f | |||
IFT_HIPPIINTERFACE = 0x39 | |||
IFT_HOSTPAD = 0x5a | |||
IFT_HSSI = 0x2e | |||
IFT_HY = 0xe | |||
IFT_IBM370PARCHAN = 0x48 | |||
IFT_IDSL = 0x9a | |||
IFT_IEEE80211 = 0x47 | |||
IFT_IEEE80212 = 0x37 | |||
IFT_IEEE8023ADLAG = 0xa1 | |||
IFT_IFGSN = 0x91 | |||
IFT_IMT = 0xbe | |||
IFT_INTERLEAVE = 0x7c | |||
IFT_IP = 0x7e | |||
IFT_IPFORWARD = 0x8e | |||
IFT_IPOVERATM = 0x72 | |||
IFT_IPOVERCDLC = 0x6d | |||
IFT_IPOVERCLAW = 0x6e | |||
IFT_IPSWITCH = 0x4e | |||
IFT_IPXIP = 0xf9 | |||
IFT_ISDN = 0x3f | |||
IFT_ISDNBASIC = 0x14 | |||
IFT_ISDNPRIMARY = 0x15 | |||
IFT_ISDNS = 0x4b | |||
IFT_ISDNU = 0x4c | |||
IFT_ISO88022LLC = 0x29 | |||
IFT_ISO88023 = 0x7 | |||
IFT_ISO88024 = 0x8 | |||
IFT_ISO88025 = 0x9 | |||
IFT_ISO88025CRFPINT = 0x62 | |||
IFT_ISO88025DTR = 0x56 | |||
IFT_ISO88025FIBER = 0x73 | |||
IFT_ISO88026 = 0xa | |||
IFT_ISUP = 0xb3 | |||
IFT_L3IPXVLAN = 0x89 | |||
IFT_LAPB = 0x10 | |||
IFT_LAPD = 0x4d | |||
IFT_LAPF = 0x77 | |||
IFT_LOCALTALK = 0x2a | |||
IFT_LOOP = 0x18 | |||
IFT_MEDIAMAILOVERIP = 0x8b | |||
IFT_MFSIGLINK = 0xa7 | |||
IFT_MIOX25 = 0x26 | |||
IFT_MODEM = 0x30 | |||
IFT_MPC = 0x71 | |||
IFT_MPLS = 0xa6 | |||
IFT_MPLSTUNNEL = 0x96 | |||
IFT_MSDSL = 0x8f | |||
IFT_MVL = 0xbf | |||
IFT_MYRINET = 0x63 | |||
IFT_NFAS = 0xaf | |||
IFT_NSIP = 0x1b | |||
IFT_OPTICALCHANNEL = 0xc3 | |||
IFT_OPTICALTRANSPORT = 0xc4 | |||
IFT_OTHER = 0x1 | |||
IFT_P10 = 0xc | |||
IFT_P80 = 0xd | |||
IFT_PARA = 0x22 | |||
IFT_PFLOG = 0xf6 | |||
IFT_PFSYNC = 0xf7 | |||
IFT_PLC = 0xae | |||
IFT_POS = 0xab | |||
IFT_PPPMULTILINKBUNDLE = 0x6c | |||
IFT_PROPBWAP2MP = 0xb8 | |||
IFT_PROPCNLS = 0x59 | |||
IFT_PROPDOCSWIRELESSDOWNSTREAM = 0xb5 | |||
IFT_PROPDOCSWIRELESSMACLAYER = 0xb4 | |||
IFT_PROPDOCSWIRELESSUPSTREAM = 0xb6 | |||
IFT_PROPMUX = 0x36 | |||
IFT_PROPWIRELESSP2P = 0x9d | |||
IFT_PTPSERIAL = 0x16 | |||
IFT_PVC = 0xf1 | |||
IFT_QLLC = 0x44 | |||
IFT_RADIOMAC = 0xbc | |||
IFT_RADSL = 0x5f | |||
IFT_REACHDSL = 0xc0 | |||
IFT_RFC1483 = 0x9f | |||
IFT_RS232 = 0x21 | |||
IFT_RSRB = 0x4f | |||
IFT_SDLC = 0x11 | |||
IFT_SDSL = 0x60 | |||
IFT_SHDSL = 0xa9 | |||
IFT_SIP = 0x1f | |||
IFT_SLIP = 0x1c | |||
IFT_SMDSDXI = 0x2b | |||
IFT_SMDSICIP = 0x34 | |||
IFT_SONET = 0x27 | |||
IFT_SONETOVERHEADCHANNEL = 0xb9 | |||
IFT_SONETPATH = 0x32 | |||
IFT_SONETVT = 0x33 | |||
IFT_SRP = 0x97 | |||
IFT_SS7SIGLINK = 0x9c | |||
IFT_STACKTOSTACK = 0x6f | |||
IFT_STARLAN = 0xb | |||
IFT_STF = 0xd7 | |||
IFT_T1 = 0x12 | |||
IFT_TDLC = 0x74 | |||
IFT_TERMPAD = 0x5b | |||
IFT_TR008 = 0xb0 | |||
IFT_TRANSPHDLC = 0x7b | |||
IFT_TUNNEL = 0x83 | |||
IFT_ULTRA = 0x1d | |||
IFT_USB = 0xa0 | |||
IFT_V11 = 0x40 | |||
IFT_V35 = 0x2d | |||
IFT_V36 = 0x41 | |||
IFT_V37 = 0x78 | |||
IFT_VDSL = 0x61 | |||
IFT_VIRTUALIPADDRESS = 0x70 | |||
IFT_VOICEEM = 0x64 | |||
IFT_VOICEENCAP = 0x67 | |||
IFT_VOICEFXO = 0x65 | |||
IFT_VOICEFXS = 0x66 | |||
IFT_VOICEOVERATM = 0x98 | |||
IFT_VOICEOVERFRAMERELAY = 0x99 | |||
IFT_VOICEOVERIP = 0x68 | |||
IFT_X213 = 0x5d | |||
IFT_X25 = 0x5 | |||
IFT_X25DDN = 0x4 | |||
IFT_X25HUNTGROUP = 0x7a | |||
IFT_X25MLP = 0x79 | |||
IFT_X25PLE = 0x28 | |||
IFT_XETHER = 0x1a | |||
IPPROTO_MAXID = 0x34 | |||
IPV6_FAITH = 0x1d | |||
IP_FAITH = 0x16 | |||
MAP_NORESERVE = 0x40 | |||
MAP_RENAME = 0x20 | |||
NET_RT_MAXID = 0x6 | |||
RTF_PRCLONING = 0x10000 | |||
RTM_OLDADD = 0x9 | |||
RTM_OLDDEL = 0xa | |||
SIOCADDRT = 0x8030720a | |||
SIOCALIFADDR = 0x8118691b | |||
SIOCDELRT = 0x8030720b | |||
SIOCDLIFADDR = 0x8118691d | |||
SIOCGLIFADDR = 0xc118691c | |||
SIOCGLIFPHYADDR = 0xc118694b | |||
SIOCSLIFPHYADDR = 0x8118694a | |||
) |
@@ -1,227 +0,0 @@ | |||
// Copyright 2017 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. | |||
// Constants that were deprecated or moved to enums in the FreeBSD headers. Keep | |||
// them here for backwards compatibility. | |||
package unix | |||
const ( | |||
IFF_SMART = 0x20 | |||
IFT_1822 = 0x2 | |||
IFT_A12MPPSWITCH = 0x82 | |||
IFT_AAL2 = 0xbb | |||
IFT_AAL5 = 0x31 | |||
IFT_ADSL = 0x5e | |||
IFT_AFLANE8023 = 0x3b | |||
IFT_AFLANE8025 = 0x3c | |||
IFT_ARAP = 0x58 | |||
IFT_ARCNET = 0x23 | |||
IFT_ARCNETPLUS = 0x24 | |||
IFT_ASYNC = 0x54 | |||
IFT_ATM = 0x25 | |||
IFT_ATMDXI = 0x69 | |||
IFT_ATMFUNI = 0x6a | |||
IFT_ATMIMA = 0x6b | |||
IFT_ATMLOGICAL = 0x50 | |||
IFT_ATMRADIO = 0xbd | |||
IFT_ATMSUBINTERFACE = 0x86 | |||
IFT_ATMVCIENDPT = 0xc2 | |||
IFT_ATMVIRTUAL = 0x95 | |||
IFT_BGPPOLICYACCOUNTING = 0xa2 | |||
IFT_BSC = 0x53 | |||
IFT_CCTEMUL = 0x3d | |||
IFT_CEPT = 0x13 | |||
IFT_CES = 0x85 | |||
IFT_CHANNEL = 0x46 | |||
IFT_CNR = 0x55 | |||
IFT_COFFEE = 0x84 | |||
IFT_COMPOSITELINK = 0x9b | |||
IFT_DCN = 0x8d | |||
IFT_DIGITALPOWERLINE = 0x8a | |||
IFT_DIGITALWRAPPEROVERHEADCHANNEL = 0xba | |||
IFT_DLSW = 0x4a | |||
IFT_DOCSCABLEDOWNSTREAM = 0x80 | |||
IFT_DOCSCABLEMACLAYER = 0x7f | |||
IFT_DOCSCABLEUPSTREAM = 0x81 | |||
IFT_DS0 = 0x51 | |||
IFT_DS0BUNDLE = 0x52 | |||
IFT_DS1FDL = 0xaa | |||
IFT_DS3 = 0x1e | |||
IFT_DTM = 0x8c | |||
IFT_DVBASILN = 0xac | |||
IFT_DVBASIOUT = 0xad | |||
IFT_DVBRCCDOWNSTREAM = 0x93 | |||
IFT_DVBRCCMACLAYER = 0x92 | |||
IFT_DVBRCCUPSTREAM = 0x94 | |||
IFT_ENC = 0xf4 | |||
IFT_EON = 0x19 | |||
IFT_EPLRS = 0x57 | |||
IFT_ESCON = 0x49 | |||
IFT_ETHER = 0x6 | |||
IFT_FAITH = 0xf2 | |||
IFT_FAST = 0x7d | |||
IFT_FASTETHER = 0x3e | |||
IFT_FASTETHERFX = 0x45 | |||
IFT_FDDI = 0xf | |||
IFT_FIBRECHANNEL = 0x38 | |||
IFT_FRAMERELAYINTERCONNECT = 0x3a | |||
IFT_FRAMERELAYMPI = 0x5c | |||
IFT_FRDLCIENDPT = 0xc1 | |||
IFT_FRELAY = 0x20 | |||
IFT_FRELAYDCE = 0x2c | |||
IFT_FRF16MFRBUNDLE = 0xa3 | |||
IFT_FRFORWARD = 0x9e | |||
IFT_G703AT2MB = 0x43 | |||
IFT_G703AT64K = 0x42 | |||
IFT_GIF = 0xf0 | |||
IFT_GIGABITETHERNET = 0x75 | |||
IFT_GR303IDT = 0xb2 | |||
IFT_GR303RDT = 0xb1 | |||
IFT_H323GATEKEEPER = 0xa4 | |||
IFT_H323PROXY = 0xa5 | |||
IFT_HDH1822 = 0x3 | |||
IFT_HDLC = 0x76 | |||
IFT_HDSL2 = 0xa8 | |||
IFT_HIPERLAN2 = 0xb7 | |||
IFT_HIPPI = 0x2f | |||
IFT_HIPPIINTERFACE = 0x39 | |||
IFT_HOSTPAD = 0x5a | |||
IFT_HSSI = 0x2e | |||
IFT_HY = 0xe | |||
IFT_IBM370PARCHAN = 0x48 | |||
IFT_IDSL = 0x9a | |||
IFT_IEEE80211 = 0x47 | |||
IFT_IEEE80212 = 0x37 | |||
IFT_IEEE8023ADLAG = 0xa1 | |||
IFT_IFGSN = 0x91 | |||
IFT_IMT = 0xbe | |||
IFT_INTERLEAVE = 0x7c | |||
IFT_IP = 0x7e | |||
IFT_IPFORWARD = 0x8e | |||
IFT_IPOVERATM = 0x72 | |||
IFT_IPOVERCDLC = 0x6d | |||
IFT_IPOVERCLAW = 0x6e | |||
IFT_IPSWITCH = 0x4e | |||
IFT_IPXIP = 0xf9 | |||
IFT_ISDN = 0x3f | |||
IFT_ISDNBASIC = 0x14 | |||
IFT_ISDNPRIMARY = 0x15 | |||
IFT_ISDNS = 0x4b | |||
IFT_ISDNU = 0x4c | |||
IFT_ISO88022LLC = 0x29 | |||
IFT_ISO88023 = 0x7 | |||
IFT_ISO88024 = 0x8 | |||
IFT_ISO88025 = 0x9 | |||
IFT_ISO88025CRFPINT = 0x62 | |||
IFT_ISO88025DTR = 0x56 | |||
IFT_ISO88025FIBER = 0x73 | |||
IFT_ISO88026 = 0xa | |||
IFT_ISUP = 0xb3 | |||
IFT_L3IPXVLAN = 0x89 | |||
IFT_LAPB = 0x10 | |||
IFT_LAPD = 0x4d | |||
IFT_LAPF = 0x77 | |||
IFT_LOCALTALK = 0x2a | |||
IFT_LOOP = 0x18 | |||
IFT_MEDIAMAILOVERIP = 0x8b | |||
IFT_MFSIGLINK = 0xa7 | |||
IFT_MIOX25 = 0x26 | |||
IFT_MODEM = 0x30 | |||
IFT_MPC = 0x71 | |||
IFT_MPLS = 0xa6 | |||
IFT_MPLSTUNNEL = 0x96 | |||
IFT_MSDSL = 0x8f | |||
IFT_MVL = 0xbf | |||
IFT_MYRINET = 0x63 | |||
IFT_NFAS = 0xaf | |||
IFT_NSIP = 0x1b | |||
IFT_OPTICALCHANNEL = 0xc3 | |||
IFT_OPTICALTRANSPORT = 0xc4 | |||
IFT_OTHER = 0x1 | |||
IFT_P10 = 0xc | |||
IFT_P80 = 0xd | |||
IFT_PARA = 0x22 | |||
IFT_PFLOG = 0xf6 | |||
IFT_PFSYNC = 0xf7 | |||
IFT_PLC = 0xae | |||
IFT_POS = 0xab | |||
IFT_PPPMULTILINKBUNDLE = 0x6c | |||
IFT_PROPBWAP2MP = 0xb8 | |||
IFT_PROPCNLS = 0x59 | |||
IFT_PROPDOCSWIRELESSDOWNSTREAM = 0xb5 | |||
IFT_PROPDOCSWIRELESSMACLAYER = 0xb4 | |||
IFT_PROPDOCSWIRELESSUPSTREAM = 0xb6 | |||
IFT_PROPMUX = 0x36 | |||
IFT_PROPWIRELESSP2P = 0x9d | |||
IFT_PTPSERIAL = 0x16 | |||
IFT_PVC = 0xf1 | |||
IFT_QLLC = 0x44 | |||
IFT_RADIOMAC = 0xbc | |||
IFT_RADSL = 0x5f | |||
IFT_REACHDSL = 0xc0 | |||
IFT_RFC1483 = 0x9f | |||
IFT_RS232 = 0x21 | |||
IFT_RSRB = 0x4f | |||
IFT_SDLC = 0x11 | |||
IFT_SDSL = 0x60 | |||
IFT_SHDSL = 0xa9 | |||
IFT_SIP = 0x1f | |||
IFT_SLIP = 0x1c | |||
IFT_SMDSDXI = 0x2b | |||
IFT_SMDSICIP = 0x34 | |||
IFT_SONET = 0x27 | |||
IFT_SONETOVERHEADCHANNEL = 0xb9 | |||
IFT_SONETPATH = 0x32 | |||
IFT_SONETVT = 0x33 | |||
IFT_SRP = 0x97 | |||
IFT_SS7SIGLINK = 0x9c | |||
IFT_STACKTOSTACK = 0x6f | |||
IFT_STARLAN = 0xb | |||
IFT_STF = 0xd7 | |||
IFT_T1 = 0x12 | |||
IFT_TDLC = 0x74 | |||
IFT_TERMPAD = 0x5b | |||
IFT_TR008 = 0xb0 | |||
IFT_TRANSPHDLC = 0x7b | |||
IFT_TUNNEL = 0x83 | |||
IFT_ULTRA = 0x1d | |||
IFT_USB = 0xa0 | |||
IFT_V11 = 0x40 | |||
IFT_V35 = 0x2d | |||
IFT_V36 = 0x41 | |||
IFT_V37 = 0x78 | |||
IFT_VDSL = 0x61 | |||
IFT_VIRTUALIPADDRESS = 0x70 | |||
IFT_VOICEEM = 0x64 | |||
IFT_VOICEENCAP = 0x67 | |||
IFT_VOICEFXO = 0x65 | |||
IFT_VOICEFXS = 0x66 | |||
IFT_VOICEOVERATM = 0x98 | |||
IFT_VOICEOVERFRAMERELAY = 0x99 | |||
IFT_VOICEOVERIP = 0x68 | |||
IFT_X213 = 0x5d | |||
IFT_X25 = 0x5 | |||
IFT_X25DDN = 0x4 | |||
IFT_X25HUNTGROUP = 0x7a | |||
IFT_X25MLP = 0x79 | |||
IFT_X25PLE = 0x28 | |||
IFT_XETHER = 0x1a | |||
IPPROTO_MAXID = 0x34 | |||
IPV6_FAITH = 0x1d | |||
IP_FAITH = 0x16 | |||
MAP_NORESERVE = 0x40 | |||
MAP_RENAME = 0x20 | |||
NET_RT_MAXID = 0x6 | |||
RTF_PRCLONING = 0x10000 | |||
RTM_OLDADD = 0x9 | |||
RTM_OLDDEL = 0xa | |||
SIOCADDRT = 0x8040720a | |||
SIOCALIFADDR = 0x8118691b | |||
SIOCDELRT = 0x8040720b | |||
SIOCDLIFADDR = 0x8118691d | |||
SIOCGLIFADDR = 0xc118691c | |||
SIOCGLIFPHYADDR = 0xc118694b | |||
SIOCSLIFPHYADDR = 0x8118694a | |||
) |
@@ -1,226 +0,0 @@ | |||
// Copyright 2017 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 | |||
const ( | |||
IFT_1822 = 0x2 | |||
IFT_A12MPPSWITCH = 0x82 | |||
IFT_AAL2 = 0xbb | |||
IFT_AAL5 = 0x31 | |||
IFT_ADSL = 0x5e | |||
IFT_AFLANE8023 = 0x3b | |||
IFT_AFLANE8025 = 0x3c | |||
IFT_ARAP = 0x58 | |||
IFT_ARCNET = 0x23 | |||
IFT_ARCNETPLUS = 0x24 | |||
IFT_ASYNC = 0x54 | |||
IFT_ATM = 0x25 | |||
IFT_ATMDXI = 0x69 | |||
IFT_ATMFUNI = 0x6a | |||
IFT_ATMIMA = 0x6b | |||
IFT_ATMLOGICAL = 0x50 | |||
IFT_ATMRADIO = 0xbd | |||
IFT_ATMSUBINTERFACE = 0x86 | |||
IFT_ATMVCIENDPT = 0xc2 | |||
IFT_ATMVIRTUAL = 0x95 | |||
IFT_BGPPOLICYACCOUNTING = 0xa2 | |||
IFT_BSC = 0x53 | |||
IFT_CCTEMUL = 0x3d | |||
IFT_CEPT = 0x13 | |||
IFT_CES = 0x85 | |||
IFT_CHANNEL = 0x46 | |||
IFT_CNR = 0x55 | |||
IFT_COFFEE = 0x84 | |||
IFT_COMPOSITELINK = 0x9b | |||
IFT_DCN = 0x8d | |||
IFT_DIGITALPOWERLINE = 0x8a | |||
IFT_DIGITALWRAPPEROVERHEADCHANNEL = 0xba | |||
IFT_DLSW = 0x4a | |||
IFT_DOCSCABLEDOWNSTREAM = 0x80 | |||
IFT_DOCSCABLEMACLAYER = 0x7f | |||
IFT_DOCSCABLEUPSTREAM = 0x81 | |||
IFT_DS0 = 0x51 | |||
IFT_DS0BUNDLE = 0x52 | |||
IFT_DS1FDL = 0xaa | |||
IFT_DS3 = 0x1e | |||
IFT_DTM = 0x8c | |||
IFT_DVBASILN = 0xac | |||
IFT_DVBASIOUT = 0xad | |||
IFT_DVBRCCDOWNSTREAM = 0x93 | |||
IFT_DVBRCCMACLAYER = 0x92 | |||
IFT_DVBRCCUPSTREAM = 0x94 | |||
IFT_ENC = 0xf4 | |||
IFT_EON = 0x19 | |||
IFT_EPLRS = 0x57 | |||
IFT_ESCON = 0x49 | |||
IFT_ETHER = 0x6 | |||
IFT_FAST = 0x7d | |||
IFT_FASTETHER = 0x3e | |||
IFT_FASTETHERFX = 0x45 | |||
IFT_FDDI = 0xf | |||
IFT_FIBRECHANNEL = 0x38 | |||
IFT_FRAMERELAYINTERCONNECT = 0x3a | |||
IFT_FRAMERELAYMPI = 0x5c | |||
IFT_FRDLCIENDPT = 0xc1 | |||
IFT_FRELAY = 0x20 | |||
IFT_FRELAYDCE = 0x2c | |||
IFT_FRF16MFRBUNDLE = 0xa3 | |||
IFT_FRFORWARD = 0x9e | |||
IFT_G703AT2MB = 0x43 | |||
IFT_G703AT64K = 0x42 | |||
IFT_GIF = 0xf0 | |||
IFT_GIGABITETHERNET = 0x75 | |||
IFT_GR303IDT = 0xb2 | |||
IFT_GR303RDT = 0xb1 | |||
IFT_H323GATEKEEPER = 0xa4 | |||
IFT_H323PROXY = 0xa5 | |||
IFT_HDH1822 = 0x3 | |||
IFT_HDLC = 0x76 | |||
IFT_HDSL2 = 0xa8 | |||
IFT_HIPERLAN2 = 0xb7 | |||
IFT_HIPPI = 0x2f | |||
IFT_HIPPIINTERFACE = 0x39 | |||
IFT_HOSTPAD = 0x5a | |||
IFT_HSSI = 0x2e | |||
IFT_HY = 0xe | |||
IFT_IBM370PARCHAN = 0x48 | |||
IFT_IDSL = 0x9a | |||
IFT_IEEE80211 = 0x47 | |||
IFT_IEEE80212 = 0x37 | |||
IFT_IEEE8023ADLAG = 0xa1 | |||
IFT_IFGSN = 0x91 | |||
IFT_IMT = 0xbe | |||
IFT_INTERLEAVE = 0x7c | |||
IFT_IP = 0x7e | |||
IFT_IPFORWARD = 0x8e | |||
IFT_IPOVERATM = 0x72 | |||
IFT_IPOVERCDLC = 0x6d | |||
IFT_IPOVERCLAW = 0x6e | |||
IFT_IPSWITCH = 0x4e | |||
IFT_ISDN = 0x3f | |||
IFT_ISDNBASIC = 0x14 | |||
IFT_ISDNPRIMARY = 0x15 | |||
IFT_ISDNS = 0x4b | |||
IFT_ISDNU = 0x4c | |||
IFT_ISO88022LLC = 0x29 | |||
IFT_ISO88023 = 0x7 | |||
IFT_ISO88024 = 0x8 | |||
IFT_ISO88025 = 0x9 | |||
IFT_ISO88025CRFPINT = 0x62 | |||
IFT_ISO88025DTR = 0x56 | |||
IFT_ISO88025FIBER = 0x73 | |||
IFT_ISO88026 = 0xa | |||
IFT_ISUP = 0xb3 | |||
IFT_L3IPXVLAN = 0x89 | |||
IFT_LAPB = 0x10 | |||
IFT_LAPD = 0x4d | |||
IFT_LAPF = 0x77 | |||
IFT_LOCALTALK = 0x2a | |||
IFT_LOOP = 0x18 | |||
IFT_MEDIAMAILOVERIP = 0x8b | |||
IFT_MFSIGLINK = 0xa7 | |||
IFT_MIOX25 = 0x26 | |||
IFT_MODEM = 0x30 | |||
IFT_MPC = 0x71 | |||
IFT_MPLS = 0xa6 | |||
IFT_MPLSTUNNEL = 0x96 | |||
IFT_MSDSL = 0x8f | |||
IFT_MVL = 0xbf | |||
IFT_MYRINET = 0x63 | |||
IFT_NFAS = 0xaf | |||
IFT_NSIP = 0x1b | |||
IFT_OPTICALCHANNEL = 0xc3 | |||
IFT_OPTICALTRANSPORT = 0xc4 | |||
IFT_OTHER = 0x1 | |||
IFT_P10 = 0xc | |||
IFT_P80 = 0xd | |||
IFT_PARA = 0x22 | |||
IFT_PFLOG = 0xf6 | |||
IFT_PFSYNC = 0xf7 | |||
IFT_PLC = 0xae | |||
IFT_POS = 0xab | |||
IFT_PPPMULTILINKBUNDLE = 0x6c | |||
IFT_PROPBWAP2MP = 0xb8 | |||
IFT_PROPCNLS = 0x59 | |||
IFT_PROPDOCSWIRELESSDOWNSTREAM = 0xb5 | |||
IFT_PROPDOCSWIRELESSMACLAYER = 0xb4 | |||
IFT_PROPDOCSWIRELESSUPSTREAM = 0xb6 | |||
IFT_PROPMUX = 0x36 | |||
IFT_PROPWIRELESSP2P = 0x9d | |||
IFT_PTPSERIAL = 0x16 | |||
IFT_PVC = 0xf1 | |||
IFT_QLLC = 0x44 | |||
IFT_RADIOMAC = 0xbc | |||
IFT_RADSL = 0x5f | |||
IFT_REACHDSL = 0xc0 | |||
IFT_RFC1483 = 0x9f | |||
IFT_RS232 = 0x21 | |||
IFT_RSRB = 0x4f | |||
IFT_SDLC = 0x11 | |||
IFT_SDSL = 0x60 | |||
IFT_SHDSL = 0xa9 | |||
IFT_SIP = 0x1f | |||
IFT_SLIP = 0x1c | |||
IFT_SMDSDXI = 0x2b | |||
IFT_SMDSICIP = 0x34 | |||
IFT_SONET = 0x27 | |||
IFT_SONETOVERHEADCHANNEL = 0xb9 | |||
IFT_SONETPATH = 0x32 | |||
IFT_SONETVT = 0x33 | |||
IFT_SRP = 0x97 | |||
IFT_SS7SIGLINK = 0x9c | |||
IFT_STACKTOSTACK = 0x6f | |||
IFT_STARLAN = 0xb | |||
IFT_STF = 0xd7 | |||
IFT_T1 = 0x12 | |||
IFT_TDLC = 0x74 | |||
IFT_TERMPAD = 0x5b | |||
IFT_TR008 = 0xb0 | |||
IFT_TRANSPHDLC = 0x7b | |||
IFT_TUNNEL = 0x83 | |||
IFT_ULTRA = 0x1d | |||
IFT_USB = 0xa0 | |||
IFT_V11 = 0x40 | |||
IFT_V35 = 0x2d | |||
IFT_V36 = 0x41 | |||
IFT_V37 = 0x78 | |||
IFT_VDSL = 0x61 | |||
IFT_VIRTUALIPADDRESS = 0x70 | |||
IFT_VOICEEM = 0x64 | |||
IFT_VOICEENCAP = 0x67 | |||
IFT_VOICEFXO = 0x65 | |||
IFT_VOICEFXS = 0x66 | |||
IFT_VOICEOVERATM = 0x98 | |||
IFT_VOICEOVERFRAMERELAY = 0x99 | |||
IFT_VOICEOVERIP = 0x68 | |||
IFT_X213 = 0x5d | |||
IFT_X25 = 0x5 | |||
IFT_X25DDN = 0x4 | |||
IFT_X25HUNTGROUP = 0x7a | |||
IFT_X25MLP = 0x79 | |||
IFT_X25PLE = 0x28 | |||
IFT_XETHER = 0x1a | |||
// missing constants on FreeBSD-11.1-RELEASE, copied from old values in ztypes_freebsd_arm.go | |||
IFF_SMART = 0x20 | |||
IFT_FAITH = 0xf2 | |||
IFT_IPXIP = 0xf9 | |||
IPPROTO_MAXID = 0x34 | |||
IPV6_FAITH = 0x1d | |||
IP_FAITH = 0x16 | |||
MAP_NORESERVE = 0x40 | |||
MAP_RENAME = 0x20 | |||
NET_RT_MAXID = 0x6 | |||
RTF_PRCLONING = 0x10000 | |||
RTM_OLDADD = 0x9 | |||
RTM_OLDDEL = 0xa | |||
SIOCADDRT = 0x8030720a | |||
SIOCALIFADDR = 0x8118691b | |||
SIOCDELRT = 0x8030720b | |||
SIOCDLIFADDR = 0x8118691d | |||
SIOCGLIFADDR = 0xc118691c | |||
SIOCGLIFPHYADDR = 0xc118694b | |||
SIOCSLIFPHYADDR = 0x8118694a | |||
) |
@@ -2,19 +2,19 @@ | |||
// Use of this source code is governed by a BSD-style | |||
// license that can be found in the LICENSE file. | |||
// +build darwin dragonfly freebsd linux netbsd openbsd | |||
//go:build dragonfly || freebsd || linux || netbsd || openbsd | |||
// +build dragonfly freebsd linux netbsd openbsd | |||
package unix | |||
import "unsafe" | |||
// fcntl64Syscall is usually SYS_FCNTL, but is overridden on 32-bit Linux | |||
// systems by flock_linux_32bit.go to be SYS_FCNTL64. | |||
// systems by fcntl_linux_32bit.go to be SYS_FCNTL64. | |||
var fcntl64Syscall uintptr = SYS_FCNTL | |||
// FcntlInt performs a fcntl syscall on fd with the provided command and argument. | |||
func FcntlInt(fd uintptr, cmd, arg int) (int, error) { | |||
valptr, _, errno := Syscall(fcntl64Syscall, fd, uintptr(cmd), uintptr(arg)) | |||
func fcntl(fd int, cmd, arg int) (int, error) { | |||
valptr, _, errno := Syscall(fcntl64Syscall, uintptr(fd), uintptr(cmd), uintptr(arg)) | |||
var err error | |||
if errno != 0 { | |||
err = errno | |||
@@ -22,6 +22,11 @@ func FcntlInt(fd uintptr, cmd, arg int) (int, error) { | |||
return int(valptr), err | |||
} | |||
// FcntlInt performs a fcntl syscall on fd with the provided command and argument. | |||
func FcntlInt(fd uintptr, cmd, arg int) (int, error) { | |||
return fcntl(int(fd), cmd, arg) | |||
} | |||
// FcntlFlock performs a fcntl syscall for the F_GETLK, F_SETLK or F_SETLKW command. | |||
func FcntlFlock(fd uintptr, cmd int, lk *Flock_t) error { | |||
_, _, errno := Syscall(fcntl64Syscall, fd, uintptr(cmd), uintptr(unsafe.Pointer(lk))) | |||
@@ -0,0 +1,24 @@ | |||
// Copyright 2019 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 | |||
import "unsafe" | |||
// FcntlInt performs a fcntl syscall on fd with the provided command and argument. | |||
func FcntlInt(fd uintptr, cmd, arg int) (int, error) { | |||
return fcntl(int(fd), cmd, arg) | |||
} | |||
// FcntlFlock performs a fcntl syscall for the F_GETLK, F_SETLK or F_SETLKW command. | |||
func FcntlFlock(fd uintptr, cmd int, lk *Flock_t) error { | |||
_, err := fcntl(int(fd), cmd, int(uintptr(unsafe.Pointer(lk)))) | |||
return err | |||
} | |||
// FcntlFstore performs a fcntl syscall for the F_PREALLOCATE command. | |||
func FcntlFstore(fd uintptr, cmd int, fstore *Fstore_t) error { | |||
_, err := fcntl(int(fd), cmd, int(uintptr(unsafe.Pointer(fstore)))) | |||
return err | |||
} |
@@ -1,9 +1,10 @@ | |||
// +build linux,386 linux,arm linux,mips linux,mipsle | |||
// Copyright 2014 The Go Authors. All rights reserved. | |||
// Use of this source code is governed by a BSD-style | |||
// license that can be found in the LICENSE file. | |||
//go:build (linux && 386) || (linux && arm) || (linux && mips) || (linux && mipsle) || (linux && ppc) | |||
// +build linux,386 linux,arm linux,mips linux,mipsle linux,ppc | |||
package unix | |||
func init() { | |||
@@ -0,0 +1,30 @@ | |||
// Copyright 2019 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. | |||
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos | |||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos | |||
package unix | |||
// Set adds fd to the set fds. | |||
func (fds *FdSet) Set(fd int) { | |||
fds.Bits[fd/NFDBITS] |= (1 << (uintptr(fd) % NFDBITS)) | |||
} | |||
// Clear removes fd from the set fds. | |||
func (fds *FdSet) Clear(fd int) { | |||
fds.Bits[fd/NFDBITS] &^= (1 << (uintptr(fd) % NFDBITS)) | |||
} | |||
// IsSet returns whether fd is in the set fds. | |||
func (fds *FdSet) IsSet(fd int) bool { | |||
return fds.Bits[fd/NFDBITS]&(1<<(uintptr(fd)%NFDBITS)) != 0 | |||
} | |||
// Zero clears the set fds. | |||
func (fds *FdSet) Zero() { | |||
for i := range fds.Bits { | |||
fds.Bits[i] = 0 | |||
} | |||
} |
@@ -0,0 +1,164 @@ | |||
// Copyright 2020 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. | |||
//go:build zos && s390x | |||
// +build zos,s390x | |||
package unix | |||
import ( | |||
"unsafe" | |||
) | |||
// This file simulates fstatfs on z/OS using fstatvfs and w_getmntent. | |||
func Fstatfs(fd int, stat *Statfs_t) (err error) { | |||
var stat_v Statvfs_t | |||
err = Fstatvfs(fd, &stat_v) | |||
if err == nil { | |||
// populate stat | |||
stat.Type = 0 | |||
stat.Bsize = stat_v.Bsize | |||
stat.Blocks = stat_v.Blocks | |||
stat.Bfree = stat_v.Bfree | |||
stat.Bavail = stat_v.Bavail | |||
stat.Files = stat_v.Files | |||
stat.Ffree = stat_v.Ffree | |||
stat.Fsid = stat_v.Fsid | |||
stat.Namelen = stat_v.Namemax | |||
stat.Frsize = stat_v.Frsize | |||
stat.Flags = stat_v.Flag | |||
for passn := 0; passn < 5; passn++ { | |||
switch passn { | |||
case 0: | |||
err = tryGetmntent64(stat) | |||
break | |||
case 1: | |||
err = tryGetmntent128(stat) | |||
break | |||
case 2: | |||
err = tryGetmntent256(stat) | |||
break | |||
case 3: | |||
err = tryGetmntent512(stat) | |||
break | |||
case 4: | |||
err = tryGetmntent1024(stat) | |||
break | |||
default: | |||
break | |||
} | |||
//proceed to return if: err is nil (found), err is nonnil but not ERANGE (another error occurred) | |||
if err == nil || err != nil && err != ERANGE { | |||
break | |||
} | |||
} | |||
} | |||
return err | |||
} | |||
func tryGetmntent64(stat *Statfs_t) (err error) { | |||
var mnt_ent_buffer struct { | |||
header W_Mnth | |||
filesys_info [64]W_Mntent | |||
} | |||
var buffer_size int = int(unsafe.Sizeof(mnt_ent_buffer)) | |||
fs_count, err := W_Getmntent((*byte)(unsafe.Pointer(&mnt_ent_buffer)), buffer_size) | |||
if err != nil { | |||
return err | |||
} | |||
err = ERANGE //return ERANGE if no match is found in this batch | |||
for i := 0; i < fs_count; i++ { | |||
if stat.Fsid == uint64(mnt_ent_buffer.filesys_info[i].Dev) { | |||
stat.Type = uint32(mnt_ent_buffer.filesys_info[i].Fstname[0]) | |||
err = nil | |||
break | |||
} | |||
} | |||
return err | |||
} | |||
func tryGetmntent128(stat *Statfs_t) (err error) { | |||
var mnt_ent_buffer struct { | |||
header W_Mnth | |||
filesys_info [128]W_Mntent | |||
} | |||
var buffer_size int = int(unsafe.Sizeof(mnt_ent_buffer)) | |||
fs_count, err := W_Getmntent((*byte)(unsafe.Pointer(&mnt_ent_buffer)), buffer_size) | |||
if err != nil { | |||
return err | |||
} | |||
err = ERANGE //return ERANGE if no match is found in this batch | |||
for i := 0; i < fs_count; i++ { | |||
if stat.Fsid == uint64(mnt_ent_buffer.filesys_info[i].Dev) { | |||
stat.Type = uint32(mnt_ent_buffer.filesys_info[i].Fstname[0]) | |||
err = nil | |||
break | |||
} | |||
} | |||
return err | |||
} | |||
func tryGetmntent256(stat *Statfs_t) (err error) { | |||
var mnt_ent_buffer struct { | |||
header W_Mnth | |||
filesys_info [256]W_Mntent | |||
} | |||
var buffer_size int = int(unsafe.Sizeof(mnt_ent_buffer)) | |||
fs_count, err := W_Getmntent((*byte)(unsafe.Pointer(&mnt_ent_buffer)), buffer_size) | |||
if err != nil { | |||
return err | |||
} | |||
err = ERANGE //return ERANGE if no match is found in this batch | |||
for i := 0; i < fs_count; i++ { | |||
if stat.Fsid == uint64(mnt_ent_buffer.filesys_info[i].Dev) { | |||
stat.Type = uint32(mnt_ent_buffer.filesys_info[i].Fstname[0]) | |||
err = nil | |||
break | |||
} | |||
} | |||
return err | |||
} | |||
func tryGetmntent512(stat *Statfs_t) (err error) { | |||
var mnt_ent_buffer struct { | |||
header W_Mnth | |||
filesys_info [512]W_Mntent | |||
} | |||
var buffer_size int = int(unsafe.Sizeof(mnt_ent_buffer)) | |||
fs_count, err := W_Getmntent((*byte)(unsafe.Pointer(&mnt_ent_buffer)), buffer_size) | |||
if err != nil { | |||
return err | |||
} | |||
err = ERANGE //return ERANGE if no match is found in this batch | |||
for i := 0; i < fs_count; i++ { | |||
if stat.Fsid == uint64(mnt_ent_buffer.filesys_info[i].Dev) { | |||
stat.Type = uint32(mnt_ent_buffer.filesys_info[i].Fstname[0]) | |||
err = nil | |||
break | |||
} | |||
} | |||
return err | |||
} | |||
func tryGetmntent1024(stat *Statfs_t) (err error) { | |||
var mnt_ent_buffer struct { | |||
header W_Mnth | |||
filesys_info [1024]W_Mntent | |||
} | |||
var buffer_size int = int(unsafe.Sizeof(mnt_ent_buffer)) | |||
fs_count, err := W_Getmntent((*byte)(unsafe.Pointer(&mnt_ent_buffer)), buffer_size) | |||
if err != nil { | |||
return err | |||
} | |||
err = ERANGE //return ERANGE if no match is found in this batch | |||
for i := 0; i < fs_count; i++ { | |||
if stat.Fsid == uint64(mnt_ent_buffer.filesys_info[i].Dev) { | |||
stat.Type = uint32(mnt_ent_buffer.filesys_info[i].Fstname[0]) | |||
err = nil | |||
break | |||
} | |||
} | |||
return err | |||
} |
@@ -2,8 +2,8 @@ | |||
// Use of this source code is governed by a BSD-style | |||
// license that can be found in the LICENSE file. | |||
// +build gccgo | |||
// +build !aix | |||
//go:build gccgo && !aix | |||
// +build gccgo,!aix | |||
package unix | |||
@@ -12,10 +12,8 @@ import "syscall" | |||
// We can't use the gc-syntax .s files for gccgo. On the plus side | |||
// much of the functionality can be written directly in Go. | |||
//extern gccgoRealSyscallNoError | |||
func realSyscallNoError(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r uintptr) | |||
//extern gccgoRealSyscall | |||
func realSyscall(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r, errno uintptr) | |||
func SyscallNoError(trap, a1, a2, a3 uintptr) (r1, r2 uintptr) { | |||
@@ -21,6 +21,9 @@ struct ret { | |||
uintptr_t err; | |||
}; | |||
struct ret gccgoRealSyscall(uintptr_t trap, uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, uintptr_t a5, uintptr_t a6, uintptr_t a7, uintptr_t a8, uintptr_t a9) | |||
__asm__(GOSYM_PREFIX GOPKGPATH ".realSyscall"); | |||
struct ret | |||
gccgoRealSyscall(uintptr_t trap, uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, uintptr_t a5, uintptr_t a6, uintptr_t a7, uintptr_t a8, uintptr_t a9) | |||
{ | |||
@@ -32,6 +35,9 @@ gccgoRealSyscall(uintptr_t trap, uintptr_t a1, uintptr_t a2, uintptr_t a3, uintp | |||
return r; | |||
} | |||
uintptr_t gccgoRealSyscallNoError(uintptr_t trap, uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, uintptr_t a5, uintptr_t a6, uintptr_t a7, uintptr_t a8, uintptr_t a9) | |||
__asm__(GOSYM_PREFIX GOPKGPATH ".realSyscallNoError"); | |||
uintptr_t | |||
gccgoRealSyscallNoError(uintptr_t trap, uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, uintptr_t a5, uintptr_t a6, uintptr_t a7, uintptr_t a8, uintptr_t a9) | |||
{ | |||
@@ -2,6 +2,7 @@ | |||
// Use of this source code is governed by a BSD-style | |||
// license that can be found in the LICENSE file. | |||
//go:build gccgo && linux && amd64 | |||
// +build gccgo,linux,amd64 | |||
package unix | |||
@@ -0,0 +1,142 @@ | |||
// Copyright 2021 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. | |||
//go:build linux | |||
// +build linux | |||
package unix | |||
import ( | |||
"unsafe" | |||
) | |||
// Helpers for dealing with ifreq since it contains a union and thus requires a | |||
// lot of unsafe.Pointer casts to use properly. | |||
// An Ifreq is a type-safe wrapper around the raw ifreq struct. An Ifreq | |||
// contains an interface name and a union of arbitrary data which can be | |||
// accessed using the Ifreq's methods. To create an Ifreq, use the NewIfreq | |||
// function. | |||
// | |||
// Use the Name method to access the stored interface name. The union data | |||
// fields can be get and set using the following methods: | |||
// - Uint16/SetUint16: flags | |||
// - Uint32/SetUint32: ifindex, metric, mtu | |||
type Ifreq struct{ raw ifreq } | |||
// NewIfreq creates an Ifreq with the input network interface name after | |||
// validating the name does not exceed IFNAMSIZ-1 (trailing NULL required) | |||
// bytes. | |||
func NewIfreq(name string) (*Ifreq, error) { | |||
// Leave room for terminating NULL byte. | |||
if len(name) >= IFNAMSIZ { | |||
return nil, EINVAL | |||
} | |||
var ifr ifreq | |||
copy(ifr.Ifrn[:], name) | |||
return &Ifreq{raw: ifr}, nil | |||
} | |||
// TODO(mdlayher): get/set methods for hardware address sockaddr, char array, etc. | |||
// Name returns the interface name associated with the Ifreq. | |||
func (ifr *Ifreq) Name() string { | |||
return ByteSliceToString(ifr.raw.Ifrn[:]) | |||
} | |||
// According to netdevice(7), only AF_INET addresses are returned for numerous | |||
// sockaddr ioctls. For convenience, we expose these as Inet4Addr since the Port | |||
// field and other data is always empty. | |||
// Inet4Addr returns the Ifreq union data from an embedded sockaddr as a C | |||
// in_addr/Go []byte (4-byte IPv4 address) value. If the sockaddr family is not | |||
// AF_INET, an error is returned. | |||
func (ifr *Ifreq) Inet4Addr() ([]byte, error) { | |||
raw := *(*RawSockaddrInet4)(unsafe.Pointer(&ifr.raw.Ifru[:SizeofSockaddrInet4][0])) | |||
if raw.Family != AF_INET { | |||
// Cannot safely interpret raw.Addr bytes as an IPv4 address. | |||
return nil, EINVAL | |||
} | |||
return raw.Addr[:], nil | |||
} | |||
// SetInet4Addr sets a C in_addr/Go []byte (4-byte IPv4 address) value in an | |||
// embedded sockaddr within the Ifreq's union data. v must be 4 bytes in length | |||
// or an error will be returned. | |||
func (ifr *Ifreq) SetInet4Addr(v []byte) error { | |||
if len(v) != 4 { | |||
return EINVAL | |||
} | |||
var addr [4]byte | |||
copy(addr[:], v) | |||
ifr.clear() | |||
*(*RawSockaddrInet4)( | |||
unsafe.Pointer(&ifr.raw.Ifru[:SizeofSockaddrInet4][0]), | |||
) = RawSockaddrInet4{ | |||
// Always set IP family as ioctls would require it anyway. | |||
Family: AF_INET, | |||
Addr: addr, | |||
} | |||
return nil | |||
} | |||
// Uint16 returns the Ifreq union data as a C short/Go uint16 value. | |||
func (ifr *Ifreq) Uint16() uint16 { | |||
return *(*uint16)(unsafe.Pointer(&ifr.raw.Ifru[:2][0])) | |||
} | |||
// SetUint16 sets a C short/Go uint16 value as the Ifreq's union data. | |||
func (ifr *Ifreq) SetUint16(v uint16) { | |||
ifr.clear() | |||
*(*uint16)(unsafe.Pointer(&ifr.raw.Ifru[:2][0])) = v | |||
} | |||
// Uint32 returns the Ifreq union data as a C int/Go uint32 value. | |||
func (ifr *Ifreq) Uint32() uint32 { | |||
return *(*uint32)(unsafe.Pointer(&ifr.raw.Ifru[:4][0])) | |||
} | |||
// SetUint32 sets a C int/Go uint32 value as the Ifreq's union data. | |||
func (ifr *Ifreq) SetUint32(v uint32) { | |||
ifr.clear() | |||
*(*uint32)(unsafe.Pointer(&ifr.raw.Ifru[:4][0])) = v | |||
} | |||
// clear zeroes the ifreq's union field to prevent trailing garbage data from | |||
// being sent to the kernel if an ifreq is reused. | |||
func (ifr *Ifreq) clear() { | |||
for i := range ifr.raw.Ifru { | |||
ifr.raw.Ifru[i] = 0 | |||
} | |||
} | |||
// TODO(mdlayher): export as IfreqData? For now we can provide helpers such as | |||
// IoctlGetEthtoolDrvinfo which use these APIs under the hood. | |||
// An ifreqData is an Ifreq which carries pointer data. To produce an ifreqData, | |||
// use the Ifreq.withData method. | |||
type ifreqData struct { | |||
name [IFNAMSIZ]byte | |||
// A type separate from ifreq is required in order to comply with the | |||
// unsafe.Pointer rules since the "pointer-ness" of data would not be | |||
// preserved if it were cast into the byte array of a raw ifreq. | |||
data unsafe.Pointer | |||
// Pad to the same size as ifreq. | |||
_ [len(ifreq{}.Ifru) - SizeofPtr]byte | |||
} | |||
// withData produces an ifreqData with the pointer p set for ioctls which require | |||
// arbitrary pointer data. | |||
func (ifr Ifreq) withData(p unsafe.Pointer) ifreqData { | |||
return ifreqData{ | |||
name: ifr.raw.Ifrn, | |||
data: p, | |||
} | |||
} |
@@ -2,11 +2,33 @@ | |||
// Use of this source code is governed by a BSD-style | |||
// license that can be found in the LICENSE file. | |||
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris | |||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris | |||
package unix | |||
import "runtime" | |||
import ( | |||
"runtime" | |||
"unsafe" | |||
) | |||
// ioctl itself should not be exposed directly, but additional get/set | |||
// functions for specific types are permissible. | |||
// IoctlSetInt performs an ioctl operation which sets an integer value | |||
// on fd, using the specified request number. | |||
func IoctlSetInt(fd int, req uint, value int) error { | |||
return ioctl(fd, req, uintptr(value)) | |||
} | |||
// IoctlSetPointerInt performs an ioctl operation which sets an | |||
// integer value on fd, using the specified request number. The ioctl | |||
// argument is called with a pointer to the integer value, rather than | |||
// passing the integer value directly. | |||
func IoctlSetPointerInt(fd int, req uint, value int) error { | |||
v := int32(value) | |||
return ioctl(fd, req, uintptr(unsafe.Pointer(&v))) | |||
} | |||
// IoctlSetWinsize performs an ioctl on fd with a *Winsize argument. | |||
// | |||
@@ -14,7 +36,7 @@ import "runtime" | |||
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) | |||
err := ioctl(fd, req, uintptr(unsafe.Pointer(value))) | |||
runtime.KeepAlive(value) | |||
return err | |||
} | |||
@@ -24,7 +46,30 @@ func IoctlSetWinsize(fd int, req uint, value *Winsize) error { | |||
// 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) | |||
err := ioctl(fd, req, uintptr(unsafe.Pointer(value))) | |||
runtime.KeepAlive(value) | |||
return err | |||
} | |||
// IoctlGetInt performs an ioctl operation which gets an integer value | |||
// from fd, using the specified request number. | |||
// | |||
// A few ioctl requests use the return value as an output parameter; | |||
// for those, IoctlRetInt should be used instead of this function. | |||
func IoctlGetInt(fd int, req uint) (int, error) { | |||
var value int | |||
err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) | |||
return value, err | |||
} | |||
func IoctlGetWinsize(fd int, req uint) (*Winsize, error) { | |||
var value Winsize | |||
err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) | |||
return &value, err | |||
} | |||
func IoctlGetTermios(fd int, req uint) (*Termios, error) { | |||
var value Termios | |||
err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) | |||
return &value, err | |||
} |
@@ -0,0 +1,233 @@ | |||
// Copyright 2021 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 | |||
import "unsafe" | |||
// IoctlRetInt performs an ioctl operation specified by req on a device | |||
// associated with opened file descriptor fd, and returns a non-negative | |||
// integer that is returned by the ioctl syscall. | |||
func IoctlRetInt(fd int, req uint) (int, error) { | |||
ret, _, err := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), 0) | |||
if err != 0 { | |||
return 0, err | |||
} | |||
return int(ret), nil | |||
} | |||
func IoctlGetUint32(fd int, req uint) (uint32, error) { | |||
var value uint32 | |||
err := ioctlPtr(fd, req, unsafe.Pointer(&value)) | |||
return value, err | |||
} | |||
func IoctlGetRTCTime(fd int) (*RTCTime, error) { | |||
var value RTCTime | |||
err := ioctlPtr(fd, RTC_RD_TIME, unsafe.Pointer(&value)) | |||
return &value, err | |||
} | |||
func IoctlSetRTCTime(fd int, value *RTCTime) error { | |||
return ioctlPtr(fd, RTC_SET_TIME, unsafe.Pointer(value)) | |||
} | |||
func IoctlGetRTCWkAlrm(fd int) (*RTCWkAlrm, error) { | |||
var value RTCWkAlrm | |||
err := ioctlPtr(fd, RTC_WKALM_RD, unsafe.Pointer(&value)) | |||
return &value, err | |||
} | |||
func IoctlSetRTCWkAlrm(fd int, value *RTCWkAlrm) error { | |||
return ioctlPtr(fd, RTC_WKALM_SET, unsafe.Pointer(value)) | |||
} | |||
// IoctlGetEthtoolDrvinfo fetches ethtool driver information for the network | |||
// device specified by ifname. | |||
func IoctlGetEthtoolDrvinfo(fd int, ifname string) (*EthtoolDrvinfo, error) { | |||
ifr, err := NewIfreq(ifname) | |||
if err != nil { | |||
return nil, err | |||
} | |||
value := EthtoolDrvinfo{Cmd: ETHTOOL_GDRVINFO} | |||
ifrd := ifr.withData(unsafe.Pointer(&value)) | |||
err = ioctlIfreqData(fd, SIOCETHTOOL, &ifrd) | |||
return &value, err | |||
} | |||
// IoctlGetWatchdogInfo fetches information about a watchdog device from the | |||
// Linux watchdog API. For more information, see: | |||
// https://www.kernel.org/doc/html/latest/watchdog/watchdog-api.html. | |||
func IoctlGetWatchdogInfo(fd int) (*WatchdogInfo, error) { | |||
var value WatchdogInfo | |||
err := ioctlPtr(fd, WDIOC_GETSUPPORT, unsafe.Pointer(&value)) | |||
return &value, err | |||
} | |||
// IoctlWatchdogKeepalive issues a keepalive ioctl to a watchdog device. For | |||
// more information, see: | |||
// https://www.kernel.org/doc/html/latest/watchdog/watchdog-api.html. | |||
func IoctlWatchdogKeepalive(fd int) error { | |||
// arg is ignored and not a pointer, so ioctl is fine instead of ioctlPtr. | |||
return ioctl(fd, WDIOC_KEEPALIVE, 0) | |||
} | |||
// IoctlFileCloneRange performs an FICLONERANGE ioctl operation to clone the | |||
// range of data conveyed in value to the file associated with the file | |||
// descriptor destFd. See the ioctl_ficlonerange(2) man page for details. | |||
func IoctlFileCloneRange(destFd int, value *FileCloneRange) error { | |||
return ioctlPtr(destFd, FICLONERANGE, unsafe.Pointer(value)) | |||
} | |||
// IoctlFileClone performs an FICLONE ioctl operation to clone the entire file | |||
// associated with the file description srcFd to the file associated with the | |||
// file descriptor destFd. See the ioctl_ficlone(2) man page for details. | |||
func IoctlFileClone(destFd, srcFd int) error { | |||
return ioctl(destFd, FICLONE, uintptr(srcFd)) | |||
} | |||
type FileDedupeRange struct { | |||
Src_offset uint64 | |||
Src_length uint64 | |||
Reserved1 uint16 | |||
Reserved2 uint32 | |||
Info []FileDedupeRangeInfo | |||
} | |||
type FileDedupeRangeInfo struct { | |||
Dest_fd int64 | |||
Dest_offset uint64 | |||
Bytes_deduped uint64 | |||
Status int32 | |||
Reserved uint32 | |||
} | |||
// IoctlFileDedupeRange performs an FIDEDUPERANGE ioctl operation to share the | |||
// range of data conveyed in value from the file associated with the file | |||
// descriptor srcFd to the value.Info destinations. See the | |||
// ioctl_fideduperange(2) man page for details. | |||
func IoctlFileDedupeRange(srcFd int, value *FileDedupeRange) error { | |||
buf := make([]byte, SizeofRawFileDedupeRange+ | |||
len(value.Info)*SizeofRawFileDedupeRangeInfo) | |||
rawrange := (*RawFileDedupeRange)(unsafe.Pointer(&buf[0])) | |||
rawrange.Src_offset = value.Src_offset | |||
rawrange.Src_length = value.Src_length | |||
rawrange.Dest_count = uint16(len(value.Info)) | |||
rawrange.Reserved1 = value.Reserved1 | |||
rawrange.Reserved2 = value.Reserved2 | |||
for i := range value.Info { | |||
rawinfo := (*RawFileDedupeRangeInfo)(unsafe.Pointer( | |||
uintptr(unsafe.Pointer(&buf[0])) + uintptr(SizeofRawFileDedupeRange) + | |||
uintptr(i*SizeofRawFileDedupeRangeInfo))) | |||
rawinfo.Dest_fd = value.Info[i].Dest_fd | |||
rawinfo.Dest_offset = value.Info[i].Dest_offset | |||
rawinfo.Bytes_deduped = value.Info[i].Bytes_deduped | |||
rawinfo.Status = value.Info[i].Status | |||
rawinfo.Reserved = value.Info[i].Reserved | |||
} | |||
err := ioctlPtr(srcFd, FIDEDUPERANGE, unsafe.Pointer(&buf[0])) | |||
// Output | |||
for i := range value.Info { | |||
rawinfo := (*RawFileDedupeRangeInfo)(unsafe.Pointer( | |||
uintptr(unsafe.Pointer(&buf[0])) + uintptr(SizeofRawFileDedupeRange) + | |||
uintptr(i*SizeofRawFileDedupeRangeInfo))) | |||
value.Info[i].Dest_fd = rawinfo.Dest_fd | |||
value.Info[i].Dest_offset = rawinfo.Dest_offset | |||
value.Info[i].Bytes_deduped = rawinfo.Bytes_deduped | |||
value.Info[i].Status = rawinfo.Status | |||
value.Info[i].Reserved = rawinfo.Reserved | |||
} | |||
return err | |||
} | |||
func IoctlHIDGetDesc(fd int, value *HIDRawReportDescriptor) error { | |||
return ioctlPtr(fd, HIDIOCGRDESC, unsafe.Pointer(value)) | |||
} | |||
func IoctlHIDGetRawInfo(fd int) (*HIDRawDevInfo, error) { | |||
var value HIDRawDevInfo | |||
err := ioctlPtr(fd, HIDIOCGRAWINFO, unsafe.Pointer(&value)) | |||
return &value, err | |||
} | |||
func IoctlHIDGetRawName(fd int) (string, error) { | |||
var value [_HIDIOCGRAWNAME_LEN]byte | |||
err := ioctlPtr(fd, _HIDIOCGRAWNAME, unsafe.Pointer(&value[0])) | |||
return ByteSliceToString(value[:]), err | |||
} | |||
func IoctlHIDGetRawPhys(fd int) (string, error) { | |||
var value [_HIDIOCGRAWPHYS_LEN]byte | |||
err := ioctlPtr(fd, _HIDIOCGRAWPHYS, unsafe.Pointer(&value[0])) | |||
return ByteSliceToString(value[:]), err | |||
} | |||
func IoctlHIDGetRawUniq(fd int) (string, error) { | |||
var value [_HIDIOCGRAWUNIQ_LEN]byte | |||
err := ioctlPtr(fd, _HIDIOCGRAWUNIQ, unsafe.Pointer(&value[0])) | |||
return ByteSliceToString(value[:]), err | |||
} | |||
// IoctlIfreq performs an ioctl using an Ifreq structure for input and/or | |||
// output. See the netdevice(7) man page for details. | |||
func IoctlIfreq(fd int, req uint, value *Ifreq) error { | |||
// It is possible we will add more fields to *Ifreq itself later to prevent | |||
// misuse, so pass the raw *ifreq directly. | |||
return ioctlPtr(fd, req, unsafe.Pointer(&value.raw)) | |||
} | |||
// TODO(mdlayher): export if and when IfreqData is exported. | |||
// ioctlIfreqData performs an ioctl using an ifreqData structure for input | |||
// and/or output. See the netdevice(7) man page for details. | |||
func ioctlIfreqData(fd int, req uint, value *ifreqData) error { | |||
// The memory layout of IfreqData (type-safe) and ifreq (not type-safe) are | |||
// identical so pass *IfreqData directly. | |||
return ioctlPtr(fd, req, unsafe.Pointer(value)) | |||
} | |||
// IoctlKCMClone attaches a new file descriptor to a multiplexor by cloning an | |||
// existing KCM socket, returning a structure containing the file descriptor of | |||
// the new socket. | |||
func IoctlKCMClone(fd int) (*KCMClone, error) { | |||
var info KCMClone | |||
if err := ioctlPtr(fd, SIOCKCMCLONE, unsafe.Pointer(&info)); err != nil { | |||
return nil, err | |||
} | |||
return &info, nil | |||
} | |||
// IoctlKCMAttach attaches a TCP socket and associated BPF program file | |||
// descriptor to a multiplexor. | |||
func IoctlKCMAttach(fd int, info KCMAttach) error { | |||
return ioctlPtr(fd, SIOCKCMATTACH, unsafe.Pointer(&info)) | |||
} | |||
// IoctlKCMUnattach unattaches a TCP socket file descriptor from a multiplexor. | |||
func IoctlKCMUnattach(fd int, info KCMUnattach) error { | |||
return ioctlPtr(fd, SIOCKCMUNATTACH, unsafe.Pointer(&info)) | |||
} | |||
// IoctlLoopGetStatus64 gets the status of the loop device associated with the | |||
// file descriptor fd using the LOOP_GET_STATUS64 operation. | |||
func IoctlLoopGetStatus64(fd int) (*LoopInfo64, error) { | |||
var value LoopInfo64 | |||
if err := ioctlPtr(fd, LOOP_GET_STATUS64, unsafe.Pointer(&value)); err != nil { | |||
return nil, err | |||
} | |||
return &value, nil | |||
} | |||
// IoctlLoopSetStatus64 sets the status of the loop device associated with the | |||
// file descriptor fd using the LOOP_SET_STATUS64 operation. | |||
func IoctlLoopSetStatus64(fd int, value *LoopInfo64) error { | |||
return ioctlPtr(fd, LOOP_SET_STATUS64, unsafe.Pointer(value)) | |||
} |
@@ -0,0 +1,74 @@ | |||
// Copyright 2020 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. | |||
//go:build zos && s390x | |||
// +build zos,s390x | |||
package unix | |||
import ( | |||
"runtime" | |||
"unsafe" | |||
) | |||
// ioctl itself should not be exposed directly, but additional get/set | |||
// functions for specific types are permissible. | |||
// IoctlSetInt performs an ioctl operation which sets an integer value | |||
// on fd, using the specified request number. | |||
func IoctlSetInt(fd int, req uint, value int) error { | |||
return ioctl(fd, req, uintptr(value)) | |||
} | |||
// 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 := ioctl(fd, req, uintptr(unsafe.Pointer(value))) | |||
runtime.KeepAlive(value) | |||
return err | |||
} | |||
// IoctlSetTermios performs an ioctl on fd with a *Termios. | |||
// | |||
// The req value is expected to be TCSETS, TCSETSW, or TCSETSF | |||
func IoctlSetTermios(fd int, req uint, value *Termios) error { | |||
if (req != TCSETS) && (req != TCSETSW) && (req != TCSETSF) { | |||
return ENOSYS | |||
} | |||
err := Tcsetattr(fd, int(req), value) | |||
runtime.KeepAlive(value) | |||
return err | |||
} | |||
// IoctlGetInt performs an ioctl operation which gets an integer value | |||
// from fd, using the specified request number. | |||
// | |||
// A few ioctl requests use the return value as an output parameter; | |||
// for those, IoctlRetInt should be used instead of this function. | |||
func IoctlGetInt(fd int, req uint) (int, error) { | |||
var value int | |||
err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) | |||
return value, err | |||
} | |||
func IoctlGetWinsize(fd int, req uint) (*Winsize, error) { | |||
var value Winsize | |||
err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) | |||
return &value, err | |||
} | |||
// IoctlGetTermios performs an ioctl on fd with a *Termios. | |||
// | |||
// The req value is expected to be TCGETS | |||
func IoctlGetTermios(fd int, req uint) (*Termios, error) { | |||
var value Termios | |||
if req != TCGETS { | |||
return &value, ENOSYS | |||
} | |||
err := Tcgetattr(fd, &value) | |||
return &value, err | |||
} |
@@ -17,6 +17,7 @@ mksysctl="" | |||
zsysctl="zsysctl_$GOOSARCH.go" | |||
mksysnum= | |||
mktypes= | |||
mkasm= | |||
run="sh" | |||
cmd="" | |||
@@ -45,11 +46,11 @@ case "$#" in | |||
exit 2 | |||
esac | |||
if [[ "$GOOS" = "linux" ]] && [[ "$GOARCH" != "sparc64" ]]; then | |||
# Use then new build system | |||
if [[ "$GOOS" = "linux" ]]; then | |||
# Use the Docker-based build system | |||
# Files generated through docker (use $cmd so you can Ctl-C the build or run) | |||
$cmd docker build --tag generate:$GOOS $GOOS | |||
$cmd docker run --interactive --tty --volume $(dirname "$(readlink -f "$0")"):/build generate:$GOOS | |||
$cmd docker run --interactive --tty --volume $(cd -- "$(dirname -- "$0")/.." && /bin/pwd):/build generate:$GOOS | |||
exit | |||
fi | |||
@@ -61,116 +62,156 @@ _* | *_ | _) | |||
;; | |||
aix_ppc) | |||
mkerrors="$mkerrors -maix32" | |||
mksyscall="./mksyscall_aix_ppc.pl -aix" | |||
mksyscall="go run mksyscall_aix_ppc.go -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) | |||
mkerrors="$mkerrors -m32" | |||
mksyscall="go run mksyscall.go -l32" | |||
mksysnum="./mksysnum_darwin.pl $(xcrun --show-sdk-path --sdk macosx)/usr/include/sys/syscall.h" | |||
mksyscall="go run mksyscall_aix_ppc64.go -aix" | |||
mktypes="GOARCH=$GOARCH go tool cgo -godefs" | |||
;; | |||
darwin_amd64) | |||
mkerrors="$mkerrors -m64" | |||
mksysnum="./mksysnum_darwin.pl $(xcrun --show-sdk-path --sdk macosx)/usr/include/sys/syscall.h" | |||
mktypes="GOARCH=$GOARCH go tool cgo -godefs" | |||
;; | |||
darwin_arm) | |||
mkerrors="$mkerrors" | |||
mksysnum="./mksysnum_darwin.pl $(xcrun --show-sdk-path --sdk iphoneos)/usr/include/sys/syscall.h" | |||
mktypes="GOARCH=$GOARCH go tool cgo -godefs" | |||
mkasm="go run mkasm.go" | |||
;; | |||
darwin_arm64) | |||
mkerrors="$mkerrors -m64" | |||
mksysnum="./mksysnum_darwin.pl $(xcrun --show-sdk-path --sdk iphoneos)/usr/include/sys/syscall.h" | |||
mktypes="GOARCH=$GOARCH go tool cgo -godefs" | |||
mkasm="go run mkasm.go" | |||
;; | |||
dragonfly_amd64) | |||
mkerrors="$mkerrors -m64" | |||
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="go run mksysnum.go 'https://gitweb.dragonflybsd.org/dragonfly.git/blob_plain/HEAD:/sys/kern/syscalls.master'" | |||
mktypes="GOARCH=$GOARCH go tool cgo -godefs" | |||
;; | |||
freebsd_386) | |||
mkerrors="$mkerrors -m32" | |||
mksyscall="go run mksyscall.go -l32" | |||
mksysnum="curl -s 'http://svn.freebsd.org/base/stable/10/sys/kern/syscalls.master' | ./mksysnum_freebsd.pl" | |||
mksysnum="go run mksysnum.go 'https://cgit.freebsd.org/src/plain/sys/kern/syscalls.master?h=stable/12'" | |||
mktypes="GOARCH=$GOARCH go tool cgo -godefs" | |||
;; | |||
freebsd_amd64) | |||
mkerrors="$mkerrors -m64" | |||
mksysnum="curl -s 'http://svn.freebsd.org/base/stable/10/sys/kern/syscalls.master' | ./mksysnum_freebsd.pl" | |||
mksysnum="go run mksysnum.go 'https://cgit.freebsd.org/src/plain/sys/kern/syscalls.master?h=stable/12'" | |||
mktypes="GOARCH=$GOARCH go tool cgo -godefs" | |||
;; | |||
freebsd_arm) | |||
mkerrors="$mkerrors" | |||
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="go run mksysnum.go 'https://cgit.freebsd.org/src/plain/sys/kern/syscalls.master?h=stable/12'" | |||
# Let the type of C char be signed for making the bare syscall | |||
# API consistent across platforms. | |||
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char" | |||
;; | |||
linux_sparc64) | |||
GOOSARCH_in=syscall_linux_sparc64.go | |||
unistd_h=/usr/include/sparc64-linux-gnu/asm/unistd.h | |||
freebsd_arm64) | |||
mkerrors="$mkerrors -m64" | |||
mksysnum="./mksysnum_linux.pl $unistd_h" | |||
mktypes="GOARCH=$GOARCH go tool cgo -godefs" | |||
mksysnum="go run mksysnum.go 'https://cgit.freebsd.org/src/plain/sys/kern/syscalls.master?h=stable/12'" | |||
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char" | |||
;; | |||
freebsd_riscv64) | |||
mkerrors="$mkerrors -m64" | |||
mksysnum="go run mksysnum.go 'https://cgit.freebsd.org/src/plain/sys/kern/syscalls.master?h=stable/12'" | |||
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char" | |||
;; | |||
netbsd_386) | |||
mkerrors="$mkerrors -m32" | |||
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="go run mksysnum.go 'http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/kern/syscalls.master'" | |||
mktypes="GOARCH=$GOARCH go tool cgo -godefs" | |||
;; | |||
netbsd_amd64) | |||
mkerrors="$mkerrors -m64" | |||
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="go run mksysnum.go 'http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/kern/syscalls.master'" | |||
mktypes="GOARCH=$GOARCH go tool cgo -godefs" | |||
;; | |||
netbsd_arm) | |||
mkerrors="$mkerrors" | |||
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="go run mksysnum.go 'http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/kern/syscalls.master'" | |||
# Let the type of C char be signed for making the bare syscall | |||
# API consistent across platforms. | |||
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char" | |||
;; | |||
netbsd_arm64) | |||
mkerrors="$mkerrors -m64" | |||
mksyscall="go run mksyscall.go -netbsd" | |||
mksysnum="go run mksysnum.go 'http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/kern/syscalls.master'" | |||
mktypes="GOARCH=$GOARCH go tool cgo -godefs" | |||
;; | |||
openbsd_386) | |||
mkasm="go run mkasm.go" | |||
mkerrors="$mkerrors -m32" | |||
mksyscall="go run mksyscall.go -l32 -openbsd" | |||
mksysctl="./mksysctl_openbsd.pl" | |||
mksysnum="curl -s 'http://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_openbsd.pl" | |||
mksyscall="go run mksyscall.go -l32 -openbsd -libc" | |||
mksysctl="go run mksysctl_openbsd.go" | |||
mktypes="GOARCH=$GOARCH go tool cgo -godefs" | |||
;; | |||
openbsd_amd64) | |||
mkasm="go run mkasm.go" | |||
mkerrors="$mkerrors -m64" | |||
mksyscall="go run mksyscall.go -openbsd" | |||
mksysctl="./mksysctl_openbsd.pl" | |||
mksysnum="curl -s 'http://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_openbsd.pl" | |||
mksyscall="go run mksyscall.go -openbsd -libc" | |||
mksysctl="go run mksysctl_openbsd.go" | |||
mktypes="GOARCH=$GOARCH go tool cgo -godefs" | |||
;; | |||
openbsd_arm) | |||
mkasm="go run mkasm.go" | |||
mkerrors="$mkerrors" | |||
mksyscall="go run mksyscall.go -l32 -openbsd -arm" | |||
mksysctl="./mksysctl_openbsd.pl" | |||
mksysnum="curl -s 'http://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_openbsd.pl" | |||
mksyscall="go run mksyscall.go -l32 -openbsd -arm -libc" | |||
mksysctl="go run mksysctl_openbsd.go" | |||
# Let the type of C char be signed for making the bare syscall | |||
# API consistent across platforms. | |||
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char" | |||
;; | |||
openbsd_arm64) | |||
mkasm="go run mkasm.go" | |||
mkerrors="$mkerrors -m64" | |||
mksyscall="go run mksyscall.go -openbsd -libc" | |||
mksysctl="go run mksysctl_openbsd.go" | |||
# Let the type of C char be signed for making the bare syscall | |||
# API consistent across platforms. | |||
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char" | |||
;; | |||
openbsd_mips64) | |||
mkerrors="$mkerrors -m64" | |||
mksyscall="go run mksyscall.go -openbsd" | |||
mksysctl="go run mksysctl_openbsd.go" | |||
mksysnum="go run mksysnum.go 'https://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master'" | |||
# Let the type of C char be signed for making the bare syscall | |||
# API consistent across platforms. | |||
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char" | |||
;; | |||
openbsd_ppc64) | |||
mkasm="go run mkasm.go" | |||
mkerrors="$mkerrors -m64" | |||
mksyscall="go run mksyscall.go -openbsd -libc" | |||
mksysctl="go run mksysctl_openbsd.go" | |||
# Let the type of C char be signed for making the bare syscall | |||
# API consistent across platforms. | |||
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char" | |||
;; | |||
openbsd_riscv64) | |||
mkasm="go run mkasm.go" | |||
mkerrors="$mkerrors -m64" | |||
mksyscall="go run mksyscall.go -openbsd -libc" | |||
mksysctl="go run mksysctl_openbsd.go" | |||
# Let the type of C char be signed for making the bare syscall | |||
# API consistent across platforms. | |||
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char" | |||
;; | |||
solaris_amd64) | |||
mksyscall="./mksyscall_solaris.pl" | |||
mksyscall="go run mksyscall_solaris.go" | |||
mkerrors="$mkerrors -m64" | |||
mksysnum= | |||
mktypes="GOARCH=$GOARCH go tool cgo -godefs" | |||
;; | |||
illumos_amd64) | |||
mksyscall="go run mksyscall_solaris.go" | |||
mkerrors= | |||
mksysnum= | |||
mktypes="GOARCH=$GOARCH go tool cgo -godefs" | |||
;; | |||
*) | |||
echo 'unrecognized $GOOS_$GOARCH: ' "$GOOSARCH" 1>&2 | |||
exit 1 | |||
@@ -191,6 +232,11 @@ esac | |||
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 " ; | |||
elif [ "$GOOS" == "illumos" ]; then | |||
# illumos code generation requires a --illumos switch | |||
echo "$mksyscall -illumos -tags illumos,$GOARCH syscall_illumos.go |gofmt > zsyscall_illumos_$GOARCH.go"; | |||
# illumos implies solaris, so solaris code generation is also required | |||
echo "$mksyscall -tags solaris,$GOARCH syscall_solaris.go syscall_solaris_$GOARCH.go |gofmt >zsyscall_solaris_$GOARCH.go"; | |||
else | |||
echo "$mksyscall -tags $GOOS,$GOARCH $syscall_goos $GOOSARCH_in |gofmt >zsyscall_$GOOSARCH.go"; | |||
fi | |||
@@ -198,7 +244,6 @@ esac | |||
esac | |||
if [ -n "$mksysctl" ]; then echo "$mksysctl |gofmt >$zsysctl"; fi | |||
if [ -n "$mksysnum" ]; then echo "$mksysnum |gofmt >zsysnum_$GOOSARCH.go"; fi | |||
if [ -n "$mktypes" ]; then | |||
echo "$mktypes types_$GOOS.go | go run mkpost.go > ztypes_$GOOSARCH.go"; | |||
fi | |||
if [ -n "$mktypes" ]; then echo "$mktypes types_$GOOS.go | go run mkpost.go > ztypes_$GOOSARCH.go"; fi | |||
if [ -n "$mkasm" ]; then echo "$mkasm $GOOS $GOARCH"; fi | |||
) | $run |
@@ -17,12 +17,10 @@ if test -z "$GOARCH" -o -z "$GOOS"; then | |||
fi | |||
# Check that we are using the new build system if we should | |||
if [[ "$GOOS" = "linux" ]] && [[ "$GOARCH" != "sparc64" ]]; then | |||
if [[ "$GOLANG_SYS_BUILD" != "docker" ]]; then | |||
echo 1>&2 "In the new build system, mkerrors should not be called directly." | |||
echo 1>&2 "See README.md" | |||
exit 1 | |||
fi | |||
if [[ "$GOOS" = "linux" ]] && [[ "$GOLANG_SYS_BUILD" != "docker" ]]; then | |||
echo 1>&2 "In the Docker based build system, mkerrors should not be called directly." | |||
echo 1>&2 "See README.md" | |||
exit 1 | |||
fi | |||
if [[ "$GOOS" = "aix" ]]; then | |||
@@ -46,6 +44,7 @@ includes_AIX=' | |||
#include <sys/stropts.h> | |||
#include <sys/mman.h> | |||
#include <sys/poll.h> | |||
#include <sys/select.h> | |||
#include <sys/termio.h> | |||
#include <termios.h> | |||
#include <fcntl.h> | |||
@@ -55,21 +54,28 @@ includes_AIX=' | |||
includes_Darwin=' | |||
#define _DARWIN_C_SOURCE | |||
#define KERNEL | |||
#define KERNEL 1 | |||
#define _DARWIN_USE_64_BIT_INODE | |||
#define __APPLE_USE_RFC_3542 | |||
#include <stdint.h> | |||
#include <sys/attr.h> | |||
#include <sys/clonefile.h> | |||
#include <sys/kern_control.h> | |||
#include <sys/types.h> | |||
#include <sys/event.h> | |||
#include <sys/ptrace.h> | |||
#include <sys/select.h> | |||
#include <sys/socket.h> | |||
#include <sys/un.h> | |||
#include <sys/sockio.h> | |||
#include <sys/sys_domain.h> | |||
#include <sys/sysctl.h> | |||
#include <sys/mman.h> | |||
#include <sys/mount.h> | |||
#include <sys/utsname.h> | |||
#include <sys/wait.h> | |||
#include <sys/xattr.h> | |||
#include <sys/vsock.h> | |||
#include <net/bpf.h> | |||
#include <net/if.h> | |||
#include <net/if_types.h> | |||
@@ -77,11 +83,15 @@ includes_Darwin=' | |||
#include <netinet/in.h> | |||
#include <netinet/ip.h> | |||
#include <termios.h> | |||
// for backwards compatibility because moved TIOCREMOTE to Kernel.framework after MacOSX12.0.sdk. | |||
#define TIOCREMOTE 0x80047469 | |||
' | |||
includes_DragonFly=' | |||
#include <sys/types.h> | |||
#include <sys/event.h> | |||
#include <sys/select.h> | |||
#include <sys/socket.h> | |||
#include <sys/sockio.h> | |||
#include <sys/stat.h> | |||
@@ -92,6 +102,7 @@ includes_DragonFly=' | |||
#include <sys/ioctl.h> | |||
#include <net/bpf.h> | |||
#include <net/if.h> | |||
#include <net/if_clone.h> | |||
#include <net/if_types.h> | |||
#include <net/route.h> | |||
#include <netinet/in.h> | |||
@@ -104,8 +115,12 @@ includes_FreeBSD=' | |||
#include <sys/capsicum.h> | |||
#include <sys/param.h> | |||
#include <sys/types.h> | |||
#include <sys/disk.h> | |||
#include <sys/event.h> | |||
#include <sys/sched.h> | |||
#include <sys/select.h> | |||
#include <sys/socket.h> | |||
#include <sys/un.h> | |||
#include <sys/sockio.h> | |||
#include <sys/stat.h> | |||
#include <sys/sysctl.h> | |||
@@ -113,6 +128,7 @@ includes_FreeBSD=' | |||
#include <sys/mount.h> | |||
#include <sys/wait.h> | |||
#include <sys/ioctl.h> | |||
#include <sys/ptrace.h> | |||
#include <net/bpf.h> | |||
#include <net/if.h> | |||
#include <net/if_types.h> | |||
@@ -181,49 +197,89 @@ struct ltchars { | |||
#include <sys/stat.h> | |||
#include <sys/types.h> | |||
#include <sys/time.h> | |||
#include <sys/select.h> | |||
#include <sys/signalfd.h> | |||
#include <sys/socket.h> | |||
#include <sys/timerfd.h> | |||
#include <sys/uio.h> | |||
#include <sys/xattr.h> | |||
#include <linux/audit.h> | |||
#include <linux/bpf.h> | |||
#include <linux/can.h> | |||
#include <linux/can/error.h> | |||
#include <linux/can/netlink.h> | |||
#include <linux/can/raw.h> | |||
#include <linux/capability.h> | |||
#include <linux/cryptouser.h> | |||
#include <linux/devlink.h> | |||
#include <linux/dm-ioctl.h> | |||
#include <linux/errqueue.h> | |||
#include <linux/ethtool_netlink.h> | |||
#include <linux/falloc.h> | |||
#include <linux/fanotify.h> | |||
#include <linux/fib_rules.h> | |||
#include <linux/filter.h> | |||
#include <linux/fs.h> | |||
#include <linux/fscrypt.h> | |||
#include <linux/fsverity.h> | |||
#include <linux/genetlink.h> | |||
#include <linux/hdreg.h> | |||
#include <linux/hidraw.h> | |||
#include <linux/if.h> | |||
#include <linux/if_addr.h> | |||
#include <linux/if_alg.h> | |||
#include <linux/if_arp.h> | |||
#include <linux/if_ether.h> | |||
#include <linux/if_ppp.h> | |||
#include <linux/if_tun.h> | |||
#include <linux/if_packet.h> | |||
#include <linux/if_addr.h> | |||
#include <linux/falloc.h> | |||
#include <linux/filter.h> | |||
#include <linux/fs.h> | |||
#include <linux/if_xdp.h> | |||
#include <linux/input.h> | |||
#include <linux/kcm.h> | |||
#include <linux/kexec.h> | |||
#include <linux/keyctl.h> | |||
#include <linux/landlock.h> | |||
#include <linux/loop.h> | |||
#include <linux/lwtunnel.h> | |||
#include <linux/magic.h> | |||
#include <linux/memfd.h> | |||
#include <linux/module.h> | |||
#include <linux/mount.h> | |||
#include <linux/netfilter/nfnetlink.h> | |||
#include <linux/netlink.h> | |||
#include <linux/net_namespace.h> | |||
#include <linux/nfc.h> | |||
#include <linux/nsfs.h> | |||
#include <linux/perf_event.h> | |||
#include <linux/pps.h> | |||
#include <linux/ptrace.h> | |||
#include <linux/random.h> | |||
#include <linux/reboot.h> | |||
#include <linux/rtc.h> | |||
#include <linux/rtnetlink.h> | |||
#include <linux/ptrace.h> | |||
#include <linux/sched.h> | |||
#include <linux/seccomp.h> | |||
#include <linux/sockios.h> | |||
#include <linux/wait.h> | |||
#include <linux/icmpv6.h> | |||
#include <linux/serial.h> | |||
#include <linux/can.h> | |||
#include <linux/vm_sockets.h> | |||
#include <linux/sockios.h> | |||
#include <linux/taskstats.h> | |||
#include <linux/genetlink.h> | |||
#include <linux/tipc.h> | |||
#include <linux/vm_sockets.h> | |||
#include <linux/wait.h> | |||
#include <linux/watchdog.h> | |||
#include <linux/hdreg.h> | |||
#include <linux/rtc.h> | |||
#include <linux/if_xdp.h> | |||
#include <linux/wireguard.h> | |||
#include <mtd/ubi-user.h> | |||
#include <mtd/mtd-user.h> | |||
#include <net/route.h> | |||
#if defined(__sparc__) | |||
// On sparc{,64}, the kernel defines struct termios2 itself which clashes with the | |||
// definition in glibc. As only the error constants are needed here, include the | |||
// generic termibits.h (which is included by termbits.h on sparc). | |||
#include <asm-generic/termbits.h> | |||
#else | |||
#include <asm/termbits.h> | |||
#endif | |||
#ifndef MSG_FASTOPEN | |||
#define MSG_FASTOPEN 0x20000000 | |||
@@ -241,6 +297,10 @@ struct ltchars { | |||
#define SOL_NETLINK 270 | |||
#endif | |||
#ifndef SOL_SMC | |||
#define SOL_SMC 286 | |||
#endif | |||
#ifdef SOL_BLUETOOTH | |||
// SPARC includes this in /usr/include/sparc64-linux-gnu/bits/socket.h | |||
// but it is already in bluetooth_linux.go | |||
@@ -252,15 +312,26 @@ struct ltchars { | |||
#define FS_KEY_DESC_PREFIX_SIZE 8 | |||
#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 | |||
// The code generator produces -0x1 for (~0), but an unsigned value is necessary | |||
// for the tipc_subscr timeout __u32 field. | |||
#undef TIPC_WAIT_FOREVER | |||
#define TIPC_WAIT_FOREVER 0xffffffff | |||
// Copied from linux/l2tp.h | |||
// Including linux/l2tp.h here causes conflicts between linux/in.h | |||
// and netinet/in.h included via net/route.h above. | |||
#define IPPROTO_L2TP 115 | |||
// Copied from linux/hid.h. | |||
// Keep in sync with the size of the referenced fields. | |||
#define _HIDIOCGRAWNAME_LEN 128 // sizeof_field(struct hid_device, name) | |||
#define _HIDIOCGRAWPHYS_LEN 64 // sizeof_field(struct hid_device, phys) | |||
#define _HIDIOCGRAWUNIQ_LEN 64 // sizeof_field(struct hid_device, uniq) | |||
#define _HIDIOCGRAWNAME HIDIOCGRAWNAME(_HIDIOCGRAWNAME_LEN) | |||
#define _HIDIOCGRAWPHYS HIDIOCGRAWPHYS(_HIDIOCGRAWPHYS_LEN) | |||
#define _HIDIOCGRAWUNIQ HIDIOCGRAWUNIQ(_HIDIOCGRAWUNIQ_LEN) | |||
#ifndef AF_XDP | |||
#define AF_XDP 44 | |||
#endif | |||
' | |||
includes_NetBSD=' | |||
@@ -270,6 +341,8 @@ includes_NetBSD=' | |||
#include <sys/extattr.h> | |||
#include <sys/mman.h> | |||
#include <sys/mount.h> | |||
#include <sys/sched.h> | |||
#include <sys/select.h> | |||
#include <sys/socket.h> | |||
#include <sys/sockio.h> | |||
#include <sys/sysctl.h> | |||
@@ -296,6 +369,8 @@ includes_OpenBSD=' | |||
#include <sys/event.h> | |||
#include <sys/mman.h> | |||
#include <sys/mount.h> | |||
#include <sys/select.h> | |||
#include <sys/sched.h> | |||
#include <sys/socket.h> | |||
#include <sys/sockio.h> | |||
#include <sys/stat.h> | |||
@@ -332,9 +407,11 @@ includes_OpenBSD=' | |||
includes_SunOS=' | |||
#include <limits.h> | |||
#include <sys/types.h> | |||
#include <sys/select.h> | |||
#include <sys/socket.h> | |||
#include <sys/sockio.h> | |||
#include <sys/stat.h> | |||
#include <sys/stream.h> | |||
#include <sys/mman.h> | |||
#include <sys/wait.h> | |||
#include <sys/ioctl.h> | |||
@@ -344,10 +421,11 @@ includes_SunOS=' | |||
#include <net/if_arp.h> | |||
#include <net/if_types.h> | |||
#include <net/route.h> | |||
#include <netinet/icmp6.h> | |||
#include <netinet/in.h> | |||
#include <termios.h> | |||
#include <netinet/ip.h> | |||
#include <netinet/ip_mroute.h> | |||
#include <termios.h> | |||
' | |||
@@ -402,6 +480,7 @@ ccflags="$@" | |||
$2 !~ /^EPROC_/ && | |||
$2 !~ /^EQUIV_/ && | |||
$2 !~ /^EXPR_/ && | |||
$2 !~ /^EVIOC/ && | |||
$2 ~ /^E[A-Z0-9_]+$/ || | |||
$2 ~ /^B[0-9_]+$/ || | |||
$2 ~ /^(OLD|NEW)DEV$/ || | |||
@@ -424,6 +503,7 @@ ccflags="$@" | |||
$2 == "XCASE" || | |||
$2 == "ALTWERASE" || | |||
$2 == "NOKERNINFO" || | |||
$2 == "NFDBITS" || | |||
$2 ~ /^PAR/ || | |||
$2 ~ /^SIG[^_]/ || | |||
$2 ~ /^O[CNPFPL][A-Z]+[^_][A-Z]+$/ || | |||
@@ -432,11 +512,18 @@ ccflags="$@" | |||
$2 ~ /^O?XTABS$/ || | |||
$2 ~ /^TC[IO](ON|OFF)$/ || | |||
$2 ~ /^IN_/ || | |||
$2 ~ /^KCM/ || | |||
$2 ~ /^LANDLOCK_/ || | |||
$2 ~ /^LOCK_(SH|EX|NB|UN)$/ || | |||
$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 ~ /^LO_(KEY|NAME)_SIZE$/ || | |||
$2 ~ /^LOOP_(CLR|CTL|GET|SET)_/ || | |||
$2 ~ /^(AF|SOCK|SO|SOL|IPPROTO|IP|IPV6|TCP|MCAST|EVFILT|NOTE|SHUT|PROT|MAP|MFD|T?PACKET|MSG|SCM|MCL|DT|MADV|PR|LOCAL|TCPOPT)_/ || | |||
$2 ~ /^NFC_(GENL|PROTO|COMM|RF|SE|DIRECTION|LLCP|SOCKPROTO)_/ || | |||
$2 ~ /^NFC_.*_(MAX)?SIZE$/ || | |||
$2 ~ /^RAW_PAYLOAD_/ || | |||
$2 ~ /^TP_STATUS_/ || | |||
$2 ~ /^FALLOC_/ || | |||
$2 == "ICMPV6_FILTER" || | |||
$2 ~ /^ICMPV?6?_(FILTER|SEC)/ || | |||
$2 == "SOMAXCONN" || | |||
$2 == "NAME_MAX" || | |||
$2 == "IFNAMSIZ" || | |||
@@ -445,42 +532,56 @@ ccflags="$@" | |||
$2 ~ /^HW_MACHINE$/ || | |||
$2 ~ /^SYSCTL_VERS/ || | |||
$2 !~ "MNT_BITS" && | |||
$2 ~ /^(MS|MNT|UMOUNT)_/ || | |||
$2 ~ /^(MS|MNT|MOUNT|UMOUNT)_/ || | |||
$2 ~ /^NS_GET_/ || | |||
$2 ~ /^TUN(SET|GET|ATTACH|DETACH)/ || | |||
$2 ~ /^(O|F|E?FD|NAME|S|PTRACE|PT)_/ || | |||
$2 ~ /^(O|F|[ES]?FD|NAME|S|PTRACE|PT|PIOD|TFD)_/ || | |||
$2 ~ /^KEXEC_/ || | |||
$2 ~ /^LINUX_REBOOT_CMD_/ || | |||
$2 ~ /^LINUX_REBOOT_MAGIC[12]$/ || | |||
$2 ~ /^MODULE_INIT_/ || | |||
$2 !~ "NLA_TYPE_MASK" && | |||
$2 !~ /^RTC_VL_(ACCURACY|BACKUP|DATA)/ && | |||
$2 ~ /^(NETLINK|NLM|NLMSG|NLA|IFA|IFAN|RT|RTC|RTCF|RTN|RTPROT|RTNH|ARPHRD|ETH_P|NETNSA)_/ || | |||
$2 ~ /^FIORDCHK$/ || | |||
$2 ~ /^SIOC/ || | |||
$2 ~ /^TIOC/ || | |||
$2 ~ /^TCGET/ || | |||
$2 ~ /^TCSET/ || | |||
$2 ~ /^TC(FLSH|SBRKP?|XONC)$/ || | |||
$2 !~ "RTF_BITS" && | |||
$2 ~ /^(IFF|IFT|NET_RT|RTM|RTF|RTV|RTA|RTAX)_/ || | |||
$2 ~ /^(IFF|IFT|NET_RT|RTM(GRP)?|RTF|RTV|RTA|RTAX)_/ || | |||
$2 ~ /^BIOC/ || | |||
$2 ~ /^DIOC/ || | |||
$2 ~ /^RUSAGE_(SELF|CHILDREN|THREAD)/ || | |||
$2 ~ /^RLIMIT_(AS|CORE|CPU|DATA|FSIZE|LOCKS|MEMLOCK|MSGQUEUE|NICE|NOFILE|NPROC|RSS|RTPRIO|RTTIME|SIGPENDING|STACK)|RLIM_INFINITY/ || | |||
$2 ~ /^PRIO_(PROCESS|PGRP|USER)/ || | |||
$2 ~ /^CLONE_[A-Z_]+/ || | |||
$2 !~ /^(BPF_TIMEVAL)$/ && | |||
$2 !~ /^(BPF_TIMEVAL|BPF_FIB_LOOKUP_[A-Z]+)$/ && | |||
$2 ~ /^(BPF|DLT)_/ || | |||
$2 ~ /^CLOCK_/ || | |||
$2 ~ /^AUDIT_/ || | |||
$2 ~ /^(CLOCK|TIMER)_/ || | |||
$2 ~ /^CAN_/ || | |||
$2 ~ /^CAP_/ || | |||
$2 ~ /^CP_/ || | |||
$2 ~ /^CPUSTATES$/ || | |||
$2 ~ /^CTLIOCGINFO$/ || | |||
$2 ~ /^ALG_/ || | |||
$2 ~ /^FS_(POLICY_FLAGS|KEY_DESC|ENCRYPTION_MODE|[A-Z0-9_]+_KEY_SIZE|IOC_(GET|SET)_ENCRYPTION)/ || | |||
$2 ~ /^FI(CLONE|DEDUPERANGE)/ || | |||
$2 ~ /^FS_(POLICY_FLAGS|KEY_DESC|ENCRYPTION_MODE|[A-Z0-9_]+_KEY_SIZE)/ || | |||
$2 ~ /^FS_IOC_.*(ENCRYPTION|VERITY|[GS]ETFLAGS)/ || | |||
$2 ~ /^FS_VERITY_/ || | |||
$2 ~ /^FSCRYPT_/ || | |||
$2 ~ /^DM_/ || | |||
$2 ~ /^GRND_/ || | |||
$2 ~ /^RND/ || | |||
$2 ~ /^KEY_(SPEC|REQKEY_DEFL)_/ || | |||
$2 ~ /^KEYCTL_/ || | |||
$2 ~ /^PERF_EVENT_IOC_/ || | |||
$2 ~ /^PERF_/ || | |||
$2 ~ /^SECCOMP_MODE_/ || | |||
$2 ~ /^SEEK_/ || | |||
$2 ~ /^SPLICE_/ || | |||
$2 ~ /^SYNC_FILE_RANGE_/ || | |||
$2 !~ /^AUDIT_RECORD_MAGIC/ && | |||
$2 !~ /IOC_MAGIC/ && | |||
$2 ~ /^[A-Z][A-Z0-9_]+_MAGIC2?$/ || | |||
$2 ~ /^(VM|VMADDR)_/ || | |||
@@ -495,13 +596,31 @@ ccflags="$@" | |||
$2 ~ /^XATTR_(CREATE|REPLACE|NO(DEFAULT|FOLLOW|SECURITY)|SHOWCOMPRESSION)/ || | |||
$2 ~ /^ATTR_(BIT_MAP_COUNT|(CMN|VOL|FILE)_)/ || | |||
$2 ~ /^FSOPT_/ || | |||
$2 ~ /^WDIOC_/ || | |||
$2 ~ /^WDIO[CFS]_/ || | |||
$2 ~ /^NFN/ || | |||
$2 ~ /^XDP_/ || | |||
$2 ~ /^RWF_/ || | |||
$2 ~ /^(HDIO|WIN|SMART)_/ || | |||
$2 ~ /^CRYPTO_/ || | |||
$2 ~ /^TIPC_/ || | |||
$2 !~ "DEVLINK_RELOAD_LIMITS_VALID_MASK" && | |||
$2 ~ /^DEVLINK_/ || | |||
$2 ~ /^ETHTOOL_/ || | |||
$2 ~ /^LWTUNNEL_IP/ || | |||
$2 ~ /^ITIMER_/ || | |||
$2 !~ "WMESGLEN" && | |||
$2 ~ /^W[A-Z0-9]+$/ || | |||
$2 ~ /^P_/ || | |||
$2 ~/^PPPIOC/ || | |||
$2 ~ /^FAN_|FANOTIFY_/ || | |||
$2 == "HID_MAX_DESCRIPTOR_SIZE" || | |||
$2 ~ /^_?HIDIOC/ || | |||
$2 ~ /^BUS_(USB|HIL|BLUETOOTH|VIRTUAL)$/ || | |||
$2 ~ /^MTD/ || | |||
$2 ~ /^OTP/ || | |||
$2 ~ /^MEM/ || | |||
$2 ~ /^WG/ || | |||
$2 ~ /^FIB_RULE_/ || | |||
$2 ~ /^BLK[A-Z]*(GET$|SET$|BUF$|PART$|SIZE)/ {printf("\t%s = C.%s\n", $2, $2)} | |||
$2 ~ /^__WCOREFLAG$/ {next} | |||
$2 ~ /^__W[A-Z0-9]+$/ {printf("\t%s = C.%s\n", substr($2,3), $2)} | |||
@@ -523,7 +642,7 @@ errors=$( | |||
signals=$( | |||
echo '#include <signal.h>' | $CC -x c - -E -dM $ccflags | | |||
awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print $2 }' | | |||
egrep -v '(SIGSTKSIZE|SIGSTKSZ|SIGRT|SIGMAX64)' | | |||
grep -v 'SIGSTKSIZE\|SIGSTKSZ\|SIGRT\|SIGMAX64' | | |||
sort | |||
) | |||
@@ -533,12 +652,13 @@ echo '#include <errno.h>' | $CC -x c - -E -dM $ccflags | | |||
sort >_error.grep | |||
echo '#include <signal.h>' | $CC -x c - -E -dM $ccflags | | |||
awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print "^\t" $2 "[ \t]*=" }' | | |||
egrep -v '(SIGSTKSIZE|SIGSTKSZ|SIGRT|SIGMAX64)' | | |||
grep -v 'SIGSTKSIZE\|SIGSTKSZ\|SIGRT\|SIGMAX64' | | |||
sort >_signal.grep | |||
echo '// mkerrors.sh' "$@" | |||
echo '// Code generated by the command above; see README.md. DO NOT EDIT.' | |||
echo | |||
echo "//go:build ${GOARCH} && ${GOOS}" | |||
echo "// +build ${GOARCH},${GOOS}" | |||
echo | |||
go tool cgo -godefs -- "$@" _const.go >_error.out | |||
@@ -1,384 +0,0 @@ | |||
#!/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; |
@@ -1,579 +0,0 @@ | |||
#!/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 | |||
# This program will generate three files and handle both gc and gccgo implementation: | |||
# - zsyscall_aix_ppc64.go: the common part of each implementation (error handler, pointer creation) | |||
# - zsyscall_aix_ppc64_gc.go: gc part with //go_cgo_import_dynamic and a call to syscall6 | |||
# - zsyscall_aix_ppc64_gccgo.go: gccgo part with C function and conversion to C type. | |||
# The generated code looks like this | |||
# | |||
# zsyscall_aix_ppc64.go | |||
# func asyscall(...) (n int, err error) { | |||
# // Pointer Creation | |||
# r1, e1 := callasyscall(...) | |||
# // Type Conversion | |||
# // Error Handler | |||
# return | |||
# } | |||
# | |||
# zsyscall_aix_ppc64_gc.go | |||
# //go:cgo_import_dynamic libc_asyscall asyscall "libc.a/shr_64.o" | |||
# //go:linkname libc_asyscall libc_asyscall | |||
# var asyscall syscallFunc | |||
# | |||
# func callasyscall(...) (r1 uintptr, e1 Errno) { | |||
# r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_asyscall)), "nb_args", ... ) | |||
# return | |||
# } | |||
# | |||
# zsyscall_aix_ppc64_ggcgo.go | |||
# /* | |||
# int asyscall(...) | |||
# | |||
# */ | |||
# import "C" | |||
# | |||
# func callasyscall(...) (r1 uintptr, e1 Errno) { | |||
# r1 = uintptr(C.asyscall(...)) | |||
# e1 = syscall.GetErrno() | |||
# return | |||
# } | |||
use strict; | |||
my $cmdline = "mksyscall_aix_ppc64.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 = ""; | |||
# GCCGO | |||
my $textgccgo = ""; | |||
my $c_extern = "/*\n#include <stdint.h>\n"; | |||
# GC | |||
my $textgc = ""; | |||
my $dynimports = ""; | |||
my $linknames = ""; | |||
my @vars = (); | |||
# COMMUN | |||
my $textcommon = ""; | |||
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); | |||
if($sysname eq "") { | |||
$sysname = "$func"; | |||
} | |||
my $onlyCommon = 0; | |||
if ($func eq "readlen" || $func eq "writelen" || $func eq "FcntlInt" || $func eq "FcntlFlock") { | |||
# This function call another syscall which is already implemented. | |||
# Therefore, the gc and gccgo part must not be generated. | |||
$onlyCommon = 1 | |||
} | |||
# 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. | |||
$textcommon .= "// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\n"; | |||
if (!$onlyCommon) { | |||
$textgccgo .= "// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\n"; | |||
$textgc .= "// 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; | |||
} | |||
} | |||
$sysname =~ s/([a-z])([A-Z])/${1}_$2/g; | |||
$sysname =~ y/A-Z/a-z/; # All libc functions are lowercase. | |||
# GCCGO Prototype return type | |||
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"; | |||
} | |||
# GCCGO Prototype arguments type | |||
my @c_in = (); | |||
foreach my $i (0 .. $#in) { | |||
my ($name, $type) = parseparam($in[$i]); | |||
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") { | |||
if (($i == 0 || $i == 2) && $func eq "fcntl"){ | |||
# These fcntl arguments needs to be uintptr to be able to call FcntlInt and FcntlFlock | |||
push @c_in, "uintptr_t"; | |||
} else { | |||
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 (!$onlyCommon){ | |||
# GCCGO Prototype Generation | |||
# Imports of system calls from libc | |||
$c_extern .= "$C_rettype $sysname"; | |||
my $c_in = join(', ', @c_in); | |||
$c_extern .= "($c_in);\n"; | |||
} | |||
# GC Library name | |||
if($modname eq "") { | |||
$modname = "libc.a/shr_64.o"; | |||
} else { | |||
print STDERR "$func: only syscall using libc are available\n"; | |||
$errors = 1; | |||
next; | |||
} | |||
my $sysvarname = "libc_${sysname}"; | |||
if (!$onlyCommon){ | |||
# GC Runtime import of function to allow cross-platform builds. | |||
$dynimports .= "//go:cgo_import_dynamic ${sysvarname} ${sysname} \"$modname\"\n"; | |||
# GC Link symbol to proc address variable. | |||
$linknames .= "//go:linkname ${sysvarname} ${sysvarname}\n"; | |||
# GC Library proc address variable. | |||
push @vars, $sysvarname; | |||
} | |||
my $strconvfunc ="BytePtrFromString"; | |||
my $strconvtype = "*byte"; | |||
# Go function header. | |||
if($out ne "") { | |||
$out = " ($out)"; | |||
} | |||
if($textcommon ne "") { | |||
$textcommon .= "\n" | |||
} | |||
$textcommon .= sprintf "func %s(%s)%s {\n", $func, join(', ', @in), $out ; | |||
# Prepare arguments to call. | |||
my @argscommun = (); # Arguments in the commun part | |||
my @argscall = (); # Arguments for call prototype | |||
my @argsgc = (); # Arguments for gc call (with syscall6) | |||
my @argsgccgo = (); # Arguments for gccgo call (with C.name_of_syscall) | |||
my $n = 0; | |||
my $arg_n = 0; | |||
foreach my $p (@in) { | |||
my ($name, $type) = parseparam($p); | |||
if($type =~ /^\*/) { | |||
push @argscommun, "uintptr(unsafe.Pointer($name))"; | |||
push @argscall, "$name uintptr"; | |||
push @argsgc, "$name"; | |||
push @argsgccgo, "C.uintptr_t($name)"; | |||
} elsif($type eq "string" && $errvar ne "") { | |||
$textcommon .= "\tvar _p$n $strconvtype\n"; | |||
$textcommon .= "\t_p$n, $errvar = $strconvfunc($name)\n"; | |||
$textcommon .= "\tif $errvar != nil {\n\t\treturn\n\t}\n"; | |||
push @argscommun, "uintptr(unsafe.Pointer(_p$n))"; | |||
push @argscall, "_p$n uintptr "; | |||
push @argsgc, "_p$n"; | |||
push @argsgccgo, "C.uintptr_t(_p$n)"; | |||
$n++; | |||
} elsif($type eq "string") { | |||
print STDERR "$ARGV:$.: $func uses string arguments, but has no error return\n"; | |||
$textcommon .= "\tvar _p$n $strconvtype\n"; | |||
$textcommon .= "\t_p$n, $errvar = $strconvfunc($name)\n"; | |||
$textcommon .= "\tif $errvar != nil {\n\t\treturn\n\t}\n"; | |||
push @argscommun, "uintptr(unsafe.Pointer(_p$n))"; | |||
push @argscall, "_p$n uintptr"; | |||
push @argsgc, "_p$n"; | |||
push @argsgccgo, "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. | |||
$textcommon .= "\tvar _p$n *$1\n"; | |||
$textcommon .= "\tif len($name) > 0 {\n\t\t_p$n = \&$name\[0]\n\t}\n"; | |||
push @argscommun, "uintptr(unsafe.Pointer(_p$n))", "len($name)"; | |||
push @argscall, "_p$n uintptr", "_lenp$n int"; | |||
push @argsgc, "_p$n", "uintptr(_lenp$n)"; | |||
push @argsgccgo, "C.uintptr_t(_p$n)", "C.size_t(_lenp$n)"; | |||
$n++; | |||
} elsif($type eq "int64" && $_32bit ne "") { | |||
print STDERR "$ARGV:$.: $func uses int64 with 32 bits mode. Case not yet implemented\n"; | |||
# 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") { | |||
print STDERR "$ARGV:$.: $func uses bool. Case not yet implemented\n"; | |||
# $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 =~ /^_/ ||$type eq "unsafe.Pointer") { | |||
push @argscommun, "uintptr($name)"; | |||
push @argscall, "$name uintptr"; | |||
push @argsgc, "$name"; | |||
push @argsgccgo, "C.uintptr_t($name)"; | |||
} elsif($type eq "int") { | |||
if (($arg_n == 0 || $arg_n == 2) && ($func eq "fcntl" || $func eq "FcntlInt" || $func eq "FcntlFlock")) { | |||
# These fcntl arguments need to be uintptr to be able to call FcntlInt and FcntlFlock | |||
push @argscommun, "uintptr($name)"; | |||
push @argscall, "$name uintptr"; | |||
push @argsgc, "$name"; | |||
push @argsgccgo, "C.uintptr_t($name)"; | |||
} else { | |||
push @argscommun, "$name"; | |||
push @argscall, "$name int"; | |||
push @argsgc, "uintptr($name)"; | |||
push @argsgccgo, "C.int($name)"; | |||
} | |||
} elsif($type eq "int32") { | |||
push @argscommun, "$name"; | |||
push @argscall, "$name int32"; | |||
push @argsgc, "uintptr($name)"; | |||
push @argsgccgo, "C.int($name)"; | |||
} elsif($type eq "int64") { | |||
push @argscommun, "$name"; | |||
push @argscall, "$name int64"; | |||
push @argsgc, "uintptr($name)"; | |||
push @argsgccgo, "C.longlong($name)"; | |||
} elsif($type eq "uint32") { | |||
push @argscommun, "$name"; | |||
push @argscall, "$name uint32"; | |||
push @argsgc, "uintptr($name)"; | |||
push @argsgccgo, "C.uint($name)"; | |||
} elsif($type eq "uint64") { | |||
push @argscommun, "$name"; | |||
push @argscall, "$name uint64"; | |||
push @argsgc, "uintptr($name)"; | |||
push @argsgccgo, "C.ulonglong($name)"; | |||
} elsif($type eq "uintptr") { | |||
push @argscommun, "$name"; | |||
push @argscall, "$name uintptr"; | |||
push @argsgc, "$name"; | |||
push @argsgccgo, "C.uintptr_t($name)"; | |||
} else { | |||
push @argscommun, "int($name)"; | |||
push @argscall, "$name int"; | |||
push @argsgc, "uintptr($name)"; | |||
push @argsgccgo, "C.int($name)"; | |||
} | |||
$arg_n++; | |||
} | |||
my $nargs = @argsgc; | |||
# COMMUN function generation | |||
my $argscommun = join(', ', @argscommun); | |||
my $callcommun = "call$sysname($argscommun)"; | |||
my @ret = ("_", "_"); | |||
my $body = ""; | |||
my $do_errno = 0; | |||
for(my $i=0; $i<@out; $i++) { | |||
my $p = $out[$i]; | |||
my ($name, $type) = parseparam($p); | |||
my $reg = ""; | |||
if($name eq "err") { | |||
$reg = "e1"; | |||
$ret[1] = $reg; | |||
$do_errno = 1; | |||
} else { | |||
$reg = "r0"; | |||
$ret[0] = $reg; | |||
} | |||
if($type eq "bool") { | |||
$reg = "$reg != 0"; | |||
} | |||
if($reg ne "e1") { | |||
$body .= "\t$name = $type($reg)\n"; | |||
} | |||
} | |||
if ($ret[0] eq "_" && $ret[1] eq "_") { | |||
$textcommon .= "\t$callcommun\n"; | |||
} else { | |||
$textcommon .= "\t$ret[0], $ret[1] := $callcommun\n"; | |||
} | |||
$textcommon .= $body; | |||
if ($do_errno) { | |||
$textcommon .= "\tif e1 != 0 {\n"; | |||
$textcommon .= "\t\terr = errnoErr(e1)\n"; | |||
$textcommon .= "\t}\n"; | |||
} | |||
$textcommon .= "\treturn\n"; | |||
$textcommon .= "}\n"; | |||
if ($onlyCommon){ | |||
next | |||
} | |||
# CALL Prototype | |||
my $callProto = sprintf "func call%s(%s) (r1 uintptr, e1 Errno) {\n", $sysname, join(', ', @argscall); | |||
# GC function generation | |||
my $asm = "syscall6"; | |||
if ($nonblock) { | |||
$asm = "rawSyscall6"; | |||
} | |||
if(@argsgc <= 6) { | |||
while(@argsgc < 6) { | |||
push @argsgc, "0"; | |||
} | |||
} else { | |||
print STDERR "$ARGV:$.: too many arguments to system call\n"; | |||
} | |||
my $argsgc = join(', ', @argsgc); | |||
my $callgc = "$asm(uintptr(unsafe.Pointer(&$sysvarname)), $nargs, $argsgc)"; | |||
$textgc .= $callProto; | |||
$textgc .= "\tr1, _, e1 = $callgc\n"; | |||
$textgc .= "\treturn\n}\n"; | |||
# GCCGO function generation | |||
my $argsgccgo = join(', ', @argsgccgo); | |||
my $callgccgo = "C.$sysname($argsgccgo)"; | |||
$textgccgo .= $callProto; | |||
$textgccgo .= "\tr1 = uintptr($callgccgo)\n"; | |||
$textgccgo .= "\te1 = syscall.GetErrno()\n"; | |||
$textgccgo .= "\treturn\n}\n"; | |||
} | |||
if($errors) { | |||
exit 1; | |||
} | |||
# Print zsyscall_aix_ppc64.go | |||
open(my $fcommun, '>', 'zsyscall_aix_ppc64.go'); | |||
my $tofcommun = <<EOF; | |||
// $cmdline | |||
// Code generated by the command above; see README.md. DO NOT EDIT. | |||
// +build $tags | |||
package $package | |||
import ( | |||
"unsafe" | |||
) | |||
EOF | |||
$tofcommun .= "import \"golang.org/x/sys/unix\"\n" if $package ne "unix"; | |||
$tofcommun .=<<EOF; | |||
$textcommon | |||
EOF | |||
print $fcommun $tofcommun; | |||
# Print zsyscall_aix_ppc64_gc.go | |||
open(my $fgc, '>', 'zsyscall_aix_ppc64_gc.go'); | |||
my $tofgc = <<EOF; | |||
// $cmdline | |||
// Code generated by the command above; see README.md. DO NOT EDIT. | |||
// +build $tags | |||
// +build !gccgo | |||
package $package | |||
import ( | |||
"unsafe" | |||
) | |||
EOF | |||
$tofgc .= "import \"golang.org/x/sys/unix\"\n" if $package ne "unix"; | |||
my $vardecls = "\t" . join(",\n\t", @vars); | |||
$vardecls .= " syscallFunc"; | |||
$tofgc .=<<EOF; | |||
$dynimports | |||
$linknames | |||
type syscallFunc uintptr | |||
var ( | |||
$vardecls | |||
) | |||
// Implemented in runtime/syscall_aix.go. | |||
func rawSyscall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) | |||
func syscall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) | |||
$textgc | |||
EOF | |||
print $fgc $tofgc; | |||
# Print zsyscall_aix_ppc64_gc.go | |||
open(my $fgccgo, '>', 'zsyscall_aix_ppc64_gccgo.go'); | |||
my $tofgccgo = <<EOF; | |||
// $cmdline | |||
// Code generated by the command above; see README.md. DO NOT EDIT. | |||
// +build $tags | |||
// +build gccgo | |||
package $package | |||
$c_extern | |||
*/ | |||
import "C" | |||
import ( | |||
"syscall" | |||
) | |||
EOF | |||
$tofgccgo .= "import \"golang.org/x/sys/unix\"\n" if $package ne "unix"; | |||
$tofgccgo .=<<EOF; | |||
$textgccgo | |||
EOF | |||
print $fgccgo $tofgccgo; | |||
exit 0; |
@@ -1,294 +0,0 @@ | |||
#!/usr/bin/env perl | |||
# Copyright 2009 The Go Authors. All rights reserved. | |||
# Use of this source code is governed by a BSD-style | |||
# license that can be found in the LICENSE file. | |||
# This program reads a file containing function prototypes | |||
# (like syscall_solaris.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_solaris.pl " . join(' ', @ARGV); | |||
my $errors = 0; | |||
my $_32bit = ""; | |||
my $tags = ""; # build tags | |||
binmode STDOUT; | |||
if($ARGV[0] eq "-b32") { | |||
$_32bit = "big-endian"; | |||
shift; | |||
} elsif($ARGV[0] eq "-l32") { | |||
$_32bit = "little-endian"; | |||
shift; | |||
} | |||
if($ARGV[0] eq "-tags") { | |||
shift; | |||
$tags = $ARGV[0]; | |||
shift; | |||
} | |||
if($ARGV[0] =~ /^-/) { | |||
print STDERR "usage: mksyscall_solaris.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 $dynimports = ""; | |||
my $linknames = ""; | |||
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); | |||
# 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. | |||
if($modname eq "") { | |||
$modname = "libc"; | |||
} | |||
# System call name. | |||
if($sysname eq "") { | |||
$sysname = "$func"; | |||
} | |||
# System call pointer variable name. | |||
my $sysvarname = "proc$sysname"; | |||
my $strconvfunc = "BytePtrFromString"; | |||
my $strconvtype = "*byte"; | |||
$sysname =~ y/A-Z/a-z/; # All libc functions are lowercase. | |||
# Runtime import of function to allow cross-platform builds. | |||
$dynimports .= "//go:cgo_import_dynamic libc_${sysname} ${sysname} \"$modname.so\"\n"; | |||
# Link symbol to proc address variable. | |||
$linknames .= "//go:linkname ${sysvarname} libc_${sysname}\n"; | |||
# Library proc address variable. | |||
push @vars, $sysvarname; | |||
# Go function header. | |||
$out = join(', ', @out); | |||
if($out ne "") { | |||
$out = " ($out)"; | |||
} | |||
if($text ne "") { | |||
$text .= "\n" | |||
} | |||
$text .= sprintf "func %s(%s)%s {\n", $func, join(', ', @in), $out; | |||
# Check if err return available | |||
my $errvar = ""; | |||
foreach my $p (@out) { | |||
my ($name, $type) = parseparam($p); | |||
if($type eq "error") { | |||
$errvar = $name; | |||
last; | |||
} | |||
} | |||
# Prepare arguments to Syscall. | |||
my @args = (); | |||
my $n = 0; | |||
foreach my $p (@in) { | |||
my ($name, $type) = parseparam($p); | |||
if($type =~ /^\*/) { | |||
push @args, "uintptr(unsafe.Pointer($name))"; | |||
} elsif($type eq "string" && $errvar ne "") { | |||
$text .= "\tvar _p$n $strconvtype\n"; | |||
$text .= "\t_p$n, $errvar = $strconvfunc($name)\n"; | |||
$text .= "\tif $errvar != nil {\n\t\treturn\n\t}\n"; | |||
push @args, "uintptr(unsafe.Pointer(_p$n))"; | |||
$n++; | |||
} elsif($type eq "string") { | |||
print STDERR "$ARGV:$.: $func uses string arguments, but has no error return\n"; | |||
$text .= "\tvar _p$n $strconvtype\n"; | |||
$text .= "\t_p$n, _ = $strconvfunc($name)\n"; | |||
push @args, "uintptr(unsafe.Pointer(_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, "uintptr(unsafe.Pointer(_p$n))", "uintptr(len($name))"; | |||
$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)"; | |||
} | |||
} 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, "uintptr(_p$n)"; | |||
$n++; | |||
} else { | |||
push @args, "uintptr($name)"; | |||
} | |||
} | |||
my $nargs = @args; | |||
# Determine which form to use; pad args with zeros. | |||
my $asm = "sysvicall6"; | |||
if ($nonblock) { | |||
$asm = "rawSysvicall6"; | |||
} | |||
if(@args <= 6) { | |||
while(@args < 6) { | |||
push @args, "0"; | |||
} | |||
} else { | |||
print STDERR "$ARGV:$.: too many arguments to system call\n"; | |||
} | |||
# Actual call. | |||
my $args = join(', ', @args); | |||
my $call = "$asm(uintptr(unsafe.Pointer(&$sysvarname)), $nargs, $args)"; | |||
# Assign return values. | |||
my $body = ""; | |||
my $failexpr = ""; | |||
my @ret = ("_", "_", "_"); | |||
my @pout= (); | |||
my $do_errno = 0; | |||
for(my $i=0; $i<@out; $i++) { | |||
my $p = $out[$i]; | |||
my ($name, $type) = parseparam($p); | |||
my $reg = ""; | |||
if($name eq "err") { | |||
$reg = "e1"; | |||
$ret[2] = $reg; | |||
$do_errno = 1; | |||
} else { | |||
$reg = sprintf("r%d", $i); | |||
$ret[$i] = $reg; | |||
} | |||
if($type eq "bool") { | |||
$reg = "$reg != 0"; | |||
} | |||
if($type eq "int64" && $_32bit ne "") { | |||
# 64-bit number in r1:r0 or r0:r1. | |||
if($i+2 > @out) { | |||
print STDERR "$ARGV:$.: not enough registers for int64 return\n"; | |||
} | |||
if($_32bit eq "big-endian") { | |||
$reg = sprintf("int64(r%d)<<32 | int64(r%d)", $i, $i+1); | |||
} else { | |||
$reg = sprintf("int64(r%d)<<32 | int64(r%d)", $i+1, $i); | |||
} | |||
$ret[$i] = sprintf("r%d", $i); | |||
$ret[$i+1] = sprintf("r%d", $i+1); | |||
} | |||
if($reg ne "e1") { | |||
$body .= "\t$name = $type($reg)\n"; | |||
} | |||
} | |||
if ($ret[0] eq "_" && $ret[1] eq "_" && $ret[2] eq "_") { | |||
$text .= "\t$call\n"; | |||
} else { | |||
$text .= "\t$ret[0], $ret[1], $ret[2] := $call\n"; | |||
} | |||
$text .= $body; | |||
if ($do_errno) { | |||
$text .= "\tif e1 != 0 {\n"; | |||
$text .= "\t\terr = e1\n"; | |||
$text .= "\t}\n"; | |||
} | |||
$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 | |||
import ( | |||
"syscall" | |||
"unsafe" | |||
) | |||
EOF | |||
print "import \"golang.org/x/sys/unix\"\n" if $package ne "unix"; | |||
my $vardecls = "\t" . join(",\n\t", @vars); | |||
$vardecls .= " syscallFunc"; | |||
chomp($_=<<EOF); | |||
$dynimports | |||
$linknames | |||
var ( | |||
$vardecls | |||
) | |||
$text | |||
EOF | |||
print $_; | |||
exit 0; |
@@ -1,265 +0,0 @@ | |||
#!/usr/bin/env perl | |||
# Copyright 2011 The Go Authors. All rights reserved. | |||
# Use of this source code is governed by a BSD-style | |||
# license that can be found in the LICENSE file. | |||
# | |||
# Parse the header files for OpenBSD and generate a Go usable sysctl MIB. | |||
# | |||
# Build a MIB with each entry being an array containing the level, type and | |||
# a hash that will contain additional entries if the current entry is a node. | |||
# We then walk this MIB and create a flattened sysctl name to OID hash. | |||
# | |||
use strict; | |||
if($ENV{'GOARCH'} eq "" || $ENV{'GOOS'} eq "") { | |||
print STDERR "GOARCH or GOOS not defined in environment\n"; | |||
exit 1; | |||
} | |||
my $debug = 0; | |||
my %ctls = (); | |||
my @headers = qw ( | |||
sys/sysctl.h | |||
sys/socket.h | |||
sys/tty.h | |||
sys/malloc.h | |||
sys/mount.h | |||
sys/namei.h | |||
sys/sem.h | |||
sys/shm.h | |||
sys/vmmeter.h | |||
uvm/uvmexp.h | |||
uvm/uvm_param.h | |||
uvm/uvm_swap_encrypt.h | |||
ddb/db_var.h | |||
net/if.h | |||
net/if_pfsync.h | |||
net/pipex.h | |||
netinet/in.h | |||
netinet/icmp_var.h | |||
netinet/igmp_var.h | |||
netinet/ip_ah.h | |||
netinet/ip_carp.h | |||
netinet/ip_divert.h | |||
netinet/ip_esp.h | |||
netinet/ip_ether.h | |||
netinet/ip_gre.h | |||
netinet/ip_ipcomp.h | |||
netinet/ip_ipip.h | |||
netinet/pim_var.h | |||
netinet/tcp_var.h | |||
netinet/udp_var.h | |||
netinet6/in6.h | |||
netinet6/ip6_divert.h | |||
netinet6/pim6_var.h | |||
netinet/icmp6.h | |||
netmpls/mpls.h | |||
); | |||
my @ctls = qw ( | |||
kern | |||
vm | |||
fs | |||
net | |||
#debug # Special handling required | |||
hw | |||
#machdep # Arch specific | |||
user | |||
ddb | |||
#vfs # Special handling required | |||
fs.posix | |||
kern.forkstat | |||
kern.intrcnt | |||
kern.malloc | |||
kern.nchstats | |||
kern.seminfo | |||
kern.shminfo | |||
kern.timecounter | |||
kern.tty | |||
kern.watchdog | |||
net.bpf | |||
net.ifq | |||
net.inet | |||
net.inet.ah | |||
net.inet.carp | |||
net.inet.divert | |||
net.inet.esp | |||
net.inet.etherip | |||
net.inet.gre | |||
net.inet.icmp | |||
net.inet.igmp | |||
net.inet.ip | |||
net.inet.ip.ifq | |||
net.inet.ipcomp | |||
net.inet.ipip | |||
net.inet.mobileip | |||
net.inet.pfsync | |||
net.inet.pim | |||
net.inet.tcp | |||
net.inet.udp | |||
net.inet6 | |||
net.inet6.divert | |||
net.inet6.ip6 | |||
net.inet6.icmp6 | |||
net.inet6.pim6 | |||
net.inet6.tcp6 | |||
net.inet6.udp6 | |||
net.mpls | |||
net.mpls.ifq | |||
net.key | |||
net.pflow | |||
net.pfsync | |||
net.pipex | |||
net.rt | |||
vm.swapencrypt | |||
#vfsgenctl # Special handling required | |||
); | |||
# Node name "fixups" | |||
my %ctl_map = ( | |||
"ipproto" => "net.inet", | |||
"net.inet.ipproto" => "net.inet", | |||
"net.inet6.ipv6proto" => "net.inet6", | |||
"net.inet6.ipv6" => "net.inet6.ip6", | |||
"net.inet.icmpv6" => "net.inet6.icmp6", | |||
"net.inet6.divert6" => "net.inet6.divert", | |||
"net.inet6.tcp6" => "net.inet.tcp", | |||
"net.inet6.udp6" => "net.inet.udp", | |||
"mpls" => "net.mpls", | |||
"swpenc" => "vm.swapencrypt" | |||
); | |||
# Node mappings | |||
my %node_map = ( | |||
"net.inet.ip.ifq" => "net.ifq", | |||
"net.inet.pfsync" => "net.pfsync", | |||
"net.mpls.ifq" => "net.ifq" | |||
); | |||
my $ctlname; | |||
my %mib = (); | |||
my %sysctl = (); | |||
my $node; | |||
sub debug() { | |||
print STDERR "$_[0]\n" if $debug; | |||
} | |||
# Walk the MIB and build a sysctl name to OID mapping. | |||
sub build_sysctl() { | |||
my ($node, $name, $oid) = @_; | |||
my %node = %{$node}; | |||
my @oid = @{$oid}; | |||
foreach my $key (sort keys %node) { | |||
my @node = @{$node{$key}}; | |||
my $nodename = $name.($name ne '' ? '.' : '').$key; | |||
my @nodeoid = (@oid, $node[0]); | |||
if ($node[1] eq 'CTLTYPE_NODE') { | |||
if (exists $node_map{$nodename}) { | |||
$node = \%mib; | |||
$ctlname = $node_map{$nodename}; | |||
foreach my $part (split /\./, $ctlname) { | |||
$node = \%{@{$$node{$part}}[2]}; | |||
} | |||
} else { | |||
$node = $node[2]; | |||
} | |||
&build_sysctl($node, $nodename, \@nodeoid); | |||
} elsif ($node[1] ne '') { | |||
$sysctl{$nodename} = \@nodeoid; | |||
} | |||
} | |||
} | |||
foreach my $ctl (@ctls) { | |||
$ctls{$ctl} = $ctl; | |||
} | |||
# Build MIB | |||
foreach my $header (@headers) { | |||
&debug("Processing $header..."); | |||
open HEADER, "/usr/include/$header" || | |||
print STDERR "Failed to open $header\n"; | |||
while (<HEADER>) { | |||
if ($_ =~ /^#define\s+(CTL_NAMES)\s+{/ || | |||
$_ =~ /^#define\s+(CTL_(.*)_NAMES)\s+{/ || | |||
$_ =~ /^#define\s+((.*)CTL_NAMES)\s+{/) { | |||
if ($1 eq 'CTL_NAMES') { | |||
# Top level. | |||
$node = \%mib; | |||
} else { | |||
# Node. | |||
my $nodename = lc($2); | |||
if ($header =~ /^netinet\//) { | |||
$ctlname = "net.inet.$nodename"; | |||
} elsif ($header =~ /^netinet6\//) { | |||
$ctlname = "net.inet6.$nodename"; | |||
} elsif ($header =~ /^net\//) { | |||
$ctlname = "net.$nodename"; | |||
} else { | |||
$ctlname = "$nodename"; | |||
$ctlname =~ s/^(fs|net|kern)_/$1\./; | |||
} | |||
if (exists $ctl_map{$ctlname}) { | |||
$ctlname = $ctl_map{$ctlname}; | |||
} | |||
if (not exists $ctls{$ctlname}) { | |||
&debug("Ignoring $ctlname..."); | |||
next; | |||
} | |||
# Walk down from the top of the MIB. | |||
$node = \%mib; | |||
foreach my $part (split /\./, $ctlname) { | |||
if (not exists $$node{$part}) { | |||
&debug("Missing node $part"); | |||
$$node{$part} = [ 0, '', {} ]; | |||
} | |||
$node = \%{@{$$node{$part}}[2]}; | |||
} | |||
} | |||
# Populate current node with entries. | |||
my $i = -1; | |||
while (defined($_) && $_ !~ /^}/) { | |||
$_ = <HEADER>; | |||
$i++ if $_ =~ /{.*}/; | |||
next if $_ !~ /{\s+"(\w+)",\s+(CTLTYPE_[A-Z]+)\s+}/; | |||
$$node{$1} = [ $i, $2, {} ]; | |||
} | |||
} | |||
} | |||
close HEADER; | |||
} | |||
&build_sysctl(\%mib, "", []); | |||
print <<EOF; | |||
// mksysctl_openbsd.pl | |||
// Code generated by the command above; DO NOT EDIT. | |||
// +build $ENV{'GOARCH'},$ENV{'GOOS'} | |||
package unix; | |||
type mibentry struct { | |||
ctlname string | |||
ctloid []_C_int | |||
} | |||
var sysctlMib = []mibentry { | |||
EOF | |||
foreach my $name (sort keys %sysctl) { | |||
my @oid = @{$sysctl{$name}}; | |||
print "\t{ \"$name\", []_C_int{ ", join(', ', @oid), " } }, \n"; | |||
} | |||
print <<EOF; | |||
} | |||
EOF |
@@ -1,39 +0,0 @@ | |||
#!/usr/bin/env perl | |||
# Copyright 2009 The Go Authors. All rights reserved. | |||
# Use of this source code is governed by a BSD-style | |||
# license that can be found in the LICENSE file. | |||
# | |||
# Generate system call table for Darwin from sys/syscall.h | |||
use strict; | |||
if($ENV{'GOARCH'} eq "" || $ENV{'GOOS'} eq "") { | |||
print STDERR "GOARCH or GOOS not defined in environment\n"; | |||
exit 1; | |||
} | |||
my $command = "mksysnum_darwin.pl " . join(' ', @ARGV); | |||
print <<EOF; | |||
// $command | |||
// Code generated by the command above; see README.md. DO NOT EDIT. | |||
// +build $ENV{'GOARCH'},$ENV{'GOOS'} | |||
package unix | |||
const ( | |||
EOF | |||
while(<>){ | |||
if(/^#define\s+SYS_(\w+)\s+([0-9]+)/){ | |||
my $name = $1; | |||
my $num = $2; | |||
$name =~ y/a-z/A-Z/; | |||
print " SYS_$name = $num;" | |||
} | |||
} | |||
print <<EOF; | |||
) | |||
EOF |
@@ -1,50 +0,0 @@ | |||
#!/usr/bin/env perl | |||
# Copyright 2009 The Go Authors. All rights reserved. | |||
# Use of this source code is governed by a BSD-style | |||
# license that can be found in the LICENSE file. | |||
# | |||
# Generate system call table for DragonFly from master list | |||
# (for example, /usr/src/sys/kern/syscalls.master). | |||
use strict; | |||
if($ENV{'GOARCH'} eq "" || $ENV{'GOOS'} eq "") { | |||
print STDERR "GOARCH or GOOS not defined in environment\n"; | |||
exit 1; | |||
} | |||
my $command = "mksysnum_dragonfly.pl " . join(' ', @ARGV); | |||
print <<EOF; | |||
// $command | |||
// Code generated by the command above; see README.md. DO NOT EDIT. | |||
// +build $ENV{'GOARCH'},$ENV{'GOOS'} | |||
package unix | |||
const ( | |||
EOF | |||
while(<>){ | |||
if(/^([0-9]+)\s+STD\s+({ \S+\s+(\w+).*)$/){ | |||
my $num = $1; | |||
my $proto = $2; | |||
my $name = "SYS_$3"; | |||
$name =~ y/a-z/A-Z/; | |||
# There are multiple entries for enosys and nosys, so comment them out. | |||
if($name =~ /^SYS_E?NOSYS$/){ | |||
$name = "// $name"; | |||
} | |||
if($name eq 'SYS_SYS_EXIT'){ | |||
$name = 'SYS_EXIT'; | |||
} | |||
print " $name = $num; // $proto\n"; | |||
} | |||
} | |||
print <<EOF; | |||
) | |||
EOF |
@@ -1,50 +0,0 @@ | |||
#!/usr/bin/env perl | |||
# Copyright 2009 The Go Authors. All rights reserved. | |||
# Use of this source code is governed by a BSD-style | |||
# license that can be found in the LICENSE file. | |||
# | |||
# Generate system call table for FreeBSD from master list | |||
# (for example, /usr/src/sys/kern/syscalls.master). | |||
use strict; | |||
if($ENV{'GOARCH'} eq "" || $ENV{'GOOS'} eq "") { | |||
print STDERR "GOARCH or GOOS not defined in environment\n"; | |||
exit 1; | |||
} | |||
my $command = "mksysnum_freebsd.pl " . join(' ', @ARGV); | |||
print <<EOF; | |||
// $command | |||
// Code generated by the command above; see README.md. DO NOT EDIT. | |||
// +build $ENV{'GOARCH'},$ENV{'GOOS'} | |||
package unix | |||
const ( | |||
EOF | |||
while(<>){ | |||
if(/^([0-9]+)\s+\S+\s+(?:NO)?STD\s+({ \S+\s+(\w+).*)$/){ | |||
my $num = $1; | |||
my $proto = $2; | |||
my $name = "SYS_$3"; | |||
$name =~ y/a-z/A-Z/; | |||
# There are multiple entries for enosys and nosys, so comment them out. | |||
if($name =~ /^SYS_E?NOSYS$/){ | |||
$name = "// $name"; | |||
} | |||
if($name eq 'SYS_SYS_EXIT'){ | |||
$name = 'SYS_EXIT'; | |||
} | |||
print " $name = $num; // $proto\n"; | |||
} | |||
} | |||
print <<EOF; | |||
) | |||
EOF |
@@ -1,58 +0,0 @@ | |||
#!/usr/bin/env perl | |||
# Copyright 2009 The Go Authors. All rights reserved. | |||
# Use of this source code is governed by a BSD-style | |||
# license that can be found in the LICENSE file. | |||
# | |||
# Generate system call table for OpenBSD from master list | |||
# (for example, /usr/src/sys/kern/syscalls.master). | |||
use strict; | |||
if($ENV{'GOARCH'} eq "" || $ENV{'GOOS'} eq "") { | |||
print STDERR "GOARCH or GOOS not defined in environment\n"; | |||
exit 1; | |||
} | |||
my $command = "mksysnum_netbsd.pl " . join(' ', @ARGV); | |||
print <<EOF; | |||
// $command | |||
// Code generated by the command above; see README.md. DO NOT EDIT. | |||
// +build $ENV{'GOARCH'},$ENV{'GOOS'} | |||
package unix | |||
const ( | |||
EOF | |||
my $line = ''; | |||
while(<>){ | |||
if($line =~ /^(.*)\\$/) { | |||
# Handle continuation | |||
$line = $1; | |||
$_ =~ s/^\s+//; | |||
$line .= $_; | |||
} else { | |||
# New line | |||
$line = $_; | |||
} | |||
next if $line =~ /\\$/; | |||
if($line =~ /^([0-9]+)\s+((STD)|(NOERR))\s+(RUMP\s+)?({\s+\S+\s*\*?\s*\|(\S+)\|(\S*)\|(\w+).*\s+})(\s+(\S+))?$/) { | |||
my $num = $1; | |||
my $proto = $6; | |||
my $compat = $8; | |||
my $name = "$7_$9"; | |||
$name = "$7_$11" if $11 ne ''; | |||
$name =~ y/a-z/A-Z/; | |||
if($compat eq '' || $compat eq '13' || $compat eq '30' || $compat eq '50') { | |||
print " $name = $num; // $proto\n"; | |||
} | |||
} | |||
} | |||
print <<EOF; | |||
) | |||
EOF |
@@ -1,50 +0,0 @@ | |||
#!/usr/bin/env perl | |||
# Copyright 2009 The Go Authors. All rights reserved. | |||
# Use of this source code is governed by a BSD-style | |||
# license that can be found in the LICENSE file. | |||
# | |||
# Generate system call table for OpenBSD from master list | |||
# (for example, /usr/src/sys/kern/syscalls.master). | |||
use strict; | |||
if($ENV{'GOARCH'} eq "" || $ENV{'GOOS'} eq "") { | |||
print STDERR "GOARCH or GOOS not defined in environment\n"; | |||
exit 1; | |||
} | |||
my $command = "mksysnum_openbsd.pl " . join(' ', @ARGV); | |||
print <<EOF; | |||
// $command | |||
// Code generated by the command above; see README.md. DO NOT EDIT. | |||
// +build $ENV{'GOARCH'},$ENV{'GOOS'} | |||
package unix | |||
const ( | |||
EOF | |||
while(<>){ | |||
if(/^([0-9]+)\s+STD\s+(NOLOCK\s+)?({ \S+\s+\*?(\w+).*)$/){ | |||
my $num = $1; | |||
my $proto = $3; | |||
my $name = $4; | |||
$name =~ y/a-z/A-Z/; | |||
# There are multiple entries for enosys and nosys, so comment them out. | |||
if($name =~ /^SYS_E?NOSYS$/){ | |||
$name = "// $name"; | |||
} | |||
if($name eq 'SYS_SYS_EXIT'){ | |||
$name = 'SYS_EXIT'; | |||
} | |||
print " $name = $num; // $proto\n"; | |||
} | |||
} | |||
print <<EOF; | |||
) | |||
EOF |
@@ -2,6 +2,7 @@ | |||
// Use of this source code is governed by a BSD-style | |||
// license that can be found in the LICENSE file. | |||
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris | |||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris | |||
// For Unix, get the pagesize from the runtime. | |||
@@ -2,9 +2,6 @@ | |||
// Use of this source code is governed by a BSD-style | |||
// license that can be found in the LICENSE file. | |||
// +build openbsd | |||
// +build 386 amd64 arm | |||
package unix | |||
import ( |
@@ -0,0 +1,12 @@ | |||
// Copyright 2020 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. | |||
//go:build darwin && !ios | |||
// +build darwin,!ios | |||
package unix | |||
func ptrace(request int, pid int, addr uintptr, data uintptr) error { | |||
return ptrace1(request, pid, addr, data) | |||
} |
@@ -0,0 +1,12 @@ | |||
// Copyright 2020 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. | |||
//go:build ios | |||
// +build ios | |||
package unix | |||
func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) { | |||
return ENOTSUP | |||
} |
@@ -2,6 +2,7 @@ | |||
// Use of this source code is governed by a BSD-style | |||
// license that can be found in the LICENSE file. | |||
//go:build (darwin && race) || (linux && race) || (freebsd && race) | |||
// +build darwin,race linux,race freebsd,race | |||
package unix | |||
@@ -2,7 +2,8 @@ | |||
// Use of this source code is governed by a BSD-style | |||
// license that can be found in the LICENSE file. | |||
// +build aix darwin,!race linux,!race freebsd,!race netbsd openbsd solaris dragonfly | |||
//go:build aix || (darwin && !race) || (linux && !race) || (freebsd && !race) || netbsd || openbsd || solaris || dragonfly || zos | |||
// +build aix darwin,!race linux,!race freebsd,!race netbsd openbsd solaris dragonfly zos | |||
package unix | |||
@@ -0,0 +1,13 @@ | |||
// Copyright 2019 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. | |||
//go:build aix || dragonfly || freebsd || linux || netbsd || openbsd | |||
// +build aix dragonfly freebsd linux netbsd openbsd | |||
package unix | |||
// ReadDirent reads directory entries from fd and writes them into buf. | |||
func ReadDirent(fd int, buf []byte) (n int, err error) { | |||
return Getdents(fd, buf) | |||
} |
@@ -0,0 +1,20 @@ | |||
// Copyright 2019 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. | |||
//go:build darwin | |||
// +build darwin | |||
package unix | |||
import "unsafe" | |||
// ReadDirent reads directory entries from fd and writes them into buf. | |||
func ReadDirent(fd int, buf []byte) (n int, err error) { | |||
// Final argument is (basep *uintptr) and the syscall doesn't take nil. | |||
// 64 bits should be enough. (32 bits isn't even on 386). Since the | |||
// actual system call is getdirentries64, 64 is a good guess. | |||
// TODO(rsc): Can we use a single global basep for all calls? | |||
var base = (*uintptr)(unsafe.Pointer(new(uint64))) | |||
return Getdirentries(fd, buf, base) | |||
} |
@@ -0,0 +1,16 @@ | |||
// Copyright 2019 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 | |||
// Round the length of a raw sockaddr up to align it properly. | |||
func cmsgAlignOf(salen int) int { | |||
salign := SizeofPtr | |||
if SizeofPtr == 8 && !supportsABI(_dragonflyABIChangeVersion) { | |||
// 64-bit Dragonfly before the September 2019 ABI changes still requires | |||
// 32-bit aligned access to network subsystem. | |||
salign = 4 | |||
} | |||
return (salen + salign - 1) & ^(salign - 1) | |||
} |
@@ -17,7 +17,7 @@ func UnixCredentials(ucred *Ucred) []byte { | |||
h.Level = SOL_SOCKET | |||
h.Type = SCM_CREDENTIALS | |||
h.SetLen(CmsgLen(SizeofUcred)) | |||
*((*Ucred)(cmsgData(h))) = *ucred | |||
*(*Ucred)(h.data(0)) = *ucred | |||
return b | |||
} | |||
@@ -34,3 +34,52 @@ func ParseUnixCredentials(m *SocketControlMessage) (*Ucred, error) { | |||
ucred := *(*Ucred)(unsafe.Pointer(&m.Data[0])) | |||
return &ucred, nil | |||
} | |||
// PktInfo4 encodes Inet4Pktinfo into a socket control message of type IP_PKTINFO. | |||
func PktInfo4(info *Inet4Pktinfo) []byte { | |||
b := make([]byte, CmsgSpace(SizeofInet4Pktinfo)) | |||
h := (*Cmsghdr)(unsafe.Pointer(&b[0])) | |||
h.Level = SOL_IP | |||
h.Type = IP_PKTINFO | |||
h.SetLen(CmsgLen(SizeofInet4Pktinfo)) | |||
*(*Inet4Pktinfo)(h.data(0)) = *info | |||
return b | |||
} | |||
// PktInfo6 encodes Inet6Pktinfo into a socket control message of type IPV6_PKTINFO. | |||
func PktInfo6(info *Inet6Pktinfo) []byte { | |||
b := make([]byte, CmsgSpace(SizeofInet6Pktinfo)) | |||
h := (*Cmsghdr)(unsafe.Pointer(&b[0])) | |||
h.Level = SOL_IPV6 | |||
h.Type = IPV6_PKTINFO | |||
h.SetLen(CmsgLen(SizeofInet6Pktinfo)) | |||
*(*Inet6Pktinfo)(h.data(0)) = *info | |||
return b | |||
} | |||
// ParseOrigDstAddr decodes a socket control message containing the original | |||
// destination address. To receive such a message the IP_RECVORIGDSTADDR or | |||
// IPV6_RECVORIGDSTADDR option must be enabled on the socket. | |||
func ParseOrigDstAddr(m *SocketControlMessage) (Sockaddr, error) { | |||
switch { | |||
case m.Header.Level == SOL_IP && m.Header.Type == IP_ORIGDSTADDR: | |||
pp := (*RawSockaddrInet4)(unsafe.Pointer(&m.Data[0])) | |||
sa := new(SockaddrInet4) | |||
p := (*[2]byte)(unsafe.Pointer(&pp.Port)) | |||
sa.Port = int(p[0])<<8 + int(p[1]) | |||
sa.Addr = pp.Addr | |||
return sa, nil | |||
case m.Header.Level == SOL_IPV6 && m.Header.Type == IPV6_ORIGDSTADDR: | |||
pp := (*RawSockaddrInet6)(unsafe.Pointer(&m.Data[0])) | |||
sa := new(SockaddrInet6) | |||
p := (*[2]byte)(unsafe.Pointer(&pp.Port)) | |||
sa.Port = int(p[0])<<8 + int(p[1]) | |||
sa.ZoneId = pp.Scope_id | |||
sa.Addr = pp.Addr | |||
return sa, nil | |||
default: | |||
return nil, EINVAL | |||
} | |||
} |
@@ -2,39 +2,17 @@ | |||
// 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 | |||
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos | |||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos | |||
// Socket control messages | |||
package unix | |||
import ( | |||
"runtime" | |||
"unsafe" | |||
) | |||
// Round the length of a raw sockaddr up to align it properly. | |||
func cmsgAlignOf(salen int) int { | |||
salign := SizeofPtr | |||
switch runtime.GOOS { | |||
case "darwin", "dragonfly", "solaris": | |||
// NOTE: It seems like 64-bit Darwin, DragonFly BSD and | |||
// Solaris kernels still require 32-bit aligned access to | |||
// network subsystem. | |||
if SizeofPtr == 8 { | |||
salign = 4 | |||
} | |||
case "openbsd": | |||
// OpenBSD armv7 requires 64-bit alignment. | |||
if runtime.GOARCH == "arm" { | |||
salign = 8 | |||
} | |||
} | |||
return (salen + salign - 1) & ^(salign - 1) | |||
} | |||
// CmsgLen returns the value to store in the Len field of the Cmsghdr | |||
// structure, taking into account any necessary alignment. | |||
func CmsgLen(datalen int) int { | |||
@@ -47,8 +25,8 @@ func CmsgSpace(datalen int) int { | |||
return cmsgAlignOf(SizeofCmsghdr) + cmsgAlignOf(datalen) | |||
} | |||
func cmsgData(h *Cmsghdr) unsafe.Pointer { | |||
return unsafe.Pointer(uintptr(unsafe.Pointer(h)) + uintptr(cmsgAlignOf(SizeofCmsghdr))) | |||
func (h *Cmsghdr) data(offset uintptr) unsafe.Pointer { | |||
return unsafe.Pointer(uintptr(unsafe.Pointer(h)) + uintptr(cmsgAlignOf(SizeofCmsghdr)) + offset) | |||
} | |||
// SocketControlMessage represents a socket control message. | |||
@@ -91,10 +69,8 @@ func UnixRights(fds ...int) []byte { | |||
h.Level = SOL_SOCKET | |||
h.Type = SCM_RIGHTS | |||
h.SetLen(CmsgLen(datalen)) | |||
data := cmsgData(h) | |||
for _, fd := range fds { | |||
*(*int32)(data) = int32(fd) | |||
data = unsafe.Pointer(uintptr(data) + 4) | |||
for i, fd := range fds { | |||
*(*int32)(h.data(4 * uintptr(i))) = int32(fd) | |||
} | |||
return b | |||
} | |||
@@ -0,0 +1,47 @@ | |||
// Copyright 2019 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. | |||
//go:build aix || darwin || freebsd || linux || netbsd || openbsd || solaris || zos | |||
// +build aix darwin freebsd linux netbsd openbsd solaris zos | |||
package unix | |||
import ( | |||
"runtime" | |||
) | |||
// Round the length of a raw sockaddr up to align it properly. | |||
func cmsgAlignOf(salen int) int { | |||
salign := SizeofPtr | |||
// dragonfly needs to check ABI version at runtime, see cmsgAlignOf in | |||
// sockcmsg_dragonfly.go | |||
switch runtime.GOOS { | |||
case "aix": | |||
// There is no alignment on AIX. | |||
salign = 1 | |||
case "darwin", "ios", "illumos", "solaris": | |||
// NOTE: It seems like 64-bit Darwin, Illumos and Solaris | |||
// kernels still require 32-bit aligned access to network | |||
// subsystem. | |||
if SizeofPtr == 8 { | |||
salign = 4 | |||
} | |||
case "netbsd", "openbsd": | |||
// NetBSD and OpenBSD armv7 require 64-bit alignment. | |||
if runtime.GOARCH == "arm" { | |||
salign = 8 | |||
} | |||
// NetBSD aarch64 requires 128-bit alignment. | |||
if runtime.GOOS == "netbsd" && runtime.GOARCH == "arm64" { | |||
salign = 16 | |||
} | |||
case "zos": | |||
// z/OS socket macros use [32-bit] sizeof(int) alignment, | |||
// not pointer width. | |||
salign = SizeofInt | |||
} | |||
return (salen + salign - 1) & ^(salign - 1) | |||
} |
@@ -1,26 +0,0 @@ | |||
// Copyright 2009 The Go Authors. All rights reserved. | |||
// Use of this source code is governed by a BSD-style | |||
// license that can be found in the LICENSE file. | |||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris | |||
package unix | |||
func itoa(val int) string { // do it here rather than with fmt to avoid dependency | |||
if val < 0 { | |||
return "-" + uitoa(uint(-val)) | |||
} | |||
return uitoa(uint(val)) | |||
} | |||
func uitoa(val uint) string { | |||
var buf [32]byte // big enough for int64 | |||
i := len(buf) - 1 | |||
for val >= 10 { | |||
buf[i] = byte(val%10 + '0') | |||
i-- | |||
val /= 10 | |||
} | |||
buf[i] = byte(val + '0') | |||
return string(buf[i:]) | |||
} |
@@ -2,7 +2,8 @@ | |||
// 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 | |||
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos | |||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos | |||
// Package unix contains an interface to the low-level operating system | |||
// primitives. OS details vary depending on the underlying system, and | |||
@@ -24,7 +25,11 @@ | |||
// holds a value of type syscall.Errno. | |||
package unix // import "golang.org/x/sys/unix" | |||
import "strings" | |||
import ( | |||
"bytes" | |||
"strings" | |||
"unsafe" | |||
) | |||
// ByteSliceFromString returns a NUL-terminated slice of bytes | |||
// containing the text of s. If s contains a NUL byte at any | |||
@@ -49,6 +54,34 @@ func BytePtrFromString(s string) (*byte, error) { | |||
return &a[0], nil | |||
} | |||
// ByteSliceToString returns a string form of the text represented by the slice s, with a terminating NUL and any | |||
// bytes after the NUL removed. | |||
func ByteSliceToString(s []byte) string { | |||
if i := bytes.IndexByte(s, 0); i != -1 { | |||
s = s[:i] | |||
} | |||
return string(s) | |||
} | |||
// BytePtrToString takes a pointer to a sequence of text and returns the corresponding string. | |||
// If the pointer is nil, it returns the empty string. It assumes that the text sequence is terminated | |||
// at a zero byte; if the zero byte is not present, the program may crash. | |||
func BytePtrToString(p *byte) string { | |||
if p == nil { | |||
return "" | |||
} | |||
if *p == 0 { | |||
return "" | |||
} | |||
// Find NUL terminator. | |||
n := 0 | |||
for ptr := unsafe.Pointer(p); *(*byte)(ptr) != 0; n++ { | |||
ptr = unsafe.Pointer(uintptr(ptr) + 1) | |||
} | |||
return string(unsafe.Slice(p, n)) | |||
} | |||
// Single-word zero for use when we need a valid pointer to 0 bytes. | |||
// See mkunix.pl. | |||
var _zero uintptr |
@@ -2,6 +2,7 @@ | |||
// Use of this source code is governed by a BSD-style | |||
// license that can be found in the LICENSE file. | |||
//go:build aix | |||
// +build aix | |||
// Aix system calls. | |||
@@ -19,7 +20,24 @@ import "unsafe" | |||
* Wrapped | |||
*/ | |||
func Access(path string, mode uint32) (err error) { | |||
return Faccessat(AT_FDCWD, path, mode, 0) | |||
} | |||
func Chmod(path string, mode uint32) (err error) { | |||
return Fchmodat(AT_FDCWD, path, mode, 0) | |||
} | |||
func Chown(path string, uid int, gid int) (err error) { | |||
return Fchownat(AT_FDCWD, path, uid, gid, 0) | |||
} | |||
func Creat(path string, mode uint32) (fd int, err error) { | |||
return Open(path, O_CREAT|O_WRONLY|O_TRUNC, mode) | |||
} | |||
//sys utimes(path string, times *[2]Timeval) (err error) | |||
func Utimes(path string, tv []Timeval) error { | |||
if len(tv) != 2 { | |||
return EINVAL | |||
@@ -28,6 +46,7 @@ func Utimes(path string, tv []Timeval) error { | |||
} | |||
//sys utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error) | |||
func UtimesNano(path string, ts []Timespec) error { | |||
if len(ts) != 2 { | |||
return EINVAL | |||
@@ -53,9 +72,7 @@ func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) { | |||
p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port)) | |||
p[0] = byte(sa.Port >> 8) | |||
p[1] = byte(sa.Port) | |||
for i := 0; i < len(sa.Addr); i++ { | |||
sa.raw.Addr[i] = sa.Addr[i] | |||
} | |||
sa.raw.Addr = sa.Addr | |||
return unsafe.Pointer(&sa.raw), SizeofSockaddrInet4, nil | |||
} | |||
@@ -68,9 +85,7 @@ func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) { | |||
p[0] = byte(sa.Port >> 8) | |||
p[1] = byte(sa.Port) | |||
sa.raw.Scope_id = sa.ZoneId | |||
for i := 0; i < len(sa.Addr); i++ { | |||
sa.raw.Addr[i] = sa.Addr[i] | |||
} | |||
sa.raw.Addr = sa.Addr | |||
return unsafe.Pointer(&sa.raw), SizeofSockaddrInet6, nil | |||
} | |||
@@ -202,20 +217,63 @@ func Accept(fd int) (nfd int, sa Sockaddr, err error) { | |||
return | |||
} | |||
func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) { | |||
// Recvmsg not implemented on AIX | |||
sa := new(SockaddrUnix) | |||
return -1, -1, -1, sa, ENOSYS | |||
} | |||
func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) { | |||
_, err = SendmsgN(fd, p, oob, to, flags) | |||
func recvmsgRaw(fd int, iov []Iovec, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) { | |||
var msg Msghdr | |||
msg.Name = (*byte)(unsafe.Pointer(rsa)) | |||
msg.Namelen = uint32(SizeofSockaddrAny) | |||
var dummy byte | |||
if len(oob) > 0 { | |||
// receive at least one normal byte | |||
if emptyIovecs(iov) { | |||
var iova [1]Iovec | |||
iova[0].Base = &dummy | |||
iova[0].SetLen(1) | |||
iov = iova[:] | |||
} | |||
msg.Control = (*byte)(unsafe.Pointer(&oob[0])) | |||
msg.SetControllen(len(oob)) | |||
} | |||
if len(iov) > 0 { | |||
msg.Iov = &iov[0] | |||
msg.SetIovlen(len(iov)) | |||
} | |||
if n, err = recvmsg(fd, &msg, flags); n == -1 { | |||
return | |||
} | |||
oobn = int(msg.Controllen) | |||
recvflags = int(msg.Flags) | |||
return | |||
} | |||
func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) { | |||
// SendmsgN not implemented on AIX | |||
return -1, ENOSYS | |||
func sendmsgN(fd int, iov []Iovec, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) { | |||
var msg Msghdr | |||
msg.Name = (*byte)(unsafe.Pointer(ptr)) | |||
msg.Namelen = uint32(salen) | |||
var dummy byte | |||
var empty bool | |||
if len(oob) > 0 { | |||
// send at least one normal byte | |||
empty = emptyIovecs(iov) | |||
if empty { | |||
var iova [1]Iovec | |||
iova[0].Base = &dummy | |||
iova[0].SetLen(1) | |||
iov = iova[:] | |||
} | |||
msg.Control = (*byte)(unsafe.Pointer(&oob[0])) | |||
msg.SetControllen(len(oob)) | |||
} | |||
if len(iov) > 0 { | |||
msg.Iov = &iov[0] | |||
msg.SetIovlen(len(iov)) | |||
} | |||
if n, err = sendmsg(fd, &msg, flags); err != nil { | |||
return 0, err | |||
} | |||
if len(oob) > 0 && empty { | |||
n = 0 | |||
} | |||
return n, nil | |||
} | |||
func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) { | |||
@@ -227,7 +285,7 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) { | |||
// Some versions of AIX have a bug in getsockname (see IV78655). | |||
// We can't rely on sa.Len being set correctly. | |||
n := SizeofSockaddrUnix - 3 // substract leading Family, Len, terminating NUL. | |||
n := SizeofSockaddrUnix - 3 // subtract leading Family, Len, terminating NUL. | |||
for i := 0; i < n; i++ { | |||
if pp.Path[i] == 0 { | |||
n = i | |||
@@ -235,7 +293,7 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) { | |||
} | |||
} | |||
bytes := (*[10000]byte)(unsafe.Pointer(&pp.Path[0]))[0:n] | |||
bytes := (*[len(pp.Path)]byte)(unsafe.Pointer(&pp.Path[0]))[0:n] | |||
sa.Name = string(bytes) | |||
return sa, nil | |||
@@ -244,9 +302,7 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) { | |||
sa := new(SockaddrInet4) | |||
p := (*[2]byte)(unsafe.Pointer(&pp.Port)) | |||
sa.Port = int(p[0])<<8 + int(p[1]) | |||
for i := 0; i < len(sa.Addr); i++ { | |||
sa.Addr[i] = pp.Addr[i] | |||
} | |||
sa.Addr = pp.Addr | |||
return sa, nil | |||
case AF_INET6: | |||
@@ -255,9 +311,7 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) { | |||
p := (*[2]byte)(unsafe.Pointer(&pp.Port)) | |||
sa.Port = int(p[0])<<8 + int(p[1]) | |||
sa.ZoneId = pp.Scope_id | |||
for i := 0; i < len(sa.Addr); i++ { | |||
sa.Addr[i] = pp.Addr[i] | |||
} | |||
sa.Addr = pp.Addr | |||
return sa, nil | |||
} | |||
return nil, EAFNOSUPPORT | |||
@@ -268,17 +322,42 @@ func Gettimeofday(tv *Timeval) (err error) { | |||
return | |||
} | |||
func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { | |||
if raceenabled { | |||
raceReleaseMerge(unsafe.Pointer(&ioSync)) | |||
} | |||
return sendfile(outfd, infd, offset, count) | |||
} | |||
// TODO | |||
func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { | |||
return -1, ENOSYS | |||
} | |||
func direntIno(buf []byte) (uint64, bool) { | |||
return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino)) | |||
} | |||
func direntReclen(buf []byte) (uint64, bool) { | |||
return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen)) | |||
} | |||
func direntNamlen(buf []byte) (uint64, bool) { | |||
reclen, ok := direntReclen(buf) | |||
if !ok { | |||
return 0, false | |||
} | |||
return reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true | |||
} | |||
//sys getdirent(fd int, buf []byte) (n int, err error) | |||
func ReadDirent(fd int, buf []byte) (n int, err error) { | |||
func Getdents(fd int, buf []byte) (n int, err error) { | |||
return getdirent(fd, buf) | |||
} | |||
//sys wait4(pid Pid_t, status *_C_int, options int, rusage *Rusage) (wpid Pid_t, err error) | |||
func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) { | |||
var status _C_int | |||
var r Pid_t | |||
@@ -327,49 +406,12 @@ func (w WaitStatus) Signal() Signal { | |||
func (w WaitStatus) Continued() bool { return w&0x01000000 != 0 } | |||
func (w WaitStatus) CoreDump() bool { return w&0x200 != 0 } | |||
func (w WaitStatus) CoreDump() bool { return w&0x80 == 0x80 } | |||
func (w WaitStatus) TrapCause() int { return -1 } | |||
//sys ioctl(fd int, req uint, arg uintptr) (err error) | |||
// ioctl itself should not be exposed directly, but additional get/set | |||
// functions for specific types are permissible. | |||
// IoctlSetInt performs an ioctl operation which sets an integer value | |||
// on fd, using the specified request number. | |||
func IoctlSetInt(fd int, req uint, value int) error { | |||
return ioctl(fd, req, uintptr(value)) | |||
} | |||
func ioctlSetWinsize(fd int, req uint, value *Winsize) error { | |||
return ioctl(fd, req, uintptr(unsafe.Pointer(value))) | |||
} | |||
func ioctlSetTermios(fd int, req uint, value *Termios) error { | |||
return ioctl(fd, req, uintptr(unsafe.Pointer(value))) | |||
} | |||
// IoctlGetInt performs an ioctl operation which gets an integer value | |||
// from fd, using the specified request number. | |||
func IoctlGetInt(fd int, req uint) (int, error) { | |||
var value int | |||
err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) | |||
return value, err | |||
} | |||
func IoctlGetWinsize(fd int, req uint) (*Winsize, error) { | |||
var value Winsize | |||
err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) | |||
return &value, err | |||
} | |||
func IoctlGetTermios(fd int, req uint) (*Termios, error) { | |||
var value Termios | |||
err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) | |||
return &value, err | |||
} | |||
// fcntl must never be called with cmd=F_DUP2FD because it doesn't work on AIX | |||
// There is no way to create a custom fcntl and to keep //sys fcntl easily, | |||
// Therefore, the programmer must call dup2 instead of fcntl in this case. | |||
@@ -382,6 +424,12 @@ func IoctlGetTermios(fd int, req uint) (*Termios, error) { | |||
//sys fcntl(fd int, cmd int, arg int) (val int, err error) | |||
//sys fsyncRange(fd int, how int, start int64, length int64) (err error) = fsync_range | |||
func Fsync(fd int) error { | |||
return fsyncRange(fd, O_SYNC, 0, 0) | |||
} | |||
/* | |||
* Direct access | |||
*/ | |||
@@ -398,7 +446,6 @@ func IoctlGetTermios(fd int, req uint) (*Termios, error) { | |||
//sys Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) | |||
//sys Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) | |||
//sys Fdatasync(fd int) (err error) | |||
//sys Fsync(fd int) (err error) | |||
// readdir_r | |||
//sysnb Getpgid(pid int) (pgid int, err error) | |||
@@ -417,8 +464,8 @@ func IoctlGetTermios(fd int, req uint) (*Termios, 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 Open(path string, mode int, perm uint32) (fd int, err error) = open64 | |||
//sys Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) | |||
//sys Open(path string, mode int, perm uint32) (fd int, err error) = open64 | |||
//sys Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) | |||
//sys read(fd int, p []byte) (n int, err error) | |||
//sys Readlink(path string, buf []byte) (n int, err error) | |||
//sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) | |||
@@ -437,10 +484,8 @@ func IoctlGetTermios(fd int, req uint) (*Termios, error) { | |||
//sysnb Times(tms *Tms) (ticks uintptr, err error) | |||
//sysnb Umask(mask int) (oldmask int) | |||
//sysnb Uname(buf *Utsname) (err error) | |||
//TODO umount | |||
// //sys Unmount(target string, flags int) (err error) = umount | |||
//sys Unlink(path string) (err error) | |||
//sys Unlinkat(dirfd int, path string, flags int) (err error) | |||
//sys Unlink(path string) (err error) | |||
//sys Unlinkat(dirfd int, path string, flags int) (err error) | |||
//sys Ustat(dev int, ubuf *Ustat_t) (err error) | |||
//sys write(fd int, p []byte) (n int, err error) | |||
//sys readlen(fd int, p *byte, np int) (n int, err error) = read | |||
@@ -449,8 +494,8 @@ func IoctlGetTermios(fd int, req uint) (*Termios, error) { | |||
//sys Dup2(oldfd int, newfd int) (err error) | |||
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = posix_fadvise64 | |||
//sys Fchown(fd int, uid int, gid int) (err error) | |||
//sys Fstat(fd int, stat *Stat_t) (err error) | |||
//sys Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = fstatat | |||
//sys fstat(fd int, stat *Stat_t) (err error) | |||
//sys fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = fstatat | |||
//sys Fstatfs(fd int, buf *Statfs_t) (err error) | |||
//sys Ftruncate(fd int, length int64) (err error) | |||
//sysnb Getegid() (egid int) | |||
@@ -459,18 +504,17 @@ func IoctlGetTermios(fd int, req uint) (*Termios, error) { | |||
//sysnb Getuid() (uid int) | |||
//sys Lchown(path string, uid int, gid int) (err error) | |||
//sys Listen(s int, n int) (err error) | |||
//sys Lstat(path string, stat *Stat_t) (err error) | |||
//sys lstat(path string, stat *Stat_t) (err error) | |||
//sys Pause() (err error) | |||
//sys Pread(fd int, p []byte, offset int64) (n int, err error) = pread64 | |||
//sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = pwrite64 | |||
//TODO Select | |||
// //sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) | |||
//sys pread(fd int, p []byte, offset int64) (n int, err error) = pread64 | |||
//sys pwrite(fd int, p []byte, offset int64) (n int, err error) = pwrite64 | |||
//sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) | |||
//sys Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error) | |||
//sysnb Setregid(rgid int, egid int) (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) | |||
//sys Stat(path string, stat *Stat_t) (err error) | |||
//sys stat(path string, statptr *Stat_t) (err error) | |||
//sys Statfs(path string, buf *Statfs_t) (err error) | |||
//sys Truncate(path string, length int64) (err error) | |||
@@ -486,8 +530,10 @@ func IoctlGetTermios(fd int, req uint) (*Termios, 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) | |||
// In order to use msghdr structure with Control, Controllen, nrecvmsg and nsendmsg must be used. | |||
//sys recvmsg(s int, msg *Msghdr, flags int) (n int, err error) = nrecvmsg | |||
//sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error) = nsendmsg | |||
//sys munmap(addr uintptr, length uintptr) (err error) | |||
@@ -513,7 +559,7 @@ func Munmap(b []byte) (err error) { | |||
//sys Munlock(b []byte) (err error) | |||
//sys Munlockall() (err error) | |||
//sysnb pipe(p *[2]_C_int) (err error) | |||
//sysnb pipe(p *[2]_C_int) (err error) | |||
func Pipe(p []int) (err error) { | |||
if len(p) != 2 { | |||
@@ -521,8 +567,10 @@ func Pipe(p []int) (err error) { | |||
} | |||
var pp [2]_C_int | |||
err = pipe(&pp) | |||
p[0] = int(pp[0]) | |||
p[1] = int(pp[1]) | |||
if err == nil { | |||
p[0] = int(pp[0]) | |||
p[1] = int(pp[1]) | |||
} | |||
return | |||
} | |||
@@ -538,3 +586,15 @@ func Poll(fds []PollFd, timeout int) (n int, err error) { | |||
//sys gettimeofday(tv *Timeval, tzp *Timezone) (err error) | |||
//sysnb Time(t *Time_t) (tt Time_t, err error) | |||
//sys Utime(path string, buf *Utimbuf) (err error) | |||
//sys Getsystemcfg(label int) (n uint64) | |||
//sys umount(target string) (err error) | |||
func Unmount(target string, flags int) (err error) { | |||
if flags != 0 { | |||
// AIX doesn't have any flags for umount. | |||
return ENOSYS | |||
} | |||
return umount(target) | |||
} |
@@ -2,8 +2,8 @@ | |||
// Use of this source code is governed by a BSD-style | |||
// license that can be found in the LICENSE file. | |||
// +build aix | |||
// +build ppc | |||
//go:build aix && ppc | |||
// +build aix,ppc | |||
package unix | |||
@@ -29,6 +29,26 @@ func (msghdr *Msghdr) SetControllen(length int) { | |||
msghdr.Controllen = uint32(length) | |||
} | |||
func (msghdr *Msghdr) SetIovlen(length int) { | |||
msghdr.Iovlen = int32(length) | |||
} | |||
func (cmsg *Cmsghdr) SetLen(length int) { | |||
cmsg.Len = uint32(length) | |||
} | |||
func Fstat(fd int, stat *Stat_t) error { | |||
return fstat(fd, stat) | |||
} | |||
func Fstatat(dirfd int, path string, stat *Stat_t, flags int) error { | |||
return fstatat(dirfd, path, stat, flags) | |||
} | |||
func Lstat(path string, stat *Stat_t) error { | |||
return lstat(path, stat) | |||
} | |||
func Stat(path string, statptr *Stat_t) error { | |||
return stat(path, statptr) | |||
} |
@@ -2,8 +2,8 @@ | |||
// Use of this source code is governed by a BSD-style | |||
// license that can be found in the LICENSE file. | |||
// +build aix | |||
// +build ppc64 | |||
//go:build aix && ppc64 | |||
// +build aix,ppc64 | |||
package unix | |||
@@ -29,6 +29,57 @@ func (msghdr *Msghdr) SetControllen(length int) { | |||
msghdr.Controllen = uint32(length) | |||
} | |||
func (msghdr *Msghdr) SetIovlen(length int) { | |||
msghdr.Iovlen = int32(length) | |||
} | |||
func (cmsg *Cmsghdr) SetLen(length int) { | |||
cmsg.Len = uint32(length) | |||
} | |||
// In order to only have Timespec structure, type of Stat_t's fields | |||
// Atim, Mtim and Ctim is changed from StTimespec to Timespec during | |||
// ztypes generation. | |||
// On ppc64, Timespec.Nsec is an int64 while StTimespec.Nsec is an | |||
// int32, so the fields' value must be modified. | |||
func fixStatTimFields(stat *Stat_t) { | |||
stat.Atim.Nsec >>= 32 | |||
stat.Mtim.Nsec >>= 32 | |||
stat.Ctim.Nsec >>= 32 | |||
} | |||
func Fstat(fd int, stat *Stat_t) error { | |||
err := fstat(fd, stat) | |||
if err != nil { | |||
return err | |||
} | |||
fixStatTimFields(stat) | |||
return nil | |||
} | |||
func Fstatat(dirfd int, path string, stat *Stat_t, flags int) error { | |||
err := fstatat(dirfd, path, stat, flags) | |||
if err != nil { | |||
return err | |||
} | |||
fixStatTimFields(stat) | |||
return nil | |||
} | |||
func Lstat(path string, stat *Stat_t) error { | |||
err := lstat(path, stat) | |||
if err != nil { | |||
return err | |||
} | |||
fixStatTimFields(stat) | |||
return nil | |||
} | |||
func Stat(path string, statptr *Stat_t) error { | |||
err := stat(path, statptr) | |||
if err != nil { | |||
return err | |||
} | |||
fixStatTimFields(statptr) | |||
return nil | |||
} |
@@ -2,6 +2,7 @@ | |||
// Use of this source code is governed by a BSD-style | |||
// license that can be found in the LICENSE file. | |||
//go:build darwin || dragonfly || freebsd || netbsd || openbsd | |||
// +build darwin dragonfly freebsd netbsd openbsd | |||
// BSD system call wrappers shared by *BSD based systems | |||
@@ -18,6 +19,21 @@ import ( | |||
"unsafe" | |||
) | |||
const ImplementsGetwd = true | |||
func Getwd() (string, error) { | |||
var buf [PathMax]byte | |||
_, err := Getcwd(buf[0:]) | |||
if err != nil { | |||
return "", err | |||
} | |||
n := clen(buf[:]) | |||
if n < 1 { | |||
return "", EINVAL | |||
} | |||
return string(buf[:n]), nil | |||
} | |||
/* | |||
* Wrapped | |||
*/ | |||
@@ -63,15 +79,6 @@ func Setgroups(gids []int) (err error) { | |||
return setgroups(len(a), &a[0]) | |||
} | |||
func ReadDirent(fd int, buf []byte) (n int, err error) { | |||
// Final argument is (basep *uintptr) and the syscall doesn't take nil. | |||
// 64 bits should be enough. (32 bits isn't even on 386). Since the | |||
// actual system call is getdirentries64, 64 is a good guess. | |||
// TODO(rsc): Can we use a single global basep for all calls? | |||
var base = (*uintptr)(unsafe.Pointer(new(uint64))) | |||
return Getdirentries(fd, buf, base) | |||
} | |||
// Wait status is 7 bits at bottom, either 0 (exited), | |||
// 0x7F (stopped), or a signal number that caused an exit. | |||
// The 0x80 bit is whether there was a core dump. | |||
@@ -86,6 +93,7 @@ const ( | |||
shift = 8 | |||
exited = 0 | |||
killed = 9 | |||
stopped = 0x7F | |||
) | |||
@@ -112,6 +120,8 @@ func (w WaitStatus) CoreDump() bool { return w.Signaled() && w&core != 0 } | |||
func (w WaitStatus) Stopped() bool { return w&mask == stopped && syscall.Signal(w>>shift) != SIGSTOP } | |||
func (w WaitStatus) Killed() bool { return w&mask == killed && syscall.Signal(w>>shift) != SIGKILL } | |||
func (w WaitStatus) Continued() bool { return w&mask == stopped && syscall.Signal(w>>shift) == SIGSTOP } | |||
func (w WaitStatus) StopSignal() syscall.Signal { | |||
@@ -153,9 +163,7 @@ func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) { | |||
p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port)) | |||
p[0] = byte(sa.Port >> 8) | |||
p[1] = byte(sa.Port) | |||
for i := 0; i < len(sa.Addr); i++ { | |||
sa.raw.Addr[i] = sa.Addr[i] | |||
} | |||
sa.raw.Addr = sa.Addr | |||
return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil | |||
} | |||
@@ -169,9 +177,7 @@ func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) { | |||
p[0] = byte(sa.Port >> 8) | |||
p[1] = byte(sa.Port) | |||
sa.raw.Scope_id = sa.ZoneId | |||
for i := 0; i < len(sa.Addr); i++ { | |||
sa.raw.Addr[i] = sa.Addr[i] | |||
} | |||
sa.raw.Addr = sa.Addr | |||
return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil | |||
} | |||
@@ -200,9 +206,7 @@ func (sa *SockaddrDatalink) sockaddr() (unsafe.Pointer, _Socklen, error) { | |||
sa.raw.Nlen = sa.Nlen | |||
sa.raw.Alen = sa.Alen | |||
sa.raw.Slen = sa.Slen | |||
for i := 0; i < len(sa.raw.Data); i++ { | |||
sa.raw.Data[i] = sa.Data[i] | |||
} | |||
sa.raw.Data = sa.Data | |||
return unsafe.Pointer(&sa.raw), SizeofSockaddrDatalink, nil | |||
} | |||
@@ -218,9 +222,7 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) { | |||
sa.Nlen = pp.Nlen | |||
sa.Alen = pp.Alen | |||
sa.Slen = pp.Slen | |||
for i := 0; i < len(sa.Data); i++ { | |||
sa.Data[i] = pp.Data[i] | |||
} | |||
sa.Data = pp.Data | |||
return sa, nil | |||
case AF_UNIX: | |||
@@ -243,7 +245,7 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) { | |||
break | |||
} | |||
} | |||
bytes := (*[10000]byte)(unsafe.Pointer(&pp.Path[0]))[0:n] | |||
bytes := (*[len(pp.Path)]byte)(unsafe.Pointer(&pp.Path[0]))[0:n] | |||
sa.Name = string(bytes) | |||
return sa, nil | |||
@@ -252,9 +254,7 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) { | |||
sa := new(SockaddrInet4) | |||
p := (*[2]byte)(unsafe.Pointer(&pp.Port)) | |||
sa.Port = int(p[0])<<8 + int(p[1]) | |||
for i := 0; i < len(sa.Addr); i++ { | |||
sa.Addr[i] = pp.Addr[i] | |||
} | |||
sa.Addr = pp.Addr | |||
return sa, nil | |||
case AF_INET6: | |||
@@ -263,12 +263,10 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) { | |||
p := (*[2]byte)(unsafe.Pointer(&pp.Port)) | |||
sa.Port = int(p[0])<<8 + int(p[1]) | |||
sa.ZoneId = pp.Scope_id | |||
for i := 0; i < len(sa.Addr); i++ { | |||
sa.Addr[i] = pp.Addr[i] | |||
} | |||
sa.Addr = pp.Addr | |||
return sa, nil | |||
} | |||
return nil, EAFNOSUPPORT | |||
return anyToSockaddrGOOS(fd, rsa) | |||
} | |||
func Accept(fd int) (nfd int, sa Sockaddr, err error) { | |||
@@ -278,7 +276,7 @@ func Accept(fd int) (nfd int, sa Sockaddr, err error) { | |||
if err != nil { | |||
return | |||
} | |||
if runtime.GOOS == "darwin" && len == 0 { | |||
if (runtime.GOOS == "darwin" || runtime.GOOS == "ios") && len == 0 { | |||
// Accepted socket has no address. | |||
// This is likely due to a bug in xnu kernels, | |||
// where instead of ECONNABORTED error socket | |||
@@ -309,7 +307,7 @@ func Getsockname(fd int) (sa Sockaddr, err error) { | |||
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) | |||
// GetsockoptString returns the string value of the socket option opt for the | |||
// socket associated with fd at the given socket level. | |||
@@ -323,84 +321,66 @@ func GetsockoptString(fd, level, opt int) (string, error) { | |||
return string(buf[:vallen-1]), nil | |||
} | |||
//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 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) | |||
func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) { | |||
func recvmsgRaw(fd int, iov []Iovec, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) { | |||
var msg Msghdr | |||
var rsa RawSockaddrAny | |||
msg.Name = (*byte)(unsafe.Pointer(&rsa)) | |||
msg.Name = (*byte)(unsafe.Pointer(rsa)) | |||
msg.Namelen = uint32(SizeofSockaddrAny) | |||
var iov Iovec | |||
if len(p) > 0 { | |||
iov.Base = (*byte)(unsafe.Pointer(&p[0])) | |||
iov.SetLen(len(p)) | |||
} | |||
var dummy byte | |||
if len(oob) > 0 { | |||
// receive at least one normal byte | |||
if len(p) == 0 { | |||
iov.Base = &dummy | |||
iov.SetLen(1) | |||
if emptyIovecs(iov) { | |||
var iova [1]Iovec | |||
iova[0].Base = &dummy | |||
iova[0].SetLen(1) | |||
iov = iova[:] | |||
} | |||
msg.Control = (*byte)(unsafe.Pointer(&oob[0])) | |||
msg.SetControllen(len(oob)) | |||
} | |||
msg.Iov = &iov | |||
msg.Iovlen = 1 | |||
if len(iov) > 0 { | |||
msg.Iov = &iov[0] | |||
msg.SetIovlen(len(iov)) | |||
} | |||
if n, err = recvmsg(fd, &msg, flags); err != nil { | |||
return | |||
} | |||
oobn = int(msg.Controllen) | |||
recvflags = int(msg.Flags) | |||
// source address is only specified if the socket is unconnected | |||
if rsa.Addr.Family != AF_UNSPEC { | |||
from, err = anyToSockaddr(fd, &rsa) | |||
} | |||
return | |||
} | |||
//sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error) | |||
func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) { | |||
_, err = SendmsgN(fd, p, oob, to, flags) | |||
return | |||
} | |||
func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) { | |||
var ptr unsafe.Pointer | |||
var salen _Socklen | |||
if to != nil { | |||
ptr, salen, err = to.sockaddr() | |||
if err != nil { | |||
return 0, err | |||
} | |||
} | |||
func sendmsgN(fd int, iov []Iovec, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) { | |||
var msg Msghdr | |||
msg.Name = (*byte)(unsafe.Pointer(ptr)) | |||
msg.Namelen = uint32(salen) | |||
var iov Iovec | |||
if len(p) > 0 { | |||
iov.Base = (*byte)(unsafe.Pointer(&p[0])) | |||
iov.SetLen(len(p)) | |||
} | |||
var dummy byte | |||
var empty bool | |||
if len(oob) > 0 { | |||
// send at least one normal byte | |||
if len(p) == 0 { | |||
iov.Base = &dummy | |||
iov.SetLen(1) | |||
empty = emptyIovecs(iov) | |||
if empty { | |||
var iova [1]Iovec | |||
iova[0].Base = &dummy | |||
iova[0].SetLen(1) | |||
iov = iova[:] | |||
} | |||
msg.Control = (*byte)(unsafe.Pointer(&oob[0])) | |||
msg.SetControllen(len(oob)) | |||
} | |||
msg.Iov = &iov | |||
msg.Iovlen = 1 | |||
if len(iov) > 0 { | |||
msg.Iov = &iov[0] | |||
msg.SetIovlen(len(iov)) | |||
} | |||
if n, err = sendmsg(fd, &msg, flags); err != nil { | |||
return 0, err | |||
} | |||
if len(oob) > 0 && len(p) == 0 { | |||
if len(oob) > 0 && empty { | |||
n = 0 | |||
} | |||
return n, nil | |||
@@ -419,8 +399,6 @@ func Kevent(kq int, changes, events []Kevent_t, timeout *Timespec) (n int, err e | |||
return kevent(kq, change, len(changes), event, len(events), timeout) | |||
} | |||
//sys sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) = SYS___SYSCTL | |||
// sysctlmib translates name to mib number and appends any additional args. | |||
func sysctlmib(name string, args ...int) ([]_C_int, error) { | |||
// Translate name to mib number. | |||
@@ -518,6 +496,40 @@ func SysctlRaw(name string, args ...int) ([]byte, error) { | |||
return buf[:n], 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 | |||
} | |||
func SysctlTimeval(name string) (*Timeval, error) { | |||
mib, err := sysctlmib(name) | |||
if err != nil { | |||
return nil, err | |||
} | |||
var tv Timeval | |||
n := uintptr(unsafe.Sizeof(tv)) | |||
if err := sysctl(mib, (*byte)(unsafe.Pointer(&tv)), &n, nil, 0); err != nil { | |||
return nil, err | |||
} | |||
if n != unsafe.Sizeof(tv) { | |||
return nil, EIO | |||
} | |||
return &tv, nil | |||
} | |||
//sys utimes(path string, timeval *[2]Timeval) (err error) | |||
func Utimes(path string, tv []Timeval) error { | |||
@@ -541,12 +553,7 @@ func UtimesNano(path string, ts []Timespec) error { | |||
if len(ts) != 2 { | |||
return EINVAL | |||
} | |||
// Darwin setattrlist can set nanosecond timestamps | |||
err := setattrlistTimes(path, ts, 0) | |||
if err != ENOSYS { | |||
return err | |||
} | |||
err = utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0) | |||
err := utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0) | |||
if err != ENOSYS { | |||
return err | |||
} | |||
@@ -566,10 +573,6 @@ func UtimesNanoAt(dirfd int, path string, ts []Timespec, flags int) error { | |||
if len(ts) != 2 { | |||
return EINVAL | |||
} | |||
err := setattrlistTimes(path, ts, flags) | |||
if err != ENOSYS { | |||
return err | |||
} | |||
return utimensat(dirfd, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), flags) | |||
} | |||
@@ -585,9 +588,7 @@ func Futimes(fd int, tv []Timeval) error { | |||
return futimes(fd, (*[2]Timeval)(unsafe.Pointer(&tv[0]))) | |||
} | |||
//sys fcntl(fd int, cmd int, arg int) (val int, err error) | |||
//sys poll(fds *PollFd, nfds int, timeout int) (n int, err error) | |||
//sys poll(fds *PollFd, nfds int, timeout int) (n int, err error) | |||
func Poll(fds []PollFd, timeout int) (n int, err error) { | |||
if len(fds) == 0 { | |||
@@ -13,27 +13,100 @@ | |||
package unix | |||
import ( | |||
"errors" | |||
"fmt" | |||
"runtime" | |||
"syscall" | |||
"unsafe" | |||
) | |||
const ImplementsGetwd = true | |||
func Getwd() (string, error) { | |||
buf := make([]byte, 2048) | |||
attrs, err := getAttrList(".", attrList{CommonAttr: attrCmnFullpath}, buf, 0) | |||
if err == nil && len(attrs) == 1 && len(attrs[0]) >= 2 { | |||
wd := string(attrs[0]) | |||
// Sanity check that it's an absolute path and ends | |||
// in a null byte, which we then strip. | |||
if wd[0] == '/' && wd[len(wd)-1] == 0 { | |||
return wd[:len(wd)-1], nil | |||
//sys closedir(dir uintptr) (err error) | |||
//sys readdir_r(dir uintptr, entry *Dirent, result **Dirent) (res Errno) | |||
func fdopendir(fd int) (dir uintptr, err error) { | |||
r0, _, e1 := syscall_syscallPtr(libc_fdopendir_trampoline_addr, uintptr(fd), 0, 0) | |||
dir = uintptr(r0) | |||
if e1 != 0 { | |||
err = errnoErr(e1) | |||
} | |||
return | |||
} | |||
var libc_fdopendir_trampoline_addr uintptr | |||
//go:cgo_import_dynamic libc_fdopendir fdopendir "/usr/lib/libSystem.B.dylib" | |||
func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) { | |||
// Simulate Getdirentries using fdopendir/readdir_r/closedir. | |||
// We store the number of entries to skip in the seek | |||
// offset of fd. See issue #31368. | |||
// It's not the full required semantics, but should handle the case | |||
// of calling Getdirentries or ReadDirent repeatedly. | |||
// It won't handle assigning the results of lseek to *basep, or handle | |||
// the directory being edited underfoot. | |||
skip, err := Seek(fd, 0, 1 /* SEEK_CUR */) | |||
if err != nil { | |||
return 0, err | |||
} | |||
// We need to duplicate the incoming file descriptor | |||
// because the caller expects to retain control of it, but | |||
// fdopendir expects to take control of its argument. | |||
// Just Dup'ing the file descriptor is not enough, as the | |||
// result shares underlying state. Use Openat to make a really | |||
// new file descriptor referring to the same directory. | |||
fd2, err := Openat(fd, ".", O_RDONLY, 0) | |||
if err != nil { | |||
return 0, err | |||
} | |||
d, err := fdopendir(fd2) | |||
if err != nil { | |||
Close(fd2) | |||
return 0, err | |||
} | |||
defer closedir(d) | |||
var cnt int64 | |||
for { | |||
var entry Dirent | |||
var entryp *Dirent | |||
e := readdir_r(d, &entry, &entryp) | |||
if e != 0 { | |||
return n, errnoErr(e) | |||
} | |||
if entryp == nil { | |||
break | |||
} | |||
if skip > 0 { | |||
skip-- | |||
cnt++ | |||
continue | |||
} | |||
reclen := int(entry.Reclen) | |||
if reclen > len(buf) { | |||
// Not enough room. Return for now. | |||
// The counter will let us know where we should start up again. | |||
// Note: this strategy for suspending in the middle and | |||
// restarting is O(n^2) in the length of the directory. Oh well. | |||
break | |||
} | |||
// Copy entry into return buffer. | |||
s := unsafe.Slice((*byte)(unsafe.Pointer(&entry)), reclen) | |||
copy(buf, s) | |||
buf = buf[reclen:] | |||
n += reclen | |||
cnt++ | |||
} | |||
// Set the seek offset of the input fd to record | |||
// how many files we've already returned. | |||
_, err = Seek(fd, cnt, 0 /* SEEK_SET */) | |||
if err != nil { | |||
return n, err | |||
} | |||
// If pkg/os/getwd.go gets ENOTSUP, it will fall back to the | |||
// slow algorithm. | |||
return "", ENOTSUP | |||
return n, nil | |||
} | |||
// SockaddrDatalink implements the Sockaddr interface for AF_LINK type sockets. | |||
@@ -49,6 +122,72 @@ type SockaddrDatalink struct { | |||
raw RawSockaddrDatalink | |||
} | |||
// SockaddrCtl implements the Sockaddr interface for AF_SYSTEM type sockets. | |||
type SockaddrCtl struct { | |||
ID uint32 | |||
Unit uint32 | |||
raw RawSockaddrCtl | |||
} | |||
func (sa *SockaddrCtl) sockaddr() (unsafe.Pointer, _Socklen, error) { | |||
sa.raw.Sc_len = SizeofSockaddrCtl | |||
sa.raw.Sc_family = AF_SYSTEM | |||
sa.raw.Ss_sysaddr = AF_SYS_CONTROL | |||
sa.raw.Sc_id = sa.ID | |||
sa.raw.Sc_unit = sa.Unit | |||
return unsafe.Pointer(&sa.raw), SizeofSockaddrCtl, nil | |||
} | |||
// SockaddrVM implements the Sockaddr interface for AF_VSOCK type sockets. | |||
// SockaddrVM provides access to Darwin VM sockets: a mechanism that enables | |||
// bidirectional communication between a hypervisor and its guest virtual | |||
// machines. | |||
type SockaddrVM struct { | |||
// CID and Port specify a context ID and port address for a VM socket. | |||
// Guests have a unique CID, and hosts may have a well-known CID of: | |||
// - VMADDR_CID_HYPERVISOR: refers to the hypervisor process. | |||
// - VMADDR_CID_LOCAL: refers to local communication (loopback). | |||
// - VMADDR_CID_HOST: refers to other processes on the host. | |||
CID uint32 | |||
Port uint32 | |||
raw RawSockaddrVM | |||
} | |||
func (sa *SockaddrVM) sockaddr() (unsafe.Pointer, _Socklen, error) { | |||
sa.raw.Len = SizeofSockaddrVM | |||
sa.raw.Family = AF_VSOCK | |||
sa.raw.Port = sa.Port | |||
sa.raw.Cid = sa.CID | |||
return unsafe.Pointer(&sa.raw), SizeofSockaddrVM, nil | |||
} | |||
func anyToSockaddrGOOS(fd int, rsa *RawSockaddrAny) (Sockaddr, error) { | |||
switch rsa.Addr.Family { | |||
case AF_SYSTEM: | |||
pp := (*RawSockaddrCtl)(unsafe.Pointer(rsa)) | |||
if pp.Ss_sysaddr == AF_SYS_CONTROL { | |||
sa := new(SockaddrCtl) | |||
sa.ID = pp.Sc_id | |||
sa.Unit = pp.Sc_unit | |||
return sa, nil | |||
} | |||
case AF_VSOCK: | |||
pp := (*RawSockaddrVM)(unsafe.Pointer(rsa)) | |||
sa := &SockaddrVM{ | |||
CID: pp.Cid, | |||
Port: pp.Port, | |||
} | |||
return sa, nil | |||
} | |||
return nil, EAFNOSUPPORT | |||
} | |||
// Some external packages rely on SYS___SYSCTL being defined to implement their | |||
// own sysctl wrappers. Provide it here, even though direct syscalls are no | |||
// longer supported on darwin. | |||
const SYS___SYSCTL = SYS_SYSCTL | |||
// Translate "kern.hostname" to []_C_int{0,1,2,3}. | |||
func nametomib(name string) (mib []_C_int, err error) { | |||
const siz = unsafe.Sizeof(mib[0]) | |||
@@ -77,87 +216,33 @@ func nametomib(name string) (mib []_C_int, err error) { | |||
return buf[0 : n/siz], nil | |||
} | |||
//sys ptrace(request int, pid int, addr uintptr, data uintptr) (err error) | |||
func PtraceAttach(pid int) (err error) { return ptrace(PT_ATTACH, pid, 0, 0) } | |||
func PtraceDetach(pid int) (err error) { return ptrace(PT_DETACH, pid, 0, 0) } | |||
const ( | |||
attrBitMapCount = 5 | |||
attrCmnFullpath = 0x08000000 | |||
) | |||
type attrList struct { | |||
bitmapCount uint16 | |||
_ uint16 | |||
CommonAttr uint32 | |||
VolAttr uint32 | |||
DirAttr uint32 | |||
FileAttr uint32 | |||
Forkattr uint32 | |||
func direntIno(buf []byte) (uint64, bool) { | |||
return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino)) | |||
} | |||
func getAttrList(path string, attrList attrList, attrBuf []byte, options uint) (attrs [][]byte, err error) { | |||
if len(attrBuf) < 4 { | |||
return nil, errors.New("attrBuf too small") | |||
} | |||
attrList.bitmapCount = attrBitMapCount | |||
var _p0 *byte | |||
_p0, err = BytePtrFromString(path) | |||
if err != nil { | |||
return nil, err | |||
} | |||
_, _, e1 := Syscall6( | |||
SYS_GETATTRLIST, | |||
uintptr(unsafe.Pointer(_p0)), | |||
uintptr(unsafe.Pointer(&attrList)), | |||
uintptr(unsafe.Pointer(&attrBuf[0])), | |||
uintptr(len(attrBuf)), | |||
uintptr(options), | |||
0, | |||
) | |||
if e1 != 0 { | |||
return nil, e1 | |||
} | |||
size := *(*uint32)(unsafe.Pointer(&attrBuf[0])) | |||
// dat is the section of attrBuf that contains valid data, | |||
// without the 4 byte length header. All attribute offsets | |||
// are relative to dat. | |||
dat := attrBuf | |||
if int(size) < len(attrBuf) { | |||
dat = dat[:size] | |||
} | |||
dat = dat[4:] // remove length prefix | |||
func direntReclen(buf []byte) (uint64, bool) { | |||
return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen)) | |||
} | |||
for i := uint32(0); int(i) < len(dat); { | |||
header := dat[i:] | |||
if len(header) < 8 { | |||
return attrs, errors.New("truncated attribute header") | |||
} | |||
datOff := *(*int32)(unsafe.Pointer(&header[0])) | |||
attrLen := *(*uint32)(unsafe.Pointer(&header[4])) | |||
if datOff < 0 || uint32(datOff)+attrLen > uint32(len(dat)) { | |||
return attrs, errors.New("truncated results; attrBuf too small") | |||
} | |||
end := uint32(datOff) + attrLen | |||
attrs = append(attrs, dat[datOff:end]) | |||
i = end | |||
if r := i % 4; r != 0 { | |||
i += (4 - r) | |||
} | |||
} | |||
return | |||
func direntNamlen(buf []byte) (uint64, bool) { | |||
return readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen)) | |||
} | |||
//sysnb pipe() (r int, w int, err error) | |||
func PtraceAttach(pid int) (err error) { return ptrace(PT_ATTACH, pid, 0, 0) } | |||
func PtraceDetach(pid int) (err error) { return ptrace(PT_DETACH, pid, 0, 0) } | |||
//sysnb pipe(p *[2]int32) (err error) | |||
func Pipe(p []int) (err error) { | |||
if len(p) != 2 { | |||
return EINVAL | |||
} | |||
p[0], p[1], err = pipe() | |||
var x [2]int32 | |||
err = pipe(&x) | |||
if err == nil { | |||
p[0] = int(x[0]) | |||
p[1] = int(x[1]) | |||
} | |||
return | |||
} | |||
@@ -168,12 +253,7 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { | |||
_p0 = unsafe.Pointer(&buf[0]) | |||
bufsize = unsafe.Sizeof(Statfs_t{}) * uintptr(len(buf)) | |||
} | |||
r0, _, e1 := Syscall(SYS_GETFSSTAT64, uintptr(_p0), bufsize, uintptr(flags)) | |||
n = int(r0) | |||
if e1 != 0 { | |||
err = e1 | |||
} | |||
return | |||
return getfsstat(_p0, bufsize, flags) | |||
} | |||
func xattrPointer(dest []byte) *byte { | |||
@@ -282,88 +362,50 @@ 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 { | |||
_p0, err := BytePtrFromString(path) | |||
if err != nil { | |||
return err | |||
} | |||
var attrList attrList | |||
attrList.bitmapCount = ATTR_BIT_MAP_COUNT | |||
attrList.CommonAttr = ATTR_CMN_MODTIME | ATTR_CMN_ACCTIME | |||
// order is mtime, atime: the opposite of Chtimes | |||
attributes := [2]Timespec{times[1], times[0]} | |||
options := 0 | |||
if flags&AT_SYMLINK_NOFOLLOW != 0 { | |||
options |= FSOPT_NOFOLLOW | |||
} | |||
_, _, e1 := Syscall6( | |||
SYS_SETATTRLIST, | |||
uintptr(unsafe.Pointer(_p0)), | |||
uintptr(unsafe.Pointer(&attrList)), | |||
uintptr(unsafe.Pointer(&attributes)), | |||
uintptr(unsafe.Sizeof(attributes)), | |||
uintptr(options), | |||
0, | |||
) | |||
if e1 != 0 { | |||
return e1 | |||
} | |||
return nil | |||
} | |||
func utimensat(dirfd int, path string, times *[2]Timespec, flags int) error { | |||
// Darwin doesn't support SYS_UTIMENSAT | |||
return ENOSYS | |||
} | |||
//sys utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) | |||
/* | |||
* Wrapped | |||
*/ | |||
//sys fcntl(fd int, cmd int, arg int) (val int, err error) | |||
//sys kill(pid int, signum int, posix int) (err error) | |||
func Kill(pid int, signum syscall.Signal) (err error) { return kill(pid, int(signum), 1) } | |||
//sys ioctl(fd int, req uint, arg uintptr) (err error) | |||
// ioctl itself should not be exposed directly, but additional get/set | |||
// functions for specific types are permissible. | |||
// IoctlSetInt performs an ioctl operation which sets an integer value | |||
// on fd, using the specified request number. | |||
func IoctlSetInt(fd int, req uint, value int) error { | |||
return ioctl(fd, req, uintptr(value)) | |||
} | |||
func ioctlSetWinsize(fd int, req uint, value *Winsize) error { | |||
return ioctl(fd, req, uintptr(unsafe.Pointer(value))) | |||
func IoctlCtlInfo(fd int, ctlInfo *CtlInfo) error { | |||
err := ioctl(fd, CTLIOCGINFO, uintptr(unsafe.Pointer(ctlInfo))) | |||
runtime.KeepAlive(ctlInfo) | |||
return err | |||
} | |||
func ioctlSetTermios(fd int, req uint, value *Termios) error { | |||
return ioctl(fd, req, uintptr(unsafe.Pointer(value))) | |||
// IfreqMTU is struct ifreq used to get or set a network device's MTU. | |||
type IfreqMTU struct { | |||
Name [IFNAMSIZ]byte | |||
MTU int32 | |||
} | |||
// IoctlGetInt performs an ioctl operation which gets an integer value | |||
// from fd, using the specified request number. | |||
func IoctlGetInt(fd int, req uint) (int, error) { | |||
var value int | |||
err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) | |||
return value, err | |||
// IoctlGetIfreqMTU performs the SIOCGIFMTU ioctl operation on fd to get the MTU | |||
// of the network device specified by ifname. | |||
func IoctlGetIfreqMTU(fd int, ifname string) (*IfreqMTU, error) { | |||
var ifreq IfreqMTU | |||
copy(ifreq.Name[:], ifname) | |||
err := ioctl(fd, SIOCGIFMTU, uintptr(unsafe.Pointer(&ifreq))) | |||
return &ifreq, err | |||
} | |||
func IoctlGetWinsize(fd int, req uint) (*Winsize, error) { | |||
var value Winsize | |||
err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) | |||
return &value, err | |||
// IoctlSetIfreqMTU performs the SIOCSIFMTU ioctl operation on fd to set the MTU | |||
// of the network device specified by ifreq.Name. | |||
func IoctlSetIfreqMTU(fd int, ifreq *IfreqMTU) error { | |||
err := ioctl(fd, SIOCSIFMTU, uintptr(unsafe.Pointer(ifreq))) | |||
runtime.KeepAlive(ifreq) | |||
return err | |||
} | |||
func IoctlGetTermios(fd int, req uint) (*Termios, error) { | |||
var value Termios | |||
err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) | |||
return &value, err | |||
} | |||
//sys sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) = SYS_SYSCTL | |||
func Uname(uname *Utsname) error { | |||
mib := []_C_int{CTL_KERN, KERN_OSTYPE} | |||
@@ -411,6 +453,99 @@ func Uname(uname *Utsname) error { | |||
return nil | |||
} | |||
func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { | |||
if raceenabled { | |||
raceReleaseMerge(unsafe.Pointer(&ioSync)) | |||
} | |||
var length = int64(count) | |||
err = sendfile(infd, outfd, *offset, &length, nil, 0) | |||
written = int(length) | |||
return | |||
} | |||
func GetsockoptIPMreqn(fd, level, opt int) (*IPMreqn, error) { | |||
var value IPMreqn | |||
vallen := _Socklen(SizeofIPMreqn) | |||
errno := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen) | |||
return &value, errno | |||
} | |||
func SetsockoptIPMreqn(fd, level, opt int, mreq *IPMreqn) (err error) { | |||
return setsockopt(fd, level, opt, unsafe.Pointer(mreq), unsafe.Sizeof(*mreq)) | |||
} | |||
// GetsockoptXucred is a getsockopt wrapper that returns an Xucred struct. | |||
// The usual level and opt are SOL_LOCAL and LOCAL_PEERCRED, respectively. | |||
func GetsockoptXucred(fd, level, opt int) (*Xucred, error) { | |||
x := new(Xucred) | |||
vallen := _Socklen(SizeofXucred) | |||
err := getsockopt(fd, level, opt, unsafe.Pointer(x), &vallen) | |||
return x, err | |||
} | |||
func GetsockoptTCPConnectionInfo(fd, level, opt int) (*TCPConnectionInfo, error) { | |||
var value TCPConnectionInfo | |||
vallen := _Socklen(SizeofTCPConnectionInfo) | |||
err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen) | |||
return &value, err | |||
} | |||
func SysctlKinfoProc(name string, args ...int) (*KinfoProc, error) { | |||
mib, err := sysctlmib(name, args...) | |||
if err != nil { | |||
return nil, err | |||
} | |||
var kinfo KinfoProc | |||
n := uintptr(SizeofKinfoProc) | |||
if err := sysctl(mib, (*byte)(unsafe.Pointer(&kinfo)), &n, nil, 0); err != nil { | |||
return nil, err | |||
} | |||
if n != SizeofKinfoProc { | |||
return nil, EIO | |||
} | |||
return &kinfo, nil | |||
} | |||
func SysctlKinfoProcSlice(name string, args ...int) ([]KinfoProc, error) { | |||
mib, err := sysctlmib(name, args...) | |||
if err != nil { | |||
return nil, err | |||
} | |||
// Find size. | |||
n := uintptr(0) | |||
if err := sysctl(mib, nil, &n, nil, 0); err != nil { | |||
return nil, err | |||
} | |||
if n == 0 { | |||
return nil, nil | |||
} | |||
if n%SizeofKinfoProc != 0 { | |||
return nil, fmt.Errorf("sysctl() returned a size of %d, which is not a multiple of %d", n, SizeofKinfoProc) | |||
} | |||
// Read into buffer of that size. | |||
buf := make([]KinfoProc, n/SizeofKinfoProc) | |||
if err := sysctl(mib, (*byte)(unsafe.Pointer(&buf[0])), &n, nil, 0); err != nil { | |||
return nil, err | |||
} | |||
if n%SizeofKinfoProc != 0 { | |||
return nil, fmt.Errorf("sysctl() returned a size of %d, which is not a multiple of %d", n, SizeofKinfoProc) | |||
} | |||
// The actual call may return less than the original reported required | |||
// size so ensure we deal with that. | |||
return buf[:n/SizeofKinfoProc], nil | |||
} | |||
//sys sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error) | |||
//sys shmat(id int, addr uintptr, flag int) (ret uintptr, err error) | |||
//sys shmctl(id int, cmd int, buf *SysvShmDesc) (result int, err error) | |||
//sys shmdt(addr uintptr) (err error) | |||
//sys shmget(key int, size int, flag int) (id int, err error) | |||
/* | |||
* Exposed directly | |||
*/ | |||
@@ -421,7 +556,10 @@ func Uname(uname *Utsname) error { | |||
//sys Chmod(path string, mode uint32) (err error) | |||
//sys Chown(path string, uid int, gid int) (err error) | |||
//sys Chroot(path string) (err error) | |||
//sys ClockGettime(clockid int32, time *Timespec) (err error) | |||
//sys Close(fd int) (err error) | |||
//sys Clonefile(src string, dst string, flags int) (err error) | |||
//sys Clonefileat(srcDirfd int, src string, dstDirfd int, dst string, flags int) (err error) | |||
//sys Dup(fd int) (nfd int, err error) | |||
//sys Dup2(from int, to int) (err error) | |||
//sys Exchangedata(path1 string, path2 string, options int) (err error) | |||
@@ -433,14 +571,12 @@ func Uname(uname *Utsname) error { | |||
//sys Fchmodat(dirfd int, path string, mode uint32, flags 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 Fclonefileat(srcDirfd int, dstDirfd int, dst string, flags int) (err error) | |||
//sys Flock(fd int, how int) (err error) | |||
//sys Fpathconf(fd int, name int) (val int, err error) | |||
//sys Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64 | |||
//sys Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) = SYS_FSTATAT64 | |||
//sys Fstatfs(fd int, stat *Statfs_t) (err error) = SYS_FSTATFS64 | |||
//sys Fsync(fd int) (err error) | |||
//sys Ftruncate(fd int, length int64) (err error) | |||
//sys Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) = SYS_GETDIRENTRIES64 | |||
//sys Getcwd(buf []byte) (n int, err error) | |||
//sys Getdtablesize() (size int) | |||
//sysnb Getegid() (egid int) | |||
//sysnb Geteuid() (uid int) | |||
@@ -453,6 +589,7 @@ func Uname(uname *Utsname) error { | |||
//sysnb Getrlimit(which int, lim *Rlimit) (err error) | |||
//sysnb Getrusage(who int, rusage *Rusage) (err error) | |||
//sysnb Getsid(pid int) (sid int, err error) | |||
//sysnb Gettimeofday(tp *Timeval) (err error) | |||
//sysnb Getuid() (uid int) | |||
//sysnb Issetugid() (tainted bool) | |||
//sys Kqueue() (fd int, err error) | |||
@@ -460,16 +597,16 @@ func Uname(uname *Utsname) 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 Lstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64 | |||
//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 Mknod(path string, mode uint32, dev int) (err error) | |||
//sys Mount(fsType string, dir string, flags int, data unsafe.Pointer) (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 Pread(fd int, p []byte, offset int64) (n int, err error) | |||
//sys Pwrite(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 read(fd int, p []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) | |||
@@ -478,7 +615,7 @@ func Uname(uname *Utsname) error { | |||
//sys Revoke(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 Select(n int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (err error) | |||
//sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) | |||
//sys Setegid(egid int) (err error) | |||
//sysnb Seteuid(euid int) (err error) | |||
//sysnb Setgid(gid int) (err error) | |||
@@ -492,8 +629,6 @@ func Uname(uname *Utsname) error { | |||
//sysnb Setsid() (pid int, err error) | |||
//sysnb Settimeofday(tp *Timeval) (err error) | |||
//sysnb Setuid(uid int) (err error) | |||
//sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64 | |||
//sys Statfs(path string, stat *Statfs_t) (err error) = SYS_STATFS64 | |||
//sys Symlink(path string, link string) (err error) | |||
//sys Symlinkat(oldpath string, newdirfd int, newpath string) (err error) | |||
//sys Sync() (err error) | |||
@@ -504,8 +639,8 @@ func Uname(uname *Utsname) error { | |||
//sys Unlinkat(dirfd int, 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 mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) | |||
//sys munmap(addr uintptr, length uintptr) (err error) | |||
//sys mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) | |||
//sys munmap(addr uintptr, length uintptr) (err 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 | |||
@@ -535,7 +670,6 @@ func Uname(uname *Utsname) error { | |||
// Nfssvc | |||
// Getfh | |||
// Quotactl | |||
// Mount | |||
// Csops | |||
// Waitid | |||
// Add_profil | |||
@@ -569,10 +703,6 @@ func Uname(uname *Utsname) error { | |||
// Msgget | |||
// Msgsnd | |||
// Msgrcv | |||
// Shmat | |||
// Shmctl | |||
// Shmdt | |||
// Shmget | |||
// Shm_open | |||
// Shm_unlink | |||
// Sem_open | |||
@@ -1,68 +0,0 @@ | |||
// Copyright 2009 The Go Authors. All rights reserved. | |||
// Use of this source code is governed by a BSD-style | |||
// license that can be found in the LICENSE file. | |||
// +build 386,darwin | |||
package unix | |||
import ( | |||
"syscall" | |||
"unsafe" | |||
) | |||
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)} | |||
} | |||
//sysnb gettimeofday(tp *Timeval) (sec int32, usec int32, err error) | |||
func Gettimeofday(tv *Timeval) (err error) { | |||
// The tv passed to gettimeofday must be non-nil | |||
// but is otherwise unused. The answers come back | |||
// in the two registers. | |||
sec, usec, err := gettimeofday(tv) | |||
tv.Sec = int32(sec) | |||
tv.Usec = int32(usec) | |||
return err | |||
} | |||
func SetKevent(k *Kevent_t, fd, mode, flags int) { | |||
k.Ident = uint32(fd) | |||
k.Filter = int16(mode) | |||
k.Flags = uint16(flags) | |||
} | |||
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) | |||
} | |||
func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { | |||
var length = uint64(count) | |||
_, _, e1 := Syscall9(SYS_SENDFILE, uintptr(infd), uintptr(outfd), uintptr(*offset), uintptr(*offset>>32), uintptr(unsafe.Pointer(&length)), 0, 0, 0, 0) | |||
written = int(length) | |||
if e1 != 0 { | |||
err = e1 | |||
} | |||
return | |||
} | |||
func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno) | |||
// SYS___SYSCTL is used by syscall_bsd.go for all BSDs, but in modern versions | |||
// of darwin/386 the syscall is called sysctl instead of __sysctl. | |||
const SYS___SYSCTL = SYS_SYSCTL |
@@ -2,14 +2,12 @@ | |||
// Use of this source code is governed by a BSD-style | |||
// license that can be found in the LICENSE file. | |||
//go:build amd64 && darwin | |||
// +build amd64,darwin | |||
package unix | |||
import ( | |||
"syscall" | |||
"unsafe" | |||
) | |||
import "syscall" | |||
func setTimespec(sec, nsec int64) Timespec { | |||
return Timespec{Sec: sec, Nsec: nsec} | |||
@@ -19,17 +17,6 @@ func setTimeval(sec, usec int64) Timeval { | |||
return Timeval{Sec: sec, Usec: int32(usec)} | |||
} | |||
//sysnb gettimeofday(tp *Timeval) (sec int64, usec int32, err error) | |||
func Gettimeofday(tv *Timeval) (err error) { | |||
// The tv passed to gettimeofday must be non-nil | |||
// but is otherwise unused. The answers come back | |||
// in the two registers. | |||
sec, usec, err := gettimeofday(tv) | |||
tv.Sec = sec | |||
tv.Usec = usec | |||
return err | |||
} | |||
func SetKevent(k *Kevent_t, fd, mode, flags int) { | |||
k.Ident = uint64(fd) | |||
k.Filter = int16(mode) | |||
@@ -44,25 +31,21 @@ func (msghdr *Msghdr) SetControllen(length int) { | |||
msghdr.Controllen = uint32(length) | |||
} | |||
func (cmsg *Cmsghdr) SetLen(length int) { | |||
cmsg.Len = uint32(length) | |||
func (msghdr *Msghdr) SetIovlen(length int) { | |||
msghdr.Iovlen = int32(length) | |||
} | |||
func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { | |||
var length = uint64(count) | |||
_, _, e1 := Syscall6(SYS_SENDFILE, uintptr(infd), uintptr(outfd), uintptr(*offset), uintptr(unsafe.Pointer(&length)), 0, 0) | |||
written = int(length) | |||
if e1 != 0 { | |||
err = e1 | |||
} | |||
return | |||
func (cmsg *Cmsghdr) SetLen(length int) { | |||
cmsg.Len = uint32(length) | |||
} | |||
func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno) | |||
// SYS___SYSCTL is used by syscall_bsd.go for all BSDs, but in modern versions | |||
// of darwin/amd64 the syscall is called sysctl instead of __sysctl. | |||
const SYS___SYSCTL = SYS_SYSCTL | |||
//sys Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64 | |||
//sys Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) = SYS_FSTATAT64 | |||
//sys Fstatfs(fd int, stat *Statfs_t) (err error) = SYS_FSTATFS64 | |||
//sys getfsstat(buf unsafe.Pointer, size uintptr, flags int) (n int, err error) = SYS_GETFSSTAT64 | |||
//sys Lstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64 | |||
//sys ptrace1(request int, pid int, addr uintptr, data uintptr) (err error) = SYS_ptrace | |||
//sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64 | |||
//sys Statfs(path string, stat *Statfs_t) (err error) = SYS_STATFS64 |
@@ -1,66 +0,0 @@ | |||
// Copyright 2015 The Go Authors. All rights reserved. | |||
// Use of this source code is governed by a BSD-style | |||
// license that can be found in the LICENSE file. | |||
package unix | |||
import ( | |||
"syscall" | |||
"unsafe" | |||
) | |||
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)} | |||
} | |||
//sysnb gettimeofday(tp *Timeval) (sec int32, usec int32, err error) | |||
func Gettimeofday(tv *Timeval) (err error) { | |||
// The tv passed to gettimeofday must be non-nil | |||
// but is otherwise unused. The answers come back | |||
// in the two registers. | |||
sec, usec, err := gettimeofday(tv) | |||
tv.Sec = int32(sec) | |||
tv.Usec = int32(usec) | |||
return err | |||
} | |||
func SetKevent(k *Kevent_t, fd, mode, flags int) { | |||
k.Ident = uint32(fd) | |||
k.Filter = int16(mode) | |||
k.Flags = uint16(flags) | |||
} | |||
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) | |||
} | |||
func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { | |||
var length = uint64(count) | |||
_, _, e1 := Syscall9(SYS_SENDFILE, uintptr(infd), uintptr(outfd), uintptr(*offset), uintptr(*offset>>32), uintptr(unsafe.Pointer(&length)), 0, 0, 0, 0) | |||
written = int(length) | |||
if e1 != 0 { | |||
err = e1 | |||
} | |||
return | |||
} | |||
func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno) // sic | |||
// SYS___SYSCTL is used by syscall_bsd.go for all BSDs, but in modern versions | |||
// of darwin/arm the syscall is called sysctl instead of __sysctl. | |||
const SYS___SYSCTL = SYS_SYSCTL |
@@ -2,14 +2,12 @@ | |||
// Use of this source code is governed by a BSD-style | |||
// license that can be found in the LICENSE file. | |||
//go:build arm64 && darwin | |||
// +build arm64,darwin | |||
package unix | |||
import ( | |||
"syscall" | |||
"unsafe" | |||
) | |||
import "syscall" | |||
func setTimespec(sec, nsec int64) Timespec { | |||
return Timespec{Sec: sec, Nsec: nsec} | |||
@@ -19,17 +17,6 @@ func setTimeval(sec, usec int64) Timeval { | |||
return Timeval{Sec: sec, Usec: int32(usec)} | |||
} | |||
//sysnb gettimeofday(tp *Timeval) (sec int64, usec int32, err error) | |||
func Gettimeofday(tv *Timeval) (err error) { | |||
// The tv passed to gettimeofday must be non-nil | |||
// but is otherwise unused. The answers come back | |||
// in the two registers. | |||
sec, usec, err := gettimeofday(tv) | |||
tv.Sec = sec | |||
tv.Usec = usec | |||
return err | |||
} | |||
func SetKevent(k *Kevent_t, fd, mode, flags int) { | |||
k.Ident = uint64(fd) | |||
k.Filter = int16(mode) | |||
@@ -44,25 +31,21 @@ func (msghdr *Msghdr) SetControllen(length int) { | |||
msghdr.Controllen = uint32(length) | |||
} | |||
func (cmsg *Cmsghdr) SetLen(length int) { | |||
cmsg.Len = uint32(length) | |||
func (msghdr *Msghdr) SetIovlen(length int) { | |||
msghdr.Iovlen = int32(length) | |||
} | |||
func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { | |||
var length = uint64(count) | |||
_, _, e1 := Syscall6(SYS_SENDFILE, uintptr(infd), uintptr(outfd), uintptr(*offset), uintptr(unsafe.Pointer(&length)), 0, 0) | |||
written = int(length) | |||
if e1 != 0 { | |||
err = e1 | |||
} | |||
return | |||
func (cmsg *Cmsghdr) SetLen(length int) { | |||
cmsg.Len = uint32(length) | |||
} | |||
func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno) // sic | |||
// SYS___SYSCTL is used by syscall_bsd.go for all BSDs, but in modern versions | |||
// of darwin/arm64 the syscall is called sysctl instead of __sysctl. | |||
const SYS___SYSCTL = SYS_SYSCTL | |||
//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, stat *Statfs_t) (err error) | |||
//sys getfsstat(buf unsafe.Pointer, size uintptr, flags int) (n int, err error) = SYS_GETFSSTAT | |||
//sys Lstat(path string, stat *Stat_t) (err error) | |||
//sys ptrace1(request int, pid int, addr uintptr, data uintptr) (err error) = SYS_ptrace | |||
//sys Stat(path string, stat *Stat_t) (err error) | |||
//sys Statfs(path string, stat *Statfs_t) (err error) |
@@ -0,0 +1,27 @@ | |||
// 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. | |||
//go:build darwin && go1.12 | |||
// +build darwin,go1.12 | |||
package unix | |||
import _ "unsafe" | |||
// Implemented in the runtime package (runtime/sys_darwin.go) | |||
func syscall_syscall(fn, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) | |||
func syscall_syscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) | |||
func syscall_syscall6X(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) | |||
func syscall_syscall9(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err Errno) // 32-bit only | |||
func syscall_rawSyscall(fn, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) | |||
func syscall_rawSyscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) | |||
func syscall_syscallPtr(fn, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) | |||
//go:linkname syscall_syscall syscall.syscall | |||
//go:linkname syscall_syscall6 syscall.syscall6 | |||
//go:linkname syscall_syscall6X syscall.syscall6X | |||
//go:linkname syscall_syscall9 syscall.syscall9 | |||
//go:linkname syscall_rawSyscall syscall.rawSyscall | |||
//go:linkname syscall_rawSyscall6 syscall.rawSyscall6 | |||
//go:linkname syscall_syscallPtr syscall.syscallPtr |
@@ -12,7 +12,25 @@ | |||
package unix | |||
import "unsafe" | |||
import ( | |||
"sync" | |||
"unsafe" | |||
) | |||
// See version list in https://github.com/DragonFlyBSD/DragonFlyBSD/blob/master/sys/sys/param.h | |||
var ( | |||
osreldateOnce sync.Once | |||
osreldate uint32 | |||
) | |||
// First __DragonFly_version after September 2019 ABI changes | |||
// http://lists.dragonflybsd.org/pipermail/users/2019-September/358280.html | |||
const _dragonflyABIChangeVersion = 500705 | |||
func supportsABI(ver uint32) bool { | |||
osreldateOnce.Do(func() { osreldate, _ = SysctlUint32("kern.osreldate") }) | |||
return osreldate >= ver | |||
} | |||
// SockaddrDatalink implements the Sockaddr interface for AF_LINK type sockets. | |||
type SockaddrDatalink struct { | |||
@@ -29,6 +47,10 @@ type SockaddrDatalink struct { | |||
raw RawSockaddrDatalink | |||
} | |||
func anyToSockaddrGOOS(fd int, rsa *RawSockaddrAny) (Sockaddr, error) { | |||
return nil, EAFNOSUPPORT | |||
} | |||
// Translate "kern.hostname" to []_C_int{0,1,2,3}. | |||
func nametomib(name string) (mib []_C_int, err error) { | |||
const siz = unsafe.Sizeof(mib[0]) | |||
@@ -57,23 +79,60 @@ func nametomib(name string) (mib []_C_int, err error) { | |||
return buf[0 : n/siz], nil | |||
} | |||
//sysnb pipe() (r int, w int, err error) | |||
func direntIno(buf []byte) (uint64, bool) { | |||
return readInt(buf, unsafe.Offsetof(Dirent{}.Fileno), unsafe.Sizeof(Dirent{}.Fileno)) | |||
} | |||
func direntReclen(buf []byte) (uint64, bool) { | |||
namlen, ok := direntNamlen(buf) | |||
if !ok { | |||
return 0, false | |||
} | |||
return (16 + namlen + 1 + 7) &^ 7, true | |||
} | |||
func direntNamlen(buf []byte) (uint64, bool) { | |||
return readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen)) | |||
} | |||
//sysnb pipe() (r int, w int, err error) | |||
func Pipe(p []int) (err error) { | |||
if len(p) != 2 { | |||
return EINVAL | |||
} | |||
p[0], p[1], err = pipe() | |||
r, w, err := pipe() | |||
if err == nil { | |||
p[0], p[1] = r, w | |||
} | |||
return | |||
} | |||
//sysnb pipe2(p *[2]_C_int, flags int) (r int, w int, err error) | |||
func Pipe2(p []int, flags int) (err error) { | |||
if len(p) != 2 { | |||
return EINVAL | |||
} | |||
var pp [2]_C_int | |||
// pipe2 on dragonfly takes an fds array as an argument, but still | |||
// returns the file descriptors. | |||
r, w, err := pipe2(&pp, flags) | |||
if err == nil { | |||
p[0], p[1] = r, w | |||
} | |||
return err | |||
} | |||
//sys extpread(fd int, p []byte, flags int, offset int64) (n int, err error) | |||
func Pread(fd int, p []byte, offset int64) (n int, err error) { | |||
func pread(fd int, p []byte, offset int64) (n int, err error) { | |||
return extpread(fd, p, 0, offset) | |||
} | |||
//sys extpwrite(fd int, p []byte, flags int, offset int64) (n int, err error) | |||
func Pwrite(fd int, p []byte, offset int64) (n int, err error) { | |||
func pwrite(fd int, p []byte, offset int64) (n int, err error) { | |||
return extpwrite(fd, p, 0, offset) | |||
} | |||
@@ -95,23 +154,8 @@ func Accept4(fd, flags int) (nfd int, sa Sockaddr, err error) { | |||
return | |||
} | |||
const ImplementsGetwd = true | |||
//sys Getcwd(buf []byte) (n int, err error) = SYS___GETCWD | |||
func Getwd() (string, error) { | |||
var buf [PathMax]byte | |||
_, err := Getcwd(buf[0:]) | |||
if err != nil { | |||
return "", err | |||
} | |||
n := clen(buf[:]) | |||
if n < 1 { | |||
return "", EINVAL | |||
} | |||
return string(buf[:n]), nil | |||
} | |||
func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { | |||
var _p0 unsafe.Pointer | |||
var bufsize uintptr | |||
@@ -127,49 +171,9 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { | |||
return | |||
} | |||
func setattrlistTimes(path string, times []Timespec, flags int) error { | |||
// used on Darwin for UtimesNano | |||
return ENOSYS | |||
} | |||
//sys ioctl(fd int, req uint, arg uintptr) (err error) | |||
// ioctl itself should not be exposed directly, but additional get/set | |||
// functions for specific types are permissible. | |||
// IoctlSetInt performs an ioctl operation which sets an integer value | |||
// on fd, using the specified request number. | |||
func IoctlSetInt(fd int, req uint, value int) error { | |||
return ioctl(fd, req, uintptr(value)) | |||
} | |||
func ioctlSetWinsize(fd int, req uint, value *Winsize) error { | |||
return ioctl(fd, req, uintptr(unsafe.Pointer(value))) | |||
} | |||
func ioctlSetTermios(fd int, req uint, value *Termios) error { | |||
return ioctl(fd, req, uintptr(unsafe.Pointer(value))) | |||
} | |||
// IoctlGetInt performs an ioctl operation which gets an integer value | |||
// from fd, using the specified request number. | |||
func IoctlGetInt(fd int, req uint) (int, error) { | |||
var value int | |||
err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) | |||
return value, err | |||
} | |||
func IoctlGetWinsize(fd int, req uint) (*Winsize, error) { | |||
var value Winsize | |||
err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) | |||
return &value, err | |||
} | |||
func IoctlGetTermios(fd int, req uint) (*Termios, error) { | |||
var value Termios | |||
err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) | |||
return &value, err | |||
} | |||
//sys sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) = SYS___SYSCTL | |||
func sysctlUname(mib []_C_int, old *byte, oldlen *uintptr) error { | |||
err := sysctl(mib, old, oldlen, nil, 0) | |||
@@ -234,6 +238,13 @@ func Uname(uname *Utsname) error { | |||
return nil | |||
} | |||
func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { | |||
if raceenabled { | |||
raceReleaseMerge(unsafe.Pointer(&ioSync)) | |||
} | |||
return sendfile(outfd, infd, offset, count) | |||
} | |||
/* | |||
* Exposed directly | |||
*/ | |||
@@ -262,6 +273,7 @@ func Uname(uname *Utsname) error { | |||
//sys Fstatfs(fd int, stat *Statfs_t) (err error) | |||
//sys Fsync(fd int) (err error) | |||
//sys Ftruncate(fd int, length int64) (err error) | |||
//sys Getdents(fd int, buf []byte) (n int, err error) | |||
//sys Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) | |||
//sys Getdtablesize() (size int) | |||
//sysnb Getegid() (egid int) | |||
@@ -297,10 +309,11 @@ func Uname(uname *Utsname) error { | |||
//sys read(fd int, p []byte) (n int, err error) | |||
//sys Readlink(path string, buf []byte) (n int, 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 Rmdir(path string) (err error) | |||
//sys Seek(fd int, offset int64, whence int) (newoffset int64, err error) = SYS_LSEEK | |||
//sys Select(n int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (err error) | |||
//sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) | |||
//sysnb Setegid(egid int) (err error) | |||
//sysnb Seteuid(euid int) (err error) | |||
//sysnb Setgid(gid int) (err error) | |||
@@ -327,8 +340,8 @@ func Uname(uname *Utsname) error { | |||
//sys Unlinkat(dirfd int, 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 mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) | |||
//sys munmap(addr uintptr, length uintptr) (err error) | |||
//sys mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) | |||
//sys munmap(addr uintptr, length uintptr) (err 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 accept4(fd int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (nfd int, err error) | |||
@@ -2,6 +2,7 @@ | |||
// Use of this source code is governed by a BSD-style | |||
// license that can be found in the LICENSE file. | |||
//go:build amd64 && dragonfly | |||
// +build amd64,dragonfly | |||
package unix | |||
@@ -33,6 +34,10 @@ func (msghdr *Msghdr) SetControllen(length int) { | |||
msghdr.Controllen = uint32(length) | |||
} | |||
func (msghdr *Msghdr) SetIovlen(length int) { | |||
msghdr.Iovlen = int32(length) | |||
} | |||
func (cmsg *Cmsghdr) SetLen(length int) { | |||
cmsg.Len = uint32(length) | |||
} | |||
@@ -17,25 +17,12 @@ import ( | |||
"unsafe" | |||
) | |||
const ( | |||
SYS_FSTAT_FREEBSD12 = 551 // { int fstat(int fd, _Out_ struct stat *sb); } | |||
SYS_FSTATAT_FREEBSD12 = 552 // { int fstatat(int fd, _In_z_ char *path, \ | |||
SYS_GETDIRENTRIES_FREEBSD12 = 554 // { ssize_t getdirentries(int fd, \ | |||
SYS_STATFS_FREEBSD12 = 555 // { int statfs(_In_z_ char *path, \ | |||
SYS_FSTATFS_FREEBSD12 = 556 // { int fstatfs(int fd, \ | |||
SYS_GETFSSTAT_FREEBSD12 = 557 // { int getfsstat( \ | |||
SYS_MKNODAT_FREEBSD12 = 559 // { int mknodat(int fd, _In_z_ char *path, \ | |||
) | |||
// See https://www.freebsd.org/doc/en_US.ISO8859-1/books/porters-handbook/versions.html. | |||
var ( | |||
osreldateOnce sync.Once | |||
osreldate uint32 | |||
) | |||
// INO64_FIRST from /usr/src/lib/libc/sys/compat-ino64.h | |||
const _ino64First = 1200031 | |||
func supportsABI(ver uint32) bool { | |||
osreldateOnce.Do(func() { osreldate, _ = SysctlUint32("kern.osreldate") }) | |||
return osreldate >= ver | |||
@@ -54,6 +41,10 @@ type SockaddrDatalink struct { | |||
raw RawSockaddrDatalink | |||
} | |||
func anyToSockaddrGOOS(fd int, rsa *RawSockaddrAny) (Sockaddr, error) { | |||
return nil, EAFNOSUPPORT | |||
} | |||
// Translate "kern.hostname" to []_C_int{0,1,2,3}. | |||
func nametomib(name string) (mib []_C_int, err error) { | |||
const siz = unsafe.Sizeof(mib[0]) | |||
@@ -82,6 +73,18 @@ func nametomib(name string) (mib []_C_int, err error) { | |||
return buf[0 : n/siz], nil | |||
} | |||
func direntIno(buf []byte) (uint64, bool) { | |||
return readInt(buf, unsafe.Offsetof(Dirent{}.Fileno), unsafe.Sizeof(Dirent{}.Fileno)) | |||
} | |||
func direntReclen(buf []byte) (uint64, bool) { | |||
return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen)) | |||
} | |||
func direntNamlen(buf []byte) (uint64, bool) { | |||
return readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen)) | |||
} | |||
func Pipe(p []int) (err error) { | |||
return Pipe2(p, 0) | |||
} | |||
@@ -94,8 +97,10 @@ func Pipe2(p []int, flags int) error { | |||
} | |||
var pp [2]_C_int | |||
err := pipe2(&pp, flags) | |||
p[0] = int(pp[0]) | |||
p[1] = int(pp[1]) | |||
if err == nil { | |||
p[0] = int(pp[0]) | |||
p[1] = int(pp[1]) | |||
} | |||
return err | |||
} | |||
@@ -110,6 +115,15 @@ func SetsockoptIPMreqn(fd, level, opt int, mreq *IPMreqn) (err error) { | |||
return setsockopt(fd, level, opt, unsafe.Pointer(mreq), unsafe.Sizeof(*mreq)) | |||
} | |||
// GetsockoptXucred is a getsockopt wrapper that returns an Xucred struct. | |||
// The usual level and opt are SOL_LOCAL and LOCAL_PEERCRED, respectively. | |||
func GetsockoptXucred(fd, level, opt int) (*Xucred, error) { | |||
x := new(Xucred) | |||
vallen := _Socklen(SizeofXucred) | |||
err := getsockopt(fd, level, opt, unsafe.Pointer(x), &vallen) | |||
return x, err | |||
} | |||
func Accept4(fd, flags int) (nfd int, sa Sockaddr, err error) { | |||
var rsa RawSockaddrAny | |||
var len _Socklen = SizeofSockaddrAny | |||
@@ -128,103 +142,28 @@ func Accept4(fd, flags int) (nfd int, sa Sockaddr, err error) { | |||
return | |||
} | |||
const ImplementsGetwd = true | |||
//sys Getcwd(buf []byte) (n int, err error) = SYS___GETCWD | |||
func Getwd() (string, error) { | |||
var buf [PathMax]byte | |||
_, err := Getcwd(buf[0:]) | |||
if err != nil { | |||
return "", err | |||
} | |||
n := clen(buf[:]) | |||
if n < 1 { | |||
return "", EINVAL | |||
} | |||
return string(buf[:n]), nil | |||
} | |||
func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { | |||
var ( | |||
_p0 unsafe.Pointer | |||
bufsize uintptr | |||
oldBuf []statfs_freebsd11_t | |||
needsConvert bool | |||
_p0 unsafe.Pointer | |||
bufsize uintptr | |||
) | |||
if len(buf) > 0 { | |||
if supportsABI(_ino64First) { | |||
_p0 = unsafe.Pointer(&buf[0]) | |||
bufsize = unsafe.Sizeof(Statfs_t{}) * uintptr(len(buf)) | |||
} else { | |||
n := len(buf) | |||
oldBuf = make([]statfs_freebsd11_t, n) | |||
_p0 = unsafe.Pointer(&oldBuf[0]) | |||
bufsize = unsafe.Sizeof(statfs_freebsd11_t{}) * uintptr(n) | |||
needsConvert = true | |||
} | |||
} | |||
var sysno uintptr = SYS_GETFSSTAT | |||
if supportsABI(_ino64First) { | |||
sysno = SYS_GETFSSTAT_FREEBSD12 | |||
_p0 = unsafe.Pointer(&buf[0]) | |||
bufsize = unsafe.Sizeof(Statfs_t{}) * uintptr(len(buf)) | |||
} | |||
r0, _, e1 := Syscall(sysno, uintptr(_p0), bufsize, uintptr(flags)) | |||
r0, _, e1 := Syscall(SYS_GETFSSTAT, uintptr(_p0), bufsize, uintptr(flags)) | |||
n = int(r0) | |||
if e1 != 0 { | |||
err = e1 | |||
} | |||
if e1 == 0 && needsConvert { | |||
for i := range oldBuf { | |||
buf[i].convertFrom(&oldBuf[i]) | |||
} | |||
} | |||
return | |||
} | |||
func setattrlistTimes(path string, times []Timespec, flags int) error { | |||
// used on Darwin for UtimesNano | |||
return ENOSYS | |||
} | |||
//sys ioctl(fd int, req uint, arg uintptr) (err error) | |||
//sys ioctl(fd int, req uint, arg uintptr) (err error) | |||
// ioctl itself should not be exposed directly, but additional get/set | |||
// functions for specific types are permissible. | |||
// IoctlSetInt performs an ioctl operation which sets an integer value | |||
// on fd, using the specified request number. | |||
func IoctlSetInt(fd int, req uint, value int) error { | |||
return ioctl(fd, req, uintptr(value)) | |||
} | |||
func ioctlSetWinsize(fd int, req uint, value *Winsize) error { | |||
return ioctl(fd, req, uintptr(unsafe.Pointer(value))) | |||
} | |||
func ioctlSetTermios(fd int, req uint, value *Termios) error { | |||
return ioctl(fd, req, uintptr(unsafe.Pointer(value))) | |||
} | |||
// IoctlGetInt performs an ioctl operation which gets an integer value | |||
// from fd, using the specified request number. | |||
func IoctlGetInt(fd int, req uint) (int, error) { | |||
var value int | |||
err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) | |||
return value, err | |||
} | |||
func IoctlGetWinsize(fd int, req uint) (*Winsize, error) { | |||
var value Winsize | |||
err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) | |||
return &value, err | |||
} | |||
func IoctlGetTermios(fd int, req uint) (*Termios, error) { | |||
var value Termios | |||
err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) | |||
return &value, err | |||
} | |||
//sys sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) = SYS___SYSCTL | |||
func Uname(uname *Utsname) error { | |||
mib := []_C_int{CTL_KERN, KERN_OSTYPE} | |||
@@ -273,231 +212,98 @@ func Uname(uname *Utsname) error { | |||
} | |||
func Stat(path string, st *Stat_t) (err error) { | |||
var oldStat stat_freebsd11_t | |||
if supportsABI(_ino64First) { | |||
return fstatat_freebsd12(AT_FDCWD, path, st, 0) | |||
} | |||
err = stat(path, &oldStat) | |||
if err != nil { | |||
return err | |||
} | |||
st.convertFrom(&oldStat) | |||
return nil | |||
return Fstatat(AT_FDCWD, path, st, 0) | |||
} | |||
func Lstat(path string, st *Stat_t) (err error) { | |||
var oldStat stat_freebsd11_t | |||
if supportsABI(_ino64First) { | |||
return fstatat_freebsd12(AT_FDCWD, path, st, AT_SYMLINK_NOFOLLOW) | |||
} | |||
err = lstat(path, &oldStat) | |||
if err != nil { | |||
return err | |||
} | |||
st.convertFrom(&oldStat) | |||
return nil | |||
return Fstatat(AT_FDCWD, path, st, AT_SYMLINK_NOFOLLOW) | |||
} | |||
func Fstat(fd int, st *Stat_t) (err error) { | |||
var oldStat stat_freebsd11_t | |||
if supportsABI(_ino64First) { | |||
return fstat_freebsd12(fd, st) | |||
} | |||
err = fstat(fd, &oldStat) | |||
if err != nil { | |||
return err | |||
} | |||
st.convertFrom(&oldStat) | |||
return nil | |||
func Getdents(fd int, buf []byte) (n int, err error) { | |||
return Getdirentries(fd, buf, nil) | |||
} | |||
func Fstatat(fd int, path string, st *Stat_t, flags int) (err error) { | |||
var oldStat stat_freebsd11_t | |||
if supportsABI(_ino64First) { | |||
return fstatat_freebsd12(fd, path, st, flags) | |||
} | |||
err = fstatat(fd, path, &oldStat, flags) | |||
if err != nil { | |||
return err | |||
func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) { | |||
if basep == nil || unsafe.Sizeof(*basep) == 8 { | |||
return getdirentries(fd, buf, (*uint64)(unsafe.Pointer(basep))) | |||
} | |||
// The syscall needs a 64-bit base. On 32-bit machines | |||
// we can't just use the basep passed in. See #32498. | |||
var base uint64 = uint64(*basep) | |||
n, err = getdirentries(fd, buf, &base) | |||
*basep = uintptr(base) | |||
if base>>32 != 0 { | |||
// We can't stuff the base back into a uintptr, so any | |||
// future calls would be suspect. Generate an error. | |||
// EIO is allowed by getdirentries. | |||
err = EIO | |||
} | |||
return | |||
} | |||
st.convertFrom(&oldStat) | |||
return nil | |||
func Mknod(path string, mode uint32, dev uint64) (err error) { | |||
return Mknodat(AT_FDCWD, path, mode, dev) | |||
} | |||
func Statfs(path string, st *Statfs_t) (err error) { | |||
var oldStatfs statfs_freebsd11_t | |||
if supportsABI(_ino64First) { | |||
return statfs_freebsd12(path, st) | |||
} | |||
err = statfs(path, &oldStatfs) | |||
if err != nil { | |||
return err | |||
func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { | |||
if raceenabled { | |||
raceReleaseMerge(unsafe.Pointer(&ioSync)) | |||
} | |||
st.convertFrom(&oldStatfs) | |||
return nil | |||
return sendfile(outfd, infd, offset, count) | |||
} | |||
func Fstatfs(fd int, st *Statfs_t) (err error) { | |||
var oldStatfs statfs_freebsd11_t | |||
if supportsABI(_ino64First) { | |||
return fstatfs_freebsd12(fd, st) | |||
} | |||
err = fstatfs(fd, &oldStatfs) | |||
if err != nil { | |||
return err | |||
} | |||
//sys ptrace(request int, pid int, addr uintptr, data int) (err error) | |||
st.convertFrom(&oldStatfs) | |||
return nil | |||
func PtraceAttach(pid int) (err error) { | |||
return ptrace(PT_ATTACH, pid, 0, 0) | |||
} | |||
func Getdents(fd int, buf []byte) (n int, err error) { | |||
return Getdirentries(fd, buf, nil) | |||
func PtraceCont(pid int, signal int) (err error) { | |||
return ptrace(PT_CONTINUE, pid, 1, signal) | |||
} | |||
func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) { | |||
if supportsABI(_ino64First) { | |||
return getdirentries_freebsd12(fd, buf, basep) | |||
} | |||
// The old syscall entries are smaller than the new. Use 1/4 of the original | |||
// buffer size rounded up to DIRBLKSIZ (see /usr/src/lib/libc/sys/getdirentries.c). | |||
oldBufLen := roundup(len(buf)/4, _dirblksiz) | |||
oldBuf := make([]byte, oldBufLen) | |||
n, err = getdirentries(fd, oldBuf, basep) | |||
if err == nil && n > 0 { | |||
n = convertFromDirents11(buf, oldBuf[:n]) | |||
} | |||
return | |||
func PtraceDetach(pid int) (err error) { | |||
return ptrace(PT_DETACH, pid, 1, 0) | |||
} | |||
func Mknod(path string, mode uint32, dev uint64) (err error) { | |||
var oldDev int | |||
if supportsABI(_ino64First) { | |||
return mknodat_freebsd12(AT_FDCWD, path, mode, dev) | |||
} | |||
oldDev = int(dev) | |||
return mknod(path, mode, oldDev) | |||
func PtraceGetFpRegs(pid int, fpregsout *FpReg) (err error) { | |||
return ptrace(PT_GETFPREGS, pid, uintptr(unsafe.Pointer(fpregsout)), 0) | |||
} | |||
func Mknodat(fd int, path string, mode uint32, dev uint64) (err error) { | |||
var oldDev int | |||
if supportsABI(_ino64First) { | |||
return mknodat_freebsd12(fd, path, mode, dev) | |||
} | |||
oldDev = int(dev) | |||
return mknodat(fd, path, mode, oldDev) | |||
} | |||
// round x to the nearest multiple of y, larger or equal to x. | |||
// | |||
// from /usr/include/sys/param.h Macros for counting and rounding. | |||
// #define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) | |||
func roundup(x, y int) int { | |||
return ((x + y - 1) / y) * y | |||
} | |||
func (s *Stat_t) convertFrom(old *stat_freebsd11_t) { | |||
*s = Stat_t{ | |||
Dev: uint64(old.Dev), | |||
Ino: uint64(old.Ino), | |||
Nlink: uint64(old.Nlink), | |||
Mode: old.Mode, | |||
Uid: old.Uid, | |||
Gid: old.Gid, | |||
Rdev: uint64(old.Rdev), | |||
Atim: old.Atim, | |||
Mtim: old.Mtim, | |||
Ctim: old.Ctim, | |||
Birthtim: old.Birthtim, | |||
Size: old.Size, | |||
Blocks: old.Blocks, | |||
Blksize: old.Blksize, | |||
Flags: old.Flags, | |||
Gen: uint64(old.Gen), | |||
} | |||
func PtraceGetRegs(pid int, regsout *Reg) (err error) { | |||
return ptrace(PT_GETREGS, pid, uintptr(unsafe.Pointer(regsout)), 0) | |||
} | |||
func (s *Statfs_t) convertFrom(old *statfs_freebsd11_t) { | |||
*s = Statfs_t{ | |||
Version: _statfsVersion, | |||
Type: old.Type, | |||
Flags: old.Flags, | |||
Bsize: old.Bsize, | |||
Iosize: old.Iosize, | |||
Blocks: old.Blocks, | |||
Bfree: old.Bfree, | |||
Bavail: old.Bavail, | |||
Files: old.Files, | |||
Ffree: old.Ffree, | |||
Syncwrites: old.Syncwrites, | |||
Asyncwrites: old.Asyncwrites, | |||
Syncreads: old.Syncreads, | |||
Asyncreads: old.Asyncreads, | |||
// Spare | |||
Namemax: old.Namemax, | |||
Owner: old.Owner, | |||
Fsid: old.Fsid, | |||
// Charspare | |||
// Fstypename | |||
// Mntfromname | |||
// Mntonname | |||
} | |||
sl := old.Fstypename[:] | |||
n := clen(*(*[]byte)(unsafe.Pointer(&sl))) | |||
copy(s.Fstypename[:], old.Fstypename[:n]) | |||
sl = old.Mntfromname[:] | |||
n = clen(*(*[]byte)(unsafe.Pointer(&sl))) | |||
copy(s.Mntfromname[:], old.Mntfromname[:n]) | |||
func PtraceLwpEvents(pid int, enable int) (err error) { | |||
return ptrace(PT_LWP_EVENTS, pid, 0, enable) | |||
} | |||
sl = old.Mntonname[:] | |||
n = clen(*(*[]byte)(unsafe.Pointer(&sl))) | |||
copy(s.Mntonname[:], old.Mntonname[:n]) | |||
func PtraceLwpInfo(pid int, info uintptr) (err error) { | |||
return ptrace(PT_LWPINFO, pid, info, int(unsafe.Sizeof(PtraceLwpInfoStruct{}))) | |||
} | |||
func convertFromDirents11(buf []byte, old []byte) int { | |||
const ( | |||
fixedSize = int(unsafe.Offsetof(Dirent{}.Name)) | |||
oldFixedSize = int(unsafe.Offsetof(dirent_freebsd11{}.Name)) | |||
) | |||
func PtracePeekData(pid int, addr uintptr, out []byte) (count int, err error) { | |||
return PtraceIO(PIOD_READ_D, pid, addr, out, SizeofLong) | |||
} | |||
dstPos := 0 | |||
srcPos := 0 | |||
for dstPos+fixedSize < len(buf) && srcPos+oldFixedSize < len(old) { | |||
dstDirent := (*Dirent)(unsafe.Pointer(&buf[dstPos])) | |||
srcDirent := (*dirent_freebsd11)(unsafe.Pointer(&old[srcPos])) | |||
func PtracePeekText(pid int, addr uintptr, out []byte) (count int, err error) { | |||
return PtraceIO(PIOD_READ_I, pid, addr, out, SizeofLong) | |||
} | |||
reclen := roundup(fixedSize+int(srcDirent.Namlen)+1, 8) | |||
if dstPos+reclen > len(buf) { | |||
break | |||
} | |||
func PtracePokeData(pid int, addr uintptr, data []byte) (count int, err error) { | |||
return PtraceIO(PIOD_WRITE_D, pid, addr, data, SizeofLong) | |||
} | |||
dstDirent.Fileno = uint64(srcDirent.Fileno) | |||
dstDirent.Off = 0 | |||
dstDirent.Reclen = uint16(reclen) | |||
dstDirent.Type = srcDirent.Type | |||
dstDirent.Pad0 = 0 | |||
dstDirent.Namlen = uint16(srcDirent.Namlen) | |||
dstDirent.Pad1 = 0 | |||
copy(dstDirent.Name[:], srcDirent.Name[:srcDirent.Namlen]) | |||
padding := buf[dstPos+fixedSize+int(dstDirent.Namlen) : dstPos+reclen] | |||
for i := range padding { | |||
padding[i] = 0 | |||
} | |||
func PtracePokeText(pid int, addr uintptr, data []byte) (count int, err error) { | |||
return PtraceIO(PIOD_WRITE_I, pid, addr, data, SizeofLong) | |||
} | |||
dstPos += int(dstDirent.Reclen) | |||
srcPos += int(srcDirent.Reclen) | |||
} | |||
func PtraceSetRegs(pid int, regs *Reg) (err error) { | |||
return ptrace(PT_SETREGS, pid, uintptr(unsafe.Pointer(regs)), 0) | |||
} | |||
return dstPos | |||
func PtraceSingleStep(pid int) (err error) { | |||
return ptrace(PT_STEP, pid, 1, 0) | |||
} | |||
/* | |||
@@ -539,16 +345,12 @@ func convertFromDirents11(buf []byte, old []byte) int { | |||
//sys Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) | |||
//sys Flock(fd int, how int) (err error) | |||
//sys Fpathconf(fd int, name int) (val int, err error) | |||
//sys fstat(fd int, stat *stat_freebsd11_t) (err error) | |||
//sys fstat_freebsd12(fd int, stat *Stat_t) (err error) | |||
//sys fstatat(fd int, path string, stat *stat_freebsd11_t, flags int) (err error) | |||
//sys fstatat_freebsd12(fd int, path string, stat *Stat_t, flags int) (err error) | |||
//sys fstatfs(fd int, stat *statfs_freebsd11_t) (err error) | |||
//sys fstatfs_freebsd12(fd int, stat *Statfs_t) (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, stat *Statfs_t) (err error) | |||
//sys Fsync(fd int) (err error) | |||
//sys Ftruncate(fd int, length int64) (err error) | |||
//sys getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) | |||
//sys getdirentries_freebsd12(fd int, buf []byte, basep *uintptr) (n int, err error) | |||
//sys getdirentries(fd int, buf []byte, basep *uint64) (n int, err error) | |||
//sys Getdtablesize() (size int) | |||
//sysnb Getegid() (egid int) | |||
//sysnb Geteuid() (uid int) | |||
@@ -570,19 +372,16 @@ func convertFromDirents11(buf []byte, old []byte) int { | |||
//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 lstat(path string, stat *stat_freebsd11_t) (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 mknod(path string, mode uint32, dev int) (err error) | |||
//sys mknodat(fd int, path string, mode uint32, dev int) (err error) | |||
//sys mknodat_freebsd12(fd int, path string, mode uint32, dev uint64) (err error) | |||
//sys Mknodat(fd int, path string, mode uint32, dev uint64) (err error) | |||
//sys Nanosleep(time *Timespec, leftover *Timespec) (err error) | |||
//sys Open(path string, mode int, perm uint32) (fd int, err error) | |||
//sys Openat(fdat int, path string, mode int, perm uint32) (fd 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 Pwrite(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 read(fd int, p []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) | |||
@@ -591,7 +390,7 @@ func convertFromDirents11(buf []byte, old []byte) int { | |||
//sys Revoke(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 Select(n int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (err error) | |||
//sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) | |||
//sysnb Setegid(egid int) (err error) | |||
//sysnb Seteuid(euid int) (err error) | |||
//sysnb Setgid(gid int) (err error) | |||
@@ -606,9 +405,7 @@ func convertFromDirents11(buf []byte, old []byte) int { | |||
//sysnb Setsid() (pid int, err error) | |||
//sysnb Settimeofday(tp *Timeval) (err error) | |||
//sysnb Setuid(uid int) (err error) | |||
//sys stat(path string, stat *stat_freebsd11_t) (err error) | |||
//sys statfs(path string, stat *statfs_freebsd11_t) (err error) | |||
//sys statfs_freebsd12(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 Symlinkat(oldpath string, newdirfd int, newpath string) (err error) | |||
//sys Sync() (err error) | |||
@@ -619,8 +416,8 @@ func convertFromDirents11(buf []byte, old []byte) int { | |||
//sys Unlinkat(dirfd int, 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 mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) | |||
//sys munmap(addr uintptr, length uintptr) (err error) | |||
//sys mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) | |||
//sys munmap(addr uintptr, length uintptr) (err 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 accept4(fd int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (nfd int, err error) | |||