Switch to Go modules, update dependencies

This commit is contained in:
2020-07-10 22:09:56 -07:00
parent 0ade0b9817
commit a801484c28
254 changed files with 21390 additions and 88916 deletions

36
Gopkg.lock generated
View File

@@ -1,36 +0,0 @@
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
[[projects]]
digest = "1:a7203c292d7f5f6c16ea98ea749abbdcd3abb81f2a4c2f966d3685fccdf5a7c0"
name = "github.com/oschwald/geoip2-golang"
packages = ["."]
pruneopts = "NUT"
revision = "347ca45869a87337a71b11efe9b3043bc10df97f"
version = "v1.3.0"
[[projects]]
digest = "1:64198924e9a427441edb6785067ec35eeca8b12d3520c6ce97a01aba509e321a"
name = "github.com/oschwald/maxminddb-golang"
packages = ["."]
pruneopts = "NUT"
revision = "2905694a1b00c5574f1418a7dbf8a22a7d247559"
version = "v1.3.1"
[[projects]]
branch = "master"
digest = "1:3b0776f2db863b8e8c7171671ff28c6bd073679476f34780b6a298cac01b0df1"
name = "golang.org/x/sys"
packages = [
"unix",
"windows",
]
pruneopts = "NUT"
revision = "c5567b49c5d04a5f83870795b8c0e2df43a8ce32"
[solve-meta]
analyzer-name = "dep"
analyzer-version = 1
input-imports = ["github.com/oschwald/geoip2-golang"]
solver-name = "gps-cdcl"
solver-version = 1

View File

@@ -1,35 +0,0 @@
# Gopkg.toml example
#
# Refer to https://golang.github.io/dep/docs/Gopkg.toml.html
# for detailed Gopkg.toml documentation.
#
# required = ["github.com/user/thing/cmd/thing"]
# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
#
# [[constraint]]
# name = "github.com/user/project"
# version = "1.0.0"
#
# [[constraint]]
# name = "github.com/user/project2"
# branch = "dev"
# source = "github.com/myfork/project2"
#
# [[override]]
# name = "github.com/x/y"
# version = "2.4.0"
#
# [prune]
# non-go = false
# go-tests = true
# unused-packages = true
[[constraint]]
name = "github.com/oschwald/geoip2-golang"
version = "1.2.1"
[prune]
go-tests = true
unused-packages = true
non-go = true

9
go.mod Normal file
View File

@@ -0,0 +1,9 @@
module go.ntppool.org/geoipapi
go 1.15
require (
github.com/oschwald/geoip2-golang v1.4.0
github.com/oschwald/maxminddb-golang v1.7.0 // indirect
golang.org/x/sys v0.0.0-20200808120158-1030fc2bf1d9 // indirect
)

22
go.sum Normal file
View File

@@ -0,0 +1,22 @@
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/oschwald/geoip2-golang v1.3.0 h1:D+Hsdos1NARPbzZ2aInUHZL+dApIzo8E0ErJVsWcku8=
github.com/oschwald/geoip2-golang v1.3.0/go.mod h1:0LTTzix/Ao1uMvOhAV4iLU0Lz7eCrP94qZWBTDKf0iE=
github.com/oschwald/geoip2-golang v1.4.0 h1:5RlrjCgRyIGDz/mBmPfnAF4h8k0IAcRv9PvrpOfz+Ug=
github.com/oschwald/geoip2-golang v1.4.0/go.mod h1:8QwxJvRImBH+Zl6Aa6MaIcs5YdlZSTKtzmPGzQqi9ng=
github.com/oschwald/maxminddb-golang v1.3.1 h1:kPc5+ieL5CC/Zn0IaXJPxDFlUxKTQEU8QBTtmfQDAIo=
github.com/oschwald/maxminddb-golang v1.3.1/go.mod h1:3jhIUymTJ5VREKyIhWm66LJiQt04F0UCDdodShpjWsY=
github.com/oschwald/maxminddb-golang v1.6.0/go.mod h1:DUJFucBg2cvqx42YmDa/+xHvb0elJtOm3o4aFQ/nb/w=
github.com/oschwald/maxminddb-golang v1.7.0 h1:JmU4Q1WBv5Q+2KZy5xJI+98aUwTIrPPxZUkd5Cwr8Zc=
github.com/oschwald/maxminddb-golang v1.7.0/go.mod h1:RXZtst0N6+FY/3qCNmZMBApR19cdQj43/NM9VkrNAis=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0 h1:HyfiK1WMnHj5FXFXatD+Qs1A/xC2Run6RzeW1SyHxpc=
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191224085550-c709ea063b76/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200808120158-1030fc2bf1d9 h1:yi1hN8dcqI9l8klZfy4B8mJvFmmAxJEePIQQFNSd7Cs=
golang.org/x/sys v0.0.0-20200808120158-1030fc2bf1d9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

3
vendor/github.com/oschwald/geoip2-golang/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,3 @@
.vscode
*.out
*.test

3
vendor/github.com/oschwald/geoip2-golang/.gitmodules generated vendored Normal file
View File

@@ -0,0 +1,3 @@
[submodule "test-data"]
path = test-data
url = https://github.com/maxmind/MaxMind-DB.git

View File

@@ -0,0 +1,30 @@
[run]
deadline = "10m"
tests = true
[linters]
disable-all = true
enable = [
"deadcode",
"depguard",
"errcheck",
"goconst",
"gocyclo",
"gocritic",
"gofmt",
"golint",
"gosec",
"gosimple",
"ineffassign",
"maligned",
"misspell",
"nakedret",
"staticcheck",
"structcheck",
"typecheck",
"unconvert",
"unparam",
"varcheck",
"vet",
"vetshadow",
]

48
vendor/github.com/oschwald/geoip2-golang/.travis.yml generated vendored Normal file
View File

@@ -0,0 +1,48 @@
language: go
go:
- 1.9.x
- 1.10.x
- 1.11.x
- 1.12.x
- 1.13.x
- tip
os:
- linux
- linux-ppc64le
- osx
- windows
matrix:
allow_failures:
- go: tip
install:
- go get -v -t ./...
before_script:
- |
if [[ $TRAVIS_GO_VERSION == '1.13.x' && $TRAVIS_OS_NAME == 'linux' && $(arch) != 'ppc64le' ]]; then
curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(go env GOPATH)/bin
fi
script:
- |
if [ $(arch) == "ppc64le" ]; then
go test -cpu 1,4 -v
else
go test -race -cpu 1,4 -v
fi
- |
if [ $(arch) == "ppc64le" ]; then
go test -v -tags appengine
else
go test -race -v -tags appengine
fi
- |
if [[ $TRAVIS_GO_VERSION == '1.13.x' && $TRAVIS_OS_NAME == 'linux' && $(arch) != 'ppc64le' ]]; then
golangci-lint run
fi
sudo: false

92
vendor/github.com/oschwald/geoip2-golang/README.md generated vendored Normal file
View File

@@ -0,0 +1,92 @@
# GeoIP2 Reader for Go #
[![Build Status](https://travis-ci.org/oschwald/geoip2-golang.png?branch=master)](https://travis-ci.org/oschwald/geoip2-golang)
[![GoDoc](https://godoc.org/github.com/oschwald/geoip2-golang?status.png)](https://godoc.org/github.com/oschwald/geoip2-golang)
This library reads MaxMind [GeoLite2](http://dev.maxmind.com/geoip/geoip2/geolite2/)
and [GeoIP2](http://www.maxmind.com/en/geolocation_landing) databases.
This library is built using
[the Go maxminddb reader](https://github.com/oschwald/maxminddb-golang).
All data for the database record is decoded using this library. If you only
need several fields, you may get superior performance by using maxminddb's
`Lookup` directly with a result struct that only contains the required fields.
(See [example_test.go](https://github.com/oschwald/maxminddb-golang/blob/master/example_test.go)
in the maxminddb repository for an example of this.)
## Installation ##
```
go get github.com/oschwald/geoip2-golang
```
## Usage ##
[See GoDoc](http://godoc.org/github.com/oschwald/geoip2-golang) for
documentation and examples.
## Example ##
```go
package main
import (
"fmt"
"github.com/oschwald/geoip2-golang"
"log"
"net"
)
func main() {
db, err := geoip2.Open("GeoIP2-City.mmdb")
if err != nil {
log.Fatal(err)
}
defer db.Close()
// If you are using strings that may be invalid, check that ip is not nil
ip := net.ParseIP("81.2.69.142")
record, err := db.City(ip)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Portuguese (BR) city name: %v\n", record.City.Names["pt-BR"])
if len(record.Subdivisions) > 0 {
fmt.Printf("English subdivision name: %v\n", record.Subdivisions[0].Names["en"])
}
fmt.Printf("Russian country name: %v\n", record.Country.Names["ru"])
fmt.Printf("ISO country code: %v\n", record.Country.IsoCode)
fmt.Printf("Time zone: %v\n", record.Location.TimeZone)
fmt.Printf("Coordinates: %v, %v\n", record.Location.Latitude, record.Location.Longitude)
// Output:
// Portuguese (BR) city name: Londres
// English subdivision name: England
// Russian country name: Великобритания
// ISO country code: GB
// Time zone: Europe/London
// Coordinates: 51.5142, -0.0931
}
```
## Testing ##
Make sure you checked out test data submodule:
```
git submodule init
git submodule update
```
Execute test suite:
```
go test
```
## Contributing ##
Contributions welcome! Please fork the repository and open a pull request
with your changes.
## License ##
This is free software, licensed under the ISC license.

8
vendor/github.com/oschwald/geoip2-golang/go.mod generated vendored Normal file
View File

@@ -0,0 +1,8 @@
module github.com/oschwald/geoip2-golang
go 1.9
require (
github.com/oschwald/maxminddb-golang v1.6.0
github.com/stretchr/testify v1.4.0
)

15
vendor/github.com/oschwald/geoip2-golang/go.sum generated vendored Normal file
View File

@@ -0,0 +1,15 @@
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/oschwald/maxminddb-golang v1.6.0 h1:KAJSjdHQ8Kv45nFIbtoLGrGWqHFajOIm7skTyz/+Dls=
github.com/oschwald/maxminddb-golang v1.6.0/go.mod h1:DUJFucBg2cvqx42YmDa/+xHvb0elJtOm3o4aFQ/nb/w=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
golang.org/x/sys v0.0.0-20191224085550-c709ea063b76 h1:Dho5nD6R3PcW2SH1or8vS0dszDaXRxIw55lBX7XiE5g=
golang.org/x/sys v0.0.0-20191224085550-c709ea063b76/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

View File

@@ -275,7 +275,11 @@ func getDBType(reader *maxminddb.Reader) (databaseType, error) {
case "GeoLite2-ASN": case "GeoLite2-ASN":
return isASN, nil return isASN, nil
// We allow City lookups on Country for back compat // We allow City lookups on Country for back compat
case "GeoLite2-City", case "DBIP-City-Lite",
"DBIP-City",
"DBIP-Country-Lite",
"DBIP-Country",
"GeoLite2-City",
"GeoIP2-City", "GeoIP2-City",
"GeoIP2-City-Africa", "GeoIP2-City-Africa",
"GeoIP2-City-Asia-Pacific", "GeoIP2-City-Asia-Pacific",
@@ -290,10 +294,12 @@ func getDBType(reader *maxminddb.Reader) (databaseType, error) {
return isConnectionType, nil return isConnectionType, nil
case "GeoIP2-Domain": case "GeoIP2-Domain":
return isDomain, nil return isDomain, nil
case "GeoIP2-Enterprise": case "DBIP-Location-ISP (compat=Enterprise)",
"GeoIP2-Enterprise":
return isEnterprise | isCity | isCountry, nil return isEnterprise | isCity | isCountry, nil
case "GeoIP2-ISP", "GeoIP2-Precision-ISP": case "GeoIP2-ISP",
return isISP, nil "GeoIP2-Precision-ISP":
return isISP | isASN, nil
default: default:
return 0, UnknownDatabaseTypeError{reader.Metadata.DatabaseType} return 0, UnknownDatabaseTypeError{reader.Metadata.DatabaseType}
} }

View File

@@ -0,0 +1,4 @@
.vscode
*.out
*.sw?
*.test

View File

@@ -0,0 +1,3 @@
[submodule "test-data"]
path = test-data
url = https://github.com/maxmind/MaxMind-DB.git

View File

@@ -0,0 +1,30 @@
[run]
deadline = "10m"
tests = true
[linters]
disable-all = true
enable = [
"deadcode",
"depguard",
"errcheck",
"goconst",
"gocyclo",
"gocritic",
"gofmt",
"golint",
"gosec",
"gosimple",
"ineffassign",
"maligned",
"misspell",
"nakedret",
"staticcheck",
"structcheck",
"typecheck",
"unconvert",
"unparam",
"varcheck",
"vet",
"vetshadow",
]

View File

@@ -0,0 +1,48 @@
language: go
go:
- 1.9.x
- 1.10.x
- 1.11.x
- 1.12.x
- 1.13.x
- 1.14.x
- tip
os:
- linux
- linux-ppc64le
- osx
matrix:
allow_failures:
- go: tip
install:
- go get -v -t ./...
before_script:
- |
if [[ $TRAVIS_GO_VERSION == 1.14 && $(arch) != 'ppc64le' ]]; then
curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(go env GOPATH)/bin
fi
script:
- |
if [ $(arch) == "ppc64le" ]; then
go test -cpu 1,4 -v
else
go test -race -cpu 1,4 -v
fi
- |
if [ $(arch) == "ppc64le" ]; then
go test -v -tags appengine
else
go test -race -v -tags appengine
fi
- |
if [[ $TRAVIS_GO_VERSION == 1.14 && $(arch) != 'ppc64le' ]]; then
golangci-lint run
fi
sudo: false

38
vendor/github.com/oschwald/maxminddb-golang/README.md generated vendored Normal file
View File

@@ -0,0 +1,38 @@
# MaxMind DB Reader for Go #
[![Build Status](https://travis-ci.org/oschwald/maxminddb-golang.svg?branch=master)](https://travis-ci.org/oschwald/maxminddb-golang)
[![Windows Build Status](https://ci.appveyor.com/api/projects/status/4j2f9oep8nnfrmov/branch/master?svg=true)](https://ci.appveyor.com/project/oschwald/maxminddb-golang/branch/master)
[![GoDoc](https://godoc.org/github.com/oschwald/maxminddb-golang?status.svg)](https://godoc.org/github.com/oschwald/maxminddb-golang)
This is a Go reader for the MaxMind DB format. Although this can be used to
read [GeoLite2](http://dev.maxmind.com/geoip/geoip2/geolite2/) and
[GeoIP2](https://www.maxmind.com/en/geoip2-databases) databases,
[geoip2](https://github.com/oschwald/geoip2-golang) provides a higher-level
API for doing so.
This is not an official MaxMind API.
## Installation ##
```
go get github.com/oschwald/maxminddb-golang
```
## Usage ##
[See GoDoc](http://godoc.org/github.com/oschwald/maxminddb-golang) for
documentation and examples.
## Examples ##
See [GoDoc](http://godoc.org/github.com/oschwald/maxminddb-golang) or
`example_test.go` for examples.
## Contributing ##
Contributions welcome! Please fork the repository and open a pull request
with your changes.
## License ##
This is free software, licensed under the ISC License.

View File

@@ -0,0 +1,19 @@
version: "{build}"
os: Windows Server 2012 R2
clone_folder: c:\gopath\src\github.com\oschwald\maxminddb-golang
environment:
GOPATH: c:\gopath
install:
- echo %PATH%
- echo %GOPATH%
- git submodule update --init --recursive
- go version
- go env
- go get -v -t ./...
build_script:
- go test -v ./...

View File

@@ -27,8 +27,10 @@ const (
_Uint64 _Uint64
_Uint128 _Uint128
_Slice _Slice
_Container // We don't use the next two. They are placeholders. See the spec
_Marker // for more details.
_Container // nolint: deadcode, varcheck
_Marker // nolint: deadcode, varcheck
_Bool _Bool
_Float32 _Float32
) )
@@ -159,10 +161,8 @@ func (d *decoder) unmarshalBool(size uint, offset uint, result reflect.Value) (u
if size > 1 { if size > 1 {
return 0, newInvalidDatabaseError("the MaxMind DB file's data section contains bad data (bool size of %v)", size) return 0, newInvalidDatabaseError("the MaxMind DB file's data section contains bad data (bool size of %v)", size)
} }
value, newOffset, err := d.decodeBool(size, offset) value, newOffset := d.decodeBool(size, offset)
if err != nil {
return 0, err
}
switch result.Kind() { switch result.Kind() {
case reflect.Bool: case reflect.Bool:
result.SetBool(value) result.SetBool(value)
@@ -207,10 +207,8 @@ func (d *decoder) indirect(result reflect.Value) reflect.Value {
var sliceType = reflect.TypeOf([]byte{}) var sliceType = reflect.TypeOf([]byte{})
func (d *decoder) unmarshalBytes(size uint, offset uint, result reflect.Value) (uint, error) { func (d *decoder) unmarshalBytes(size uint, offset uint, result reflect.Value) (uint, error) {
value, newOffset, err := d.decodeBytes(size, offset) value, newOffset := d.decodeBytes(size, offset)
if err != nil {
return 0, err
}
switch result.Kind() { switch result.Kind() {
case reflect.Slice: case reflect.Slice:
if result.Type() == sliceType { if result.Type() == sliceType {
@@ -230,10 +228,7 @@ func (d *decoder) unmarshalFloat32(size uint, offset uint, result reflect.Value)
if size != 4 { if size != 4 {
return 0, newInvalidDatabaseError("the MaxMind DB file's data section contains bad data (float32 size of %v)", size) return 0, newInvalidDatabaseError("the MaxMind DB file's data section contains bad data (float32 size of %v)", size)
} }
value, newOffset, err := d.decodeFloat32(size, offset) value, newOffset := d.decodeFloat32(size, offset)
if err != nil {
return 0, err
}
switch result.Kind() { switch result.Kind() {
case reflect.Float32, reflect.Float64: case reflect.Float32, reflect.Float64:
@@ -253,10 +248,8 @@ func (d *decoder) unmarshalFloat64(size uint, offset uint, result reflect.Value)
if size != 8 { if size != 8 {
return 0, newInvalidDatabaseError("the MaxMind DB file's data section contains bad data (float 64 size of %v)", size) return 0, newInvalidDatabaseError("the MaxMind DB file's data section contains bad data (float 64 size of %v)", size)
} }
value, newOffset, err := d.decodeFloat64(size, offset) value, newOffset := d.decodeFloat64(size, offset)
if err != nil {
return 0, err
}
switch result.Kind() { switch result.Kind() {
case reflect.Float32, reflect.Float64: case reflect.Float32, reflect.Float64:
if result.OverflowFloat(value) { if result.OverflowFloat(value) {
@@ -277,10 +270,7 @@ func (d *decoder) unmarshalInt32(size uint, offset uint, result reflect.Value) (
if size > 4 { if size > 4 {
return 0, newInvalidDatabaseError("the MaxMind DB file's data section contains bad data (int32 size of %v)", size) return 0, newInvalidDatabaseError("the MaxMind DB file's data section contains bad data (int32 size of %v)", size)
} }
value, newOffset, err := d.decodeInt(size, offset) value, newOffset := d.decodeInt(size, offset)
if err != nil {
return 0, err
}
switch result.Kind() { switch result.Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
@@ -360,11 +350,8 @@ func (d *decoder) unmarshalSlice(
} }
func (d *decoder) unmarshalString(size uint, offset uint, result reflect.Value) (uint, error) { func (d *decoder) unmarshalString(size uint, offset uint, result reflect.Value) (uint, error) {
value, newOffset, err := d.decodeString(size, offset) value, newOffset := d.decodeString(size, offset)
if err != nil {
return 0, err
}
switch result.Kind() { switch result.Kind() {
case reflect.String: case reflect.String:
result.SetString(value) result.SetString(value)
@@ -384,10 +371,7 @@ func (d *decoder) unmarshalUint(size uint, offset uint, result reflect.Value, ui
return 0, newInvalidDatabaseError("the MaxMind DB file's data section contains bad data (uint%v size of %v)", uintType, size) return 0, newInvalidDatabaseError("the MaxMind DB file's data section contains bad data (uint%v size of %v)", uintType, size)
} }
value, newOffset, err := d.decodeUint(size, offset) value, newOffset := d.decodeUint(size, offset)
if err != nil {
return 0, err
}
switch result.Kind() { switch result.Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
@@ -416,10 +400,7 @@ func (d *decoder) unmarshalUint128(size uint, offset uint, result reflect.Value)
if size > 16 { if size > 16 {
return 0, newInvalidDatabaseError("the MaxMind DB file's data section contains bad data (uint128 size of %v)", size) return 0, newInvalidDatabaseError("the MaxMind DB file's data section contains bad data (uint128 size of %v)", size)
} }
value, newOffset, err := d.decodeUint128(size, offset) value, newOffset := d.decodeUint128(size, offset)
if err != nil {
return 0, err
}
switch result.Kind() { switch result.Kind() {
case reflect.Struct: case reflect.Struct:
@@ -436,36 +417,36 @@ func (d *decoder) unmarshalUint128(size uint, offset uint, result reflect.Value)
return newOffset, newUnmarshalTypeError(value, result.Type()) return newOffset, newUnmarshalTypeError(value, result.Type())
} }
func (d *decoder) decodeBool(size uint, offset uint) (bool, uint, error) { func (d *decoder) decodeBool(size uint, offset uint) (bool, uint) {
return size != 0, offset, nil return size != 0, offset
} }
func (d *decoder) decodeBytes(size uint, offset uint) ([]byte, uint, error) { func (d *decoder) decodeBytes(size uint, offset uint) ([]byte, uint) {
newOffset := offset + size newOffset := offset + size
bytes := make([]byte, size) bytes := make([]byte, size)
copy(bytes, d.buffer[offset:newOffset]) copy(bytes, d.buffer[offset:newOffset])
return bytes, newOffset, nil return bytes, newOffset
} }
func (d *decoder) decodeFloat64(size uint, offset uint) (float64, uint, error) { func (d *decoder) decodeFloat64(size uint, offset uint) (float64, uint) {
newOffset := offset + size newOffset := offset + size
bits := binary.BigEndian.Uint64(d.buffer[offset:newOffset]) bits := binary.BigEndian.Uint64(d.buffer[offset:newOffset])
return math.Float64frombits(bits), newOffset, nil return math.Float64frombits(bits), newOffset
} }
func (d *decoder) decodeFloat32(size uint, offset uint) (float32, uint, error) { func (d *decoder) decodeFloat32(size uint, offset uint) (float32, uint) {
newOffset := offset + size newOffset := offset + size
bits := binary.BigEndian.Uint32(d.buffer[offset:newOffset]) bits := binary.BigEndian.Uint32(d.buffer[offset:newOffset])
return math.Float32frombits(bits), newOffset, nil return math.Float32frombits(bits), newOffset
} }
func (d *decoder) decodeInt(size uint, offset uint) (int, uint, error) { func (d *decoder) decodeInt(size uint, offset uint) (int, uint) {
newOffset := offset + size newOffset := offset + size
var val int32 var val int32
for _, b := range d.buffer[offset:newOffset] { for _, b := range d.buffer[offset:newOffset] {
val = (val << 8) | int32(b) val = (val << 8) | int32(b)
} }
return int(val), newOffset, nil return int(val), newOffset
} }
func (d *decoder) decodeMap( func (d *decoder) decodeMap(
@@ -475,9 +456,14 @@ func (d *decoder) decodeMap(
depth int, depth int,
) (uint, error) { ) (uint, error) {
if result.IsNil() { if result.IsNil() {
result.Set(reflect.MakeMap(result.Type())) result.Set(reflect.MakeMapWithSize(result.Type(), int(size)))
} }
mapType := result.Type()
keyValue := reflect.New(mapType.Key()).Elem()
elemType := mapType.Elem()
elemKind := elemType.Kind()
var elemValue reflect.Value
for i := uint(0); i < size; i++ { for i := uint(0); i < size; i++ {
var key []byte var key []byte
var err error var err error
@@ -487,12 +473,17 @@ func (d *decoder) decodeMap(
return 0, err return 0, err
} }
value := reflect.New(result.Type().Elem()) if !elemValue.IsValid() || elemKind == reflect.Interface {
offset, err = d.decode(offset, value, depth) elemValue = reflect.New(elemType).Elem()
}
offset, err = d.decode(offset, elemValue, depth)
if err != nil { if err != nil {
return 0, err return 0, err
} }
result.SetMapIndex(reflect.ValueOf(string(key)), value.Elem())
keyValue.SetString(string(key))
result.SetMapIndex(keyValue, elemValue)
} }
return offset, nil return offset, nil
} }
@@ -511,7 +502,7 @@ func (d *decoder) decodePointer(
if pointerSize == 4 { if pointerSize == 4 {
prefix = 0 prefix = 0
} else { } else {
prefix = uint(size & 0x7) prefix = size & 0x7
} }
unpacked := uintFromBytes(prefix, pointerBytes) unpacked := uintFromBytes(prefix, pointerBytes)
@@ -549,57 +540,18 @@ func (d *decoder) decodeSlice(
return offset, nil return offset, nil
} }
func (d *decoder) decodeString(size uint, offset uint) (string, uint, error) { func (d *decoder) decodeString(size uint, offset uint) (string, uint) {
newOffset := offset + size newOffset := offset + size
return string(d.buffer[offset:newOffset]), newOffset, nil return string(d.buffer[offset:newOffset]), newOffset
} }
type fieldsType struct {
namedFields map[string]int
anonymousFields []int
}
var (
fieldMap = map[reflect.Type]*fieldsType{}
fieldMapMu sync.RWMutex
)
func (d *decoder) decodeStruct( func (d *decoder) decodeStruct(
size uint, size uint,
offset uint, offset uint,
result reflect.Value, result reflect.Value,
depth int, depth int,
) (uint, error) { ) (uint, error) {
resultType := result.Type() fields := cachedFields(result)
fieldMapMu.RLock()
fields, ok := fieldMap[resultType]
fieldMapMu.RUnlock()
if !ok {
numFields := resultType.NumField()
namedFields := make(map[string]int, numFields)
var anonymous []int
for i := 0; i < numFields; i++ {
field := resultType.Field(i)
fieldName := field.Name
if tag := field.Tag.Get("maxminddb"); tag != "" {
if tag == "-" {
continue
}
fieldName = tag
}
if field.Anonymous {
anonymous = append(anonymous, i)
continue
}
namedFields[fieldName] = i
}
fieldMapMu.Lock()
fields = &fieldsType{namedFields, anonymous}
fieldMap[resultType] = fields
fieldMapMu.Unlock()
}
// This fills in embedded structs // This fills in embedded structs
for _, i := range fields.anonymousFields { for _, i := range fields.anonymousFields {
@@ -638,7 +590,45 @@ func (d *decoder) decodeStruct(
return offset, nil return offset, nil
} }
func (d *decoder) decodeUint(size uint, offset uint) (uint64, uint, error) { type fieldsType struct {
namedFields map[string]int
anonymousFields []int
}
var fieldsMap sync.Map
func cachedFields(result reflect.Value) *fieldsType {
resultType := result.Type()
if fields, ok := fieldsMap.Load(resultType); ok {
return fields.(*fieldsType)
}
numFields := resultType.NumField()
namedFields := make(map[string]int, numFields)
var anonymous []int
for i := 0; i < numFields; i++ {
field := resultType.Field(i)
fieldName := field.Name
if tag := field.Tag.Get("maxminddb"); tag != "" {
if tag == "-" {
continue
}
fieldName = tag
}
if field.Anonymous {
anonymous = append(anonymous, i)
continue
}
namedFields[fieldName] = i
}
fields := &fieldsType{namedFields, anonymous}
fieldsMap.Store(resultType, fields)
return fields
}
func (d *decoder) decodeUint(size uint, offset uint) (uint64, uint) {
newOffset := offset + size newOffset := offset + size
bytes := d.buffer[offset:newOffset] bytes := d.buffer[offset:newOffset]
@@ -646,15 +636,15 @@ func (d *decoder) decodeUint(size uint, offset uint) (uint64, uint, error) {
for _, b := range bytes { for _, b := range bytes {
val = (val << 8) | uint64(b) val = (val << 8) | uint64(b)
} }
return val, newOffset, nil return val, newOffset
} }
func (d *decoder) decodeUint128(size uint, offset uint) (*big.Int, uint, error) { func (d *decoder) decodeUint128(size uint, offset uint) (*big.Int, uint) {
newOffset := offset + size newOffset := offset + size
val := new(big.Int) val := new(big.Int)
val.SetBytes(d.buffer[offset:newOffset]) val.SetBytes(d.buffer[offset:newOffset])
return val, newOffset, nil return val, newOffset
} }
func uintFromBytes(prefix uint, uintBytes []byte) uint { func uintFromBytes(prefix uint, uintBytes []byte) uint {

8
vendor/github.com/oschwald/maxminddb-golang/go.mod generated vendored Normal file
View File

@@ -0,0 +1,8 @@
module github.com/oschwald/maxminddb-golang
go 1.9
require (
github.com/stretchr/testify v1.6.1
golang.org/x/sys v0.0.0-20191224085550-c709ea063b76
)

22
vendor/github.com/oschwald/maxminddb-golang/go.sum generated vendored Normal file
View File

@@ -0,0 +1,22 @@
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.0 h1:DMOzIV76tmoDNE9pX6RSN0aDtCYeCg5VueieJaAo1uw=
github.com/stretchr/testify v1.5.0/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
golang.org/x/sys v0.0.0-20191224085550-c709ea063b76 h1:Dho5nD6R3PcW2SH1or8vS0dszDaXRxIw55lBX7XiE5g=
golang.org/x/sys v0.0.0-20191224085550-c709ea063b76/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@@ -1,4 +1,4 @@
// +build !windows,!appengine // +build !windows,!appengine,!plan9
package maxminddb package maxminddb

42
vendor/github.com/oschwald/maxminddb-golang/node.go generated vendored Normal file
View File

@@ -0,0 +1,42 @@
package maxminddb
type nodeReader interface {
readLeft(uint) uint
readRight(uint) uint
}
type nodeReader24 struct {
buffer []byte
}
func (n nodeReader24) readLeft(nodeNumber uint) uint {
return (uint(n.buffer[nodeNumber]) << 16) | (uint(n.buffer[nodeNumber+1]) << 8) | uint(n.buffer[nodeNumber+2])
}
func (n nodeReader24) readRight(nodeNumber uint) uint {
return (uint(n.buffer[nodeNumber+3]) << 16) | (uint(n.buffer[nodeNumber+4]) << 8) | uint(n.buffer[nodeNumber+5])
}
type nodeReader28 struct {
buffer []byte
}
func (n nodeReader28) readLeft(nodeNumber uint) uint {
return ((uint(n.buffer[nodeNumber+3]) & 0xF0) << 20) | (uint(n.buffer[nodeNumber]) << 16) | (uint(n.buffer[nodeNumber+1]) << 8) | uint(n.buffer[nodeNumber+2])
}
func (n nodeReader28) readRight(nodeNumber uint) uint {
return ((uint(n.buffer[nodeNumber+3]) & 0x0F) << 24) | (uint(n.buffer[nodeNumber+4]) << 16) | (uint(n.buffer[nodeNumber+5]) << 8) | uint(n.buffer[nodeNumber+6])
}
type nodeReader32 struct {
buffer []byte
}
func (n nodeReader32) readLeft(nodeNumber uint) uint {
return (uint(n.buffer[nodeNumber]) << 24) | (uint(n.buffer[nodeNumber+1]) << 16) | (uint(n.buffer[nodeNumber+2]) << 8) | uint(n.buffer[nodeNumber+3])
}
func (n nodeReader32) readRight(nodeNumber uint) uint {
return (uint(n.buffer[nodeNumber+4]) << 24) | (uint(n.buffer[nodeNumber+5]) << 16) | (uint(n.buffer[nodeNumber+6]) << 8) | uint(n.buffer[nodeNumber+7])
}

View File

@@ -20,16 +20,22 @@ var metadataStartMarker = []byte("\xAB\xCD\xEFMaxMind.com")
// Reader holds the data corresponding to the MaxMind DB file. Its only public // Reader holds the data corresponding to the MaxMind DB file. Its only public
// field is Metadata, which contains the metadata from the MaxMind DB file. // field is Metadata, which contains the metadata from the MaxMind DB file.
//
// All of the methods on Reader are thread-safe. The struct may be safely
// shared across goroutines.
type Reader struct { type Reader struct {
hasMappedFile bool hasMappedFile bool
buffer []byte buffer []byte
decoder decoder nodeReader nodeReader
Metadata Metadata decoder decoder
ipv4Start uint Metadata Metadata
ipv4Start uint
ipv4StartBitDepth int
nodeOffsetMult uint
} }
// Metadata holds the metadata decoded from the MaxMind DB file. In particular // Metadata holds the metadata decoded from the MaxMind DB file. In particular
// in has the format version, the build time as Unix epoch time, the database // it has the format version, the build time as Unix epoch time, the database
// type and description, the IP version supported, and a slice of the natural // type and description, the IP version supported, and a slice of the natural
// languages included. // languages included.
type Metadata struct { type Metadata struct {
@@ -74,65 +80,123 @@ func FromBytes(buffer []byte) (*Reader, error) {
buffer[searchTreeSize+dataSectionSeparatorSize : metadataStart-len(metadataStartMarker)], buffer[searchTreeSize+dataSectionSeparatorSize : metadataStart-len(metadataStartMarker)],
} }
reader := &Reader{ nodeBuffer := buffer[:searchTreeSize]
buffer: buffer, var nodeReader nodeReader
decoder: d, switch metadata.RecordSize {
Metadata: metadata, case 24:
ipv4Start: 0, nodeReader = nodeReader24{buffer: nodeBuffer}
case 28:
nodeReader = nodeReader28{buffer: nodeBuffer}
case 32:
nodeReader = nodeReader32{buffer: nodeBuffer}
default:
return nil, newInvalidDatabaseError("unknown record size: %d", metadata.RecordSize)
} }
reader.ipv4Start, err = reader.startNode() reader := &Reader{
buffer: buffer,
nodeReader: nodeReader,
decoder: d,
Metadata: metadata,
ipv4Start: 0,
nodeOffsetMult: metadata.RecordSize / 4,
}
reader.setIPv4Start()
return reader, err return reader, err
} }
func (r *Reader) startNode() (uint, error) { func (r *Reader) setIPv4Start() {
if r.Metadata.IPVersion != 6 { if r.Metadata.IPVersion != 6 {
return 0, nil return
} }
nodeCount := r.Metadata.NodeCount nodeCount := r.Metadata.NodeCount
node := uint(0) node := uint(0)
var err error i := 0
for i := 0; i < 96 && node < nodeCount; i++ { for ; i < 96 && node < nodeCount; i++ {
node, err = r.readNode(node, 0) node = r.nodeReader.readLeft(node * r.nodeOffsetMult)
if err != nil {
return 0, err
}
} }
return node, err r.ipv4Start = node
r.ipv4StartBitDepth = i
} }
// Lookup takes an IP address as a net.IP structure and a pointer to the // Lookup retrieves the database record for ip and stores it in the value
// result value to Decode into. // pointed to by result. If result is nil or not a pointer, an error is
func (r *Reader) Lookup(ipAddress net.IP, result interface{}) error { // returned. If the data in the database record cannot be stored in result
// because of type differences, an UnmarshalTypeError is returned. If the
// database is invalid or otherwise cannot be read, an InvalidDatabaseError
// is returned.
func (r *Reader) Lookup(ip net.IP, result interface{}) error {
if r.buffer == nil { if r.buffer == nil {
return errors.New("cannot call Lookup on a closed database") return errors.New("cannot call Lookup on a closed database")
} }
pointer, err := r.lookupPointer(ipAddress) pointer, _, _, err := r.lookupPointer(ip)
if pointer == 0 || err != nil { if pointer == 0 || err != nil {
return err return err
} }
return r.retrieveData(pointer, result) return r.retrieveData(pointer, result)
} }
// LookupNetwork retrieves the database record for ip and stores it in the
// value pointed to by result. The network returned is the network associated
// with the data record in the database. The ok return value indicates whether
// the database contained a record for the ip.
//
// If result is nil or not a pointer, an error is returned. If the data in the
// database record cannot be stored in result because of type differences, an
// UnmarshalTypeError is returned. If the database is invalid or otherwise
// cannot be read, an InvalidDatabaseError is returned.
func (r *Reader) LookupNetwork(ip net.IP, result interface{}) (network *net.IPNet, ok bool, err error) {
if r.buffer == nil {
return nil, false, errors.New("cannot call Lookup on a closed database")
}
pointer, prefixLength, ip, err := r.lookupPointer(ip)
network = r.cidr(ip, prefixLength)
if pointer == 0 || err != nil {
return network, false, err
}
return network, true, r.retrieveData(pointer, result)
}
// LookupOffset maps an argument net.IP to a corresponding record offset in the // LookupOffset maps an argument net.IP to a corresponding record offset in the
// database. NotFound is returned if no such record is found, and a record may // database. NotFound is returned if no such record is found, and a record may
// otherwise be extracted by passing the returned offset to Decode. LookupOffset // otherwise be extracted by passing the returned offset to Decode. LookupOffset
// is an advanced API, which exists to provide clients with a means to cache // is an advanced API, which exists to provide clients with a means to cache
// previously-decoded records. // previously-decoded records.
func (r *Reader) LookupOffset(ipAddress net.IP) (uintptr, error) { func (r *Reader) LookupOffset(ip net.IP) (uintptr, error) {
if r.buffer == nil { if r.buffer == nil {
return 0, errors.New("cannot call LookupOffset on a closed database") return 0, errors.New("cannot call LookupOffset on a closed database")
} }
pointer, err := r.lookupPointer(ipAddress) pointer, _, _, err := r.lookupPointer(ip)
if pointer == 0 || err != nil { if pointer == 0 || err != nil {
return NotFound, err return NotFound, err
} }
return r.resolveDataPointer(pointer) return r.resolveDataPointer(pointer)
} }
func (r *Reader) cidr(ip net.IP, prefixLength int) *net.IPNet {
// This is necessary as the node that the IPv4 start is at may
// be at a bit depth that is less that 96, i.e., ipv4Start points
// to a leaf node. For instance, if a record was inserted at ::/8,
// the ipv4Start would point directly at the leaf node for the
// record and would have a bit depth of 8. This would not happen
// with databases currently distributed by MaxMind as all of them
// have an IPv4 subtree that is greater than a single node.
if r.Metadata.IPVersion == 6 &&
len(ip) == net.IPv4len &&
r.ipv4StartBitDepth != 96 {
return &net.IPNet{IP: net.ParseIP("::"), Mask: net.CIDRMask(r.ipv4StartBitDepth, 128)}
}
mask := net.CIDRMask(prefixLength, len(ip)*8)
return &net.IPNet{IP: ip.Mask(mask), Mask: mask}
}
// Decode the record at |offset| into |result|. The result value pointed to // Decode the record at |offset| into |result|. The result value pointed to
// must be a data value that corresponds to a record in the database. This may // must be a data value that corresponds to a record in the database. This may
// include a struct representation of the data, a map capable of holding the // include a struct representation of the data, a map capable of holding the
@@ -166,79 +230,54 @@ func (r *Reader) decode(offset uintptr, result interface{}) error {
return err return err
} }
func (r *Reader) lookupPointer(ipAddress net.IP) (uint, error) { func (r *Reader) lookupPointer(ip net.IP) (uint, int, net.IP, error) {
if ipAddress == nil { if ip == nil {
return 0, errors.New("ipAddress passed to Lookup cannot be nil") return 0, 0, ip, errors.New("IP passed to Lookup cannot be nil")
} }
ipV4Address := ipAddress.To4() ipV4Address := ip.To4()
if ipV4Address != nil { if ipV4Address != nil {
ipAddress = ipV4Address ip = ipV4Address
} }
if len(ipAddress) == 16 && r.Metadata.IPVersion == 4 { if len(ip) == 16 && r.Metadata.IPVersion == 4 {
return 0, fmt.Errorf("error looking up '%s': you attempted to look up an IPv6 address in an IPv4-only database", ipAddress.String()) return 0, 0, ip, fmt.Errorf("error looking up '%s': you attempted to look up an IPv6 address in an IPv4-only database", ip.String())
} }
return r.findAddressInTree(ipAddress) bitCount := uint(len(ip) * 8)
}
func (r *Reader) findAddressInTree(ipAddress net.IP) (uint, error) {
bitCount := uint(len(ipAddress) * 8)
var node uint var node uint
if bitCount == 32 { if bitCount == 32 {
node = r.ipv4Start node = r.ipv4Start
} }
node, prefixLength := r.traverseTree(ip, node, bitCount)
nodeCount := r.Metadata.NodeCount nodeCount := r.Metadata.NodeCount
for i := uint(0); i < bitCount && node < nodeCount; i++ {
bit := uint(1) & (uint(ipAddress[i>>3]) >> (7 - (i % 8)))
var err error
node, err = r.readNode(node, bit)
if err != nil {
return 0, err
}
}
if node == nodeCount { if node == nodeCount {
// Record is empty // Record is empty
return 0, nil return 0, prefixLength, ip, nil
} else if node > nodeCount { } else if node > nodeCount {
return node, nil return node, prefixLength, ip, nil
} }
return 0, newInvalidDatabaseError("invalid node in search tree") return 0, prefixLength, ip, newInvalidDatabaseError("invalid node in search tree")
} }
func (r *Reader) readNode(nodeNumber uint, index uint) (uint, error) { func (r *Reader) traverseTree(ip net.IP, node uint, bitCount uint) (uint, int) {
RecordSize := r.Metadata.RecordSize nodeCount := r.Metadata.NodeCount
baseOffset := nodeNumber * RecordSize / 4 i := uint(0)
for ; i < bitCount && node < nodeCount; i++ {
bit := uint(1) & (uint(ip[i>>3]) >> (7 - (i % 8)))
var nodeBytes []byte offset := node * r.nodeOffsetMult
var prefix uint if bit == 0 {
switch RecordSize { node = r.nodeReader.readLeft(offset)
case 24:
offset := baseOffset + index*3
nodeBytes = r.buffer[offset : offset+3]
case 28:
prefix = uint(r.buffer[baseOffset+3])
if index != 0 {
prefix &= 0x0F
} else { } else {
prefix = (0xF0 & prefix) >> 4 node = r.nodeReader.readRight(offset)
} }
offset := baseOffset + index*4
nodeBytes = r.buffer[offset : offset+3]
case 32:
offset := baseOffset + index*4
nodeBytes = r.buffer[offset : offset+4]
default:
return 0, newInvalidDatabaseError("unknown record size: %d", RecordSize)
} }
return uintFromBytes(prefix, nodeBytes), nil
return node, int(i)
} }
func (r *Reader) retrieveData(pointer uint, result interface{}) error { func (r *Reader) retrieveData(pointer uint, result interface{}) error {
@@ -252,7 +291,7 @@ func (r *Reader) retrieveData(pointer uint, result interface{}) error {
func (r *Reader) resolveDataPointer(pointer uint) (uintptr, error) { func (r *Reader) resolveDataPointer(pointer uint) (uintptr, error) {
var resolved = uintptr(pointer - r.Metadata.NodeCount - dataSectionSeparatorSize) var resolved = uintptr(pointer - r.Metadata.NodeCount - dataSectionSeparatorSize)
if resolved > uintptr(len(r.buffer)) { if resolved >= uintptr(len(r.buffer)) {
return 0, newInvalidDatabaseError("the MaxMind DB file's search tree is corrupt") return 0, newInvalidDatabaseError("the MaxMind DB file's search tree is corrupt")
} }
return resolved, nil return resolved, nil

View File

@@ -1,4 +1,4 @@
// +build appengine // +build appengine plan9
package maxminddb package maxminddb

View File

@@ -1,4 +1,4 @@
// +build !appengine // +build !appengine,!plan9
package maxminddb package maxminddb
@@ -15,37 +15,37 @@ import (
func Open(file string) (*Reader, error) { func Open(file string) (*Reader, error) {
mapFile, err := os.Open(file) mapFile, err := os.Open(file)
if err != nil { if err != nil {
_ = mapFile.Close()
return nil, err return nil, err
} }
defer func() {
if rerr := mapFile.Close(); rerr != nil {
err = rerr
}
}()
stats, err := mapFile.Stat() stats, err := mapFile.Stat()
if err != nil { if err != nil {
_ = mapFile.Close()
return nil, err return nil, err
} }
fileSize := int(stats.Size()) fileSize := int(stats.Size())
mmap, err := mmap(int(mapFile.Fd()), fileSize) mmap, err := mmap(int(mapFile.Fd()), fileSize)
if err != nil { if err != nil {
_ = mapFile.Close()
return nil, err
}
if err := mapFile.Close(); err != nil {
_ = munmap(mmap)
return nil, err return nil, err
} }
reader, err := FromBytes(mmap) reader, err := FromBytes(mmap)
if err != nil { if err != nil {
if err2 := munmap(mmap); err2 != nil { _ = munmap(mmap)
// failing to unmap the file is probably the more severe error
return nil, err2
}
return nil, err return nil, err
} }
reader.hasMappedFile = true reader.hasMappedFile = true
runtime.SetFinalizer(reader, (*Reader).Close) runtime.SetFinalizer(reader, (*Reader).Close)
return reader, err return reader, nil
} }
// Close unmaps the database file from virtual memory and returns the // Close unmaps the database file from virtual memory and returns the

View File

@@ -1,6 +1,8 @@
package maxminddb package maxminddb
import "net" import (
"net"
)
// Internal structure used to keep track of nodes we still need to visit. // Internal structure used to keep track of nodes we still need to visit.
type netNode struct { type netNode struct {
@@ -17,22 +19,52 @@ type Networks struct {
err error err error
} }
var allIPv4 = &net.IPNet{IP: make(net.IP, 4), Mask: net.CIDRMask(0, 32)}
var allIPv6 = &net.IPNet{IP: make(net.IP, 16), Mask: net.CIDRMask(0, 128)}
// Networks returns an iterator that can be used to traverse all networks in // Networks returns an iterator that can be used to traverse all networks in
// the database. // the database.
// //
// Please note that a MaxMind DB may map IPv4 networks into several locations // Please note that a MaxMind DB may map IPv4 networks into several locations
// in in an IPv6 database. This iterator will iterate over all of these // in an IPv6 database. This iterator will iterate over all of these
// locations separately. // locations separately.
func (r *Reader) Networks() *Networks { func (r *Reader) Networks() *Networks {
s := 4 var networks *Networks
if r.Metadata.IPVersion == 6 { if r.Metadata.IPVersion == 6 {
s = 16 networks = r.NetworksWithin(allIPv6)
} else {
networks = r.NetworksWithin(allIPv4)
} }
return networks
}
// NetworksWithin returns an iterator that can be used to traverse all networks
// in the database which are contained in a given network.
//
// Please note that a MaxMind DB may map IPv4 networks into several locations
// in an IPv6 database. This iterator will iterate over all of these locations
// separately.
//
// If the provided network is contained within a network in the database, the
// iterator will iterate over exactly one network, the containing network.
func (r *Reader) NetworksWithin(network *net.IPNet) *Networks {
ip := network.IP
prefixLength, _ := network.Mask.Size()
if r.Metadata.IPVersion == 6 && len(ip) == net.IPv4len {
ip = net.IP.To16(ip)
prefixLength += 96
}
pointer, bit := r.traverseTree(ip, 0, uint(prefixLength))
return &Networks{ return &Networks{
reader: r, reader: r,
nodes: []netNode{ nodes: []netNode{
{ {
ip: make(net.IP, s), ip: ip,
bit: uint(bit),
pointer: pointer,
}, },
}, },
} }
@@ -46,42 +78,31 @@ func (n *Networks) Next() bool {
node := n.nodes[len(n.nodes)-1] node := n.nodes[len(n.nodes)-1]
n.nodes = n.nodes[:len(n.nodes)-1] n.nodes = n.nodes[:len(n.nodes)-1]
for { for node.pointer != n.reader.Metadata.NodeCount {
if node.pointer < n.reader.Metadata.NodeCount { if node.pointer > n.reader.Metadata.NodeCount {
ipRight := make(net.IP, len(node.ip))
copy(ipRight, node.ip)
if len(ipRight) <= int(node.bit>>3) {
n.err = newInvalidDatabaseError(
"invalid search tree at %v/%v", ipRight, node.bit)
return false
}
ipRight[node.bit>>3] |= 1 << (7 - (node.bit % 8))
rightPointer, err := n.reader.readNode(node.pointer, 1)
if err != nil {
n.err = err
return false
}
node.bit++
n.nodes = append(n.nodes, netNode{
pointer: rightPointer,
ip: ipRight,
bit: node.bit,
})
node.pointer, err = n.reader.readNode(node.pointer, 0)
if err != nil {
n.err = err
return false
}
} else if node.pointer > n.reader.Metadata.NodeCount {
n.lastNode = node n.lastNode = node
return true return true
} else {
break
} }
ipRight := make(net.IP, len(node.ip))
copy(ipRight, node.ip)
if len(ipRight) <= int(node.bit>>3) {
n.err = newInvalidDatabaseError(
"invalid search tree at %v/%v", ipRight, node.bit)
return false
}
ipRight[node.bit>>3] |= 1 << (7 - (node.bit % 8))
offset := node.pointer * n.reader.nodeOffsetMult
rightPointer := n.reader.nodeReader.readRight(offset)
node.bit++
n.nodes = append(n.nodes, netNode{
pointer: rightPointer,
ip: ipRight,
bit: node.bit,
})
node.pointer = n.reader.nodeReader.readLeft(offset)
} }
} }

View File

@@ -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
}

2
vendor/golang.org/x/sys/unix/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,2 @@
_obj/
unix.test

184
vendor/golang.org/x/sys/unix/README.md generated vendored Normal file
View File

@@ -0,0 +1,184 @@
# Building `sys/unix`
The sys/unix package provides access to the raw system call interface of the
underlying operating system. See: https://godoc.org/golang.org/x/sys/unix
Porting Go to a new architecture/OS combination or adding syscalls, types, or
constants to an existing architecture/OS pair requires some manual effort;
however, there are tools that automate much of the process.
## Build Systems
There are currently two ways we generate the necessary files. We are currently
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"`)
The old build system generates the Go files based on the C header files
present on your system. This means that files
for a given GOOS/GOARCH pair must be generated on a system with that OS and
architecture. This also means that the generated code can differ from system
to system, based on differences in the header files.
To avoid this, if you are using the old build system, only generate the Go
files on an installation with unmodified header files. It is also important to
keep track of which version of the OS the files were generated from (ex.
Darwin 14 vs Darwin 15). This makes it easier to track the progress of changes
and have each OS upgrade correspond to a single change.
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, go
### 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
that on any platform that supports Docker, all the files using the new build
system can be generated at once, and generated files will not change based on
what the person running the scripts has installed on their computer.
The OS specific files for the new build system are located in the `${GOOS}`
directory, and the build is coordinated by the `${GOOS}/mkall.go` program. When
the kernel or system library updates, modify the Dockerfile at
`${GOOS}/Dockerfile` to checkout the new release of the source.
To build all the files under the new build system, you must be on an amd64/Linux
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, 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/programs cannot be called normally.
They must be called from within the docker container.
### asm files
The hand-written assembly file at `asm_${GOOS}_${GOARCH}.s` implements system
call dispatch. There are three entry points:
```
func Syscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr)
func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr)
func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr)
```
The first and second are the standard ones; they differ only in how many
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
each GOOS/GOARCH pair.
### mksysnum
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 may need to update the
parsing in mksysnum.
### 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.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.
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
`syscall_${GOOS}.go`.
### types files
For each OS, there is a hand-written Go file at `${GOOS}/types.go` (or
`types_${GOOS}.go` on the old system). This file includes standard C headers and
creates Go type aliases to the corresponding C types. The file is then fed
through godef to get the Go compatible definitions. Finally, the generated code
is fed though mkpost.go to format the code correctly and remove any hidden or
private identifiers. This cleaned-up code is written to
`ztypes_${GOOS}_${GOARCH}.go`.
The hardest part about preparing this file is figuring out which headers to
include and which symbols need to be `#define`d to get the actual data
structures that pass through to the kernel system calls. Some C libraries
preset alternate versions for binary compatibility and translate them on the
way in and out of system calls, but there is almost always a `#define` that can
get the real ones.
See `types_darwin.go` and `linux/types.go` for examples.
To add a new type, add in the necessary include statement at the top of the
file (if it is not already there) and add in a type alias line. Note that if
your type is significantly different on different architectures, you may need
some `#if/#elif` macros in your include statements.
### mkerrors.sh
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
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
signal numbers and strings are generated from `#include <signal.h>`. All of
these constants are written to `zerrors_${GOOS}_${GOARCH}.go` via a C program,
`_errors.c`, which prints out all the constants.
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.
### mkmerge.go
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
### `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).
### `zsyscall_${GOOS}_${GOARCH}.go`
A file containing all the generated syscalls for a specific GOOS and GOARCH.
Generated by `mksyscall.go` (see above).
### `zsysnum_${GOOS}_${GOARCH}.go`
A list of numeric constants for all the syscall number of the specific GOOS
and GOARCH. Generated by mksysnum (see above).
### `ztypes_${GOOS}_${GOARCH}.go`
A file containing Go types for passing into (or returning from) syscalls.
Generated by godefs and the types file (see above).

View File

@@ -7,6 +7,7 @@
package unix package unix
import ( import (
"math/bits"
"unsafe" "unsafe"
) )
@@ -79,46 +80,7 @@ func (s *CPUSet) IsSet(cpu int) bool {
func (s *CPUSet) Count() int { func (s *CPUSet) Count() int {
c := 0 c := 0
for _, b := range s { for _, b := range s {
c += onesCount64(uint64(b)) c += bits.OnesCount64(uint64(b))
} }
return c 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)
}

View File

@@ -23,10 +23,6 @@ TEXT ·SyscallNoError(SB),NOSPLIT,$0-48
MOV a1+8(FP), A0 MOV a1+8(FP), A0
MOV a2+16(FP), A1 MOV a2+16(FP), A1
MOV a3+24(FP), A2 MOV a3+24(FP), A2
MOV $0, A3
MOV $0, A4
MOV $0, A5
MOV $0, A6
MOV trap+0(FP), A7 // syscall entry MOV trap+0(FP), A7 // syscall entry
ECALL ECALL
MOV A0, r1+32(FP) // r1 MOV A0, r1+32(FP) // r1
@@ -44,9 +40,6 @@ TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-48
MOV a1+8(FP), A0 MOV a1+8(FP), A0
MOV a2+16(FP), A1 MOV a2+16(FP), A1
MOV a3+24(FP), A2 MOV a3+24(FP), A2
MOV ZERO, A3
MOV ZERO, A4
MOV ZERO, A5
MOV trap+0(FP), A7 // syscall entry MOV trap+0(FP), A7 // syscall entry
ECALL ECALL
MOV A0, r1+32(FP) MOV A0, r1+32(FP)

View File

@@ -23,6 +23,7 @@ const (
HCI_CHANNEL_USER = 1 HCI_CHANNEL_USER = 1
HCI_CHANNEL_MONITOR = 2 HCI_CHANNEL_MONITOR = 2
HCI_CHANNEL_CONTROL = 3 HCI_CHANNEL_CONTROL = 3
HCI_CHANNEL_LOGGING = 4
) )
// Socketoption Level // Socketoption Level

View File

@@ -2,16 +2,101 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build aix darwin dragonfly freebsd linux nacl netbsd openbsd solaris // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
package unix 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, // ParseDirent parses up to max directory entries in buf,
// appending the names to names. It returns the number of // appending the names to names. It returns the number of
// bytes consumed from buf, the number of entries added // bytes consumed from buf, the number of entries added
// to names, and the new names slice. // to names, and the new names slice.
func ParseDirent(buf []byte, max int, names []string) (consumed int, count int, newnames []string) { 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
} }

View File

@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// //
// +build 386 amd64 amd64p32 arm arm64 ppc64le mipsle mips64le // +build 386 amd64 amd64p32 arm arm64 ppc64le mipsle mips64le riscv64
package unix package unix

View File

@@ -8,6 +8,7 @@
package unix package unix
const ( const (
DLT_HHDLC = 0x79
IFF_SMART = 0x20 IFF_SMART = 0x20
IFT_1822 = 0x2 IFT_1822 = 0x2
IFT_A12MPPSWITCH = 0x82 IFT_A12MPPSWITCH = 0x82
@@ -210,13 +211,18 @@ const (
IFT_XETHER = 0x1a IFT_XETHER = 0x1a
IPPROTO_MAXID = 0x34 IPPROTO_MAXID = 0x34
IPV6_FAITH = 0x1d IPV6_FAITH = 0x1d
IPV6_MIN_MEMBERSHIPS = 0x1f
IP_FAITH = 0x16 IP_FAITH = 0x16
IP_MAX_SOURCE_FILTER = 0x400
IP_MIN_MEMBERSHIPS = 0x1f
MAP_NORESERVE = 0x40 MAP_NORESERVE = 0x40
MAP_RENAME = 0x20 MAP_RENAME = 0x20
NET_RT_MAXID = 0x6 NET_RT_MAXID = 0x6
RTF_PRCLONING = 0x10000 RTF_PRCLONING = 0x10000
RTM_OLDADD = 0x9 RTM_OLDADD = 0x9
RTM_OLDDEL = 0xa RTM_OLDDEL = 0xa
RT_CACHING_CONTEXT = 0x1
RT_NORTREF = 0x2
SIOCADDRT = 0x8030720a SIOCADDRT = 0x8030720a
SIOCALIFADDR = 0x8118691b SIOCALIFADDR = 0x8118691b
SIOCDELRT = 0x8030720b SIOCDELRT = 0x8030720b

View File

@@ -8,6 +8,7 @@
package unix package unix
const ( const (
DLT_HHDLC = 0x79
IFF_SMART = 0x20 IFF_SMART = 0x20
IFT_1822 = 0x2 IFT_1822 = 0x2
IFT_A12MPPSWITCH = 0x82 IFT_A12MPPSWITCH = 0x82
@@ -210,13 +211,18 @@ const (
IFT_XETHER = 0x1a IFT_XETHER = 0x1a
IPPROTO_MAXID = 0x34 IPPROTO_MAXID = 0x34
IPV6_FAITH = 0x1d IPV6_FAITH = 0x1d
IPV6_MIN_MEMBERSHIPS = 0x1f
IP_FAITH = 0x16 IP_FAITH = 0x16
IP_MAX_SOURCE_FILTER = 0x400
IP_MIN_MEMBERSHIPS = 0x1f
MAP_NORESERVE = 0x40 MAP_NORESERVE = 0x40
MAP_RENAME = 0x20 MAP_RENAME = 0x20
NET_RT_MAXID = 0x6 NET_RT_MAXID = 0x6
RTF_PRCLONING = 0x10000 RTF_PRCLONING = 0x10000
RTM_OLDADD = 0x9 RTM_OLDADD = 0x9
RTM_OLDDEL = 0xa RTM_OLDDEL = 0xa
RT_CACHING_CONTEXT = 0x1
RT_NORTREF = 0x2
SIOCADDRT = 0x8040720a SIOCADDRT = 0x8040720a
SIOCALIFADDR = 0x8118691b SIOCALIFADDR = 0x8118691b
SIOCDELRT = 0x8040720b SIOCDELRT = 0x8040720b

17
vendor/golang.org/x/sys/unix/errors_freebsd_arm64.go generated vendored Normal file
View File

@@ -0,0 +1,17 @@
// 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.
// Constants that were deprecated or moved to enums in the FreeBSD headers. Keep
// them here for backwards compatibility.
package unix
const (
DLT_HHDLC = 0x79
IPV6_MIN_MEMBERSHIPS = 0x1f
IP_MAX_SOURCE_FILTER = 0x400
IP_MIN_MEMBERSHIPS = 0x1f
RT_CACHING_CONTEXT = 0x1
RT_NORTREF = 0x2
)

View File

@@ -9,12 +9,11 @@ package unix
import "unsafe" import "unsafe"
// fcntl64Syscall is usually SYS_FCNTL, but is overridden on 32-bit Linux // 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 var fcntl64Syscall uintptr = SYS_FCNTL
// FcntlInt performs a fcntl syscall on fd with the provided command and argument. func fcntl(fd int, cmd, arg int) (int, error) {
func FcntlInt(fd uintptr, cmd, arg int) (int, error) { valptr, _, errno := Syscall(fcntl64Syscall, uintptr(fd), uintptr(cmd), uintptr(arg))
valptr, _, errno := Syscall(fcntl64Syscall, fd, uintptr(cmd), uintptr(arg))
var err error var err error
if errno != 0 { if errno != 0 {
err = errno err = errno
@@ -22,6 +21,11 @@ func FcntlInt(fd uintptr, cmd, arg int) (int, error) {
return int(valptr), err 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. // 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 { func FcntlFlock(fd uintptr, cmd int, lk *Flock_t) error {
_, _, errno := Syscall(fcntl64Syscall, fd, uintptr(cmd), uintptr(unsafe.Pointer(lk))) _, _, errno := Syscall(fcntl64Syscall, fd, uintptr(cmd), uintptr(unsafe.Pointer(lk)))

29
vendor/golang.org/x/sys/unix/fdset.go generated vendored Normal file
View File

@@ -0,0 +1,29 @@
// 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 aix darwin dragonfly freebsd linux netbsd openbsd solaris
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
}
}

View File

@@ -6,7 +6,19 @@
package unix 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))
}
// IoctlSetWinsize performs an ioctl on fd with a *Winsize argument. // IoctlSetWinsize performs an ioctl on fd with a *Winsize argument.
// //
@@ -14,7 +26,7 @@ import "runtime"
func IoctlSetWinsize(fd int, req uint, value *Winsize) error { func IoctlSetWinsize(fd int, req uint, value *Winsize) error {
// TODO: if we get the chance, remove the req parameter and // TODO: if we get the chance, remove the req parameter and
// hardcode TIOCSWINSZ. // hardcode TIOCSWINSZ.
err := ioctlSetWinsize(fd, req, value) err := ioctl(fd, req, uintptr(unsafe.Pointer(value)))
runtime.KeepAlive(value) runtime.KeepAlive(value)
return err return err
} }
@@ -24,7 +36,30 @@ func IoctlSetWinsize(fd int, req uint, value *Winsize) error {
// The req value will usually be TCSETA or TIOCSETA. // The req value will usually be TCSETA or TIOCSETA.
func IoctlSetTermios(fd int, req uint, value *Termios) error { func IoctlSetTermios(fd int, req uint, value *Termios) error {
// TODO: if we get the chance, remove the req parameter. // 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) runtime.KeepAlive(value)
return err 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
}

240
vendor/golang.org/x/sys/unix/mkall.sh generated vendored Normal file
View File

@@ -0,0 +1,240 @@
#!/usr/bin/env bash
# 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 script runs or (given -n) prints suggested commands to generate files for
# the Architecture/OS specified by the GOARCH and GOOS environment variables.
# See README.md for more information about how the build system works.
GOOSARCH="${GOOS}_${GOARCH}"
# defaults
mksyscall="go run mksyscall.go"
mkerrors="./mkerrors.sh"
zerrors="zerrors_$GOOSARCH.go"
mksysctl=""
zsysctl="zsysctl_$GOOSARCH.go"
mksysnum=
mktypes=
mkasm=
run="sh"
cmd=""
case "$1" in
-syscalls)
for i in zsyscall*go
do
# Run the command line that appears in the first line
# of the generated file to regenerate it.
sed 1q $i | sed 's;^// ;;' | sh > _$i && gofmt < _$i > $i
rm _$i
done
exit 0
;;
-n)
run="cat"
cmd="echo"
shift
esac
case "$#" in
0)
;;
*)
echo 'usage: mkall.sh [-n]' 1>&2
exit 2
esac
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 $(cd -- "$(dirname -- "$0")" && /bin/pwd):/build generate:$GOOS
exit
fi
GOOSARCH_in=syscall_$GOOSARCH.go
case "$GOOSARCH" in
_* | *_ | _)
echo 'undefined $GOOS_$GOARCH:' "$GOOSARCH" 1>&2
exit 1
;;
aix_ppc)
mkerrors="$mkerrors -maix32"
mksyscall="go run mksyscall_aix_ppc.go -aix"
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
;;
aix_ppc64)
mkerrors="$mkerrors -maix64"
mksyscall="go run mksyscall_aix_ppc64.go -aix"
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
;;
darwin_386)
mkerrors="$mkerrors -m32"
mksyscall="go run mksyscall.go -l32"
mksysnum="go run mksysnum.go $(xcrun --show-sdk-path --sdk macosx)/usr/include/sys/syscall.h"
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
mkasm="go run mkasm_darwin.go"
;;
darwin_amd64)
mkerrors="$mkerrors -m64"
mksysnum="go run mksysnum.go $(xcrun --show-sdk-path --sdk macosx)/usr/include/sys/syscall.h"
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
mkasm="go run mkasm_darwin.go"
;;
darwin_arm)
mkerrors="$mkerrors"
mksyscall="go run mksyscall.go -l32"
mksysnum="go run mksysnum.go $(xcrun --show-sdk-path --sdk iphoneos)/usr/include/sys/syscall.h"
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
mkasm="go run mkasm_darwin.go"
;;
darwin_arm64)
mkerrors="$mkerrors -m64"
mksysnum="go run mksysnum.go $(xcrun --show-sdk-path --sdk iphoneos)/usr/include/sys/syscall.h"
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
mkasm="go run mkasm_darwin.go"
;;
dragonfly_amd64)
mkerrors="$mkerrors -m64"
mksyscall="go run mksyscall.go -dragonfly"
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="go run mksysnum.go 'https://svn.freebsd.org/base/stable/11/sys/kern/syscalls.master'"
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
;;
freebsd_amd64)
mkerrors="$mkerrors -m64"
mksysnum="go run mksysnum.go 'https://svn.freebsd.org/base/stable/11/sys/kern/syscalls.master'"
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
;;
freebsd_arm)
mkerrors="$mkerrors"
mksyscall="go run mksyscall.go -l32 -arm"
mksysnum="go run mksysnum.go 'https://svn.freebsd.org/base/stable/11/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"
;;
freebsd_arm64)
mkerrors="$mkerrors -m64"
mksysnum="go run mksysnum.go 'https://svn.freebsd.org/base/stable/11/sys/kern/syscalls.master'"
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
;;
netbsd_386)
mkerrors="$mkerrors -m32"
mksyscall="go run mksyscall.go -l32 -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"
;;
netbsd_amd64)
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"
;;
netbsd_arm)
mkerrors="$mkerrors"
mksyscall="go run mksyscall.go -l32 -netbsd -arm"
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)
mkerrors="$mkerrors -m32"
mksyscall="go run mksyscall.go -l32 -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'"
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
;;
openbsd_amd64)
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'"
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
;;
openbsd_arm)
mkerrors="$mkerrors"
mksyscall="go run mksyscall.go -l32 -openbsd -arm"
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_arm64)
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"
;;
solaris_amd64)
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=
;;
*)
echo 'unrecognized $GOOS_$GOARCH: ' "$GOOSARCH" 1>&2
exit 1
;;
esac
(
if [ -n "$mkerrors" ]; then echo "$mkerrors |gofmt >$zerrors"; fi
case "$GOOS" in
*)
syscall_goos="syscall_$GOOS.go"
case "$GOOS" in
darwin | dragonfly | freebsd | netbsd | openbsd)
syscall_goos="syscall_bsd.go $syscall_goos"
;;
esac
if [ -n "$mksyscall" ]; then
if [ "$GOOSARCH" == "aix_ppc64" ]; then
# aix/ppc64 script generates files instead of writing to stdin.
echo "$mksyscall -tags $GOOS,$GOARCH $syscall_goos $GOOSARCH_in && gofmt -w zsyscall_$GOOSARCH.go && gofmt -w zsyscall_"$GOOSARCH"_gccgo.go && gofmt -w zsyscall_"$GOOSARCH"_gc.go " ;
elif [ "$GOOS" == "darwin" ]; then
# pre-1.12, direct syscalls
echo "$mksyscall -tags $GOOS,$GOARCH,!go1.12 $syscall_goos syscall_darwin_${GOARCH}.1_11.go $GOOSARCH_in |gofmt >zsyscall_$GOOSARCH.1_11.go";
# 1.12 and later, syscalls via libSystem
echo "$mksyscall -tags $GOOS,$GOARCH,go1.12 $syscall_goos $GOOSARCH_in |gofmt >zsyscall_$GOOSARCH.go";
# 1.13 and later, syscalls via libSystem (including syscallPtr)
echo "$mksyscall -tags $GOOS,$GOARCH,go1.13 syscall_darwin.1_13.go |gofmt >zsyscall_$GOOSARCH.1_13.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
fi
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 "$mkasm" ]; then echo "$mkasm $GOARCH"; fi
) | $run

View File

@@ -1,61 +0,0 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build ignore
// mkasm_darwin.go generates assembly trampolines to call libSystem routines from Go.
//This program must be run after mksyscall.go.
package main
import (
"bytes"
"fmt"
"io/ioutil"
"log"
"os"
"strings"
)
func main() {
in1, err := ioutil.ReadFile("syscall_darwin.go")
if err != nil {
log.Fatalf("can't open syscall_darwin.go: %s", err)
}
arch := os.Args[1]
in2, err := ioutil.ReadFile(fmt.Sprintf("syscall_darwin_%s.go", arch))
if err != nil {
log.Fatalf("can't open syscall_darwin_%s.go: %s", arch, err)
}
in3, err := ioutil.ReadFile(fmt.Sprintf("zsyscall_darwin_%s.go", arch))
if err != nil {
log.Fatalf("can't open zsyscall_darwin_%s.go: %s", arch, err)
}
in := string(in1) + string(in2) + string(in3)
trampolines := map[string]bool{}
var out bytes.Buffer
fmt.Fprintf(&out, "// go run mkasm_darwin.go %s\n", strings.Join(os.Args[1:], " "))
fmt.Fprintf(&out, "// Code generated by the command above; DO NOT EDIT.\n")
fmt.Fprintf(&out, "\n")
fmt.Fprintf(&out, "// +build go1.12\n")
fmt.Fprintf(&out, "\n")
fmt.Fprintf(&out, "#include \"textflag.h\"\n")
for _, line := range strings.Split(in, "\n") {
if !strings.HasPrefix(line, "func ") || !strings.HasSuffix(line, "_trampoline()") {
continue
}
fn := line[5 : len(line)-13]
if !trampolines[fn] {
trampolines[fn] = true
fmt.Fprintf(&out, "TEXT ·%s_trampoline(SB),NOSPLIT,$0-0\n", fn)
fmt.Fprintf(&out, "\tJMP\t%s(SB)\n", fn)
}
}
err = ioutil.WriteFile(fmt.Sprintf("zsyscall_darwin_%s.s", arch), out.Bytes(), 0644)
if err != nil {
log.Fatalf("can't write zsyscall_darwin_%s.s: %s", arch, err)
}
}

708
vendor/golang.org/x/sys/unix/mkerrors.sh generated vendored Normal file
View File

@@ -0,0 +1,708 @@
#!/usr/bin/env bash
# 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 Go code listing errors and other #defined constant
# values (ENAMETOOLONG etc.), by asking the preprocessor
# about the definitions.
unset LANG
export LC_ALL=C
export LC_CTYPE=C
if test -z "$GOARCH" -o -z "$GOOS"; then
echo 1>&2 "GOARCH or GOOS not defined in environment"
exit 1
fi
# Check that we are using the new build system if we should
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
CC=${CC:-gcc}
else
CC=${CC:-cc}
fi
if [[ "$GOOS" = "solaris" ]]; then
# Assumes GNU versions of utilities in PATH.
export PATH=/usr/gnu/bin:$PATH
fi
uname=$(uname)
includes_AIX='
#include <net/if.h>
#include <net/netopt.h>
#include <netinet/ip_mroute.h>
#include <sys/protosw.h>
#include <sys/stropts.h>
#include <sys/mman.h>
#include <sys/poll.h>
#include <sys/select.h>
#include <sys/termio.h>
#include <termios.h>
#include <fcntl.h>
#define AF_LOCAL AF_UNIX
'
includes_Darwin='
#define _DARWIN_C_SOURCE
#define KERNEL
#define _DARWIN_USE_64_BIT_INODE
#include <stdint.h>
#include <sys/attr.h>
#include <sys/types.h>
#include <sys/event.h>
#include <sys/ptrace.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/sockio.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 <net/bpf.h>
#include <net/if.h>
#include <net/if_types.h>
#include <net/route.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <termios.h>
'
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>
#include <sys/sysctl.h>
#include <sys/mman.h>
#include <sys/mount.h>
#include <sys/wait.h>
#include <sys/ioctl.h>
#include <net/bpf.h>
#include <net/if.h>
#include <net/if_types.h>
#include <net/route.h>
#include <netinet/in.h>
#include <termios.h>
#include <netinet/ip.h>
#include <net/ip_mroute/ip_mroute.h>
'
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/sockio.h>
#include <sys/stat.h>
#include <sys/sysctl.h>
#include <sys/mman.h>
#include <sys/mount.h>
#include <sys/wait.h>
#include <sys/ioctl.h>
#include <net/bpf.h>
#include <net/if.h>
#include <net/if_types.h>
#include <net/route.h>
#include <netinet/in.h>
#include <termios.h>
#include <netinet/ip.h>
#include <netinet/ip_mroute.h>
#include <sys/extattr.h>
#if __FreeBSD__ >= 10
#define IFT_CARP 0xf8 // IFT_CARP is deprecated in FreeBSD 10
#undef SIOCAIFADDR
#define SIOCAIFADDR _IOW(105, 26, struct oifaliasreq) // ifaliasreq contains if_data
#undef SIOCSIFPHYADDR
#define SIOCSIFPHYADDR _IOW(105, 70, struct oifaliasreq) // ifaliasreq contains if_data
#endif
'
includes_Linux='
#define _LARGEFILE_SOURCE
#define _LARGEFILE64_SOURCE
#ifndef __LP64__
#define _FILE_OFFSET_BITS 64
#endif
#define _GNU_SOURCE
// <sys/ioctl.h> is broken on powerpc64, as it fails to include definitions of
// these structures. We just include them copied from <bits/termios.h>.
#if defined(__powerpc__)
struct sgttyb {
char sg_ispeed;
char sg_ospeed;
char sg_erase;
char sg_kill;
short sg_flags;
};
struct tchars {
char t_intrc;
char t_quitc;
char t_startc;
char t_stopc;
char t_eofc;
char t_brkc;
};
struct ltchars {
char t_suspc;
char t_dsuspc;
char t_rprntc;
char t_flushc;
char t_werasc;
char t_lnextc;
};
#endif
#include <bits/sockaddr.h>
#include <sys/epoll.h>
#include <sys/eventfd.h>
#include <sys/inotify.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/mount.h>
#include <sys/prctl.h>
#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/bpf.h>
#include <linux/can.h>
#include <linux/capability.h>
#include <linux/cryptouser.h>
#include <linux/devlink.h>
#include <linux/errqueue.h>
#include <linux/falloc.h>
#include <linux/fanotify.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/icmpv6.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_xdp.h>
#include <linux/kexec.h>
#include <linux/keyctl.h>
#include <linux/loop.h>
#include <linux/magic.h>
#include <linux/memfd.h>
#include <linux/module.h>
#include <linux/netfilter/nfnetlink.h>
#include <linux/netlink.h>
#include <linux/net_namespace.h>
#include <linux/nsfs.h>
#include <linux/perf_event.h>
#include <linux/ptrace.h>
#include <linux/random.h>
#include <linux/reboot.h>
#include <linux/rtc.h>
#include <linux/rtnetlink.h>
#include <linux/sched.h>
#include <linux/seccomp.h>
#include <linux/serial.h>
#include <linux/sockios.h>
#include <linux/taskstats.h>
#include <linux/tipc.h>
#include <linux/vm_sockets.h>
#include <linux/wait.h>
#include <linux/watchdog.h>
#include <mtd/ubi-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
#endif
#ifndef PTRACE_GETREGS
#define PTRACE_GETREGS 0xc
#endif
#ifndef PTRACE_SETREGS
#define PTRACE_SETREGS 0xd
#endif
#ifndef SOL_NETLINK
#define SOL_NETLINK 270
#endif
#ifdef SOL_BLUETOOTH
// SPARC includes this in /usr/include/sparc64-linux-gnu/bits/socket.h
// but it is already in bluetooth_linux.go
#undef SOL_BLUETOOTH
#endif
// Certain constants are missing from the fs/crypto UAPI
#define FS_KEY_DESC_PREFIX "fscrypt:"
#define FS_KEY_DESC_PREFIX_SIZE 8
#define FS_MAX_KEY_SIZE 64
// 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
'
includes_NetBSD='
#include <sys/types.h>
#include <sys/param.h>
#include <sys/event.h>
#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>
#include <sys/termios.h>
#include <sys/ttycom.h>
#include <sys/wait.h>
#include <net/bpf.h>
#include <net/if.h>
#include <net/if_types.h>
#include <net/route.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/ip_mroute.h>
#include <netinet/if_ether.h>
// Needed since <sys/param.h> refers to it...
#define schedppq 1
'
includes_OpenBSD='
#include <sys/types.h>
#include <sys/param.h>
#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>
#include <sys/sysctl.h>
#include <sys/termios.h>
#include <sys/ttycom.h>
#include <sys/unistd.h>
#include <sys/wait.h>
#include <net/bpf.h>
#include <net/if.h>
#include <net/if_types.h>
#include <net/if_var.h>
#include <net/route.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/ip_mroute.h>
#include <netinet/if_ether.h>
#include <net/if_bridge.h>
// We keep some constants not supported in OpenBSD 5.5 and beyond for
// the promise of compatibility.
#define EMUL_ENABLED 0x1
#define EMUL_NATIVE 0x2
#define IPV6_FAITH 0x1d
#define IPV6_OPTIONS 0x1
#define IPV6_RTHDR_STRICT 0x1
#define IPV6_SOCKOPT_RESERVED1 0x3
#define SIOCGIFGENERIC 0xc020693a
#define SIOCSIFGENERIC 0x80206939
#define WALTSIG 0x4
'
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/mman.h>
#include <sys/wait.h>
#include <sys/ioctl.h>
#include <sys/mkdev.h>
#include <net/bpf.h>
#include <net/if.h>
#include <net/if_arp.h>
#include <net/if_types.h>
#include <net/route.h>
#include <netinet/in.h>
#include <termios.h>
#include <netinet/ip.h>
#include <netinet/ip_mroute.h>
'
includes='
#include <sys/types.h>
#include <sys/file.h>
#include <fcntl.h>
#include <dirent.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip6.h>
#include <netinet/tcp.h>
#include <errno.h>
#include <sys/signal.h>
#include <signal.h>
#include <sys/resource.h>
#include <time.h>
'
ccflags="$@"
# Write go tool cgo -godefs input.
(
echo package unix
echo
echo '/*'
indirect="includes_$(uname)"
echo "${!indirect} $includes"
echo '*/'
echo 'import "C"'
echo 'import "syscall"'
echo
echo 'const ('
# The gcc command line prints all the #defines
# it encounters while processing the input
echo "${!indirect} $includes" | $CC -x c - -E -dM $ccflags |
awk '
$1 != "#define" || $2 ~ /\(/ || $3 == "" {next}
$2 ~ /^E([ABCD]X|[BIS]P|[SD]I|S|FL)$/ {next} # 386 registers
$2 ~ /^(SIGEV_|SIGSTKSZ|SIGRT(MIN|MAX))/ {next}
$2 ~ /^(SCM_SRCRT)$/ {next}
$2 ~ /^(MAP_FAILED)$/ {next}
$2 ~ /^ELF_.*$/ {next}# <asm/elf.h> contains ELF_ARCH, etc.
$2 ~ /^EXTATTR_NAMESPACE_NAMES/ ||
$2 ~ /^EXTATTR_NAMESPACE_[A-Z]+_STRING/ {next}
$2 !~ /^ECCAPBITS/ &&
$2 !~ /^ETH_/ &&
$2 !~ /^EPROC_/ &&
$2 !~ /^EQUIV_/ &&
$2 !~ /^EXPR_/ &&
$2 ~ /^E[A-Z0-9_]+$/ ||
$2 ~ /^B[0-9_]+$/ ||
$2 ~ /^(OLD|NEW)DEV$/ ||
$2 == "BOTHER" ||
$2 ~ /^CI?BAUD(EX)?$/ ||
$2 == "IBSHIFT" ||
$2 ~ /^V[A-Z0-9]+$/ ||
$2 ~ /^CS[A-Z0-9]/ ||
$2 ~ /^I(SIG|CANON|CRNL|UCLC|EXTEN|MAXBEL|STRIP|UTF8)$/ ||
$2 ~ /^IGN/ ||
$2 ~ /^IX(ON|ANY|OFF)$/ ||
$2 ~ /^IN(LCR|PCK)$/ ||
$2 !~ "X86_CR3_PCID_NOFLUSH" &&
$2 ~ /(^FLU?SH)|(FLU?SH$)/ ||
$2 ~ /^C(LOCAL|READ|MSPAR|RTSCTS)$/ ||
$2 == "BRKINT" ||
$2 == "HUPCL" ||
$2 == "PENDIN" ||
$2 == "TOSTOP" ||
$2 == "XCASE" ||
$2 == "ALTWERASE" ||
$2 == "NOKERNINFO" ||
$2 == "NFDBITS" ||
$2 ~ /^PAR/ ||
$2 ~ /^SIG[^_]/ ||
$2 ~ /^O[CNPFPL][A-Z]+[^_][A-Z]+$/ ||
$2 ~ /^(NL|CR|TAB|BS|VT|FF)DLY$/ ||
$2 ~ /^(NL|CR|TAB|BS|VT|FF)[0-9]$/ ||
$2 ~ /^O?XTABS$/ ||
$2 ~ /^TC[IO](ON|OFF)$/ ||
$2 ~ /^IN_/ ||
$2 ~ /^LOCK_(SH|EX|NB|UN)$/ ||
$2 ~ /^LO_(KEY|NAME)_SIZE$/ ||
$2 ~ /^LOOP_(CLR|CTL|GET|SET)_/ ||
$2 ~ /^(AF|SOCK|SO|SOL|IPPROTO|IP|IPV6|ICMP6|TCP|MCAST|EVFILT|NOTE|EV|SHUT|PROT|MAP|MFD|T?PACKET|MSG|SCM|MCL|DT|MADV|PR)_/ ||
$2 ~ /^TP_STATUS_/ ||
$2 ~ /^FALLOC_/ ||
$2 == "ICMPV6_FILTER" ||
$2 == "SOMAXCONN" ||
$2 == "NAME_MAX" ||
$2 == "IFNAMSIZ" ||
$2 ~ /^CTL_(HW|KERN|MAXNAME|NET|QUERY)$/ ||
$2 ~ /^KERN_(HOSTNAME|OS(RELEASE|TYPE)|VERSION)$/ ||
$2 ~ /^HW_MACHINE$/ ||
$2 ~ /^SYSCTL_VERS/ ||
$2 !~ "MNT_BITS" &&
$2 ~ /^(MS|MNT|UMOUNT)_/ ||
$2 ~ /^NS_GET_/ ||
$2 ~ /^TUN(SET|GET|ATTACH|DETACH)/ ||
$2 ~ /^(O|F|[ES]?FD|NAME|S|PTRACE|PT|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 ~ /^SIOC/ ||
$2 ~ /^TIOC/ ||
$2 ~ /^TCGET/ ||
$2 ~ /^TCSET/ ||
$2 ~ /^TC(FLSH|SBRKP?|XONC)$/ ||
$2 !~ "RTF_BITS" &&
$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|BPF_FIB_LOOKUP_[A-Z]+)$/ &&
$2 ~ /^(BPF|DLT)_/ ||
$2 ~ /^(CLOCK|TIMER)_/ ||
$2 ~ /^CAN_/ ||
$2 ~ /^CAP_/ ||
$2 ~ /^CP_/ ||
$2 ~ /^CPUSTATES$/ ||
$2 ~ /^ALG_/ ||
$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 ~ /^GRND_/ ||
$2 ~ /^RND/ ||
$2 ~ /^KEY_(SPEC|REQKEY_DEFL)_/ ||
$2 ~ /^KEYCTL_/ ||
$2 ~ /^PERF_EVENT_IOC_/ ||
$2 ~ /^SECCOMP_MODE_/ ||
$2 ~ /^SPLICE_/ ||
$2 ~ /^SYNC_FILE_RANGE_/ ||
$2 !~ /^AUDIT_RECORD_MAGIC/ &&
$2 !~ /IOC_MAGIC/ &&
$2 ~ /^[A-Z][A-Z0-9_]+_MAGIC2?$/ ||
$2 ~ /^(VM|VMADDR)_/ ||
$2 ~ /^IOCTL_VM_SOCKETS_/ ||
$2 ~ /^(TASKSTATS|TS)_/ ||
$2 ~ /^CGROUPSTATS_/ ||
$2 ~ /^GENL_/ ||
$2 ~ /^STATX_/ ||
$2 ~ /^RENAME/ ||
$2 ~ /^UBI_IOC[A-Z]/ ||
$2 ~ /^UTIME_/ ||
$2 ~ /^XATTR_(CREATE|REPLACE|NO(DEFAULT|FOLLOW|SECURITY)|SHOWCOMPRESSION)/ ||
$2 ~ /^ATTR_(BIT_MAP_COUNT|(CMN|VOL|FILE)_)/ ||
$2 ~ /^FSOPT_/ ||
$2 ~ /^WDIOC_/ ||
$2 ~ /^NFN/ ||
$2 ~ /^XDP_/ ||
$2 ~ /^RWF_/ ||
$2 ~ /^(HDIO|WIN|SMART)_/ ||
$2 ~ /^CRYPTO_/ ||
$2 ~ /^TIPC_/ ||
$2 ~ /^DEVLINK_/ ||
$2 !~ "WMESGLEN" &&
$2 ~ /^W[A-Z0-9]+$/ ||
$2 ~/^PPPIOC/ ||
$2 ~ /^FAN_|FANOTIFY_/ ||
$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)}
{next}
' | sort
echo ')'
) >_const.go
# Pull out the error names for later.
errors=$(
echo '#include <errno.h>' | $CC -x c - -E -dM $ccflags |
awk '$1=="#define" && $2 ~ /^E[A-Z0-9_]+$/ { print $2 }' |
sort
)
# Pull out the signal names for later.
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)' |
sort
)
# Again, writing regexps to a file.
echo '#include <errno.h>' | $CC -x c - -E -dM $ccflags |
awk '$1=="#define" && $2 ~ /^E[A-Z0-9_]+$/ { print "^\t" $2 "[ \t]*=" }' |
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)' |
sort >_signal.grep
echo '// mkerrors.sh' "$@"
echo '// Code generated by the command above; see README.md. DO NOT EDIT.'
echo
echo "// +build ${GOARCH},${GOOS}"
echo
go tool cgo -godefs -- "$@" _const.go >_error.out
cat _error.out | grep -vf _error.grep | grep -vf _signal.grep
echo
echo '// Errors'
echo 'const ('
cat _error.out | grep -f _error.grep | sed 's/=\(.*\)/= syscall.Errno(\1)/'
echo ')'
echo
echo '// Signals'
echo 'const ('
cat _error.out | grep -f _signal.grep | sed 's/=\(.*\)/= syscall.Signal(\1)/'
echo ')'
# Run C program to print error and syscall strings.
(
echo -E "
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <ctype.h>
#include <string.h>
#include <signal.h>
#define nelem(x) (sizeof(x)/sizeof((x)[0]))
enum { A = 'A', Z = 'Z', a = 'a', z = 'z' }; // avoid need for single quotes below
struct tuple {
int num;
const char *name;
};
struct tuple errors[] = {
"
for i in $errors
do
echo -E ' {'$i', "'$i'" },'
done
echo -E "
};
struct tuple signals[] = {
"
for i in $signals
do
echo -E ' {'$i', "'$i'" },'
done
# Use -E because on some systems bash builtin interprets \n itself.
echo -E '
};
static int
tuplecmp(const void *a, const void *b)
{
return ((struct tuple *)a)->num - ((struct tuple *)b)->num;
}
int
main(void)
{
int i, e;
char buf[1024], *p;
printf("\n\n// Error table\n");
printf("var errorList = [...]struct {\n");
printf("\tnum syscall.Errno\n");
printf("\tname string\n");
printf("\tdesc string\n");
printf("} {\n");
qsort(errors, nelem(errors), sizeof errors[0], tuplecmp);
for(i=0; i<nelem(errors); i++) {
e = errors[i].num;
if(i > 0 && errors[i-1].num == e)
continue;
strcpy(buf, strerror(e));
// lowercase first letter: Bad -> bad, but STREAM -> STREAM.
if(A <= buf[0] && buf[0] <= Z && a <= buf[1] && buf[1] <= z)
buf[0] += a - A;
printf("\t{ %d, \"%s\", \"%s\" },\n", e, errors[i].name, buf);
}
printf("}\n\n");
printf("\n\n// Signal table\n");
printf("var signalList = [...]struct {\n");
printf("\tnum syscall.Signal\n");
printf("\tname string\n");
printf("\tdesc string\n");
printf("} {\n");
qsort(signals, nelem(signals), sizeof signals[0], tuplecmp);
for(i=0; i<nelem(signals); i++) {
e = signals[i].num;
if(i > 0 && signals[i-1].num == e)
continue;
strcpy(buf, strsignal(e));
// lowercase first letter: Bad -> bad, but STREAM -> STREAM.
if(A <= buf[0] && buf[0] <= Z && a <= buf[1] && buf[1] <= z)
buf[0] += a - A;
// cut trailing : number.
p = strrchr(buf, ":"[0]);
if(p)
*p = '\0';
printf("\t{ %d, \"%s\", \"%s\" },\n", e, signals[i].name, buf);
}
printf("}\n\n");
return 0;
}
'
) >_errors.c
$CC $ccflags -o _errors _errors.c && $GORUN ./_errors && rm -f _errors.c _errors _const.go _error.grep _signal.grep _error.out

View File

@@ -1,122 +0,0 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build ignore
// mkpost processes the output of cgo -godefs to
// modify the generated types. It is used to clean up
// the sys API in an architecture specific manner.
//
// mkpost is run after cgo -godefs; see README.md.
package main
import (
"bytes"
"fmt"
"go/format"
"io/ioutil"
"log"
"os"
"regexp"
)
func main() {
// Get the OS and architecture (using GOARCH_TARGET if it exists)
goos := os.Getenv("GOOS")
goarch := os.Getenv("GOARCH_TARGET")
if goarch == "" {
goarch = os.Getenv("GOARCH")
}
// Check that we are using the Docker-based build system if we should be.
if goos == "linux" {
if os.Getenv("GOLANG_SYS_BUILD") != "docker" {
os.Stderr.WriteString("In the Docker-based build system, mkpost should not be called directly.\n")
os.Stderr.WriteString("See README.md\n")
os.Exit(1)
}
}
b, err := ioutil.ReadAll(os.Stdin)
if err != nil {
log.Fatal(err)
}
if goos == "aix" {
// Replace type of Atim, Mtim and Ctim by Timespec in Stat_t
// to avoid having both StTimespec and Timespec.
sttimespec := regexp.MustCompile(`_Ctype_struct_st_timespec`)
b = sttimespec.ReplaceAll(b, []byte("Timespec"))
}
// Intentionally export __val fields in Fsid and Sigset_t
valRegex := regexp.MustCompile(`type (Fsid|Sigset_t) struct {(\s+)X__(bits|val)(\s+\S+\s+)}`)
b = valRegex.ReplaceAll(b, []byte("type $1 struct {${2}Val$4}"))
// Intentionally export __fds_bits field in FdSet
fdSetRegex := regexp.MustCompile(`type (FdSet) struct {(\s+)X__fds_bits(\s+\S+\s+)}`)
b = fdSetRegex.ReplaceAll(b, []byte("type $1 struct {${2}Bits$3}"))
// If we have empty Ptrace structs, we should delete them. Only s390x emits
// nonempty Ptrace structs.
ptraceRexexp := regexp.MustCompile(`type Ptrace((Psw|Fpregs|Per) struct {\s*})`)
b = ptraceRexexp.ReplaceAll(b, nil)
// Replace the control_regs union with a blank identifier for now.
controlRegsRegex := regexp.MustCompile(`(Control_regs)\s+\[0\]uint64`)
b = controlRegsRegex.ReplaceAll(b, []byte("_ [0]uint64"))
// Remove fields that are added by glibc
// Note that this is unstable as the identifers are private.
removeFieldsRegex := regexp.MustCompile(`X__glibc\S*`)
b = removeFieldsRegex.ReplaceAll(b, []byte("_"))
// Convert [65]int8 to [65]byte in Utsname members to simplify
// conversion to string; see golang.org/issue/20753
convertUtsnameRegex := regexp.MustCompile(`((Sys|Node|Domain)name|Release|Version|Machine)(\s+)\[(\d+)\]u?int8`)
b = convertUtsnameRegex.ReplaceAll(b, []byte("$1$3[$4]byte"))
// Convert [1024]int8 to [1024]byte in Ptmget members
convertPtmget := regexp.MustCompile(`([SC]n)(\s+)\[(\d+)\]u?int8`)
b = convertPtmget.ReplaceAll(b, []byte("$1[$3]byte"))
// Remove spare fields (e.g. in Statx_t)
spareFieldsRegex := regexp.MustCompile(`X__spare\S*`)
b = spareFieldsRegex.ReplaceAll(b, []byte("_"))
// Remove cgo padding fields
removePaddingFieldsRegex := regexp.MustCompile(`Pad_cgo_\d+`)
b = removePaddingFieldsRegex.ReplaceAll(b, []byte("_"))
// Remove padding, hidden, or unused fields
removeFieldsRegex = regexp.MustCompile(`\b(X_\S+|Padding)`)
b = removeFieldsRegex.ReplaceAll(b, []byte("_"))
// Remove the first line of warning from cgo
b = b[bytes.IndexByte(b, '\n')+1:]
// Modify the command in the header to include:
// mkpost, our own warning, and a build tag.
replacement := fmt.Sprintf(`$1 | go run mkpost.go
// Code generated by the command above; see README.md. DO NOT EDIT.
// +build %s,%s`, goarch, goos)
cgoCommandRegex := regexp.MustCompile(`(cgo -godefs .*)`)
b = cgoCommandRegex.ReplaceAll(b, []byte(replacement))
// Rename Stat_t time fields
if goos == "freebsd" && goarch == "386" {
// Hide Stat_t.[AMCB]tim_ext fields
renameStatTimeExtFieldsRegex := regexp.MustCompile(`[AMCB]tim_ext`)
b = renameStatTimeExtFieldsRegex.ReplaceAll(b, []byte("_"))
}
renameStatTimeFieldsRegex := regexp.MustCompile(`([AMCB])(?:irth)?time?(?:spec)?\s+(Timespec|StTimespec)`)
b = renameStatTimeFieldsRegex.ReplaceAll(b, []byte("${1}tim ${2}"))
// gofmt
b, err = format.Source(b)
if err != nil {
log.Fatal(err)
}
os.Stdout.Write(b)
}

View File

@@ -1,407 +0,0 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build ignore
/*
This program reads a file containing function prototypes
(like syscall_darwin.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 errno.
A line beginning with //sysnb is like //sys, except that the
goroutine will not be suspended during the execution of the system
call. This must only be used for system calls which can never
block, as otherwise the system call could cause all goroutines to
hang.
*/
package main
import (
"bufio"
"flag"
"fmt"
"os"
"regexp"
"strings"
)
var (
b32 = flag.Bool("b32", false, "32bit big-endian")
l32 = flag.Bool("l32", false, "32bit little-endian")
plan9 = flag.Bool("plan9", false, "plan9")
openbsd = flag.Bool("openbsd", false, "openbsd")
netbsd = flag.Bool("netbsd", false, "netbsd")
dragonfly = flag.Bool("dragonfly", false, "dragonfly")
arm = flag.Bool("arm", false, "arm") // 64-bit value should use (even, odd)-pair
tags = flag.String("tags", "", "build tags")
filename = flag.String("output", "", "output file name (standard output if omitted)")
)
// cmdLine returns this programs's commandline arguments
func cmdLine() string {
return "go run mksyscall.go " + strings.Join(os.Args[1:], " ")
}
// buildTags returns build tags
func buildTags() string {
return *tags
}
// Param is function parameter
type Param struct {
Name string
Type string
}
// usage prints the program usage
func usage() {
fmt.Fprintf(os.Stderr, "usage: go run mksyscall.go [-b32 | -l32] [-tags x,y] [file ...]\n")
os.Exit(1)
}
// parseParamList parses parameter list and returns a slice of parameters
func parseParamList(list string) []string {
list = strings.TrimSpace(list)
if list == "" {
return []string{}
}
return regexp.MustCompile(`\s*,\s*`).Split(list, -1)
}
// parseParam splits a parameter into name and type
func parseParam(p string) Param {
ps := regexp.MustCompile(`^(\S*) (\S*)$`).FindStringSubmatch(p)
if ps == nil {
fmt.Fprintf(os.Stderr, "malformed parameter: %s\n", p)
os.Exit(1)
}
return Param{ps[1], ps[2]}
}
func main() {
// Get the OS and architecture (using GOARCH_TARGET if it exists)
goos := os.Getenv("GOOS")
if goos == "" {
fmt.Fprintln(os.Stderr, "GOOS not defined in environment")
os.Exit(1)
}
goarch := os.Getenv("GOARCH_TARGET")
if goarch == "" {
goarch = os.Getenv("GOARCH")
}
// Check that we are using the Docker-based build system if we should
if goos == "linux" {
if os.Getenv("GOLANG_SYS_BUILD") != "docker" {
fmt.Fprintf(os.Stderr, "In the Docker-based build system, mksyscall should not be called directly.\n")
fmt.Fprintf(os.Stderr, "See README.md\n")
os.Exit(1)
}
}
flag.Usage = usage
flag.Parse()
if len(flag.Args()) <= 0 {
fmt.Fprintf(os.Stderr, "no files to parse provided\n")
usage()
}
endianness := ""
if *b32 {
endianness = "big-endian"
} else if *l32 {
endianness = "little-endian"
}
libc := false
if goos == "darwin" && strings.Contains(buildTags(), ",go1.12") {
libc = true
}
trampolines := map[string]bool{}
text := ""
for _, path := range flag.Args() {
file, err := os.Open(path)
if err != nil {
fmt.Fprintf(os.Stderr, err.Error())
os.Exit(1)
}
s := bufio.NewScanner(file)
for s.Scan() {
t := s.Text()
t = strings.TrimSpace(t)
t = regexp.MustCompile(`\s+`).ReplaceAllString(t, ` `)
nonblock := regexp.MustCompile(`^\/\/sysnb `).FindStringSubmatch(t)
if regexp.MustCompile(`^\/\/sys `).FindStringSubmatch(t) == nil && nonblock == nil {
continue
}
// Line must be of the form
// func Open(path string, mode int, perm int) (fd int, errno error)
// Split into name, in params, out params.
f := regexp.MustCompile(`^\/\/sys(nb)? (\w+)\(([^()]*)\)\s*(?:\(([^()]+)\))?\s*(?:=\s*((?i)SYS_[A-Z0-9_]+))?$`).FindStringSubmatch(t)
if f == nil {
fmt.Fprintf(os.Stderr, "%s:%s\nmalformed //sys declaration\n", path, t)
os.Exit(1)
}
funct, inps, outps, sysname := f[2], f[3], f[4], f[5]
// ClockGettime doesn't have a syscall number on Darwin, only generate libc wrappers.
if goos == "darwin" && !libc && funct == "ClockGettime" {
continue
}
// Split argument lists on comma.
in := parseParamList(inps)
out := parseParamList(outps)
// 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"
// Go function header.
outDecl := ""
if len(out) > 0 {
outDecl = fmt.Sprintf(" (%s)", strings.Join(out, ", "))
}
text += fmt.Sprintf("func %s(%s)%s {\n", funct, strings.Join(in, ", "), outDecl)
// Check if err return available
errvar := ""
for _, param := range out {
p := parseParam(param)
if p.Type == "error" {
errvar = p.Name
break
}
}
// Prepare arguments to Syscall.
var args []string
n := 0
for _, param := range in {
p := parseParam(param)
if regexp.MustCompile(`^\*`).FindStringSubmatch(p.Type) != nil {
args = append(args, "uintptr(unsafe.Pointer("+p.Name+"))")
} else if p.Type == "string" && errvar != "" {
text += fmt.Sprintf("\tvar _p%d *byte\n", n)
text += fmt.Sprintf("\t_p%d, %s = BytePtrFromString(%s)\n", n, errvar, p.Name)
text += fmt.Sprintf("\tif %s != nil {\n\t\treturn\n\t}\n", errvar)
args = append(args, fmt.Sprintf("uintptr(unsafe.Pointer(_p%d))", n))
n++
} else if p.Type == "string" {
fmt.Fprintf(os.Stderr, path+":"+funct+" uses string arguments, but has no error return\n")
text += fmt.Sprintf("\tvar _p%d *byte\n", n)
text += fmt.Sprintf("\t_p%d, _ = BytePtrFromString(%s)\n", n, p.Name)
args = append(args, fmt.Sprintf("uintptr(unsafe.Pointer(_p%d))", n))
n++
} else if regexp.MustCompile(`^\[\](.*)`).FindStringSubmatch(p.Type) != nil {
// Convert slice into pointer, length.
// Have to be careful not to take address of &a[0] if len == 0:
// pass dummy pointer in that case.
// Used to pass nil, but some OSes or simulators reject write(fd, nil, 0).
text += fmt.Sprintf("\tvar _p%d unsafe.Pointer\n", n)
text += fmt.Sprintf("\tif len(%s) > 0 {\n\t\t_p%d = unsafe.Pointer(&%s[0])\n\t}", p.Name, n, p.Name)
text += fmt.Sprintf(" else {\n\t\t_p%d = unsafe.Pointer(&_zero)\n\t}\n", n)
args = append(args, fmt.Sprintf("uintptr(_p%d)", n), fmt.Sprintf("uintptr(len(%s))", p.Name))
n++
} else if p.Type == "int64" && (*openbsd || *netbsd) {
args = append(args, "0")
if endianness == "big-endian" {
args = append(args, fmt.Sprintf("uintptr(%s>>32)", p.Name), fmt.Sprintf("uintptr(%s)", p.Name))
} else if endianness == "little-endian" {
args = append(args, fmt.Sprintf("uintptr(%s)", p.Name), fmt.Sprintf("uintptr(%s>>32)", p.Name))
} else {
args = append(args, fmt.Sprintf("uintptr(%s)", p.Name))
}
} else if p.Type == "int64" && *dragonfly {
if regexp.MustCompile(`^(?i)extp(read|write)`).FindStringSubmatch(funct) == nil {
args = append(args, "0")
}
if endianness == "big-endian" {
args = append(args, fmt.Sprintf("uintptr(%s>>32)", p.Name), fmt.Sprintf("uintptr(%s)", p.Name))
} else if endianness == "little-endian" {
args = append(args, fmt.Sprintf("uintptr(%s)", p.Name), fmt.Sprintf("uintptr(%s>>32)", p.Name))
} else {
args = append(args, fmt.Sprintf("uintptr(%s)", p.Name))
}
} else if (p.Type == "int64" || p.Type == "uint64") && endianness != "" {
if len(args)%2 == 1 && *arm {
// arm abi specifies 64-bit argument uses
// (even, odd) pair
args = append(args, "0")
}
if endianness == "big-endian" {
args = append(args, fmt.Sprintf("uintptr(%s>>32)", p.Name), fmt.Sprintf("uintptr(%s)", p.Name))
} else {
args = append(args, fmt.Sprintf("uintptr(%s)", p.Name), fmt.Sprintf("uintptr(%s>>32)", p.Name))
}
} else {
args = append(args, fmt.Sprintf("uintptr(%s)", p.Name))
}
}
// Determine which form to use; pad args with zeros.
asm := "Syscall"
if nonblock != nil {
if errvar == "" && goos == "linux" {
asm = "RawSyscallNoError"
} else {
asm = "RawSyscall"
}
} else {
if errvar == "" && goos == "linux" {
asm = "SyscallNoError"
}
}
if len(args) <= 3 {
for len(args) < 3 {
args = append(args, "0")
}
} else if len(args) <= 6 {
asm += "6"
for len(args) < 6 {
args = append(args, "0")
}
} else if len(args) <= 9 {
asm += "9"
for len(args) < 9 {
args = append(args, "0")
}
} else {
fmt.Fprintf(os.Stderr, "%s:%s too many arguments to system call\n", path, funct)
}
// System call number.
if sysname == "" {
sysname = "SYS_" + funct
sysname = regexp.MustCompile(`([a-z])([A-Z])`).ReplaceAllString(sysname, `${1}_$2`)
sysname = strings.ToUpper(sysname)
}
var libcFn string
if libc {
asm = "syscall_" + strings.ToLower(asm[:1]) + asm[1:] // internal syscall call
sysname = strings.TrimPrefix(sysname, "SYS_") // remove SYS_
sysname = strings.ToLower(sysname) // lowercase
if sysname == "getdirentries64" {
// Special case - libSystem name and
// raw syscall name don't match.
sysname = "__getdirentries64"
}
libcFn = sysname
sysname = "funcPC(libc_" + sysname + "_trampoline)"
}
// Actual call.
arglist := strings.Join(args, ", ")
call := fmt.Sprintf("%s(%s, %s)", asm, sysname, arglist)
// Assign return values.
body := ""
ret := []string{"_", "_", "_"}
doErrno := false
for i := 0; i < len(out); i++ {
p := parseParam(out[i])
reg := ""
if p.Name == "err" && !*plan9 {
reg = "e1"
ret[2] = reg
doErrno = true
} else if p.Name == "err" && *plan9 {
ret[0] = "r0"
ret[2] = "e1"
break
} else {
reg = fmt.Sprintf("r%d", i)
ret[i] = reg
}
if p.Type == "bool" {
reg = fmt.Sprintf("%s != 0", reg)
}
if p.Type == "int64" && endianness != "" {
// 64-bit number in r1:r0 or r0:r1.
if i+2 > len(out) {
fmt.Fprintf(os.Stderr, "%s:%s not enough registers for int64 return\n", path, funct)
}
if endianness == "big-endian" {
reg = fmt.Sprintf("int64(r%d)<<32 | int64(r%d)", i, i+1)
} else {
reg = fmt.Sprintf("int64(r%d)<<32 | int64(r%d)", i+1, i)
}
ret[i] = fmt.Sprintf("r%d", i)
ret[i+1] = fmt.Sprintf("r%d", i+1)
}
if reg != "e1" || *plan9 {
body += fmt.Sprintf("\t%s = %s(%s)\n", p.Name, p.Type, reg)
}
}
if ret[0] == "_" && ret[1] == "_" && ret[2] == "_" {
text += fmt.Sprintf("\t%s\n", call)
} else {
if errvar == "" && goos == "linux" {
// raw syscall without error on Linux, see golang.org/issue/22924
text += fmt.Sprintf("\t%s, %s := %s\n", ret[0], ret[1], call)
} else {
text += fmt.Sprintf("\t%s, %s, %s := %s\n", ret[0], ret[1], ret[2], call)
}
}
text += body
if *plan9 && ret[2] == "e1" {
text += "\tif int32(r0) == -1 {\n"
text += "\t\terr = e1\n"
text += "\t}\n"
} else if doErrno {
text += "\tif e1 != 0 {\n"
text += "\t\terr = errnoErr(e1)\n"
text += "\t}\n"
}
text += "\treturn\n"
text += "}\n\n"
if libc && !trampolines[libcFn] {
// some system calls share a trampoline, like read and readlen.
trampolines[libcFn] = true
// Declare assembly trampoline.
text += fmt.Sprintf("func libc_%s_trampoline()\n", libcFn)
// Assembly trampoline calls the libc_* function, which this magic
// redirects to use the function from libSystem.
text += fmt.Sprintf("//go:linkname libc_%s libc_%s\n", libcFn, libcFn)
text += fmt.Sprintf("//go:cgo_import_dynamic libc_%s %s \"/usr/lib/libSystem.B.dylib\"\n", libcFn, libcFn)
text += "\n"
}
}
if err := s.Err(); err != nil {
fmt.Fprintf(os.Stderr, err.Error())
os.Exit(1)
}
file.Close()
}
fmt.Printf(srcTemplate, cmdLine(), buildTags(), text)
}
const srcTemplate = `// %s
// Code generated by the command above; see README.md. DO NOT EDIT.
// +build %s
package unix
import (
"syscall"
"unsafe"
)
var _ syscall.Errno
%s
`

View File

@@ -1,415 +0,0 @@
// 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 ignore
/*
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
*/
package main
import (
"bufio"
"flag"
"fmt"
"os"
"regexp"
"strings"
)
var (
b32 = flag.Bool("b32", false, "32bit big-endian")
l32 = flag.Bool("l32", false, "32bit little-endian")
aix = flag.Bool("aix", false, "aix")
tags = flag.String("tags", "", "build tags")
)
// cmdLine returns this programs's commandline arguments
func cmdLine() string {
return "go run mksyscall_aix_ppc.go " + strings.Join(os.Args[1:], " ")
}
// buildTags returns build tags
func buildTags() string {
return *tags
}
// Param is function parameter
type Param struct {
Name string
Type string
}
// usage prints the program usage
func usage() {
fmt.Fprintf(os.Stderr, "usage: go run mksyscall_aix_ppc.go [-b32 | -l32] [-tags x,y] [file ...]\n")
os.Exit(1)
}
// parseParamList parses parameter list and returns a slice of parameters
func parseParamList(list string) []string {
list = strings.TrimSpace(list)
if list == "" {
return []string{}
}
return regexp.MustCompile(`\s*,\s*`).Split(list, -1)
}
// parseParam splits a parameter into name and type
func parseParam(p string) Param {
ps := regexp.MustCompile(`^(\S*) (\S*)$`).FindStringSubmatch(p)
if ps == nil {
fmt.Fprintf(os.Stderr, "malformed parameter: %s\n", p)
os.Exit(1)
}
return Param{ps[1], ps[2]}
}
func main() {
flag.Usage = usage
flag.Parse()
if len(flag.Args()) <= 0 {
fmt.Fprintf(os.Stderr, "no files to parse provided\n")
usage()
}
endianness := ""
if *b32 {
endianness = "big-endian"
} else if *l32 {
endianness = "little-endian"
}
pack := ""
text := ""
cExtern := "/*\n#include <stdint.h>\n#include <stddef.h>\n"
for _, path := range flag.Args() {
file, err := os.Open(path)
if err != nil {
fmt.Fprintf(os.Stderr, err.Error())
os.Exit(1)
}
s := bufio.NewScanner(file)
for s.Scan() {
t := s.Text()
t = strings.TrimSpace(t)
t = regexp.MustCompile(`\s+`).ReplaceAllString(t, ` `)
if p := regexp.MustCompile(`^package (\S+)$`).FindStringSubmatch(t); p != nil && pack == "" {
pack = p[1]
}
nonblock := regexp.MustCompile(`^\/\/sysnb `).FindStringSubmatch(t)
if regexp.MustCompile(`^\/\/sys `).FindStringSubmatch(t) == nil && nonblock == nil {
continue
}
// 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.
f := regexp.MustCompile(`^\/\/sys(nb)? (\w+)\(([^()]*)\)\s*(?:\(([^()]+)\))?\s*(?:=\s*(?:(\w*)\.)?(\w*))?$`).FindStringSubmatch(t)
if f == nil {
fmt.Fprintf(os.Stderr, "%s:%s\nmalformed //sys declaration\n", path, t)
os.Exit(1)
}
funct, inps, outps, modname, sysname := f[2], f[3], f[4], f[5], f[6]
// Split argument lists on comma.
in := parseParamList(inps)
out := parseParamList(outps)
inps = strings.Join(in, ", ")
outps = strings.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
errvar := ""
retvar := ""
rettype := ""
for _, param := range out {
p := parseParam(param)
if p.Type == "error" {
errvar = p.Name
} else {
retvar = p.Name
rettype = p.Type
}
}
// System call name.
if sysname == "" {
sysname = funct
}
sysname = regexp.MustCompile(`([a-z])([A-Z])`).ReplaceAllString(sysname, `${1}_$2`)
sysname = strings.ToLower(sysname) // All libc functions are lowercase.
cRettype := ""
if rettype == "unsafe.Pointer" {
cRettype = "uintptr_t"
} else if rettype == "uintptr" {
cRettype = "uintptr_t"
} else if regexp.MustCompile(`^_`).FindStringSubmatch(rettype) != nil {
cRettype = "uintptr_t"
} else if rettype == "int" {
cRettype = "int"
} else if rettype == "int32" {
cRettype = "int"
} else if rettype == "int64" {
cRettype = "long long"
} else if rettype == "uint32" {
cRettype = "unsigned int"
} else if rettype == "uint64" {
cRettype = "unsigned long long"
} else {
cRettype = "int"
}
if sysname == "exit" {
cRettype = "void"
}
// Change p.Types to c
var cIn []string
for _, param := range in {
p := parseParam(param)
if regexp.MustCompile(`^\*`).FindStringSubmatch(p.Type) != nil {
cIn = append(cIn, "uintptr_t")
} else if p.Type == "string" {
cIn = append(cIn, "uintptr_t")
} else if regexp.MustCompile(`^\[\](.*)`).FindStringSubmatch(p.Type) != nil {
cIn = append(cIn, "uintptr_t", "size_t")
} else if p.Type == "unsafe.Pointer" {
cIn = append(cIn, "uintptr_t")
} else if p.Type == "uintptr" {
cIn = append(cIn, "uintptr_t")
} else if regexp.MustCompile(`^_`).FindStringSubmatch(p.Type) != nil {
cIn = append(cIn, "uintptr_t")
} else if p.Type == "int" {
cIn = append(cIn, "int")
} else if p.Type == "int32" {
cIn = append(cIn, "int")
} else if p.Type == "int64" {
cIn = append(cIn, "long long")
} else if p.Type == "uint32" {
cIn = append(cIn, "unsigned int")
} else if p.Type == "uint64" {
cIn = append(cIn, "unsigned long long")
} else {
cIn = append(cIn, "int")
}
}
if funct != "fcntl" && funct != "FcntlInt" && funct != "readlen" && funct != "writelen" {
if sysname == "select" {
// select is a keyword of Go. Its name is
// changed to c_select.
cExtern += "#define c_select select\n"
}
// Imports of system calls from libc
cExtern += fmt.Sprintf("%s %s", cRettype, sysname)
cIn := strings.Join(cIn, ", ")
cExtern += fmt.Sprintf("(%s);\n", cIn)
}
// So file name.
if *aix {
if modname == "" {
modname = "libc.a/shr_64.o"
} else {
fmt.Fprintf(os.Stderr, "%s: only syscall using libc are available\n", funct)
os.Exit(1)
}
}
strconvfunc := "C.CString"
// Go function header.
if outps != "" {
outps = fmt.Sprintf(" (%s)", outps)
}
if text != "" {
text += "\n"
}
text += fmt.Sprintf("func %s(%s)%s {\n", funct, strings.Join(in, ", "), outps)
// Prepare arguments to Syscall.
var args []string
n := 0
argN := 0
for _, param := range in {
p := parseParam(param)
if regexp.MustCompile(`^\*`).FindStringSubmatch(p.Type) != nil {
args = append(args, "C.uintptr_t(uintptr(unsafe.Pointer("+p.Name+")))")
} else if p.Type == "string" && errvar != "" {
text += fmt.Sprintf("\t_p%d := uintptr(unsafe.Pointer(%s(%s)))\n", n, strconvfunc, p.Name)
args = append(args, fmt.Sprintf("C.uintptr_t(_p%d)", n))
n++
} else if p.Type == "string" {
fmt.Fprintf(os.Stderr, path+":"+funct+" uses string arguments, but has no error return\n")
text += fmt.Sprintf("\t_p%d := uintptr(unsafe.Pointer(%s(%s)))\n", n, strconvfunc, p.Name)
args = append(args, fmt.Sprintf("C.uintptr_t(_p%d)", n))
n++
} else if m := regexp.MustCompile(`^\[\](.*)`).FindStringSubmatch(p.Type); m != nil {
// 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 += fmt.Sprintf("\tvar _p%d *%s\n", n, m[1])
text += fmt.Sprintf("\tif len(%s) > 0 {\n\t\t_p%d = &%s[0]\n\t}\n", p.Name, n, p.Name)
args = append(args, fmt.Sprintf("C.uintptr_t(uintptr(unsafe.Pointer(_p%d)))", n))
n++
text += fmt.Sprintf("\tvar _p%d int\n", n)
text += fmt.Sprintf("\t_p%d = len(%s)\n", n, p.Name)
args = append(args, fmt.Sprintf("C.size_t(_p%d)", n))
n++
} else if p.Type == "int64" && endianness != "" {
if endianness == "big-endian" {
args = append(args, fmt.Sprintf("uintptr(%s>>32)", p.Name), fmt.Sprintf("uintptr(%s)", p.Name))
} else {
args = append(args, fmt.Sprintf("uintptr(%s)", p.Name), fmt.Sprintf("uintptr(%s>>32)", p.Name))
}
n++
} else if p.Type == "bool" {
text += fmt.Sprintf("\tvar _p%d uint32\n", n)
text += fmt.Sprintf("\tif %s {\n\t\t_p%d = 1\n\t} else {\n\t\t_p%d = 0\n\t}\n", p.Name, n, n)
args = append(args, fmt.Sprintf("_p%d", n))
} else if regexp.MustCompile(`^_`).FindStringSubmatch(p.Type) != nil {
args = append(args, fmt.Sprintf("C.uintptr_t(uintptr(%s))", p.Name))
} else if p.Type == "unsafe.Pointer" {
args = append(args, fmt.Sprintf("C.uintptr_t(uintptr(%s))", p.Name))
} else if p.Type == "int" {
if (argN == 2) && ((funct == "readlen") || (funct == "writelen")) {
args = append(args, fmt.Sprintf("C.size_t(%s)", p.Name))
} else if argN == 0 && funct == "fcntl" {
args = append(args, fmt.Sprintf("C.uintptr_t(%s)", p.Name))
} else if (argN == 2) && ((funct == "fcntl") || (funct == "FcntlInt")) {
args = append(args, fmt.Sprintf("C.uintptr_t(%s)", p.Name))
} else {
args = append(args, fmt.Sprintf("C.int(%s)", p.Name))
}
} else if p.Type == "int32" {
args = append(args, fmt.Sprintf("C.int(%s)", p.Name))
} else if p.Type == "int64" {
args = append(args, fmt.Sprintf("C.longlong(%s)", p.Name))
} else if p.Type == "uint32" {
args = append(args, fmt.Sprintf("C.uint(%s)", p.Name))
} else if p.Type == "uint64" {
args = append(args, fmt.Sprintf("C.ulonglong(%s)", p.Name))
} else if p.Type == "uintptr" {
args = append(args, fmt.Sprintf("C.uintptr_t(%s)", p.Name))
} else {
args = append(args, fmt.Sprintf("C.int(%s)", p.Name))
}
argN++
}
// Actual call.
arglist := strings.Join(args, ", ")
call := ""
if sysname == "exit" {
if errvar != "" {
call += "er :="
} else {
call += ""
}
} else if errvar != "" {
call += "r0,er :="
} else if retvar != "" {
call += "r0,_ :="
} else {
call += ""
}
if sysname == "select" {
// select is a keyword of Go. Its name is
// changed to c_select.
call += fmt.Sprintf("C.c_%s(%s)", sysname, arglist)
} else {
call += fmt.Sprintf("C.%s(%s)", sysname, arglist)
}
// Assign return values.
body := ""
for i := 0; i < len(out); i++ {
p := parseParam(out[i])
reg := ""
if p.Name == "err" {
reg = "e1"
} else {
reg = "r0"
}
if reg != "e1" {
body += fmt.Sprintf("\t%s = %s(%s)\n", p.Name, p.Type, reg)
}
}
// verify return
if sysname != "exit" && errvar != "" {
if regexp.MustCompile(`^uintptr`).FindStringSubmatch(cRettype) != nil {
body += "\tif (uintptr(r0) ==^uintptr(0) && er != nil) {\n"
body += fmt.Sprintf("\t\t%s = er\n", errvar)
body += "\t}\n"
} else {
body += "\tif (r0 ==-1 && er != nil) {\n"
body += fmt.Sprintf("\t\t%s = er\n", errvar)
body += "\t}\n"
}
} else if errvar != "" {
body += "\tif (er != nil) {\n"
body += fmt.Sprintf("\t\t%s = er\n", errvar)
body += "\t}\n"
}
text += fmt.Sprintf("\t%s\n", call)
text += body
text += "\treturn\n"
text += "}\n"
}
if err := s.Err(); err != nil {
fmt.Fprintf(os.Stderr, err.Error())
os.Exit(1)
}
file.Close()
}
imp := ""
if pack != "unix" {
imp = "import \"golang.org/x/sys/unix\"\n"
}
fmt.Printf(srcTemplate, cmdLine(), buildTags(), pack, cExtern, imp, text)
}
const srcTemplate = `// %s
// Code generated by the command above; see README.md. DO NOT EDIT.
// +build %s
package %s
%s
*/
import "C"
import (
"unsafe"
)
%s
%s
`

View File

@@ -1,614 +0,0 @@
// 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 ignore
/*
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
}
*/
package main
import (
"bufio"
"flag"
"fmt"
"io/ioutil"
"os"
"regexp"
"strings"
)
var (
b32 = flag.Bool("b32", false, "32bit big-endian")
l32 = flag.Bool("l32", false, "32bit little-endian")
aix = flag.Bool("aix", false, "aix")
tags = flag.String("tags", "", "build tags")
)
// cmdLine returns this programs's commandline arguments
func cmdLine() string {
return "go run mksyscall_aix_ppc64.go " + strings.Join(os.Args[1:], " ")
}
// buildTags returns build tags
func buildTags() string {
return *tags
}
// Param is function parameter
type Param struct {
Name string
Type string
}
// usage prints the program usage
func usage() {
fmt.Fprintf(os.Stderr, "usage: go run mksyscall_aix_ppc64.go [-b32 | -l32] [-tags x,y] [file ...]\n")
os.Exit(1)
}
// parseParamList parses parameter list and returns a slice of parameters
func parseParamList(list string) []string {
list = strings.TrimSpace(list)
if list == "" {
return []string{}
}
return regexp.MustCompile(`\s*,\s*`).Split(list, -1)
}
// parseParam splits a parameter into name and type
func parseParam(p string) Param {
ps := regexp.MustCompile(`^(\S*) (\S*)$`).FindStringSubmatch(p)
if ps == nil {
fmt.Fprintf(os.Stderr, "malformed parameter: %s\n", p)
os.Exit(1)
}
return Param{ps[1], ps[2]}
}
func main() {
flag.Usage = usage
flag.Parse()
if len(flag.Args()) <= 0 {
fmt.Fprintf(os.Stderr, "no files to parse provided\n")
usage()
}
endianness := ""
if *b32 {
endianness = "big-endian"
} else if *l32 {
endianness = "little-endian"
}
pack := ""
// GCCGO
textgccgo := ""
cExtern := "/*\n#include <stdint.h>\n"
// GC
textgc := ""
dynimports := ""
linknames := ""
var vars []string
// COMMON
textcommon := ""
for _, path := range flag.Args() {
file, err := os.Open(path)
if err != nil {
fmt.Fprintf(os.Stderr, err.Error())
os.Exit(1)
}
s := bufio.NewScanner(file)
for s.Scan() {
t := s.Text()
t = strings.TrimSpace(t)
t = regexp.MustCompile(`\s+`).ReplaceAllString(t, ` `)
if p := regexp.MustCompile(`^package (\S+)$`).FindStringSubmatch(t); p != nil && pack == "" {
pack = p[1]
}
nonblock := regexp.MustCompile(`^\/\/sysnb `).FindStringSubmatch(t)
if regexp.MustCompile(`^\/\/sys `).FindStringSubmatch(t) == nil && nonblock == nil {
continue
}
// 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.
f := regexp.MustCompile(`^\/\/sys(nb)? (\w+)\(([^()]*)\)\s*(?:\(([^()]+)\))?\s*(?:=\s*(?:(\w*)\.)?(\w*))?$`).FindStringSubmatch(t)
if f == nil {
fmt.Fprintf(os.Stderr, "%s:%s\nmalformed //sys declaration\n", path, t)
os.Exit(1)
}
funct, inps, outps, modname, sysname := f[2], f[3], f[4], f[5], f[6]
// Split argument lists on comma.
in := parseParamList(inps)
out := parseParamList(outps)
inps = strings.Join(in, ", ")
outps = strings.Join(out, ", ")
if sysname == "" {
sysname = funct
}
onlyCommon := false
if funct == "readlen" || funct == "writelen" || funct == "FcntlInt" || funct == "FcntlFlock" {
// This function call another syscall which is already implemented.
// Therefore, the gc and gccgo part must not be generated.
onlyCommon = true
}
// 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
errvar := ""
rettype := ""
for _, param := range out {
p := parseParam(param)
if p.Type == "error" {
errvar = p.Name
} else {
rettype = p.Type
}
}
sysname = regexp.MustCompile(`([a-z])([A-Z])`).ReplaceAllString(sysname, `${1}_$2`)
sysname = strings.ToLower(sysname) // All libc functions are lowercase.
// GCCGO Prototype return type
cRettype := ""
if rettype == "unsafe.Pointer" {
cRettype = "uintptr_t"
} else if rettype == "uintptr" {
cRettype = "uintptr_t"
} else if regexp.MustCompile(`^_`).FindStringSubmatch(rettype) != nil {
cRettype = "uintptr_t"
} else if rettype == "int" {
cRettype = "int"
} else if rettype == "int32" {
cRettype = "int"
} else if rettype == "int64" {
cRettype = "long long"
} else if rettype == "uint32" {
cRettype = "unsigned int"
} else if rettype == "uint64" {
cRettype = "unsigned long long"
} else {
cRettype = "int"
}
if sysname == "exit" {
cRettype = "void"
}
// GCCGO Prototype arguments type
var cIn []string
for i, param := range in {
p := parseParam(param)
if regexp.MustCompile(`^\*`).FindStringSubmatch(p.Type) != nil {
cIn = append(cIn, "uintptr_t")
} else if p.Type == "string" {
cIn = append(cIn, "uintptr_t")
} else if regexp.MustCompile(`^\[\](.*)`).FindStringSubmatch(p.Type) != nil {
cIn = append(cIn, "uintptr_t", "size_t")
} else if p.Type == "unsafe.Pointer" {
cIn = append(cIn, "uintptr_t")
} else if p.Type == "uintptr" {
cIn = append(cIn, "uintptr_t")
} else if regexp.MustCompile(`^_`).FindStringSubmatch(p.Type) != nil {
cIn = append(cIn, "uintptr_t")
} else if p.Type == "int" {
if (i == 0 || i == 2) && funct == "fcntl" {
// These fcntl arguments needs to be uintptr to be able to call FcntlInt and FcntlFlock
cIn = append(cIn, "uintptr_t")
} else {
cIn = append(cIn, "int")
}
} else if p.Type == "int32" {
cIn = append(cIn, "int")
} else if p.Type == "int64" {
cIn = append(cIn, "long long")
} else if p.Type == "uint32" {
cIn = append(cIn, "unsigned int")
} else if p.Type == "uint64" {
cIn = append(cIn, "unsigned long long")
} else {
cIn = append(cIn, "int")
}
}
if !onlyCommon {
// GCCGO Prototype Generation
// Imports of system calls from libc
if sysname == "select" {
// select is a keyword of Go. Its name is
// changed to c_select.
cExtern += "#define c_select select\n"
}
cExtern += fmt.Sprintf("%s %s", cRettype, sysname)
cIn := strings.Join(cIn, ", ")
cExtern += fmt.Sprintf("(%s);\n", cIn)
}
// GC Library name
if modname == "" {
modname = "libc.a/shr_64.o"
} else {
fmt.Fprintf(os.Stderr, "%s: only syscall using libc are available\n", funct)
os.Exit(1)
}
sysvarname := fmt.Sprintf("libc_%s", sysname)
if !onlyCommon {
// GC Runtime import of function to allow cross-platform builds.
dynimports += fmt.Sprintf("//go:cgo_import_dynamic %s %s \"%s\"\n", sysvarname, sysname, modname)
// GC Link symbol to proc address variable.
linknames += fmt.Sprintf("//go:linkname %s %s\n", sysvarname, sysvarname)
// GC Library proc address variable.
vars = append(vars, sysvarname)
}
strconvfunc := "BytePtrFromString"
strconvtype := "*byte"
// Go function header.
if outps != "" {
outps = fmt.Sprintf(" (%s)", outps)
}
if textcommon != "" {
textcommon += "\n"
}
textcommon += fmt.Sprintf("func %s(%s)%s {\n", funct, strings.Join(in, ", "), outps)
// Prepare arguments tocall.
var argscommon []string // Arguments in the common part
var argscall []string // Arguments for call prototype
var argsgc []string // Arguments for gc call (with syscall6)
var argsgccgo []string // Arguments for gccgo call (with C.name_of_syscall)
n := 0
argN := 0
for _, param := range in {
p := parseParam(param)
if regexp.MustCompile(`^\*`).FindStringSubmatch(p.Type) != nil {
argscommon = append(argscommon, fmt.Sprintf("uintptr(unsafe.Pointer(%s))", p.Name))
argscall = append(argscall, fmt.Sprintf("%s uintptr", p.Name))
argsgc = append(argsgc, p.Name)
argsgccgo = append(argsgccgo, fmt.Sprintf("C.uintptr_t(%s)", p.Name))
} else if p.Type == "string" && errvar != "" {
textcommon += fmt.Sprintf("\tvar _p%d %s\n", n, strconvtype)
textcommon += fmt.Sprintf("\t_p%d, %s = %s(%s)\n", n, errvar, strconvfunc, p.Name)
textcommon += fmt.Sprintf("\tif %s != nil {\n\t\treturn\n\t}\n", errvar)
argscommon = append(argscommon, fmt.Sprintf("uintptr(unsafe.Pointer(_p%d))", n))
argscall = append(argscall, fmt.Sprintf("_p%d uintptr ", n))
argsgc = append(argsgc, fmt.Sprintf("_p%d", n))
argsgccgo = append(argsgccgo, fmt.Sprintf("C.uintptr_t(_p%d)", n))
n++
} else if p.Type == "string" {
fmt.Fprintf(os.Stderr, path+":"+funct+" uses string arguments, but has no error return\n")
textcommon += fmt.Sprintf("\tvar _p%d %s\n", n, strconvtype)
textcommon += fmt.Sprintf("\t_p%d, %s = %s(%s)\n", n, errvar, strconvfunc, p.Name)
textcommon += fmt.Sprintf("\tif %s != nil {\n\t\treturn\n\t}\n", errvar)
argscommon = append(argscommon, fmt.Sprintf("uintptr(unsafe.Pointer(_p%d))", n))
argscall = append(argscall, fmt.Sprintf("_p%d uintptr", n))
argsgc = append(argsgc, fmt.Sprintf("_p%d", n))
argsgccgo = append(argsgccgo, fmt.Sprintf("C.uintptr_t(_p%d)", n))
n++
} else if m := regexp.MustCompile(`^\[\](.*)`).FindStringSubmatch(p.Type); m != nil {
// 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 += fmt.Sprintf("\tvar _p%d *%s\n", n, m[1])
textcommon += fmt.Sprintf("\tif len(%s) > 0 {\n\t\t_p%d = &%s[0]\n\t}\n", p.Name, n, p.Name)
argscommon = append(argscommon, fmt.Sprintf("uintptr(unsafe.Pointer(_p%d))", n), fmt.Sprintf("len(%s)", p.Name))
argscall = append(argscall, fmt.Sprintf("_p%d uintptr", n), fmt.Sprintf("_lenp%d int", n))
argsgc = append(argsgc, fmt.Sprintf("_p%d", n), fmt.Sprintf("uintptr(_lenp%d)", n))
argsgccgo = append(argsgccgo, fmt.Sprintf("C.uintptr_t(_p%d)", n), fmt.Sprintf("C.size_t(_lenp%d)", n))
n++
} else if p.Type == "int64" && endianness != "" {
fmt.Fprintf(os.Stderr, path+":"+funct+" uses int64 with 32 bits mode. Case not yet implemented\n")
} else if p.Type == "bool" {
fmt.Fprintf(os.Stderr, path+":"+funct+" uses bool. Case not yet implemented\n")
} else if regexp.MustCompile(`^_`).FindStringSubmatch(p.Type) != nil || p.Type == "unsafe.Pointer" {
argscommon = append(argscommon, fmt.Sprintf("uintptr(%s)", p.Name))
argscall = append(argscall, fmt.Sprintf("%s uintptr", p.Name))
argsgc = append(argsgc, p.Name)
argsgccgo = append(argsgccgo, fmt.Sprintf("C.uintptr_t(%s)", p.Name))
} else if p.Type == "int" {
if (argN == 0 || argN == 2) && ((funct == "fcntl") || (funct == "FcntlInt") || (funct == "FcntlFlock")) {
// These fcntl arguments need to be uintptr to be able to call FcntlInt and FcntlFlock
argscommon = append(argscommon, fmt.Sprintf("uintptr(%s)", p.Name))
argscall = append(argscall, fmt.Sprintf("%s uintptr", p.Name))
argsgc = append(argsgc, p.Name)
argsgccgo = append(argsgccgo, fmt.Sprintf("C.uintptr_t(%s)", p.Name))
} else {
argscommon = append(argscommon, p.Name)
argscall = append(argscall, fmt.Sprintf("%s int", p.Name))
argsgc = append(argsgc, fmt.Sprintf("uintptr(%s)", p.Name))
argsgccgo = append(argsgccgo, fmt.Sprintf("C.int(%s)", p.Name))
}
} else if p.Type == "int32" {
argscommon = append(argscommon, p.Name)
argscall = append(argscall, fmt.Sprintf("%s int32", p.Name))
argsgc = append(argsgc, fmt.Sprintf("uintptr(%s)", p.Name))
argsgccgo = append(argsgccgo, fmt.Sprintf("C.int(%s)", p.Name))
} else if p.Type == "int64" {
argscommon = append(argscommon, p.Name)
argscall = append(argscall, fmt.Sprintf("%s int64", p.Name))
argsgc = append(argsgc, fmt.Sprintf("uintptr(%s)", p.Name))
argsgccgo = append(argsgccgo, fmt.Sprintf("C.longlong(%s)", p.Name))
} else if p.Type == "uint32" {
argscommon = append(argscommon, p.Name)
argscall = append(argscall, fmt.Sprintf("%s uint32", p.Name))
argsgc = append(argsgc, fmt.Sprintf("uintptr(%s)", p.Name))
argsgccgo = append(argsgccgo, fmt.Sprintf("C.uint(%s)", p.Name))
} else if p.Type == "uint64" {
argscommon = append(argscommon, p.Name)
argscall = append(argscall, fmt.Sprintf("%s uint64", p.Name))
argsgc = append(argsgc, fmt.Sprintf("uintptr(%s)", p.Name))
argsgccgo = append(argsgccgo, fmt.Sprintf("C.ulonglong(%s)", p.Name))
} else if p.Type == "uintptr" {
argscommon = append(argscommon, p.Name)
argscall = append(argscall, fmt.Sprintf("%s uintptr", p.Name))
argsgc = append(argsgc, p.Name)
argsgccgo = append(argsgccgo, fmt.Sprintf("C.uintptr_t(%s)", p.Name))
} else {
argscommon = append(argscommon, fmt.Sprintf("int(%s)", p.Name))
argscall = append(argscall, fmt.Sprintf("%s int", p.Name))
argsgc = append(argsgc, fmt.Sprintf("uintptr(%s)", p.Name))
argsgccgo = append(argsgccgo, fmt.Sprintf("C.int(%s)", p.Name))
}
argN++
}
nargs := len(argsgc)
// COMMON function generation
argscommonlist := strings.Join(argscommon, ", ")
callcommon := fmt.Sprintf("call%s(%s)", sysname, argscommonlist)
ret := []string{"_", "_"}
body := ""
doErrno := false
for i := 0; i < len(out); i++ {
p := parseParam(out[i])
reg := ""
if p.Name == "err" {
reg = "e1"
ret[1] = reg
doErrno = true
} else {
reg = "r0"
ret[0] = reg
}
if p.Type == "bool" {
reg = fmt.Sprintf("%s != 0", reg)
}
if reg != "e1" {
body += fmt.Sprintf("\t%s = %s(%s)\n", p.Name, p.Type, reg)
}
}
if ret[0] == "_" && ret[1] == "_" {
textcommon += fmt.Sprintf("\t%s\n", callcommon)
} else {
textcommon += fmt.Sprintf("\t%s, %s := %s\n", ret[0], ret[1], callcommon)
}
textcommon += body
if doErrno {
textcommon += "\tif e1 != 0 {\n"
textcommon += "\t\terr = errnoErr(e1)\n"
textcommon += "\t}\n"
}
textcommon += "\treturn\n"
textcommon += "}\n"
if onlyCommon {
continue
}
// CALL Prototype
callProto := fmt.Sprintf("func call%s(%s) (r1 uintptr, e1 Errno) {\n", sysname, strings.Join(argscall, ", "))
// GC function generation
asm := "syscall6"
if nonblock != nil {
asm = "rawSyscall6"
}
if len(argsgc) <= 6 {
for len(argsgc) < 6 {
argsgc = append(argsgc, "0")
}
} else {
fmt.Fprintf(os.Stderr, "%s: too many arguments to system call", funct)
os.Exit(1)
}
argsgclist := strings.Join(argsgc, ", ")
callgc := fmt.Sprintf("%s(uintptr(unsafe.Pointer(&%s)), %d, %s)", asm, sysvarname, nargs, argsgclist)
textgc += callProto
textgc += fmt.Sprintf("\tr1, _, e1 = %s\n", callgc)
textgc += "\treturn\n}\n"
// GCCGO function generation
argsgccgolist := strings.Join(argsgccgo, ", ")
var callgccgo string
if sysname == "select" {
// select is a keyword of Go. Its name is
// changed to c_select.
callgccgo = fmt.Sprintf("C.c_%s(%s)", sysname, argsgccgolist)
} else {
callgccgo = fmt.Sprintf("C.%s(%s)", sysname, argsgccgolist)
}
textgccgo += callProto
textgccgo += fmt.Sprintf("\tr1 = uintptr(%s)\n", callgccgo)
textgccgo += "\te1 = syscall.GetErrno()\n"
textgccgo += "\treturn\n}\n"
}
if err := s.Err(); err != nil {
fmt.Fprintf(os.Stderr, err.Error())
os.Exit(1)
}
file.Close()
}
imp := ""
if pack != "unix" {
imp = "import \"golang.org/x/sys/unix\"\n"
}
// Print zsyscall_aix_ppc64.go
err := ioutil.WriteFile("zsyscall_aix_ppc64.go",
[]byte(fmt.Sprintf(srcTemplate1, cmdLine(), buildTags(), pack, imp, textcommon)),
0644)
if err != nil {
fmt.Fprintf(os.Stderr, err.Error())
os.Exit(1)
}
// Print zsyscall_aix_ppc64_gc.go
vardecls := "\t" + strings.Join(vars, ",\n\t")
vardecls += " syscallFunc"
err = ioutil.WriteFile("zsyscall_aix_ppc64_gc.go",
[]byte(fmt.Sprintf(srcTemplate2, cmdLine(), buildTags(), pack, imp, dynimports, linknames, vardecls, textgc)),
0644)
if err != nil {
fmt.Fprintf(os.Stderr, err.Error())
os.Exit(1)
}
// Print zsyscall_aix_ppc64_gccgo.go
err = ioutil.WriteFile("zsyscall_aix_ppc64_gccgo.go",
[]byte(fmt.Sprintf(srcTemplate3, cmdLine(), buildTags(), pack, cExtern, imp, textgccgo)),
0644)
if err != nil {
fmt.Fprintf(os.Stderr, err.Error())
os.Exit(1)
}
}
const srcTemplate1 = `// %s
// Code generated by the command above; see README.md. DO NOT EDIT.
// +build %s
package %s
import (
"unsafe"
)
%s
%s
`
const srcTemplate2 = `// %s
// Code generated by the command above; see README.md. DO NOT EDIT.
// +build %s
// +build !gccgo
package %s
import (
"unsafe"
)
%s
%s
%s
type syscallFunc uintptr
var (
%s
)
// 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)
%s
`
const srcTemplate3 = `// %s
// Code generated by the command above; see README.md. DO NOT EDIT.
// +build %s
// +build gccgo
package %s
%s
*/
import "C"
import (
"syscall"
)
%s
%s
`

View File

@@ -1,335 +0,0 @@
// 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 ignore
/*
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
*/
package main
import (
"bufio"
"flag"
"fmt"
"os"
"regexp"
"strings"
)
var (
b32 = flag.Bool("b32", false, "32bit big-endian")
l32 = flag.Bool("l32", false, "32bit little-endian")
tags = flag.String("tags", "", "build tags")
)
// cmdLine returns this programs's commandline arguments
func cmdLine() string {
return "go run mksyscall_solaris.go " + strings.Join(os.Args[1:], " ")
}
// buildTags returns build tags
func buildTags() string {
return *tags
}
// Param is function parameter
type Param struct {
Name string
Type string
}
// usage prints the program usage
func usage() {
fmt.Fprintf(os.Stderr, "usage: go run mksyscall_solaris.go [-b32 | -l32] [-tags x,y] [file ...]\n")
os.Exit(1)
}
// parseParamList parses parameter list and returns a slice of parameters
func parseParamList(list string) []string {
list = strings.TrimSpace(list)
if list == "" {
return []string{}
}
return regexp.MustCompile(`\s*,\s*`).Split(list, -1)
}
// parseParam splits a parameter into name and type
func parseParam(p string) Param {
ps := regexp.MustCompile(`^(\S*) (\S*)$`).FindStringSubmatch(p)
if ps == nil {
fmt.Fprintf(os.Stderr, "malformed parameter: %s\n", p)
os.Exit(1)
}
return Param{ps[1], ps[2]}
}
func main() {
flag.Usage = usage
flag.Parse()
if len(flag.Args()) <= 0 {
fmt.Fprintf(os.Stderr, "no files to parse provided\n")
usage()
}
endianness := ""
if *b32 {
endianness = "big-endian"
} else if *l32 {
endianness = "little-endian"
}
pack := ""
text := ""
dynimports := ""
linknames := ""
var vars []string
for _, path := range flag.Args() {
file, err := os.Open(path)
if err != nil {
fmt.Fprintf(os.Stderr, err.Error())
os.Exit(1)
}
s := bufio.NewScanner(file)
for s.Scan() {
t := s.Text()
t = strings.TrimSpace(t)
t = regexp.MustCompile(`\s+`).ReplaceAllString(t, ` `)
if p := regexp.MustCompile(`^package (\S+)$`).FindStringSubmatch(t); p != nil && pack == "" {
pack = p[1]
}
nonblock := regexp.MustCompile(`^\/\/sysnb `).FindStringSubmatch(t)
if regexp.MustCompile(`^\/\/sys `).FindStringSubmatch(t) == nil && nonblock == nil {
continue
}
// 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.
f := regexp.MustCompile(`^\/\/sys(nb)? (\w+)\(([^()]*)\)\s*(?:\(([^()]+)\))?\s*(?:=\s*(?:(\w*)\.)?(\w*))?$`).FindStringSubmatch(t)
if f == nil {
fmt.Fprintf(os.Stderr, "%s:%s\nmalformed //sys declaration\n", path, t)
os.Exit(1)
}
funct, inps, outps, modname, sysname := f[2], f[3], f[4], f[5], f[6]
// Split argument lists on comma.
in := parseParamList(inps)
out := parseParamList(outps)
inps = strings.Join(in, ", ")
outps = strings.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"
// So file name.
if modname == "" {
modname = "libc"
}
// System call name.
if sysname == "" {
sysname = funct
}
// System call pointer variable name.
sysvarname := fmt.Sprintf("proc%s", sysname)
strconvfunc := "BytePtrFromString"
strconvtype := "*byte"
sysname = strings.ToLower(sysname) // All libc functions are lowercase.
// Runtime import of function to allow cross-platform builds.
dynimports += fmt.Sprintf("//go:cgo_import_dynamic libc_%s %s \"%s.so\"\n", sysname, sysname, modname)
// Link symbol to proc address variable.
linknames += fmt.Sprintf("//go:linkname %s libc_%s\n", sysvarname, sysname)
// Library proc address variable.
vars = append(vars, sysvarname)
// Go function header.
outlist := strings.Join(out, ", ")
if outlist != "" {
outlist = fmt.Sprintf(" (%s)", outlist)
}
if text != "" {
text += "\n"
}
text += fmt.Sprintf("func %s(%s)%s {\n", funct, strings.Join(in, ", "), outlist)
// Check if err return available
errvar := ""
for _, param := range out {
p := parseParam(param)
if p.Type == "error" {
errvar = p.Name
continue
}
}
// Prepare arguments to Syscall.
var args []string
n := 0
for _, param := range in {
p := parseParam(param)
if regexp.MustCompile(`^\*`).FindStringSubmatch(p.Type) != nil {
args = append(args, "uintptr(unsafe.Pointer("+p.Name+"))")
} else if p.Type == "string" && errvar != "" {
text += fmt.Sprintf("\tvar _p%d %s\n", n, strconvtype)
text += fmt.Sprintf("\t_p%d, %s = %s(%s)\n", n, errvar, strconvfunc, p.Name)
text += fmt.Sprintf("\tif %s != nil {\n\t\treturn\n\t}\n", errvar)
args = append(args, fmt.Sprintf("uintptr(unsafe.Pointer(_p%d))", n))
n++
} else if p.Type == "string" {
fmt.Fprintf(os.Stderr, path+":"+funct+" uses string arguments, but has no error return\n")
text += fmt.Sprintf("\tvar _p%d %s\n", n, strconvtype)
text += fmt.Sprintf("\t_p%d, _ = %s(%s)\n", n, strconvfunc, p.Name)
args = append(args, fmt.Sprintf("uintptr(unsafe.Pointer(_p%d))", n))
n++
} else if s := regexp.MustCompile(`^\[\](.*)`).FindStringSubmatch(p.Type); s != nil {
// 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 += fmt.Sprintf("\tvar _p%d *%s\n", n, s[1])
text += fmt.Sprintf("\tif len(%s) > 0 {\n\t\t_p%d = &%s[0]\n\t}\n", p.Name, n, p.Name)
args = append(args, fmt.Sprintf("uintptr(unsafe.Pointer(_p%d))", n), fmt.Sprintf("uintptr(len(%s))", p.Name))
n++
} else if p.Type == "int64" && endianness != "" {
if endianness == "big-endian" {
args = append(args, fmt.Sprintf("uintptr(%s>>32)", p.Name), fmt.Sprintf("uintptr(%s)", p.Name))
} else {
args = append(args, fmt.Sprintf("uintptr(%s)", p.Name), fmt.Sprintf("uintptr(%s>>32)", p.Name))
}
} else if p.Type == "bool" {
text += fmt.Sprintf("\tvar _p%d uint32\n", n)
text += fmt.Sprintf("\tif %s {\n\t\t_p%d = 1\n\t} else {\n\t\t_p%d = 0\n\t}\n", p.Name, n, n)
args = append(args, fmt.Sprintf("uintptr(_p%d)", n))
n++
} else {
args = append(args, fmt.Sprintf("uintptr(%s)", p.Name))
}
}
nargs := len(args)
// Determine which form to use; pad args with zeros.
asm := "sysvicall6"
if nonblock != nil {
asm = "rawSysvicall6"
}
if len(args) <= 6 {
for len(args) < 6 {
args = append(args, "0")
}
} else {
fmt.Fprintf(os.Stderr, "%s: too many arguments to system call\n", path)
os.Exit(1)
}
// Actual call.
arglist := strings.Join(args, ", ")
call := fmt.Sprintf("%s(uintptr(unsafe.Pointer(&%s)), %d, %s)", asm, sysvarname, nargs, arglist)
// Assign return values.
body := ""
ret := []string{"_", "_", "_"}
doErrno := false
for i := 0; i < len(out); i++ {
p := parseParam(out[i])
reg := ""
if p.Name == "err" {
reg = "e1"
ret[2] = reg
doErrno = true
} else {
reg = fmt.Sprintf("r%d", i)
ret[i] = reg
}
if p.Type == "bool" {
reg = fmt.Sprintf("%d != 0", reg)
}
if p.Type == "int64" && endianness != "" {
// 64-bit number in r1:r0 or r0:r1.
if i+2 > len(out) {
fmt.Fprintf(os.Stderr, "%s: not enough registers for int64 return\n", path)
os.Exit(1)
}
if endianness == "big-endian" {
reg = fmt.Sprintf("int64(r%d)<<32 | int64(r%d)", i, i+1)
} else {
reg = fmt.Sprintf("int64(r%d)<<32 | int64(r%d)", i+1, i)
}
ret[i] = fmt.Sprintf("r%d", i)
ret[i+1] = fmt.Sprintf("r%d", i+1)
}
if reg != "e1" {
body += fmt.Sprintf("\t%s = %s(%s)\n", p.Name, p.Type, reg)
}
}
if ret[0] == "_" && ret[1] == "_" && ret[2] == "_" {
text += fmt.Sprintf("\t%s\n", call)
} else {
text += fmt.Sprintf("\t%s, %s, %s := %s\n", ret[0], ret[1], ret[2], call)
}
text += body
if doErrno {
text += "\tif e1 != 0 {\n"
text += "\t\terr = e1\n"
text += "\t}\n"
}
text += "\treturn\n"
text += "}\n"
}
if err := s.Err(); err != nil {
fmt.Fprintf(os.Stderr, err.Error())
os.Exit(1)
}
file.Close()
}
imp := ""
if pack != "unix" {
imp = "import \"golang.org/x/sys/unix\"\n"
}
vardecls := "\t" + strings.Join(vars, ",\n\t")
vardecls += " syscallFunc"
fmt.Printf(srcTemplate, cmdLine(), buildTags(), pack, imp, dynimports, linknames, vardecls, text)
}
const srcTemplate = `// %s
// Code generated by the command above; see README.md. DO NOT EDIT.
// +build %s
package %s
import (
"syscall"
"unsafe"
)
%s
%s
%s
var (
%s
)
%s
`

View File

@@ -1,355 +0,0 @@
// 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 ignore
// 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.
package main
import (
"bufio"
"fmt"
"os"
"path/filepath"
"regexp"
"sort"
"strings"
)
var (
goos, goarch string
)
// cmdLine returns this programs's commandline arguments.
func cmdLine() string {
return "go run mksysctl_openbsd.go " + strings.Join(os.Args[1:], " ")
}
// buildTags returns build tags.
func buildTags() string {
return fmt.Sprintf("%s,%s", goarch, goos)
}
// reMatch performs regular expression match and stores the substring slice to value pointed by m.
func reMatch(re *regexp.Regexp, str string, m *[]string) bool {
*m = re.FindStringSubmatch(str)
if *m != nil {
return true
}
return false
}
type nodeElement struct {
n int
t string
pE *map[string]nodeElement
}
var (
debugEnabled bool
mib map[string]nodeElement
node *map[string]nodeElement
nodeMap map[string]string
sysCtl []string
)
var (
ctlNames1RE = regexp.MustCompile(`^#define\s+(CTL_NAMES)\s+{`)
ctlNames2RE = regexp.MustCompile(`^#define\s+(CTL_(.*)_NAMES)\s+{`)
ctlNames3RE = regexp.MustCompile(`^#define\s+((.*)CTL_NAMES)\s+{`)
netInetRE = regexp.MustCompile(`^netinet/`)
netInet6RE = regexp.MustCompile(`^netinet6/`)
netRE = regexp.MustCompile(`^net/`)
bracesRE = regexp.MustCompile(`{.*}`)
ctlTypeRE = regexp.MustCompile(`{\s+"(\w+)",\s+(CTLTYPE_[A-Z]+)\s+}`)
fsNetKernRE = regexp.MustCompile(`^(fs|net|kern)_`)
)
func debug(s string) {
if debugEnabled {
fmt.Fprintln(os.Stderr, s)
}
}
// Walk the MIB and build a sysctl name to OID mapping.
func buildSysctl(pNode *map[string]nodeElement, name string, oid []int) {
lNode := pNode // local copy of pointer to node
var keys []string
for k := range *lNode {
keys = append(keys, k)
}
sort.Strings(keys)
for _, key := range keys {
nodename := name
if name != "" {
nodename += "."
}
nodename += key
nodeoid := append(oid, (*pNode)[key].n)
if (*pNode)[key].t == `CTLTYPE_NODE` {
if _, ok := nodeMap[nodename]; ok {
lNode = &mib
ctlName := nodeMap[nodename]
for _, part := range strings.Split(ctlName, ".") {
lNode = ((*lNode)[part]).pE
}
} else {
lNode = (*pNode)[key].pE
}
buildSysctl(lNode, nodename, nodeoid)
} else if (*pNode)[key].t != "" {
oidStr := []string{}
for j := range nodeoid {
oidStr = append(oidStr, fmt.Sprintf("%d", nodeoid[j]))
}
text := "\t{ \"" + nodename + "\", []_C_int{ " + strings.Join(oidStr, ", ") + " } }, \n"
sysCtl = append(sysCtl, text)
}
}
}
func main() {
// Get the OS (using GOOS_TARGET if it exist)
goos = os.Getenv("GOOS_TARGET")
if goos == "" {
goos = os.Getenv("GOOS")
}
// Get the architecture (using GOARCH_TARGET if it exists)
goarch = os.Getenv("GOARCH_TARGET")
if goarch == "" {
goarch = os.Getenv("GOARCH")
}
// Check if GOOS and GOARCH environment variables are defined
if goarch == "" || goos == "" {
fmt.Fprintf(os.Stderr, "GOARCH or GOOS not defined in environment\n")
os.Exit(1)
}
mib = make(map[string]nodeElement)
headers := [...]string{
`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`,
}
ctls := [...]string{
`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"
ctlMap := map[string]string{
"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
nodeMap = map[string]string{
"net.inet.ip.ifq": "net.ifq",
"net.inet.pfsync": "net.pfsync",
"net.mpls.ifq": "net.ifq",
}
mCtls := make(map[string]bool)
for _, ctl := range ctls {
mCtls[ctl] = true
}
for _, header := range headers {
debug("Processing " + header)
file, err := os.Open(filepath.Join("/usr/include", header))
if err != nil {
fmt.Fprintf(os.Stderr, "%v\n", err)
os.Exit(1)
}
s := bufio.NewScanner(file)
for s.Scan() {
var sub []string
if reMatch(ctlNames1RE, s.Text(), &sub) ||
reMatch(ctlNames2RE, s.Text(), &sub) ||
reMatch(ctlNames3RE, s.Text(), &sub) {
if sub[1] == `CTL_NAMES` {
// Top level.
node = &mib
} else {
// Node.
nodename := strings.ToLower(sub[2])
ctlName := ""
if reMatch(netInetRE, header, &sub) {
ctlName = "net.inet." + nodename
} else if reMatch(netInet6RE, header, &sub) {
ctlName = "net.inet6." + nodename
} else if reMatch(netRE, header, &sub) {
ctlName = "net." + nodename
} else {
ctlName = nodename
ctlName = fsNetKernRE.ReplaceAllString(ctlName, `$1.`)
}
if val, ok := ctlMap[ctlName]; ok {
ctlName = val
}
if _, ok := mCtls[ctlName]; !ok {
debug("Ignoring " + ctlName + "...")
continue
}
// Walk down from the top of the MIB.
node = &mib
for _, part := range strings.Split(ctlName, ".") {
if _, ok := (*node)[part]; !ok {
debug("Missing node " + part)
(*node)[part] = nodeElement{n: 0, t: "", pE: &map[string]nodeElement{}}
}
node = (*node)[part].pE
}
}
// Populate current node with entries.
i := -1
for !strings.HasPrefix(s.Text(), "}") {
s.Scan()
if reMatch(bracesRE, s.Text(), &sub) {
i++
}
if !reMatch(ctlTypeRE, s.Text(), &sub) {
continue
}
(*node)[sub[1]] = nodeElement{n: i, t: sub[2], pE: &map[string]nodeElement{}}
}
}
}
err = s.Err()
if err != nil {
fmt.Fprintf(os.Stderr, "%v\n", err)
os.Exit(1)
}
file.Close()
}
buildSysctl(&mib, "", []int{})
sort.Strings(sysCtl)
text := strings.Join(sysCtl, "")
fmt.Printf(srcTemplate, cmdLine(), buildTags(), text)
}
const srcTemplate = `// %s
// Code generated by the command above; DO NOT EDIT.
// +build %s
package unix
type mibentry struct {
ctlname string
ctloid []_C_int
}
var sysctlMib = []mibentry {
%s
}
`

View File

@@ -1,190 +0,0 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build ignore
// Generate system call table for DragonFly, NetBSD,
// FreeBSD, OpenBSD or Darwin from master list
// (for example, /usr/src/sys/kern/syscalls.master or
// sys/syscall.h).
package main
import (
"bufio"
"fmt"
"io"
"io/ioutil"
"net/http"
"os"
"regexp"
"strings"
)
var (
goos, goarch string
)
// cmdLine returns this programs's commandline arguments
func cmdLine() string {
return "go run mksysnum.go " + strings.Join(os.Args[1:], " ")
}
// buildTags returns build tags
func buildTags() string {
return fmt.Sprintf("%s,%s", goarch, goos)
}
func checkErr(err error) {
if err != nil {
fmt.Fprintf(os.Stderr, "%v\n", err)
os.Exit(1)
}
}
// source string and substring slice for regexp
type re struct {
str string // source string
sub []string // matched sub-string
}
// Match performs regular expression match
func (r *re) Match(exp string) bool {
r.sub = regexp.MustCompile(exp).FindStringSubmatch(r.str)
if r.sub != nil {
return true
}
return false
}
// fetchFile fetches a text file from URL
func fetchFile(URL string) io.Reader {
resp, err := http.Get(URL)
checkErr(err)
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
checkErr(err)
return strings.NewReader(string(body))
}
// readFile reads a text file from path
func readFile(path string) io.Reader {
file, err := os.Open(os.Args[1])
checkErr(err)
return file
}
func format(name, num, proto string) string {
name = strings.ToUpper(name)
// There are multiple entries for enosys and nosys, so comment them out.
nm := re{str: name}
if nm.Match(`^SYS_E?NOSYS$`) {
name = fmt.Sprintf("// %s", name)
}
if name == `SYS_SYS_EXIT` {
name = `SYS_EXIT`
}
return fmt.Sprintf(" %s = %s; // %s\n", name, num, proto)
}
func main() {
// Get the OS (using GOOS_TARGET if it exist)
goos = os.Getenv("GOOS_TARGET")
if goos == "" {
goos = os.Getenv("GOOS")
}
// Get the architecture (using GOARCH_TARGET if it exists)
goarch = os.Getenv("GOARCH_TARGET")
if goarch == "" {
goarch = os.Getenv("GOARCH")
}
// Check if GOOS and GOARCH environment variables are defined
if goarch == "" || goos == "" {
fmt.Fprintf(os.Stderr, "GOARCH or GOOS not defined in environment\n")
os.Exit(1)
}
file := strings.TrimSpace(os.Args[1])
var syscalls io.Reader
if strings.HasPrefix(file, "https://") || strings.HasPrefix(file, "http://") {
// Download syscalls.master file
syscalls = fetchFile(file)
} else {
syscalls = readFile(file)
}
var text, line string
s := bufio.NewScanner(syscalls)
for s.Scan() {
t := re{str: line}
if t.Match(`^(.*)\\$`) {
// Handle continuation
line = t.sub[1]
line += strings.TrimLeft(s.Text(), " \t")
} else {
// New line
line = s.Text()
}
t = re{str: line}
if t.Match(`\\$`) {
continue
}
t = re{str: line}
switch goos {
case "dragonfly":
if t.Match(`^([0-9]+)\s+STD\s+({ \S+\s+(\w+).*)$`) {
num, proto := t.sub[1], t.sub[2]
name := fmt.Sprintf("SYS_%s", t.sub[3])
text += format(name, num, proto)
}
case "freebsd":
if t.Match(`^([0-9]+)\s+\S+\s+(?:(?:NO)?STD|COMPAT10)\s+({ \S+\s+(\w+).*)$`) {
num, proto := t.sub[1], t.sub[2]
name := fmt.Sprintf("SYS_%s", t.sub[3])
text += format(name, num, proto)
}
case "openbsd":
if t.Match(`^([0-9]+)\s+STD\s+(NOLOCK\s+)?({ \S+\s+\*?(\w+).*)$`) {
num, proto, name := t.sub[1], t.sub[3], t.sub[4]
text += format(name, num, proto)
}
case "netbsd":
if t.Match(`^([0-9]+)\s+((STD)|(NOERR))\s+(RUMP\s+)?({\s+\S+\s*\*?\s*\|(\S+)\|(\S*)\|(\w+).*\s+})(\s+(\S+))?$`) {
num, proto, compat := t.sub[1], t.sub[6], t.sub[8]
name := t.sub[7] + "_" + t.sub[9]
if t.sub[11] != "" {
name = t.sub[7] + "_" + t.sub[11]
}
name = strings.ToUpper(name)
if compat == "" || compat == "13" || compat == "30" || compat == "50" {
text += fmt.Sprintf(" %s = %s; // %s\n", name, num, proto)
}
}
case "darwin":
if t.Match(`^#define\s+SYS_(\w+)\s+([0-9]+)`) {
name, num := t.sub[1], t.sub[2]
name = strings.ToUpper(name)
text += fmt.Sprintf(" SYS_%s = %s;\n", name, num)
}
default:
fmt.Fprintf(os.Stderr, "unrecognized GOOS=%s\n", goos)
os.Exit(1)
}
}
err := s.Err()
checkErr(err)
fmt.Printf(template, cmdLine(), buildTags(), text)
}
const template = `// %s
// Code generated by the command above; see README.md. DO NOT EDIT.
// +build %s
package unix
const(
%s)`

16
vendor/golang.org/x/sys/unix/sockcmsg_dragonfly.go generated vendored Normal file
View File

@@ -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)
}

View File

@@ -17,7 +17,7 @@ func UnixCredentials(ucred *Ucred) []byte {
h.Level = SOL_SOCKET h.Level = SOL_SOCKET
h.Type = SCM_CREDENTIALS h.Type = SCM_CREDENTIALS
h.SetLen(CmsgLen(SizeofUcred)) h.SetLen(CmsgLen(SizeofUcred))
*((*Ucred)(cmsgData(h))) = *ucred *(*Ucred)(h.data(0)) = *ucred
return b return b
} }

View File

@@ -9,35 +9,9 @@
package unix package unix
import ( import (
"runtime"
"unsafe" "unsafe"
) )
// Round the length of a raw sockaddr up to align it properly.
func cmsgAlignOf(salen int) int {
salign := SizeofPtr
switch runtime.GOOS {
case "aix":
// There is no alignment on AIX.
salign = 1
case "darwin", "dragonfly", "solaris", "illumos":
// NOTE: It seems like 64-bit Darwin, DragonFly BSD,
// 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
}
}
return (salen + salign - 1) & ^(salign - 1)
}
// CmsgLen returns the value to store in the Len field of the Cmsghdr // CmsgLen returns the value to store in the Len field of the Cmsghdr
// structure, taking into account any necessary alignment. // structure, taking into account any necessary alignment.
func CmsgLen(datalen int) int { func CmsgLen(datalen int) int {
@@ -50,8 +24,8 @@ func CmsgSpace(datalen int) int {
return cmsgAlignOf(SizeofCmsghdr) + cmsgAlignOf(datalen) return cmsgAlignOf(SizeofCmsghdr) + cmsgAlignOf(datalen)
} }
func cmsgData(h *Cmsghdr) unsafe.Pointer { func (h *Cmsghdr) data(offset uintptr) unsafe.Pointer {
return unsafe.Pointer(uintptr(unsafe.Pointer(h)) + uintptr(cmsgAlignOf(SizeofCmsghdr))) return unsafe.Pointer(uintptr(unsafe.Pointer(h)) + uintptr(cmsgAlignOf(SizeofCmsghdr)) + offset)
} }
// SocketControlMessage represents a socket control message. // SocketControlMessage represents a socket control message.
@@ -94,10 +68,8 @@ func UnixRights(fds ...int) []byte {
h.Level = SOL_SOCKET h.Level = SOL_SOCKET
h.Type = SCM_RIGHTS h.Type = SCM_RIGHTS
h.SetLen(CmsgLen(datalen)) h.SetLen(CmsgLen(datalen))
data := cmsgData(h) for i, fd := range fds {
for _, fd := range fds { *(*int32)(h.data(4 * uintptr(i))) = int32(fd)
*(*int32)(data) = int32(fd)
data = unsafe.Pointer(uintptr(data) + 4)
} }
return b return b
} }

38
vendor/golang.org/x/sys/unix/sockcmsg_unix_other.go generated vendored Normal file
View File

@@ -0,0 +1,38 @@
// 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 aix darwin freebsd linux netbsd openbsd solaris
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", "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
}
}
return (salen + salign - 1) & ^(salign - 1)
}

View File

@@ -280,6 +280,22 @@ func sendfile(outfd int, infd int, offset *int64, count int) (written int, err e
return -1, ENOSYS 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) //sys getdirent(fd int, buf []byte) (n int, err error)
func Getdents(fd int, buf []byte) (n int, err error) { func Getdents(fd int, buf []byte) (n int, err error) {
return getdirent(fd, buf) return getdirent(fd, buf)
@@ -334,49 +350,12 @@ func (w WaitStatus) Signal() Signal {
func (w WaitStatus) Continued() bool { return w&0x01000000 != 0 } 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 } func (w WaitStatus) TrapCause() int { return -1 }
//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
}
// fcntl must never be called with cmd=F_DUP2FD because it doesn't work on AIX // 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, // 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. // Therefore, the programmer must call dup2 instead of fcntl in this case.

View File

@@ -29,6 +29,10 @@ func (msghdr *Msghdr) SetControllen(length int) {
msghdr.Controllen = uint32(length) msghdr.Controllen = uint32(length)
} }
func (msghdr *Msghdr) SetIovlen(length int) {
msghdr.Iovlen = int32(length)
}
func (cmsg *Cmsghdr) SetLen(length int) { func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint32(length) cmsg.Len = uint32(length)
} }

View File

@@ -29,6 +29,10 @@ func (msghdr *Msghdr) SetControllen(length int) {
msghdr.Controllen = uint32(length) msghdr.Controllen = uint32(length)
} }
func (msghdr *Msghdr) SetIovlen(length int) {
msghdr.Iovlen = int32(length)
}
func (cmsg *Cmsghdr) SetLen(length int) { func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint32(length) cmsg.Len = uint32(length)
} }

View File

@@ -237,7 +237,7 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
break 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) sa.Name = string(bytes)
return sa, nil return sa, nil
@@ -413,8 +413,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) 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. // sysctlmib translates name to mib number and appends any additional args.
func sysctlmib(name string, args ...int) ([]_C_int, error) { func sysctlmib(name string, args ...int) ([]_C_int, error) {
// Translate name to mib number. // Translate name to mib number.
@@ -512,6 +510,40 @@ func SysctlRaw(name string, args ...int) ([]byte, error) {
return buf[:n], nil 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) //sys utimes(path string, timeval *[2]Timeval) (err error)
func Utimes(path string, tv []Timeval) error { func Utimes(path string, tv []Timeval) error {
@@ -579,8 +611,6 @@ func Futimes(fd int, tv []Timeval) error {
return futimes(fd, (*[2]Timeval)(unsafe.Pointer(&tv[0]))) 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) { func Poll(fds []PollFd, timeout int) (n int, err error) {

29
vendor/golang.org/x/sys/unix/syscall_darwin.1_12.go generated vendored Normal file
View File

@@ -0,0 +1,29 @@
// 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 darwin,go1.12,!go1.13
package unix
import (
"unsafe"
)
func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
// To implement this using libSystem we'd need syscall_syscallPtr for
// fdopendir. However, syscallPtr was only added in Go 1.13, so we fall
// back to raw syscalls for this func on Go 1.12.
var p unsafe.Pointer
if len(buf) > 0 {
p = unsafe.Pointer(&buf[0])
} else {
p = unsafe.Pointer(&_zero)
}
r0, _, e1 := Syscall6(SYS_GETDIRENTRIES64, uintptr(fd), uintptr(p), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0)
n = int(r0)
if e1 != 0 {
return n, errnoErr(e1)
}
return n, nil
}

108
vendor/golang.org/x/sys/unix/syscall_darwin.1_13.go generated vendored Normal file
View File

@@ -0,0 +1,108 @@
// 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 darwin,go1.13
package unix
import (
"unsafe"
"golang.org/x/sys/internal/unsafeheader"
)
//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(funcPC(libc_fdopendir_trampoline), uintptr(fd), 0, 0)
dir = uintptr(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
func libc_fdopendir_trampoline()
//go:linkname libc_fdopendir libc_fdopendir
//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.
var s []byte
hdr := (*unsafeheader.Slice)(unsafe.Pointer(&s))
hdr.Data = unsafe.Pointer(&entry)
hdr.Cap = reclen
hdr.Len = 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
}
return n, nil
}

View File

@@ -77,7 +77,18 @@ func nametomib(name string) (mib []_C_int, err error) {
return buf[0 : n/siz], nil return buf[0 : n/siz], nil
} }
//sys ptrace(request int, pid int, addr uintptr, data uintptr) (err error) func direntIno(buf []byte) (uint64, bool) {
return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino))
}
func direntReclen(buf []byte) (uint64, bool) {
return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
}
func direntNamlen(buf []byte) (uint64, bool) {
return readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen))
}
func PtraceAttach(pid int) (err error) { return ptrace(PT_ATTACH, pid, 0, 0) } 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) } func PtraceDetach(pid int) (err error) { return ptrace(PT_DETACH, pid, 0, 0) }
@@ -144,23 +155,6 @@ func getAttrList(path string, attrList attrList, attrBuf []byte, options uint) (
//sys getattrlist(path *byte, list unsafe.Pointer, buf unsafe.Pointer, size uintptr, options int) (err error) //sys getattrlist(path *byte, list unsafe.Pointer, buf unsafe.Pointer, size uintptr, options int) (err error)
func SysctlClockinfo(name string) (*Clockinfo, error) {
mib, err := sysctlmib(name)
if err != nil {
return nil, err
}
n := uintptr(SizeofClockinfo)
var ci Clockinfo
if err := sysctl(mib, (*byte)(unsafe.Pointer(&ci)), &n, nil, 0); err != nil {
return nil, err
}
if n != SizeofClockinfo {
return nil, EIO
}
return &ci, nil
}
//sysnb pipe() (r int, w int, err error) //sysnb pipe() (r int, w int, err error)
func Pipe(p []int) (err error) { func Pipe(p []int) (err error) {
@@ -322,48 +316,15 @@ func utimensat(dirfd int, path string, times *[2]Timespec, flags int) error {
* Wrapped * Wrapped
*/ */
//sys fcntl(fd int, cmd int, arg int) (val int, err error)
//sys kill(pid int, signum int, posix 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) } 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) //sys ioctl(fd int, req uint, arg uintptr) (err error)
// ioctl itself should not be exposed directly, but additional get/set //sys sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) = SYS_SYSCTL
// 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
}
func Uname(uname *Utsname) error { func Uname(uname *Utsname) error {
mib := []_C_int{CTL_KERN, KERN_OSTYPE} mib := []_C_int{CTL_KERN, KERN_OSTYPE}
@@ -462,6 +423,7 @@ func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err e
//sysnb Getrlimit(which int, lim *Rlimit) (err error) //sysnb Getrlimit(which int, lim *Rlimit) (err error)
//sysnb Getrusage(who int, rusage *Rusage) (err error) //sysnb Getrusage(who int, rusage *Rusage) (err error)
//sysnb Getsid(pid int) (sid int, err error) //sysnb Getsid(pid int) (sid int, err error)
//sysnb Gettimeofday(tp *Timeval) (err error)
//sysnb Getuid() (uid int) //sysnb Getuid() (uid int)
//sysnb Issetugid() (tainted bool) //sysnb Issetugid() (tainted bool)
//sys Kqueue() (fd int, err error) //sys Kqueue() (fd int, err error)
@@ -486,7 +448,7 @@ func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err e
//sys Revoke(path string) (err error) //sys Revoke(path string) (err error)
//sys Rmdir(path string) (err error) //sys Rmdir(path string) (err error)
//sys Seek(fd int, offset int64, whence int) (newoffset int64, err error) = SYS_LSEEK //sys Seek(fd int, offset int64, whence int) (newoffset int64, err error) = SYS_LSEEK
//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) //sys Setegid(egid int) (err error)
//sysnb Seteuid(euid int) (err error) //sysnb Seteuid(euid int) (err error)
//sysnb Setgid(gid int) (err error) //sysnb Setgid(gid int) (err error)

View File

@@ -0,0 +1,9 @@
// 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 darwin,386,!go1.12
package unix
//sys Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) = SYS_GETDIRENTRIES64

View File

@@ -10,6 +10,8 @@ import (
"syscall" "syscall"
) )
//sys ptrace(request int, pid int, addr uintptr, data uintptr) (err error)
func setTimespec(sec, nsec int64) Timespec { func setTimespec(sec, nsec int64) Timespec {
return Timespec{Sec: int32(sec), Nsec: int32(nsec)} return Timespec{Sec: int32(sec), Nsec: int32(nsec)}
} }
@@ -18,17 +20,6 @@ func setTimeval(sec, usec int64) Timeval {
return Timeval{Sec: int32(sec), Usec: int32(usec)} 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) { func SetKevent(k *Kevent_t, fd, mode, flags int) {
k.Ident = uint32(fd) k.Ident = uint32(fd)
k.Filter = int16(mode) k.Filter = int16(mode)
@@ -43,6 +34,10 @@ func (msghdr *Msghdr) SetControllen(length int) {
msghdr.Controllen = uint32(length) msghdr.Controllen = uint32(length)
} }
func (msghdr *Msghdr) SetIovlen(length int) {
msghdr.Iovlen = int32(length)
}
func (cmsg *Cmsghdr) SetLen(length int) { func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint32(length) cmsg.Len = uint32(length)
} }
@@ -56,7 +51,6 @@ const SYS___SYSCTL = SYS_SYSCTL
//sys Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64 //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 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 Fstatfs(fd int, stat *Statfs_t) (err error) = SYS_FSTATFS64
//sys Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) = SYS_GETDIRENTRIES64
//sys getfsstat(buf unsafe.Pointer, size uintptr, flags int) (n int, err error) = SYS_GETFSSTAT64 //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 Lstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64
//sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64 //sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64

View File

@@ -0,0 +1,9 @@
// 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 darwin,amd64,!go1.12
package unix
//sys Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) = SYS_GETDIRENTRIES64

View File

@@ -10,6 +10,8 @@ import (
"syscall" "syscall"
) )
//sys ptrace(request int, pid int, addr uintptr, data uintptr) (err error)
func setTimespec(sec, nsec int64) Timespec { func setTimespec(sec, nsec int64) Timespec {
return Timespec{Sec: sec, Nsec: nsec} return Timespec{Sec: sec, Nsec: nsec}
} }
@@ -18,17 +20,6 @@ func setTimeval(sec, usec int64) Timeval {
return Timeval{Sec: sec, Usec: int32(usec)} 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) { func SetKevent(k *Kevent_t, fd, mode, flags int) {
k.Ident = uint64(fd) k.Ident = uint64(fd)
k.Filter = int16(mode) k.Filter = int16(mode)
@@ -43,6 +34,10 @@ func (msghdr *Msghdr) SetControllen(length int) {
msghdr.Controllen = uint32(length) msghdr.Controllen = uint32(length)
} }
func (msghdr *Msghdr) SetIovlen(length int) {
msghdr.Iovlen = int32(length)
}
func (cmsg *Cmsghdr) SetLen(length int) { func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint32(length) cmsg.Len = uint32(length)
} }
@@ -56,7 +51,6 @@ const SYS___SYSCTL = SYS_SYSCTL
//sys Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64 //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 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 Fstatfs(fd int, stat *Statfs_t) (err error) = SYS_FSTATFS64
//sys Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) = SYS_GETDIRENTRIES64
//sys getfsstat(buf unsafe.Pointer, size uintptr, flags int) (n int, err error) = SYS_GETFSSTAT64 //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 Lstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64
//sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64 //sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64

View File

@@ -0,0 +1,11 @@
// 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 darwin,arm,!go1.12
package unix
func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
return 0, ENOSYS
}

View File

@@ -8,6 +8,10 @@ import (
"syscall" "syscall"
) )
func ptrace(request int, pid int, addr uintptr, data uintptr) error {
return ENOTSUP
}
func setTimespec(sec, nsec int64) Timespec { func setTimespec(sec, nsec int64) Timespec {
return Timespec{Sec: int32(sec), Nsec: int32(nsec)} return Timespec{Sec: int32(sec), Nsec: int32(nsec)}
} }
@@ -16,17 +20,6 @@ func setTimeval(sec, usec int64) Timeval {
return Timeval{Sec: int32(sec), Usec: int32(usec)} 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) { func SetKevent(k *Kevent_t, fd, mode, flags int) {
k.Ident = uint32(fd) k.Ident = uint32(fd)
k.Filter = int16(mode) k.Filter = int16(mode)
@@ -41,6 +34,10 @@ func (msghdr *Msghdr) SetControllen(length int) {
msghdr.Controllen = uint32(length) msghdr.Controllen = uint32(length)
} }
func (msghdr *Msghdr) SetIovlen(length int) {
msghdr.Iovlen = int32(length)
}
func (cmsg *Cmsghdr) SetLen(length int) { func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint32(length) cmsg.Len = uint32(length)
} }
@@ -58,7 +55,3 @@ const SYS___SYSCTL = SYS_SYSCTL
//sys Lstat(path string, stat *Stat_t) (err error) //sys Lstat(path string, stat *Stat_t) (err error)
//sys Stat(path string, stat *Stat_t) (err error) //sys Stat(path string, stat *Stat_t) (err error)
//sys Statfs(path string, stat *Statfs_t) (err error) //sys Statfs(path string, stat *Statfs_t) (err error)
func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
return 0, ENOSYS
}

View File

@@ -0,0 +1,11 @@
// 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 darwin,arm64,!go1.12
package unix
func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
return 0, ENOSYS
}

View File

@@ -10,6 +10,10 @@ import (
"syscall" "syscall"
) )
func ptrace(request int, pid int, addr uintptr, data uintptr) error {
return ENOTSUP
}
func setTimespec(sec, nsec int64) Timespec { func setTimespec(sec, nsec int64) Timespec {
return Timespec{Sec: sec, Nsec: nsec} return Timespec{Sec: sec, Nsec: nsec}
} }
@@ -18,17 +22,6 @@ func setTimeval(sec, usec int64) Timeval {
return Timeval{Sec: sec, Usec: int32(usec)} 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) { func SetKevent(k *Kevent_t, fd, mode, flags int) {
k.Ident = uint64(fd) k.Ident = uint64(fd)
k.Filter = int16(mode) k.Filter = int16(mode)
@@ -43,6 +36,10 @@ func (msghdr *Msghdr) SetControllen(length int) {
msghdr.Controllen = uint32(length) msghdr.Controllen = uint32(length)
} }
func (msghdr *Msghdr) SetIovlen(length int) {
msghdr.Iovlen = int32(length)
}
func (cmsg *Cmsghdr) SetLen(length int) { func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint32(length) cmsg.Len = uint32(length)
} }
@@ -60,7 +57,3 @@ const SYS___SYSCTL = SYS_SYSCTL
//sys Lstat(path string, stat *Stat_t) (err error) //sys Lstat(path string, stat *Stat_t) (err error)
//sys Stat(path string, stat *Stat_t) (err error) //sys Stat(path string, stat *Stat_t) (err error)
//sys Statfs(path string, stat *Statfs_t) (err error) //sys Statfs(path string, stat *Statfs_t) (err error)
func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
return 0, ENOSYS
}

View File

@@ -15,6 +15,7 @@ func syscall_syscall6X(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err
func syscall_syscall9(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err Errno) // 32-bit only 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_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_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_syscall syscall.syscall
//go:linkname syscall_syscall6 syscall.syscall6 //go:linkname syscall_syscall6 syscall.syscall6
@@ -22,6 +23,7 @@ func syscall_rawSyscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, er
//go:linkname syscall_syscall9 syscall.syscall9 //go:linkname syscall_syscall9 syscall.syscall9
//go:linkname syscall_rawSyscall syscall.rawSyscall //go:linkname syscall_rawSyscall syscall.rawSyscall
//go:linkname syscall_rawSyscall6 syscall.rawSyscall6 //go:linkname syscall_rawSyscall6 syscall.rawSyscall6
//go:linkname syscall_syscallPtr syscall.syscallPtr
// Find the entry point for f. See comments in runtime/proc.go for the // Find the entry point for f. See comments in runtime/proc.go for the
// function of the same name. // function of the same name.

View File

@@ -12,7 +12,25 @@
package unix 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. // SockaddrDatalink implements the Sockaddr interface for AF_LINK type sockets.
type SockaddrDatalink struct { type SockaddrDatalink struct {
@@ -57,6 +75,22 @@ func nametomib(name string) (mib []_C_int, err error) {
return buf[0 : n/siz], nil 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) {
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) //sysnb pipe() (r int, w int, err error)
func Pipe(p []int) (err error) { func Pipe(p []int) (err error) {
@@ -134,42 +168,7 @@ func setattrlistTimes(path string, times []Timespec, flags int) error {
//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 //sys sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) = SYS___SYSCTL
// 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
}
func sysctlUname(mib []_C_int, old *byte, oldlen *uintptr) error { func sysctlUname(mib []_C_int, old *byte, oldlen *uintptr) error {
err := sysctl(mib, old, oldlen, nil, 0) err := sysctl(mib, old, oldlen, nil, 0)
@@ -309,7 +308,7 @@ func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err e
//sys Revoke(path string) (err error) //sys Revoke(path string) (err error)
//sys Rmdir(path string) (err error) //sys Rmdir(path string) (err error)
//sys Seek(fd int, offset int64, whence int) (newoffset int64, err error) = SYS_LSEEK //sys Seek(fd int, offset int64, whence int) (newoffset int64, err error) = SYS_LSEEK
//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 Setegid(egid int) (err error)
//sysnb Seteuid(euid int) (err error) //sysnb Seteuid(euid int) (err error)
//sysnb Setgid(gid int) (err error) //sysnb Setgid(gid int) (err error)

View File

@@ -33,6 +33,10 @@ func (msghdr *Msghdr) SetControllen(length int) {
msghdr.Controllen = uint32(length) msghdr.Controllen = uint32(length)
} }
func (msghdr *Msghdr) SetIovlen(length int) {
msghdr.Iovlen = int32(length)
}
func (cmsg *Cmsghdr) SetLen(length int) { func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint32(length) cmsg.Len = uint32(length)
} }

View File

@@ -82,6 +82,18 @@ func nametomib(name string) (mib []_C_int, err error) {
return buf[0 : n/siz], nil 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) { func Pipe(p []int) (err error) {
return Pipe2(p, 0) return Pipe2(p, 0)
} }
@@ -189,42 +201,7 @@ func setattrlistTimes(path string, times []Timespec, flags int) error {
//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 //sys sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) = SYS___SYSCTL
// 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
}
func Uname(uname *Utsname) error { func Uname(uname *Utsname) error {
mib := []_C_int{CTL_KERN, KERN_OSTYPE} mib := []_C_int{CTL_KERN, KERN_OSTYPE}
@@ -485,8 +462,12 @@ func convertFromDirents11(buf []byte, old []byte) int {
dstPos := 0 dstPos := 0
srcPos := 0 srcPos := 0
for dstPos+fixedSize < len(buf) && srcPos+oldFixedSize < len(old) { for dstPos+fixedSize < len(buf) && srcPos+oldFixedSize < len(old) {
dstDirent := (*Dirent)(unsafe.Pointer(&buf[dstPos])) var dstDirent Dirent
srcDirent := (*dirent_freebsd11)(unsafe.Pointer(&old[srcPos])) var srcDirent dirent_freebsd11
// If multiple direntries are written, sometimes when we reach the final one,
// we may have cap of old less than size of dirent_freebsd11.
copy((*[unsafe.Sizeof(srcDirent)]byte)(unsafe.Pointer(&srcDirent))[:], old[srcPos:])
reclen := roundup(fixedSize+int(srcDirent.Namlen)+1, 8) reclen := roundup(fixedSize+int(srcDirent.Namlen)+1, 8)
if dstPos+reclen > len(buf) { if dstPos+reclen > len(buf) {
@@ -502,6 +483,7 @@ func convertFromDirents11(buf []byte, old []byte) int {
dstDirent.Pad1 = 0 dstDirent.Pad1 = 0
copy(dstDirent.Name[:], srcDirent.Name[:srcDirent.Namlen]) copy(dstDirent.Name[:], srcDirent.Name[:srcDirent.Namlen])
copy(buf[dstPos:], (*[unsafe.Sizeof(dstDirent)]byte)(unsafe.Pointer(&dstDirent))[:])
padding := buf[dstPos+fixedSize+int(dstDirent.Namlen) : dstPos+reclen] padding := buf[dstPos+fixedSize+int(dstDirent.Namlen) : dstPos+reclen]
for i := range padding { for i := range padding {
padding[i] = 0 padding[i] = 0
@@ -539,20 +521,10 @@ func PtraceGetFpRegs(pid int, fpregsout *FpReg) (err error) {
return ptrace(PTRACE_GETFPREGS, pid, uintptr(unsafe.Pointer(fpregsout)), 0) return ptrace(PTRACE_GETFPREGS, pid, uintptr(unsafe.Pointer(fpregsout)), 0)
} }
func PtraceGetFsBase(pid int, fsbase *int64) (err error) {
return ptrace(PTRACE_GETFSBASE, pid, uintptr(unsafe.Pointer(fsbase)), 0)
}
func PtraceGetRegs(pid int, regsout *Reg) (err error) { func PtraceGetRegs(pid int, regsout *Reg) (err error) {
return ptrace(PTRACE_GETREGS, pid, uintptr(unsafe.Pointer(regsout)), 0) return ptrace(PTRACE_GETREGS, pid, uintptr(unsafe.Pointer(regsout)), 0)
} }
func PtraceIO(req int, pid int, addr uintptr, out []byte, countin int) (count int, err error) {
ioDesc := PtraceIoDesc{Op: int32(req), Offs: (*byte)(unsafe.Pointer(addr)), Addr: (*byte)(unsafe.Pointer(&out[0])), Len: uint(countin)}
err = ptrace(PTRACE_IO, pid, uintptr(unsafe.Pointer(&ioDesc)), 0)
return int(ioDesc.Len), err
}
func PtraceLwpEvents(pid int, enable int) (err error) { func PtraceLwpEvents(pid int, enable int) (err error) {
return ptrace(PTRACE_LWPEVENTS, pid, 0, enable) return ptrace(PTRACE_LWPEVENTS, pid, 0, enable)
} }
@@ -676,7 +648,7 @@ func PtraceSingleStep(pid int) (err error) {
//sys Revoke(path string) (err error) //sys Revoke(path string) (err error)
//sys Rmdir(path string) (err error) //sys Rmdir(path string) (err error)
//sys Seek(fd int, offset int64, whence int) (newoffset int64, err error) = SYS_LSEEK //sys Seek(fd int, offset int64, whence int) (newoffset int64, err error) = SYS_LSEEK
//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 Setegid(egid int) (err error)
//sysnb Seteuid(euid int) (err error) //sysnb Seteuid(euid int) (err error)
//sysnb Setgid(gid int) (err error) //sysnb Setgid(gid int) (err error)

View File

@@ -33,6 +33,10 @@ func (msghdr *Msghdr) SetControllen(length int) {
msghdr.Controllen = uint32(length) msghdr.Controllen = uint32(length)
} }
func (msghdr *Msghdr) SetIovlen(length int) {
msghdr.Iovlen = int32(length)
}
func (cmsg *Cmsghdr) SetLen(length int) { func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint32(length) cmsg.Len = uint32(length)
} }
@@ -50,3 +54,13 @@ func sendfile(outfd int, infd int, offset *int64, count int) (written int, err e
} }
func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno) func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)
func PtraceGetFsBase(pid int, fsbase *int64) (err error) {
return ptrace(PTRACE_GETFSBASE, pid, uintptr(unsafe.Pointer(fsbase)), 0)
}
func PtraceIO(req int, pid int, addr uintptr, out []byte, countin int) (count int, err error) {
ioDesc := PtraceIoDesc{Op: int32(req), Offs: (*byte)(unsafe.Pointer(addr)), Addr: (*byte)(unsafe.Pointer(&out[0])), Len: uint32(countin)}
err = ptrace(PTRACE_IO, pid, uintptr(unsafe.Pointer(&ioDesc)), 0)
return int(ioDesc.Len), err
}

View File

@@ -33,6 +33,10 @@ func (msghdr *Msghdr) SetControllen(length int) {
msghdr.Controllen = uint32(length) msghdr.Controllen = uint32(length)
} }
func (msghdr *Msghdr) SetIovlen(length int) {
msghdr.Iovlen = int32(length)
}
func (cmsg *Cmsghdr) SetLen(length int) { func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint32(length) cmsg.Len = uint32(length)
} }
@@ -50,3 +54,13 @@ func sendfile(outfd int, infd int, offset *int64, count int) (written int, err e
} }
func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno) func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)
func PtraceGetFsBase(pid int, fsbase *int64) (err error) {
return ptrace(PTRACE_GETFSBASE, pid, uintptr(unsafe.Pointer(fsbase)), 0)
}
func PtraceIO(req int, pid int, addr uintptr, out []byte, countin int) (count int, err error) {
ioDesc := PtraceIoDesc{Op: int32(req), Offs: (*byte)(unsafe.Pointer(addr)), Addr: (*byte)(unsafe.Pointer(&out[0])), Len: uint64(countin)}
err = ptrace(PTRACE_IO, pid, uintptr(unsafe.Pointer(&ioDesc)), 0)
return int(ioDesc.Len), err
}

View File

@@ -33,6 +33,10 @@ func (msghdr *Msghdr) SetControllen(length int) {
msghdr.Controllen = uint32(length) msghdr.Controllen = uint32(length)
} }
func (msghdr *Msghdr) SetIovlen(length int) {
msghdr.Iovlen = int32(length)
}
func (cmsg *Cmsghdr) SetLen(length int) { func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint32(length) cmsg.Len = uint32(length)
} }
@@ -50,3 +54,9 @@ func sendfile(outfd int, infd int, offset *int64, count int) (written int, err e
} }
func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno) func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)
func PtraceIO(req int, pid int, addr uintptr, out []byte, countin int) (count int, err error) {
ioDesc := PtraceIoDesc{Op: int32(req), Offs: (*byte)(unsafe.Pointer(addr)), Addr: (*byte)(unsafe.Pointer(&out[0])), Len: uint32(countin)}
err = ptrace(PTRACE_IO, pid, uintptr(unsafe.Pointer(&ioDesc)), 0)
return int(ioDesc.Len), err
}

View File

@@ -33,6 +33,10 @@ func (msghdr *Msghdr) SetControllen(length int) {
msghdr.Controllen = uint32(length) msghdr.Controllen = uint32(length)
} }
func (msghdr *Msghdr) SetIovlen(length int) {
msghdr.Iovlen = int32(length)
}
func (cmsg *Cmsghdr) SetLen(length int) { func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint32(length) cmsg.Len = uint32(length)
} }
@@ -50,3 +54,9 @@ func sendfile(outfd int, infd int, offset *int64, count int) (written int, err e
} }
func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno) func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)
func PtraceIO(req int, pid int, addr uintptr, out []byte, countin int) (count int, err error) {
ioDesc := PtraceIoDesc{Op: int32(req), Offs: (*byte)(unsafe.Pointer(addr)), Addr: (*byte)(unsafe.Pointer(&out[0])), Len: uint64(countin)}
err = ptrace(PTRACE_IO, pid, uintptr(unsafe.Pointer(&ioDesc)), 0)
return int(ioDesc.Len), err
}

57
vendor/golang.org/x/sys/unix/syscall_illumos.go generated vendored Normal file
View File

@@ -0,0 +1,57 @@
// 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.
// illumos system calls not present on Solaris.
// +build amd64,illumos
package unix
import "unsafe"
func bytes2iovec(bs [][]byte) []Iovec {
iovecs := make([]Iovec, len(bs))
for i, b := range bs {
iovecs[i].SetLen(len(b))
if len(b) > 0 {
// somehow Iovec.Base on illumos is (*int8), not (*byte)
iovecs[i].Base = (*int8)(unsafe.Pointer(&b[0]))
} else {
iovecs[i].Base = (*int8)(unsafe.Pointer(&_zero))
}
}
return iovecs
}
//sys readv(fd int, iovs []Iovec) (n int, err error)
func Readv(fd int, iovs [][]byte) (n int, err error) {
iovecs := bytes2iovec(iovs)
n, err = readv(fd, iovecs)
return n, err
}
//sys preadv(fd int, iovs []Iovec, off int64) (n int, err error)
func Preadv(fd int, iovs [][]byte, off int64) (n int, err error) {
iovecs := bytes2iovec(iovs)
n, err = preadv(fd, iovecs, off)
return n, err
}
//sys writev(fd int, iovs []Iovec) (n int, err error)
func Writev(fd int, iovs [][]byte) (n int, err error) {
iovecs := bytes2iovec(iovs)
n, err = writev(fd, iovecs)
return n, err
}
//sys pwritev(fd int, iovs []Iovec, off int64) (n int, err error)
func Pwritev(fd int, iovs [][]byte, off int64) (n int, err error) {
iovecs := bytes2iovec(iovs)
n, err = pwritev(fd, iovecs, off)
return n, err
}

View File

@@ -71,6 +71,17 @@ func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) {
// ioctl itself should not be exposed directly, but additional get/set // ioctl itself should not be exposed directly, but additional get/set
// functions for specific types are permissible. // functions for specific types are permissible.
// 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
}
// IoctlSetPointerInt performs an ioctl operation which sets an // IoctlSetPointerInt performs an ioctl operation which sets an
// integer value on fd, using the specified request number. The ioctl // integer value on fd, using the specified request number. The ioctl
// argument is called with a pointer to the integer value, rather than // argument is called with a pointer to the integer value, rather than
@@ -80,32 +91,16 @@ func IoctlSetPointerInt(fd int, req uint, value int) error {
return ioctl(fd, req, uintptr(unsafe.Pointer(&v))) return ioctl(fd, req, uintptr(unsafe.Pointer(&v)))
} }
// 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)))
}
func IoctlSetRTCTime(fd int, value *RTCTime) error { func IoctlSetRTCTime(fd int, value *RTCTime) error {
err := ioctl(fd, RTC_SET_TIME, uintptr(unsafe.Pointer(value))) err := ioctl(fd, RTC_SET_TIME, uintptr(unsafe.Pointer(value)))
runtime.KeepAlive(value) runtime.KeepAlive(value)
return err return err
} }
// IoctlGetInt performs an ioctl operation which gets an integer value func IoctlSetRTCWkAlrm(fd int, value *RTCWkAlrm) error {
// from fd, using the specified request number. err := ioctl(fd, RTC_WKALM_SET, uintptr(unsafe.Pointer(value)))
func IoctlGetInt(fd int, req uint) (int, error) { runtime.KeepAlive(value)
var value int return err
err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
return value, err
} }
func IoctlGetUint32(fd int, req uint) (uint32, error) { func IoctlGetUint32(fd int, req uint) (uint32, error) {
@@ -114,24 +109,18 @@ func IoctlGetUint32(fd int, req uint) (uint32, error) {
return value, err 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
}
func IoctlGetRTCTime(fd int) (*RTCTime, error) { func IoctlGetRTCTime(fd int) (*RTCTime, error) {
var value RTCTime var value RTCTime
err := ioctl(fd, RTC_RD_TIME, uintptr(unsafe.Pointer(&value))) err := ioctl(fd, RTC_RD_TIME, uintptr(unsafe.Pointer(&value)))
return &value, err return &value, err
} }
func IoctlGetRTCWkAlrm(fd int) (*RTCWkAlrm, error) {
var value RTCWkAlrm
err := ioctl(fd, RTC_WKALM_RD, uintptr(unsafe.Pointer(&value)))
return &value, err
}
//sys Linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error) //sys Linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error)
func Link(oldpath string, newpath string) (err error) { func Link(oldpath string, newpath string) (err error) {
@@ -798,6 +787,104 @@ func (sa *SockaddrPPPoE) sockaddr() (unsafe.Pointer, _Socklen, error) {
return unsafe.Pointer(&sa.raw), SizeofSockaddrPPPoX, nil return unsafe.Pointer(&sa.raw), SizeofSockaddrPPPoX, nil
} }
// SockaddrTIPC implements the Sockaddr interface for AF_TIPC type sockets.
// For more information on TIPC, see: http://tipc.sourceforge.net/.
type SockaddrTIPC struct {
// Scope is the publication scopes when binding service/service range.
// Should be set to TIPC_CLUSTER_SCOPE or TIPC_NODE_SCOPE.
Scope int
// Addr is the type of address used to manipulate a socket. Addr must be
// one of:
// - *TIPCSocketAddr: "id" variant in the C addr union
// - *TIPCServiceRange: "nameseq" variant in the C addr union
// - *TIPCServiceName: "name" variant in the C addr union
//
// If nil, EINVAL will be returned when the structure is used.
Addr TIPCAddr
raw RawSockaddrTIPC
}
// TIPCAddr is implemented by types that can be used as an address for
// SockaddrTIPC. It is only implemented by *TIPCSocketAddr, *TIPCServiceRange,
// and *TIPCServiceName.
type TIPCAddr interface {
tipcAddrtype() uint8
tipcAddr() [12]byte
}
func (sa *TIPCSocketAddr) tipcAddr() [12]byte {
var out [12]byte
copy(out[:], (*(*[unsafe.Sizeof(TIPCSocketAddr{})]byte)(unsafe.Pointer(sa)))[:])
return out
}
func (sa *TIPCSocketAddr) tipcAddrtype() uint8 { return TIPC_SOCKET_ADDR }
func (sa *TIPCServiceRange) tipcAddr() [12]byte {
var out [12]byte
copy(out[:], (*(*[unsafe.Sizeof(TIPCServiceRange{})]byte)(unsafe.Pointer(sa)))[:])
return out
}
func (sa *TIPCServiceRange) tipcAddrtype() uint8 { return TIPC_SERVICE_RANGE }
func (sa *TIPCServiceName) tipcAddr() [12]byte {
var out [12]byte
copy(out[:], (*(*[unsafe.Sizeof(TIPCServiceName{})]byte)(unsafe.Pointer(sa)))[:])
return out
}
func (sa *TIPCServiceName) tipcAddrtype() uint8 { return TIPC_SERVICE_ADDR }
func (sa *SockaddrTIPC) sockaddr() (unsafe.Pointer, _Socklen, error) {
if sa.Addr == nil {
return nil, 0, EINVAL
}
sa.raw.Family = AF_TIPC
sa.raw.Scope = int8(sa.Scope)
sa.raw.Addrtype = sa.Addr.tipcAddrtype()
sa.raw.Addr = sa.Addr.tipcAddr()
return unsafe.Pointer(&sa.raw), SizeofSockaddrTIPC, nil
}
// SockaddrL2TPIP implements the Sockaddr interface for IPPROTO_L2TP/AF_INET sockets.
type SockaddrL2TPIP struct {
Addr [4]byte
ConnId uint32
raw RawSockaddrL2TPIP
}
func (sa *SockaddrL2TPIP) sockaddr() (unsafe.Pointer, _Socklen, error) {
sa.raw.Family = AF_INET
sa.raw.Conn_id = sa.ConnId
for i := 0; i < len(sa.Addr); i++ {
sa.raw.Addr[i] = sa.Addr[i]
}
return unsafe.Pointer(&sa.raw), SizeofSockaddrL2TPIP, nil
}
// SockaddrL2TPIP6 implements the Sockaddr interface for IPPROTO_L2TP/AF_INET6 sockets.
type SockaddrL2TPIP6 struct {
Addr [16]byte
ZoneId uint32
ConnId uint32
raw RawSockaddrL2TPIP6
}
func (sa *SockaddrL2TPIP6) sockaddr() (unsafe.Pointer, _Socklen, error) {
sa.raw.Family = AF_INET6
sa.raw.Conn_id = sa.ConnId
sa.raw.Scope_id = sa.ZoneId
for i := 0; i < len(sa.Addr); i++ {
sa.raw.Addr[i] = sa.Addr[i]
}
return unsafe.Pointer(&sa.raw), SizeofSockaddrL2TPIP6, nil
}
func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) { func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
switch rsa.Addr.Family { switch rsa.Addr.Family {
case AF_NETLINK: case AF_NETLINK:
@@ -843,30 +930,63 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
for n < len(pp.Path) && pp.Path[n] != 0 { for n < len(pp.Path) && pp.Path[n] != 0 {
n++ n++
} }
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) sa.Name = string(bytes)
return sa, nil return sa, nil
case AF_INET: case AF_INET:
pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa)) proto, err := GetsockoptInt(fd, SOL_SOCKET, SO_PROTOCOL)
sa := new(SockaddrInet4) if err != nil {
p := (*[2]byte)(unsafe.Pointer(&pp.Port)) return nil, err
sa.Port = int(p[0])<<8 + int(p[1]) }
for i := 0; i < len(sa.Addr); i++ {
sa.Addr[i] = pp.Addr[i] switch proto {
case IPPROTO_L2TP:
pp := (*RawSockaddrL2TPIP)(unsafe.Pointer(rsa))
sa := new(SockaddrL2TPIP)
sa.ConnId = pp.Conn_id
for i := 0; i < len(sa.Addr); i++ {
sa.Addr[i] = pp.Addr[i]
}
return sa, nil
default:
pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
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]
}
return sa, nil
} }
return sa, nil
case AF_INET6: case AF_INET6:
pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa)) proto, err := GetsockoptInt(fd, SOL_SOCKET, SO_PROTOCOL)
sa := new(SockaddrInet6) if err != nil {
p := (*[2]byte)(unsafe.Pointer(&pp.Port)) return nil, err
sa.Port = int(p[0])<<8 + int(p[1]) }
sa.ZoneId = pp.Scope_id
for i := 0; i < len(sa.Addr); i++ { switch proto {
sa.Addr[i] = pp.Addr[i] case IPPROTO_L2TP:
pp := (*RawSockaddrL2TPIP6)(unsafe.Pointer(rsa))
sa := new(SockaddrL2TPIP6)
sa.ConnId = pp.Conn_id
sa.ZoneId = pp.Scope_id
for i := 0; i < len(sa.Addr); i++ {
sa.Addr[i] = pp.Addr[i]
}
return sa, nil
default:
pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))
sa := new(SockaddrInet6)
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]
}
return sa, nil
} }
return sa, nil
case AF_VSOCK: case AF_VSOCK:
pp := (*RawSockaddrVM)(unsafe.Pointer(rsa)) pp := (*RawSockaddrVM)(unsafe.Pointer(rsa))
@@ -923,6 +1043,27 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
break break
} }
} }
return sa, nil
case AF_TIPC:
pp := (*RawSockaddrTIPC)(unsafe.Pointer(rsa))
sa := &SockaddrTIPC{
Scope: int(pp.Scope),
}
// Determine which union variant is present in pp.Addr by checking
// pp.Addrtype.
switch pp.Addrtype {
case TIPC_SERVICE_RANGE:
sa.Addr = (*TIPCServiceRange)(unsafe.Pointer(&pp.Addr))
case TIPC_SERVICE_ADDR:
sa.Addr = (*TIPCServiceName)(unsafe.Pointer(&pp.Addr))
case TIPC_SOCKET_ADDR:
sa.Addr = (*TIPCSocketAddr)(unsafe.Pointer(&pp.Addr))
default:
return nil, EINVAL
}
return sa, nil return sa, nil
} }
return nil, EAFNOSUPPORT return nil, EAFNOSUPPORT
@@ -1160,6 +1301,34 @@ func KeyctlDHCompute(params *KeyctlDHParams, buffer []byte) (size int, err error
return keyctlDH(KEYCTL_DH_COMPUTE, params, buffer) return keyctlDH(KEYCTL_DH_COMPUTE, params, buffer)
} }
// KeyctlRestrictKeyring implements the KEYCTL_RESTRICT_KEYRING command. This
// command limits the set of keys that can be linked to the keyring, regardless
// of keyring permissions. The command requires the "setattr" permission.
//
// When called with an empty keyType the command locks the keyring, preventing
// any further keys from being linked to the keyring.
//
// The "asymmetric" keyType defines restrictions requiring key payloads to be
// DER encoded X.509 certificates signed by keys in another keyring. Restrictions
// for "asymmetric" include "builtin_trusted", "builtin_and_secondary_trusted",
// "key_or_keyring:<key>", and "key_or_keyring:<key>:chain".
//
// As of Linux 4.12, only the "asymmetric" keyType defines type-specific
// restrictions.
//
// See the full documentation at:
// http://man7.org/linux/man-pages/man3/keyctl_restrict_keyring.3.html
// http://man7.org/linux/man-pages/man2/keyctl.2.html
func KeyctlRestrictKeyring(ringid int, keyType string, restriction string) error {
if keyType == "" {
return keyctlRestrictKeyring(KEYCTL_RESTRICT_KEYRING, ringid)
}
return keyctlRestrictKeyringByType(KEYCTL_RESTRICT_KEYRING, ringid, keyType, restriction)
}
//sys keyctlRestrictKeyringByType(cmd int, arg2 int, keyType string, restriction string) (err error) = SYS_KEYCTL
//sys keyctlRestrictKeyring(cmd int, arg2 int) (err error) = SYS_KEYCTL
func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) { func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) {
var msg Msghdr var msg Msghdr
var rsa RawSockaddrAny var rsa RawSockaddrAny
@@ -1403,8 +1572,12 @@ func PtraceSyscall(pid int, signal int) (err error) {
func PtraceSingleStep(pid int) (err error) { return ptrace(PTRACE_SINGLESTEP, pid, 0, 0) } func PtraceSingleStep(pid int) (err error) { return ptrace(PTRACE_SINGLESTEP, pid, 0, 0) }
func PtraceInterrupt(pid int) (err error) { return ptrace(PTRACE_INTERRUPT, pid, 0, 0) }
func PtraceAttach(pid int) (err error) { return ptrace(PTRACE_ATTACH, pid, 0, 0) } func PtraceAttach(pid int) (err error) { return ptrace(PTRACE_ATTACH, pid, 0, 0) }
func PtraceSeize(pid int) (err error) { return ptrace(PTRACE_SEIZE, pid, 0, 0) }
func PtraceDetach(pid int) (err error) { return ptrace(PTRACE_DETACH, pid, 0, 0) } func PtraceDetach(pid int) (err error) { return ptrace(PTRACE_DETACH, pid, 0, 0) }
//sys reboot(magic1 uint, magic2 uint, cmd int, arg string) (err error) //sys reboot(magic1 uint, magic2 uint, cmd int, arg string) (err error)
@@ -1413,6 +1586,22 @@ func Reboot(cmd int) (err error) {
return reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd, "") return reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd, "")
} }
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 mount(source string, target string, fstype string, flags uintptr, data *byte) (err error) //sys mount(source string, target string, fstype string, flags uintptr, data *byte) (err error)
func Mount(source string, target string, fstype string, flags uintptr, data string) (err error) { func Mount(source string, target string, fstype string, flags uintptr, data string) (err error) {
@@ -1445,8 +1634,8 @@ func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err e
//sys Acct(path string) (err error) //sys Acct(path string) (err error)
//sys AddKey(keyType string, description string, payload []byte, ringid int) (id int, err error) //sys AddKey(keyType string, description string, payload []byte, ringid int) (id int, err error)
//sys Adjtimex(buf *Timex) (state int, err error) //sys Adjtimex(buf *Timex) (state int, err error)
//sys Capget(hdr *CapUserHeader, data *CapUserData) (err error) //sysnb Capget(hdr *CapUserHeader, data *CapUserData) (err error)
//sys Capset(hdr *CapUserHeader, data *CapUserData) (err error) //sysnb Capset(hdr *CapUserHeader, data *CapUserData) (err error)
//sys Chdir(path string) (err error) //sys Chdir(path string) (err error)
//sys Chroot(path string) (err error) //sys Chroot(path string) (err error)
//sys ClockGetres(clockid int32, res *Timespec) (err error) //sys ClockGetres(clockid int32, res *Timespec) (err error)
@@ -1456,6 +1645,15 @@ func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err e
//sys CopyFileRange(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error) //sys CopyFileRange(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error)
//sys DeleteModule(name string, flags int) (err error) //sys DeleteModule(name string, flags int) (err error)
//sys Dup(oldfd int) (fd int, err error) //sys Dup(oldfd int) (fd int, err error)
func Dup2(oldfd, newfd int) error {
// Android O and newer blocks dup2; riscv and arm64 don't implement dup2.
if runtime.GOOS == "android" || runtime.GOARCH == "riscv64" || runtime.GOARCH == "arm64" {
return Dup3(oldfd, newfd, 0)
}
return dup2(oldfd, newfd)
}
//sys Dup3(oldfd int, newfd int, flags int) (err error) //sys Dup3(oldfd int, newfd int, flags int) (err error)
//sysnb EpollCreate1(flag int) (fd int, err error) //sysnb EpollCreate1(flag int) (fd int, err error)
//sysnb EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error) //sysnb EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error)
@@ -1465,7 +1663,6 @@ func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err e
//sys Fchdir(fd int) (err error) //sys Fchdir(fd int) (err error)
//sys Fchmod(fd int, mode uint32) (err error) //sys Fchmod(fd int, mode uint32) (err error)
//sys Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) //sys Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error)
//sys fcntl(fd int, cmd int, arg int) (val int, err error)
//sys Fdatasync(fd int) (err error) //sys Fdatasync(fd int) (err error)
//sys Fgetxattr(fd int, attr string, dest []byte) (sz int, err error) //sys Fgetxattr(fd int, attr string, dest []byte) (sz int, err error)
//sys FinitModule(fd int, params string, flags int) (err error) //sys FinitModule(fd int, params string, flags int) (err error)
@@ -1521,6 +1718,17 @@ func Getpgrp() (pid int) {
//sysnb Settimeofday(tv *Timeval) (err error) //sysnb Settimeofday(tv *Timeval) (err error)
//sys Setns(fd int, nstype int) (err error) //sys Setns(fd int, nstype int) (err error)
// PrctlRetInt performs a prctl operation specified by option and further
// optional arguments arg2 through arg5 depending on option. It returns a
// non-negative integer that is returned by the prctl syscall.
func PrctlRetInt(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (int, error) {
ret, _, err := Syscall6(SYS_PRCTL, uintptr(option), uintptr(arg2), uintptr(arg3), uintptr(arg4), uintptr(arg5), 0)
if err != 0 {
return 0, err
}
return int(ret), nil
}
// issue 1435. // issue 1435.
// On linux Setuid and Setgid only affects the current thread, not the process. // On linux Setuid and Setgid only affects the current thread, not the process.
// This does not match what most callers expect so we must return an error // This does not match what most callers expect so we must return an error
@@ -1534,6 +1742,30 @@ func Setgid(uid int) (err error) {
return EOPNOTSUPP return EOPNOTSUPP
} }
// SetfsgidRetGid sets fsgid for current thread and returns previous fsgid set.
// setfsgid(2) will return a non-nil error only if its caller lacks CAP_SETUID capability.
// If the call fails due to other reasons, current fsgid will be returned.
func SetfsgidRetGid(gid int) (int, error) {
return setfsgid(gid)
}
// SetfsuidRetUid sets fsuid for current thread and returns previous fsuid set.
// setfsgid(2) will return a non-nil error only if its caller lacks CAP_SETUID capability
// If the call fails due to other reasons, current fsuid will be returned.
func SetfsuidRetUid(uid int) (int, error) {
return setfsuid(uid)
}
func Setfsgid(gid int) error {
_, err := setfsgid(gid)
return err
}
func Setfsuid(uid int) error {
_, err := setfsuid(uid)
return err
}
func Signalfd(fd int, sigmask *Sigset_t, flags int) (newfd int, err error) { func Signalfd(fd int, sigmask *Sigset_t, flags int) (newfd int, err error) {
return signalfd(fd, sigmask, _C__NSIG/8, flags) return signalfd(fd, sigmask, _C__NSIG/8, flags)
} }
@@ -1546,6 +1778,9 @@ func Signalfd(fd int, sigmask *Sigset_t, flags int) (newfd int, err error) {
//sys Syncfs(fd int) (err error) //sys Syncfs(fd int) (err error)
//sysnb Sysinfo(info *Sysinfo_t) (err error) //sysnb Sysinfo(info *Sysinfo_t) (err error)
//sys Tee(rfd int, wfd int, len int, flags int) (n int64, err error) //sys Tee(rfd int, wfd int, len int, flags int) (n int64, err error)
//sysnb TimerfdCreate(clockid int, flags int) (fd int, err error)
//sysnb TimerfdGettime(fd int, currValue *ItimerSpec) (err error)
//sysnb TimerfdSettime(fd int, flags int, newValue *ItimerSpec, oldValue *ItimerSpec) (err error)
//sysnb Tgkill(tgid int, tid int, sig syscall.Signal) (err error) //sysnb Tgkill(tgid int, tid int, sig syscall.Signal) (err error)
//sysnb Times(tms *Tms) (ticks uintptr, err error) //sysnb Times(tms *Tms) (ticks uintptr, err error)
//sysnb Umask(mask int) (oldmask int) //sysnb Umask(mask int) (oldmask int)
@@ -1556,6 +1791,123 @@ func Signalfd(fd int, sigmask *Sigset_t, flags int) (newfd int, err error) {
//sys exitThread(code int) (err error) = SYS_EXIT //sys exitThread(code int) (err error) = SYS_EXIT
//sys readlen(fd int, p *byte, np int) (n int, err error) = SYS_READ //sys readlen(fd int, p *byte, np int) (n int, err error) = SYS_READ
//sys writelen(fd int, p *byte, np int) (n int, err error) = SYS_WRITE //sys writelen(fd int, p *byte, np int) (n int, err error) = SYS_WRITE
//sys readv(fd int, iovs []Iovec) (n int, err error) = SYS_READV
//sys writev(fd int, iovs []Iovec) (n int, err error) = SYS_WRITEV
//sys preadv(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr) (n int, err error) = SYS_PREADV
//sys pwritev(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr) (n int, err error) = SYS_PWRITEV
//sys preadv2(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr, flags int) (n int, err error) = SYS_PREADV2
//sys pwritev2(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr, flags int) (n int, err error) = SYS_PWRITEV2
func bytes2iovec(bs [][]byte) []Iovec {
iovecs := make([]Iovec, len(bs))
for i, b := range bs {
iovecs[i].SetLen(len(b))
if len(b) > 0 {
iovecs[i].Base = &b[0]
} else {
iovecs[i].Base = (*byte)(unsafe.Pointer(&_zero))
}
}
return iovecs
}
// offs2lohi splits offs into its lower and upper unsigned long. On 64-bit
// systems, hi will always be 0. On 32-bit systems, offs will be split in half.
// preadv/pwritev chose this calling convention so they don't need to add a
// padding-register for alignment on ARM.
func offs2lohi(offs int64) (lo, hi uintptr) {
return uintptr(offs), uintptr(uint64(offs) >> SizeofLong)
}
func Readv(fd int, iovs [][]byte) (n int, err error) {
iovecs := bytes2iovec(iovs)
n, err = readv(fd, iovecs)
readvRacedetect(iovecs, n, err)
return n, err
}
func Preadv(fd int, iovs [][]byte, offset int64) (n int, err error) {
iovecs := bytes2iovec(iovs)
lo, hi := offs2lohi(offset)
n, err = preadv(fd, iovecs, lo, hi)
readvRacedetect(iovecs, n, err)
return n, err
}
func Preadv2(fd int, iovs [][]byte, offset int64, flags int) (n int, err error) {
iovecs := bytes2iovec(iovs)
lo, hi := offs2lohi(offset)
n, err = preadv2(fd, iovecs, lo, hi, flags)
readvRacedetect(iovecs, n, err)
return n, err
}
func readvRacedetect(iovecs []Iovec, n int, err error) {
if !raceenabled {
return
}
for i := 0; n > 0 && i < len(iovecs); i++ {
m := int(iovecs[i].Len)
if m > n {
m = n
}
n -= m
if m > 0 {
raceWriteRange(unsafe.Pointer(iovecs[i].Base), m)
}
}
if err == nil {
raceAcquire(unsafe.Pointer(&ioSync))
}
}
func Writev(fd int, iovs [][]byte) (n int, err error) {
iovecs := bytes2iovec(iovs)
if raceenabled {
raceReleaseMerge(unsafe.Pointer(&ioSync))
}
n, err = writev(fd, iovecs)
writevRacedetect(iovecs, n)
return n, err
}
func Pwritev(fd int, iovs [][]byte, offset int64) (n int, err error) {
iovecs := bytes2iovec(iovs)
if raceenabled {
raceReleaseMerge(unsafe.Pointer(&ioSync))
}
lo, hi := offs2lohi(offset)
n, err = pwritev(fd, iovecs, lo, hi)
writevRacedetect(iovecs, n)
return n, err
}
func Pwritev2(fd int, iovs [][]byte, offset int64, flags int) (n int, err error) {
iovecs := bytes2iovec(iovs)
if raceenabled {
raceReleaseMerge(unsafe.Pointer(&ioSync))
}
lo, hi := offs2lohi(offset)
n, err = pwritev2(fd, iovecs, lo, hi, flags)
writevRacedetect(iovecs, n)
return n, err
}
func writevRacedetect(iovecs []Iovec, n int) {
if !raceenabled {
return
}
for i := 0; n > 0 && i < len(iovecs); i++ {
m := int(iovecs[i].Len)
if m > n {
m = n
}
n -= m
if m > 0 {
raceReadRange(unsafe.Pointer(iovecs[i].Base), m)
}
}
}
// mmap varies by architecture; see syscall_linux_*.go. // mmap varies by architecture; see syscall_linux_*.go.
//sys munmap(addr uintptr, length uintptr) (err error) //sys munmap(addr uintptr, length uintptr) (err error)
@@ -1598,11 +1950,30 @@ func Vmsplice(fd int, iovs []Iovec, flags int) (int, error) {
return int(n), nil return int(n), nil
} }
func isGroupMember(gid int) bool {
groups, err := Getgroups()
if err != nil {
return false
}
for _, g := range groups {
if g == gid {
return true
}
}
return false
}
//sys faccessat(dirfd int, path string, mode uint32) (err error) //sys faccessat(dirfd int, path string, mode uint32) (err error)
//sys Faccessat2(dirfd int, path string, mode uint32, flags int) (err error)
func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) { func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {
if flags & ^(AT_SYMLINK_NOFOLLOW|AT_EACCESS) != 0 { if flags == 0 {
return EINVAL return faccessat(dirfd, path, mode)
}
if err := Faccessat2(dirfd, path, mode, flags); err != ENOSYS && err != EPERM {
return err
} }
// The Linux kernel faccessat system call does not take any flags. // The Linux kernel faccessat system call does not take any flags.
@@ -1611,8 +1982,8 @@ func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {
// Because people naturally expect syscall.Faccessat to act // Because people naturally expect syscall.Faccessat to act
// like C faccessat, we do the same. // like C faccessat, we do the same.
if flags == 0 { if flags & ^(AT_SYMLINK_NOFOLLOW|AT_EACCESS) != 0 {
return faccessat(dirfd, path, mode) return EINVAL
} }
var st Stat_t var st Stat_t
@@ -1655,7 +2026,7 @@ func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {
gid = Getgid() gid = Getgid()
} }
if uint32(gid) == st.Gid { if uint32(gid) == st.Gid || isGroupMember(gid) {
fmode = (st.Mode >> 3) & 7 fmode = (st.Mode >> 3) & 7
} else { } else {
fmode = st.Mode & 7 fmode = st.Mode & 7
@@ -1745,6 +2116,29 @@ func OpenByHandleAt(mountFD int, handle FileHandle, flags int) (fd int, err erro
return openByHandleAt(mountFD, handle.fileHandle, flags) return openByHandleAt(mountFD, handle.fileHandle, flags)
} }
// Klogset wraps the sys_syslog system call; it sets console_loglevel to
// the value specified by arg and passes a dummy pointer to bufp.
func Klogset(typ int, arg int) (err error) {
var p unsafe.Pointer
_, _, errno := Syscall(SYS_SYSLOG, uintptr(typ), uintptr(p), uintptr(arg))
if errno != 0 {
return errnoErr(errno)
}
return nil
}
// RemoteIovec is Iovec with the pointer replaced with an integer.
// It is used for ProcessVMReadv and ProcessVMWritev, where the pointer
// refers to a location in a different process' address space, which
// would confuse the Go garbage collector.
type RemoteIovec struct {
Base uintptr
Len int
}
//sys ProcessVMReadv(pid int, localIov []Iovec, remoteIov []RemoteIovec, flags uint) (n int, err error) = SYS_PROCESS_VM_READV
//sys ProcessVMWritev(pid int, localIov []Iovec, remoteIov []RemoteIovec, flags uint) (n int, err error) = SYS_PROCESS_VM_WRITEV
/* /*
* Unimplemented * Unimplemented
*/ */
@@ -1839,7 +2233,6 @@ func OpenByHandleAt(mountFD int, handle FileHandle, flags int) (fd int, err erro
// TimerGetoverrun // TimerGetoverrun
// TimerGettime // TimerGettime
// TimerSettime // TimerSettime
// Timerfd
// Tkill (obsolete) // Tkill (obsolete)
// Tuxcall // Tuxcall
// Umount2 // Umount2

View File

@@ -49,7 +49,7 @@ func Pipe2(p []int, flags int) (err error) {
// 64-bit file system and 32-bit uid calls // 64-bit file system and 32-bit uid calls
// (386 default is 32-bit file system and 16-bit uid). // (386 default is 32-bit file system and 16-bit uid).
//sys Dup2(oldfd int, newfd int) (err error) //sys dup2(oldfd int, newfd int) (err error)
//sysnb EpollCreate(size int) (fd int, err error) //sysnb EpollCreate(size int) (fd int, err error)
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) //sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64_64 //sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64_64
@@ -70,8 +70,8 @@ func Pipe2(p []int, flags int) (err error) {
//sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64 //sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
//sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) //sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = SYS_SENDFILE64 //sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = SYS_SENDFILE64
//sys Setfsgid(gid int) (err error) = SYS_SETFSGID32 //sys setfsgid(gid int) (prev int, err error) = SYS_SETFSGID32
//sys Setfsuid(uid int) (err error) = SYS_SETFSUID32 //sys setfsuid(uid int) (prev int, err error) = SYS_SETFSUID32
//sysnb Setregid(rgid int, egid int) (err error) = SYS_SETREGID32 //sysnb Setregid(rgid int, egid int) (err error) = SYS_SETREGID32
//sysnb Setresgid(rgid int, egid int, sgid int) (err error) = SYS_SETRESGID32 //sysnb Setresgid(rgid int, egid int, sgid int) (err error) = SYS_SETRESGID32
//sysnb Setresuid(ruid int, euid int, suid int) (err error) = SYS_SETRESUID32 //sysnb Setresuid(ruid int, euid int, suid int) (err error) = SYS_SETRESUID32
@@ -372,6 +372,10 @@ func (msghdr *Msghdr) SetControllen(length int) {
msghdr.Controllen = uint32(length) msghdr.Controllen = uint32(length)
} }
func (msghdr *Msghdr) SetIovlen(length int) {
msghdr.Iovlen = uint32(length)
}
func (cmsg *Cmsghdr) SetLen(length int) { func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint32(length) cmsg.Len = uint32(length)
} }

View File

@@ -6,7 +6,7 @@
package unix package unix
//sys Dup2(oldfd int, newfd int) (err error) //sys dup2(oldfd int, newfd int) (err error)
//sysnb EpollCreate(size int) (fd int, err error) //sysnb EpollCreate(size int) (fd int, err error)
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) //sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64 //sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64
@@ -55,8 +55,8 @@ func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err
} }
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) //sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
//sys Setfsgid(gid int) (err error) //sys setfsgid(gid int) (prev int, err error)
//sys Setfsuid(uid int) (err error) //sys setfsuid(uid int) (prev int, err error)
//sysnb Setregid(rgid int, egid int) (err error) //sysnb Setregid(rgid int, egid int) (err error)
//sysnb Setresgid(rgid int, egid int, sgid int) (err error) //sysnb Setresgid(rgid int, egid int, sgid int) (err error)
//sysnb Setresuid(ruid int, euid int, suid int) (err error) //sysnb Setresuid(ruid int, euid int, suid int) (err error)
@@ -163,6 +163,10 @@ func (msghdr *Msghdr) SetControllen(length int) {
msghdr.Controllen = uint64(length) msghdr.Controllen = uint64(length)
} }
func (msghdr *Msghdr) SetIovlen(length int) {
msghdr.Iovlen = uint64(length)
}
func (cmsg *Cmsghdr) SetLen(length int) { func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint64(length) cmsg.Len = uint64(length)
} }

View File

@@ -80,7 +80,7 @@ func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
// 64-bit file system and 32-bit uid calls // 64-bit file system and 32-bit uid calls
// (16-bit uid calls are not always supported in newer kernels) // (16-bit uid calls are not always supported in newer kernels)
//sys Dup2(oldfd int, newfd int) (err error) //sys dup2(oldfd int, newfd int) (err error)
//sysnb EpollCreate(size int) (fd int, err error) //sysnb EpollCreate(size int) (fd int, err error)
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) //sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
//sys Fchown(fd int, uid int, gid int) (err error) = SYS_FCHOWN32 //sys Fchown(fd int, uid int, gid int) (err error) = SYS_FCHOWN32
@@ -98,8 +98,8 @@ func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
//sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) //sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = SYS_SENDFILE64 //sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = SYS_SENDFILE64
//sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) = SYS__NEWSELECT //sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) = SYS__NEWSELECT
//sys Setfsgid(gid int) (err error) = SYS_SETFSGID32 //sys setfsgid(gid int) (prev int, err error) = SYS_SETFSGID32
//sys Setfsuid(uid int) (err error) = SYS_SETFSUID32 //sys setfsuid(uid int) (prev int, err error) = SYS_SETFSUID32
//sysnb Setregid(rgid int, egid int) (err error) = SYS_SETREGID32 //sysnb Setregid(rgid int, egid int) (err error) = SYS_SETREGID32
//sysnb Setresgid(rgid int, egid int, sgid int) (err error) = SYS_SETRESGID32 //sysnb Setresgid(rgid int, egid int, sgid int) (err error) = SYS_SETRESGID32
//sysnb Setresuid(ruid int, euid int, suid int) (err error) = SYS_SETRESUID32 //sysnb Setresuid(ruid int, euid int, suid int) (err error) = SYS_SETRESUID32
@@ -252,6 +252,10 @@ func (msghdr *Msghdr) SetControllen(length int) {
msghdr.Controllen = uint32(length) msghdr.Controllen = uint32(length)
} }
func (msghdr *Msghdr) SetIovlen(length int) {
msghdr.Iovlen = uint32(length)
}
func (cmsg *Cmsghdr) SetLen(length int) { func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint32(length) cmsg.Len = uint32(length)
} }

View File

@@ -25,7 +25,7 @@ func EpollCreate(size int) (fd int, err error) {
//sysnb Getegid() (egid int) //sysnb Getegid() (egid int)
//sysnb Geteuid() (euid int) //sysnb Geteuid() (euid int)
//sysnb Getgid() (gid int) //sysnb Getgid() (gid int)
//sysnb Getrlimit(resource int, rlim *Rlimit) (err error) //sysnb getrlimit(resource int, rlim *Rlimit) (err error)
//sysnb Getuid() (uid int) //sysnb Getuid() (uid int)
//sys Listen(s int, n int) (err error) //sys Listen(s int, n int) (err error)
//sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64 //sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
@@ -42,12 +42,12 @@ func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err
} }
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) //sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
//sys Setfsgid(gid int) (err error) //sys setfsgid(gid int) (prev int, err error)
//sys Setfsuid(uid int) (err error) //sys setfsuid(uid int) (prev int, err error)
//sysnb Setregid(rgid int, egid int) (err error) //sysnb Setregid(rgid int, egid int) (err error)
//sysnb Setresgid(rgid int, egid int, sgid int) (err error) //sysnb Setresgid(rgid int, egid int, sgid int) (err error)
//sysnb Setresuid(ruid int, euid int, suid int) (err error) //sysnb Setresuid(ruid int, euid int, suid int) (err error)
//sysnb Setrlimit(resource int, rlim *Rlimit) (err error) //sysnb setrlimit(resource int, rlim *Rlimit) (err error)
//sysnb Setreuid(ruid int, euid int) (err error) //sysnb Setreuid(ruid int, euid int) (err error)
//sys Shutdown(fd int, how 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 Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
@@ -168,6 +168,24 @@ func Pipe2(p []int, flags int) (err error) {
return return
} }
// Getrlimit prefers the prlimit64 system call. See issue 38604.
func Getrlimit(resource int, rlim *Rlimit) error {
err := prlimit(0, resource, nil, rlim)
if err != ENOSYS {
return err
}
return getrlimit(resource, rlim)
}
// Setrlimit prefers the prlimit64 system call. See issue 38604.
func Setrlimit(resource int, rlim *Rlimit) error {
err := prlimit(0, resource, rlim, nil)
if err != ENOSYS {
return err
}
return setrlimit(resource, rlim)
}
func (r *PtraceRegs) PC() uint64 { return r.Pc } func (r *PtraceRegs) PC() uint64 { return r.Pc }
func (r *PtraceRegs) SetPC(pc uint64) { r.Pc = pc } func (r *PtraceRegs) SetPC(pc uint64) { r.Pc = pc }
@@ -180,6 +198,10 @@ func (msghdr *Msghdr) SetControllen(length int) {
msghdr.Controllen = uint64(length) msghdr.Controllen = uint64(length)
} }
func (msghdr *Msghdr) SetIovlen(length int) {
msghdr.Iovlen = uint64(length)
}
func (cmsg *Cmsghdr) SetLen(length int) { func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint64(length) cmsg.Len = uint64(length)
} }
@@ -188,9 +210,9 @@ func InotifyInit() (fd int, err error) {
return InotifyInit1(0) return InotifyInit1(0)
} }
func Dup2(oldfd int, newfd int) (err error) { // dup2 exists because func Dup3 in syscall_linux.go references
return Dup3(oldfd, newfd, 0) // it in an unreachable path. dup2 isn't available on arm64.
} func dup2(oldfd int, newfd int) error
func Pause() error { func Pause() error {
_, err := ppoll(nil, 0, nil, nil) _, err := ppoll(nil, 0, nil, nil)

View File

@@ -7,7 +7,7 @@
package unix package unix
//sys Dup2(oldfd int, newfd int) (err error) //sys dup2(oldfd int, newfd int) (err error)
//sysnb EpollCreate(size int) (fd int, err error) //sysnb EpollCreate(size int) (fd int, err error)
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) //sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64 //sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64
@@ -36,8 +36,8 @@ func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err
} }
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) //sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
//sys Setfsgid(gid int) (err error) //sys setfsgid(gid int) (prev int, err error)
//sys Setfsuid(uid int) (err error) //sys setfsuid(uid int) (prev int, err error)
//sysnb Setregid(rgid int, egid int) (err error) //sysnb Setregid(rgid int, egid int) (err error)
//sysnb Setresgid(rgid int, egid int, sgid int) (err error) //sysnb Setresgid(rgid int, egid int, sgid int) (err error)
//sysnb Setresuid(ruid int, euid int, suid int) (err error) //sysnb Setresuid(ruid int, euid int, suid int) (err error)
@@ -208,10 +208,18 @@ func (msghdr *Msghdr) SetControllen(length int) {
msghdr.Controllen = uint64(length) msghdr.Controllen = uint64(length)
} }
func (msghdr *Msghdr) SetIovlen(length int) {
msghdr.Iovlen = uint64(length)
}
func (cmsg *Cmsghdr) SetLen(length int) { func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint64(length) cmsg.Len = uint64(length)
} }
func InotifyInit() (fd int, err error) {
return InotifyInit1(0)
}
//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) { func Poll(fds []PollFd, timeout int) (n int, err error) {

View File

@@ -14,7 +14,7 @@ import (
func Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno) func Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)
//sys Dup2(oldfd int, newfd int) (err error) //sys dup2(oldfd int, newfd int) (err error)
//sysnb EpollCreate(size int) (fd int, err error) //sysnb EpollCreate(size int) (fd int, err error)
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) //sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64 //sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64
@@ -31,8 +31,8 @@ func Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr,
//sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) //sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)
//sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) = SYS__NEWSELECT //sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) = SYS__NEWSELECT
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = SYS_SENDFILE64 //sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = SYS_SENDFILE64
//sys Setfsgid(gid int) (err error) //sys setfsgid(gid int) (prev int, err error)
//sys Setfsuid(uid int) (err error) //sys setfsuid(uid int) (prev int, err error)
//sysnb Setregid(rgid int, egid int) (err error) //sysnb Setregid(rgid int, egid int) (err error)
//sysnb Setresgid(rgid int, egid int, sgid int) (err error) //sysnb Setresgid(rgid int, egid int, sgid int) (err error)
//sysnb Setresuid(ruid int, euid int, suid int) (err error) //sysnb Setresuid(ruid int, euid int, suid int) (err error)
@@ -220,6 +220,10 @@ func (msghdr *Msghdr) SetControllen(length int) {
msghdr.Controllen = uint32(length) msghdr.Controllen = uint32(length)
} }
func (msghdr *Msghdr) SetIovlen(length int) {
msghdr.Iovlen = uint32(length)
}
func (cmsg *Cmsghdr) SetLen(length int) { func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint32(length) cmsg.Len = uint32(length)
} }

View File

@@ -7,7 +7,7 @@
package unix package unix
//sys Dup2(oldfd int, newfd int) (err error) //sys dup2(oldfd int, newfd int) (err error)
//sysnb EpollCreate(size int) (fd int, err error) //sysnb EpollCreate(size int) (fd int, err error)
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) //sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64 //sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64
@@ -34,8 +34,8 @@ package unix
//sys Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK //sys Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK
//sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) = SYS__NEWSELECT //sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) = SYS__NEWSELECT
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) //sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
//sys Setfsgid(gid int) (err error) //sys setfsgid(gid int) (prev int, err error)
//sys Setfsuid(uid int) (err error) //sys setfsuid(uid int) (prev int, err error)
//sysnb Setregid(rgid int, egid int) (err error) //sysnb Setregid(rgid int, egid int) (err error)
//sysnb Setresgid(rgid int, egid int, sgid int) (err error) //sysnb Setresgid(rgid int, egid int, sgid int) (err error)
//sysnb Setresuid(ruid int, euid int, suid int) (err error) //sysnb Setresuid(ruid int, euid int, suid int) (err error)
@@ -91,6 +91,10 @@ func (msghdr *Msghdr) SetControllen(length int) {
msghdr.Controllen = uint64(length) msghdr.Controllen = uint64(length)
} }
func (msghdr *Msghdr) SetIovlen(length int) {
msghdr.Iovlen = uint64(length)
}
func (cmsg *Cmsghdr) SetLen(length int) { func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint64(length) cmsg.Len = uint64(length)
} }

View File

@@ -41,8 +41,8 @@ func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err
} }
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) //sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
//sys Setfsgid(gid int) (err error) //sys setfsgid(gid int) (prev int, err error)
//sys Setfsuid(uid int) (err error) //sys setfsuid(uid int) (prev int, err error)
//sysnb Setregid(rgid int, egid int) (err error) //sysnb Setregid(rgid int, egid int) (err error)
//sysnb Setresgid(rgid int, egid int, sgid int) (err error) //sysnb Setresgid(rgid int, egid int, sgid int) (err error)
//sysnb Setresuid(ruid int, euid int, suid int) (err error) //sysnb Setresuid(ruid int, euid int, suid int) (err error)
@@ -179,6 +179,10 @@ func (msghdr *Msghdr) SetControllen(length int) {
msghdr.Controllen = uint64(length) msghdr.Controllen = uint64(length)
} }
func (msghdr *Msghdr) SetIovlen(length int) {
msghdr.Iovlen = uint64(length)
}
func (cmsg *Cmsghdr) SetLen(length int) { func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint64(length) cmsg.Len = uint64(length)
} }
@@ -187,10 +191,6 @@ func InotifyInit() (fd int, err error) {
return InotifyInit1(0) return InotifyInit1(0)
} }
func Dup2(oldfd int, newfd int) (err error) {
return Dup3(oldfd, newfd, 0)
}
func Pause() error { func Pause() error {
_, err := ppoll(nil, 0, nil, nil) _, err := ppoll(nil, 0, nil, nil)
return err return err
@@ -224,3 +224,7 @@ func KexecFileLoad(kernelFd int, initrdFd int, cmdline string, flags int) error
} }
return kexecFileLoad(kernelFd, initrdFd, cmdlineLen, cmdline, flags) return kexecFileLoad(kernelFd, initrdFd, cmdlineLen, cmdline, flags)
} }
// dup2 exists because func Dup3 in syscall_linux.go references
// it in an unreachable path. dup2 isn't available on arm64.
func dup2(oldfd int, newfd int) error

View File

@@ -10,7 +10,7 @@ import (
"unsafe" "unsafe"
) )
//sys Dup2(oldfd int, newfd int) (err error) //sys dup2(oldfd int, newfd int) (err error)
//sysnb EpollCreate(size int) (fd int, err error) //sysnb EpollCreate(size int) (fd int, err error)
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) //sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64 //sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64
@@ -34,8 +34,8 @@ import (
//sys Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK //sys Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK
//sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) //sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error)
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) //sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
//sys Setfsgid(gid int) (err error) //sys setfsgid(gid int) (prev int, err error)
//sys Setfsuid(uid int) (err error) //sys setfsuid(uid int) (prev int, err error)
//sysnb Setregid(rgid int, egid int) (err error) //sysnb Setregid(rgid int, egid int) (err error)
//sysnb Setresgid(rgid int, egid int, sgid int) (err error) //sysnb Setresgid(rgid int, egid int, sgid int) (err error)
//sysnb Setresuid(ruid int, euid int, suid int) (err error) //sysnb Setresuid(ruid int, euid int, suid int) (err error)
@@ -120,6 +120,10 @@ func (msghdr *Msghdr) SetControllen(length int) {
msghdr.Controllen = uint64(length) msghdr.Controllen = uint64(length)
} }
func (msghdr *Msghdr) SetIovlen(length int) {
msghdr.Iovlen = uint64(length)
}
func (cmsg *Cmsghdr) SetLen(length int) { func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint64(length) cmsg.Len = uint64(length)
} }

View File

@@ -8,7 +8,7 @@ package unix
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) //sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64 //sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64
//sys Dup2(oldfd int, newfd int) (err error) //sys dup2(oldfd int, newfd int) (err error)
//sys Fchown(fd int, uid int, gid int) (err error) //sys Fchown(fd int, uid int, gid int) (err error)
//sys Fstat(fd int, stat *Stat_t) (err error) //sys Fstat(fd int, stat *Stat_t) (err error)
//sys Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_FSTATAT64 //sys Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_FSTATAT64
@@ -30,8 +30,8 @@ package unix
//sys Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK //sys Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK
//sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) //sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error)
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) //sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
//sys Setfsgid(gid int) (err error) //sys setfsgid(gid int) (prev int, err error)
//sys Setfsuid(uid int) (err error) //sys setfsuid(uid int) (prev int, err error)
//sysnb Setregid(rgid int, egid int) (err error) //sysnb Setregid(rgid int, egid int) (err error)
//sysnb Setresgid(rgid int, egid int, sgid int) (err error) //sysnb Setresgid(rgid int, egid int, sgid int) (err error)
//sysnb Setresuid(ruid int, euid int, suid int) (err error) //sysnb Setresuid(ruid int, euid int, suid int) (err error)
@@ -107,6 +107,10 @@ func (msghdr *Msghdr) SetControllen(length int) {
msghdr.Controllen = uint64(length) msghdr.Controllen = uint64(length)
} }
func (msghdr *Msghdr) SetIovlen(length int) {
msghdr.Iovlen = uint64(length)
}
func (cmsg *Cmsghdr) SetLen(length int) { func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint64(length) cmsg.Len = uint64(length)
} }

View File

@@ -94,21 +94,16 @@ func nametomib(name string) (mib []_C_int, err error) {
return mib, nil return mib, nil
} }
func SysctlClockinfo(name string) (*Clockinfo, error) { func direntIno(buf []byte) (uint64, bool) {
mib, err := sysctlmib(name) return readInt(buf, unsafe.Offsetof(Dirent{}.Fileno), unsafe.Sizeof(Dirent{}.Fileno))
if err != nil { }
return nil, err
}
n := uintptr(SizeofClockinfo) func direntReclen(buf []byte) (uint64, bool) {
var ci Clockinfo return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
if err := sysctl(mib, (*byte)(unsafe.Pointer(&ci)), &n, nil, 0); err != nil { }
return nil, err
} func direntNamlen(buf []byte) (uint64, bool) {
if n != SizeofClockinfo { return readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen))
return nil, EIO
}
return &ci, nil
} }
//sysnb pipe() (fd1 int, fd2 int, err error) //sysnb pipe() (fd1 int, fd2 int, err error)
@@ -175,42 +170,7 @@ func setattrlistTimes(path string, times []Timespec, flags int) error {
//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 //sys sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) = SYS___SYSCTL
// 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
}
func IoctlGetPtmget(fd int, req uint) (*Ptmget, error) { func IoctlGetPtmget(fd int, req uint) (*Ptmget, error) {
var value Ptmget var value Ptmget
@@ -272,6 +232,14 @@ func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err e
return sendfile(outfd, infd, offset, count) return sendfile(outfd, infd, offset, count)
} }
func Fstatvfs(fd int, buf *Statvfs_t) (err error) {
return Fstatvfs1(fd, buf, ST_WAIT)
}
func Statvfs(path string, buf *Statvfs_t) (err error) {
return Statvfs1(path, buf, ST_WAIT)
}
/* /*
* Exposed directly * Exposed directly
*/ */
@@ -285,6 +253,7 @@ func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err e
//sys Close(fd int) (err error) //sys Close(fd int) (err error)
//sys Dup(fd int) (nfd int, err error) //sys Dup(fd int) (nfd int, err error)
//sys Dup2(from int, to int) (err error) //sys Dup2(from int, to int) (err error)
//sys Dup3(from int, to int, flags int) (err error)
//sys Exit(code int) //sys Exit(code int)
//sys ExtattrGetFd(fd int, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error) //sys ExtattrGetFd(fd int, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error)
//sys ExtattrSetFd(fd int, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error) //sys ExtattrSetFd(fd int, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error)
@@ -310,6 +279,7 @@ func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err e
//sys Fpathconf(fd int, name int) (val int, err error) //sys Fpathconf(fd int, name int) (val int, err error)
//sys Fstat(fd int, stat *Stat_t) (err error) //sys Fstat(fd int, stat *Stat_t) (err error)
//sys Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) //sys Fstatat(fd int, path string, stat *Stat_t, flags int) (err error)
//sys Fstatvfs1(fd int, buf *Statvfs_t, flags int) (err error) = SYS_FSTATVFS1
//sys Fsync(fd int) (err error) //sys Fsync(fd int) (err error)
//sys Ftruncate(fd int, length int64) (err error) //sys Ftruncate(fd int, length int64) (err error)
//sysnb Getegid() (egid int) //sysnb Getegid() (egid int)
@@ -353,7 +323,7 @@ func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err e
//sys Revoke(path string) (err error) //sys Revoke(path string) (err error)
//sys Rmdir(path string) (err error) //sys Rmdir(path string) (err error)
//sys Seek(fd int, offset int64, whence int) (newoffset int64, err error) = SYS_LSEEK //sys Seek(fd int, offset int64, whence int) (newoffset int64, err error) = SYS_LSEEK
//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 Setegid(egid int) (err error)
//sysnb Seteuid(euid int) (err error) //sysnb Seteuid(euid int) (err error)
//sysnb Setgid(gid int) (err error) //sysnb Setgid(gid int) (err error)
@@ -366,6 +336,7 @@ func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err e
//sysnb Settimeofday(tp *Timeval) (err error) //sysnb Settimeofday(tp *Timeval) (err error)
//sysnb Setuid(uid int) (err error) //sysnb Setuid(uid int) (err error)
//sys Stat(path string, stat *Stat_t) (err error) //sys Stat(path string, stat *Stat_t) (err error)
//sys Statvfs1(path string, buf *Statvfs_t, flags int) (err error) = SYS_STATVFS1
//sys Symlink(path string, link string) (err error) //sys Symlink(path string, link string) (err error)
//sys Symlinkat(oldpath string, newdirfd int, newpath string) (err error) //sys Symlinkat(oldpath string, newdirfd int, newpath string) (err error)
//sys Sync() (err error) //sys Sync() (err error)

View File

@@ -28,6 +28,10 @@ func (msghdr *Msghdr) SetControllen(length int) {
msghdr.Controllen = uint32(length) msghdr.Controllen = uint32(length)
} }
func (msghdr *Msghdr) SetIovlen(length int) {
msghdr.Iovlen = int32(length)
}
func (cmsg *Cmsghdr) SetLen(length int) { func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint32(length) cmsg.Len = uint32(length)
} }

View File

@@ -28,6 +28,10 @@ func (msghdr *Msghdr) SetControllen(length int) {
msghdr.Controllen = uint32(length) msghdr.Controllen = uint32(length)
} }
func (msghdr *Msghdr) SetIovlen(length int) {
msghdr.Iovlen = int32(length)
}
func (cmsg *Cmsghdr) SetLen(length int) { func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint32(length) cmsg.Len = uint32(length)
} }

View File

@@ -28,6 +28,10 @@ func (msghdr *Msghdr) SetControllen(length int) {
msghdr.Controllen = uint32(length) msghdr.Controllen = uint32(length)
} }
func (msghdr *Msghdr) SetIovlen(length int) {
msghdr.Iovlen = int32(length)
}
func (cmsg *Cmsghdr) SetLen(length int) { func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint32(length) cmsg.Len = uint32(length)
} }

View File

@@ -28,6 +28,10 @@ func (msghdr *Msghdr) SetControllen(length int) {
msghdr.Controllen = uint32(length) msghdr.Controllen = uint32(length)
} }
func (msghdr *Msghdr) SetIovlen(length int) {
msghdr.Iovlen = int32(length)
}
func (cmsg *Cmsghdr) SetLen(length int) { func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint32(length) cmsg.Len = uint32(length)
} }

View File

@@ -43,21 +43,16 @@ func nametomib(name string) (mib []_C_int, err error) {
return nil, EINVAL return nil, EINVAL
} }
func SysctlClockinfo(name string) (*Clockinfo, error) { func direntIno(buf []byte) (uint64, bool) {
mib, err := sysctlmib(name) return readInt(buf, unsafe.Offsetof(Dirent{}.Fileno), unsafe.Sizeof(Dirent{}.Fileno))
if err != nil { }
return nil, err
}
n := uintptr(SizeofClockinfo) func direntReclen(buf []byte) (uint64, bool) {
var ci Clockinfo return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
if err := sysctl(mib, (*byte)(unsafe.Pointer(&ci)), &n, nil, 0); err != nil { }
return nil, err
} func direntNamlen(buf []byte) (uint64, bool) {
if n != SizeofClockinfo { return readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen))
return nil, EIO
}
return &ci, nil
} }
func SysctlUvmexp(name string) (*Uvmexp, error) { func SysctlUvmexp(name string) (*Uvmexp, error) {
@@ -77,16 +72,20 @@ func SysctlUvmexp(name string) (*Uvmexp, error) {
return &u, nil return &u, nil
} }
//sysnb pipe(p *[2]_C_int) (err error)
func Pipe(p []int) (err error) { func Pipe(p []int) (err error) {
return Pipe2(p, 0)
}
//sysnb pipe2(p *[2]_C_int, flags int) (err error)
func Pipe2(p []int, flags int) error {
if len(p) != 2 { if len(p) != 2 {
return EINVAL return EINVAL
} }
var pp [2]_C_int var pp [2]_C_int
err = pipe(&pp) err := pipe2(&pp, flags)
p[0] = int(pp[0]) p[0] = int(pp[0])
p[1] = int(pp[1]) p[1] = int(pp[1])
return return err
} }
//sys Getdents(fd int, buf []byte) (n int, err error) //sys Getdents(fd int, buf []byte) (n int, err error)
@@ -166,42 +165,7 @@ func setattrlistTimes(path string, times []Timespec, flags int) error {
//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 //sys sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) = SYS___SYSCTL
// 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 ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error) //sys ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error)
@@ -271,6 +235,7 @@ func Uname(uname *Utsname) error {
//sys Close(fd int) (err error) //sys Close(fd int) (err error)
//sys Dup(fd int) (nfd int, err error) //sys Dup(fd int) (nfd int, err error)
//sys Dup2(from int, to int) (err error) //sys Dup2(from int, to int) (err error)
//sys Dup3(from int, to int, flags int) (err error)
//sys Exit(code int) //sys Exit(code int)
//sys Faccessat(dirfd int, path string, mode uint32, flags int) (err error) //sys Faccessat(dirfd int, path string, mode uint32, flags int) (err error)
//sys Fchdir(fd int) (err error) //sys Fchdir(fd int) (err error)
@@ -328,7 +293,7 @@ func Uname(uname *Utsname) error {
//sys Revoke(path string) (err error) //sys Revoke(path string) (err error)
//sys Rmdir(path string) (err error) //sys Rmdir(path string) (err error)
//sys Seek(fd int, offset int64, whence int) (newoffset int64, err error) = SYS_LSEEK //sys Seek(fd int, offset int64, whence int) (newoffset int64, err error) = SYS_LSEEK
//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 Setegid(egid int) (err error)
//sysnb Seteuid(euid int) (err error) //sysnb Seteuid(euid int) (err error)
//sysnb Setgid(gid int) (err error) //sysnb Setgid(gid int) (err error)
@@ -375,7 +340,6 @@ func Uname(uname *Utsname) error {
// clock_settime // clock_settime
// closefrom // closefrom
// execve // execve
// fcntl
// fhopen // fhopen
// fhstat // fhstat
// fhstatfs // fhstatfs

View File

@@ -28,6 +28,10 @@ func (msghdr *Msghdr) SetControllen(length int) {
msghdr.Controllen = uint32(length) msghdr.Controllen = uint32(length)
} }
func (msghdr *Msghdr) SetIovlen(length int) {
msghdr.Iovlen = uint32(length)
}
func (cmsg *Cmsghdr) SetLen(length int) { func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint32(length) cmsg.Len = uint32(length)
} }

View File

@@ -28,6 +28,10 @@ func (msghdr *Msghdr) SetControllen(length int) {
msghdr.Controllen = uint32(length) msghdr.Controllen = uint32(length)
} }
func (msghdr *Msghdr) SetIovlen(length int) {
msghdr.Iovlen = uint32(length)
}
func (cmsg *Cmsghdr) SetLen(length int) { func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint32(length) cmsg.Len = uint32(length)
} }

View File

@@ -28,6 +28,10 @@ func (msghdr *Msghdr) SetControllen(length int) {
msghdr.Controllen = uint32(length) msghdr.Controllen = uint32(length)
} }
func (msghdr *Msghdr) SetIovlen(length int) {
msghdr.Iovlen = uint32(length)
}
func (cmsg *Cmsghdr) SetLen(length int) { func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint32(length) cmsg.Len = uint32(length)
} }

View File

@@ -28,6 +28,10 @@ func (msghdr *Msghdr) SetControllen(length int) {
msghdr.Controllen = uint32(length) msghdr.Controllen = uint32(length)
} }
func (msghdr *Msghdr) SetIovlen(length int) {
msghdr.Iovlen = uint32(length)
}
func (cmsg *Cmsghdr) SetLen(length int) { func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint32(length) cmsg.Len = uint32(length)
} }

Some files were not shown because too many files have changed in this diff Show More