parent
716f857335
commit
bbe7775c27
21
go.mod
21
go.mod
|
|
@ -1,19 +1,20 @@
|
|||
module github.com/letsencrypt/pebble/v2
|
||||
|
||||
go 1.22
|
||||
go 1.22.0
|
||||
|
||||
toolchain go1.23.1
|
||||
|
||||
require (
|
||||
github.com/go-jose/go-jose/v4 v4.0.1
|
||||
github.com/go-jose/go-jose/v4 v4.0.4
|
||||
github.com/letsencrypt/challtestsrv v1.3.2
|
||||
github.com/miekg/dns v1.1.58
|
||||
github.com/miekg/dns v1.1.62
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/google/go-cmp v0.6.0 // indirect
|
||||
github.com/stretchr/testify v1.8.4 // indirect
|
||||
golang.org/x/crypto v0.26.0 // indirect
|
||||
golang.org/x/mod v0.15.0 // indirect
|
||||
golang.org/x/net v0.28.0 // indirect
|
||||
golang.org/x/sys v0.23.0 // indirect
|
||||
golang.org/x/tools v0.18.0 // indirect
|
||||
golang.org/x/crypto v0.32.0 // indirect
|
||||
golang.org/x/mod v0.22.0 // indirect
|
||||
golang.org/x/net v0.34.0 // indirect
|
||||
golang.org/x/sync v0.10.0 // indirect
|
||||
golang.org/x/sys v0.29.0 // indirect
|
||||
golang.org/x/tools v0.29.0 // indirect
|
||||
)
|
||||
|
|
|
|||
36
go.sum
36
go.sum
|
|
@ -1,36 +1,36 @@
|
|||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/go-jose/go-jose/v4 v4.0.1 h1:QVEPDE3OluqXBQZDcnNvQrInro2h0e4eqNbnZSWqS6U=
|
||||
github.com/go-jose/go-jose/v4 v4.0.1/go.mod h1:WVf9LFMHh/QVrmqrOfqun0C45tMe3RoiKJMPvgWwLfY=
|
||||
github.com/go-jose/go-jose/v4 v4.0.4 h1:VsjPI33J0SB9vQM6PLmNjoHqMQNGPiZ0rHL7Ni7Q6/E=
|
||||
github.com/go-jose/go-jose/v4 v4.0.4/go.mod h1:NKb5HO1EZccyMpiZNbdUw/14tiXNyUJh188dfnMCAfc=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/letsencrypt/challtestsrv v1.3.2 h1:pIDLBCLXR3B1DLmOmkkqg29qVa7DDozBnsOpL9PxmAY=
|
||||
github.com/letsencrypt/challtestsrv v1.3.2/go.mod h1:Ur4e4FvELUXLGhkMztHOsPIsvGxD/kzSJninOrkM+zc=
|
||||
github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4=
|
||||
github.com/miekg/dns v1.1.58 h1:ca2Hdkz+cDg/7eNF6V56jjzuZ4aCAE+DbVkILdQWG/4=
|
||||
github.com/miekg/dns v1.1.58/go.mod h1:Ypv+3b/KadlvW9vJfXOTf300O4UqaHFzFCuHz+rPkBY=
|
||||
github.com/miekg/dns v1.1.62 h1:cN8OuEF1/x5Rq6Np+h1epln8OiyPWV+lROx9LxcGgIQ=
|
||||
github.com/miekg/dns v1.1.62/go.mod h1:mvDlcItzm+br7MToIKqkglaGhlFMHJ9DTNNWONWXbNQ=
|
||||
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/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
|
||||
golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
|
||||
golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8=
|
||||
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc=
|
||||
golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc=
|
||||
golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4=
|
||||
golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
|
||||
golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
|
||||
golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0=
|
||||
golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
|
||||
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
|
||||
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM=
|
||||
golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
|
||||
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.18.0 h1:k8NLag8AGHnn+PHbl7g43CtqZAwG60vZkLqgyZgIHgQ=
|
||||
golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg=
|
||||
golang.org/x/tools v0.29.0 h1:Xx0h3TtM9rzQpQuR4dKLrdglAmCEN5Oi+P74JdhdzXE=
|
||||
golang.org/x/tools v0.29.0/go.mod h1:KMQVMRsVxU6nHCFXrBPhDB8XncLNLM0lIy/F14RP588=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
|
|
|||
|
|
@ -1,3 +1,27 @@
|
|||
# v4.0.4
|
||||
|
||||
## Fixed
|
||||
|
||||
- Reverted "Allow unmarshalling JSONWebKeySets with unsupported key types" as a
|
||||
breaking change. See #136 / #137.
|
||||
|
||||
# v4.0.3
|
||||
|
||||
## Changed
|
||||
|
||||
- Allow unmarshalling JSONWebKeySets with unsupported key types (#130)
|
||||
- Document that OpaqueKeyEncrypter can't be implemented (for now) (#129)
|
||||
- Dependency updates
|
||||
|
||||
# v4.0.2
|
||||
|
||||
## Changed
|
||||
|
||||
- Improved documentation of Verify() to note that JSONWebKeySet is a supported
|
||||
argument type (#104)
|
||||
- Defined exported error values for missing x5c header and unsupported elliptic
|
||||
curves error cases (#117)
|
||||
|
||||
# v4.0.1
|
||||
|
||||
## Fixed
|
||||
|
|
|
|||
|
|
@ -459,7 +459,10 @@ func (obj JSONWebEncryption) Decrypt(decryptionKey interface{}) ([]byte, error)
|
|||
return nil, fmt.Errorf("go-jose/go-jose: unsupported crit header")
|
||||
}
|
||||
|
||||
key := tryJWKS(decryptionKey, obj.Header)
|
||||
key, err := tryJWKS(decryptionKey, obj.Header)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
decrypter, err := newDecrypter(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -529,7 +532,10 @@ func (obj JSONWebEncryption) DecryptMulti(decryptionKey interface{}) (int, Heade
|
|||
return -1, Header{}, nil, fmt.Errorf("go-jose/go-jose: unsupported crit header")
|
||||
}
|
||||
|
||||
key := tryJWKS(decryptionKey, obj.Header)
|
||||
key, err := tryJWKS(decryptionKey, obj.Header)
|
||||
if err != nil {
|
||||
return -1, Header{}, nil, err
|
||||
}
|
||||
decrypter, err := newDecrypter(key)
|
||||
if err != nil {
|
||||
return -1, Header{}, nil, err
|
||||
|
|
|
|||
|
|
@ -779,7 +779,13 @@ func (key rawJSONWebKey) symmetricKey() ([]byte, error) {
|
|||
return key.K.bytes(), nil
|
||||
}
|
||||
|
||||
func tryJWKS(key interface{}, headers ...Header) interface{} {
|
||||
var (
|
||||
// ErrJWKSKidNotFound is returned when a JWKS does not contain a JWK with a
|
||||
// key ID which matches one in the provided tokens headers.
|
||||
ErrJWKSKidNotFound = errors.New("go-jose/go-jose: JWK with matching kid not found in JWK Set")
|
||||
)
|
||||
|
||||
func tryJWKS(key interface{}, headers ...Header) (interface{}, error) {
|
||||
var jwks JSONWebKeySet
|
||||
|
||||
switch jwksType := key.(type) {
|
||||
|
|
@ -788,9 +794,11 @@ func tryJWKS(key interface{}, headers ...Header) interface{} {
|
|||
case JSONWebKeySet:
|
||||
jwks = jwksType
|
||||
default:
|
||||
return key
|
||||
// If the specified key is not a JWKS, return as is.
|
||||
return key, nil
|
||||
}
|
||||
|
||||
// Determine the KID to search for from the headers.
|
||||
var kid string
|
||||
for _, header := range headers {
|
||||
if header.KeyID != "" {
|
||||
|
|
@ -799,14 +807,17 @@ func tryJWKS(key interface{}, headers ...Header) interface{} {
|
|||
}
|
||||
}
|
||||
|
||||
// If no KID is specified in the headers, reject.
|
||||
if kid == "" {
|
||||
return key
|
||||
return nil, ErrJWKSKidNotFound
|
||||
}
|
||||
|
||||
// Find the JWK with the matching KID. If no JWK with the specified KID is
|
||||
// found, reject.
|
||||
keys := jwks.Key(kid)
|
||||
if len(keys) == 0 {
|
||||
return key
|
||||
return nil, ErrJWKSKidNotFound
|
||||
}
|
||||
|
||||
return keys[0].Key
|
||||
return keys[0].Key, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -83,6 +83,9 @@ func (o *opaqueVerifier) verifyPayload(payload []byte, signature []byte, alg Sig
|
|||
}
|
||||
|
||||
// OpaqueKeyEncrypter is an interface that supports encrypting keys with an opaque key.
|
||||
//
|
||||
// Note: this cannot currently be implemented outside this package because of its
|
||||
// unexported method.
|
||||
type OpaqueKeyEncrypter interface {
|
||||
// KeyID returns the kid
|
||||
KeyID() string
|
||||
|
|
|
|||
|
|
@ -71,6 +71,12 @@ var (
|
|||
// ErrUnprotectedNonce indicates that while parsing a JWS or JWE object, a
|
||||
// nonce header parameter was included in an unprotected header object.
|
||||
ErrUnprotectedNonce = errors.New("go-jose/go-jose: Nonce parameter included in unprotected header")
|
||||
|
||||
// ErrMissingX5cHeader indicates that the JWT header is missing x5c headers.
|
||||
ErrMissingX5cHeader = errors.New("go-jose/go-jose: no x5c header present in message")
|
||||
|
||||
// ErrUnsupportedEllipticCurve indicates unsupported or unknown elliptic curve has been found.
|
||||
ErrUnsupportedEllipticCurve = errors.New("go-jose/go-jose: unsupported/unknown elliptic curve")
|
||||
)
|
||||
|
||||
// Key management algorithms
|
||||
|
|
@ -199,7 +205,7 @@ type Header struct {
|
|||
// not be validated with the given verify options.
|
||||
func (h Header) Certificates(opts x509.VerifyOptions) ([][]*x509.Certificate, error) {
|
||||
if len(h.certificates) == 0 {
|
||||
return nil, errors.New("go-jose/go-jose: no x5c header present in message")
|
||||
return nil, ErrMissingX5cHeader
|
||||
}
|
||||
|
||||
leaf := h.certificates[0]
|
||||
|
|
@ -501,7 +507,7 @@ func curveName(crv elliptic.Curve) (string, error) {
|
|||
case elliptic.P521():
|
||||
return "P-521", nil
|
||||
default:
|
||||
return "", fmt.Errorf("go-jose/go-jose: unsupported/unknown elliptic curve")
|
||||
return "", ErrUnsupportedEllipticCurve
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -358,6 +358,8 @@ func (ctx *genericSigner) Options() SignerOptions {
|
|||
// - *rsa.PublicKey
|
||||
// - *JSONWebKey
|
||||
// - JSONWebKey
|
||||
// - *JSONWebKeySet
|
||||
// - JSONWebKeySet
|
||||
// - []byte (an HMAC key)
|
||||
// - Any type that implements the OpaqueVerifier interface.
|
||||
//
|
||||
|
|
@ -388,7 +390,10 @@ func (obj JSONWebSignature) UnsafePayloadWithoutVerification() []byte {
|
|||
// The verificationKey argument must have one of the types allowed for the
|
||||
// verificationKey argument of JSONWebSignature.Verify().
|
||||
func (obj JSONWebSignature) DetachedVerify(payload []byte, verificationKey interface{}) error {
|
||||
key := tryJWKS(verificationKey, obj.headers()...)
|
||||
key, err := tryJWKS(verificationKey, obj.headers()...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
verifier, err := newVerifier(key)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -453,7 +458,10 @@ func (obj JSONWebSignature) VerifyMulti(verificationKey interface{}) (int, Signa
|
|||
// The verificationKey argument must have one of the types allowed for the
|
||||
// verificationKey argument of JSONWebSignature.Verify().
|
||||
func (obj JSONWebSignature) DetachedVerifyMulti(payload []byte, verificationKey interface{}) (int, Signature, error) {
|
||||
key := tryJWKS(verificationKey, obj.headers()...)
|
||||
key, err := tryJWKS(verificationKey, obj.headers()...)
|
||||
if err != nil {
|
||||
return -1, Signature{}, err
|
||||
}
|
||||
verifier, err := newVerifier(key)
|
||||
if err != nil {
|
||||
return -1, Signature{}, err
|
||||
|
|
|
|||
|
|
@ -83,6 +83,8 @@ A not-so-up-to-date-list-that-may-be-actually-current:
|
|||
* https://github.com/egbakou/domainverifier
|
||||
* https://github.com/semihalev/sdns
|
||||
* https://github.com/wintbiit/NineDNS
|
||||
* https://linuxcontainers.org/incus/
|
||||
* https://ifconfig.es
|
||||
|
||||
|
||||
Send pull request if you want to be listed here.
|
||||
|
|
@ -146,6 +148,7 @@ Example programs can be found in the `github.com/miekg/exdns` repository.
|
|||
* 3225 - DO bit (DNSSEC OK)
|
||||
* 340{1,2,3} - NAPTR record
|
||||
* 3445 - Limiting the scope of (DNS)KEY
|
||||
* 3596 - AAAA record
|
||||
* 3597 - Unknown RRs
|
||||
* 4025 - A Method for Storing IPsec Keying Material in DNS
|
||||
* 403{3,4,5} - DNSSEC + validation functions
|
||||
|
|
@ -186,6 +189,9 @@ Example programs can be found in the `github.com/miekg/exdns` repository.
|
|||
* 8777 - DNS Reverse IP Automatic Multicast Tunneling (AMT) Discovery
|
||||
* 8914 - Extended DNS Errors
|
||||
* 8976 - Message Digest for DNS Zones (ZONEMD RR)
|
||||
* 9460 - Service Binding and Parameter Specification via the DNS
|
||||
* 9461 - Service Binding Mapping for DNS Servers
|
||||
* 9462 - Discovery of Designated Resolvers
|
||||
|
||||
## Loosely Based Upon
|
||||
|
||||
|
|
|
|||
|
|
@ -198,10 +198,12 @@ func IsDomainName(s string) (labels int, ok bool) {
|
|||
off int
|
||||
begin int
|
||||
wasDot bool
|
||||
escape bool
|
||||
)
|
||||
for i := 0; i < len(s); i++ {
|
||||
switch s[i] {
|
||||
case '\\':
|
||||
escape = !escape
|
||||
if off+1 > lenmsg {
|
||||
return labels, false
|
||||
}
|
||||
|
|
@ -217,6 +219,7 @@ func IsDomainName(s string) (labels int, ok bool) {
|
|||
|
||||
wasDot = false
|
||||
case '.':
|
||||
escape = false
|
||||
if i == 0 && len(s) > 1 {
|
||||
// leading dots are not legal except for the root zone
|
||||
return labels, false
|
||||
|
|
@ -243,10 +246,13 @@ func IsDomainName(s string) (labels int, ok bool) {
|
|||
labels++
|
||||
begin = i + 1
|
||||
default:
|
||||
escape = false
|
||||
wasDot = false
|
||||
}
|
||||
}
|
||||
|
||||
if escape {
|
||||
return labels, false
|
||||
}
|
||||
return labels, true
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -756,36 +756,48 @@ const (
|
|||
ExtendedErrorCodeNoReachableAuthority
|
||||
ExtendedErrorCodeNetworkError
|
||||
ExtendedErrorCodeInvalidData
|
||||
ExtendedErrorCodeSignatureExpiredBeforeValid
|
||||
ExtendedErrorCodeTooEarly
|
||||
ExtendedErrorCodeUnsupportedNSEC3IterValue
|
||||
ExtendedErrorCodeUnableToConformToPolicy
|
||||
ExtendedErrorCodeSynthesized
|
||||
ExtendedErrorCodeInvalidQueryType
|
||||
)
|
||||
|
||||
// ExtendedErrorCodeToString maps extended error info codes to a human readable
|
||||
// description.
|
||||
var ExtendedErrorCodeToString = map[uint16]string{
|
||||
ExtendedErrorCodeOther: "Other",
|
||||
ExtendedErrorCodeUnsupportedDNSKEYAlgorithm: "Unsupported DNSKEY Algorithm",
|
||||
ExtendedErrorCodeUnsupportedDSDigestType: "Unsupported DS Digest Type",
|
||||
ExtendedErrorCodeStaleAnswer: "Stale Answer",
|
||||
ExtendedErrorCodeForgedAnswer: "Forged Answer",
|
||||
ExtendedErrorCodeDNSSECIndeterminate: "DNSSEC Indeterminate",
|
||||
ExtendedErrorCodeDNSBogus: "DNSSEC Bogus",
|
||||
ExtendedErrorCodeSignatureExpired: "Signature Expired",
|
||||
ExtendedErrorCodeSignatureNotYetValid: "Signature Not Yet Valid",
|
||||
ExtendedErrorCodeDNSKEYMissing: "DNSKEY Missing",
|
||||
ExtendedErrorCodeRRSIGsMissing: "RRSIGs Missing",
|
||||
ExtendedErrorCodeNoZoneKeyBitSet: "No Zone Key Bit Set",
|
||||
ExtendedErrorCodeNSECMissing: "NSEC Missing",
|
||||
ExtendedErrorCodeCachedError: "Cached Error",
|
||||
ExtendedErrorCodeNotReady: "Not Ready",
|
||||
ExtendedErrorCodeBlocked: "Blocked",
|
||||
ExtendedErrorCodeCensored: "Censored",
|
||||
ExtendedErrorCodeFiltered: "Filtered",
|
||||
ExtendedErrorCodeProhibited: "Prohibited",
|
||||
ExtendedErrorCodeStaleNXDOMAINAnswer: "Stale NXDOMAIN Answer",
|
||||
ExtendedErrorCodeNotAuthoritative: "Not Authoritative",
|
||||
ExtendedErrorCodeNotSupported: "Not Supported",
|
||||
ExtendedErrorCodeNoReachableAuthority: "No Reachable Authority",
|
||||
ExtendedErrorCodeNetworkError: "Network Error",
|
||||
ExtendedErrorCodeInvalidData: "Invalid Data",
|
||||
ExtendedErrorCodeOther: "Other",
|
||||
ExtendedErrorCodeUnsupportedDNSKEYAlgorithm: "Unsupported DNSKEY Algorithm",
|
||||
ExtendedErrorCodeUnsupportedDSDigestType: "Unsupported DS Digest Type",
|
||||
ExtendedErrorCodeStaleAnswer: "Stale Answer",
|
||||
ExtendedErrorCodeForgedAnswer: "Forged Answer",
|
||||
ExtendedErrorCodeDNSSECIndeterminate: "DNSSEC Indeterminate",
|
||||
ExtendedErrorCodeDNSBogus: "DNSSEC Bogus",
|
||||
ExtendedErrorCodeSignatureExpired: "Signature Expired",
|
||||
ExtendedErrorCodeSignatureNotYetValid: "Signature Not Yet Valid",
|
||||
ExtendedErrorCodeDNSKEYMissing: "DNSKEY Missing",
|
||||
ExtendedErrorCodeRRSIGsMissing: "RRSIGs Missing",
|
||||
ExtendedErrorCodeNoZoneKeyBitSet: "No Zone Key Bit Set",
|
||||
ExtendedErrorCodeNSECMissing: "NSEC Missing",
|
||||
ExtendedErrorCodeCachedError: "Cached Error",
|
||||
ExtendedErrorCodeNotReady: "Not Ready",
|
||||
ExtendedErrorCodeBlocked: "Blocked",
|
||||
ExtendedErrorCodeCensored: "Censored",
|
||||
ExtendedErrorCodeFiltered: "Filtered",
|
||||
ExtendedErrorCodeProhibited: "Prohibited",
|
||||
ExtendedErrorCodeStaleNXDOMAINAnswer: "Stale NXDOMAIN Answer",
|
||||
ExtendedErrorCodeNotAuthoritative: "Not Authoritative",
|
||||
ExtendedErrorCodeNotSupported: "Not Supported",
|
||||
ExtendedErrorCodeNoReachableAuthority: "No Reachable Authority",
|
||||
ExtendedErrorCodeNetworkError: "Network Error",
|
||||
ExtendedErrorCodeInvalidData: "Invalid Data",
|
||||
ExtendedErrorCodeSignatureExpiredBeforeValid: "Signature Expired Before Valid",
|
||||
ExtendedErrorCodeTooEarly: "Too Early",
|
||||
ExtendedErrorCodeUnsupportedNSEC3IterValue: "Unsupported NSEC3 Iterations Value",
|
||||
ExtendedErrorCodeUnableToConformToPolicy: "Unable To Conform To Policy",
|
||||
ExtendedErrorCodeSynthesized: "Synthesized",
|
||||
ExtendedErrorCodeInvalidQueryType: "Invalid Query Type",
|
||||
}
|
||||
|
||||
// StringToExtendedErrorCode is a map from human readable descriptions to
|
||||
|
|
|
|||
|
|
@ -714,7 +714,7 @@ func (h *MsgHdr) String() string {
|
|||
return s
|
||||
}
|
||||
|
||||
// Pack packs a Msg: it is converted to to wire format.
|
||||
// Pack packs a Msg: it is converted to wire format.
|
||||
// If the dns.Compress is true the message will be in compressed wire format.
|
||||
func (dns *Msg) Pack() (msg []byte, err error) {
|
||||
return dns.PackBuffer(nil)
|
||||
|
|
|
|||
|
|
@ -101,12 +101,13 @@ type ttlState struct {
|
|||
isByDirective bool // isByDirective indicates whether ttl was set by a $TTL directive
|
||||
}
|
||||
|
||||
// NewRR reads the RR contained in the string s. Only the first RR is returned.
|
||||
// NewRR reads a string s and returns the first RR.
|
||||
// If s contains no records, NewRR will return nil with no error.
|
||||
//
|
||||
// The class defaults to IN and TTL defaults to 3600. The full zone file syntax
|
||||
// like $TTL, $ORIGIN, etc. is supported. All fields of the returned RR are
|
||||
// set, except RR.Header().Rdlength which is set to 0.
|
||||
// The class defaults to IN, TTL defaults to 3600, and
|
||||
// origin for resolving relative domain names defaults to the DNS root (.).
|
||||
// Full zone file syntax is supported, including directives like $TTL and $ORIGIN.
|
||||
// All fields of the returned RR are set from the read data, except RR.Header().Rdlength which is set to 0.
|
||||
func NewRR(s string) (RR, error) {
|
||||
if len(s) > 0 && s[len(s)-1] != '\n' { // We need a closing newline
|
||||
return ReadRR(strings.NewReader(s+"\n"), "")
|
||||
|
|
@ -1282,7 +1283,7 @@ func stringToCm(token string) (e, m uint8, ok bool) {
|
|||
cmeters *= 10
|
||||
}
|
||||
}
|
||||
// This slighly ugly condition will allow omitting the 'meter' part, like .01 (meaning 0.01m = 1cm).
|
||||
// This slightly ugly condition will allow omitting the 'meter' part, like .01 (meaning 0.01m = 1cm).
|
||||
if !hasCM || mStr != "" {
|
||||
meters, err = strconv.Atoi(mStr)
|
||||
// RFC1876 states the max value is 90000000.00. The latter two conditions enforce it.
|
||||
|
|
|
|||
|
|
@ -51,25 +51,24 @@ func endingToTxtSlice(c *zlexer, errstr string) ([]string, *ParseError) {
|
|||
switch l.value {
|
||||
case zString:
|
||||
empty = false
|
||||
if len(l.token) > 255 {
|
||||
// split up tokens that are larger than 255 into 255-chunks
|
||||
sx := []string{}
|
||||
p, i := 0, 255
|
||||
for {
|
||||
if i <= len(l.token) {
|
||||
sx = append(sx, l.token[p:i])
|
||||
} else {
|
||||
sx = append(sx, l.token[p:])
|
||||
break
|
||||
|
||||
}
|
||||
p, i = p+255, i+255
|
||||
// split up tokens that are larger than 255 into 255-chunks
|
||||
sx := []string{}
|
||||
p := 0
|
||||
for {
|
||||
i, ok := escapedStringOffset(l.token[p:], 255)
|
||||
if !ok {
|
||||
return nil, &ParseError{err: errstr, lex: l}
|
||||
}
|
||||
s = append(s, sx...)
|
||||
break
|
||||
}
|
||||
if i != -1 && p+i != len(l.token) {
|
||||
sx = append(sx, l.token[p:p+i])
|
||||
} else {
|
||||
sx = append(sx, l.token[p:])
|
||||
break
|
||||
|
||||
s = append(s, l.token)
|
||||
}
|
||||
p += i
|
||||
}
|
||||
s = append(s, sx...)
|
||||
case zBlank:
|
||||
if quote {
|
||||
// zBlank can only be seen in between txt parts.
|
||||
|
|
@ -1920,3 +1919,39 @@ func (rr *APL) parse(c *zlexer, o string) *ParseError {
|
|||
rr.Prefixes = prefixes
|
||||
return nil
|
||||
}
|
||||
|
||||
// escapedStringOffset finds the offset within a string (which may contain escape
|
||||
// sequences) that corresponds to a certain byte offset. If the input offset is
|
||||
// out of bounds, -1 is returned (which is *not* considered an error).
|
||||
func escapedStringOffset(s string, desiredByteOffset int) (int, bool) {
|
||||
if desiredByteOffset == 0 {
|
||||
return 0, true
|
||||
}
|
||||
|
||||
currentByteOffset, i := 0, 0
|
||||
|
||||
for i < len(s) {
|
||||
currentByteOffset += 1
|
||||
|
||||
// Skip escape sequences
|
||||
if s[i] != '\\' {
|
||||
// Single plain byte, not an escape sequence.
|
||||
i++
|
||||
} else if isDDD(s[i+1:]) {
|
||||
// Skip backslash and DDD.
|
||||
i += 4
|
||||
} else if len(s[i+1:]) < 1 {
|
||||
// No character following the backslash; that's an error.
|
||||
return 0, false
|
||||
} else {
|
||||
// Skip backslash and following byte.
|
||||
i += 2
|
||||
}
|
||||
|
||||
if currentByteOffset >= desiredByteOffset {
|
||||
return i, true
|
||||
}
|
||||
}
|
||||
|
||||
return -1, true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -188,6 +188,14 @@ type DecorateReader func(Reader) Reader
|
|||
// Implementations should never return a nil Writer.
|
||||
type DecorateWriter func(Writer) Writer
|
||||
|
||||
// MsgInvalidFunc is a listener hook for observing incoming messages that were discarded
|
||||
// because they could not be parsed.
|
||||
// Every message that is read by a Reader will eventually be provided to the Handler,
|
||||
// rejected (or ignored) by the MsgAcceptFunc, or passed to this function.
|
||||
type MsgInvalidFunc func(m []byte, err error)
|
||||
|
||||
func DefaultMsgInvalidFunc(m []byte, err error) {}
|
||||
|
||||
// A Server defines parameters for running an DNS server.
|
||||
type Server struct {
|
||||
// Address to listen on, ":dns" if empty.
|
||||
|
|
@ -233,6 +241,8 @@ type Server struct {
|
|||
// AcceptMsgFunc will check the incoming message and will reject it early in the process.
|
||||
// By default DefaultMsgAcceptFunc will be used.
|
||||
MsgAcceptFunc MsgAcceptFunc
|
||||
// MsgInvalidFunc is optional, will be called if a message is received but cannot be parsed.
|
||||
MsgInvalidFunc MsgInvalidFunc
|
||||
|
||||
// Shutdown handling
|
||||
lock sync.RWMutex
|
||||
|
|
@ -277,6 +287,9 @@ func (srv *Server) init() {
|
|||
if srv.MsgAcceptFunc == nil {
|
||||
srv.MsgAcceptFunc = DefaultMsgAcceptFunc
|
||||
}
|
||||
if srv.MsgInvalidFunc == nil {
|
||||
srv.MsgInvalidFunc = DefaultMsgInvalidFunc
|
||||
}
|
||||
if srv.Handler == nil {
|
||||
srv.Handler = DefaultServeMux
|
||||
}
|
||||
|
|
@ -531,6 +544,7 @@ func (srv *Server) serveUDP(l net.PacketConn) error {
|
|||
if cap(m) == srv.UDPSize {
|
||||
srv.udpPool.Put(m[:srv.UDPSize])
|
||||
}
|
||||
srv.MsgInvalidFunc(m, ErrShortRead)
|
||||
continue
|
||||
}
|
||||
wg.Add(1)
|
||||
|
|
@ -611,6 +625,7 @@ func (srv *Server) serveUDPPacket(wg *sync.WaitGroup, m []byte, u net.PacketConn
|
|||
func (srv *Server) serveDNS(m []byte, w *response) {
|
||||
dh, off, err := unpackMsgHdr(m, 0)
|
||||
if err != nil {
|
||||
srv.MsgInvalidFunc(m, err)
|
||||
// Let client hang, they are sending crap; any reply can be used to amplify.
|
||||
return
|
||||
}
|
||||
|
|
@ -620,10 +635,12 @@ func (srv *Server) serveDNS(m []byte, w *response) {
|
|||
|
||||
switch action := srv.MsgAcceptFunc(dh); action {
|
||||
case MsgAccept:
|
||||
if req.unpack(dh, m, off) == nil {
|
||||
err := req.unpack(dh, m, off)
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
|
||||
srv.MsgInvalidFunc(m, err)
|
||||
fallthrough
|
||||
case MsgReject, MsgRejectNotImplemented:
|
||||
opcode := req.Opcode
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import (
|
|||
// SVCBKey is the type of the keys used in the SVCB RR.
|
||||
type SVCBKey uint16
|
||||
|
||||
// Keys defined in draft-ietf-dnsop-svcb-https-08 Section 14.3.2.
|
||||
// Keys defined in rfc9460
|
||||
const (
|
||||
SVCB_MANDATORY SVCBKey = iota
|
||||
SVCB_ALPN
|
||||
|
|
@ -23,7 +23,8 @@ const (
|
|||
SVCB_IPV4HINT
|
||||
SVCB_ECHCONFIG
|
||||
SVCB_IPV6HINT
|
||||
SVCB_DOHPATH // draft-ietf-add-svcb-dns-02 Section 9
|
||||
SVCB_DOHPATH // rfc9461 Section 5
|
||||
SVCB_OHTTP // rfc9540 Section 8
|
||||
|
||||
svcb_RESERVED SVCBKey = 65535
|
||||
)
|
||||
|
|
@ -37,6 +38,7 @@ var svcbKeyToStringMap = map[SVCBKey]string{
|
|||
SVCB_ECHCONFIG: "ech",
|
||||
SVCB_IPV6HINT: "ipv6hint",
|
||||
SVCB_DOHPATH: "dohpath",
|
||||
SVCB_OHTTP: "ohttp",
|
||||
}
|
||||
|
||||
var svcbStringToKeyMap = reverseSVCBKeyMap(svcbKeyToStringMap)
|
||||
|
|
@ -201,6 +203,8 @@ func makeSVCBKeyValue(key SVCBKey) SVCBKeyValue {
|
|||
return new(SVCBIPv6Hint)
|
||||
case SVCB_DOHPATH:
|
||||
return new(SVCBDoHPath)
|
||||
case SVCB_OHTTP:
|
||||
return new(SVCBOhttp)
|
||||
case svcb_RESERVED:
|
||||
return nil
|
||||
default:
|
||||
|
|
@ -771,8 +775,8 @@ func (s *SVCBIPv6Hint) copy() SVCBKeyValue {
|
|||
// SVCBDoHPath pair is used to indicate the URI template that the
|
||||
// clients may use to construct a DNS over HTTPS URI.
|
||||
//
|
||||
// See RFC xxxx (https://datatracker.ietf.org/doc/html/draft-ietf-add-svcb-dns-02)
|
||||
// and RFC yyyy (https://datatracker.ietf.org/doc/html/draft-ietf-add-ddr-06).
|
||||
// See RFC 9461 (https://datatracker.ietf.org/doc/html/rfc9461)
|
||||
// and RFC 9462 (https://datatracker.ietf.org/doc/html/rfc9462).
|
||||
//
|
||||
// A basic example of using the dohpath option together with the alpn
|
||||
// option to indicate support for DNS over HTTPS on a certain path:
|
||||
|
|
@ -816,6 +820,44 @@ func (s *SVCBDoHPath) copy() SVCBKeyValue {
|
|||
}
|
||||
}
|
||||
|
||||
// The "ohttp" SvcParamKey is used to indicate that a service described in a SVCB RR
|
||||
// can be accessed as a target using an associated gateway.
|
||||
// Both the presentation and wire-format values for the "ohttp" parameter MUST be empty.
|
||||
//
|
||||
// See RFC 9460 (https://datatracker.ietf.org/doc/html/rfc9460/)
|
||||
// and RFC 9230 (https://datatracker.ietf.org/doc/html/rfc9230/)
|
||||
//
|
||||
// A basic example of using the dohpath option together with the alpn
|
||||
// option to indicate support for DNS over HTTPS on a certain path:
|
||||
//
|
||||
// s := new(dns.SVCB)
|
||||
// s.Hdr = dns.RR_Header{Name: ".", Rrtype: dns.TypeSVCB, Class: dns.ClassINET}
|
||||
// e := new(dns.SVCBAlpn)
|
||||
// e.Alpn = []string{"h2", "h3"}
|
||||
// p := new(dns.SVCBOhttp)
|
||||
// s.Value = append(s.Value, e, p)
|
||||
type SVCBOhttp struct{}
|
||||
|
||||
func (*SVCBOhttp) Key() SVCBKey { return SVCB_OHTTP }
|
||||
func (*SVCBOhttp) copy() SVCBKeyValue { return &SVCBOhttp{} }
|
||||
func (*SVCBOhttp) pack() ([]byte, error) { return []byte{}, nil }
|
||||
func (*SVCBOhttp) String() string { return "" }
|
||||
func (*SVCBOhttp) len() int { return 0 }
|
||||
|
||||
func (*SVCBOhttp) unpack(b []byte) error {
|
||||
if len(b) != 0 {
|
||||
return errors.New("dns: svcbotthp: svcbotthp must have no value")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (*SVCBOhttp) parse(b string) error {
|
||||
if b != "" {
|
||||
return errors.New("dns: svcbotthp: svcbotthp must have no value")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SVCBLocal pair is intended for experimental/private use. The key is recommended
|
||||
// to be in the range [SVCB_PRIVATE_LOWER, SVCB_PRIVATE_UPPER].
|
||||
// Basic use pattern for creating a keyNNNNN option:
|
||||
|
|
|
|||
|
|
@ -96,6 +96,7 @@ const (
|
|||
TypeLP uint16 = 107
|
||||
TypeEUI48 uint16 = 108
|
||||
TypeEUI64 uint16 = 109
|
||||
TypeNXNAME uint16 = 128
|
||||
TypeURI uint16 = 256
|
||||
TypeCAA uint16 = 257
|
||||
TypeAVC uint16 = 258
|
||||
|
|
@ -294,6 +295,19 @@ func (*NULL) parse(c *zlexer, origin string) *ParseError {
|
|||
return &ParseError{err: "NULL records do not have a presentation format"}
|
||||
}
|
||||
|
||||
// NXNAME is a meta record. See https://www.iana.org/go/draft-ietf-dnsop-compact-denial-of-existence-04
|
||||
// Reference: https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml
|
||||
type NXNAME struct {
|
||||
Hdr RR_Header
|
||||
// Does not have any rdata
|
||||
}
|
||||
|
||||
func (rr *NXNAME) String() string { return rr.Hdr.String() }
|
||||
|
||||
func (*NXNAME) parse(c *zlexer, origin string) *ParseError {
|
||||
return &ParseError{err: "NXNAME records do not have a presentation format"}
|
||||
}
|
||||
|
||||
// CNAME RR. See RFC 1034.
|
||||
type CNAME struct {
|
||||
Hdr RR_Header
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ package dns
|
|||
import "fmt"
|
||||
|
||||
// Version is current version of this library.
|
||||
var Version = v{1, 1, 58}
|
||||
var Version = v{1, 1, 62}
|
||||
|
||||
// v holds the version of this library.
|
||||
type v struct {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package dns
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
|
@ -20,6 +21,7 @@ type Transfer struct {
|
|||
TsigProvider TsigProvider // An implementation of the TsigProvider interface. If defined it replaces TsigSecret and is used for all TSIG operations.
|
||||
TsigSecret map[string]string // Secret(s) for Tsig map[<zonename>]<base64 secret>, zonename must be in canonical form (lowercase, fqdn, see RFC 4034 Section 6.2)
|
||||
tsigTimersOnly bool
|
||||
TLS *tls.Config // TLS config. If Xfr over TLS will be attempted
|
||||
}
|
||||
|
||||
func (t *Transfer) tsigProvider() TsigProvider {
|
||||
|
|
@ -57,7 +59,11 @@ func (t *Transfer) In(q *Msg, a string) (env chan *Envelope, err error) {
|
|||
}
|
||||
|
||||
if t.Conn == nil {
|
||||
t.Conn, err = DialTimeout("tcp", a, timeout)
|
||||
if t.TLS != nil {
|
||||
t.Conn, err = DialTimeoutWithTLS("tcp-tls", a, t.TLS, timeout)
|
||||
} else {
|
||||
t.Conn, err = DialTimeout("tcp", a, timeout)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -182,7 +188,7 @@ func (t *Transfer) inIxfr(q *Msg, c chan *Envelope) {
|
|||
if v, ok := rr.(*SOA); ok {
|
||||
if v.Serial == serial {
|
||||
n++
|
||||
// quit if it's a full axfr or the the servers' SOA is repeated the third time
|
||||
// quit if it's a full axfr or the servers' SOA is repeated the third time
|
||||
if axfr && n == 2 || n == 3 {
|
||||
c <- &Envelope{in.Answer, nil}
|
||||
return
|
||||
|
|
@ -203,6 +209,7 @@ func (t *Transfer) inIxfr(q *Msg, c chan *Envelope) {
|
|||
// ch := make(chan *dns.Envelope)
|
||||
// tr := new(dns.Transfer)
|
||||
// var wg sync.WaitGroup
|
||||
// wg.Add(1)
|
||||
// go func() {
|
||||
// tr.Out(w, r, ch)
|
||||
// wg.Done()
|
||||
|
|
|
|||
|
|
@ -886,6 +886,15 @@ func (r1 *NULL) isDuplicate(_r2 RR) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
func (r1 *NXNAME) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*NXNAME)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
_ = r2
|
||||
return true
|
||||
}
|
||||
|
||||
func (r1 *NXT) isDuplicate(_r2 RR) bool {
|
||||
r2, ok := _r2.(*NXT)
|
||||
if !ok {
|
||||
|
|
|
|||
|
|
@ -706,6 +706,10 @@ func (rr *NULL) pack(msg []byte, off int, compression compressionMap, compress b
|
|||
return off, nil
|
||||
}
|
||||
|
||||
func (rr *NXNAME) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
|
||||
return off, nil
|
||||
}
|
||||
|
||||
func (rr *NXT) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
|
||||
off, err = packDomainName(rr.NextDomain, msg, off, compression, false)
|
||||
if err != nil {
|
||||
|
|
@ -2266,6 +2270,13 @@ func (rr *NULL) unpack(msg []byte, off int) (off1 int, err error) {
|
|||
return off, nil
|
||||
}
|
||||
|
||||
func (rr *NXNAME) unpack(msg []byte, off int) (off1 int, err error) {
|
||||
rdStart := off
|
||||
_ = rdStart
|
||||
|
||||
return off, nil
|
||||
}
|
||||
|
||||
func (rr *NXT) unpack(msg []byte, off int) (off1 int, err error) {
|
||||
rdStart := off
|
||||
_ = rdStart
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ var TypeToRR = map[uint16]func() RR{
|
|||
TypeNSEC3: func() RR { return new(NSEC3) },
|
||||
TypeNSEC3PARAM: func() RR { return new(NSEC3PARAM) },
|
||||
TypeNULL: func() RR { return new(NULL) },
|
||||
TypeNXNAME: func() RR { return new(NXNAME) },
|
||||
TypeNXT: func() RR { return new(NXT) },
|
||||
TypeOPENPGPKEY: func() RR { return new(OPENPGPKEY) },
|
||||
TypeOPT: func() RR { return new(OPT) },
|
||||
|
|
@ -146,6 +147,7 @@ var TypeToString = map[uint16]string{
|
|||
TypeNSEC3: "NSEC3",
|
||||
TypeNSEC3PARAM: "NSEC3PARAM",
|
||||
TypeNULL: "NULL",
|
||||
TypeNXNAME: "NXNAME",
|
||||
TypeNXT: "NXT",
|
||||
TypeNone: "None",
|
||||
TypeOPENPGPKEY: "OPENPGPKEY",
|
||||
|
|
@ -230,6 +232,7 @@ func (rr *NSEC) Header() *RR_Header { return &rr.Hdr }
|
|||
func (rr *NSEC3) Header() *RR_Header { return &rr.Hdr }
|
||||
func (rr *NSEC3PARAM) Header() *RR_Header { return &rr.Hdr }
|
||||
func (rr *NULL) Header() *RR_Header { return &rr.Hdr }
|
||||
func (rr *NXNAME) Header() *RR_Header { return &rr.Hdr }
|
||||
func (rr *NXT) Header() *RR_Header { return &rr.Hdr }
|
||||
func (rr *OPENPGPKEY) Header() *RR_Header { return &rr.Hdr }
|
||||
func (rr *OPT) Header() *RR_Header { return &rr.Hdr }
|
||||
|
|
@ -594,6 +597,11 @@ func (rr *NULL) len(off int, compression map[string]struct{}) int {
|
|||
return l
|
||||
}
|
||||
|
||||
func (rr *NXNAME) len(off int, compression map[string]struct{}) int {
|
||||
l := rr.Hdr.len(off, compression)
|
||||
return l
|
||||
}
|
||||
|
||||
func (rr *OPENPGPKEY) len(off int, compression map[string]struct{}) int {
|
||||
l := rr.Hdr.len(off, compression)
|
||||
l += base64.StdEncoding.DecodedLen(len(rr.PublicKey))
|
||||
|
|
@ -1107,6 +1115,10 @@ func (rr *NULL) copy() RR {
|
|||
return &NULL{rr.Hdr, rr.Data}
|
||||
}
|
||||
|
||||
func (rr *NXNAME) copy() RR {
|
||||
return &NXNAME{rr.Hdr}
|
||||
}
|
||||
|
||||
func (rr *NXT) copy() RR {
|
||||
return &NXT{*rr.NSEC.copy().(*NSEC)}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
Copyright (c) 2009 The Go Authors. All rights reserved.
|
||||
Copyright 2009 The Go Authors.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
|
|
@ -10,7 +10,7 @@ notice, this list of conditions and the following disclaimer.
|
|||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
* Neither the name of Google LLC nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
|
|
|
|||
|
|
@ -4,27 +4,27 @@
|
|||
package socket
|
||||
|
||||
type iovec struct {
|
||||
Base *byte
|
||||
Len uint64
|
||||
Base *byte
|
||||
Len uint64
|
||||
}
|
||||
|
||||
type msghdr struct {
|
||||
Name *byte
|
||||
Namelen uint32
|
||||
Iov *iovec
|
||||
Iovlen uint32
|
||||
Control *byte
|
||||
Controllen uint32
|
||||
Flags int32
|
||||
Name *byte
|
||||
Namelen uint32
|
||||
Iov *iovec
|
||||
Iovlen uint32
|
||||
Control *byte
|
||||
Controllen uint32
|
||||
Flags int32
|
||||
}
|
||||
|
||||
type cmsghdr struct {
|
||||
Len uint32
|
||||
Level int32
|
||||
Type int32
|
||||
Len uint32
|
||||
Level int32
|
||||
Type int32
|
||||
}
|
||||
|
||||
const (
|
||||
sizeofIovec = 0x10
|
||||
sizeofMsghdr = 0x30
|
||||
sizeofIovec = 0x10
|
||||
sizeofMsghdr = 0x30
|
||||
)
|
||||
|
|
|
|||
|
|
@ -4,27 +4,27 @@
|
|||
package socket
|
||||
|
||||
type iovec struct {
|
||||
Base *byte
|
||||
Len uint64
|
||||
Base *byte
|
||||
Len uint64
|
||||
}
|
||||
|
||||
type msghdr struct {
|
||||
Name *byte
|
||||
Namelen uint32
|
||||
Iov *iovec
|
||||
Iovlen uint32
|
||||
Control *byte
|
||||
Controllen uint32
|
||||
Flags int32
|
||||
Name *byte
|
||||
Namelen uint32
|
||||
Iov *iovec
|
||||
Iovlen uint32
|
||||
Control *byte
|
||||
Controllen uint32
|
||||
Flags int32
|
||||
}
|
||||
|
||||
type cmsghdr struct {
|
||||
Len uint32
|
||||
Level int32
|
||||
Type int32
|
||||
Len uint32
|
||||
Level int32
|
||||
Type int32
|
||||
}
|
||||
|
||||
const (
|
||||
sizeofIovec = 0x10
|
||||
sizeofMsghdr = 0x30
|
||||
sizeofIovec = 0x10
|
||||
sizeofMsghdr = 0x30
|
||||
)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,27 @@
|
|||
Copyright 2009 The Go Authors.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Google LLC nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
Additional IP Rights Grant (Patents)
|
||||
|
||||
"This implementation" means the copyrightable works distributed by
|
||||
Google as part of the Go project.
|
||||
|
||||
Google hereby grants to You a perpetual, worldwide, non-exclusive,
|
||||
no-charge, royalty-free, irrevocable (except as stated in this section)
|
||||
patent license to make, have made, use, offer to sell, sell, import,
|
||||
transfer and otherwise run, modify and propagate the contents of this
|
||||
implementation of Go, where such license applies only to those patent
|
||||
claims, both currently owned or controlled by Google and acquired in
|
||||
the future, licensable by Google that are necessarily infringed by this
|
||||
implementation of Go. This grant does not include claims that would be
|
||||
infringed only as a consequence of further modification of this
|
||||
implementation. If you or your agent or exclusive licensee institute or
|
||||
order or agree to the institution of patent litigation against any
|
||||
entity (including a cross-claim or counterclaim in a lawsuit) alleging
|
||||
that this implementation of Go or any code incorporated within this
|
||||
implementation of Go constitutes direct or contributory patent
|
||||
infringement, or inducement of patent infringement, then any patent
|
||||
rights granted to you under this License for this implementation of Go
|
||||
shall terminate as of the date such litigation is filed.
|
||||
|
|
@ -0,0 +1,135 @@
|
|||
// 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.
|
||||
|
||||
// Package errgroup provides synchronization, error propagation, and Context
|
||||
// cancelation for groups of goroutines working on subtasks of a common task.
|
||||
//
|
||||
// [errgroup.Group] is related to [sync.WaitGroup] but adds handling of tasks
|
||||
// returning errors.
|
||||
package errgroup
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type token struct{}
|
||||
|
||||
// A Group is a collection of goroutines working on subtasks that are part of
|
||||
// the same overall task.
|
||||
//
|
||||
// A zero Group is valid, has no limit on the number of active goroutines,
|
||||
// and does not cancel on error.
|
||||
type Group struct {
|
||||
cancel func(error)
|
||||
|
||||
wg sync.WaitGroup
|
||||
|
||||
sem chan token
|
||||
|
||||
errOnce sync.Once
|
||||
err error
|
||||
}
|
||||
|
||||
func (g *Group) done() {
|
||||
if g.sem != nil {
|
||||
<-g.sem
|
||||
}
|
||||
g.wg.Done()
|
||||
}
|
||||
|
||||
// WithContext returns a new Group and an associated Context derived from ctx.
|
||||
//
|
||||
// The derived Context is canceled the first time a function passed to Go
|
||||
// returns a non-nil error or the first time Wait returns, whichever occurs
|
||||
// first.
|
||||
func WithContext(ctx context.Context) (*Group, context.Context) {
|
||||
ctx, cancel := withCancelCause(ctx)
|
||||
return &Group{cancel: cancel}, ctx
|
||||
}
|
||||
|
||||
// Wait blocks until all function calls from the Go method have returned, then
|
||||
// returns the first non-nil error (if any) from them.
|
||||
func (g *Group) Wait() error {
|
||||
g.wg.Wait()
|
||||
if g.cancel != nil {
|
||||
g.cancel(g.err)
|
||||
}
|
||||
return g.err
|
||||
}
|
||||
|
||||
// Go calls the given function in a new goroutine.
|
||||
// It blocks until the new goroutine can be added without the number of
|
||||
// active goroutines in the group exceeding the configured limit.
|
||||
//
|
||||
// The first call to return a non-nil error cancels the group's context, if the
|
||||
// group was created by calling WithContext. The error will be returned by Wait.
|
||||
func (g *Group) Go(f func() error) {
|
||||
if g.sem != nil {
|
||||
g.sem <- token{}
|
||||
}
|
||||
|
||||
g.wg.Add(1)
|
||||
go func() {
|
||||
defer g.done()
|
||||
|
||||
if err := f(); err != nil {
|
||||
g.errOnce.Do(func() {
|
||||
g.err = err
|
||||
if g.cancel != nil {
|
||||
g.cancel(g.err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
// TryGo calls the given function in a new goroutine only if the number of
|
||||
// active goroutines in the group is currently below the configured limit.
|
||||
//
|
||||
// The return value reports whether the goroutine was started.
|
||||
func (g *Group) TryGo(f func() error) bool {
|
||||
if g.sem != nil {
|
||||
select {
|
||||
case g.sem <- token{}:
|
||||
// Note: this allows barging iff channels in general allow barging.
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
g.wg.Add(1)
|
||||
go func() {
|
||||
defer g.done()
|
||||
|
||||
if err := f(); err != nil {
|
||||
g.errOnce.Do(func() {
|
||||
g.err = err
|
||||
if g.cancel != nil {
|
||||
g.cancel(g.err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}()
|
||||
return true
|
||||
}
|
||||
|
||||
// SetLimit limits the number of active goroutines in this group to at most n.
|
||||
// A negative value indicates no limit.
|
||||
//
|
||||
// Any subsequent call to the Go method will block until it can add an active
|
||||
// goroutine without exceeding the configured limit.
|
||||
//
|
||||
// The limit must not be modified while any goroutines in the group are active.
|
||||
func (g *Group) SetLimit(n int) {
|
||||
if n < 0 {
|
||||
g.sem = nil
|
||||
return
|
||||
}
|
||||
if len(g.sem) != 0 {
|
||||
panic(fmt.Errorf("errgroup: modify limit while %v goroutines in the group are still active", len(g.sem)))
|
||||
}
|
||||
g.sem = make(chan token, n)
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
// Copyright 2023 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build go1.20
|
||||
|
||||
package errgroup
|
||||
|
||||
import "context"
|
||||
|
||||
func withCancelCause(parent context.Context) (context.Context, func(error)) {
|
||||
return context.WithCancelCause(parent)
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
// Copyright 2023 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !go1.20
|
||||
|
||||
package errgroup
|
||||
|
||||
import "context"
|
||||
|
||||
func withCancelCause(parent context.Context) (context.Context, func(error)) {
|
||||
ctx, cancel := context.WithCancel(parent)
|
||||
return ctx, func(error) { cancel() }
|
||||
}
|
||||
|
|
@ -156,7 +156,7 @@ 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.
|
||||
1. Construct the set of common code that is identical in all architecture-specific files.
|
||||
2. Write this common code to the merged file.
|
||||
3. Remove the common code from all architecture-specific files.
|
||||
|
||||
|
|
|
|||
|
|
@ -58,6 +58,102 @@ func IoctlGetEthtoolDrvinfo(fd int, ifname string) (*EthtoolDrvinfo, error) {
|
|||
return &value, err
|
||||
}
|
||||
|
||||
// IoctlGetEthtoolTsInfo fetches ethtool timestamping and PHC
|
||||
// association for the network device specified by ifname.
|
||||
func IoctlGetEthtoolTsInfo(fd int, ifname string) (*EthtoolTsInfo, error) {
|
||||
ifr, err := NewIfreq(ifname)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
value := EthtoolTsInfo{Cmd: ETHTOOL_GET_TS_INFO}
|
||||
ifrd := ifr.withData(unsafe.Pointer(&value))
|
||||
|
||||
err = ioctlIfreqData(fd, SIOCETHTOOL, &ifrd)
|
||||
return &value, err
|
||||
}
|
||||
|
||||
// IoctlGetHwTstamp retrieves the hardware timestamping configuration
|
||||
// for the network device specified by ifname.
|
||||
func IoctlGetHwTstamp(fd int, ifname string) (*HwTstampConfig, error) {
|
||||
ifr, err := NewIfreq(ifname)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
value := HwTstampConfig{}
|
||||
ifrd := ifr.withData(unsafe.Pointer(&value))
|
||||
|
||||
err = ioctlIfreqData(fd, SIOCGHWTSTAMP, &ifrd)
|
||||
return &value, err
|
||||
}
|
||||
|
||||
// IoctlSetHwTstamp updates the hardware timestamping configuration for
|
||||
// the network device specified by ifname.
|
||||
func IoctlSetHwTstamp(fd int, ifname string, cfg *HwTstampConfig) error {
|
||||
ifr, err := NewIfreq(ifname)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ifrd := ifr.withData(unsafe.Pointer(cfg))
|
||||
return ioctlIfreqData(fd, SIOCSHWTSTAMP, &ifrd)
|
||||
}
|
||||
|
||||
// FdToClockID derives the clock ID from the file descriptor number
|
||||
// - see clock_gettime(3), FD_TO_CLOCKID macros. The resulting ID is
|
||||
// suitable for system calls like ClockGettime.
|
||||
func FdToClockID(fd int) int32 { return int32((int(^fd) << 3) | 3) }
|
||||
|
||||
// IoctlPtpClockGetcaps returns the description of a given PTP device.
|
||||
func IoctlPtpClockGetcaps(fd int) (*PtpClockCaps, error) {
|
||||
var value PtpClockCaps
|
||||
err := ioctlPtr(fd, PTP_CLOCK_GETCAPS2, unsafe.Pointer(&value))
|
||||
return &value, err
|
||||
}
|
||||
|
||||
// IoctlPtpSysOffsetPrecise returns a description of the clock
|
||||
// offset compared to the system clock.
|
||||
func IoctlPtpSysOffsetPrecise(fd int) (*PtpSysOffsetPrecise, error) {
|
||||
var value PtpSysOffsetPrecise
|
||||
err := ioctlPtr(fd, PTP_SYS_OFFSET_PRECISE2, unsafe.Pointer(&value))
|
||||
return &value, err
|
||||
}
|
||||
|
||||
// IoctlPtpSysOffsetExtended returns an extended description of the
|
||||
// clock offset compared to the system clock. The samples parameter
|
||||
// specifies the desired number of measurements.
|
||||
func IoctlPtpSysOffsetExtended(fd int, samples uint) (*PtpSysOffsetExtended, error) {
|
||||
value := PtpSysOffsetExtended{Samples: uint32(samples)}
|
||||
err := ioctlPtr(fd, PTP_SYS_OFFSET_EXTENDED2, unsafe.Pointer(&value))
|
||||
return &value, err
|
||||
}
|
||||
|
||||
// IoctlPtpPinGetfunc returns the configuration of the specified
|
||||
// I/O pin on given PTP device.
|
||||
func IoctlPtpPinGetfunc(fd int, index uint) (*PtpPinDesc, error) {
|
||||
value := PtpPinDesc{Index: uint32(index)}
|
||||
err := ioctlPtr(fd, PTP_PIN_GETFUNC2, unsafe.Pointer(&value))
|
||||
return &value, err
|
||||
}
|
||||
|
||||
// IoctlPtpPinSetfunc updates configuration of the specified PTP
|
||||
// I/O pin.
|
||||
func IoctlPtpPinSetfunc(fd int, pd *PtpPinDesc) error {
|
||||
return ioctlPtr(fd, PTP_PIN_SETFUNC2, unsafe.Pointer(pd))
|
||||
}
|
||||
|
||||
// IoctlPtpPeroutRequest configures the periodic output mode of the
|
||||
// PTP I/O pins.
|
||||
func IoctlPtpPeroutRequest(fd int, r *PtpPeroutRequest) error {
|
||||
return ioctlPtr(fd, PTP_PEROUT_REQUEST2, unsafe.Pointer(r))
|
||||
}
|
||||
|
||||
// IoctlPtpExttsRequest configures the external timestamping mode
|
||||
// of the PTP I/O pins.
|
||||
func IoctlPtpExttsRequest(fd int, r *PtpExttsRequest) error {
|
||||
return ioctlPtr(fd, PTP_EXTTS_REQUEST2, unsafe.Pointer(r))
|
||||
}
|
||||
|
||||
// IoctlGetWatchdogInfo fetches information about a watchdog device from the
|
||||
// Linux watchdog API. For more information, see:
|
||||
// https://www.kernel.org/doc/html/latest/watchdog/watchdog-api.html.
|
||||
|
|
|
|||
|
|
@ -158,6 +158,16 @@ includes_Linux='
|
|||
#endif
|
||||
#define _GNU_SOURCE
|
||||
|
||||
// See the description in unix/linux/types.go
|
||||
#if defined(__ARM_EABI__) || \
|
||||
(defined(__mips__) && (_MIPS_SIM == _ABIO32)) || \
|
||||
(defined(__powerpc__) && (!defined(__powerpc64__)))
|
||||
# ifdef _TIME_BITS
|
||||
# undef _TIME_BITS
|
||||
# endif
|
||||
# define _TIME_BITS 32
|
||||
#endif
|
||||
|
||||
// <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__)
|
||||
|
|
@ -256,6 +266,7 @@ struct ltchars {
|
|||
#include <linux/nsfs.h>
|
||||
#include <linux/perf_event.h>
|
||||
#include <linux/pps.h>
|
||||
#include <linux/ptp_clock.h>
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/random.h>
|
||||
#include <linux/reboot.h>
|
||||
|
|
@ -527,6 +538,7 @@ ccflags="$@"
|
|||
$2 ~ /^(AF|SOCK|SO|SOL|IPPROTO|IP|IPV6|TCP|MCAST|EVFILT|NOTE|SHUT|PROT|MAP|MREMAP|MFD|T?PACKET|MSG|SCM|MCL|DT|MADV|PR|LOCAL|TCPOPT|UDP)_/ ||
|
||||
$2 ~ /^NFC_(GENL|PROTO|COMM|RF|SE|DIRECTION|LLCP|SOCKPROTO)_/ ||
|
||||
$2 ~ /^NFC_.*_(MAX)?SIZE$/ ||
|
||||
$2 ~ /^PTP_/ ||
|
||||
$2 ~ /^RAW_PAYLOAD_/ ||
|
||||
$2 ~ /^[US]F_/ ||
|
||||
$2 ~ /^TP_STATUS_/ ||
|
||||
|
|
@ -552,6 +564,7 @@ ccflags="$@"
|
|||
$2 !~ /^RTC_VL_(ACCURACY|BACKUP|DATA)/ &&
|
||||
$2 ~ /^(NETLINK|NLM|NLMSG|NLA|IFA|IFAN|RT|RTC|RTCF|RTN|RTPROT|RTNH|ARPHRD|ETH_P|NETNSA)_/ ||
|
||||
$2 ~ /^SOCK_|SK_DIAG_|SKNLGRP_$/ ||
|
||||
$2 ~ /^(CONNECT|SAE)_/ ||
|
||||
$2 ~ /^FIORDCHK$/ ||
|
||||
$2 ~ /^SIOC/ ||
|
||||
$2 ~ /^TIOC/ ||
|
||||
|
|
@ -655,7 +668,7 @@ errors=$(
|
|||
signals=$(
|
||||
echo '#include <signal.h>' | $CC -x c - -E -dM $ccflags |
|
||||
awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print $2 }' |
|
||||
grep -v 'SIGSTKSIZE\|SIGSTKSZ\|SIGRT\|SIGMAX64' |
|
||||
grep -E -v '(SIGSTKSIZE|SIGSTKSZ|SIGRT|SIGMAX64)' |
|
||||
sort
|
||||
)
|
||||
|
||||
|
|
@ -665,7 +678,7 @@ echo '#include <errno.h>' | $CC -x c - -E -dM $ccflags |
|
|||
sort >_error.grep
|
||||
echo '#include <signal.h>' | $CC -x c - -E -dM $ccflags |
|
||||
awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print "^\t" $2 "[ \t]*=" }' |
|
||||
grep -v 'SIGSTKSIZE\|SIGSTKSZ\|SIGRT\|SIGMAX64' |
|
||||
grep -E -v '(SIGSTKSIZE|SIGSTKSZ|SIGRT|SIGMAX64)' |
|
||||
sort >_signal.grep
|
||||
|
||||
echo '// mkerrors.sh' "$@"
|
||||
|
|
|
|||
|
|
@ -360,7 +360,7 @@ func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int,
|
|||
var status _C_int
|
||||
var r Pid_t
|
||||
err = ERESTART
|
||||
// AIX wait4 may return with ERESTART errno, while the processus is still
|
||||
// AIX wait4 may return with ERESTART errno, while the process is still
|
||||
// active.
|
||||
for err == ERESTART {
|
||||
r, err = wait4(Pid_t(pid), &status, options, rusage)
|
||||
|
|
|
|||
|
|
@ -566,6 +566,43 @@ func PthreadFchdir(fd int) (err error) {
|
|||
return pthread_fchdir_np(fd)
|
||||
}
|
||||
|
||||
// Connectx calls connectx(2) to initiate a connection on a socket.
|
||||
//
|
||||
// srcIf, srcAddr, and dstAddr are filled into a [SaEndpoints] struct and passed as the endpoints argument.
|
||||
//
|
||||
// - srcIf is the optional source interface index. 0 means unspecified.
|
||||
// - srcAddr is the optional source address. nil means unspecified.
|
||||
// - dstAddr is the destination address.
|
||||
//
|
||||
// On success, Connectx returns the number of bytes enqueued for transmission.
|
||||
func Connectx(fd int, srcIf uint32, srcAddr, dstAddr Sockaddr, associd SaeAssocID, flags uint32, iov []Iovec, connid *SaeConnID) (n uintptr, err error) {
|
||||
endpoints := SaEndpoints{
|
||||
Srcif: srcIf,
|
||||
}
|
||||
|
||||
if srcAddr != nil {
|
||||
addrp, addrlen, err := srcAddr.sockaddr()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
endpoints.Srcaddr = (*RawSockaddr)(addrp)
|
||||
endpoints.Srcaddrlen = uint32(addrlen)
|
||||
}
|
||||
|
||||
if dstAddr != nil {
|
||||
addrp, addrlen, err := dstAddr.sockaddr()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
endpoints.Dstaddr = (*RawSockaddr)(addrp)
|
||||
endpoints.Dstaddrlen = uint32(addrlen)
|
||||
}
|
||||
|
||||
err = connectx(fd, &endpoints, associd, flags, iov, &n, connid)
|
||||
return
|
||||
}
|
||||
|
||||
//sys connectx(fd int, endpoints *SaEndpoints, associd SaeAssocID, flags uint32, iov []Iovec, n *uintptr, connid *SaeConnID) (err error)
|
||||
//sys sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error)
|
||||
|
||||
//sys shmat(id int, addr uintptr, flag int) (ret uintptr, err error)
|
||||
|
|
|
|||
|
|
@ -246,6 +246,18 @@ func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err e
|
|||
return sendfile(outfd, infd, offset, count)
|
||||
}
|
||||
|
||||
func Dup3(oldfd, newfd, flags int) error {
|
||||
if oldfd == newfd || flags&^O_CLOEXEC != 0 {
|
||||
return EINVAL
|
||||
}
|
||||
how := F_DUP2FD
|
||||
if flags&O_CLOEXEC != 0 {
|
||||
how = F_DUP2FD_CLOEXEC
|
||||
}
|
||||
_, err := fcntl(oldfd, how, newfd)
|
||||
return err
|
||||
}
|
||||
|
||||
/*
|
||||
* Exposed directly
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ package unix
|
|||
int ioctl(int, unsigned long int, uintptr_t);
|
||||
*/
|
||||
import "C"
|
||||
import "unsafe"
|
||||
|
||||
func ioctl(fd int, req uint, arg uintptr) (err error) {
|
||||
r0, er := C.ioctl(C.int(fd), C.ulong(req), C.uintptr_t(arg))
|
||||
|
|
|
|||
|
|
@ -1295,6 +1295,48 @@ func GetsockoptTCPInfo(fd, level, opt int) (*TCPInfo, error) {
|
|||
return &value, err
|
||||
}
|
||||
|
||||
// GetsockoptTCPCCVegasInfo returns algorithm specific congestion control information for a socket using the "vegas"
|
||||
// algorithm.
|
||||
//
|
||||
// The socket's congestion control algorighm can be retrieved via [GetsockoptString] with the [TCP_CONGESTION] option:
|
||||
//
|
||||
// algo, err := unix.GetsockoptString(fd, unix.IPPROTO_TCP, unix.TCP_CONGESTION)
|
||||
func GetsockoptTCPCCVegasInfo(fd, level, opt int) (*TCPVegasInfo, error) {
|
||||
var value [SizeofTCPCCInfo / 4]uint32 // ensure proper alignment
|
||||
vallen := _Socklen(SizeofTCPCCInfo)
|
||||
err := getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen)
|
||||
out := (*TCPVegasInfo)(unsafe.Pointer(&value[0]))
|
||||
return out, err
|
||||
}
|
||||
|
||||
// GetsockoptTCPCCDCTCPInfo returns algorithm specific congestion control information for a socket using the "dctp"
|
||||
// algorithm.
|
||||
//
|
||||
// The socket's congestion control algorighm can be retrieved via [GetsockoptString] with the [TCP_CONGESTION] option:
|
||||
//
|
||||
// algo, err := unix.GetsockoptString(fd, unix.IPPROTO_TCP, unix.TCP_CONGESTION)
|
||||
func GetsockoptTCPCCDCTCPInfo(fd, level, opt int) (*TCPDCTCPInfo, error) {
|
||||
var value [SizeofTCPCCInfo / 4]uint32 // ensure proper alignment
|
||||
vallen := _Socklen(SizeofTCPCCInfo)
|
||||
err := getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen)
|
||||
out := (*TCPDCTCPInfo)(unsafe.Pointer(&value[0]))
|
||||
return out, err
|
||||
}
|
||||
|
||||
// GetsockoptTCPCCBBRInfo returns algorithm specific congestion control information for a socket using the "bbr"
|
||||
// algorithm.
|
||||
//
|
||||
// The socket's congestion control algorighm can be retrieved via [GetsockoptString] with the [TCP_CONGESTION] option:
|
||||
//
|
||||
// algo, err := unix.GetsockoptString(fd, unix.IPPROTO_TCP, unix.TCP_CONGESTION)
|
||||
func GetsockoptTCPCCBBRInfo(fd, level, opt int) (*TCPBBRInfo, error) {
|
||||
var value [SizeofTCPCCInfo / 4]uint32 // ensure proper alignment
|
||||
vallen := _Socklen(SizeofTCPCCInfo)
|
||||
err := getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen)
|
||||
out := (*TCPBBRInfo)(unsafe.Pointer(&value[0]))
|
||||
return out, err
|
||||
}
|
||||
|
||||
// GetsockoptString returns the string value of the socket option opt for the
|
||||
// socket associated with fd at the given socket level.
|
||||
func GetsockoptString(fd, level, opt int) (string, error) {
|
||||
|
|
@ -1818,6 +1860,7 @@ func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err e
|
|||
//sys ClockAdjtime(clockid int32, buf *Timex) (state int, err error)
|
||||
//sys ClockGetres(clockid int32, res *Timespec) (err error)
|
||||
//sys ClockGettime(clockid int32, time *Timespec) (err error)
|
||||
//sys ClockSettime(clockid int32, time *Timespec) (err error)
|
||||
//sys ClockNanosleep(clockid int32, flags int, request *Timespec, remain *Timespec) (err error)
|
||||
//sys Close(fd int) (err error)
|
||||
//sys CloseRange(first uint, last uint, flags uint) (err error)
|
||||
|
|
@ -1959,7 +2002,26 @@ func Getpgrp() (pid int) {
|
|||
//sysnb Getpid() (pid int)
|
||||
//sysnb Getppid() (ppid int)
|
||||
//sys Getpriority(which int, who int) (prio int, err error)
|
||||
//sys Getrandom(buf []byte, flags int) (n int, err error)
|
||||
|
||||
func Getrandom(buf []byte, flags int) (n int, err error) {
|
||||
vdsoRet, supported := vgetrandom(buf, uint32(flags))
|
||||
if supported {
|
||||
if vdsoRet < 0 {
|
||||
return 0, errnoErr(syscall.Errno(-vdsoRet))
|
||||
}
|
||||
return vdsoRet, nil
|
||||
}
|
||||
var p *byte
|
||||
if len(buf) > 0 {
|
||||
p = &buf[0]
|
||||
}
|
||||
r, _, e := Syscall(SYS_GETRANDOM, uintptr(unsafe.Pointer(p)), uintptr(len(buf)), uintptr(flags))
|
||||
if e != 0 {
|
||||
return 0, errnoErr(e)
|
||||
}
|
||||
return int(r), nil
|
||||
}
|
||||
|
||||
//sysnb Getrusage(who int, rusage *Rusage) (err error)
|
||||
//sysnb Getsid(pid int) (sid int, err error)
|
||||
//sysnb Gettid() (tid int)
|
||||
|
|
|
|||
|
|
@ -182,3 +182,5 @@ func KexecFileLoad(kernelFd int, initrdFd int, cmdline string, flags int) error
|
|||
}
|
||||
return kexecFileLoad(kernelFd, initrdFd, cmdlineLen, cmdline, flags)
|
||||
}
|
||||
|
||||
const SYS_FSTATAT = SYS_NEWFSTATAT
|
||||
|
|
|
|||
|
|
@ -214,3 +214,5 @@ func KexecFileLoad(kernelFd int, initrdFd int, cmdline string, flags int) error
|
|||
}
|
||||
return kexecFileLoad(kernelFd, initrdFd, cmdlineLen, cmdline, flags)
|
||||
}
|
||||
|
||||
const SYS_FSTATAT = SYS_NEWFSTATAT
|
||||
|
|
|
|||
|
|
@ -187,3 +187,5 @@ func RISCVHWProbe(pairs []RISCVHWProbePairs, set *CPUSet, flags uint) (err error
|
|||
}
|
||||
return riscvHWProbe(pairs, setSize, set, flags)
|
||||
}
|
||||
|
||||
const SYS_FSTATAT = SYS_NEWFSTATAT
|
||||
|
|
|
|||
|
|
@ -768,6 +768,15 @@ func Munmap(b []byte) (err error) {
|
|||
return mapper.Munmap(b)
|
||||
}
|
||||
|
||||
func MmapPtr(fd int, offset int64, addr unsafe.Pointer, length uintptr, prot int, flags int) (ret unsafe.Pointer, err error) {
|
||||
xaddr, err := mapper.mmap(uintptr(addr), length, prot, flags, fd, offset)
|
||||
return unsafe.Pointer(xaddr), err
|
||||
}
|
||||
|
||||
func MunmapPtr(addr unsafe.Pointer, length uintptr) (err error) {
|
||||
return mapper.munmap(uintptr(addr), length)
|
||||
}
|
||||
|
||||
//sys Gethostname(buf []byte) (err error) = SYS___GETHOSTNAME_A
|
||||
//sysnb Getgid() (gid int)
|
||||
//sysnb Getpid() (pid int)
|
||||
|
|
@ -816,10 +825,10 @@ func Lstat(path string, stat *Stat_t) (err error) {
|
|||
// for checking symlinks begins with $VERSION/ $SYSNAME/ $SYSSYMR/ $SYSSYMA/
|
||||
func isSpecialPath(path []byte) (v bool) {
|
||||
var special = [4][8]byte{
|
||||
[8]byte{'V', 'E', 'R', 'S', 'I', 'O', 'N', '/'},
|
||||
[8]byte{'S', 'Y', 'S', 'N', 'A', 'M', 'E', '/'},
|
||||
[8]byte{'S', 'Y', 'S', 'S', 'Y', 'M', 'R', '/'},
|
||||
[8]byte{'S', 'Y', 'S', 'S', 'Y', 'M', 'A', '/'}}
|
||||
{'V', 'E', 'R', 'S', 'I', 'O', 'N', '/'},
|
||||
{'S', 'Y', 'S', 'N', 'A', 'M', 'E', '/'},
|
||||
{'S', 'Y', 'S', 'S', 'Y', 'M', 'R', '/'},
|
||||
{'S', 'Y', 'S', 'S', 'Y', 'M', 'A', '/'}}
|
||||
|
||||
var i, j int
|
||||
for i = 0; i < len(special); i++ {
|
||||
|
|
@ -3115,3 +3124,90 @@ func legacy_Mkfifoat(dirfd int, path string, mode uint32) (err error) {
|
|||
//sys Posix_openpt(oflag int) (fd int, err error) = SYS_POSIX_OPENPT
|
||||
//sys Grantpt(fildes int) (rc int, err error) = SYS_GRANTPT
|
||||
//sys Unlockpt(fildes int) (rc int, err error) = SYS_UNLOCKPT
|
||||
|
||||
func fcntlAsIs(fd uintptr, cmd int, arg uintptr) (val int, err error) {
|
||||
runtime.EnterSyscall()
|
||||
r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_FCNTL<<4, uintptr(fd), uintptr(cmd), arg)
|
||||
runtime.ExitSyscall()
|
||||
val = int(r0)
|
||||
if int64(r0) == -1 {
|
||||
err = errnoErr2(e1, e2)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func Fcntl(fd uintptr, cmd int, op interface{}) (ret int, err error) {
|
||||
switch op.(type) {
|
||||
case *Flock_t:
|
||||
err = FcntlFlock(fd, cmd, op.(*Flock_t))
|
||||
if err != nil {
|
||||
ret = -1
|
||||
}
|
||||
return
|
||||
case int:
|
||||
return FcntlInt(fd, cmd, op.(int))
|
||||
case *F_cnvrt:
|
||||
return fcntlAsIs(fd, cmd, uintptr(unsafe.Pointer(op.(*F_cnvrt))))
|
||||
case unsafe.Pointer:
|
||||
return fcntlAsIs(fd, cmd, uintptr(op.(unsafe.Pointer)))
|
||||
default:
|
||||
return -1, EINVAL
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
|
||||
if raceenabled {
|
||||
raceReleaseMerge(unsafe.Pointer(&ioSync))
|
||||
}
|
||||
return sendfile(outfd, infd, offset, count)
|
||||
}
|
||||
|
||||
func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
|
||||
// TODO: use LE call instead if the call is implemented
|
||||
originalOffset, err := Seek(infd, 0, SEEK_CUR)
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
//start reading data from in_fd
|
||||
if offset != nil {
|
||||
_, err := Seek(infd, *offset, SEEK_SET)
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
}
|
||||
|
||||
buf := make([]byte, count)
|
||||
readBuf := make([]byte, 0)
|
||||
var n int = 0
|
||||
for i := 0; i < count; i += n {
|
||||
n, err := Read(infd, buf)
|
||||
if n == 0 {
|
||||
if err != nil {
|
||||
return -1, err
|
||||
} else { // EOF
|
||||
break
|
||||
}
|
||||
}
|
||||
readBuf = append(readBuf, buf...)
|
||||
buf = buf[0:0]
|
||||
}
|
||||
|
||||
n2, err := Write(outfd, readBuf)
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
|
||||
//When sendfile() returns, this variable will be set to the
|
||||
// offset of the byte following the last byte that was read.
|
||||
if offset != nil {
|
||||
*offset = *offset + int64(n)
|
||||
// If offset is not NULL, then sendfile() does not modify the file
|
||||
// offset of in_fd
|
||||
_, err := Seek(infd, originalOffset, SEEK_SET)
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
}
|
||||
return n2, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
// Copyright 2024 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build linux && go1.24
|
||||
|
||||
package unix
|
||||
|
||||
import _ "unsafe"
|
||||
|
||||
//go:linkname vgetrandom runtime.vgetrandom
|
||||
//go:noescape
|
||||
func vgetrandom(p []byte, flags uint32) (ret int, supported bool)
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
// Copyright 2024 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !linux || !go1.24
|
||||
|
||||
package unix
|
||||
|
||||
func vgetrandom(p []byte, flags uint32) (ret int, supported bool) {
|
||||
return -1, false
|
||||
}
|
||||
|
|
@ -237,6 +237,9 @@ const (
|
|||
CLOCK_UPTIME_RAW_APPROX = 0x9
|
||||
CLONE_NOFOLLOW = 0x1
|
||||
CLONE_NOOWNERCOPY = 0x2
|
||||
CONNECT_DATA_AUTHENTICATED = 0x4
|
||||
CONNECT_DATA_IDEMPOTENT = 0x2
|
||||
CONNECT_RESUME_ON_READ_WRITE = 0x1
|
||||
CR0 = 0x0
|
||||
CR1 = 0x1000
|
||||
CR2 = 0x2000
|
||||
|
|
@ -1265,6 +1268,10 @@ const (
|
|||
RTV_SSTHRESH = 0x20
|
||||
RUSAGE_CHILDREN = -0x1
|
||||
RUSAGE_SELF = 0x0
|
||||
SAE_ASSOCID_ALL = 0xffffffff
|
||||
SAE_ASSOCID_ANY = 0x0
|
||||
SAE_CONNID_ALL = 0xffffffff
|
||||
SAE_CONNID_ANY = 0x0
|
||||
SCM_CREDS = 0x3
|
||||
SCM_RIGHTS = 0x1
|
||||
SCM_TIMESTAMP = 0x2
|
||||
|
|
|
|||
|
|
@ -237,6 +237,9 @@ const (
|
|||
CLOCK_UPTIME_RAW_APPROX = 0x9
|
||||
CLONE_NOFOLLOW = 0x1
|
||||
CLONE_NOOWNERCOPY = 0x2
|
||||
CONNECT_DATA_AUTHENTICATED = 0x4
|
||||
CONNECT_DATA_IDEMPOTENT = 0x2
|
||||
CONNECT_RESUME_ON_READ_WRITE = 0x1
|
||||
CR0 = 0x0
|
||||
CR1 = 0x1000
|
||||
CR2 = 0x2000
|
||||
|
|
@ -1265,6 +1268,10 @@ const (
|
|||
RTV_SSTHRESH = 0x20
|
||||
RUSAGE_CHILDREN = -0x1
|
||||
RUSAGE_SELF = 0x0
|
||||
SAE_ASSOCID_ALL = 0xffffffff
|
||||
SAE_ASSOCID_ANY = 0x0
|
||||
SAE_CONNID_ALL = 0xffffffff
|
||||
SAE_CONNID_ANY = 0x0
|
||||
SCM_CREDS = 0x3
|
||||
SCM_RIGHTS = 0x1
|
||||
SCM_TIMESTAMP = 0x2
|
||||
|
|
|
|||
|
|
@ -321,6 +321,9 @@ const (
|
|||
AUDIT_INTEGRITY_STATUS = 0x70a
|
||||
AUDIT_IPC = 0x517
|
||||
AUDIT_IPC_SET_PERM = 0x51f
|
||||
AUDIT_IPE_ACCESS = 0x58c
|
||||
AUDIT_IPE_CONFIG_CHANGE = 0x58d
|
||||
AUDIT_IPE_POLICY_LOAD = 0x58e
|
||||
AUDIT_KERNEL = 0x7d0
|
||||
AUDIT_KERNEL_OTHER = 0x524
|
||||
AUDIT_KERN_MODULE = 0x532
|
||||
|
|
@ -489,12 +492,14 @@ const (
|
|||
BPF_F_ID = 0x20
|
||||
BPF_F_NETFILTER_IP_DEFRAG = 0x1
|
||||
BPF_F_QUERY_EFFECTIVE = 0x1
|
||||
BPF_F_REDIRECT_FLAGS = 0x19
|
||||
BPF_F_REPLACE = 0x4
|
||||
BPF_F_SLEEPABLE = 0x10
|
||||
BPF_F_STRICT_ALIGNMENT = 0x1
|
||||
BPF_F_TEST_REG_INVARIANTS = 0x80
|
||||
BPF_F_TEST_RND_HI32 = 0x4
|
||||
BPF_F_TEST_RUN_ON_CPU = 0x1
|
||||
BPF_F_TEST_SKB_CHECKSUM_COMPLETE = 0x4
|
||||
BPF_F_TEST_STATE_FREQ = 0x8
|
||||
BPF_F_TEST_XDP_LIVE_FRAMES = 0x2
|
||||
BPF_F_XDP_DEV_BOUND_ONLY = 0x40
|
||||
|
|
@ -1165,6 +1170,7 @@ const (
|
|||
EXTA = 0xe
|
||||
EXTB = 0xf
|
||||
F2FS_SUPER_MAGIC = 0xf2f52010
|
||||
FALLOC_FL_ALLOCATE_RANGE = 0x0
|
||||
FALLOC_FL_COLLAPSE_RANGE = 0x8
|
||||
FALLOC_FL_INSERT_RANGE = 0x20
|
||||
FALLOC_FL_KEEP_SIZE = 0x1
|
||||
|
|
@ -1798,6 +1804,8 @@ const (
|
|||
LANDLOCK_ACCESS_NET_BIND_TCP = 0x1
|
||||
LANDLOCK_ACCESS_NET_CONNECT_TCP = 0x2
|
||||
LANDLOCK_CREATE_RULESET_VERSION = 0x1
|
||||
LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET = 0x1
|
||||
LANDLOCK_SCOPE_SIGNAL = 0x2
|
||||
LINUX_REBOOT_CMD_CAD_OFF = 0x0
|
||||
LINUX_REBOOT_CMD_CAD_ON = 0x89abcdef
|
||||
LINUX_REBOOT_CMD_HALT = 0xcdef0123
|
||||
|
|
@ -1922,6 +1930,8 @@ const (
|
|||
MNT_EXPIRE = 0x4
|
||||
MNT_FORCE = 0x1
|
||||
MNT_ID_REQ_SIZE_VER0 = 0x18
|
||||
MNT_ID_REQ_SIZE_VER1 = 0x20
|
||||
MNT_NS_INFO_SIZE_VER0 = 0x10
|
||||
MODULE_INIT_COMPRESSED_FILE = 0x4
|
||||
MODULE_INIT_IGNORE_MODVERSIONS = 0x1
|
||||
MODULE_INIT_IGNORE_VERMAGIC = 0x2
|
||||
|
|
@ -2187,7 +2197,7 @@ const (
|
|||
NFT_REG_SIZE = 0x10
|
||||
NFT_REJECT_ICMPX_MAX = 0x3
|
||||
NFT_RT_MAX = 0x4
|
||||
NFT_SECMARK_CTX_MAXLEN = 0x100
|
||||
NFT_SECMARK_CTX_MAXLEN = 0x1000
|
||||
NFT_SET_MAXNAMELEN = 0x100
|
||||
NFT_SOCKET_MAX = 0x3
|
||||
NFT_TABLE_F_MASK = 0x7
|
||||
|
|
@ -2356,9 +2366,11 @@ const (
|
|||
PERF_MEM_LVLNUM_IO = 0xa
|
||||
PERF_MEM_LVLNUM_L1 = 0x1
|
||||
PERF_MEM_LVLNUM_L2 = 0x2
|
||||
PERF_MEM_LVLNUM_L2_MHB = 0x5
|
||||
PERF_MEM_LVLNUM_L3 = 0x3
|
||||
PERF_MEM_LVLNUM_L4 = 0x4
|
||||
PERF_MEM_LVLNUM_LFB = 0xc
|
||||
PERF_MEM_LVLNUM_MSC = 0x6
|
||||
PERF_MEM_LVLNUM_NA = 0xf
|
||||
PERF_MEM_LVLNUM_PMEM = 0xe
|
||||
PERF_MEM_LVLNUM_RAM = 0xd
|
||||
|
|
@ -2431,6 +2443,7 @@ const (
|
|||
PRIO_PGRP = 0x1
|
||||
PRIO_PROCESS = 0x0
|
||||
PRIO_USER = 0x2
|
||||
PROCFS_IOCTL_MAGIC = 'f'
|
||||
PROC_SUPER_MAGIC = 0x9fa0
|
||||
PROT_EXEC = 0x4
|
||||
PROT_GROWSDOWN = 0x1000000
|
||||
|
|
@ -2620,6 +2633,28 @@ const (
|
|||
PR_UNALIGN_NOPRINT = 0x1
|
||||
PR_UNALIGN_SIGBUS = 0x2
|
||||
PSTOREFS_MAGIC = 0x6165676c
|
||||
PTP_CLK_MAGIC = '='
|
||||
PTP_ENABLE_FEATURE = 0x1
|
||||
PTP_EXTTS_EDGES = 0x6
|
||||
PTP_EXTTS_EVENT_VALID = 0x1
|
||||
PTP_EXTTS_V1_VALID_FLAGS = 0x7
|
||||
PTP_EXTTS_VALID_FLAGS = 0x1f
|
||||
PTP_EXT_OFFSET = 0x10
|
||||
PTP_FALLING_EDGE = 0x4
|
||||
PTP_MAX_SAMPLES = 0x19
|
||||
PTP_PEROUT_DUTY_CYCLE = 0x2
|
||||
PTP_PEROUT_ONE_SHOT = 0x1
|
||||
PTP_PEROUT_PHASE = 0x4
|
||||
PTP_PEROUT_V1_VALID_FLAGS = 0x0
|
||||
PTP_PEROUT_VALID_FLAGS = 0x7
|
||||
PTP_PIN_GETFUNC = 0xc0603d06
|
||||
PTP_PIN_GETFUNC2 = 0xc0603d0f
|
||||
PTP_RISING_EDGE = 0x2
|
||||
PTP_STRICT_FLAGS = 0x8
|
||||
PTP_SYS_OFFSET_EXTENDED = 0xc4c03d09
|
||||
PTP_SYS_OFFSET_EXTENDED2 = 0xc4c03d12
|
||||
PTP_SYS_OFFSET_PRECISE = 0xc0403d08
|
||||
PTP_SYS_OFFSET_PRECISE2 = 0xc0403d11
|
||||
PTRACE_ATTACH = 0x10
|
||||
PTRACE_CONT = 0x7
|
||||
PTRACE_DETACH = 0x11
|
||||
|
|
@ -2933,15 +2968,17 @@ const (
|
|||
RUSAGE_SELF = 0x0
|
||||
RUSAGE_THREAD = 0x1
|
||||
RWF_APPEND = 0x10
|
||||
RWF_ATOMIC = 0x40
|
||||
RWF_DSYNC = 0x2
|
||||
RWF_HIPRI = 0x1
|
||||
RWF_NOAPPEND = 0x20
|
||||
RWF_NOWAIT = 0x8
|
||||
RWF_SUPPORTED = 0x3f
|
||||
RWF_SUPPORTED = 0x7f
|
||||
RWF_SYNC = 0x4
|
||||
RWF_WRITE_LIFE_NOT_SET = 0x0
|
||||
SCHED_BATCH = 0x3
|
||||
SCHED_DEADLINE = 0x6
|
||||
SCHED_EXT = 0x7
|
||||
SCHED_FIFO = 0x1
|
||||
SCHED_FLAG_ALL = 0x7f
|
||||
SCHED_FLAG_DL_OVERRUN = 0x4
|
||||
|
|
@ -3210,6 +3247,7 @@ const (
|
|||
STATX_ATTR_MOUNT_ROOT = 0x2000
|
||||
STATX_ATTR_NODUMP = 0x40
|
||||
STATX_ATTR_VERITY = 0x100000
|
||||
STATX_ATTR_WRITE_ATOMIC = 0x400000
|
||||
STATX_BASIC_STATS = 0x7ff
|
||||
STATX_BLOCKS = 0x400
|
||||
STATX_BTIME = 0x800
|
||||
|
|
@ -3226,6 +3264,7 @@ const (
|
|||
STATX_SUBVOL = 0x8000
|
||||
STATX_TYPE = 0x1
|
||||
STATX_UID = 0x8
|
||||
STATX_WRITE_ATOMIC = 0x10000
|
||||
STATX__RESERVED = 0x80000000
|
||||
SYNC_FILE_RANGE_WAIT_AFTER = 0x4
|
||||
SYNC_FILE_RANGE_WAIT_BEFORE = 0x1
|
||||
|
|
@ -3624,6 +3663,7 @@ const (
|
|||
XDP_UMEM_PGOFF_COMPLETION_RING = 0x180000000
|
||||
XDP_UMEM_PGOFF_FILL_RING = 0x100000000
|
||||
XDP_UMEM_REG = 0x4
|
||||
XDP_UMEM_TX_METADATA_LEN = 0x4
|
||||
XDP_UMEM_TX_SW_CSUM = 0x2
|
||||
XDP_UMEM_UNALIGNED_CHUNK_FLAG = 0x1
|
||||
XDP_USE_NEED_WAKEUP = 0x8
|
||||
|
|
|
|||
|
|
@ -109,6 +109,7 @@ const (
|
|||
HIDIOCGRAWINFO = 0x80084803
|
||||
HIDIOCGRDESC = 0x90044802
|
||||
HIDIOCGRDESCSIZE = 0x80044801
|
||||
HIDIOCREVOKE = 0x4004480d
|
||||
HUPCL = 0x400
|
||||
ICANON = 0x2
|
||||
IEXTEN = 0x8000
|
||||
|
|
@ -153,9 +154,14 @@ const (
|
|||
NFDBITS = 0x20
|
||||
NLDLY = 0x100
|
||||
NOFLSH = 0x80
|
||||
NS_GET_MNTNS_ID = 0x8008b705
|
||||
NS_GET_NSTYPE = 0xb703
|
||||
NS_GET_OWNER_UID = 0xb704
|
||||
NS_GET_PARENT = 0xb702
|
||||
NS_GET_PID_FROM_PIDNS = 0x8004b706
|
||||
NS_GET_PID_IN_PIDNS = 0x8004b708
|
||||
NS_GET_TGID_FROM_PIDNS = 0x8004b707
|
||||
NS_GET_TGID_IN_PIDNS = 0x8004b709
|
||||
NS_GET_USERNS = 0xb701
|
||||
OLCUC = 0x2
|
||||
ONLCR = 0x4
|
||||
|
|
@ -232,6 +238,20 @@ const (
|
|||
PPPIOCUNBRIDGECHAN = 0x7434
|
||||
PPPIOCXFERUNIT = 0x744e
|
||||
PR_SET_PTRACER_ANY = 0xffffffff
|
||||
PTP_CLOCK_GETCAPS = 0x80503d01
|
||||
PTP_CLOCK_GETCAPS2 = 0x80503d0a
|
||||
PTP_ENABLE_PPS = 0x40043d04
|
||||
PTP_ENABLE_PPS2 = 0x40043d0d
|
||||
PTP_EXTTS_REQUEST = 0x40103d02
|
||||
PTP_EXTTS_REQUEST2 = 0x40103d0b
|
||||
PTP_MASK_CLEAR_ALL = 0x3d13
|
||||
PTP_MASK_EN_SINGLE = 0x40043d14
|
||||
PTP_PEROUT_REQUEST = 0x40383d03
|
||||
PTP_PEROUT_REQUEST2 = 0x40383d0c
|
||||
PTP_PIN_SETFUNC = 0x40603d07
|
||||
PTP_PIN_SETFUNC2 = 0x40603d10
|
||||
PTP_SYS_OFFSET = 0x43403d05
|
||||
PTP_SYS_OFFSET2 = 0x43403d0e
|
||||
PTRACE_GETFPREGS = 0xe
|
||||
PTRACE_GETFPXREGS = 0x12
|
||||
PTRACE_GET_THREAD_AREA = 0x19
|
||||
|
|
@ -278,6 +298,8 @@ const (
|
|||
RTC_WIE_ON = 0x700f
|
||||
RTC_WKALM_RD = 0x80287010
|
||||
RTC_WKALM_SET = 0x4028700f
|
||||
SCM_DEVMEM_DMABUF = 0x4f
|
||||
SCM_DEVMEM_LINEAR = 0x4e
|
||||
SCM_TIMESTAMPING = 0x25
|
||||
SCM_TIMESTAMPING_OPT_STATS = 0x36
|
||||
SCM_TIMESTAMPING_PKTINFO = 0x3a
|
||||
|
|
@ -316,6 +338,9 @@ const (
|
|||
SO_CNX_ADVICE = 0x35
|
||||
SO_COOKIE = 0x39
|
||||
SO_DETACH_REUSEPORT_BPF = 0x44
|
||||
SO_DEVMEM_DMABUF = 0x4f
|
||||
SO_DEVMEM_DONTNEED = 0x50
|
||||
SO_DEVMEM_LINEAR = 0x4e
|
||||
SO_DOMAIN = 0x27
|
||||
SO_DONTROUTE = 0x5
|
||||
SO_ERROR = 0x4
|
||||
|
|
|
|||
|
|
@ -109,6 +109,7 @@ const (
|
|||
HIDIOCGRAWINFO = 0x80084803
|
||||
HIDIOCGRDESC = 0x90044802
|
||||
HIDIOCGRDESCSIZE = 0x80044801
|
||||
HIDIOCREVOKE = 0x4004480d
|
||||
HUPCL = 0x400
|
||||
ICANON = 0x2
|
||||
IEXTEN = 0x8000
|
||||
|
|
@ -153,9 +154,14 @@ const (
|
|||
NFDBITS = 0x40
|
||||
NLDLY = 0x100
|
||||
NOFLSH = 0x80
|
||||
NS_GET_MNTNS_ID = 0x8008b705
|
||||
NS_GET_NSTYPE = 0xb703
|
||||
NS_GET_OWNER_UID = 0xb704
|
||||
NS_GET_PARENT = 0xb702
|
||||
NS_GET_PID_FROM_PIDNS = 0x8004b706
|
||||
NS_GET_PID_IN_PIDNS = 0x8004b708
|
||||
NS_GET_TGID_FROM_PIDNS = 0x8004b707
|
||||
NS_GET_TGID_IN_PIDNS = 0x8004b709
|
||||
NS_GET_USERNS = 0xb701
|
||||
OLCUC = 0x2
|
||||
ONLCR = 0x4
|
||||
|
|
@ -232,6 +238,20 @@ const (
|
|||
PPPIOCUNBRIDGECHAN = 0x7434
|
||||
PPPIOCXFERUNIT = 0x744e
|
||||
PR_SET_PTRACER_ANY = 0xffffffffffffffff
|
||||
PTP_CLOCK_GETCAPS = 0x80503d01
|
||||
PTP_CLOCK_GETCAPS2 = 0x80503d0a
|
||||
PTP_ENABLE_PPS = 0x40043d04
|
||||
PTP_ENABLE_PPS2 = 0x40043d0d
|
||||
PTP_EXTTS_REQUEST = 0x40103d02
|
||||
PTP_EXTTS_REQUEST2 = 0x40103d0b
|
||||
PTP_MASK_CLEAR_ALL = 0x3d13
|
||||
PTP_MASK_EN_SINGLE = 0x40043d14
|
||||
PTP_PEROUT_REQUEST = 0x40383d03
|
||||
PTP_PEROUT_REQUEST2 = 0x40383d0c
|
||||
PTP_PIN_SETFUNC = 0x40603d07
|
||||
PTP_PIN_SETFUNC2 = 0x40603d10
|
||||
PTP_SYS_OFFSET = 0x43403d05
|
||||
PTP_SYS_OFFSET2 = 0x43403d0e
|
||||
PTRACE_ARCH_PRCTL = 0x1e
|
||||
PTRACE_GETFPREGS = 0xe
|
||||
PTRACE_GETFPXREGS = 0x12
|
||||
|
|
@ -279,6 +299,8 @@ const (
|
|||
RTC_WIE_ON = 0x700f
|
||||
RTC_WKALM_RD = 0x80287010
|
||||
RTC_WKALM_SET = 0x4028700f
|
||||
SCM_DEVMEM_DMABUF = 0x4f
|
||||
SCM_DEVMEM_LINEAR = 0x4e
|
||||
SCM_TIMESTAMPING = 0x25
|
||||
SCM_TIMESTAMPING_OPT_STATS = 0x36
|
||||
SCM_TIMESTAMPING_PKTINFO = 0x3a
|
||||
|
|
@ -317,6 +339,9 @@ const (
|
|||
SO_CNX_ADVICE = 0x35
|
||||
SO_COOKIE = 0x39
|
||||
SO_DETACH_REUSEPORT_BPF = 0x44
|
||||
SO_DEVMEM_DMABUF = 0x4f
|
||||
SO_DEVMEM_DONTNEED = 0x50
|
||||
SO_DEVMEM_LINEAR = 0x4e
|
||||
SO_DOMAIN = 0x27
|
||||
SO_DONTROUTE = 0x5
|
||||
SO_ERROR = 0x4
|
||||
|
|
|
|||
|
|
@ -108,6 +108,7 @@ const (
|
|||
HIDIOCGRAWINFO = 0x80084803
|
||||
HIDIOCGRDESC = 0x90044802
|
||||
HIDIOCGRDESCSIZE = 0x80044801
|
||||
HIDIOCREVOKE = 0x4004480d
|
||||
HUPCL = 0x400
|
||||
ICANON = 0x2
|
||||
IEXTEN = 0x8000
|
||||
|
|
@ -150,9 +151,14 @@ const (
|
|||
NFDBITS = 0x20
|
||||
NLDLY = 0x100
|
||||
NOFLSH = 0x80
|
||||
NS_GET_MNTNS_ID = 0x8008b705
|
||||
NS_GET_NSTYPE = 0xb703
|
||||
NS_GET_OWNER_UID = 0xb704
|
||||
NS_GET_PARENT = 0xb702
|
||||
NS_GET_PID_FROM_PIDNS = 0x8004b706
|
||||
NS_GET_PID_IN_PIDNS = 0x8004b708
|
||||
NS_GET_TGID_FROM_PIDNS = 0x8004b707
|
||||
NS_GET_TGID_IN_PIDNS = 0x8004b709
|
||||
NS_GET_USERNS = 0xb701
|
||||
OLCUC = 0x2
|
||||
ONLCR = 0x4
|
||||
|
|
@ -229,6 +235,20 @@ const (
|
|||
PPPIOCUNBRIDGECHAN = 0x7434
|
||||
PPPIOCXFERUNIT = 0x744e
|
||||
PR_SET_PTRACER_ANY = 0xffffffff
|
||||
PTP_CLOCK_GETCAPS = 0x80503d01
|
||||
PTP_CLOCK_GETCAPS2 = 0x80503d0a
|
||||
PTP_ENABLE_PPS = 0x40043d04
|
||||
PTP_ENABLE_PPS2 = 0x40043d0d
|
||||
PTP_EXTTS_REQUEST = 0x40103d02
|
||||
PTP_EXTTS_REQUEST2 = 0x40103d0b
|
||||
PTP_MASK_CLEAR_ALL = 0x3d13
|
||||
PTP_MASK_EN_SINGLE = 0x40043d14
|
||||
PTP_PEROUT_REQUEST = 0x40383d03
|
||||
PTP_PEROUT_REQUEST2 = 0x40383d0c
|
||||
PTP_PIN_SETFUNC = 0x40603d07
|
||||
PTP_PIN_SETFUNC2 = 0x40603d10
|
||||
PTP_SYS_OFFSET = 0x43403d05
|
||||
PTP_SYS_OFFSET2 = 0x43403d0e
|
||||
PTRACE_GETCRUNCHREGS = 0x19
|
||||
PTRACE_GETFDPIC = 0x1f
|
||||
PTRACE_GETFDPIC_EXEC = 0x0
|
||||
|
|
@ -284,6 +304,8 @@ const (
|
|||
RTC_WIE_ON = 0x700f
|
||||
RTC_WKALM_RD = 0x80287010
|
||||
RTC_WKALM_SET = 0x4028700f
|
||||
SCM_DEVMEM_DMABUF = 0x4f
|
||||
SCM_DEVMEM_LINEAR = 0x4e
|
||||
SCM_TIMESTAMPING = 0x25
|
||||
SCM_TIMESTAMPING_OPT_STATS = 0x36
|
||||
SCM_TIMESTAMPING_PKTINFO = 0x3a
|
||||
|
|
@ -322,6 +344,9 @@ const (
|
|||
SO_CNX_ADVICE = 0x35
|
||||
SO_COOKIE = 0x39
|
||||
SO_DETACH_REUSEPORT_BPF = 0x44
|
||||
SO_DEVMEM_DMABUF = 0x4f
|
||||
SO_DEVMEM_DONTNEED = 0x50
|
||||
SO_DEVMEM_LINEAR = 0x4e
|
||||
SO_DOMAIN = 0x27
|
||||
SO_DONTROUTE = 0x5
|
||||
SO_ERROR = 0x4
|
||||
|
|
|
|||
|
|
@ -112,6 +112,7 @@ const (
|
|||
HIDIOCGRAWINFO = 0x80084803
|
||||
HIDIOCGRDESC = 0x90044802
|
||||
HIDIOCGRDESCSIZE = 0x80044801
|
||||
HIDIOCREVOKE = 0x4004480d
|
||||
HUPCL = 0x400
|
||||
ICANON = 0x2
|
||||
IEXTEN = 0x8000
|
||||
|
|
@ -154,9 +155,14 @@ const (
|
|||
NFDBITS = 0x40
|
||||
NLDLY = 0x100
|
||||
NOFLSH = 0x80
|
||||
NS_GET_MNTNS_ID = 0x8008b705
|
||||
NS_GET_NSTYPE = 0xb703
|
||||
NS_GET_OWNER_UID = 0xb704
|
||||
NS_GET_PARENT = 0xb702
|
||||
NS_GET_PID_FROM_PIDNS = 0x8004b706
|
||||
NS_GET_PID_IN_PIDNS = 0x8004b708
|
||||
NS_GET_TGID_FROM_PIDNS = 0x8004b707
|
||||
NS_GET_TGID_IN_PIDNS = 0x8004b709
|
||||
NS_GET_USERNS = 0xb701
|
||||
OLCUC = 0x2
|
||||
ONLCR = 0x4
|
||||
|
|
@ -200,6 +206,7 @@ const (
|
|||
PERF_EVENT_IOC_SET_BPF = 0x40042408
|
||||
PERF_EVENT_IOC_SET_FILTER = 0x40082406
|
||||
PERF_EVENT_IOC_SET_OUTPUT = 0x2405
|
||||
POE_MAGIC = 0x504f4530
|
||||
PPPIOCATTACH = 0x4004743d
|
||||
PPPIOCATTCHAN = 0x40047438
|
||||
PPPIOCBRIDGECHAN = 0x40047435
|
||||
|
|
@ -235,6 +242,20 @@ const (
|
|||
PROT_BTI = 0x10
|
||||
PROT_MTE = 0x20
|
||||
PR_SET_PTRACER_ANY = 0xffffffffffffffff
|
||||
PTP_CLOCK_GETCAPS = 0x80503d01
|
||||
PTP_CLOCK_GETCAPS2 = 0x80503d0a
|
||||
PTP_ENABLE_PPS = 0x40043d04
|
||||
PTP_ENABLE_PPS2 = 0x40043d0d
|
||||
PTP_EXTTS_REQUEST = 0x40103d02
|
||||
PTP_EXTTS_REQUEST2 = 0x40103d0b
|
||||
PTP_MASK_CLEAR_ALL = 0x3d13
|
||||
PTP_MASK_EN_SINGLE = 0x40043d14
|
||||
PTP_PEROUT_REQUEST = 0x40383d03
|
||||
PTP_PEROUT_REQUEST2 = 0x40383d0c
|
||||
PTP_PIN_SETFUNC = 0x40603d07
|
||||
PTP_PIN_SETFUNC2 = 0x40603d10
|
||||
PTP_SYS_OFFSET = 0x43403d05
|
||||
PTP_SYS_OFFSET2 = 0x43403d0e
|
||||
PTRACE_PEEKMTETAGS = 0x21
|
||||
PTRACE_POKEMTETAGS = 0x22
|
||||
PTRACE_SYSEMU = 0x1f
|
||||
|
|
@ -275,6 +296,8 @@ const (
|
|||
RTC_WIE_ON = 0x700f
|
||||
RTC_WKALM_RD = 0x80287010
|
||||
RTC_WKALM_SET = 0x4028700f
|
||||
SCM_DEVMEM_DMABUF = 0x4f
|
||||
SCM_DEVMEM_LINEAR = 0x4e
|
||||
SCM_TIMESTAMPING = 0x25
|
||||
SCM_TIMESTAMPING_OPT_STATS = 0x36
|
||||
SCM_TIMESTAMPING_PKTINFO = 0x3a
|
||||
|
|
@ -313,6 +336,9 @@ const (
|
|||
SO_CNX_ADVICE = 0x35
|
||||
SO_COOKIE = 0x39
|
||||
SO_DETACH_REUSEPORT_BPF = 0x44
|
||||
SO_DEVMEM_DMABUF = 0x4f
|
||||
SO_DEVMEM_DONTNEED = 0x50
|
||||
SO_DEVMEM_LINEAR = 0x4e
|
||||
SO_DOMAIN = 0x27
|
||||
SO_DONTROUTE = 0x5
|
||||
SO_ERROR = 0x4
|
||||
|
|
|
|||
|
|
@ -109,6 +109,7 @@ const (
|
|||
HIDIOCGRAWINFO = 0x80084803
|
||||
HIDIOCGRDESC = 0x90044802
|
||||
HIDIOCGRDESCSIZE = 0x80044801
|
||||
HIDIOCREVOKE = 0x4004480d
|
||||
HUPCL = 0x400
|
||||
ICANON = 0x2
|
||||
IEXTEN = 0x8000
|
||||
|
|
@ -154,9 +155,14 @@ const (
|
|||
NFDBITS = 0x40
|
||||
NLDLY = 0x100
|
||||
NOFLSH = 0x80
|
||||
NS_GET_MNTNS_ID = 0x8008b705
|
||||
NS_GET_NSTYPE = 0xb703
|
||||
NS_GET_OWNER_UID = 0xb704
|
||||
NS_GET_PARENT = 0xb702
|
||||
NS_GET_PID_FROM_PIDNS = 0x8004b706
|
||||
NS_GET_PID_IN_PIDNS = 0x8004b708
|
||||
NS_GET_TGID_FROM_PIDNS = 0x8004b707
|
||||
NS_GET_TGID_IN_PIDNS = 0x8004b709
|
||||
NS_GET_USERNS = 0xb701
|
||||
OLCUC = 0x2
|
||||
ONLCR = 0x4
|
||||
|
|
@ -233,6 +239,20 @@ const (
|
|||
PPPIOCUNBRIDGECHAN = 0x7434
|
||||
PPPIOCXFERUNIT = 0x744e
|
||||
PR_SET_PTRACER_ANY = 0xffffffffffffffff
|
||||
PTP_CLOCK_GETCAPS = 0x80503d01
|
||||
PTP_CLOCK_GETCAPS2 = 0x80503d0a
|
||||
PTP_ENABLE_PPS = 0x40043d04
|
||||
PTP_ENABLE_PPS2 = 0x40043d0d
|
||||
PTP_EXTTS_REQUEST = 0x40103d02
|
||||
PTP_EXTTS_REQUEST2 = 0x40103d0b
|
||||
PTP_MASK_CLEAR_ALL = 0x3d13
|
||||
PTP_MASK_EN_SINGLE = 0x40043d14
|
||||
PTP_PEROUT_REQUEST = 0x40383d03
|
||||
PTP_PEROUT_REQUEST2 = 0x40383d0c
|
||||
PTP_PIN_SETFUNC = 0x40603d07
|
||||
PTP_PIN_SETFUNC2 = 0x40603d10
|
||||
PTP_SYS_OFFSET = 0x43403d05
|
||||
PTP_SYS_OFFSET2 = 0x43403d0e
|
||||
PTRACE_SYSEMU = 0x1f
|
||||
PTRACE_SYSEMU_SINGLESTEP = 0x20
|
||||
RLIMIT_AS = 0x9
|
||||
|
|
@ -271,6 +291,8 @@ const (
|
|||
RTC_WIE_ON = 0x700f
|
||||
RTC_WKALM_RD = 0x80287010
|
||||
RTC_WKALM_SET = 0x4028700f
|
||||
SCM_DEVMEM_DMABUF = 0x4f
|
||||
SCM_DEVMEM_LINEAR = 0x4e
|
||||
SCM_TIMESTAMPING = 0x25
|
||||
SCM_TIMESTAMPING_OPT_STATS = 0x36
|
||||
SCM_TIMESTAMPING_PKTINFO = 0x3a
|
||||
|
|
@ -309,6 +331,9 @@ const (
|
|||
SO_CNX_ADVICE = 0x35
|
||||
SO_COOKIE = 0x39
|
||||
SO_DETACH_REUSEPORT_BPF = 0x44
|
||||
SO_DEVMEM_DMABUF = 0x4f
|
||||
SO_DEVMEM_DONTNEED = 0x50
|
||||
SO_DEVMEM_LINEAR = 0x4e
|
||||
SO_DOMAIN = 0x27
|
||||
SO_DONTROUTE = 0x5
|
||||
SO_ERROR = 0x4
|
||||
|
|
|
|||
|
|
@ -108,6 +108,7 @@ const (
|
|||
HIDIOCGRAWINFO = 0x40084803
|
||||
HIDIOCGRDESC = 0x50044802
|
||||
HIDIOCGRDESCSIZE = 0x40044801
|
||||
HIDIOCREVOKE = 0x8004480d
|
||||
HUPCL = 0x400
|
||||
ICANON = 0x2
|
||||
IEXTEN = 0x100
|
||||
|
|
@ -150,9 +151,14 @@ const (
|
|||
NFDBITS = 0x20
|
||||
NLDLY = 0x100
|
||||
NOFLSH = 0x80
|
||||
NS_GET_MNTNS_ID = 0x4008b705
|
||||
NS_GET_NSTYPE = 0x2000b703
|
||||
NS_GET_OWNER_UID = 0x2000b704
|
||||
NS_GET_PARENT = 0x2000b702
|
||||
NS_GET_PID_FROM_PIDNS = 0x4004b706
|
||||
NS_GET_PID_IN_PIDNS = 0x4004b708
|
||||
NS_GET_TGID_FROM_PIDNS = 0x4004b707
|
||||
NS_GET_TGID_IN_PIDNS = 0x4004b709
|
||||
NS_GET_USERNS = 0x2000b701
|
||||
OLCUC = 0x2
|
||||
ONLCR = 0x4
|
||||
|
|
@ -229,6 +235,20 @@ const (
|
|||
PPPIOCUNBRIDGECHAN = 0x20007434
|
||||
PPPIOCXFERUNIT = 0x2000744e
|
||||
PR_SET_PTRACER_ANY = 0xffffffff
|
||||
PTP_CLOCK_GETCAPS = 0x40503d01
|
||||
PTP_CLOCK_GETCAPS2 = 0x40503d0a
|
||||
PTP_ENABLE_PPS = 0x80043d04
|
||||
PTP_ENABLE_PPS2 = 0x80043d0d
|
||||
PTP_EXTTS_REQUEST = 0x80103d02
|
||||
PTP_EXTTS_REQUEST2 = 0x80103d0b
|
||||
PTP_MASK_CLEAR_ALL = 0x20003d13
|
||||
PTP_MASK_EN_SINGLE = 0x80043d14
|
||||
PTP_PEROUT_REQUEST = 0x80383d03
|
||||
PTP_PEROUT_REQUEST2 = 0x80383d0c
|
||||
PTP_PIN_SETFUNC = 0x80603d07
|
||||
PTP_PIN_SETFUNC2 = 0x80603d10
|
||||
PTP_SYS_OFFSET = 0x83403d05
|
||||
PTP_SYS_OFFSET2 = 0x83403d0e
|
||||
PTRACE_GETFPREGS = 0xe
|
||||
PTRACE_GET_THREAD_AREA = 0x19
|
||||
PTRACE_GET_THREAD_AREA_3264 = 0xc4
|
||||
|
|
@ -277,6 +297,8 @@ const (
|
|||
RTC_WIE_ON = 0x2000700f
|
||||
RTC_WKALM_RD = 0x40287010
|
||||
RTC_WKALM_SET = 0x8028700f
|
||||
SCM_DEVMEM_DMABUF = 0x4f
|
||||
SCM_DEVMEM_LINEAR = 0x4e
|
||||
SCM_TIMESTAMPING = 0x25
|
||||
SCM_TIMESTAMPING_OPT_STATS = 0x36
|
||||
SCM_TIMESTAMPING_PKTINFO = 0x3a
|
||||
|
|
@ -315,6 +337,9 @@ const (
|
|||
SO_CNX_ADVICE = 0x35
|
||||
SO_COOKIE = 0x39
|
||||
SO_DETACH_REUSEPORT_BPF = 0x44
|
||||
SO_DEVMEM_DMABUF = 0x4f
|
||||
SO_DEVMEM_DONTNEED = 0x50
|
||||
SO_DEVMEM_LINEAR = 0x4e
|
||||
SO_DOMAIN = 0x1029
|
||||
SO_DONTROUTE = 0x10
|
||||
SO_ERROR = 0x1007
|
||||
|
|
|
|||
|
|
@ -108,6 +108,7 @@ const (
|
|||
HIDIOCGRAWINFO = 0x40084803
|
||||
HIDIOCGRDESC = 0x50044802
|
||||
HIDIOCGRDESCSIZE = 0x40044801
|
||||
HIDIOCREVOKE = 0x8004480d
|
||||
HUPCL = 0x400
|
||||
ICANON = 0x2
|
||||
IEXTEN = 0x100
|
||||
|
|
@ -150,9 +151,14 @@ const (
|
|||
NFDBITS = 0x40
|
||||
NLDLY = 0x100
|
||||
NOFLSH = 0x80
|
||||
NS_GET_MNTNS_ID = 0x4008b705
|
||||
NS_GET_NSTYPE = 0x2000b703
|
||||
NS_GET_OWNER_UID = 0x2000b704
|
||||
NS_GET_PARENT = 0x2000b702
|
||||
NS_GET_PID_FROM_PIDNS = 0x4004b706
|
||||
NS_GET_PID_IN_PIDNS = 0x4004b708
|
||||
NS_GET_TGID_FROM_PIDNS = 0x4004b707
|
||||
NS_GET_TGID_IN_PIDNS = 0x4004b709
|
||||
NS_GET_USERNS = 0x2000b701
|
||||
OLCUC = 0x2
|
||||
ONLCR = 0x4
|
||||
|
|
@ -229,6 +235,20 @@ const (
|
|||
PPPIOCUNBRIDGECHAN = 0x20007434
|
||||
PPPIOCXFERUNIT = 0x2000744e
|
||||
PR_SET_PTRACER_ANY = 0xffffffffffffffff
|
||||
PTP_CLOCK_GETCAPS = 0x40503d01
|
||||
PTP_CLOCK_GETCAPS2 = 0x40503d0a
|
||||
PTP_ENABLE_PPS = 0x80043d04
|
||||
PTP_ENABLE_PPS2 = 0x80043d0d
|
||||
PTP_EXTTS_REQUEST = 0x80103d02
|
||||
PTP_EXTTS_REQUEST2 = 0x80103d0b
|
||||
PTP_MASK_CLEAR_ALL = 0x20003d13
|
||||
PTP_MASK_EN_SINGLE = 0x80043d14
|
||||
PTP_PEROUT_REQUEST = 0x80383d03
|
||||
PTP_PEROUT_REQUEST2 = 0x80383d0c
|
||||
PTP_PIN_SETFUNC = 0x80603d07
|
||||
PTP_PIN_SETFUNC2 = 0x80603d10
|
||||
PTP_SYS_OFFSET = 0x83403d05
|
||||
PTP_SYS_OFFSET2 = 0x83403d0e
|
||||
PTRACE_GETFPREGS = 0xe
|
||||
PTRACE_GET_THREAD_AREA = 0x19
|
||||
PTRACE_GET_THREAD_AREA_3264 = 0xc4
|
||||
|
|
@ -277,6 +297,8 @@ const (
|
|||
RTC_WIE_ON = 0x2000700f
|
||||
RTC_WKALM_RD = 0x40287010
|
||||
RTC_WKALM_SET = 0x8028700f
|
||||
SCM_DEVMEM_DMABUF = 0x4f
|
||||
SCM_DEVMEM_LINEAR = 0x4e
|
||||
SCM_TIMESTAMPING = 0x25
|
||||
SCM_TIMESTAMPING_OPT_STATS = 0x36
|
||||
SCM_TIMESTAMPING_PKTINFO = 0x3a
|
||||
|
|
@ -315,6 +337,9 @@ const (
|
|||
SO_CNX_ADVICE = 0x35
|
||||
SO_COOKIE = 0x39
|
||||
SO_DETACH_REUSEPORT_BPF = 0x44
|
||||
SO_DEVMEM_DMABUF = 0x4f
|
||||
SO_DEVMEM_DONTNEED = 0x50
|
||||
SO_DEVMEM_LINEAR = 0x4e
|
||||
SO_DOMAIN = 0x1029
|
||||
SO_DONTROUTE = 0x10
|
||||
SO_ERROR = 0x1007
|
||||
|
|
|
|||
|
|
@ -108,6 +108,7 @@ const (
|
|||
HIDIOCGRAWINFO = 0x40084803
|
||||
HIDIOCGRDESC = 0x50044802
|
||||
HIDIOCGRDESCSIZE = 0x40044801
|
||||
HIDIOCREVOKE = 0x8004480d
|
||||
HUPCL = 0x400
|
||||
ICANON = 0x2
|
||||
IEXTEN = 0x100
|
||||
|
|
@ -150,9 +151,14 @@ const (
|
|||
NFDBITS = 0x40
|
||||
NLDLY = 0x100
|
||||
NOFLSH = 0x80
|
||||
NS_GET_MNTNS_ID = 0x4008b705
|
||||
NS_GET_NSTYPE = 0x2000b703
|
||||
NS_GET_OWNER_UID = 0x2000b704
|
||||
NS_GET_PARENT = 0x2000b702
|
||||
NS_GET_PID_FROM_PIDNS = 0x4004b706
|
||||
NS_GET_PID_IN_PIDNS = 0x4004b708
|
||||
NS_GET_TGID_FROM_PIDNS = 0x4004b707
|
||||
NS_GET_TGID_IN_PIDNS = 0x4004b709
|
||||
NS_GET_USERNS = 0x2000b701
|
||||
OLCUC = 0x2
|
||||
ONLCR = 0x4
|
||||
|
|
@ -229,6 +235,20 @@ const (
|
|||
PPPIOCUNBRIDGECHAN = 0x20007434
|
||||
PPPIOCXFERUNIT = 0x2000744e
|
||||
PR_SET_PTRACER_ANY = 0xffffffffffffffff
|
||||
PTP_CLOCK_GETCAPS = 0x40503d01
|
||||
PTP_CLOCK_GETCAPS2 = 0x40503d0a
|
||||
PTP_ENABLE_PPS = 0x80043d04
|
||||
PTP_ENABLE_PPS2 = 0x80043d0d
|
||||
PTP_EXTTS_REQUEST = 0x80103d02
|
||||
PTP_EXTTS_REQUEST2 = 0x80103d0b
|
||||
PTP_MASK_CLEAR_ALL = 0x20003d13
|
||||
PTP_MASK_EN_SINGLE = 0x80043d14
|
||||
PTP_PEROUT_REQUEST = 0x80383d03
|
||||
PTP_PEROUT_REQUEST2 = 0x80383d0c
|
||||
PTP_PIN_SETFUNC = 0x80603d07
|
||||
PTP_PIN_SETFUNC2 = 0x80603d10
|
||||
PTP_SYS_OFFSET = 0x83403d05
|
||||
PTP_SYS_OFFSET2 = 0x83403d0e
|
||||
PTRACE_GETFPREGS = 0xe
|
||||
PTRACE_GET_THREAD_AREA = 0x19
|
||||
PTRACE_GET_THREAD_AREA_3264 = 0xc4
|
||||
|
|
@ -277,6 +297,8 @@ const (
|
|||
RTC_WIE_ON = 0x2000700f
|
||||
RTC_WKALM_RD = 0x40287010
|
||||
RTC_WKALM_SET = 0x8028700f
|
||||
SCM_DEVMEM_DMABUF = 0x4f
|
||||
SCM_DEVMEM_LINEAR = 0x4e
|
||||
SCM_TIMESTAMPING = 0x25
|
||||
SCM_TIMESTAMPING_OPT_STATS = 0x36
|
||||
SCM_TIMESTAMPING_PKTINFO = 0x3a
|
||||
|
|
@ -315,6 +337,9 @@ const (
|
|||
SO_CNX_ADVICE = 0x35
|
||||
SO_COOKIE = 0x39
|
||||
SO_DETACH_REUSEPORT_BPF = 0x44
|
||||
SO_DEVMEM_DMABUF = 0x4f
|
||||
SO_DEVMEM_DONTNEED = 0x50
|
||||
SO_DEVMEM_LINEAR = 0x4e
|
||||
SO_DOMAIN = 0x1029
|
||||
SO_DONTROUTE = 0x10
|
||||
SO_ERROR = 0x1007
|
||||
|
|
|
|||
|
|
@ -108,6 +108,7 @@ const (
|
|||
HIDIOCGRAWINFO = 0x40084803
|
||||
HIDIOCGRDESC = 0x50044802
|
||||
HIDIOCGRDESCSIZE = 0x40044801
|
||||
HIDIOCREVOKE = 0x8004480d
|
||||
HUPCL = 0x400
|
||||
ICANON = 0x2
|
||||
IEXTEN = 0x100
|
||||
|
|
@ -150,9 +151,14 @@ const (
|
|||
NFDBITS = 0x20
|
||||
NLDLY = 0x100
|
||||
NOFLSH = 0x80
|
||||
NS_GET_MNTNS_ID = 0x4008b705
|
||||
NS_GET_NSTYPE = 0x2000b703
|
||||
NS_GET_OWNER_UID = 0x2000b704
|
||||
NS_GET_PARENT = 0x2000b702
|
||||
NS_GET_PID_FROM_PIDNS = 0x4004b706
|
||||
NS_GET_PID_IN_PIDNS = 0x4004b708
|
||||
NS_GET_TGID_FROM_PIDNS = 0x4004b707
|
||||
NS_GET_TGID_IN_PIDNS = 0x4004b709
|
||||
NS_GET_USERNS = 0x2000b701
|
||||
OLCUC = 0x2
|
||||
ONLCR = 0x4
|
||||
|
|
@ -229,6 +235,20 @@ const (
|
|||
PPPIOCUNBRIDGECHAN = 0x20007434
|
||||
PPPIOCXFERUNIT = 0x2000744e
|
||||
PR_SET_PTRACER_ANY = 0xffffffff
|
||||
PTP_CLOCK_GETCAPS = 0x40503d01
|
||||
PTP_CLOCK_GETCAPS2 = 0x40503d0a
|
||||
PTP_ENABLE_PPS = 0x80043d04
|
||||
PTP_ENABLE_PPS2 = 0x80043d0d
|
||||
PTP_EXTTS_REQUEST = 0x80103d02
|
||||
PTP_EXTTS_REQUEST2 = 0x80103d0b
|
||||
PTP_MASK_CLEAR_ALL = 0x20003d13
|
||||
PTP_MASK_EN_SINGLE = 0x80043d14
|
||||
PTP_PEROUT_REQUEST = 0x80383d03
|
||||
PTP_PEROUT_REQUEST2 = 0x80383d0c
|
||||
PTP_PIN_SETFUNC = 0x80603d07
|
||||
PTP_PIN_SETFUNC2 = 0x80603d10
|
||||
PTP_SYS_OFFSET = 0x83403d05
|
||||
PTP_SYS_OFFSET2 = 0x83403d0e
|
||||
PTRACE_GETFPREGS = 0xe
|
||||
PTRACE_GET_THREAD_AREA = 0x19
|
||||
PTRACE_GET_THREAD_AREA_3264 = 0xc4
|
||||
|
|
@ -277,6 +297,8 @@ const (
|
|||
RTC_WIE_ON = 0x2000700f
|
||||
RTC_WKALM_RD = 0x40287010
|
||||
RTC_WKALM_SET = 0x8028700f
|
||||
SCM_DEVMEM_DMABUF = 0x4f
|
||||
SCM_DEVMEM_LINEAR = 0x4e
|
||||
SCM_TIMESTAMPING = 0x25
|
||||
SCM_TIMESTAMPING_OPT_STATS = 0x36
|
||||
SCM_TIMESTAMPING_PKTINFO = 0x3a
|
||||
|
|
@ -315,6 +337,9 @@ const (
|
|||
SO_CNX_ADVICE = 0x35
|
||||
SO_COOKIE = 0x39
|
||||
SO_DETACH_REUSEPORT_BPF = 0x44
|
||||
SO_DEVMEM_DMABUF = 0x4f
|
||||
SO_DEVMEM_DONTNEED = 0x50
|
||||
SO_DEVMEM_LINEAR = 0x4e
|
||||
SO_DOMAIN = 0x1029
|
||||
SO_DONTROUTE = 0x10
|
||||
SO_ERROR = 0x1007
|
||||
|
|
|
|||
|
|
@ -108,6 +108,7 @@ const (
|
|||
HIDIOCGRAWINFO = 0x40084803
|
||||
HIDIOCGRDESC = 0x50044802
|
||||
HIDIOCGRDESCSIZE = 0x40044801
|
||||
HIDIOCREVOKE = 0x8004480d
|
||||
HUPCL = 0x4000
|
||||
ICANON = 0x100
|
||||
IEXTEN = 0x400
|
||||
|
|
@ -152,9 +153,14 @@ const (
|
|||
NL3 = 0x300
|
||||
NLDLY = 0x300
|
||||
NOFLSH = 0x80000000
|
||||
NS_GET_MNTNS_ID = 0x4008b705
|
||||
NS_GET_NSTYPE = 0x2000b703
|
||||
NS_GET_OWNER_UID = 0x2000b704
|
||||
NS_GET_PARENT = 0x2000b702
|
||||
NS_GET_PID_FROM_PIDNS = 0x4004b706
|
||||
NS_GET_PID_IN_PIDNS = 0x4004b708
|
||||
NS_GET_TGID_FROM_PIDNS = 0x4004b707
|
||||
NS_GET_TGID_IN_PIDNS = 0x4004b709
|
||||
NS_GET_USERNS = 0x2000b701
|
||||
OLCUC = 0x4
|
||||
ONLCR = 0x2
|
||||
|
|
@ -232,6 +238,20 @@ const (
|
|||
PPPIOCXFERUNIT = 0x2000744e
|
||||
PROT_SAO = 0x10
|
||||
PR_SET_PTRACER_ANY = 0xffffffff
|
||||
PTP_CLOCK_GETCAPS = 0x40503d01
|
||||
PTP_CLOCK_GETCAPS2 = 0x40503d0a
|
||||
PTP_ENABLE_PPS = 0x80043d04
|
||||
PTP_ENABLE_PPS2 = 0x80043d0d
|
||||
PTP_EXTTS_REQUEST = 0x80103d02
|
||||
PTP_EXTTS_REQUEST2 = 0x80103d0b
|
||||
PTP_MASK_CLEAR_ALL = 0x20003d13
|
||||
PTP_MASK_EN_SINGLE = 0x80043d14
|
||||
PTP_PEROUT_REQUEST = 0x80383d03
|
||||
PTP_PEROUT_REQUEST2 = 0x80383d0c
|
||||
PTP_PIN_SETFUNC = 0x80603d07
|
||||
PTP_PIN_SETFUNC2 = 0x80603d10
|
||||
PTP_SYS_OFFSET = 0x83403d05
|
||||
PTP_SYS_OFFSET2 = 0x83403d0e
|
||||
PTRACE_GETEVRREGS = 0x14
|
||||
PTRACE_GETFPREGS = 0xe
|
||||
PTRACE_GETREGS64 = 0x16
|
||||
|
|
@ -332,6 +352,8 @@ const (
|
|||
RTC_WIE_ON = 0x2000700f
|
||||
RTC_WKALM_RD = 0x40287010
|
||||
RTC_WKALM_SET = 0x8028700f
|
||||
SCM_DEVMEM_DMABUF = 0x4f
|
||||
SCM_DEVMEM_LINEAR = 0x4e
|
||||
SCM_TIMESTAMPING = 0x25
|
||||
SCM_TIMESTAMPING_OPT_STATS = 0x36
|
||||
SCM_TIMESTAMPING_PKTINFO = 0x3a
|
||||
|
|
@ -370,6 +392,9 @@ const (
|
|||
SO_CNX_ADVICE = 0x35
|
||||
SO_COOKIE = 0x39
|
||||
SO_DETACH_REUSEPORT_BPF = 0x44
|
||||
SO_DEVMEM_DMABUF = 0x4f
|
||||
SO_DEVMEM_DONTNEED = 0x50
|
||||
SO_DEVMEM_LINEAR = 0x4e
|
||||
SO_DOMAIN = 0x27
|
||||
SO_DONTROUTE = 0x5
|
||||
SO_ERROR = 0x4
|
||||
|
|
|
|||
|
|
@ -108,6 +108,7 @@ const (
|
|||
HIDIOCGRAWINFO = 0x40084803
|
||||
HIDIOCGRDESC = 0x50044802
|
||||
HIDIOCGRDESCSIZE = 0x40044801
|
||||
HIDIOCREVOKE = 0x8004480d
|
||||
HUPCL = 0x4000
|
||||
ICANON = 0x100
|
||||
IEXTEN = 0x400
|
||||
|
|
@ -152,9 +153,14 @@ const (
|
|||
NL3 = 0x300
|
||||
NLDLY = 0x300
|
||||
NOFLSH = 0x80000000
|
||||
NS_GET_MNTNS_ID = 0x4008b705
|
||||
NS_GET_NSTYPE = 0x2000b703
|
||||
NS_GET_OWNER_UID = 0x2000b704
|
||||
NS_GET_PARENT = 0x2000b702
|
||||
NS_GET_PID_FROM_PIDNS = 0x4004b706
|
||||
NS_GET_PID_IN_PIDNS = 0x4004b708
|
||||
NS_GET_TGID_FROM_PIDNS = 0x4004b707
|
||||
NS_GET_TGID_IN_PIDNS = 0x4004b709
|
||||
NS_GET_USERNS = 0x2000b701
|
||||
OLCUC = 0x4
|
||||
ONLCR = 0x2
|
||||
|
|
@ -232,6 +238,20 @@ const (
|
|||
PPPIOCXFERUNIT = 0x2000744e
|
||||
PROT_SAO = 0x10
|
||||
PR_SET_PTRACER_ANY = 0xffffffffffffffff
|
||||
PTP_CLOCK_GETCAPS = 0x40503d01
|
||||
PTP_CLOCK_GETCAPS2 = 0x40503d0a
|
||||
PTP_ENABLE_PPS = 0x80043d04
|
||||
PTP_ENABLE_PPS2 = 0x80043d0d
|
||||
PTP_EXTTS_REQUEST = 0x80103d02
|
||||
PTP_EXTTS_REQUEST2 = 0x80103d0b
|
||||
PTP_MASK_CLEAR_ALL = 0x20003d13
|
||||
PTP_MASK_EN_SINGLE = 0x80043d14
|
||||
PTP_PEROUT_REQUEST = 0x80383d03
|
||||
PTP_PEROUT_REQUEST2 = 0x80383d0c
|
||||
PTP_PIN_SETFUNC = 0x80603d07
|
||||
PTP_PIN_SETFUNC2 = 0x80603d10
|
||||
PTP_SYS_OFFSET = 0x83403d05
|
||||
PTP_SYS_OFFSET2 = 0x83403d0e
|
||||
PTRACE_GETEVRREGS = 0x14
|
||||
PTRACE_GETFPREGS = 0xe
|
||||
PTRACE_GETREGS64 = 0x16
|
||||
|
|
@ -336,6 +356,8 @@ const (
|
|||
RTC_WIE_ON = 0x2000700f
|
||||
RTC_WKALM_RD = 0x40287010
|
||||
RTC_WKALM_SET = 0x8028700f
|
||||
SCM_DEVMEM_DMABUF = 0x4f
|
||||
SCM_DEVMEM_LINEAR = 0x4e
|
||||
SCM_TIMESTAMPING = 0x25
|
||||
SCM_TIMESTAMPING_OPT_STATS = 0x36
|
||||
SCM_TIMESTAMPING_PKTINFO = 0x3a
|
||||
|
|
@ -374,6 +396,9 @@ const (
|
|||
SO_CNX_ADVICE = 0x35
|
||||
SO_COOKIE = 0x39
|
||||
SO_DETACH_REUSEPORT_BPF = 0x44
|
||||
SO_DEVMEM_DMABUF = 0x4f
|
||||
SO_DEVMEM_DONTNEED = 0x50
|
||||
SO_DEVMEM_LINEAR = 0x4e
|
||||
SO_DOMAIN = 0x27
|
||||
SO_DONTROUTE = 0x5
|
||||
SO_ERROR = 0x4
|
||||
|
|
|
|||
|
|
@ -108,6 +108,7 @@ const (
|
|||
HIDIOCGRAWINFO = 0x40084803
|
||||
HIDIOCGRDESC = 0x50044802
|
||||
HIDIOCGRDESCSIZE = 0x40044801
|
||||
HIDIOCREVOKE = 0x8004480d
|
||||
HUPCL = 0x4000
|
||||
ICANON = 0x100
|
||||
IEXTEN = 0x400
|
||||
|
|
@ -152,9 +153,14 @@ const (
|
|||
NL3 = 0x300
|
||||
NLDLY = 0x300
|
||||
NOFLSH = 0x80000000
|
||||
NS_GET_MNTNS_ID = 0x4008b705
|
||||
NS_GET_NSTYPE = 0x2000b703
|
||||
NS_GET_OWNER_UID = 0x2000b704
|
||||
NS_GET_PARENT = 0x2000b702
|
||||
NS_GET_PID_FROM_PIDNS = 0x4004b706
|
||||
NS_GET_PID_IN_PIDNS = 0x4004b708
|
||||
NS_GET_TGID_FROM_PIDNS = 0x4004b707
|
||||
NS_GET_TGID_IN_PIDNS = 0x4004b709
|
||||
NS_GET_USERNS = 0x2000b701
|
||||
OLCUC = 0x4
|
||||
ONLCR = 0x2
|
||||
|
|
@ -232,6 +238,20 @@ const (
|
|||
PPPIOCXFERUNIT = 0x2000744e
|
||||
PROT_SAO = 0x10
|
||||
PR_SET_PTRACER_ANY = 0xffffffffffffffff
|
||||
PTP_CLOCK_GETCAPS = 0x40503d01
|
||||
PTP_CLOCK_GETCAPS2 = 0x40503d0a
|
||||
PTP_ENABLE_PPS = 0x80043d04
|
||||
PTP_ENABLE_PPS2 = 0x80043d0d
|
||||
PTP_EXTTS_REQUEST = 0x80103d02
|
||||
PTP_EXTTS_REQUEST2 = 0x80103d0b
|
||||
PTP_MASK_CLEAR_ALL = 0x20003d13
|
||||
PTP_MASK_EN_SINGLE = 0x80043d14
|
||||
PTP_PEROUT_REQUEST = 0x80383d03
|
||||
PTP_PEROUT_REQUEST2 = 0x80383d0c
|
||||
PTP_PIN_SETFUNC = 0x80603d07
|
||||
PTP_PIN_SETFUNC2 = 0x80603d10
|
||||
PTP_SYS_OFFSET = 0x83403d05
|
||||
PTP_SYS_OFFSET2 = 0x83403d0e
|
||||
PTRACE_GETEVRREGS = 0x14
|
||||
PTRACE_GETFPREGS = 0xe
|
||||
PTRACE_GETREGS64 = 0x16
|
||||
|
|
@ -336,6 +356,8 @@ const (
|
|||
RTC_WIE_ON = 0x2000700f
|
||||
RTC_WKALM_RD = 0x40287010
|
||||
RTC_WKALM_SET = 0x8028700f
|
||||
SCM_DEVMEM_DMABUF = 0x4f
|
||||
SCM_DEVMEM_LINEAR = 0x4e
|
||||
SCM_TIMESTAMPING = 0x25
|
||||
SCM_TIMESTAMPING_OPT_STATS = 0x36
|
||||
SCM_TIMESTAMPING_PKTINFO = 0x3a
|
||||
|
|
@ -374,6 +396,9 @@ const (
|
|||
SO_CNX_ADVICE = 0x35
|
||||
SO_COOKIE = 0x39
|
||||
SO_DETACH_REUSEPORT_BPF = 0x44
|
||||
SO_DEVMEM_DMABUF = 0x4f
|
||||
SO_DEVMEM_DONTNEED = 0x50
|
||||
SO_DEVMEM_LINEAR = 0x4e
|
||||
SO_DOMAIN = 0x27
|
||||
SO_DONTROUTE = 0x5
|
||||
SO_ERROR = 0x4
|
||||
|
|
|
|||
|
|
@ -108,6 +108,7 @@ const (
|
|||
HIDIOCGRAWINFO = 0x80084803
|
||||
HIDIOCGRDESC = 0x90044802
|
||||
HIDIOCGRDESCSIZE = 0x80044801
|
||||
HIDIOCREVOKE = 0x4004480d
|
||||
HUPCL = 0x400
|
||||
ICANON = 0x2
|
||||
IEXTEN = 0x8000
|
||||
|
|
@ -150,9 +151,14 @@ const (
|
|||
NFDBITS = 0x40
|
||||
NLDLY = 0x100
|
||||
NOFLSH = 0x80
|
||||
NS_GET_MNTNS_ID = 0x8008b705
|
||||
NS_GET_NSTYPE = 0xb703
|
||||
NS_GET_OWNER_UID = 0xb704
|
||||
NS_GET_PARENT = 0xb702
|
||||
NS_GET_PID_FROM_PIDNS = 0x8004b706
|
||||
NS_GET_PID_IN_PIDNS = 0x8004b708
|
||||
NS_GET_TGID_FROM_PIDNS = 0x8004b707
|
||||
NS_GET_TGID_IN_PIDNS = 0x8004b709
|
||||
NS_GET_USERNS = 0xb701
|
||||
OLCUC = 0x2
|
||||
ONLCR = 0x4
|
||||
|
|
@ -229,6 +235,20 @@ const (
|
|||
PPPIOCUNBRIDGECHAN = 0x7434
|
||||
PPPIOCXFERUNIT = 0x744e
|
||||
PR_SET_PTRACER_ANY = 0xffffffffffffffff
|
||||
PTP_CLOCK_GETCAPS = 0x80503d01
|
||||
PTP_CLOCK_GETCAPS2 = 0x80503d0a
|
||||
PTP_ENABLE_PPS = 0x40043d04
|
||||
PTP_ENABLE_PPS2 = 0x40043d0d
|
||||
PTP_EXTTS_REQUEST = 0x40103d02
|
||||
PTP_EXTTS_REQUEST2 = 0x40103d0b
|
||||
PTP_MASK_CLEAR_ALL = 0x3d13
|
||||
PTP_MASK_EN_SINGLE = 0x40043d14
|
||||
PTP_PEROUT_REQUEST = 0x40383d03
|
||||
PTP_PEROUT_REQUEST2 = 0x40383d0c
|
||||
PTP_PIN_SETFUNC = 0x40603d07
|
||||
PTP_PIN_SETFUNC2 = 0x40603d10
|
||||
PTP_SYS_OFFSET = 0x43403d05
|
||||
PTP_SYS_OFFSET2 = 0x43403d0e
|
||||
PTRACE_GETFDPIC = 0x21
|
||||
PTRACE_GETFDPIC_EXEC = 0x0
|
||||
PTRACE_GETFDPIC_INTERP = 0x1
|
||||
|
|
@ -268,6 +288,8 @@ const (
|
|||
RTC_WIE_ON = 0x700f
|
||||
RTC_WKALM_RD = 0x80287010
|
||||
RTC_WKALM_SET = 0x4028700f
|
||||
SCM_DEVMEM_DMABUF = 0x4f
|
||||
SCM_DEVMEM_LINEAR = 0x4e
|
||||
SCM_TIMESTAMPING = 0x25
|
||||
SCM_TIMESTAMPING_OPT_STATS = 0x36
|
||||
SCM_TIMESTAMPING_PKTINFO = 0x3a
|
||||
|
|
@ -306,6 +328,9 @@ const (
|
|||
SO_CNX_ADVICE = 0x35
|
||||
SO_COOKIE = 0x39
|
||||
SO_DETACH_REUSEPORT_BPF = 0x44
|
||||
SO_DEVMEM_DMABUF = 0x4f
|
||||
SO_DEVMEM_DONTNEED = 0x50
|
||||
SO_DEVMEM_LINEAR = 0x4e
|
||||
SO_DOMAIN = 0x27
|
||||
SO_DONTROUTE = 0x5
|
||||
SO_ERROR = 0x4
|
||||
|
|
|
|||
|
|
@ -108,6 +108,7 @@ const (
|
|||
HIDIOCGRAWINFO = 0x80084803
|
||||
HIDIOCGRDESC = 0x90044802
|
||||
HIDIOCGRDESCSIZE = 0x80044801
|
||||
HIDIOCREVOKE = 0x4004480d
|
||||
HUPCL = 0x400
|
||||
ICANON = 0x2
|
||||
IEXTEN = 0x8000
|
||||
|
|
@ -150,9 +151,14 @@ const (
|
|||
NFDBITS = 0x40
|
||||
NLDLY = 0x100
|
||||
NOFLSH = 0x80
|
||||
NS_GET_MNTNS_ID = 0x8008b705
|
||||
NS_GET_NSTYPE = 0xb703
|
||||
NS_GET_OWNER_UID = 0xb704
|
||||
NS_GET_PARENT = 0xb702
|
||||
NS_GET_PID_FROM_PIDNS = 0x8004b706
|
||||
NS_GET_PID_IN_PIDNS = 0x8004b708
|
||||
NS_GET_TGID_FROM_PIDNS = 0x8004b707
|
||||
NS_GET_TGID_IN_PIDNS = 0x8004b709
|
||||
NS_GET_USERNS = 0xb701
|
||||
OLCUC = 0x2
|
||||
ONLCR = 0x4
|
||||
|
|
@ -229,6 +235,20 @@ const (
|
|||
PPPIOCUNBRIDGECHAN = 0x7434
|
||||
PPPIOCXFERUNIT = 0x744e
|
||||
PR_SET_PTRACER_ANY = 0xffffffffffffffff
|
||||
PTP_CLOCK_GETCAPS = 0x80503d01
|
||||
PTP_CLOCK_GETCAPS2 = 0x80503d0a
|
||||
PTP_ENABLE_PPS = 0x40043d04
|
||||
PTP_ENABLE_PPS2 = 0x40043d0d
|
||||
PTP_EXTTS_REQUEST = 0x40103d02
|
||||
PTP_EXTTS_REQUEST2 = 0x40103d0b
|
||||
PTP_MASK_CLEAR_ALL = 0x3d13
|
||||
PTP_MASK_EN_SINGLE = 0x40043d14
|
||||
PTP_PEROUT_REQUEST = 0x40383d03
|
||||
PTP_PEROUT_REQUEST2 = 0x40383d0c
|
||||
PTP_PIN_SETFUNC = 0x40603d07
|
||||
PTP_PIN_SETFUNC2 = 0x40603d10
|
||||
PTP_SYS_OFFSET = 0x43403d05
|
||||
PTP_SYS_OFFSET2 = 0x43403d0e
|
||||
PTRACE_DISABLE_TE = 0x5010
|
||||
PTRACE_ENABLE_TE = 0x5009
|
||||
PTRACE_GET_LAST_BREAK = 0x5006
|
||||
|
|
@ -340,6 +360,8 @@ const (
|
|||
RTC_WIE_ON = 0x700f
|
||||
RTC_WKALM_RD = 0x80287010
|
||||
RTC_WKALM_SET = 0x4028700f
|
||||
SCM_DEVMEM_DMABUF = 0x4f
|
||||
SCM_DEVMEM_LINEAR = 0x4e
|
||||
SCM_TIMESTAMPING = 0x25
|
||||
SCM_TIMESTAMPING_OPT_STATS = 0x36
|
||||
SCM_TIMESTAMPING_PKTINFO = 0x3a
|
||||
|
|
@ -378,6 +400,9 @@ const (
|
|||
SO_CNX_ADVICE = 0x35
|
||||
SO_COOKIE = 0x39
|
||||
SO_DETACH_REUSEPORT_BPF = 0x44
|
||||
SO_DEVMEM_DMABUF = 0x4f
|
||||
SO_DEVMEM_DONTNEED = 0x50
|
||||
SO_DEVMEM_LINEAR = 0x4e
|
||||
SO_DOMAIN = 0x27
|
||||
SO_DONTROUTE = 0x5
|
||||
SO_ERROR = 0x4
|
||||
|
|
|
|||
|
|
@ -112,6 +112,7 @@ const (
|
|||
HIDIOCGRAWINFO = 0x40084803
|
||||
HIDIOCGRDESC = 0x50044802
|
||||
HIDIOCGRDESCSIZE = 0x40044801
|
||||
HIDIOCREVOKE = 0x8004480d
|
||||
HUPCL = 0x400
|
||||
ICANON = 0x2
|
||||
IEXTEN = 0x8000
|
||||
|
|
@ -155,9 +156,14 @@ const (
|
|||
NFDBITS = 0x40
|
||||
NLDLY = 0x100
|
||||
NOFLSH = 0x80
|
||||
NS_GET_MNTNS_ID = 0x4008b705
|
||||
NS_GET_NSTYPE = 0x2000b703
|
||||
NS_GET_OWNER_UID = 0x2000b704
|
||||
NS_GET_PARENT = 0x2000b702
|
||||
NS_GET_PID_FROM_PIDNS = 0x4004b706
|
||||
NS_GET_PID_IN_PIDNS = 0x4004b708
|
||||
NS_GET_TGID_FROM_PIDNS = 0x4004b707
|
||||
NS_GET_TGID_IN_PIDNS = 0x4004b709
|
||||
NS_GET_USERNS = 0x2000b701
|
||||
OLCUC = 0x2
|
||||
ONLCR = 0x4
|
||||
|
|
@ -234,6 +240,20 @@ const (
|
|||
PPPIOCUNBRIDGECHAN = 0x20007434
|
||||
PPPIOCXFERUNIT = 0x2000744e
|
||||
PR_SET_PTRACER_ANY = 0xffffffffffffffff
|
||||
PTP_CLOCK_GETCAPS = 0x40503d01
|
||||
PTP_CLOCK_GETCAPS2 = 0x40503d0a
|
||||
PTP_ENABLE_PPS = 0x80043d04
|
||||
PTP_ENABLE_PPS2 = 0x80043d0d
|
||||
PTP_EXTTS_REQUEST = 0x80103d02
|
||||
PTP_EXTTS_REQUEST2 = 0x80103d0b
|
||||
PTP_MASK_CLEAR_ALL = 0x20003d13
|
||||
PTP_MASK_EN_SINGLE = 0x80043d14
|
||||
PTP_PEROUT_REQUEST = 0x80383d03
|
||||
PTP_PEROUT_REQUEST2 = 0x80383d0c
|
||||
PTP_PIN_SETFUNC = 0x80603d07
|
||||
PTP_PIN_SETFUNC2 = 0x80603d10
|
||||
PTP_SYS_OFFSET = 0x83403d05
|
||||
PTP_SYS_OFFSET2 = 0x83403d0e
|
||||
PTRACE_GETFPAREGS = 0x14
|
||||
PTRACE_GETFPREGS = 0xe
|
||||
PTRACE_GETFPREGS64 = 0x19
|
||||
|
|
@ -331,6 +351,8 @@ const (
|
|||
RTC_WIE_ON = 0x2000700f
|
||||
RTC_WKALM_RD = 0x40287010
|
||||
RTC_WKALM_SET = 0x8028700f
|
||||
SCM_DEVMEM_DMABUF = 0x58
|
||||
SCM_DEVMEM_LINEAR = 0x57
|
||||
SCM_TIMESTAMPING = 0x23
|
||||
SCM_TIMESTAMPING_OPT_STATS = 0x38
|
||||
SCM_TIMESTAMPING_PKTINFO = 0x3c
|
||||
|
|
@ -417,6 +439,9 @@ const (
|
|||
SO_CNX_ADVICE = 0x37
|
||||
SO_COOKIE = 0x3b
|
||||
SO_DETACH_REUSEPORT_BPF = 0x47
|
||||
SO_DEVMEM_DMABUF = 0x58
|
||||
SO_DEVMEM_DONTNEED = 0x59
|
||||
SO_DEVMEM_LINEAR = 0x57
|
||||
SO_DOMAIN = 0x1029
|
||||
SO_DONTROUTE = 0x10
|
||||
SO_ERROR = 0x1007
|
||||
|
|
|
|||
|
|
@ -581,6 +581,8 @@ const (
|
|||
AT_EMPTY_PATH = 0x1000
|
||||
AT_REMOVEDIR = 0x200
|
||||
RENAME_NOREPLACE = 1 << 0
|
||||
ST_RDONLY = 1
|
||||
ST_NOSUID = 2
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
|
|||
|
|
@ -841,6 +841,26 @@ var libc_pthread_fchdir_np_trampoline_addr uintptr
|
|||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func connectx(fd int, endpoints *SaEndpoints, associd SaeAssocID, flags uint32, iov []Iovec, n *uintptr, connid *SaeConnID) (err error) {
|
||||
var _p0 unsafe.Pointer
|
||||
if len(iov) > 0 {
|
||||
_p0 = unsafe.Pointer(&iov[0])
|
||||
} else {
|
||||
_p0 = unsafe.Pointer(&_zero)
|
||||
}
|
||||
_, _, e1 := syscall_syscall9(libc_connectx_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(endpoints)), uintptr(associd), uintptr(flags), uintptr(_p0), uintptr(len(iov)), uintptr(unsafe.Pointer(n)), uintptr(unsafe.Pointer(connid)), 0)
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
var libc_connectx_trampoline_addr uintptr
|
||||
|
||||
//go:cgo_import_dynamic libc_connectx connectx "/usr/lib/libSystem.B.dylib"
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error) {
|
||||
_, _, e1 := syscall_syscall6(libc_sendfile_trampoline_addr, uintptr(infd), uintptr(outfd), uintptr(offset), uintptr(unsafe.Pointer(len)), uintptr(hdtr), uintptr(flags))
|
||||
if e1 != 0 {
|
||||
|
|
|
|||
|
|
@ -248,6 +248,11 @@ TEXT libc_pthread_fchdir_np_trampoline<>(SB),NOSPLIT,$0-0
|
|||
GLOBL ·libc_pthread_fchdir_np_trampoline_addr(SB), RODATA, $8
|
||||
DATA ·libc_pthread_fchdir_np_trampoline_addr(SB)/8, $libc_pthread_fchdir_np_trampoline<>(SB)
|
||||
|
||||
TEXT libc_connectx_trampoline<>(SB),NOSPLIT,$0-0
|
||||
JMP libc_connectx(SB)
|
||||
GLOBL ·libc_connectx_trampoline_addr(SB), RODATA, $8
|
||||
DATA ·libc_connectx_trampoline_addr(SB)/8, $libc_connectx_trampoline<>(SB)
|
||||
|
||||
TEXT libc_sendfile_trampoline<>(SB),NOSPLIT,$0-0
|
||||
JMP libc_sendfile(SB)
|
||||
GLOBL ·libc_sendfile_trampoline_addr(SB), RODATA, $8
|
||||
|
|
|
|||
|
|
@ -841,6 +841,26 @@ var libc_pthread_fchdir_np_trampoline_addr uintptr
|
|||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func connectx(fd int, endpoints *SaEndpoints, associd SaeAssocID, flags uint32, iov []Iovec, n *uintptr, connid *SaeConnID) (err error) {
|
||||
var _p0 unsafe.Pointer
|
||||
if len(iov) > 0 {
|
||||
_p0 = unsafe.Pointer(&iov[0])
|
||||
} else {
|
||||
_p0 = unsafe.Pointer(&_zero)
|
||||
}
|
||||
_, _, e1 := syscall_syscall9(libc_connectx_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(endpoints)), uintptr(associd), uintptr(flags), uintptr(_p0), uintptr(len(iov)), uintptr(unsafe.Pointer(n)), uintptr(unsafe.Pointer(connid)), 0)
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
var libc_connectx_trampoline_addr uintptr
|
||||
|
||||
//go:cgo_import_dynamic libc_connectx connectx "/usr/lib/libSystem.B.dylib"
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error) {
|
||||
_, _, e1 := syscall_syscall6(libc_sendfile_trampoline_addr, uintptr(infd), uintptr(outfd), uintptr(offset), uintptr(unsafe.Pointer(len)), uintptr(hdtr), uintptr(flags))
|
||||
if e1 != 0 {
|
||||
|
|
|
|||
|
|
@ -248,6 +248,11 @@ TEXT libc_pthread_fchdir_np_trampoline<>(SB),NOSPLIT,$0-0
|
|||
GLOBL ·libc_pthread_fchdir_np_trampoline_addr(SB), RODATA, $8
|
||||
DATA ·libc_pthread_fchdir_np_trampoline_addr(SB)/8, $libc_pthread_fchdir_np_trampoline<>(SB)
|
||||
|
||||
TEXT libc_connectx_trampoline<>(SB),NOSPLIT,$0-0
|
||||
JMP libc_connectx(SB)
|
||||
GLOBL ·libc_connectx_trampoline_addr(SB), RODATA, $8
|
||||
DATA ·libc_connectx_trampoline_addr(SB)/8, $libc_connectx_trampoline<>(SB)
|
||||
|
||||
TEXT libc_sendfile_trampoline<>(SB),NOSPLIT,$0-0
|
||||
JMP libc_sendfile(SB)
|
||||
GLOBL ·libc_sendfile_trampoline_addr(SB), RODATA, $8
|
||||
|
|
|
|||
|
|
@ -592,6 +592,16 @@ func ClockGettime(clockid int32, time *Timespec) (err error) {
|
|||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func ClockSettime(clockid int32, time *Timespec) (err error) {
|
||||
_, _, e1 := Syscall(SYS_CLOCK_SETTIME, uintptr(clockid), uintptr(unsafe.Pointer(time)), 0)
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func ClockNanosleep(clockid int32, flags int, request *Timespec, remain *Timespec) (err error) {
|
||||
_, _, e1 := Syscall6(SYS_CLOCK_NANOSLEEP, uintptr(clockid), uintptr(flags), uintptr(unsafe.Pointer(request)), uintptr(unsafe.Pointer(remain)), 0, 0)
|
||||
if e1 != 0 {
|
||||
|
|
@ -971,23 +981,6 @@ func Getpriority(which int, who int) (prio int, err error) {
|
|||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func Getrandom(buf []byte, flags int) (n int, err error) {
|
||||
var _p0 unsafe.Pointer
|
||||
if len(buf) > 0 {
|
||||
_p0 = unsafe.Pointer(&buf[0])
|
||||
} else {
|
||||
_p0 = unsafe.Pointer(&_zero)
|
||||
}
|
||||
r0, _, e1 := Syscall(SYS_GETRANDOM, uintptr(_p0), uintptr(len(buf)), uintptr(flags))
|
||||
n = int(r0)
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func Getrusage(who int, rusage *Rusage) (err error) {
|
||||
_, _, e1 := RawSyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
|
||||
if e1 != 0 {
|
||||
|
|
|
|||
|
|
@ -341,6 +341,7 @@ const (
|
|||
SYS_STATX = 332
|
||||
SYS_IO_PGETEVENTS = 333
|
||||
SYS_RSEQ = 334
|
||||
SYS_URETPROBE = 335
|
||||
SYS_PIDFD_SEND_SIGNAL = 424
|
||||
SYS_IO_URING_SETUP = 425
|
||||
SYS_IO_URING_ENTER = 426
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ const (
|
|||
SYS_SPLICE = 76
|
||||
SYS_TEE = 77
|
||||
SYS_READLINKAT = 78
|
||||
SYS_FSTATAT = 79
|
||||
SYS_NEWFSTATAT = 79
|
||||
SYS_FSTAT = 80
|
||||
SYS_SYNC = 81
|
||||
SYS_FSYNC = 82
|
||||
|
|
|
|||
|
|
@ -84,6 +84,8 @@ const (
|
|||
SYS_SPLICE = 76
|
||||
SYS_TEE = 77
|
||||
SYS_READLINKAT = 78
|
||||
SYS_NEWFSTATAT = 79
|
||||
SYS_FSTAT = 80
|
||||
SYS_SYNC = 81
|
||||
SYS_FSYNC = 82
|
||||
SYS_FDATASYNC = 83
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ const (
|
|||
SYS_SPLICE = 76
|
||||
SYS_TEE = 77
|
||||
SYS_READLINKAT = 78
|
||||
SYS_FSTATAT = 79
|
||||
SYS_NEWFSTATAT = 79
|
||||
SYS_FSTAT = 80
|
||||
SYS_SYNC = 81
|
||||
SYS_FSYNC = 82
|
||||
|
|
|
|||
|
|
@ -306,6 +306,19 @@ type XVSockPgen struct {
|
|||
|
||||
type _Socklen uint32
|
||||
|
||||
type SaeAssocID uint32
|
||||
|
||||
type SaeConnID uint32
|
||||
|
||||
type SaEndpoints struct {
|
||||
Srcif uint32
|
||||
Srcaddr *RawSockaddr
|
||||
Srcaddrlen uint32
|
||||
Dstaddr *RawSockaddr
|
||||
Dstaddrlen uint32
|
||||
_ [4]byte
|
||||
}
|
||||
|
||||
type Xucred struct {
|
||||
Version uint32
|
||||
Uid uint32
|
||||
|
|
@ -449,11 +462,14 @@ type FdSet struct {
|
|||
|
||||
const (
|
||||
SizeofIfMsghdr = 0x70
|
||||
SizeofIfMsghdr2 = 0xa0
|
||||
SizeofIfData = 0x60
|
||||
SizeofIfData64 = 0x80
|
||||
SizeofIfaMsghdr = 0x14
|
||||
SizeofIfmaMsghdr = 0x10
|
||||
SizeofIfmaMsghdr2 = 0x14
|
||||
SizeofRtMsghdr = 0x5c
|
||||
SizeofRtMsghdr2 = 0x5c
|
||||
SizeofRtMetrics = 0x38
|
||||
)
|
||||
|
||||
|
|
@ -467,6 +483,20 @@ type IfMsghdr struct {
|
|||
Data IfData
|
||||
}
|
||||
|
||||
type IfMsghdr2 struct {
|
||||
Msglen uint16
|
||||
Version uint8
|
||||
Type uint8
|
||||
Addrs int32
|
||||
Flags int32
|
||||
Index uint16
|
||||
Snd_len int32
|
||||
Snd_maxlen int32
|
||||
Snd_drops int32
|
||||
Timer int32
|
||||
Data IfData64
|
||||
}
|
||||
|
||||
type IfData struct {
|
||||
Type uint8
|
||||
Typelen uint8
|
||||
|
|
@ -499,6 +529,34 @@ type IfData struct {
|
|||
Reserved2 uint32
|
||||
}
|
||||
|
||||
type IfData64 struct {
|
||||
Type uint8
|
||||
Typelen uint8
|
||||
Physical uint8
|
||||
Addrlen uint8
|
||||
Hdrlen uint8
|
||||
Recvquota uint8
|
||||
Xmitquota uint8
|
||||
Unused1 uint8
|
||||
Mtu uint32
|
||||
Metric uint32
|
||||
Baudrate uint64
|
||||
Ipackets uint64
|
||||
Ierrors uint64
|
||||
Opackets uint64
|
||||
Oerrors uint64
|
||||
Collisions uint64
|
||||
Ibytes uint64
|
||||
Obytes uint64
|
||||
Imcasts uint64
|
||||
Omcasts uint64
|
||||
Iqdrops uint64
|
||||
Noproto uint64
|
||||
Recvtiming uint32
|
||||
Xmittiming uint32
|
||||
Lastchange Timeval32
|
||||
}
|
||||
|
||||
type IfaMsghdr struct {
|
||||
Msglen uint16
|
||||
Version uint8
|
||||
|
|
@ -544,6 +602,21 @@ type RtMsghdr struct {
|
|||
Rmx RtMetrics
|
||||
}
|
||||
|
||||
type RtMsghdr2 struct {
|
||||
Msglen uint16
|
||||
Version uint8
|
||||
Type uint8
|
||||
Index uint16
|
||||
Flags int32
|
||||
Addrs int32
|
||||
Refcnt int32
|
||||
Parentflags int32
|
||||
Reserved int32
|
||||
Use int32
|
||||
Inits uint32
|
||||
Rmx RtMetrics
|
||||
}
|
||||
|
||||
type RtMetrics struct {
|
||||
Locks uint32
|
||||
Mtu uint32
|
||||
|
|
|
|||
|
|
@ -306,6 +306,19 @@ type XVSockPgen struct {
|
|||
|
||||
type _Socklen uint32
|
||||
|
||||
type SaeAssocID uint32
|
||||
|
||||
type SaeConnID uint32
|
||||
|
||||
type SaEndpoints struct {
|
||||
Srcif uint32
|
||||
Srcaddr *RawSockaddr
|
||||
Srcaddrlen uint32
|
||||
Dstaddr *RawSockaddr
|
||||
Dstaddrlen uint32
|
||||
_ [4]byte
|
||||
}
|
||||
|
||||
type Xucred struct {
|
||||
Version uint32
|
||||
Uid uint32
|
||||
|
|
@ -449,11 +462,14 @@ type FdSet struct {
|
|||
|
||||
const (
|
||||
SizeofIfMsghdr = 0x70
|
||||
SizeofIfMsghdr2 = 0xa0
|
||||
SizeofIfData = 0x60
|
||||
SizeofIfData64 = 0x80
|
||||
SizeofIfaMsghdr = 0x14
|
||||
SizeofIfmaMsghdr = 0x10
|
||||
SizeofIfmaMsghdr2 = 0x14
|
||||
SizeofRtMsghdr = 0x5c
|
||||
SizeofRtMsghdr2 = 0x5c
|
||||
SizeofRtMetrics = 0x38
|
||||
)
|
||||
|
||||
|
|
@ -467,6 +483,20 @@ type IfMsghdr struct {
|
|||
Data IfData
|
||||
}
|
||||
|
||||
type IfMsghdr2 struct {
|
||||
Msglen uint16
|
||||
Version uint8
|
||||
Type uint8
|
||||
Addrs int32
|
||||
Flags int32
|
||||
Index uint16
|
||||
Snd_len int32
|
||||
Snd_maxlen int32
|
||||
Snd_drops int32
|
||||
Timer int32
|
||||
Data IfData64
|
||||
}
|
||||
|
||||
type IfData struct {
|
||||
Type uint8
|
||||
Typelen uint8
|
||||
|
|
@ -499,6 +529,34 @@ type IfData struct {
|
|||
Reserved2 uint32
|
||||
}
|
||||
|
||||
type IfData64 struct {
|
||||
Type uint8
|
||||
Typelen uint8
|
||||
Physical uint8
|
||||
Addrlen uint8
|
||||
Hdrlen uint8
|
||||
Recvquota uint8
|
||||
Xmitquota uint8
|
||||
Unused1 uint8
|
||||
Mtu uint32
|
||||
Metric uint32
|
||||
Baudrate uint64
|
||||
Ipackets uint64
|
||||
Ierrors uint64
|
||||
Opackets uint64
|
||||
Oerrors uint64
|
||||
Collisions uint64
|
||||
Ibytes uint64
|
||||
Obytes uint64
|
||||
Imcasts uint64
|
||||
Omcasts uint64
|
||||
Iqdrops uint64
|
||||
Noproto uint64
|
||||
Recvtiming uint32
|
||||
Xmittiming uint32
|
||||
Lastchange Timeval32
|
||||
}
|
||||
|
||||
type IfaMsghdr struct {
|
||||
Msglen uint16
|
||||
Version uint8
|
||||
|
|
@ -544,6 +602,21 @@ type RtMsghdr struct {
|
|||
Rmx RtMetrics
|
||||
}
|
||||
|
||||
type RtMsghdr2 struct {
|
||||
Msglen uint16
|
||||
Version uint8
|
||||
Type uint8
|
||||
Index uint16
|
||||
Flags int32
|
||||
Addrs int32
|
||||
Refcnt int32
|
||||
Parentflags int32
|
||||
Reserved int32
|
||||
Use int32
|
||||
Inits uint32
|
||||
Rmx RtMetrics
|
||||
}
|
||||
|
||||
type RtMetrics struct {
|
||||
Locks uint32
|
||||
Mtu uint32
|
||||
|
|
|
|||
|
|
@ -625,6 +625,7 @@ const (
|
|||
POLLRDNORM = 0x40
|
||||
POLLWRBAND = 0x100
|
||||
POLLWRNORM = 0x4
|
||||
POLLRDHUP = 0x4000
|
||||
)
|
||||
|
||||
type CapRights struct {
|
||||
|
|
|
|||
|
|
@ -630,6 +630,7 @@ const (
|
|||
POLLRDNORM = 0x40
|
||||
POLLWRBAND = 0x100
|
||||
POLLWRNORM = 0x4
|
||||
POLLRDHUP = 0x4000
|
||||
)
|
||||
|
||||
type CapRights struct {
|
||||
|
|
|
|||
|
|
@ -616,6 +616,7 @@ const (
|
|||
POLLRDNORM = 0x40
|
||||
POLLWRBAND = 0x100
|
||||
POLLWRNORM = 0x4
|
||||
POLLRDHUP = 0x4000
|
||||
)
|
||||
|
||||
type CapRights struct {
|
||||
|
|
|
|||
|
|
@ -610,6 +610,7 @@ const (
|
|||
POLLRDNORM = 0x40
|
||||
POLLWRBAND = 0x100
|
||||
POLLWRNORM = 0x4
|
||||
POLLRDHUP = 0x4000
|
||||
)
|
||||
|
||||
type CapRights struct {
|
||||
|
|
|
|||
|
|
@ -612,6 +612,7 @@ const (
|
|||
POLLRDNORM = 0x40
|
||||
POLLWRBAND = 0x100
|
||||
POLLWRNORM = 0x4
|
||||
POLLRDHUP = 0x4000
|
||||
)
|
||||
|
||||
type CapRights struct {
|
||||
|
|
|
|||
|
|
@ -87,31 +87,35 @@ type StatxTimestamp struct {
|
|||
}
|
||||
|
||||
type Statx_t struct {
|
||||
Mask uint32
|
||||
Blksize uint32
|
||||
Attributes uint64
|
||||
Nlink uint32
|
||||
Uid uint32
|
||||
Gid uint32
|
||||
Mode uint16
|
||||
_ [1]uint16
|
||||
Ino uint64
|
||||
Size uint64
|
||||
Blocks uint64
|
||||
Attributes_mask uint64
|
||||
Atime StatxTimestamp
|
||||
Btime StatxTimestamp
|
||||
Ctime StatxTimestamp
|
||||
Mtime StatxTimestamp
|
||||
Rdev_major uint32
|
||||
Rdev_minor uint32
|
||||
Dev_major uint32
|
||||
Dev_minor uint32
|
||||
Mnt_id uint64
|
||||
Dio_mem_align uint32
|
||||
Dio_offset_align uint32
|
||||
Subvol uint64
|
||||
_ [11]uint64
|
||||
Mask uint32
|
||||
Blksize uint32
|
||||
Attributes uint64
|
||||
Nlink uint32
|
||||
Uid uint32
|
||||
Gid uint32
|
||||
Mode uint16
|
||||
_ [1]uint16
|
||||
Ino uint64
|
||||
Size uint64
|
||||
Blocks uint64
|
||||
Attributes_mask uint64
|
||||
Atime StatxTimestamp
|
||||
Btime StatxTimestamp
|
||||
Ctime StatxTimestamp
|
||||
Mtime StatxTimestamp
|
||||
Rdev_major uint32
|
||||
Rdev_minor uint32
|
||||
Dev_major uint32
|
||||
Dev_minor uint32
|
||||
Mnt_id uint64
|
||||
Dio_mem_align uint32
|
||||
Dio_offset_align uint32
|
||||
Subvol uint64
|
||||
Atomic_write_unit_min uint32
|
||||
Atomic_write_unit_max uint32
|
||||
Atomic_write_segments_max uint32
|
||||
_ [1]uint32
|
||||
_ [9]uint64
|
||||
}
|
||||
|
||||
type Fsid struct {
|
||||
|
|
@ -516,6 +520,29 @@ type TCPInfo struct {
|
|||
Total_rto_time uint32
|
||||
}
|
||||
|
||||
type TCPVegasInfo struct {
|
||||
Enabled uint32
|
||||
Rttcnt uint32
|
||||
Rtt uint32
|
||||
Minrtt uint32
|
||||
}
|
||||
|
||||
type TCPDCTCPInfo struct {
|
||||
Enabled uint16
|
||||
Ce_state uint16
|
||||
Alpha uint32
|
||||
Ab_ecn uint32
|
||||
Ab_tot uint32
|
||||
}
|
||||
|
||||
type TCPBBRInfo struct {
|
||||
Bw_lo uint32
|
||||
Bw_hi uint32
|
||||
Min_rtt uint32
|
||||
Pacing_gain uint32
|
||||
Cwnd_gain uint32
|
||||
}
|
||||
|
||||
type CanFilter struct {
|
||||
Id uint32
|
||||
Mask uint32
|
||||
|
|
@ -557,6 +584,7 @@ const (
|
|||
SizeofICMPv6Filter = 0x20
|
||||
SizeofUcred = 0xc
|
||||
SizeofTCPInfo = 0xf8
|
||||
SizeofTCPCCInfo = 0x14
|
||||
SizeofCanFilter = 0x8
|
||||
SizeofTCPRepairOpt = 0x8
|
||||
)
|
||||
|
|
@ -1724,12 +1752,6 @@ const (
|
|||
IFLA_IPVLAN_UNSPEC = 0x0
|
||||
IFLA_IPVLAN_MODE = 0x1
|
||||
IFLA_IPVLAN_FLAGS = 0x2
|
||||
NETKIT_NEXT = -0x1
|
||||
NETKIT_PASS = 0x0
|
||||
NETKIT_DROP = 0x2
|
||||
NETKIT_REDIRECT = 0x7
|
||||
NETKIT_L2 = 0x0
|
||||
NETKIT_L3 = 0x1
|
||||
IFLA_NETKIT_UNSPEC = 0x0
|
||||
IFLA_NETKIT_PEER_INFO = 0x1
|
||||
IFLA_NETKIT_PRIMARY = 0x2
|
||||
|
|
@ -1768,6 +1790,7 @@ const (
|
|||
IFLA_VXLAN_DF = 0x1d
|
||||
IFLA_VXLAN_VNIFILTER = 0x1e
|
||||
IFLA_VXLAN_LOCALBYPASS = 0x1f
|
||||
IFLA_VXLAN_LABEL_POLICY = 0x20
|
||||
IFLA_GENEVE_UNSPEC = 0x0
|
||||
IFLA_GENEVE_ID = 0x1
|
||||
IFLA_GENEVE_REMOTE = 0x2
|
||||
|
|
@ -1797,6 +1820,8 @@ const (
|
|||
IFLA_GTP_ROLE = 0x4
|
||||
IFLA_GTP_CREATE_SOCKETS = 0x5
|
||||
IFLA_GTP_RESTART_COUNT = 0x6
|
||||
IFLA_GTP_LOCAL = 0x7
|
||||
IFLA_GTP_LOCAL6 = 0x8
|
||||
IFLA_BOND_UNSPEC = 0x0
|
||||
IFLA_BOND_MODE = 0x1
|
||||
IFLA_BOND_ACTIVE_SLAVE = 0x2
|
||||
|
|
@ -1829,6 +1854,7 @@ const (
|
|||
IFLA_BOND_AD_LACP_ACTIVE = 0x1d
|
||||
IFLA_BOND_MISSED_MAX = 0x1e
|
||||
IFLA_BOND_NS_IP6_TARGET = 0x1f
|
||||
IFLA_BOND_COUPLED_CONTROL = 0x20
|
||||
IFLA_BOND_AD_INFO_UNSPEC = 0x0
|
||||
IFLA_BOND_AD_INFO_AGGREGATOR = 0x1
|
||||
IFLA_BOND_AD_INFO_NUM_PORTS = 0x2
|
||||
|
|
@ -1897,6 +1923,7 @@ const (
|
|||
IFLA_HSR_SEQ_NR = 0x5
|
||||
IFLA_HSR_VERSION = 0x6
|
||||
IFLA_HSR_PROTOCOL = 0x7
|
||||
IFLA_HSR_INTERLINK = 0x8
|
||||
IFLA_STATS_UNSPEC = 0x0
|
||||
IFLA_STATS_LINK_64 = 0x1
|
||||
IFLA_STATS_LINK_XSTATS = 0x2
|
||||
|
|
@ -1949,6 +1976,15 @@ const (
|
|||
IFLA_DSA_MASTER = 0x1
|
||||
)
|
||||
|
||||
const (
|
||||
NETKIT_NEXT = -0x1
|
||||
NETKIT_PASS = 0x0
|
||||
NETKIT_DROP = 0x2
|
||||
NETKIT_REDIRECT = 0x7
|
||||
NETKIT_L2 = 0x0
|
||||
NETKIT_L3 = 0x1
|
||||
)
|
||||
|
||||
const (
|
||||
NF_INET_PRE_ROUTING = 0x0
|
||||
NF_INET_LOCAL_IN = 0x1
|
||||
|
|
@ -2486,7 +2522,7 @@ type XDPMmapOffsets struct {
|
|||
type XDPUmemReg struct {
|
||||
Addr uint64
|
||||
Len uint64
|
||||
Chunk_size uint32
|
||||
Size uint32
|
||||
Headroom uint32
|
||||
Flags uint32
|
||||
Tx_metadata_len uint32
|
||||
|
|
@ -2558,8 +2594,8 @@ const (
|
|||
SOF_TIMESTAMPING_BIND_PHC = 0x8000
|
||||
SOF_TIMESTAMPING_OPT_ID_TCP = 0x10000
|
||||
|
||||
SOF_TIMESTAMPING_LAST = 0x10000
|
||||
SOF_TIMESTAMPING_MASK = 0x1ffff
|
||||
SOF_TIMESTAMPING_LAST = 0x20000
|
||||
SOF_TIMESTAMPING_MASK = 0x3ffff
|
||||
|
||||
SCM_TSTAMP_SND = 0x0
|
||||
SCM_TSTAMP_SCHED = 0x1
|
||||
|
|
@ -3505,7 +3541,7 @@ type Nhmsg struct {
|
|||
type NexthopGrp struct {
|
||||
Id uint32
|
||||
Weight uint8
|
||||
Resvd1 uint8
|
||||
High uint8
|
||||
Resvd2 uint16
|
||||
}
|
||||
|
||||
|
|
@ -3766,7 +3802,7 @@ const (
|
|||
ETHTOOL_MSG_PSE_GET = 0x24
|
||||
ETHTOOL_MSG_PSE_SET = 0x25
|
||||
ETHTOOL_MSG_RSS_GET = 0x26
|
||||
ETHTOOL_MSG_USER_MAX = 0x2b
|
||||
ETHTOOL_MSG_USER_MAX = 0x2d
|
||||
ETHTOOL_MSG_KERNEL_NONE = 0x0
|
||||
ETHTOOL_MSG_STRSET_GET_REPLY = 0x1
|
||||
ETHTOOL_MSG_LINKINFO_GET_REPLY = 0x2
|
||||
|
|
@ -3806,12 +3842,15 @@ const (
|
|||
ETHTOOL_MSG_MODULE_NTF = 0x24
|
||||
ETHTOOL_MSG_PSE_GET_REPLY = 0x25
|
||||
ETHTOOL_MSG_RSS_GET_REPLY = 0x26
|
||||
ETHTOOL_MSG_KERNEL_MAX = 0x2b
|
||||
ETHTOOL_MSG_KERNEL_MAX = 0x2e
|
||||
ETHTOOL_FLAG_COMPACT_BITSETS = 0x1
|
||||
ETHTOOL_FLAG_OMIT_REPLY = 0x2
|
||||
ETHTOOL_FLAG_STATS = 0x4
|
||||
ETHTOOL_A_HEADER_UNSPEC = 0x0
|
||||
ETHTOOL_A_HEADER_DEV_INDEX = 0x1
|
||||
ETHTOOL_A_HEADER_DEV_NAME = 0x2
|
||||
ETHTOOL_A_HEADER_FLAGS = 0x3
|
||||
ETHTOOL_A_HEADER_MAX = 0x3
|
||||
ETHTOOL_A_HEADER_MAX = 0x4
|
||||
ETHTOOL_A_BITSET_BIT_UNSPEC = 0x0
|
||||
ETHTOOL_A_BITSET_BIT_INDEX = 0x1
|
||||
ETHTOOL_A_BITSET_BIT_NAME = 0x2
|
||||
|
|
@ -3948,7 +3987,7 @@ const (
|
|||
ETHTOOL_A_COALESCE_RATE_SAMPLE_INTERVAL = 0x17
|
||||
ETHTOOL_A_COALESCE_USE_CQE_MODE_TX = 0x18
|
||||
ETHTOOL_A_COALESCE_USE_CQE_MODE_RX = 0x19
|
||||
ETHTOOL_A_COALESCE_MAX = 0x1c
|
||||
ETHTOOL_A_COALESCE_MAX = 0x1e
|
||||
ETHTOOL_A_PAUSE_UNSPEC = 0x0
|
||||
ETHTOOL_A_PAUSE_HEADER = 0x1
|
||||
ETHTOOL_A_PAUSE_AUTONEG = 0x2
|
||||
|
|
@ -3992,11 +4031,11 @@ const (
|
|||
ETHTOOL_A_CABLE_RESULT_UNSPEC = 0x0
|
||||
ETHTOOL_A_CABLE_RESULT_PAIR = 0x1
|
||||
ETHTOOL_A_CABLE_RESULT_CODE = 0x2
|
||||
ETHTOOL_A_CABLE_RESULT_MAX = 0x2
|
||||
ETHTOOL_A_CABLE_RESULT_MAX = 0x3
|
||||
ETHTOOL_A_CABLE_FAULT_LENGTH_UNSPEC = 0x0
|
||||
ETHTOOL_A_CABLE_FAULT_LENGTH_PAIR = 0x1
|
||||
ETHTOOL_A_CABLE_FAULT_LENGTH_CM = 0x2
|
||||
ETHTOOL_A_CABLE_FAULT_LENGTH_MAX = 0x2
|
||||
ETHTOOL_A_CABLE_FAULT_LENGTH_MAX = 0x3
|
||||
ETHTOOL_A_CABLE_TEST_NTF_STATUS_UNSPEC = 0x0
|
||||
ETHTOOL_A_CABLE_TEST_NTF_STATUS_STARTED = 0x1
|
||||
ETHTOOL_A_CABLE_TEST_NTF_STATUS_COMPLETED = 0x2
|
||||
|
|
@ -4079,6 +4118,107 @@ type EthtoolDrvinfo struct {
|
|||
Regdump_len uint32
|
||||
}
|
||||
|
||||
type EthtoolTsInfo struct {
|
||||
Cmd uint32
|
||||
So_timestamping uint32
|
||||
Phc_index int32
|
||||
Tx_types uint32
|
||||
Tx_reserved [3]uint32
|
||||
Rx_filters uint32
|
||||
Rx_reserved [3]uint32
|
||||
}
|
||||
|
||||
type HwTstampConfig struct {
|
||||
Flags int32
|
||||
Tx_type int32
|
||||
Rx_filter int32
|
||||
}
|
||||
|
||||
const (
|
||||
HWTSTAMP_FILTER_NONE = 0x0
|
||||
HWTSTAMP_FILTER_ALL = 0x1
|
||||
HWTSTAMP_FILTER_SOME = 0x2
|
||||
HWTSTAMP_FILTER_PTP_V1_L4_EVENT = 0x3
|
||||
HWTSTAMP_FILTER_PTP_V2_L4_EVENT = 0x6
|
||||
HWTSTAMP_FILTER_PTP_V2_L2_EVENT = 0x9
|
||||
HWTSTAMP_FILTER_PTP_V2_EVENT = 0xc
|
||||
)
|
||||
|
||||
const (
|
||||
HWTSTAMP_TX_OFF = 0x0
|
||||
HWTSTAMP_TX_ON = 0x1
|
||||
HWTSTAMP_TX_ONESTEP_SYNC = 0x2
|
||||
)
|
||||
|
||||
type (
|
||||
PtpClockCaps struct {
|
||||
Max_adj int32
|
||||
N_alarm int32
|
||||
N_ext_ts int32
|
||||
N_per_out int32
|
||||
Pps int32
|
||||
N_pins int32
|
||||
Cross_timestamping int32
|
||||
Adjust_phase int32
|
||||
Max_phase_adj int32
|
||||
Rsv [11]int32
|
||||
}
|
||||
PtpClockTime struct {
|
||||
Sec int64
|
||||
Nsec uint32
|
||||
Reserved uint32
|
||||
}
|
||||
PtpExttsEvent struct {
|
||||
T PtpClockTime
|
||||
Index uint32
|
||||
Flags uint32
|
||||
Rsv [2]uint32
|
||||
}
|
||||
PtpExttsRequest struct {
|
||||
Index uint32
|
||||
Flags uint32
|
||||
Rsv [2]uint32
|
||||
}
|
||||
PtpPeroutRequest struct {
|
||||
StartOrPhase PtpClockTime
|
||||
Period PtpClockTime
|
||||
Index uint32
|
||||
Flags uint32
|
||||
On PtpClockTime
|
||||
}
|
||||
PtpPinDesc struct {
|
||||
Name [64]byte
|
||||
Index uint32
|
||||
Func uint32
|
||||
Chan uint32
|
||||
Rsv [5]uint32
|
||||
}
|
||||
PtpSysOffset struct {
|
||||
Samples uint32
|
||||
Rsv [3]uint32
|
||||
Ts [51]PtpClockTime
|
||||
}
|
||||
PtpSysOffsetExtended struct {
|
||||
Samples uint32
|
||||
Clockid int32
|
||||
Rsv [2]uint32
|
||||
Ts [25][3]PtpClockTime
|
||||
}
|
||||
PtpSysOffsetPrecise struct {
|
||||
Device PtpClockTime
|
||||
Realtime PtpClockTime
|
||||
Monoraw PtpClockTime
|
||||
Rsv [4]uint32
|
||||
}
|
||||
)
|
||||
|
||||
const (
|
||||
PTP_PF_NONE = 0x0
|
||||
PTP_PF_EXTTS = 0x1
|
||||
PTP_PF_PEROUT = 0x2
|
||||
PTP_PF_PHYSYNC = 0x3
|
||||
)
|
||||
|
||||
type (
|
||||
HIDRawReportDescriptor struct {
|
||||
Size uint32
|
||||
|
|
@ -4260,6 +4400,7 @@ const (
|
|||
type LandlockRulesetAttr struct {
|
||||
Access_fs uint64
|
||||
Access_net uint64
|
||||
Scoped uint64
|
||||
}
|
||||
|
||||
type LandlockPathBeneathAttr struct {
|
||||
|
|
@ -4606,7 +4747,7 @@ const (
|
|||
NL80211_ATTR_MAC_HINT = 0xc8
|
||||
NL80211_ATTR_MAC_MASK = 0xd7
|
||||
NL80211_ATTR_MAX_AP_ASSOC_STA = 0xca
|
||||
NL80211_ATTR_MAX = 0x14a
|
||||
NL80211_ATTR_MAX = 0x14c
|
||||
NL80211_ATTR_MAX_CRIT_PROT_DURATION = 0xb4
|
||||
NL80211_ATTR_MAX_CSA_COUNTERS = 0xce
|
||||
NL80211_ATTR_MAX_MATCH_SETS = 0x85
|
||||
|
|
@ -5210,7 +5351,7 @@ const (
|
|||
NL80211_FREQUENCY_ATTR_GO_CONCURRENT = 0xf
|
||||
NL80211_FREQUENCY_ATTR_INDOOR_ONLY = 0xe
|
||||
NL80211_FREQUENCY_ATTR_IR_CONCURRENT = 0xf
|
||||
NL80211_FREQUENCY_ATTR_MAX = 0x20
|
||||
NL80211_FREQUENCY_ATTR_MAX = 0x21
|
||||
NL80211_FREQUENCY_ATTR_MAX_TX_POWER = 0x6
|
||||
NL80211_FREQUENCY_ATTR_NO_10MHZ = 0x11
|
||||
NL80211_FREQUENCY_ATTR_NO_160MHZ = 0xc
|
||||
|
|
|
|||
|
|
@ -727,6 +727,37 @@ const (
|
|||
RISCV_HWPROBE_EXT_ZBA = 0x8
|
||||
RISCV_HWPROBE_EXT_ZBB = 0x10
|
||||
RISCV_HWPROBE_EXT_ZBS = 0x20
|
||||
RISCV_HWPROBE_EXT_ZICBOZ = 0x40
|
||||
RISCV_HWPROBE_EXT_ZBC = 0x80
|
||||
RISCV_HWPROBE_EXT_ZBKB = 0x100
|
||||
RISCV_HWPROBE_EXT_ZBKC = 0x200
|
||||
RISCV_HWPROBE_EXT_ZBKX = 0x400
|
||||
RISCV_HWPROBE_EXT_ZKND = 0x800
|
||||
RISCV_HWPROBE_EXT_ZKNE = 0x1000
|
||||
RISCV_HWPROBE_EXT_ZKNH = 0x2000
|
||||
RISCV_HWPROBE_EXT_ZKSED = 0x4000
|
||||
RISCV_HWPROBE_EXT_ZKSH = 0x8000
|
||||
RISCV_HWPROBE_EXT_ZKT = 0x10000
|
||||
RISCV_HWPROBE_EXT_ZVBB = 0x20000
|
||||
RISCV_HWPROBE_EXT_ZVBC = 0x40000
|
||||
RISCV_HWPROBE_EXT_ZVKB = 0x80000
|
||||
RISCV_HWPROBE_EXT_ZVKG = 0x100000
|
||||
RISCV_HWPROBE_EXT_ZVKNED = 0x200000
|
||||
RISCV_HWPROBE_EXT_ZVKNHA = 0x400000
|
||||
RISCV_HWPROBE_EXT_ZVKNHB = 0x800000
|
||||
RISCV_HWPROBE_EXT_ZVKSED = 0x1000000
|
||||
RISCV_HWPROBE_EXT_ZVKSH = 0x2000000
|
||||
RISCV_HWPROBE_EXT_ZVKT = 0x4000000
|
||||
RISCV_HWPROBE_EXT_ZFH = 0x8000000
|
||||
RISCV_HWPROBE_EXT_ZFHMIN = 0x10000000
|
||||
RISCV_HWPROBE_EXT_ZIHINTNTL = 0x20000000
|
||||
RISCV_HWPROBE_EXT_ZVFH = 0x40000000
|
||||
RISCV_HWPROBE_EXT_ZVFHMIN = 0x80000000
|
||||
RISCV_HWPROBE_EXT_ZFA = 0x100000000
|
||||
RISCV_HWPROBE_EXT_ZTSO = 0x200000000
|
||||
RISCV_HWPROBE_EXT_ZACAS = 0x400000000
|
||||
RISCV_HWPROBE_EXT_ZICOND = 0x800000000
|
||||
RISCV_HWPROBE_EXT_ZIHINTPAUSE = 0x1000000000
|
||||
RISCV_HWPROBE_KEY_CPUPERF_0 = 0x5
|
||||
RISCV_HWPROBE_MISALIGNED_UNKNOWN = 0x0
|
||||
RISCV_HWPROBE_MISALIGNED_EMULATED = 0x1
|
||||
|
|
@ -734,4 +765,6 @@ const (
|
|||
RISCV_HWPROBE_MISALIGNED_FAST = 0x3
|
||||
RISCV_HWPROBE_MISALIGNED_UNSUPPORTED = 0x4
|
||||
RISCV_HWPROBE_MISALIGNED_MASK = 0x7
|
||||
RISCV_HWPROBE_KEY_ZICBOZ_BLOCK_SIZE = 0x6
|
||||
RISCV_HWPROBE_WHICH_CPUS = 0x1
|
||||
)
|
||||
|
|
|
|||
|
|
@ -377,6 +377,12 @@ type Flock_t struct {
|
|||
Pid int32
|
||||
}
|
||||
|
||||
type F_cnvrt struct {
|
||||
Cvtcmd int32
|
||||
Pccsid int16
|
||||
Fccsid int16
|
||||
}
|
||||
|
||||
type Termios struct {
|
||||
Cflag uint32
|
||||
Iflag uint32
|
||||
|
|
|
|||
|
|
@ -43,8 +43,8 @@ type DLL struct {
|
|||
// LoadDLL loads DLL file into memory.
|
||||
//
|
||||
// Warning: using LoadDLL without an absolute path name is subject to
|
||||
// DLL preloading attacks. To safely load a system DLL, use LazyDLL
|
||||
// with System set to true, or use LoadLibraryEx directly.
|
||||
// DLL preloading attacks. To safely load a system DLL, use [NewLazySystemDLL],
|
||||
// or use [LoadLibraryEx] directly.
|
||||
func LoadDLL(name string) (dll *DLL, err error) {
|
||||
namep, err := UTF16PtrFromString(name)
|
||||
if err != nil {
|
||||
|
|
@ -65,7 +65,7 @@ func LoadDLL(name string) (dll *DLL, err error) {
|
|||
return d, nil
|
||||
}
|
||||
|
||||
// MustLoadDLL is like LoadDLL but panics if load operation failes.
|
||||
// MustLoadDLL is like LoadDLL but panics if load operation fails.
|
||||
func MustLoadDLL(name string) *DLL {
|
||||
d, e := LoadDLL(name)
|
||||
if e != nil {
|
||||
|
|
@ -271,6 +271,9 @@ func (d *LazyDLL) NewProc(name string) *LazyProc {
|
|||
}
|
||||
|
||||
// NewLazyDLL creates new LazyDLL associated with DLL file.
|
||||
//
|
||||
// Warning: using NewLazyDLL without an absolute path name is subject to
|
||||
// DLL preloading attacks. To safely load a system DLL, use [NewLazySystemDLL].
|
||||
func NewLazyDLL(name string) *LazyDLL {
|
||||
return &LazyDLL{Name: name}
|
||||
}
|
||||
|
|
@ -410,7 +413,3 @@ func loadLibraryEx(name string, system bool) (*DLL, error) {
|
|||
}
|
||||
return &DLL{Name: name, Handle: h}, nil
|
||||
}
|
||||
|
||||
type errString string
|
||||
|
||||
func (s errString) Error() string { return string(s) }
|
||||
|
|
|
|||
|
|
@ -168,6 +168,8 @@ func NewCallbackCDecl(fn interface{}) uintptr {
|
|||
//sys CreateNamedPipe(name *uint16, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *SecurityAttributes) (handle Handle, err error) [failretval==InvalidHandle] = CreateNamedPipeW
|
||||
//sys ConnectNamedPipe(pipe Handle, overlapped *Overlapped) (err error)
|
||||
//sys DisconnectNamedPipe(pipe Handle) (err error)
|
||||
//sys GetNamedPipeClientProcessId(pipe Handle, clientProcessID *uint32) (err error)
|
||||
//sys GetNamedPipeServerProcessId(pipe Handle, serverProcessID *uint32) (err error)
|
||||
//sys GetNamedPipeInfo(pipe Handle, flags *uint32, outSize *uint32, inSize *uint32, maxInstances *uint32) (err error)
|
||||
//sys GetNamedPipeHandleState(pipe Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) = GetNamedPipeHandleStateW
|
||||
//sys SetNamedPipeHandleState(pipe Handle, state *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32) (err error) = SetNamedPipeHandleState
|
||||
|
|
@ -313,6 +315,10 @@ func NewCallbackCDecl(fn interface{}) uintptr {
|
|||
//sys SetConsoleMode(console Handle, mode uint32) (err error) = kernel32.SetConsoleMode
|
||||
//sys GetConsoleScreenBufferInfo(console Handle, info *ConsoleScreenBufferInfo) (err error) = kernel32.GetConsoleScreenBufferInfo
|
||||
//sys setConsoleCursorPosition(console Handle, position uint32) (err error) = kernel32.SetConsoleCursorPosition
|
||||
//sys GetConsoleCP() (cp uint32, err error) = kernel32.GetConsoleCP
|
||||
//sys GetConsoleOutputCP() (cp uint32, err error) = kernel32.GetConsoleOutputCP
|
||||
//sys SetConsoleCP(cp uint32) (err error) = kernel32.SetConsoleCP
|
||||
//sys SetConsoleOutputCP(cp uint32) (err error) = kernel32.SetConsoleOutputCP
|
||||
//sys WriteConsole(console Handle, buf *uint16, towrite uint32, written *uint32, reserved *byte) (err error) = kernel32.WriteConsoleW
|
||||
//sys ReadConsole(console Handle, buf *uint16, toread uint32, read *uint32, inputControl *byte) (err error) = kernel32.ReadConsoleW
|
||||
//sys resizePseudoConsole(pconsole Handle, size uint32) (hr error) = kernel32.ResizePseudoConsole
|
||||
|
|
@ -721,20 +727,12 @@ func DurationSinceBoot() time.Duration {
|
|||
}
|
||||
|
||||
func Ftruncate(fd Handle, length int64) (err error) {
|
||||
curoffset, e := Seek(fd, 0, 1)
|
||||
if e != nil {
|
||||
return e
|
||||
type _FILE_END_OF_FILE_INFO struct {
|
||||
EndOfFile int64
|
||||
}
|
||||
defer Seek(fd, curoffset, 0)
|
||||
_, e = Seek(fd, length, 0)
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
e = SetEndOfFile(fd)
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
return nil
|
||||
var info _FILE_END_OF_FILE_INFO
|
||||
info.EndOfFile = length
|
||||
return SetFileInformationByHandle(fd, FileEndOfFileInfo, (*byte)(unsafe.Pointer(&info)), uint32(unsafe.Sizeof(info)))
|
||||
}
|
||||
|
||||
func Gettimeofday(tv *Timeval) (err error) {
|
||||
|
|
@ -890,6 +888,11 @@ const socket_error = uintptr(^uint32(0))
|
|||
//sys GetACP() (acp uint32) = kernel32.GetACP
|
||||
//sys MultiByteToWideChar(codePage uint32, dwFlags uint32, str *byte, nstr int32, wchar *uint16, nwchar int32) (nwrite int32, err error) = kernel32.MultiByteToWideChar
|
||||
//sys getBestInterfaceEx(sockaddr unsafe.Pointer, pdwBestIfIndex *uint32) (errcode error) = iphlpapi.GetBestInterfaceEx
|
||||
//sys GetIfEntry2Ex(level uint32, row *MibIfRow2) (errcode error) = iphlpapi.GetIfEntry2Ex
|
||||
//sys GetUnicastIpAddressEntry(row *MibUnicastIpAddressRow) (errcode error) = iphlpapi.GetUnicastIpAddressEntry
|
||||
//sys NotifyIpInterfaceChange(family uint16, callback uintptr, callerContext unsafe.Pointer, initialNotification bool, notificationHandle *Handle) (errcode error) = iphlpapi.NotifyIpInterfaceChange
|
||||
//sys NotifyUnicastIpAddressChange(family uint16, callback uintptr, callerContext unsafe.Pointer, initialNotification bool, notificationHandle *Handle) (errcode error) = iphlpapi.NotifyUnicastIpAddressChange
|
||||
//sys CancelMibChangeNotify2(notificationHandle Handle) (errcode error) = iphlpapi.CancelMibChangeNotify2
|
||||
|
||||
// For testing: clients can set this flag to force
|
||||
// creation of IPv6 sockets to return EAFNOSUPPORT.
|
||||
|
|
@ -1681,13 +1684,16 @@ func (s NTStatus) Error() string {
|
|||
// do not use NTUnicodeString, and instead UTF16PtrFromString should be used for
|
||||
// the more common *uint16 string type.
|
||||
func NewNTUnicodeString(s string) (*NTUnicodeString, error) {
|
||||
var u NTUnicodeString
|
||||
s16, err := UTF16PtrFromString(s)
|
||||
s16, err := UTF16FromString(s)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
RtlInitUnicodeString(&u, s16)
|
||||
return &u, nil
|
||||
n := uint16(len(s16) * 2)
|
||||
return &NTUnicodeString{
|
||||
Length: n - 2, // subtract 2 bytes for the NULL terminator
|
||||
MaximumLength: n,
|
||||
Buffer: &s16[0],
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Slice returns a uint16 slice that aliases the data in the NTUnicodeString.
|
||||
|
|
|
|||
|
|
@ -176,6 +176,7 @@ const (
|
|||
WAIT_FAILED = 0xFFFFFFFF
|
||||
|
||||
// Access rights for process.
|
||||
PROCESS_ALL_ACCESS = 0xFFFF
|
||||
PROCESS_CREATE_PROCESS = 0x0080
|
||||
PROCESS_CREATE_THREAD = 0x0002
|
||||
PROCESS_DUP_HANDLE = 0x0040
|
||||
|
|
@ -1060,6 +1061,7 @@ const (
|
|||
SIO_GET_EXTENSION_FUNCTION_POINTER = IOC_INOUT | IOC_WS2 | 6
|
||||
SIO_KEEPALIVE_VALS = IOC_IN | IOC_VENDOR | 4
|
||||
SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12
|
||||
SIO_UDP_NETRESET = IOC_IN | IOC_VENDOR | 15
|
||||
|
||||
// cf. http://support.microsoft.com/default.aspx?scid=kb;en-us;257460
|
||||
|
||||
|
|
@ -2031,6 +2033,50 @@ const (
|
|||
IF_TYPE_IEEE1394 = 144
|
||||
)
|
||||
|
||||
// Enum NL_PREFIX_ORIGIN for [IpAdapterUnicastAddress], see
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/nldef/ne-nldef-nl_prefix_origin
|
||||
const (
|
||||
IpPrefixOriginOther = 0
|
||||
IpPrefixOriginManual = 1
|
||||
IpPrefixOriginWellKnown = 2
|
||||
IpPrefixOriginDhcp = 3
|
||||
IpPrefixOriginRouterAdvertisement = 4
|
||||
IpPrefixOriginUnchanged = 1 << 4
|
||||
)
|
||||
|
||||
// Enum NL_SUFFIX_ORIGIN for [IpAdapterUnicastAddress], see
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/nldef/ne-nldef-nl_suffix_origin
|
||||
const (
|
||||
NlsoOther = 0
|
||||
NlsoManual = 1
|
||||
NlsoWellKnown = 2
|
||||
NlsoDhcp = 3
|
||||
NlsoLinkLayerAddress = 4
|
||||
NlsoRandom = 5
|
||||
IpSuffixOriginOther = 0
|
||||
IpSuffixOriginManual = 1
|
||||
IpSuffixOriginWellKnown = 2
|
||||
IpSuffixOriginDhcp = 3
|
||||
IpSuffixOriginLinkLayerAddress = 4
|
||||
IpSuffixOriginRandom = 5
|
||||
IpSuffixOriginUnchanged = 1 << 4
|
||||
)
|
||||
|
||||
// Enum NL_DAD_STATE for [IpAdapterUnicastAddress], see
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/nldef/ne-nldef-nl_dad_state
|
||||
const (
|
||||
NldsInvalid = 0
|
||||
NldsTentative = 1
|
||||
NldsDuplicate = 2
|
||||
NldsDeprecated = 3
|
||||
NldsPreferred = 4
|
||||
IpDadStateInvalid = 0
|
||||
IpDadStateTentative = 1
|
||||
IpDadStateDuplicate = 2
|
||||
IpDadStateDeprecated = 3
|
||||
IpDadStatePreferred = 4
|
||||
)
|
||||
|
||||
type SocketAddress struct {
|
||||
Sockaddr *syscall.RawSockaddrAny
|
||||
SockaddrLength int32
|
||||
|
|
@ -2158,6 +2204,132 @@ const (
|
|||
IfOperStatusLowerLayerDown = 7
|
||||
)
|
||||
|
||||
const (
|
||||
IF_MAX_PHYS_ADDRESS_LENGTH = 32
|
||||
IF_MAX_STRING_SIZE = 256
|
||||
)
|
||||
|
||||
// MIB_IF_ENTRY_LEVEL enumeration from netioapi.h or
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/netioapi/nf-netioapi-getifentry2ex.
|
||||
const (
|
||||
MibIfEntryNormal = 0
|
||||
MibIfEntryNormalWithoutStatistics = 2
|
||||
)
|
||||
|
||||
// MIB_NOTIFICATION_TYPE enumeration from netioapi.h or
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/netioapi/ne-netioapi-mib_notification_type.
|
||||
const (
|
||||
MibParameterNotification = 0
|
||||
MibAddInstance = 1
|
||||
MibDeleteInstance = 2
|
||||
MibInitialNotification = 3
|
||||
)
|
||||
|
||||
// MibIfRow2 stores information about a particular interface. See
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/netioapi/ns-netioapi-mib_if_row2.
|
||||
type MibIfRow2 struct {
|
||||
InterfaceLuid uint64
|
||||
InterfaceIndex uint32
|
||||
InterfaceGuid GUID
|
||||
Alias [IF_MAX_STRING_SIZE + 1]uint16
|
||||
Description [IF_MAX_STRING_SIZE + 1]uint16
|
||||
PhysicalAddressLength uint32
|
||||
PhysicalAddress [IF_MAX_PHYS_ADDRESS_LENGTH]uint8
|
||||
PermanentPhysicalAddress [IF_MAX_PHYS_ADDRESS_LENGTH]uint8
|
||||
Mtu uint32
|
||||
Type uint32
|
||||
TunnelType uint32
|
||||
MediaType uint32
|
||||
PhysicalMediumType uint32
|
||||
AccessType uint32
|
||||
DirectionType uint32
|
||||
InterfaceAndOperStatusFlags uint8
|
||||
OperStatus uint32
|
||||
AdminStatus uint32
|
||||
MediaConnectState uint32
|
||||
NetworkGuid GUID
|
||||
ConnectionType uint32
|
||||
TransmitLinkSpeed uint64
|
||||
ReceiveLinkSpeed uint64
|
||||
InOctets uint64
|
||||
InUcastPkts uint64
|
||||
InNUcastPkts uint64
|
||||
InDiscards uint64
|
||||
InErrors uint64
|
||||
InUnknownProtos uint64
|
||||
InUcastOctets uint64
|
||||
InMulticastOctets uint64
|
||||
InBroadcastOctets uint64
|
||||
OutOctets uint64
|
||||
OutUcastPkts uint64
|
||||
OutNUcastPkts uint64
|
||||
OutDiscards uint64
|
||||
OutErrors uint64
|
||||
OutUcastOctets uint64
|
||||
OutMulticastOctets uint64
|
||||
OutBroadcastOctets uint64
|
||||
OutQLen uint64
|
||||
}
|
||||
|
||||
// MIB_UNICASTIPADDRESS_ROW stores information about a unicast IP address. See
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/netioapi/ns-netioapi-mib_unicastipaddress_row.
|
||||
type MibUnicastIpAddressRow struct {
|
||||
Address RawSockaddrInet6 // SOCKADDR_INET union
|
||||
InterfaceLuid uint64
|
||||
InterfaceIndex uint32
|
||||
PrefixOrigin uint32
|
||||
SuffixOrigin uint32
|
||||
ValidLifetime uint32
|
||||
PreferredLifetime uint32
|
||||
OnLinkPrefixLength uint8
|
||||
SkipAsSource uint8
|
||||
DadState uint32
|
||||
ScopeId uint32
|
||||
CreationTimeStamp Filetime
|
||||
}
|
||||
|
||||
const ScopeLevelCount = 16
|
||||
|
||||
// MIB_IPINTERFACE_ROW stores interface management information for a particular IP address family on a network interface.
|
||||
// See https://learn.microsoft.com/en-us/windows/win32/api/netioapi/ns-netioapi-mib_ipinterface_row.
|
||||
type MibIpInterfaceRow struct {
|
||||
Family uint16
|
||||
InterfaceLuid uint64
|
||||
InterfaceIndex uint32
|
||||
MaxReassemblySize uint32
|
||||
InterfaceIdentifier uint64
|
||||
MinRouterAdvertisementInterval uint32
|
||||
MaxRouterAdvertisementInterval uint32
|
||||
AdvertisingEnabled uint8
|
||||
ForwardingEnabled uint8
|
||||
WeakHostSend uint8
|
||||
WeakHostReceive uint8
|
||||
UseAutomaticMetric uint8
|
||||
UseNeighborUnreachabilityDetection uint8
|
||||
ManagedAddressConfigurationSupported uint8
|
||||
OtherStatefulConfigurationSupported uint8
|
||||
AdvertiseDefaultRoute uint8
|
||||
RouterDiscoveryBehavior uint32
|
||||
DadTransmits uint32
|
||||
BaseReachableTime uint32
|
||||
RetransmitTime uint32
|
||||
PathMtuDiscoveryTimeout uint32
|
||||
LinkLocalAddressBehavior uint32
|
||||
LinkLocalAddressTimeout uint32
|
||||
ZoneIndices [ScopeLevelCount]uint32
|
||||
SitePrefixLength uint32
|
||||
Metric uint32
|
||||
NlMtu uint32
|
||||
Connected uint8
|
||||
SupportsWakeUpPatterns uint8
|
||||
SupportsNeighborDiscovery uint8
|
||||
SupportsRouterDiscovery uint8
|
||||
ReachableTime uint32
|
||||
TransmitOffload uint32
|
||||
ReceiveOffload uint32
|
||||
DisableDefaultRoutes uint8
|
||||
}
|
||||
|
||||
// Console related constants used for the mode parameter to SetConsoleMode. See
|
||||
// https://docs.microsoft.com/en-us/windows/console/setconsolemode for details.
|
||||
|
||||
|
|
|
|||
|
|
@ -181,10 +181,15 @@ var (
|
|||
procDnsRecordListFree = moddnsapi.NewProc("DnsRecordListFree")
|
||||
procDwmGetWindowAttribute = moddwmapi.NewProc("DwmGetWindowAttribute")
|
||||
procDwmSetWindowAttribute = moddwmapi.NewProc("DwmSetWindowAttribute")
|
||||
procCancelMibChangeNotify2 = modiphlpapi.NewProc("CancelMibChangeNotify2")
|
||||
procGetAdaptersAddresses = modiphlpapi.NewProc("GetAdaptersAddresses")
|
||||
procGetAdaptersInfo = modiphlpapi.NewProc("GetAdaptersInfo")
|
||||
procGetBestInterfaceEx = modiphlpapi.NewProc("GetBestInterfaceEx")
|
||||
procGetIfEntry = modiphlpapi.NewProc("GetIfEntry")
|
||||
procGetIfEntry2Ex = modiphlpapi.NewProc("GetIfEntry2Ex")
|
||||
procGetUnicastIpAddressEntry = modiphlpapi.NewProc("GetUnicastIpAddressEntry")
|
||||
procNotifyIpInterfaceChange = modiphlpapi.NewProc("NotifyIpInterfaceChange")
|
||||
procNotifyUnicastIpAddressChange = modiphlpapi.NewProc("NotifyUnicastIpAddressChange")
|
||||
procAddDllDirectory = modkernel32.NewProc("AddDllDirectory")
|
||||
procAssignProcessToJobObject = modkernel32.NewProc("AssignProcessToJobObject")
|
||||
procCancelIo = modkernel32.NewProc("CancelIo")
|
||||
|
|
@ -247,7 +252,9 @@ var (
|
|||
procGetCommandLineW = modkernel32.NewProc("GetCommandLineW")
|
||||
procGetComputerNameExW = modkernel32.NewProc("GetComputerNameExW")
|
||||
procGetComputerNameW = modkernel32.NewProc("GetComputerNameW")
|
||||
procGetConsoleCP = modkernel32.NewProc("GetConsoleCP")
|
||||
procGetConsoleMode = modkernel32.NewProc("GetConsoleMode")
|
||||
procGetConsoleOutputCP = modkernel32.NewProc("GetConsoleOutputCP")
|
||||
procGetConsoleScreenBufferInfo = modkernel32.NewProc("GetConsoleScreenBufferInfo")
|
||||
procGetCurrentDirectoryW = modkernel32.NewProc("GetCurrentDirectoryW")
|
||||
procGetCurrentProcessId = modkernel32.NewProc("GetCurrentProcessId")
|
||||
|
|
@ -273,8 +280,10 @@ var (
|
|||
procGetMaximumProcessorCount = modkernel32.NewProc("GetMaximumProcessorCount")
|
||||
procGetModuleFileNameW = modkernel32.NewProc("GetModuleFileNameW")
|
||||
procGetModuleHandleExW = modkernel32.NewProc("GetModuleHandleExW")
|
||||
procGetNamedPipeClientProcessId = modkernel32.NewProc("GetNamedPipeClientProcessId")
|
||||
procGetNamedPipeHandleStateW = modkernel32.NewProc("GetNamedPipeHandleStateW")
|
||||
procGetNamedPipeInfo = modkernel32.NewProc("GetNamedPipeInfo")
|
||||
procGetNamedPipeServerProcessId = modkernel32.NewProc("GetNamedPipeServerProcessId")
|
||||
procGetOverlappedResult = modkernel32.NewProc("GetOverlappedResult")
|
||||
procGetPriorityClass = modkernel32.NewProc("GetPriorityClass")
|
||||
procGetProcAddress = modkernel32.NewProc("GetProcAddress")
|
||||
|
|
@ -347,8 +356,10 @@ var (
|
|||
procSetCommMask = modkernel32.NewProc("SetCommMask")
|
||||
procSetCommState = modkernel32.NewProc("SetCommState")
|
||||
procSetCommTimeouts = modkernel32.NewProc("SetCommTimeouts")
|
||||
procSetConsoleCP = modkernel32.NewProc("SetConsoleCP")
|
||||
procSetConsoleCursorPosition = modkernel32.NewProc("SetConsoleCursorPosition")
|
||||
procSetConsoleMode = modkernel32.NewProc("SetConsoleMode")
|
||||
procSetConsoleOutputCP = modkernel32.NewProc("SetConsoleOutputCP")
|
||||
procSetCurrentDirectoryW = modkernel32.NewProc("SetCurrentDirectoryW")
|
||||
procSetDefaultDllDirectories = modkernel32.NewProc("SetDefaultDllDirectories")
|
||||
procSetDllDirectoryW = modkernel32.NewProc("SetDllDirectoryW")
|
||||
|
|
@ -1602,6 +1613,14 @@ func DwmSetWindowAttribute(hwnd HWND, attribute uint32, value unsafe.Pointer, si
|
|||
return
|
||||
}
|
||||
|
||||
func CancelMibChangeNotify2(notificationHandle Handle) (errcode error) {
|
||||
r0, _, _ := syscall.Syscall(procCancelMibChangeNotify2.Addr(), 1, uintptr(notificationHandle), 0, 0)
|
||||
if r0 != 0 {
|
||||
errcode = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func GetAdaptersAddresses(family uint32, flags uint32, reserved uintptr, adapterAddresses *IpAdapterAddresses, sizePointer *uint32) (errcode error) {
|
||||
r0, _, _ := syscall.Syscall6(procGetAdaptersAddresses.Addr(), 5, uintptr(family), uintptr(flags), uintptr(reserved), uintptr(unsafe.Pointer(adapterAddresses)), uintptr(unsafe.Pointer(sizePointer)), 0)
|
||||
if r0 != 0 {
|
||||
|
|
@ -1634,6 +1653,46 @@ func GetIfEntry(pIfRow *MibIfRow) (errcode error) {
|
|||
return
|
||||
}
|
||||
|
||||
func GetIfEntry2Ex(level uint32, row *MibIfRow2) (errcode error) {
|
||||
r0, _, _ := syscall.Syscall(procGetIfEntry2Ex.Addr(), 2, uintptr(level), uintptr(unsafe.Pointer(row)), 0)
|
||||
if r0 != 0 {
|
||||
errcode = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func GetUnicastIpAddressEntry(row *MibUnicastIpAddressRow) (errcode error) {
|
||||
r0, _, _ := syscall.Syscall(procGetUnicastIpAddressEntry.Addr(), 1, uintptr(unsafe.Pointer(row)), 0, 0)
|
||||
if r0 != 0 {
|
||||
errcode = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func NotifyIpInterfaceChange(family uint16, callback uintptr, callerContext unsafe.Pointer, initialNotification bool, notificationHandle *Handle) (errcode error) {
|
||||
var _p0 uint32
|
||||
if initialNotification {
|
||||
_p0 = 1
|
||||
}
|
||||
r0, _, _ := syscall.Syscall6(procNotifyIpInterfaceChange.Addr(), 5, uintptr(family), uintptr(callback), uintptr(callerContext), uintptr(_p0), uintptr(unsafe.Pointer(notificationHandle)), 0)
|
||||
if r0 != 0 {
|
||||
errcode = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func NotifyUnicastIpAddressChange(family uint16, callback uintptr, callerContext unsafe.Pointer, initialNotification bool, notificationHandle *Handle) (errcode error) {
|
||||
var _p0 uint32
|
||||
if initialNotification {
|
||||
_p0 = 1
|
||||
}
|
||||
r0, _, _ := syscall.Syscall6(procNotifyUnicastIpAddressChange.Addr(), 5, uintptr(family), uintptr(callback), uintptr(callerContext), uintptr(_p0), uintptr(unsafe.Pointer(notificationHandle)), 0)
|
||||
if r0 != 0 {
|
||||
errcode = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func AddDllDirectory(path *uint16) (cookie uintptr, err error) {
|
||||
r0, _, e1 := syscall.Syscall(procAddDllDirectory.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0)
|
||||
cookie = uintptr(r0)
|
||||
|
|
@ -2162,6 +2221,15 @@ func GetComputerName(buf *uint16, n *uint32) (err error) {
|
|||
return
|
||||
}
|
||||
|
||||
func GetConsoleCP() (cp uint32, err error) {
|
||||
r0, _, e1 := syscall.Syscall(procGetConsoleCP.Addr(), 0, 0, 0, 0)
|
||||
cp = uint32(r0)
|
||||
if cp == 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func GetConsoleMode(console Handle, mode *uint32) (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(console), uintptr(unsafe.Pointer(mode)), 0)
|
||||
if r1 == 0 {
|
||||
|
|
@ -2170,6 +2238,15 @@ func GetConsoleMode(console Handle, mode *uint32) (err error) {
|
|||
return
|
||||
}
|
||||
|
||||
func GetConsoleOutputCP() (cp uint32, err error) {
|
||||
r0, _, e1 := syscall.Syscall(procGetConsoleOutputCP.Addr(), 0, 0, 0, 0)
|
||||
cp = uint32(r0)
|
||||
if cp == 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func GetConsoleScreenBufferInfo(console Handle, info *ConsoleScreenBufferInfo) (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procGetConsoleScreenBufferInfo.Addr(), 2, uintptr(console), uintptr(unsafe.Pointer(info)), 0)
|
||||
if r1 == 0 {
|
||||
|
|
@ -2371,6 +2448,14 @@ func GetModuleHandleEx(flags uint32, moduleName *uint16, module *Handle) (err er
|
|||
return
|
||||
}
|
||||
|
||||
func GetNamedPipeClientProcessId(pipe Handle, clientProcessID *uint32) (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procGetNamedPipeClientProcessId.Addr(), 2, uintptr(pipe), uintptr(unsafe.Pointer(clientProcessID)), 0)
|
||||
if r1 == 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func GetNamedPipeHandleState(pipe Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) {
|
||||
r1, _, e1 := syscall.Syscall9(procGetNamedPipeHandleStateW.Addr(), 7, uintptr(pipe), uintptr(unsafe.Pointer(state)), uintptr(unsafe.Pointer(curInstances)), uintptr(unsafe.Pointer(maxCollectionCount)), uintptr(unsafe.Pointer(collectDataTimeout)), uintptr(unsafe.Pointer(userName)), uintptr(maxUserNameSize), 0, 0)
|
||||
if r1 == 0 {
|
||||
|
|
@ -2387,6 +2472,14 @@ func GetNamedPipeInfo(pipe Handle, flags *uint32, outSize *uint32, inSize *uint3
|
|||
return
|
||||
}
|
||||
|
||||
func GetNamedPipeServerProcessId(pipe Handle, serverProcessID *uint32) (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procGetNamedPipeServerProcessId.Addr(), 2, uintptr(pipe), uintptr(unsafe.Pointer(serverProcessID)), 0)
|
||||
if r1 == 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func GetOverlappedResult(handle Handle, overlapped *Overlapped, done *uint32, wait bool) (err error) {
|
||||
var _p0 uint32
|
||||
if wait {
|
||||
|
|
@ -3038,6 +3131,14 @@ func SetCommTimeouts(handle Handle, timeouts *CommTimeouts) (err error) {
|
|||
return
|
||||
}
|
||||
|
||||
func SetConsoleCP(cp uint32) (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procSetConsoleCP.Addr(), 1, uintptr(cp), 0, 0)
|
||||
if r1 == 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func setConsoleCursorPosition(console Handle, position uint32) (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procSetConsoleCursorPosition.Addr(), 2, uintptr(console), uintptr(position), 0)
|
||||
if r1 == 0 {
|
||||
|
|
@ -3054,6 +3155,14 @@ func SetConsoleMode(console Handle, mode uint32) (err error) {
|
|||
return
|
||||
}
|
||||
|
||||
func SetConsoleOutputCP(cp uint32) (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procSetConsoleOutputCP.Addr(), 1, uintptr(cp), 0, 0)
|
||||
if r1 == 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func SetCurrentDirectory(path *uint16) (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procSetCurrentDirectoryW.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0)
|
||||
if r1 == 0 {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
Copyright (c) 2009 The Go Authors. All rights reserved.
|
||||
Copyright 2009 The Go Authors.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
|
|
@ -10,7 +10,7 @@ notice, this list of conditions and the following disclaimer.
|
|||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
* Neither the name of Google LLC nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
|
|
|
|||
|
|
@ -2,22 +2,64 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package gcexportdata provides functions for locating, reading, and
|
||||
// writing export data files containing type information produced by the
|
||||
// gc compiler. This package supports go1.7 export data format and all
|
||||
// later versions.
|
||||
// Package gcexportdata provides functions for reading and writing
|
||||
// export data, which is a serialized description of the API of a Go
|
||||
// package including the names, kinds, types, and locations of all
|
||||
// exported declarations.
|
||||
//
|
||||
// Although it might seem convenient for this package to live alongside
|
||||
// go/types in the standard library, this would cause version skew
|
||||
// problems for developer tools that use it, since they must be able to
|
||||
// consume the outputs of the gc compiler both before and after a Go
|
||||
// update such as from Go 1.7 to Go 1.8. Because this package lives in
|
||||
// golang.org/x/tools, sites can update their version of this repo some
|
||||
// time before the Go 1.8 release and rebuild and redeploy their
|
||||
// developer tools, which will then be able to consume both Go 1.7 and
|
||||
// Go 1.8 export data files, so they will work before and after the
|
||||
// Go update. (See discussion at https://golang.org/issue/15651.)
|
||||
package gcexportdata // import "golang.org/x/tools/go/gcexportdata"
|
||||
// The standard Go compiler (cmd/compile) writes an export data file
|
||||
// for each package it compiles, which it later reads when compiling
|
||||
// packages that import the earlier one. The compiler must thus
|
||||
// contain logic to both write and read export data.
|
||||
// (See the "Export" section in the cmd/compile/README file.)
|
||||
//
|
||||
// The [Read] function in this package can read files produced by the
|
||||
// compiler, producing [go/types] data structures. As a matter of
|
||||
// policy, Read supports export data files produced by only the last
|
||||
// two Go releases plus tip; see https://go.dev/issue/68898. The
|
||||
// export data files produced by the compiler contain additional
|
||||
// details related to generics, inlining, and other optimizations that
|
||||
// cannot be decoded by the [Read] function.
|
||||
//
|
||||
// In files written by the compiler, the export data is not at the
|
||||
// start of the file. Before calling Read, use [NewReader] to locate
|
||||
// the desired portion of the file.
|
||||
//
|
||||
// The [Write] function in this package encodes the exported API of a
|
||||
// Go package ([types.Package]) as a file. Such files can be later
|
||||
// decoded by Read, but cannot be consumed by the compiler.
|
||||
//
|
||||
// # Future changes
|
||||
//
|
||||
// Although Read supports the formats written by both Write and the
|
||||
// compiler, the two are quite different, and there is an open
|
||||
// proposal (https://go.dev/issue/69491) to separate these APIs.
|
||||
//
|
||||
// Under that proposal, this package would ultimately provide only the
|
||||
// Read operation for compiler export data, which must be defined in
|
||||
// this module (golang.org/x/tools), not in the standard library, to
|
||||
// avoid version skew for developer tools that need to read compiler
|
||||
// export data both before and after a Go release, such as from Go
|
||||
// 1.23 to Go 1.24. Because this package lives in the tools module,
|
||||
// clients can update their version of the module some time before the
|
||||
// Go 1.24 release and rebuild and redeploy their tools, which will
|
||||
// then be able to consume both Go 1.23 and Go 1.24 export data files,
|
||||
// so they will work before and after the Go update. (See discussion
|
||||
// at https://go.dev/issue/15651.)
|
||||
//
|
||||
// The operations to import and export [go/types] data structures
|
||||
// would be defined in the go/types package as Import and Export.
|
||||
// [Write] would (eventually) delegate to Export,
|
||||
// and [Read], when it detects a file produced by Export,
|
||||
// would delegate to Import.
|
||||
//
|
||||
// # Deprecations
|
||||
//
|
||||
// The [NewImporter] and [Find] functions are deprecated and should
|
||||
// not be used in new code. The [WriteBundle] and [ReadBundle]
|
||||
// functions are experimental, and there is an open proposal to
|
||||
// deprecate them (https://go.dev/issue/69573).
|
||||
package gcexportdata
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
|
|
@ -47,7 +89,7 @@ import (
|
|||
func Find(importPath, srcDir string) (filename, path string) {
|
||||
cmd := exec.Command("go", "list", "-json", "-export", "--", importPath)
|
||||
cmd.Dir = srcDir
|
||||
out, err := cmd.CombinedOutput()
|
||||
out, err := cmd.Output()
|
||||
if err != nil {
|
||||
return "", ""
|
||||
}
|
||||
|
|
@ -64,24 +106,18 @@ func Find(importPath, srcDir string) (filename, path string) {
|
|||
// additional trailing data beyond the end of the export data.
|
||||
func NewReader(r io.Reader) (io.Reader, error) {
|
||||
buf := bufio.NewReader(r)
|
||||
_, size, err := gcimporter.FindExportData(buf)
|
||||
size, err := gcimporter.FindExportData(buf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if size >= 0 {
|
||||
// We were given an archive and found the __.PKGDEF in it.
|
||||
// This tells us the size of the export data, and we don't
|
||||
// need to return the entire file.
|
||||
return &io.LimitedReader{
|
||||
R: buf,
|
||||
N: size,
|
||||
}, nil
|
||||
} else {
|
||||
// We were given an object file. As such, we don't know how large
|
||||
// the export data is and must return the entire file.
|
||||
return buf, nil
|
||||
}
|
||||
// We were given an archive and found the __.PKGDEF in it.
|
||||
// This tells us the size of the export data, and we don't
|
||||
// need to return the entire file.
|
||||
return &io.LimitedReader{
|
||||
R: buf,
|
||||
N: size,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// readAll works the same way as io.ReadAll, but avoids allocations and copies
|
||||
|
|
@ -100,6 +136,11 @@ func readAll(r io.Reader) ([]byte, error) {
|
|||
// Read reads export data from in, decodes it, and returns type
|
||||
// information for the package.
|
||||
//
|
||||
// Read is capable of reading export data produced by [Write] at the
|
||||
// same source code version, or by the last two Go releases (plus tip)
|
||||
// of the standard Go compiler. Reading files from older compilers may
|
||||
// produce an error.
|
||||
//
|
||||
// The package path (effectively its linker symbol prefix) is
|
||||
// specified by path, since unlike the package name, this information
|
||||
// may not be recorded in the export data.
|
||||
|
|
@ -128,14 +169,26 @@ func Read(in io.Reader, fset *token.FileSet, imports map[string]*types.Package,
|
|||
// (from "version"). Select appropriate importer.
|
||||
if len(data) > 0 {
|
||||
switch data[0] {
|
||||
case 'v', 'c', 'd': // binary, till go1.10
|
||||
case 'v', 'c', 'd':
|
||||
// binary, produced by cmd/compile till go1.10
|
||||
return nil, fmt.Errorf("binary (%c) import format is no longer supported", data[0])
|
||||
|
||||
case 'i': // indexed, till go1.19
|
||||
case 'i':
|
||||
// indexed, produced by cmd/compile till go1.19,
|
||||
// and also by [Write].
|
||||
//
|
||||
// If proposal #69491 is accepted, go/types
|
||||
// serialization will be implemented by
|
||||
// types.Export, to which Write would eventually
|
||||
// delegate (explicitly dropping any pretence at
|
||||
// inter-version Write-Read compatibility).
|
||||
// This [Read] function would delegate to types.Import
|
||||
// when it detects that the file was produced by Export.
|
||||
_, pkg, err := gcimporter.IImportData(fset, imports, data[1:], path)
|
||||
return pkg, err
|
||||
|
||||
case 'u': // unified, from go1.20
|
||||
case 'u':
|
||||
// unified, produced by cmd/compile since go1.20
|
||||
_, pkg, err := gcimporter.UImportData(fset, imports, data[1:], path)
|
||||
return pkg, err
|
||||
|
||||
|
|
|
|||
|
|
@ -1,53 +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.
|
||||
|
||||
// Package packagesdriver fetches type sizes for go/packages and go/analysis.
|
||||
package packagesdriver
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/tools/internal/gocommand"
|
||||
)
|
||||
|
||||
func GetSizesForArgsGolist(ctx context.Context, inv gocommand.Invocation, gocmdRunner *gocommand.Runner) (string, string, error) {
|
||||
inv.Verb = "list"
|
||||
inv.Args = []string{"-f", "{{context.GOARCH}} {{context.Compiler}}", "--", "unsafe"}
|
||||
stdout, stderr, friendlyErr, rawErr := gocmdRunner.RunRaw(ctx, inv)
|
||||
var goarch, compiler string
|
||||
if rawErr != nil {
|
||||
rawErrMsg := rawErr.Error()
|
||||
if strings.Contains(rawErrMsg, "cannot find main module") ||
|
||||
strings.Contains(rawErrMsg, "go.mod file not found") {
|
||||
// User's running outside of a module.
|
||||
// All bets are off. Get GOARCH and guess compiler is gc.
|
||||
// TODO(matloob): Is this a problem in practice?
|
||||
inv.Verb = "env"
|
||||
inv.Args = []string{"GOARCH"}
|
||||
envout, enverr := gocmdRunner.Run(ctx, inv)
|
||||
if enverr != nil {
|
||||
return "", "", enverr
|
||||
}
|
||||
goarch = strings.TrimSpace(envout.String())
|
||||
compiler = "gc"
|
||||
} else if friendlyErr != nil {
|
||||
return "", "", friendlyErr
|
||||
} else {
|
||||
// This should be unreachable, but be defensive
|
||||
// in case RunRaw's error results are inconsistent.
|
||||
return "", "", rawErr
|
||||
}
|
||||
} else {
|
||||
fields := strings.Fields(stdout.String())
|
||||
if len(fields) < 2 {
|
||||
return "", "", fmt.Errorf("could not parse GOARCH and Go compiler in format \"<GOARCH> <compiler>\":\nstdout: <<%s>>\nstderr: <<%s>>",
|
||||
stdout.String(), stderr.String())
|
||||
}
|
||||
goarch = fields[0]
|
||||
compiler = fields[1]
|
||||
}
|
||||
return compiler, goarch, nil
|
||||
}
|
||||
|
|
@ -64,7 +64,7 @@ graph using the Imports fields.
|
|||
|
||||
The Load function can be configured by passing a pointer to a Config as
|
||||
the first argument. A nil Config is equivalent to the zero Config, which
|
||||
causes Load to run in LoadFiles mode, collecting minimal information.
|
||||
causes Load to run in [LoadFiles] mode, collecting minimal information.
|
||||
See the documentation for type Config for details.
|
||||
|
||||
As noted earlier, the Config.Mode controls the amount of detail
|
||||
|
|
@ -72,14 +72,14 @@ reported about the loaded packages. See the documentation for type LoadMode
|
|||
for details.
|
||||
|
||||
Most tools should pass their command-line arguments (after any flags)
|
||||
uninterpreted to [Load], so that it can interpret them
|
||||
uninterpreted to Load, so that it can interpret them
|
||||
according to the conventions of the underlying build system.
|
||||
|
||||
See the Example function for typical usage.
|
||||
|
||||
# The driver protocol
|
||||
|
||||
[Load] may be used to load Go packages even in Go projects that use
|
||||
Load may be used to load Go packages even in Go projects that use
|
||||
alternative build systems, by installing an appropriate "driver"
|
||||
program for the build system and specifying its location in the
|
||||
GOPACKAGESDRIVER environment variable.
|
||||
|
|
@ -97,6 +97,15 @@ JSON-encoded [DriverRequest] message providing additional information
|
|||
is written to the driver's standard input. The driver must write a
|
||||
JSON-encoded [DriverResponse] message to its standard output. (This
|
||||
message differs from the JSON schema produced by 'go list'.)
|
||||
|
||||
The value of the PWD environment variable seen by the driver process
|
||||
is the preferred name of its working directory. (The working directory
|
||||
may have other aliases due to symbolic links; see the comment on the
|
||||
Dir field of [exec.Cmd] for related information.)
|
||||
When the driver process emits in its response the name of a file
|
||||
that is a descendant of this directory, it must use an absolute path
|
||||
that has the value of PWD as a prefix, to ensure that the returned
|
||||
filenames satisfy the original query.
|
||||
*/
|
||||
package packages // import "golang.org/x/tools/go/packages"
|
||||
|
||||
|
|
@ -198,14 +207,6 @@ Instead, ssadump no longer requests the runtime package,
|
|||
but seeks it among the dependencies of the user-specified packages,
|
||||
and emits an error if it is not found.
|
||||
|
||||
Overlays: The Overlay field in the Config allows providing alternate contents
|
||||
for Go source files, by providing a mapping from file path to contents.
|
||||
go/packages will pull in new imports added in overlay files when go/packages
|
||||
is run in LoadImports mode or greater.
|
||||
Overlay support for the go list driver isn't complete yet: if the file doesn't
|
||||
exist on disk, it will only be recognized in an overlay if it is a non-test file
|
||||
and the package would be reported even without the overlay.
|
||||
|
||||
Questions & Tasks
|
||||
|
||||
- Add GOARCH/GOOS?
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import (
|
|||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"slices"
|
||||
"strings"
|
||||
)
|
||||
|
||||
|
|
@ -34,8 +35,8 @@ type DriverRequest struct {
|
|||
// Tests specifies whether the patterns should also return test packages.
|
||||
Tests bool `json:"tests"`
|
||||
|
||||
// Overlay maps file paths (relative to the driver's working directory) to the byte contents
|
||||
// of overlay files.
|
||||
// Overlay maps file paths (relative to the driver's working directory)
|
||||
// to the contents of overlay files (see Config.Overlay).
|
||||
Overlay map[string][]byte `json:"overlay"`
|
||||
}
|
||||
|
||||
|
|
@ -79,10 +80,10 @@ type DriverResponse struct {
|
|||
|
||||
// driver is the type for functions that query the build system for the
|
||||
// packages named by the patterns.
|
||||
type driver func(cfg *Config, patterns ...string) (*DriverResponse, error)
|
||||
type driver func(cfg *Config, patterns []string) (*DriverResponse, error)
|
||||
|
||||
// findExternalDriver returns the file path of a tool that supplies
|
||||
// the build system package structure, or "" if not found."
|
||||
// the build system package structure, or "" if not found.
|
||||
// If GOPACKAGESDRIVER is set in the environment findExternalTool returns its
|
||||
// value, otherwise it searches for a binary named gopackagesdriver on the PATH.
|
||||
func findExternalDriver(cfg *Config) driver {
|
||||
|
|
@ -103,7 +104,7 @@ func findExternalDriver(cfg *Config) driver {
|
|||
return nil
|
||||
}
|
||||
}
|
||||
return func(cfg *Config, words ...string) (*DriverResponse, error) {
|
||||
return func(cfg *Config, patterns []string) (*DriverResponse, error) {
|
||||
req, err := json.Marshal(DriverRequest{
|
||||
Mode: cfg.Mode,
|
||||
Env: cfg.Env,
|
||||
|
|
@ -117,9 +118,21 @@ func findExternalDriver(cfg *Config) driver {
|
|||
|
||||
buf := new(bytes.Buffer)
|
||||
stderr := new(bytes.Buffer)
|
||||
cmd := exec.CommandContext(cfg.Context, tool, words...)
|
||||
cmd := exec.CommandContext(cfg.Context, tool, patterns...)
|
||||
cmd.Dir = cfg.Dir
|
||||
cmd.Env = cfg.Env
|
||||
// The cwd gets resolved to the real path. On Darwin, where
|
||||
// /tmp is a symlink, this breaks anything that expects the
|
||||
// working directory to keep the original path, including the
|
||||
// go command when dealing with modules.
|
||||
//
|
||||
// os.Getwd stdlib has a special feature where if the
|
||||
// cwd and the PWD are the same node then it trusts
|
||||
// the PWD, so by setting it in the env for the child
|
||||
// process we fix up all the paths returned by the go
|
||||
// command.
|
||||
//
|
||||
// (See similar trick in Invocation.run in ../../internal/gocommand/invoke.go)
|
||||
cmd.Env = append(slices.Clip(cfg.Env), "PWD="+cfg.Dir)
|
||||
cmd.Stdin = bytes.NewReader(req)
|
||||
cmd.Stdout = buf
|
||||
cmd.Stderr = stderr
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@ import (
|
|||
"sync"
|
||||
"unicode"
|
||||
|
||||
"golang.org/x/tools/go/internal/packagesdriver"
|
||||
"golang.org/x/tools/internal/gocommand"
|
||||
"golang.org/x/tools/internal/packagesinternal"
|
||||
)
|
||||
|
|
@ -81,6 +80,12 @@ type golistState struct {
|
|||
cfg *Config
|
||||
ctx context.Context
|
||||
|
||||
runner *gocommand.Runner
|
||||
|
||||
// overlay is the JSON file that encodes the Config.Overlay
|
||||
// mapping, used by 'go list -overlay=...'.
|
||||
overlay string
|
||||
|
||||
envOnce sync.Once
|
||||
goEnvError error
|
||||
goEnv map[string]string
|
||||
|
|
@ -128,7 +133,10 @@ func (state *golistState) mustGetEnv() map[string]string {
|
|||
// goListDriver uses the go list command to interpret the patterns and produce
|
||||
// the build system package structure.
|
||||
// See driver for more details.
|
||||
func goListDriver(cfg *Config, patterns ...string) (_ *DriverResponse, err error) {
|
||||
//
|
||||
// overlay is the JSON file that encodes the cfg.Overlay
|
||||
// mapping, used by 'go list -overlay=...'
|
||||
func goListDriver(cfg *Config, runner *gocommand.Runner, overlay string, patterns []string) (_ *DriverResponse, err error) {
|
||||
// Make sure that any asynchronous go commands are killed when we return.
|
||||
parentCtx := cfg.Context
|
||||
if parentCtx == nil {
|
||||
|
|
@ -143,13 +151,15 @@ func goListDriver(cfg *Config, patterns ...string) (_ *DriverResponse, err error
|
|||
cfg: cfg,
|
||||
ctx: ctx,
|
||||
vendorDirs: map[string]bool{},
|
||||
overlay: overlay,
|
||||
runner: runner,
|
||||
}
|
||||
|
||||
// Fill in response.Sizes asynchronously if necessary.
|
||||
if cfg.Mode&NeedTypesSizes != 0 || cfg.Mode&NeedTypes != 0 {
|
||||
if cfg.Mode&NeedTypesSizes != 0 || cfg.Mode&(NeedTypes|NeedTypesInfo) != 0 {
|
||||
errCh := make(chan error)
|
||||
go func() {
|
||||
compiler, arch, err := packagesdriver.GetSizesForArgsGolist(ctx, state.cfgInvocation(), cfg.gocmdRunner)
|
||||
compiler, arch, err := getSizesForArgs(ctx, state.cfgInvocation(), runner)
|
||||
response.dr.Compiler = compiler
|
||||
response.dr.Arch = arch
|
||||
errCh <- err
|
||||
|
|
@ -312,6 +322,7 @@ type jsonPackage struct {
|
|||
ImportPath string
|
||||
Dir string
|
||||
Name string
|
||||
Target string
|
||||
Export string
|
||||
GoFiles []string
|
||||
CompiledGoFiles []string
|
||||
|
|
@ -495,13 +506,15 @@ func (state *golistState) createDriverResponse(words ...string) (*DriverResponse
|
|||
pkg := &Package{
|
||||
Name: p.Name,
|
||||
ID: p.ImportPath,
|
||||
Dir: p.Dir,
|
||||
Target: p.Target,
|
||||
GoFiles: absJoin(p.Dir, p.GoFiles, p.CgoFiles),
|
||||
CompiledGoFiles: absJoin(p.Dir, p.CompiledGoFiles),
|
||||
OtherFiles: absJoin(p.Dir, otherFiles(p)...),
|
||||
EmbedFiles: absJoin(p.Dir, p.EmbedFiles),
|
||||
EmbedPatterns: absJoin(p.Dir, p.EmbedPatterns),
|
||||
IgnoredFiles: absJoin(p.Dir, p.IgnoredGoFiles, p.IgnoredOtherFiles),
|
||||
forTest: p.ForTest,
|
||||
ForTest: p.ForTest,
|
||||
depsErrors: p.DepsErrors,
|
||||
Module: p.Module,
|
||||
}
|
||||
|
|
@ -682,7 +695,7 @@ func (state *golistState) shouldAddFilenameFromError(p *jsonPackage) bool {
|
|||
// getGoVersion returns the effective minor version of the go command.
|
||||
func (state *golistState) getGoVersion() (int, error) {
|
||||
state.goVersionOnce.Do(func() {
|
||||
state.goVersion, state.goVersionError = gocommand.GoVersion(state.ctx, state.cfgInvocation(), state.cfg.gocmdRunner)
|
||||
state.goVersion, state.goVersionError = gocommand.GoVersion(state.ctx, state.cfgInvocation(), state.runner)
|
||||
})
|
||||
return state.goVersion, state.goVersionError
|
||||
}
|
||||
|
|
@ -752,7 +765,7 @@ func jsonFlag(cfg *Config, goVersion int) string {
|
|||
}
|
||||
}
|
||||
addFields("Name", "ImportPath", "Error") // These fields are always needed
|
||||
if cfg.Mode&NeedFiles != 0 || cfg.Mode&NeedTypes != 0 {
|
||||
if cfg.Mode&NeedFiles != 0 || cfg.Mode&(NeedTypes|NeedTypesInfo) != 0 {
|
||||
addFields("Dir", "GoFiles", "IgnoredGoFiles", "IgnoredOtherFiles", "CFiles",
|
||||
"CgoFiles", "CXXFiles", "MFiles", "HFiles", "FFiles", "SFiles",
|
||||
"SwigFiles", "SwigCXXFiles", "SysoFiles")
|
||||
|
|
@ -760,7 +773,7 @@ func jsonFlag(cfg *Config, goVersion int) string {
|
|||
addFields("TestGoFiles", "XTestGoFiles")
|
||||
}
|
||||
}
|
||||
if cfg.Mode&NeedTypes != 0 {
|
||||
if cfg.Mode&(NeedTypes|NeedTypesInfo) != 0 {
|
||||
// CompiledGoFiles seems to be required for the test case TestCgoNoSyntax,
|
||||
// even when -compiled isn't passed in.
|
||||
// TODO(#52435): Should we make the test ask for -compiled, or automatically
|
||||
|
|
@ -785,7 +798,7 @@ func jsonFlag(cfg *Config, goVersion int) string {
|
|||
// Request Dir in the unlikely case Export is not absolute.
|
||||
addFields("Dir", "Export")
|
||||
}
|
||||
if cfg.Mode&needInternalForTest != 0 {
|
||||
if cfg.Mode&NeedForTest != 0 {
|
||||
addFields("ForTest")
|
||||
}
|
||||
if cfg.Mode&needInternalDepsErrors != 0 {
|
||||
|
|
@ -800,6 +813,9 @@ func jsonFlag(cfg *Config, goVersion int) string {
|
|||
if cfg.Mode&NeedEmbedPatterns != 0 {
|
||||
addFields("EmbedPatterns")
|
||||
}
|
||||
if cfg.Mode&NeedTarget != 0 {
|
||||
addFields("Target")
|
||||
}
|
||||
return "-json=" + strings.Join(fields, ",")
|
||||
}
|
||||
|
||||
|
|
@ -841,6 +857,7 @@ func (state *golistState) cfgInvocation() gocommand.Invocation {
|
|||
Env: cfg.Env,
|
||||
Logf: cfg.Logf,
|
||||
WorkingDir: cfg.Dir,
|
||||
Overlay: state.overlay,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -849,33 +866,10 @@ func (state *golistState) invokeGo(verb string, args ...string) (*bytes.Buffer,
|
|||
cfg := state.cfg
|
||||
|
||||
inv := state.cfgInvocation()
|
||||
|
||||
// For Go versions 1.16 and above, `go list` accepts overlays directly via
|
||||
// the -overlay flag. Set it, if it's available.
|
||||
//
|
||||
// The check for "list" is not necessarily required, but we should avoid
|
||||
// getting the go version if possible.
|
||||
if verb == "list" {
|
||||
goVersion, err := state.getGoVersion()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if goVersion >= 16 {
|
||||
filename, cleanup, err := state.writeOverlays()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer cleanup()
|
||||
inv.Overlay = filename
|
||||
}
|
||||
}
|
||||
inv.Verb = verb
|
||||
inv.Args = args
|
||||
gocmdRunner := cfg.gocmdRunner
|
||||
if gocmdRunner == nil {
|
||||
gocmdRunner = &gocommand.Runner{}
|
||||
}
|
||||
stdout, stderr, friendlyErr, err := gocmdRunner.RunRaw(cfg.Context, inv)
|
||||
|
||||
stdout, stderr, friendlyErr, err := state.runner.RunRaw(cfg.Context, inv)
|
||||
if err != nil {
|
||||
// Check for 'go' executable not being found.
|
||||
if ee, ok := err.(*exec.Error); ok && ee.Err == exec.ErrNotFound {
|
||||
|
|
@ -899,6 +893,12 @@ func (state *golistState) invokeGo(verb string, args ...string) (*bytes.Buffer,
|
|||
return nil, friendlyErr
|
||||
}
|
||||
|
||||
// Return an error if 'go list' failed due to missing tools in
|
||||
// $GOROOT/pkg/tool/$GOOS_$GOARCH (#69606).
|
||||
if len(stderr.String()) > 0 && strings.Contains(stderr.String(), `go: no such tool`) {
|
||||
return nil, friendlyErr
|
||||
}
|
||||
|
||||
// Is there an error running the C compiler in cgo? This will be reported in the "Error" field
|
||||
// and should be suppressed by go list -e.
|
||||
//
|
||||
|
|
@ -1015,67 +1015,6 @@ func (state *golistState) invokeGo(verb string, args ...string) (*bytes.Buffer,
|
|||
return stdout, nil
|
||||
}
|
||||
|
||||
// OverlayJSON is the format overlay files are expected to be in.
|
||||
// The Replace map maps from overlaid paths to replacement paths:
|
||||
// the Go command will forward all reads trying to open
|
||||
// each overlaid path to its replacement path, or consider the overlaid
|
||||
// path not to exist if the replacement path is empty.
|
||||
//
|
||||
// From golang/go#39958.
|
||||
type OverlayJSON struct {
|
||||
Replace map[string]string `json:"replace,omitempty"`
|
||||
}
|
||||
|
||||
// writeOverlays writes out files for go list's -overlay flag, as described
|
||||
// above.
|
||||
func (state *golistState) writeOverlays() (filename string, cleanup func(), err error) {
|
||||
// Do nothing if there are no overlays in the config.
|
||||
if len(state.cfg.Overlay) == 0 {
|
||||
return "", func() {}, nil
|
||||
}
|
||||
dir, err := os.MkdirTemp("", "gopackages-*")
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
// The caller must clean up this directory, unless this function returns an
|
||||
// error.
|
||||
cleanup = func() {
|
||||
os.RemoveAll(dir)
|
||||
}
|
||||
defer func() {
|
||||
if err != nil {
|
||||
cleanup()
|
||||
}
|
||||
}()
|
||||
overlays := map[string]string{}
|
||||
for k, v := range state.cfg.Overlay {
|
||||
// Create a unique filename for the overlaid files, to avoid
|
||||
// creating nested directories.
|
||||
noSeparator := strings.Join(strings.Split(filepath.ToSlash(k), "/"), "")
|
||||
f, err := os.CreateTemp(dir, fmt.Sprintf("*-%s", noSeparator))
|
||||
if err != nil {
|
||||
return "", func() {}, err
|
||||
}
|
||||
if _, err := f.Write(v); err != nil {
|
||||
return "", func() {}, err
|
||||
}
|
||||
if err := f.Close(); err != nil {
|
||||
return "", func() {}, err
|
||||
}
|
||||
overlays[k] = f.Name()
|
||||
}
|
||||
b, err := json.Marshal(OverlayJSON{Replace: overlays})
|
||||
if err != nil {
|
||||
return "", func() {}, err
|
||||
}
|
||||
// Write out the overlay file that contains the filepath mappings.
|
||||
filename = filepath.Join(dir, "overlay.json")
|
||||
if err := os.WriteFile(filename, b, 0665); err != nil {
|
||||
return "", func() {}, err
|
||||
}
|
||||
return filename, cleanup, nil
|
||||
}
|
||||
|
||||
func containsGoFile(s []string) bool {
|
||||
for _, f := range s {
|
||||
if strings.HasSuffix(f, ".go") {
|
||||
|
|
@ -1104,3 +1043,44 @@ func cmdDebugStr(cmd *exec.Cmd) string {
|
|||
}
|
||||
return fmt.Sprintf("GOROOT=%v GOPATH=%v GO111MODULE=%v GOPROXY=%v PWD=%v %v", env["GOROOT"], env["GOPATH"], env["GO111MODULE"], env["GOPROXY"], env["PWD"], strings.Join(args, " "))
|
||||
}
|
||||
|
||||
// getSizesForArgs queries 'go list' for the appropriate
|
||||
// Compiler and GOARCH arguments to pass to [types.SizesFor].
|
||||
func getSizesForArgs(ctx context.Context, inv gocommand.Invocation, gocmdRunner *gocommand.Runner) (string, string, error) {
|
||||
inv.Verb = "list"
|
||||
inv.Args = []string{"-f", "{{context.GOARCH}} {{context.Compiler}}", "--", "unsafe"}
|
||||
stdout, stderr, friendlyErr, rawErr := gocmdRunner.RunRaw(ctx, inv)
|
||||
var goarch, compiler string
|
||||
if rawErr != nil {
|
||||
rawErrMsg := rawErr.Error()
|
||||
if strings.Contains(rawErrMsg, "cannot find main module") ||
|
||||
strings.Contains(rawErrMsg, "go.mod file not found") {
|
||||
// User's running outside of a module.
|
||||
// All bets are off. Get GOARCH and guess compiler is gc.
|
||||
// TODO(matloob): Is this a problem in practice?
|
||||
inv.Verb = "env"
|
||||
inv.Args = []string{"GOARCH"}
|
||||
envout, enverr := gocmdRunner.Run(ctx, inv)
|
||||
if enverr != nil {
|
||||
return "", "", enverr
|
||||
}
|
||||
goarch = strings.TrimSpace(envout.String())
|
||||
compiler = "gc"
|
||||
} else if friendlyErr != nil {
|
||||
return "", "", friendlyErr
|
||||
} else {
|
||||
// This should be unreachable, but be defensive
|
||||
// in case RunRaw's error results are inconsistent.
|
||||
return "", "", rawErr
|
||||
}
|
||||
} else {
|
||||
fields := strings.Fields(stdout.String())
|
||||
if len(fields) < 2 {
|
||||
return "", "", fmt.Errorf("could not parse GOARCH and Go compiler in format \"<GOARCH> <compiler>\":\nstdout: <<%s>>\nstderr: <<%s>>",
|
||||
stdout.String(), stderr.String())
|
||||
}
|
||||
goarch = fields[0]
|
||||
compiler = fields[1]
|
||||
}
|
||||
return compiler, goarch, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,49 +9,48 @@ import (
|
|||
"strings"
|
||||
)
|
||||
|
||||
var allModes = []LoadMode{
|
||||
NeedName,
|
||||
NeedFiles,
|
||||
NeedCompiledGoFiles,
|
||||
NeedImports,
|
||||
NeedDeps,
|
||||
NeedExportFile,
|
||||
NeedTypes,
|
||||
NeedSyntax,
|
||||
NeedTypesInfo,
|
||||
NeedTypesSizes,
|
||||
var modes = [...]struct {
|
||||
mode LoadMode
|
||||
name string
|
||||
}{
|
||||
{NeedName, "NeedName"},
|
||||
{NeedFiles, "NeedFiles"},
|
||||
{NeedCompiledGoFiles, "NeedCompiledGoFiles"},
|
||||
{NeedImports, "NeedImports"},
|
||||
{NeedDeps, "NeedDeps"},
|
||||
{NeedExportFile, "NeedExportFile"},
|
||||
{NeedTypes, "NeedTypes"},
|
||||
{NeedSyntax, "NeedSyntax"},
|
||||
{NeedTypesInfo, "NeedTypesInfo"},
|
||||
{NeedTypesSizes, "NeedTypesSizes"},
|
||||
{NeedForTest, "NeedForTest"},
|
||||
{NeedModule, "NeedModule"},
|
||||
{NeedEmbedFiles, "NeedEmbedFiles"},
|
||||
{NeedEmbedPatterns, "NeedEmbedPatterns"},
|
||||
{NeedTarget, "NeedTarget"},
|
||||
}
|
||||
|
||||
var modeStrings = []string{
|
||||
"NeedName",
|
||||
"NeedFiles",
|
||||
"NeedCompiledGoFiles",
|
||||
"NeedImports",
|
||||
"NeedDeps",
|
||||
"NeedExportFile",
|
||||
"NeedTypes",
|
||||
"NeedSyntax",
|
||||
"NeedTypesInfo",
|
||||
"NeedTypesSizes",
|
||||
}
|
||||
|
||||
func (mod LoadMode) String() string {
|
||||
m := mod
|
||||
if m == 0 {
|
||||
func (mode LoadMode) String() string {
|
||||
if mode == 0 {
|
||||
return "LoadMode(0)"
|
||||
}
|
||||
var out []string
|
||||
for i, x := range allModes {
|
||||
if x > m {
|
||||
break
|
||||
}
|
||||
if (m & x) != 0 {
|
||||
out = append(out, modeStrings[i])
|
||||
m = m ^ x
|
||||
// named bits
|
||||
for _, item := range modes {
|
||||
if (mode & item.mode) != 0 {
|
||||
mode ^= item.mode
|
||||
out = append(out, item.name)
|
||||
}
|
||||
}
|
||||
if m != 0 {
|
||||
out = append(out, "Unknown")
|
||||
// unnamed residue
|
||||
if mode != 0 {
|
||||
if out == nil {
|
||||
return fmt.Sprintf("LoadMode(%#x)", int(mode))
|
||||
}
|
||||
out = append(out, fmt.Sprintf("%#x", int(mode)))
|
||||
}
|
||||
return fmt.Sprintf("LoadMode(%s)", strings.Join(out, "|"))
|
||||
if len(out) == 1 {
|
||||
return out[0]
|
||||
}
|
||||
return "(" + strings.Join(out, "|") + ")"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,42 +9,67 @@ package packages
|
|||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"go/parser"
|
||||
"go/scanner"
|
||||
"go/token"
|
||||
"go/types"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"golang.org/x/sync/errgroup"
|
||||
|
||||
"golang.org/x/tools/go/gcexportdata"
|
||||
"golang.org/x/tools/internal/gocommand"
|
||||
"golang.org/x/tools/internal/packagesinternal"
|
||||
"golang.org/x/tools/internal/typesinternal"
|
||||
"golang.org/x/tools/internal/versions"
|
||||
)
|
||||
|
||||
// A LoadMode controls the amount of detail to return when loading.
|
||||
// The bits below can be combined to specify which fields should be
|
||||
// filled in the result packages.
|
||||
//
|
||||
// The zero value is a special case, equivalent to combining
|
||||
// the NeedName, NeedFiles, and NeedCompiledGoFiles bits.
|
||||
//
|
||||
// ID and Errors (if present) will always be filled.
|
||||
// Load may return more information than requested.
|
||||
// [Load] may return more information than requested.
|
||||
//
|
||||
// The Mode flag is a union of several bits named NeedName,
|
||||
// NeedFiles, and so on, each of which determines whether
|
||||
// a given field of Package (Name, Files, etc) should be
|
||||
// populated.
|
||||
//
|
||||
// For convenience, we provide named constants for the most
|
||||
// common combinations of Need flags:
|
||||
//
|
||||
// [LoadFiles] lists of files in each package
|
||||
// [LoadImports] ... plus imports
|
||||
// [LoadTypes] ... plus type information
|
||||
// [LoadSyntax] ... plus type-annotated syntax
|
||||
// [LoadAllSyntax] ... for all dependencies
|
||||
//
|
||||
// Unfortunately there are a number of open bugs related to
|
||||
// interactions among the LoadMode bits:
|
||||
// - https://github.com/golang/go/issues/56633
|
||||
// - https://github.com/golang/go/issues/56677
|
||||
// - https://github.com/golang/go/issues/58726
|
||||
// - https://github.com/golang/go/issues/63517
|
||||
type LoadMode int
|
||||
|
||||
const (
|
||||
// NeedName adds Name and PkgPath.
|
||||
NeedName LoadMode = 1 << iota
|
||||
|
||||
// NeedFiles adds GoFiles and OtherFiles.
|
||||
// NeedFiles adds Dir, GoFiles, OtherFiles, and IgnoredFiles
|
||||
NeedFiles
|
||||
|
||||
// NeedCompiledGoFiles adds CompiledGoFiles.
|
||||
|
|
@ -63,10 +88,10 @@ const (
|
|||
// NeedTypes adds Types, Fset, and IllTyped.
|
||||
NeedTypes
|
||||
|
||||
// NeedSyntax adds Syntax.
|
||||
// NeedSyntax adds Syntax and Fset.
|
||||
NeedSyntax
|
||||
|
||||
// NeedTypesInfo adds TypesInfo.
|
||||
// NeedTypesInfo adds TypesInfo and Fset.
|
||||
NeedTypesInfo
|
||||
|
||||
// NeedTypesSizes adds TypesSizes.
|
||||
|
|
@ -75,9 +100,10 @@ const (
|
|||
// needInternalDepsErrors adds the internal deps errors field for use by gopls.
|
||||
needInternalDepsErrors
|
||||
|
||||
// needInternalForTest adds the internal forTest field.
|
||||
// NeedForTest adds ForTest.
|
||||
//
|
||||
// Tests must also be set on the context for this field to be populated.
|
||||
needInternalForTest
|
||||
NeedForTest
|
||||
|
||||
// typecheckCgo enables full support for type checking cgo. Requires Go 1.15+.
|
||||
// Modifies CompiledGoFiles and Types, and has no effect on its own.
|
||||
|
|
@ -91,27 +117,27 @@ const (
|
|||
|
||||
// NeedEmbedPatterns adds EmbedPatterns.
|
||||
NeedEmbedPatterns
|
||||
|
||||
// NeedTarget adds Target.
|
||||
NeedTarget
|
||||
|
||||
// Be sure to update loadmode_string.go when adding new items!
|
||||
)
|
||||
|
||||
const (
|
||||
// Deprecated: LoadFiles exists for historical compatibility
|
||||
// and should not be used. Please directly specify the needed fields using the Need values.
|
||||
// LoadFiles loads the name and file names for the initial packages.
|
||||
LoadFiles = NeedName | NeedFiles | NeedCompiledGoFiles
|
||||
|
||||
// Deprecated: LoadImports exists for historical compatibility
|
||||
// and should not be used. Please directly specify the needed fields using the Need values.
|
||||
// LoadImports loads the name, file names, and import mapping for the initial packages.
|
||||
LoadImports = LoadFiles | NeedImports
|
||||
|
||||
// Deprecated: LoadTypes exists for historical compatibility
|
||||
// and should not be used. Please directly specify the needed fields using the Need values.
|
||||
// LoadTypes loads exported type information for the initial packages.
|
||||
LoadTypes = LoadImports | NeedTypes | NeedTypesSizes
|
||||
|
||||
// Deprecated: LoadSyntax exists for historical compatibility
|
||||
// and should not be used. Please directly specify the needed fields using the Need values.
|
||||
// LoadSyntax loads typed syntax for the initial packages.
|
||||
LoadSyntax = LoadTypes | NeedSyntax | NeedTypesInfo
|
||||
|
||||
// Deprecated: LoadAllSyntax exists for historical compatibility
|
||||
// and should not be used. Please directly specify the needed fields using the Need values.
|
||||
// LoadAllSyntax loads typed syntax for the initial packages and all dependencies.
|
||||
LoadAllSyntax = LoadSyntax | NeedDeps
|
||||
|
||||
// Deprecated: NeedExportsFile is a historical misspelling of NeedExportFile.
|
||||
|
|
@ -120,15 +146,15 @@ const (
|
|||
|
||||
// A Config specifies details about how packages should be loaded.
|
||||
// The zero value is a valid configuration.
|
||||
// Calls to Load do not modify this struct.
|
||||
//
|
||||
// Calls to [Load] do not modify this struct.
|
||||
type Config struct {
|
||||
// Mode controls the level of information returned for each package.
|
||||
Mode LoadMode
|
||||
|
||||
// Context specifies the context for the load operation.
|
||||
// If the context is cancelled, the loader may stop early
|
||||
// and return an ErrCancelled error.
|
||||
// If Context is nil, the load cannot be cancelled.
|
||||
// Cancelling the context may cause [Load] to abort and
|
||||
// return an error.
|
||||
Context context.Context
|
||||
|
||||
// Logf is the logger for the config.
|
||||
|
|
@ -152,19 +178,10 @@ type Config struct {
|
|||
//
|
||||
Env []string
|
||||
|
||||
// gocmdRunner guards go command calls from concurrency errors.
|
||||
gocmdRunner *gocommand.Runner
|
||||
|
||||
// BuildFlags is a list of command-line flags to be passed through to
|
||||
// the build system's query tool.
|
||||
BuildFlags []string
|
||||
|
||||
// modFile will be used for -modfile in go command invocations.
|
||||
modFile string
|
||||
|
||||
// modFlag will be used for -modfile in go command invocations.
|
||||
modFlag string
|
||||
|
||||
// Fset provides source position information for syntax trees and types.
|
||||
// If Fset is nil, Load will use a new fileset, but preserve Fset's value.
|
||||
Fset *token.FileSet
|
||||
|
|
@ -197,28 +214,55 @@ type Config struct {
|
|||
// setting Tests may have no effect.
|
||||
Tests bool
|
||||
|
||||
// Overlay provides a mapping of absolute file paths to file contents.
|
||||
// If the file with the given path already exists, the parser will use the
|
||||
// alternative file contents provided by the map.
|
||||
// Overlay is a mapping from absolute file paths to file contents.
|
||||
//
|
||||
// Overlays provide incomplete support for when a given file doesn't
|
||||
// already exist on disk. See the package doc above for more details.
|
||||
// For each map entry, [Load] uses the alternative file
|
||||
// contents provided by the overlay mapping instead of reading
|
||||
// from the file system. This mechanism can be used to enable
|
||||
// editor-integrated tools to correctly analyze the contents
|
||||
// of modified but unsaved buffers, for example.
|
||||
//
|
||||
// The overlay mapping is passed to the build system's driver
|
||||
// (see "The driver protocol") so that it too can report
|
||||
// consistent package metadata about unsaved files. However,
|
||||
// drivers may vary in their level of support for overlays.
|
||||
Overlay map[string][]byte
|
||||
|
||||
// -- Hidden configuration fields only for use in x/tools --
|
||||
|
||||
// modFile will be used for -modfile in go command invocations.
|
||||
modFile string
|
||||
|
||||
// modFlag will be used for -modfile in go command invocations.
|
||||
modFlag string
|
||||
}
|
||||
|
||||
// Load loads and returns the Go packages named by the given patterns.
|
||||
//
|
||||
// Config specifies loading options;
|
||||
// nil behaves the same as an empty Config.
|
||||
// The cfg parameter specifies loading options; nil behaves the same as an empty [Config].
|
||||
//
|
||||
// Load returns an error if any of the patterns was invalid
|
||||
// as defined by the underlying build system.
|
||||
// The [Config.Mode] field is a set of bits that determine what kinds
|
||||
// of information should be computed and returned. Modes that require
|
||||
// more information tend to be slower. See [LoadMode] for details
|
||||
// and important caveats. Its zero value is equivalent to
|
||||
// [NeedName] | [NeedFiles] | [NeedCompiledGoFiles].
|
||||
//
|
||||
// Each call to Load returns a new set of [Package] instances.
|
||||
// The Packages and their Imports form a directed acyclic graph.
|
||||
//
|
||||
// If the [NeedTypes] mode flag was set, each call to Load uses a new
|
||||
// [types.Importer], so [types.Object] and [types.Type] values from
|
||||
// different calls to Load must not be mixed as they will have
|
||||
// inconsistent notions of type identity.
|
||||
//
|
||||
// If any of the patterns was invalid as defined by the
|
||||
// underlying build system, Load returns an error.
|
||||
// It may return an empty list of packages without an error,
|
||||
// for instance for an empty expansion of a valid wildcard.
|
||||
// Errors associated with a particular package are recorded in the
|
||||
// corresponding Package's Errors list, and do not cause Load to
|
||||
// return an error. Clients may need to handle such errors before
|
||||
// proceeding with further analysis. The PrintErrors function is
|
||||
// proceeding with further analysis. The [PrintErrors] function is
|
||||
// provided for convenient display of all errors.
|
||||
func Load(cfg *Config, patterns ...string) ([]*Package, error) {
|
||||
ld := newLoader(cfg)
|
||||
|
|
@ -255,24 +299,129 @@ func Load(cfg *Config, patterns ...string) ([]*Package, error) {
|
|||
// defaultDriver will fall back to the go list driver.
|
||||
// The boolean result indicates that an external driver handled the request.
|
||||
func defaultDriver(cfg *Config, patterns ...string) (*DriverResponse, bool, error) {
|
||||
const (
|
||||
// windowsArgMax specifies the maximum command line length for
|
||||
// the Windows' CreateProcess function.
|
||||
windowsArgMax = 32767
|
||||
// maxEnvSize is a very rough estimation of the maximum environment
|
||||
// size of a user.
|
||||
maxEnvSize = 16384
|
||||
// safeArgMax specifies the maximum safe command line length to use
|
||||
// by the underlying driver excl. the environment. We choose the Windows'
|
||||
// ARG_MAX as the starting point because it's one of the lowest ARG_MAX
|
||||
// constants out of the different supported platforms,
|
||||
// e.g., https://www.in-ulm.de/~mascheck/various/argmax/#results.
|
||||
safeArgMax = windowsArgMax - maxEnvSize
|
||||
)
|
||||
chunks, err := splitIntoChunks(patterns, safeArgMax)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
|
||||
if driver := findExternalDriver(cfg); driver != nil {
|
||||
response, err := driver(cfg, patterns...)
|
||||
response, err := callDriverOnChunks(driver, cfg, chunks)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
} else if !response.NotHandled {
|
||||
return response, true, nil
|
||||
}
|
||||
// (fall through)
|
||||
// not handled: fall through
|
||||
}
|
||||
|
||||
response, err := goListDriver(cfg, patterns...)
|
||||
// go list fallback
|
||||
|
||||
// Write overlays once, as there are many calls
|
||||
// to 'go list' (one per chunk plus others too).
|
||||
overlayFile, cleanupOverlay, err := gocommand.WriteOverlays(cfg.Overlay)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
return response, false, nil
|
||||
defer cleanupOverlay()
|
||||
|
||||
var runner gocommand.Runner // (shared across many 'go list' calls)
|
||||
driver := func(cfg *Config, patterns []string) (*DriverResponse, error) {
|
||||
return goListDriver(cfg, &runner, overlayFile, patterns)
|
||||
}
|
||||
response, err := callDriverOnChunks(driver, cfg, chunks)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
return response, false, err
|
||||
}
|
||||
|
||||
// splitIntoChunks chunks the slice so that the total number of characters
|
||||
// in a chunk is no longer than argMax.
|
||||
func splitIntoChunks(patterns []string, argMax int) ([][]string, error) {
|
||||
if argMax <= 0 {
|
||||
return nil, errors.New("failed to split patterns into chunks, negative safe argMax value")
|
||||
}
|
||||
var chunks [][]string
|
||||
charsInChunk := 0
|
||||
nextChunkStart := 0
|
||||
for i, v := range patterns {
|
||||
vChars := len(v)
|
||||
if vChars > argMax {
|
||||
// a single pattern is longer than the maximum safe ARG_MAX, hardly should happen
|
||||
return nil, errors.New("failed to split patterns into chunks, a pattern is too long")
|
||||
}
|
||||
charsInChunk += vChars + 1 // +1 is for a whitespace between patterns that has to be counted too
|
||||
if charsInChunk > argMax {
|
||||
chunks = append(chunks, patterns[nextChunkStart:i])
|
||||
nextChunkStart = i
|
||||
charsInChunk = vChars
|
||||
}
|
||||
}
|
||||
// add the last chunk
|
||||
if nextChunkStart < len(patterns) {
|
||||
chunks = append(chunks, patterns[nextChunkStart:])
|
||||
}
|
||||
return chunks, nil
|
||||
}
|
||||
|
||||
func callDriverOnChunks(driver driver, cfg *Config, chunks [][]string) (*DriverResponse, error) {
|
||||
if len(chunks) == 0 {
|
||||
return driver(cfg, nil)
|
||||
}
|
||||
responses := make([]*DriverResponse, len(chunks))
|
||||
errNotHandled := errors.New("driver returned NotHandled")
|
||||
var g errgroup.Group
|
||||
for i, chunk := range chunks {
|
||||
g.Go(func() (err error) {
|
||||
responses[i], err = driver(cfg, chunk)
|
||||
if responses[i] != nil && responses[i].NotHandled {
|
||||
err = errNotHandled
|
||||
}
|
||||
return err
|
||||
})
|
||||
}
|
||||
if err := g.Wait(); err != nil {
|
||||
if errors.Is(err, errNotHandled) {
|
||||
return &DriverResponse{NotHandled: true}, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return mergeResponses(responses...), nil
|
||||
}
|
||||
|
||||
func mergeResponses(responses ...*DriverResponse) *DriverResponse {
|
||||
if len(responses) == 0 {
|
||||
return nil
|
||||
}
|
||||
response := newDeduper()
|
||||
response.dr.NotHandled = false
|
||||
response.dr.Compiler = responses[0].Compiler
|
||||
response.dr.Arch = responses[0].Arch
|
||||
response.dr.GoVersion = responses[0].GoVersion
|
||||
for _, v := range responses {
|
||||
response.addAll(v)
|
||||
}
|
||||
return response.dr
|
||||
}
|
||||
|
||||
// A Package describes a loaded Go package.
|
||||
//
|
||||
// It also defines part of the JSON schema of [DriverResponse].
|
||||
// See the package documentation for an overview.
|
||||
type Package struct {
|
||||
// ID is a unique identifier for a package,
|
||||
// in a syntax provided by the underlying build system.
|
||||
|
|
@ -288,6 +437,12 @@ type Package struct {
|
|||
// PkgPath is the package path as used by the go/types package.
|
||||
PkgPath string
|
||||
|
||||
// Dir is the directory associated with the package, if it exists.
|
||||
//
|
||||
// For packages listed by the go command, this is the directory containing
|
||||
// the package files.
|
||||
Dir string
|
||||
|
||||
// Errors contains any errors encountered querying the metadata
|
||||
// of the package, or while parsing or type-checking its files.
|
||||
Errors []Error
|
||||
|
|
@ -327,23 +482,38 @@ type Package struct {
|
|||
// information for the package as provided by the build system.
|
||||
ExportFile string
|
||||
|
||||
// Target is the absolute install path of the .a file, for libraries,
|
||||
// and of the executable file, for binaries.
|
||||
Target string
|
||||
|
||||
// Imports maps import paths appearing in the package's Go source files
|
||||
// to corresponding loaded Packages.
|
||||
Imports map[string]*Package
|
||||
|
||||
// Module is the module information for the package if it exists.
|
||||
//
|
||||
// Note: it may be missing for std and cmd; see Go issue #65816.
|
||||
Module *Module
|
||||
|
||||
// -- The following fields are not part of the driver JSON schema. --
|
||||
|
||||
// Types provides type information for the package.
|
||||
// The NeedTypes LoadMode bit sets this field for packages matching the
|
||||
// patterns; type information for dependencies may be missing or incomplete,
|
||||
// unless NeedDeps and NeedImports are also set.
|
||||
Types *types.Package
|
||||
//
|
||||
// Each call to [Load] returns a consistent set of type
|
||||
// symbols, as defined by the comment at [types.Identical].
|
||||
// Avoid mixing type information from two or more calls to [Load].
|
||||
Types *types.Package `json:"-"`
|
||||
|
||||
// Fset provides position information for Types, TypesInfo, and Syntax.
|
||||
// It is set only when Types is set.
|
||||
Fset *token.FileSet
|
||||
Fset *token.FileSet `json:"-"`
|
||||
|
||||
// IllTyped indicates whether the package or any dependency contains errors.
|
||||
// It is set only when Types is set.
|
||||
IllTyped bool
|
||||
IllTyped bool `json:"-"`
|
||||
|
||||
// Syntax is the package's syntax trees, for the files listed in CompiledGoFiles.
|
||||
//
|
||||
|
|
@ -353,26 +523,28 @@ type Package struct {
|
|||
//
|
||||
// Syntax is kept in the same order as CompiledGoFiles, with the caveat that nils are
|
||||
// removed. If parsing returned nil, Syntax may be shorter than CompiledGoFiles.
|
||||
Syntax []*ast.File
|
||||
Syntax []*ast.File `json:"-"`
|
||||
|
||||
// TypesInfo provides type information about the package's syntax trees.
|
||||
// It is set only when Syntax is set.
|
||||
TypesInfo *types.Info
|
||||
TypesInfo *types.Info `json:"-"`
|
||||
|
||||
// TypesSizes provides the effective size function for types in TypesInfo.
|
||||
TypesSizes types.Sizes
|
||||
TypesSizes types.Sizes `json:"-"`
|
||||
|
||||
// forTest is the package under test, if any.
|
||||
forTest string
|
||||
// -- internal --
|
||||
|
||||
// ForTest is the package under test, if any.
|
||||
ForTest string
|
||||
|
||||
// depsErrors is the DepsErrors field from the go list response, if any.
|
||||
depsErrors []*packagesinternal.PackageError
|
||||
|
||||
// module is the module information for the package if it exists.
|
||||
Module *Module
|
||||
}
|
||||
|
||||
// Module provides module information for a package.
|
||||
//
|
||||
// It also defines part of the JSON schema of [DriverResponse].
|
||||
// See the package documentation for an overview.
|
||||
type Module struct {
|
||||
Path string // module path
|
||||
Version string // module version
|
||||
|
|
@ -392,9 +564,6 @@ type ModuleError struct {
|
|||
}
|
||||
|
||||
func init() {
|
||||
packagesinternal.GetForTest = func(p interface{}) string {
|
||||
return p.(*Package).forTest
|
||||
}
|
||||
packagesinternal.GetDepsErrors = func(p interface{}) []*packagesinternal.PackageError {
|
||||
return p.(*Package).depsErrors
|
||||
}
|
||||
|
|
@ -406,7 +575,6 @@ func init() {
|
|||
}
|
||||
packagesinternal.TypecheckCgo = int(typecheckCgo)
|
||||
packagesinternal.DepsErrors = int(needInternalDepsErrors)
|
||||
packagesinternal.ForTest = int(needInternalForTest)
|
||||
}
|
||||
|
||||
// An Error describes a problem with a package's metadata, syntax, or types.
|
||||
|
|
@ -505,6 +673,7 @@ func (p *Package) UnmarshalJSON(b []byte) error {
|
|||
OtherFiles: flat.OtherFiles,
|
||||
EmbedFiles: flat.EmbedFiles,
|
||||
EmbedPatterns: flat.EmbedPatterns,
|
||||
IgnoredFiles: flat.IgnoredFiles,
|
||||
ExportFile: flat.ExportFile,
|
||||
}
|
||||
if len(flat.Imports) > 0 {
|
||||
|
|
@ -521,18 +690,19 @@ func (p *Package) String() string { return p.ID }
|
|||
// loaderPackage augments Package with state used during the loading phase
|
||||
type loaderPackage struct {
|
||||
*Package
|
||||
importErrors map[string]error // maps each bad import to its error
|
||||
loadOnce sync.Once
|
||||
color uint8 // for cycle detection
|
||||
needsrc bool // load from source (Mode >= LoadTypes)
|
||||
needtypes bool // type information is either requested or depended on
|
||||
initial bool // package was matched by a pattern
|
||||
goVersion int // minor version number of go command on PATH
|
||||
importErrors map[string]error // maps each bad import to its error
|
||||
preds []*loaderPackage // packages that import this one
|
||||
unfinishedSuccs atomic.Int32 // number of direct imports not yet loaded
|
||||
color uint8 // for cycle detection
|
||||
needsrc bool // load from source (Mode >= LoadTypes)
|
||||
needtypes bool // type information is either requested or depended on
|
||||
initial bool // package was matched by a pattern
|
||||
goVersion int // minor version number of go command on PATH
|
||||
}
|
||||
|
||||
// loader holds the working state of a single call to load.
|
||||
type loader struct {
|
||||
pkgs map[string]*loaderPackage
|
||||
pkgs map[string]*loaderPackage // keyed by Package.ID
|
||||
Config
|
||||
sizes types.Sizes // non-nil if needed by mode
|
||||
parseCache map[string]*parseValue
|
||||
|
|
@ -578,9 +748,6 @@ func newLoader(cfg *Config) *loader {
|
|||
if ld.Config.Env == nil {
|
||||
ld.Config.Env = os.Environ()
|
||||
}
|
||||
if ld.Config.gocmdRunner == nil {
|
||||
ld.Config.gocmdRunner = &gocommand.Runner{}
|
||||
}
|
||||
if ld.Context == nil {
|
||||
ld.Context = context.Background()
|
||||
}
|
||||
|
|
@ -594,7 +761,7 @@ func newLoader(cfg *Config) *loader {
|
|||
ld.requestedMode = ld.Mode
|
||||
ld.Mode = impliedLoadMode(ld.Mode)
|
||||
|
||||
if ld.Mode&NeedTypes != 0 || ld.Mode&NeedSyntax != 0 {
|
||||
if ld.Mode&(NeedSyntax|NeedTypes|NeedTypesInfo) != 0 {
|
||||
if ld.Fset == nil {
|
||||
ld.Fset = token.NewFileSet()
|
||||
}
|
||||
|
|
@ -603,6 +770,7 @@ func newLoader(cfg *Config) *loader {
|
|||
// because we load source if export data is missing.
|
||||
if ld.ParseFile == nil {
|
||||
ld.ParseFile = func(fset *token.FileSet, filename string, src []byte) (*ast.File, error) {
|
||||
// We implicitly promise to keep doing ast.Object resolution. :(
|
||||
const mode = parser.AllErrors | parser.ParseComments
|
||||
return parser.ParseFile(fset, filename, src, mode)
|
||||
}
|
||||
|
|
@ -634,7 +802,7 @@ func (ld *loader) refine(response *DriverResponse) ([]*Package, error) {
|
|||
exportDataInvalid := len(ld.Overlay) > 0 || pkg.ExportFile == "" && pkg.PkgPath != "unsafe"
|
||||
// This package needs type information if the caller requested types and the package is
|
||||
// either a root, or it's a non-root and the user requested dependencies ...
|
||||
needtypes := (ld.Mode&NeedTypes|NeedTypesInfo != 0 && (rootIndex >= 0 || ld.Mode&NeedDeps != 0))
|
||||
needtypes := (ld.Mode&(NeedTypes|NeedTypesInfo) != 0 && (rootIndex >= 0 || ld.Mode&NeedDeps != 0))
|
||||
// This package needs source if the call requested source (or types info, which implies source)
|
||||
// and the package is either a root, or itas a non- root and the user requested dependencies...
|
||||
needsrc := ((ld.Mode&(NeedSyntax|NeedTypesInfo) != 0 && (rootIndex >= 0 || ld.Mode&NeedDeps != 0)) ||
|
||||
|
|
@ -659,9 +827,10 @@ func (ld *loader) refine(response *DriverResponse) ([]*Package, error) {
|
|||
}
|
||||
}
|
||||
|
||||
if ld.Mode&NeedImports != 0 {
|
||||
// Materialize the import graph.
|
||||
|
||||
// Materialize the import graph if it is needed (NeedImports),
|
||||
// or if we'll be using loadPackages (Need{Syntax|Types|TypesInfo}).
|
||||
var leaves []*loaderPackage // packages with no unfinished successors
|
||||
if ld.Mode&(NeedImports|NeedSyntax|NeedTypes|NeedTypesInfo) != 0 {
|
||||
const (
|
||||
white = 0 // new
|
||||
grey = 1 // in progress
|
||||
|
|
@ -680,63 +849,76 @@ func (ld *loader) refine(response *DriverResponse) ([]*Package, error) {
|
|||
// dependency on a package that does. These are the only packages
|
||||
// for which we load source code.
|
||||
var stack []*loaderPackage
|
||||
var visit func(lpkg *loaderPackage) bool
|
||||
visit = func(lpkg *loaderPackage) bool {
|
||||
switch lpkg.color {
|
||||
case black:
|
||||
return lpkg.needsrc
|
||||
case grey:
|
||||
var visit func(from, lpkg *loaderPackage) bool
|
||||
visit = func(from, lpkg *loaderPackage) bool {
|
||||
if lpkg.color == grey {
|
||||
panic("internal error: grey node")
|
||||
}
|
||||
lpkg.color = grey
|
||||
stack = append(stack, lpkg) // push
|
||||
stubs := lpkg.Imports // the structure form has only stubs with the ID in the Imports
|
||||
lpkg.Imports = make(map[string]*Package, len(stubs))
|
||||
for importPath, ipkg := range stubs {
|
||||
var importErr error
|
||||
imp := ld.pkgs[ipkg.ID]
|
||||
if imp == nil {
|
||||
// (includes package "C" when DisableCgo)
|
||||
importErr = fmt.Errorf("missing package: %q", ipkg.ID)
|
||||
} else if imp.color == grey {
|
||||
importErr = fmt.Errorf("import cycle: %s", stack)
|
||||
}
|
||||
if importErr != nil {
|
||||
if lpkg.importErrors == nil {
|
||||
lpkg.importErrors = make(map[string]error)
|
||||
if lpkg.color == white {
|
||||
lpkg.color = grey
|
||||
stack = append(stack, lpkg) // push
|
||||
stubs := lpkg.Imports // the structure form has only stubs with the ID in the Imports
|
||||
lpkg.Imports = make(map[string]*Package, len(stubs))
|
||||
for importPath, ipkg := range stubs {
|
||||
var importErr error
|
||||
imp := ld.pkgs[ipkg.ID]
|
||||
if imp == nil {
|
||||
// (includes package "C" when DisableCgo)
|
||||
importErr = fmt.Errorf("missing package: %q", ipkg.ID)
|
||||
} else if imp.color == grey {
|
||||
importErr = fmt.Errorf("import cycle: %s", stack)
|
||||
}
|
||||
lpkg.importErrors[importPath] = importErr
|
||||
continue
|
||||
if importErr != nil {
|
||||
if lpkg.importErrors == nil {
|
||||
lpkg.importErrors = make(map[string]error)
|
||||
}
|
||||
lpkg.importErrors[importPath] = importErr
|
||||
continue
|
||||
}
|
||||
|
||||
if visit(lpkg, imp) {
|
||||
lpkg.needsrc = true
|
||||
}
|
||||
lpkg.Imports[importPath] = imp.Package
|
||||
}
|
||||
|
||||
if visit(imp) {
|
||||
lpkg.needsrc = true
|
||||
// -- postorder --
|
||||
|
||||
// Complete type information is required for the
|
||||
// immediate dependencies of each source package.
|
||||
if lpkg.needsrc && ld.Mode&NeedTypes != 0 {
|
||||
for _, ipkg := range lpkg.Imports {
|
||||
ld.pkgs[ipkg.ID].needtypes = true
|
||||
}
|
||||
}
|
||||
lpkg.Imports[importPath] = imp.Package
|
||||
|
||||
// NeedTypeSizes causes TypeSizes to be set even
|
||||
// on packages for which types aren't needed.
|
||||
if ld.Mode&NeedTypesSizes != 0 {
|
||||
lpkg.TypesSizes = ld.sizes
|
||||
}
|
||||
|
||||
// Add packages with no imports directly to the queue of leaves.
|
||||
if len(lpkg.Imports) == 0 {
|
||||
leaves = append(leaves, lpkg)
|
||||
}
|
||||
|
||||
stack = stack[:len(stack)-1] // pop
|
||||
lpkg.color = black
|
||||
}
|
||||
|
||||
// Complete type information is required for the
|
||||
// immediate dependencies of each source package.
|
||||
if lpkg.needsrc && ld.Mode&NeedTypes != 0 {
|
||||
for _, ipkg := range lpkg.Imports {
|
||||
ld.pkgs[ipkg.ID].needtypes = true
|
||||
}
|
||||
// Add edge from predecessor.
|
||||
if from != nil {
|
||||
from.unfinishedSuccs.Add(+1) // incref
|
||||
lpkg.preds = append(lpkg.preds, from)
|
||||
}
|
||||
|
||||
// NeedTypeSizes causes TypeSizes to be set even
|
||||
// on packages for which types aren't needed.
|
||||
if ld.Mode&NeedTypesSizes != 0 {
|
||||
lpkg.TypesSizes = ld.sizes
|
||||
}
|
||||
stack = stack[:len(stack)-1] // pop
|
||||
lpkg.color = black
|
||||
|
||||
return lpkg.needsrc
|
||||
}
|
||||
|
||||
// For each initial package, create its import DAG.
|
||||
for _, lpkg := range initial {
|
||||
visit(lpkg)
|
||||
visit(nil, lpkg)
|
||||
}
|
||||
|
||||
} else {
|
||||
|
|
@ -749,16 +931,51 @@ func (ld *loader) refine(response *DriverResponse) ([]*Package, error) {
|
|||
|
||||
// Load type data and syntax if needed, starting at
|
||||
// the initial packages (roots of the import DAG).
|
||||
if ld.Mode&NeedTypes != 0 || ld.Mode&NeedSyntax != 0 {
|
||||
var wg sync.WaitGroup
|
||||
for _, lpkg := range initial {
|
||||
wg.Add(1)
|
||||
go func(lpkg *loaderPackage) {
|
||||
ld.loadRecursive(lpkg)
|
||||
wg.Done()
|
||||
}(lpkg)
|
||||
if ld.Mode&(NeedSyntax|NeedTypes|NeedTypesInfo) != 0 {
|
||||
|
||||
// We avoid using g.SetLimit to limit concurrency as
|
||||
// it makes g.Go stop accepting work, which prevents
|
||||
// workers from enqeuing, and thus finishing, and thus
|
||||
// allowing the group to make progress: deadlock.
|
||||
//
|
||||
// Instead we use the ioLimit and cpuLimit semaphores.
|
||||
g, _ := errgroup.WithContext(ld.Context)
|
||||
|
||||
// enqueues adds a package to the type-checking queue.
|
||||
// It must have no unfinished successors.
|
||||
var enqueue func(*loaderPackage)
|
||||
enqueue = func(lpkg *loaderPackage) {
|
||||
g.Go(func() error {
|
||||
// Parse and type-check.
|
||||
ld.loadPackage(lpkg)
|
||||
|
||||
// Notify each waiting predecessor,
|
||||
// and enqueue it when it becomes a leaf.
|
||||
for _, pred := range lpkg.preds {
|
||||
if pred.unfinishedSuccs.Add(-1) == 0 { // decref
|
||||
enqueue(pred)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
wg.Wait()
|
||||
|
||||
// Load leaves first, adding new packages
|
||||
// to the queue as they become leaves.
|
||||
for _, leaf := range leaves {
|
||||
enqueue(leaf)
|
||||
}
|
||||
|
||||
if err := g.Wait(); err != nil {
|
||||
return nil, err // cancelled
|
||||
}
|
||||
}
|
||||
|
||||
// If the context is done, return its error and
|
||||
// throw out [likely] incomplete packages.
|
||||
if err := ld.Context.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := make([]*Package, len(initial))
|
||||
|
|
@ -794,12 +1011,14 @@ func (ld *loader) refine(response *DriverResponse) ([]*Package, error) {
|
|||
}
|
||||
if ld.requestedMode&NeedTypes == 0 {
|
||||
ld.pkgs[i].Types = nil
|
||||
ld.pkgs[i].Fset = nil
|
||||
ld.pkgs[i].IllTyped = false
|
||||
}
|
||||
if ld.requestedMode&NeedSyntax == 0 {
|
||||
ld.pkgs[i].Syntax = nil
|
||||
}
|
||||
if ld.requestedMode&(NeedSyntax|NeedTypes|NeedTypesInfo) == 0 {
|
||||
ld.pkgs[i].Fset = nil
|
||||
}
|
||||
if ld.requestedMode&NeedTypesInfo == 0 {
|
||||
ld.pkgs[i].TypesInfo = nil
|
||||
}
|
||||
|
|
@ -814,31 +1033,10 @@ func (ld *loader) refine(response *DriverResponse) ([]*Package, error) {
|
|||
return result, nil
|
||||
}
|
||||
|
||||
// loadRecursive loads the specified package and its dependencies,
|
||||
// recursively, in parallel, in topological order.
|
||||
// It is atomic and idempotent.
|
||||
// Precondition: ld.Mode&NeedTypes.
|
||||
func (ld *loader) loadRecursive(lpkg *loaderPackage) {
|
||||
lpkg.loadOnce.Do(func() {
|
||||
// Load the direct dependencies, in parallel.
|
||||
var wg sync.WaitGroup
|
||||
for _, ipkg := range lpkg.Imports {
|
||||
imp := ld.pkgs[ipkg.ID]
|
||||
wg.Add(1)
|
||||
go func(imp *loaderPackage) {
|
||||
ld.loadRecursive(imp)
|
||||
wg.Done()
|
||||
}(imp)
|
||||
}
|
||||
wg.Wait()
|
||||
ld.loadPackage(lpkg)
|
||||
})
|
||||
}
|
||||
|
||||
// loadPackage loads the specified package.
|
||||
// loadPackage loads/parses/typechecks the specified package.
|
||||
// It must be called only once per Package,
|
||||
// after immediate dependencies are loaded.
|
||||
// Precondition: ld.Mode & NeedTypes.
|
||||
// Precondition: ld.Mode&(NeedSyntax|NeedTypes|NeedTypesInfo) != 0.
|
||||
func (ld *loader) loadPackage(lpkg *loaderPackage) {
|
||||
if lpkg.PkgPath == "unsafe" {
|
||||
// Fill in the blanks to avoid surprises.
|
||||
|
|
@ -856,6 +1054,14 @@ func (ld *loader) loadPackage(lpkg *loaderPackage) {
|
|||
lpkg.Types = types.NewPackage(lpkg.PkgPath, lpkg.Name)
|
||||
lpkg.Fset = ld.Fset
|
||||
|
||||
// Start shutting down if the context is done and do not load
|
||||
// source or export data files.
|
||||
// Packages that import this one will have ld.Context.Err() != nil.
|
||||
// ld.Context.Err() will be returned later by refine.
|
||||
if ld.Context.Err() != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Subtle: we populate all Types fields with an empty Package
|
||||
// before loading export data so that export data processing
|
||||
// never has to create a types.Package for an indirect dependency,
|
||||
|
|
@ -866,6 +1072,10 @@ func (ld *loader) loadPackage(lpkg *loaderPackage) {
|
|||
if !lpkg.needtypes && !lpkg.needsrc {
|
||||
return
|
||||
}
|
||||
|
||||
// TODO(adonovan): this condition looks wrong:
|
||||
// I think it should be lpkg.needtypes && !lpg.needsrc,
|
||||
// so that NeedSyntax without NeedTypes can be satisfied by export data.
|
||||
if !lpkg.needsrc {
|
||||
if err := ld.loadFromExportData(lpkg); err != nil {
|
||||
lpkg.Errors = append(lpkg.Errors, Error{
|
||||
|
|
@ -971,20 +1181,31 @@ func (ld *loader) loadPackage(lpkg *loaderPackage) {
|
|||
}
|
||||
|
||||
lpkg.Syntax = files
|
||||
if ld.Config.Mode&NeedTypes == 0 {
|
||||
if ld.Config.Mode&(NeedTypes|NeedTypesInfo) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
lpkg.TypesInfo = &types.Info{
|
||||
Types: make(map[ast.Expr]types.TypeAndValue),
|
||||
Defs: make(map[*ast.Ident]types.Object),
|
||||
Uses: make(map[*ast.Ident]types.Object),
|
||||
Implicits: make(map[ast.Node]types.Object),
|
||||
Instances: make(map[*ast.Ident]types.Instance),
|
||||
Scopes: make(map[ast.Node]*types.Scope),
|
||||
Selections: make(map[*ast.SelectorExpr]*types.Selection),
|
||||
// Start shutting down if the context is done and do not type check.
|
||||
// Packages that import this one will have ld.Context.Err() != nil.
|
||||
// ld.Context.Err() will be returned later by refine.
|
||||
if ld.Context.Err() != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Populate TypesInfo only if needed, as it
|
||||
// causes the type checker to work much harder.
|
||||
if ld.Config.Mode&NeedTypesInfo != 0 {
|
||||
lpkg.TypesInfo = &types.Info{
|
||||
Types: make(map[ast.Expr]types.TypeAndValue),
|
||||
Defs: make(map[*ast.Ident]types.Object),
|
||||
Uses: make(map[*ast.Ident]types.Object),
|
||||
Implicits: make(map[ast.Node]types.Object),
|
||||
Instances: make(map[*ast.Ident]types.Instance),
|
||||
Scopes: make(map[ast.Node]*types.Scope),
|
||||
Selections: make(map[*ast.SelectorExpr]*types.Selection),
|
||||
FileVersions: make(map[*ast.File]string),
|
||||
}
|
||||
}
|
||||
versions.InitFileVersions(lpkg.TypesInfo)
|
||||
lpkg.TypesSizes = ld.sizes
|
||||
|
||||
importer := importerFunc(func(path string) (*types.Package, error) {
|
||||
|
|
@ -1025,7 +1246,7 @@ func (ld *loader) loadPackage(lpkg *loaderPackage) {
|
|||
Sizes: ld.sizes, // may be nil
|
||||
}
|
||||
if lpkg.Module != nil && lpkg.Module.GoVersion != "" {
|
||||
typesinternal.SetGoVersion(tc, "go"+lpkg.Module.GoVersion)
|
||||
tc.GoVersion = "go" + lpkg.Module.GoVersion
|
||||
}
|
||||
if (ld.Mode & typecheckCgo) != 0 {
|
||||
if !typesinternal.SetUsesCgo(tc) {
|
||||
|
|
@ -1036,10 +1257,28 @@ func (ld *loader) loadPackage(lpkg *loaderPackage) {
|
|||
return
|
||||
}
|
||||
}
|
||||
types.NewChecker(tc, ld.Fset, lpkg.Types, lpkg.TypesInfo).Files(lpkg.Syntax)
|
||||
|
||||
// Type-checking is CPU intensive.
|
||||
cpuLimit <- unit{} // acquire a token
|
||||
defer func() { <-cpuLimit }() // release a token
|
||||
|
||||
typErr := types.NewChecker(tc, ld.Fset, lpkg.Types, lpkg.TypesInfo).Files(lpkg.Syntax)
|
||||
lpkg.importErrors = nil // no longer needed
|
||||
|
||||
// In go/types go1.21 and go1.22, Checker.Files failed fast with a
|
||||
// a "too new" error, without calling tc.Error and without
|
||||
// proceeding to type-check the package (#66525).
|
||||
// We rely on the runtimeVersion error to give the suggested remedy.
|
||||
if typErr != nil && len(lpkg.Errors) == 0 && len(lpkg.Syntax) > 0 {
|
||||
if msg := typErr.Error(); strings.HasPrefix(msg, "package requires newer Go version") {
|
||||
appendError(types.Error{
|
||||
Fset: ld.Fset,
|
||||
Pos: lpkg.Syntax[0].Package,
|
||||
Msg: msg,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// If !Cgo, the type-checker uses FakeImportC mode, so
|
||||
// it doesn't invoke the importer for import "C",
|
||||
// nor report an error for the import,
|
||||
|
|
@ -1061,6 +1300,12 @@ func (ld *loader) loadPackage(lpkg *loaderPackage) {
|
|||
}
|
||||
}
|
||||
|
||||
// If types.Checker.Files had an error that was unreported,
|
||||
// make sure to report the unknown error so the package is illTyped.
|
||||
if typErr != nil && len(lpkg.Errors) == 0 {
|
||||
appendError(typErr)
|
||||
}
|
||||
|
||||
// Record accumulated errors.
|
||||
illTyped := len(lpkg.Errors) > 0
|
||||
if !illTyped {
|
||||
|
|
@ -1081,8 +1326,11 @@ type importerFunc func(path string) (*types.Package, error)
|
|||
func (f importerFunc) Import(path string) (*types.Package, error) { return f(path) }
|
||||
|
||||
// We use a counting semaphore to limit
|
||||
// the number of parallel I/O calls per process.
|
||||
var ioLimit = make(chan bool, 20)
|
||||
// the number of parallel I/O calls or CPU threads per process.
|
||||
var (
|
||||
ioLimit = make(chan unit, 20)
|
||||
cpuLimit = make(chan unit, runtime.GOMAXPROCS(0))
|
||||
)
|
||||
|
||||
func (ld *loader) parseFile(filename string) (*ast.File, error) {
|
||||
ld.parseCacheMu.Lock()
|
||||
|
|
@ -1099,20 +1347,28 @@ func (ld *loader) parseFile(filename string) (*ast.File, error) {
|
|||
|
||||
var src []byte
|
||||
for f, contents := range ld.Config.Overlay {
|
||||
// TODO(adonovan): Inefficient for large overlays.
|
||||
// Do an exact name-based map lookup
|
||||
// (for nonexistent files) followed by a
|
||||
// FileID-based map lookup (for existing ones).
|
||||
if sameFile(f, filename) {
|
||||
src = contents
|
||||
break
|
||||
}
|
||||
}
|
||||
var err error
|
||||
if src == nil {
|
||||
ioLimit <- true // wait
|
||||
ioLimit <- unit{} // acquire a token
|
||||
src, err = os.ReadFile(filename)
|
||||
<-ioLimit // signal
|
||||
<-ioLimit // release a token
|
||||
}
|
||||
if err != nil {
|
||||
v.err = err
|
||||
} else {
|
||||
// Parsing is CPU intensive.
|
||||
cpuLimit <- unit{} // acquire a token
|
||||
v.f, v.err = ld.ParseFile(ld.Fset, filename, src)
|
||||
<-cpuLimit // release a token
|
||||
}
|
||||
|
||||
close(v.ready)
|
||||
|
|
@ -1127,23 +1383,21 @@ func (ld *loader) parseFile(filename string) (*ast.File, error) {
|
|||
// Because files are scanned in parallel, the token.Pos
|
||||
// positions of the resulting ast.Files are not ordered.
|
||||
func (ld *loader) parseFiles(filenames []string) ([]*ast.File, []error) {
|
||||
var wg sync.WaitGroup
|
||||
n := len(filenames)
|
||||
parsed := make([]*ast.File, n)
|
||||
errors := make([]error, n)
|
||||
for i, file := range filenames {
|
||||
if ld.Config.Context.Err() != nil {
|
||||
parsed[i] = nil
|
||||
errors[i] = ld.Config.Context.Err()
|
||||
continue
|
||||
}
|
||||
wg.Add(1)
|
||||
go func(i int, filename string) {
|
||||
var (
|
||||
n = len(filenames)
|
||||
parsed = make([]*ast.File, n)
|
||||
errors = make([]error, n)
|
||||
)
|
||||
var g errgroup.Group
|
||||
for i, filename := range filenames {
|
||||
// This creates goroutines unnecessarily in the
|
||||
// cache-hit case, but that case is uncommon.
|
||||
g.Go(func() error {
|
||||
parsed[i], errors[i] = ld.parseFile(filename)
|
||||
wg.Done()
|
||||
}(i, file)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
wg.Wait()
|
||||
g.Wait()
|
||||
|
||||
// Eliminate nils, preserving order.
|
||||
var o int
|
||||
|
|
@ -1302,6 +1556,10 @@ func impliedLoadMode(loadMode LoadMode) LoadMode {
|
|||
// All these things require knowing the import graph.
|
||||
loadMode |= NeedImports
|
||||
}
|
||||
if loadMode&NeedTypes != 0 {
|
||||
// Types require the GoVersion from Module.
|
||||
loadMode |= NeedModule
|
||||
}
|
||||
|
||||
return loadMode
|
||||
}
|
||||
|
|
@ -1310,4 +1568,4 @@ func usesExportData(cfg *Config) bool {
|
|||
return cfg.Mode&NeedExportFile != 0 || cfg.Mode&NeedTypes != 0 && cfg.Mode&NeedDeps == 0
|
||||
}
|
||||
|
||||
var _ interface{} = io.Discard // assert build toolchain is go1.16 or later
|
||||
type unit struct{}
|
||||
|
|
|
|||
|
|
@ -49,11 +49,20 @@ func Visit(pkgs []*Package, pre func(*Package) bool, post func(*Package)) {
|
|||
// PrintErrors returns the number of errors printed.
|
||||
func PrintErrors(pkgs []*Package) int {
|
||||
var n int
|
||||
errModules := make(map[*Module]bool)
|
||||
Visit(pkgs, nil, func(pkg *Package) {
|
||||
for _, err := range pkg.Errors {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
n++
|
||||
}
|
||||
|
||||
// Print pkg.Module.Error once if present.
|
||||
mod := pkg.Module
|
||||
if mod != nil && mod.Error != nil && !errModules[mod] {
|
||||
errModules[mod] = true
|
||||
fmt.Fprintln(os.Stderr, mod.Error.Err)
|
||||
n++
|
||||
}
|
||||
})
|
||||
return n
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,9 +29,12 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/tools/internal/typeparams"
|
||||
"golang.org/x/tools/internal/aliases"
|
||||
"golang.org/x/tools/internal/typesinternal"
|
||||
)
|
||||
|
||||
// TODO(adonovan): think about generic aliases.
|
||||
|
||||
// A Path is an opaque name that identifies a types.Object
|
||||
// relative to its package. Conceptually, the name consists of a
|
||||
// sequence of destructuring operations applied to the package scope
|
||||
|
|
@ -48,7 +51,7 @@ type Path string
|
|||
//
|
||||
// PO package->object Package.Scope.Lookup
|
||||
// OT object->type Object.Type
|
||||
// TT type->type Type.{Elem,Key,Params,Results,Underlying} [EKPRU]
|
||||
// TT type->type Type.{Elem,Key,{,{,Recv}Type}Params,Results,Underlying,Rhs} [EKPRUTrCa]
|
||||
// TO type->object Type.{At,Field,Method,Obj} [AFMO]
|
||||
//
|
||||
// All valid paths start with a package and end at an object
|
||||
|
|
@ -60,8 +63,8 @@ type Path string
|
|||
// - The only PO operator is Package.Scope.Lookup, which requires an identifier.
|
||||
// - The only OT operator is Object.Type,
|
||||
// which we encode as '.' because dot cannot appear in an identifier.
|
||||
// - The TT operators are encoded as [EKPRUTC];
|
||||
// one of these (TypeParam) requires an integer operand,
|
||||
// - The TT operators are encoded as [EKPRUTrCa];
|
||||
// two of these ({,Recv}TypeParams) require an integer operand,
|
||||
// which is encoded as a string of decimal digits.
|
||||
// - The TO operators are encoded as [AFMO];
|
||||
// three of these (At,Field,Method) require an integer operand,
|
||||
|
|
@ -95,19 +98,21 @@ const (
|
|||
opType = '.' // .Type() (Object)
|
||||
|
||||
// type->type operators
|
||||
opElem = 'E' // .Elem() (Pointer, Slice, Array, Chan, Map)
|
||||
opKey = 'K' // .Key() (Map)
|
||||
opParams = 'P' // .Params() (Signature)
|
||||
opResults = 'R' // .Results() (Signature)
|
||||
opUnderlying = 'U' // .Underlying() (Named)
|
||||
opTypeParam = 'T' // .TypeParams.At(i) (Named, Signature)
|
||||
opConstraint = 'C' // .Constraint() (TypeParam)
|
||||
opElem = 'E' // .Elem() (Pointer, Slice, Array, Chan, Map)
|
||||
opKey = 'K' // .Key() (Map)
|
||||
opParams = 'P' // .Params() (Signature)
|
||||
opResults = 'R' // .Results() (Signature)
|
||||
opUnderlying = 'U' // .Underlying() (Named)
|
||||
opTypeParam = 'T' // .TypeParams.At(i) (Named, Signature)
|
||||
opRecvTypeParam = 'r' // .RecvTypeParams.At(i) (Signature)
|
||||
opConstraint = 'C' // .Constraint() (TypeParam)
|
||||
opRhs = 'a' // .Rhs() (Alias)
|
||||
|
||||
// type->object operators
|
||||
opAt = 'A' // .At(i) (Tuple)
|
||||
opField = 'F' // .Field(i) (Struct)
|
||||
opMethod = 'M' // .Method(i) (Named or Interface; not Struct: "promoted" names are ignored)
|
||||
opObj = 'O' // .Obj() (Named, TypeParam)
|
||||
opAt = 'A' // .At(i) (Tuple)
|
||||
opField = 'F' // .Field(i) (Struct)
|
||||
opMethod = 'M' // .Method(i) (Named or Interface; not Struct: "promoted" names are ignored)
|
||||
opObj = 'O' // .Obj() (Named, TypeParam)
|
||||
)
|
||||
|
||||
// For is equivalent to new(Encoder).For(obj).
|
||||
|
|
@ -223,7 +228,7 @@ func (enc *Encoder) For(obj types.Object) (Path, error) {
|
|||
// Reject obviously non-viable cases.
|
||||
switch obj := obj.(type) {
|
||||
case *types.TypeName:
|
||||
if _, ok := obj.Type().(*types.TypeParam); !ok {
|
||||
if _, ok := types.Unalias(obj.Type()).(*types.TypeParam); !ok {
|
||||
// With the exception of type parameters, only package-level type names
|
||||
// have a path.
|
||||
return "", fmt.Errorf("no path for %v", obj)
|
||||
|
|
@ -275,21 +280,26 @@ func (enc *Encoder) For(obj types.Object) (Path, error) {
|
|||
path = append(path, opType)
|
||||
|
||||
T := o.Type()
|
||||
|
||||
if tname.IsAlias() {
|
||||
// type alias
|
||||
if r := find(obj, T, path, nil); r != nil {
|
||||
if alias, ok := T.(*types.Alias); ok {
|
||||
if r := findTypeParam(obj, aliases.TypeParams(alias), path, opTypeParam); r != nil {
|
||||
return Path(r), nil
|
||||
}
|
||||
} else {
|
||||
if named, _ := T.(*types.Named); named != nil {
|
||||
if r := findTypeParam(obj, named.TypeParams(), path, nil); r != nil {
|
||||
// generic named type
|
||||
return Path(r), nil
|
||||
}
|
||||
if r := find(obj, aliases.Rhs(alias), append(path, opRhs)); r != nil {
|
||||
return Path(r), nil
|
||||
}
|
||||
|
||||
} else if tname.IsAlias() {
|
||||
// legacy alias
|
||||
if r := find(obj, T, path); r != nil {
|
||||
return Path(r), nil
|
||||
}
|
||||
|
||||
} else if named, ok := T.(*types.Named); ok {
|
||||
// defined (named) type
|
||||
if r := find(obj, T.Underlying(), append(path, opUnderlying), nil); r != nil {
|
||||
if r := findTypeParam(obj, named.TypeParams(), path, opTypeParam); r != nil {
|
||||
return Path(r), nil
|
||||
}
|
||||
if r := find(obj, named.Underlying(), append(path, opUnderlying)); r != nil {
|
||||
return Path(r), nil
|
||||
}
|
||||
}
|
||||
|
|
@ -302,7 +312,7 @@ func (enc *Encoder) For(obj types.Object) (Path, error) {
|
|||
if _, ok := o.(*types.TypeName); !ok {
|
||||
if o.Exported() {
|
||||
// exported non-type (const, var, func)
|
||||
if r := find(obj, o.Type(), append(path, opType), nil); r != nil {
|
||||
if r := find(obj, o.Type(), append(path, opType)); r != nil {
|
||||
return Path(r), nil
|
||||
}
|
||||
}
|
||||
|
|
@ -310,7 +320,7 @@ func (enc *Encoder) For(obj types.Object) (Path, error) {
|
|||
}
|
||||
|
||||
// Inspect declared methods of defined types.
|
||||
if T, ok := o.Type().(*types.Named); ok {
|
||||
if T, ok := types.Unalias(o.Type()).(*types.Named); ok {
|
||||
path = append(path, opType)
|
||||
// The method index here is always with respect
|
||||
// to the underlying go/types data structures,
|
||||
|
|
@ -322,7 +332,7 @@ func (enc *Encoder) For(obj types.Object) (Path, error) {
|
|||
if m == obj {
|
||||
return Path(path2), nil // found declared method
|
||||
}
|
||||
if r := find(obj, m.Type(), append(path2, opType), nil); r != nil {
|
||||
if r := find(obj, m.Type(), append(path2, opType)); r != nil {
|
||||
return Path(r), nil
|
||||
}
|
||||
}
|
||||
|
|
@ -391,17 +401,12 @@ func (enc *Encoder) concreteMethod(meth *types.Func) (Path, bool) {
|
|||
// of objectpath will only be giving us origin methods, anyway, as referring
|
||||
// to instantiated methods is usually not useful.
|
||||
|
||||
if typeparams.OriginMethod(meth) != meth {
|
||||
if meth.Origin() != meth {
|
||||
return "", false
|
||||
}
|
||||
|
||||
recvT := meth.Type().(*types.Signature).Recv().Type()
|
||||
if ptr, ok := recvT.(*types.Pointer); ok {
|
||||
recvT = ptr.Elem()
|
||||
}
|
||||
|
||||
named, ok := recvT.(*types.Named)
|
||||
if !ok {
|
||||
_, named := typesinternal.ReceiverNamed(meth.Type().(*types.Signature).Recv())
|
||||
if named == nil {
|
||||
return "", false
|
||||
}
|
||||
|
||||
|
|
@ -442,41 +447,64 @@ func (enc *Encoder) concreteMethod(meth *types.Func) (Path, bool) {
|
|||
//
|
||||
// The seen map is used to short circuit cycles through type parameters. If
|
||||
// nil, it will be allocated as necessary.
|
||||
func find(obj types.Object, T types.Type, path []byte, seen map[*types.TypeName]bool) []byte {
|
||||
//
|
||||
// The seenMethods map is used internally to short circuit cycles through
|
||||
// interface methods, such as occur in the following example:
|
||||
//
|
||||
// type I interface { f() interface{I} }
|
||||
//
|
||||
// See golang/go#68046 for details.
|
||||
func find(obj types.Object, T types.Type, path []byte) []byte {
|
||||
return (&finder{obj: obj}).find(T, path)
|
||||
}
|
||||
|
||||
// finder closes over search state for a call to find.
|
||||
type finder struct {
|
||||
obj types.Object // the sought object
|
||||
seenTParamNames map[*types.TypeName]bool // for cycle breaking through type parameters
|
||||
seenMethods map[*types.Func]bool // for cycle breaking through recursive interfaces
|
||||
}
|
||||
|
||||
func (f *finder) find(T types.Type, path []byte) []byte {
|
||||
switch T := T.(type) {
|
||||
case *types.Alias:
|
||||
return f.find(types.Unalias(T), path)
|
||||
case *types.Basic, *types.Named:
|
||||
// Named types belonging to pkg were handled already,
|
||||
// so T must belong to another package. No path.
|
||||
return nil
|
||||
case *types.Pointer:
|
||||
return find(obj, T.Elem(), append(path, opElem), seen)
|
||||
return f.find(T.Elem(), append(path, opElem))
|
||||
case *types.Slice:
|
||||
return find(obj, T.Elem(), append(path, opElem), seen)
|
||||
return f.find(T.Elem(), append(path, opElem))
|
||||
case *types.Array:
|
||||
return find(obj, T.Elem(), append(path, opElem), seen)
|
||||
return f.find(T.Elem(), append(path, opElem))
|
||||
case *types.Chan:
|
||||
return find(obj, T.Elem(), append(path, opElem), seen)
|
||||
return f.find(T.Elem(), append(path, opElem))
|
||||
case *types.Map:
|
||||
if r := find(obj, T.Key(), append(path, opKey), seen); r != nil {
|
||||
if r := f.find(T.Key(), append(path, opKey)); r != nil {
|
||||
return r
|
||||
}
|
||||
return find(obj, T.Elem(), append(path, opElem), seen)
|
||||
return f.find(T.Elem(), append(path, opElem))
|
||||
case *types.Signature:
|
||||
if r := findTypeParam(obj, T.TypeParams(), path, seen); r != nil {
|
||||
if r := f.findTypeParam(T.RecvTypeParams(), path, opRecvTypeParam); r != nil {
|
||||
return r
|
||||
}
|
||||
if r := find(obj, T.Params(), append(path, opParams), seen); r != nil {
|
||||
if r := f.findTypeParam(T.TypeParams(), path, opTypeParam); r != nil {
|
||||
return r
|
||||
}
|
||||
return find(obj, T.Results(), append(path, opResults), seen)
|
||||
if r := f.find(T.Params(), append(path, opParams)); r != nil {
|
||||
return r
|
||||
}
|
||||
return f.find(T.Results(), append(path, opResults))
|
||||
case *types.Struct:
|
||||
for i := 0; i < T.NumFields(); i++ {
|
||||
fld := T.Field(i)
|
||||
path2 := appendOpArg(path, opField, i)
|
||||
if fld == obj {
|
||||
if fld == f.obj {
|
||||
return path2 // found field var
|
||||
}
|
||||
if r := find(obj, fld.Type(), append(path2, opType), seen); r != nil {
|
||||
if r := f.find(fld.Type(), append(path2, opType)); r != nil {
|
||||
return r
|
||||
}
|
||||
}
|
||||
|
|
@ -485,10 +513,10 @@ func find(obj types.Object, T types.Type, path []byte, seen map[*types.TypeName]
|
|||
for i := 0; i < T.Len(); i++ {
|
||||
v := T.At(i)
|
||||
path2 := appendOpArg(path, opAt, i)
|
||||
if v == obj {
|
||||
if v == f.obj {
|
||||
return path2 // found param/result var
|
||||
}
|
||||
if r := find(obj, v.Type(), append(path2, opType), seen); r != nil {
|
||||
if r := f.find(v.Type(), append(path2, opType)); r != nil {
|
||||
return r
|
||||
}
|
||||
}
|
||||
|
|
@ -496,28 +524,35 @@ func find(obj types.Object, T types.Type, path []byte, seen map[*types.TypeName]
|
|||
case *types.Interface:
|
||||
for i := 0; i < T.NumMethods(); i++ {
|
||||
m := T.Method(i)
|
||||
if f.seenMethods[m] {
|
||||
return nil
|
||||
}
|
||||
path2 := appendOpArg(path, opMethod, i)
|
||||
if m == obj {
|
||||
if m == f.obj {
|
||||
return path2 // found interface method
|
||||
}
|
||||
if r := find(obj, m.Type(), append(path2, opType), seen); r != nil {
|
||||
if f.seenMethods == nil {
|
||||
f.seenMethods = make(map[*types.Func]bool)
|
||||
}
|
||||
f.seenMethods[m] = true
|
||||
if r := f.find(m.Type(), append(path2, opType)); r != nil {
|
||||
return r
|
||||
}
|
||||
}
|
||||
return nil
|
||||
case *types.TypeParam:
|
||||
name := T.Obj()
|
||||
if name == obj {
|
||||
return append(path, opObj)
|
||||
}
|
||||
if seen[name] {
|
||||
if f.seenTParamNames[name] {
|
||||
return nil
|
||||
}
|
||||
if seen == nil {
|
||||
seen = make(map[*types.TypeName]bool)
|
||||
if name == f.obj {
|
||||
return append(path, opObj)
|
||||
}
|
||||
seen[name] = true
|
||||
if r := find(obj, T.Constraint(), append(path, opConstraint), seen); r != nil {
|
||||
if f.seenTParamNames == nil {
|
||||
f.seenTParamNames = make(map[*types.TypeName]bool)
|
||||
}
|
||||
f.seenTParamNames[name] = true
|
||||
if r := f.find(T.Constraint(), append(path, opConstraint)); r != nil {
|
||||
return r
|
||||
}
|
||||
return nil
|
||||
|
|
@ -525,11 +560,15 @@ func find(obj types.Object, T types.Type, path []byte, seen map[*types.TypeName]
|
|||
panic(T)
|
||||
}
|
||||
|
||||
func findTypeParam(obj types.Object, list *types.TypeParamList, path []byte, seen map[*types.TypeName]bool) []byte {
|
||||
func findTypeParam(obj types.Object, list *types.TypeParamList, path []byte, op byte) []byte {
|
||||
return (&finder{obj: obj}).findTypeParam(list, path, op)
|
||||
}
|
||||
|
||||
func (f *finder) findTypeParam(list *types.TypeParamList, path []byte, op byte) []byte {
|
||||
for i := 0; i < list.Len(); i++ {
|
||||
tparam := list.At(i)
|
||||
path2 := appendOpArg(path, opTypeParam, i)
|
||||
if r := find(obj, tparam, path2, seen); r != nil {
|
||||
path2 := appendOpArg(path, op, i)
|
||||
if r := f.find(tparam, path2); r != nil {
|
||||
return r
|
||||
}
|
||||
}
|
||||
|
|
@ -580,10 +619,10 @@ func Object(pkg *types.Package, p Path) (types.Object, error) {
|
|||
code := suffix[0]
|
||||
suffix = suffix[1:]
|
||||
|
||||
// Codes [AFM] have an integer operand.
|
||||
// Codes [AFMTr] have an integer operand.
|
||||
var index int
|
||||
switch code {
|
||||
case opAt, opField, opMethod, opTypeParam:
|
||||
case opAt, opField, opMethod, opTypeParam, opRecvTypeParam:
|
||||
rest := strings.TrimLeft(suffix, "0123456789")
|
||||
numerals := suffix[:len(suffix)-len(rest)]
|
||||
suffix = rest
|
||||
|
|
@ -616,6 +655,7 @@ func Object(pkg *types.Package, p Path) (types.Object, error) {
|
|||
|
||||
// Inv: t != nil, obj == nil
|
||||
|
||||
t = types.Unalias(t)
|
||||
switch code {
|
||||
case opElem:
|
||||
hasElem, ok := t.(hasElem) // Pointer, Slice, Array, Chan, Map
|
||||
|
|
@ -652,6 +692,16 @@ func Object(pkg *types.Package, p Path) (types.Object, error) {
|
|||
}
|
||||
t = named.Underlying()
|
||||
|
||||
case opRhs:
|
||||
if alias, ok := t.(*types.Alias); ok {
|
||||
t = aliases.Rhs(alias)
|
||||
} else if false && aliases.Enabled() {
|
||||
// The Enabled check is too expensive, so for now we
|
||||
// simply assume that aliases are not enabled.
|
||||
// TODO(adonovan): replace with "if true {" when go1.24 is assured.
|
||||
return nil, fmt.Errorf("cannot apply %q to %s (got %T, want alias)", code, t, t)
|
||||
}
|
||||
|
||||
case opTypeParam:
|
||||
hasTypeParams, ok := t.(hasTypeParams) // Named, Signature
|
||||
if !ok {
|
||||
|
|
@ -663,6 +713,17 @@ func Object(pkg *types.Package, p Path) (types.Object, error) {
|
|||
}
|
||||
t = tparams.At(index)
|
||||
|
||||
case opRecvTypeParam:
|
||||
sig, ok := t.(*types.Signature) // Signature
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("cannot apply %q to %s (got %T, want signature)", code, t, t)
|
||||
}
|
||||
rtparams := sig.RecvTypeParams()
|
||||
if n := rtparams.Len(); index >= n {
|
||||
return nil, fmt.Errorf("tuple index %d out of range [0-%d)", index, n)
|
||||
}
|
||||
t = rtparams.At(index)
|
||||
|
||||
case opConstraint:
|
||||
tparam, ok := t.(*types.TypeParam)
|
||||
if !ok {
|
||||
|
|
@ -724,6 +785,10 @@ func Object(pkg *types.Package, p Path) (types.Object, error) {
|
|||
}
|
||||
}
|
||||
|
||||
if obj == nil {
|
||||
panic(p) // path does not end in an object-valued operator
|
||||
}
|
||||
|
||||
if obj.Pkg() != pkg {
|
||||
return nil, fmt.Errorf("path denotes %s, which belongs to a different package", obj)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,68 @@
|
|||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package typeutil
|
||||
|
||||
import (
|
||||
"go/ast"
|
||||
"go/types"
|
||||
|
||||
"golang.org/x/tools/internal/typeparams"
|
||||
)
|
||||
|
||||
// Callee returns the named target of a function call, if any:
|
||||
// a function, method, builtin, or variable.
|
||||
//
|
||||
// Functions and methods may potentially have type parameters.
|
||||
func Callee(info *types.Info, call *ast.CallExpr) types.Object {
|
||||
fun := ast.Unparen(call.Fun)
|
||||
|
||||
// Look through type instantiation if necessary.
|
||||
isInstance := false
|
||||
switch fun.(type) {
|
||||
case *ast.IndexExpr, *ast.IndexListExpr:
|
||||
// When extracting the callee from an *IndexExpr, we need to check that
|
||||
// it is a *types.Func and not a *types.Var.
|
||||
// Example: Don't match a slice m within the expression `m[0]()`.
|
||||
isInstance = true
|
||||
fun, _, _, _ = typeparams.UnpackIndexExpr(fun)
|
||||
}
|
||||
|
||||
var obj types.Object
|
||||
switch fun := fun.(type) {
|
||||
case *ast.Ident:
|
||||
obj = info.Uses[fun] // type, var, builtin, or declared func
|
||||
case *ast.SelectorExpr:
|
||||
if sel, ok := info.Selections[fun]; ok {
|
||||
obj = sel.Obj() // method or field
|
||||
} else {
|
||||
obj = info.Uses[fun.Sel] // qualified identifier?
|
||||
}
|
||||
}
|
||||
if _, ok := obj.(*types.TypeName); ok {
|
||||
return nil // T(x) is a conversion, not a call
|
||||
}
|
||||
// A Func is required to match instantiations.
|
||||
if _, ok := obj.(*types.Func); isInstance && !ok {
|
||||
return nil // Was not a Func.
|
||||
}
|
||||
return obj
|
||||
}
|
||||
|
||||
// StaticCallee returns the target (function or method) of a static function
|
||||
// call, if any. It returns nil for calls to builtins.
|
||||
//
|
||||
// Note: for calls of instantiated functions and methods, StaticCallee returns
|
||||
// the corresponding generic function or method on the generic type.
|
||||
func StaticCallee(info *types.Info, call *ast.CallExpr) *types.Func {
|
||||
if f, ok := Callee(info, call).(*types.Func); ok && !interfaceMethod(f) {
|
||||
return f
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func interfaceMethod(f *types.Func) bool {
|
||||
recv := f.Type().(*types.Signature).Recv()
|
||||
return recv != nil && types.IsInterface(recv.Type())
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
// Copyright 2014 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package typeutil
|
||||
|
||||
import "go/types"
|
||||
|
||||
// Dependencies returns all dependencies of the specified packages.
|
||||
//
|
||||
// Dependent packages appear in topological order: if package P imports
|
||||
// package Q, Q appears earlier than P in the result.
|
||||
// The algorithm follows import statements in the order they
|
||||
// appear in the source code, so the result is a total order.
|
||||
func Dependencies(pkgs ...*types.Package) []*types.Package {
|
||||
var result []*types.Package
|
||||
seen := make(map[*types.Package]bool)
|
||||
var visit func(pkgs []*types.Package)
|
||||
visit = func(pkgs []*types.Package) {
|
||||
for _, p := range pkgs {
|
||||
if !seen[p] {
|
||||
seen[p] = true
|
||||
visit(p.Imports())
|
||||
result = append(result, p)
|
||||
}
|
||||
}
|
||||
}
|
||||
visit(pkgs)
|
||||
return result
|
||||
}
|
||||
|
|
@ -0,0 +1,467 @@
|
|||
// Copyright 2014 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package typeutil defines various utilities for types, such as [Map],
|
||||
// a hash table that maps [types.Type] to any value.
|
||||
package typeutil
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"go/types"
|
||||
"hash/maphash"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/tools/internal/typeparams"
|
||||
)
|
||||
|
||||
// Map is a hash-table-based mapping from types (types.Type) to
|
||||
// arbitrary values. The concrete types that implement
|
||||
// the Type interface are pointers. Since they are not canonicalized,
|
||||
// == cannot be used to check for equivalence, and thus we cannot
|
||||
// simply use a Go map.
|
||||
//
|
||||
// Just as with map[K]V, a nil *Map is a valid empty map.
|
||||
//
|
||||
// Read-only map operations ([Map.At], [Map.Len], and so on) may
|
||||
// safely be called concurrently.
|
||||
//
|
||||
// TODO(adonovan): deprecate in favor of https://go.dev/issues/69420
|
||||
// and 69559, if the latter proposals for a generic hash-map type and
|
||||
// a types.Hash function are accepted.
|
||||
type Map struct {
|
||||
table map[uint32][]entry // maps hash to bucket; entry.key==nil means unused
|
||||
length int // number of map entries
|
||||
}
|
||||
|
||||
// entry is an entry (key/value association) in a hash bucket.
|
||||
type entry struct {
|
||||
key types.Type
|
||||
value any
|
||||
}
|
||||
|
||||
// SetHasher has no effect.
|
||||
//
|
||||
// It is a relic of an optimization that is no longer profitable. Do
|
||||
// not use [Hasher], [MakeHasher], or [SetHasher] in new code.
|
||||
func (m *Map) SetHasher(Hasher) {}
|
||||
|
||||
// Delete removes the entry with the given key, if any.
|
||||
// It returns true if the entry was found.
|
||||
func (m *Map) Delete(key types.Type) bool {
|
||||
if m != nil && m.table != nil {
|
||||
hash := hash(key)
|
||||
bucket := m.table[hash]
|
||||
for i, e := range bucket {
|
||||
if e.key != nil && types.Identical(key, e.key) {
|
||||
// We can't compact the bucket as it
|
||||
// would disturb iterators.
|
||||
bucket[i] = entry{}
|
||||
m.length--
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// At returns the map entry for the given key.
|
||||
// The result is nil if the entry is not present.
|
||||
func (m *Map) At(key types.Type) any {
|
||||
if m != nil && m.table != nil {
|
||||
for _, e := range m.table[hash(key)] {
|
||||
if e.key != nil && types.Identical(key, e.key) {
|
||||
return e.value
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Set sets the map entry for key to val,
|
||||
// and returns the previous entry, if any.
|
||||
func (m *Map) Set(key types.Type, value any) (prev any) {
|
||||
if m.table != nil {
|
||||
hash := hash(key)
|
||||
bucket := m.table[hash]
|
||||
var hole *entry
|
||||
for i, e := range bucket {
|
||||
if e.key == nil {
|
||||
hole = &bucket[i]
|
||||
} else if types.Identical(key, e.key) {
|
||||
prev = e.value
|
||||
bucket[i].value = value
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if hole != nil {
|
||||
*hole = entry{key, value} // overwrite deleted entry
|
||||
} else {
|
||||
m.table[hash] = append(bucket, entry{key, value})
|
||||
}
|
||||
} else {
|
||||
hash := hash(key)
|
||||
m.table = map[uint32][]entry{hash: {entry{key, value}}}
|
||||
}
|
||||
|
||||
m.length++
|
||||
return
|
||||
}
|
||||
|
||||
// Len returns the number of map entries.
|
||||
func (m *Map) Len() int {
|
||||
if m != nil {
|
||||
return m.length
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// Iterate calls function f on each entry in the map in unspecified order.
|
||||
//
|
||||
// If f should mutate the map, Iterate provides the same guarantees as
|
||||
// Go maps: if f deletes a map entry that Iterate has not yet reached,
|
||||
// f will not be invoked for it, but if f inserts a map entry that
|
||||
// Iterate has not yet reached, whether or not f will be invoked for
|
||||
// it is unspecified.
|
||||
func (m *Map) Iterate(f func(key types.Type, value any)) {
|
||||
if m != nil {
|
||||
for _, bucket := range m.table {
|
||||
for _, e := range bucket {
|
||||
if e.key != nil {
|
||||
f(e.key, e.value)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Keys returns a new slice containing the set of map keys.
|
||||
// The order is unspecified.
|
||||
func (m *Map) Keys() []types.Type {
|
||||
keys := make([]types.Type, 0, m.Len())
|
||||
m.Iterate(func(key types.Type, _ any) {
|
||||
keys = append(keys, key)
|
||||
})
|
||||
return keys
|
||||
}
|
||||
|
||||
func (m *Map) toString(values bool) string {
|
||||
if m == nil {
|
||||
return "{}"
|
||||
}
|
||||
var buf bytes.Buffer
|
||||
fmt.Fprint(&buf, "{")
|
||||
sep := ""
|
||||
m.Iterate(func(key types.Type, value any) {
|
||||
fmt.Fprint(&buf, sep)
|
||||
sep = ", "
|
||||
fmt.Fprint(&buf, key)
|
||||
if values {
|
||||
fmt.Fprintf(&buf, ": %q", value)
|
||||
}
|
||||
})
|
||||
fmt.Fprint(&buf, "}")
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
// String returns a string representation of the map's entries.
|
||||
// Values are printed using fmt.Sprintf("%v", v).
|
||||
// Order is unspecified.
|
||||
func (m *Map) String() string {
|
||||
return m.toString(true)
|
||||
}
|
||||
|
||||
// KeysString returns a string representation of the map's key set.
|
||||
// Order is unspecified.
|
||||
func (m *Map) KeysString() string {
|
||||
return m.toString(false)
|
||||
}
|
||||
|
||||
// -- Hasher --
|
||||
|
||||
// hash returns the hash of type t.
|
||||
// TODO(adonovan): replace by types.Hash when Go proposal #69420 is accepted.
|
||||
func hash(t types.Type) uint32 {
|
||||
return theHasher.Hash(t)
|
||||
}
|
||||
|
||||
// A Hasher provides a [Hasher.Hash] method to map a type to its hash value.
|
||||
// Hashers are stateless, and all are equivalent.
|
||||
type Hasher struct{}
|
||||
|
||||
var theHasher Hasher
|
||||
|
||||
// MakeHasher returns Hasher{}.
|
||||
// Hashers are stateless; all are equivalent.
|
||||
func MakeHasher() Hasher { return theHasher }
|
||||
|
||||
// Hash computes a hash value for the given type t such that
|
||||
// Identical(t, t') => Hash(t) == Hash(t').
|
||||
func (h Hasher) Hash(t types.Type) uint32 {
|
||||
return hasher{inGenericSig: false}.hash(t)
|
||||
}
|
||||
|
||||
// hasher holds the state of a single Hash traversal: whether we are
|
||||
// inside the signature of a generic function; this is used to
|
||||
// optimize [hasher.hashTypeParam].
|
||||
type hasher struct{ inGenericSig bool }
|
||||
|
||||
// hashString computes the Fowler–Noll–Vo hash of s.
|
||||
func hashString(s string) uint32 {
|
||||
var h uint32
|
||||
for i := 0; i < len(s); i++ {
|
||||
h ^= uint32(s[i])
|
||||
h *= 16777619
|
||||
}
|
||||
return h
|
||||
}
|
||||
|
||||
// hash computes the hash of t.
|
||||
func (h hasher) hash(t types.Type) uint32 {
|
||||
// See Identical for rationale.
|
||||
switch t := t.(type) {
|
||||
case *types.Basic:
|
||||
return uint32(t.Kind())
|
||||
|
||||
case *types.Alias:
|
||||
return h.hash(types.Unalias(t))
|
||||
|
||||
case *types.Array:
|
||||
return 9043 + 2*uint32(t.Len()) + 3*h.hash(t.Elem())
|
||||
|
||||
case *types.Slice:
|
||||
return 9049 + 2*h.hash(t.Elem())
|
||||
|
||||
case *types.Struct:
|
||||
var hash uint32 = 9059
|
||||
for i, n := 0, t.NumFields(); i < n; i++ {
|
||||
f := t.Field(i)
|
||||
if f.Anonymous() {
|
||||
hash += 8861
|
||||
}
|
||||
hash += hashString(t.Tag(i))
|
||||
hash += hashString(f.Name()) // (ignore f.Pkg)
|
||||
hash += h.hash(f.Type())
|
||||
}
|
||||
return hash
|
||||
|
||||
case *types.Pointer:
|
||||
return 9067 + 2*h.hash(t.Elem())
|
||||
|
||||
case *types.Signature:
|
||||
var hash uint32 = 9091
|
||||
if t.Variadic() {
|
||||
hash *= 8863
|
||||
}
|
||||
|
||||
tparams := t.TypeParams()
|
||||
for i := range tparams.Len() {
|
||||
h.inGenericSig = true
|
||||
tparam := tparams.At(i)
|
||||
hash += 7 * h.hash(tparam.Constraint())
|
||||
}
|
||||
|
||||
return hash + 3*h.hashTuple(t.Params()) + 5*h.hashTuple(t.Results())
|
||||
|
||||
case *types.Union:
|
||||
return h.hashUnion(t)
|
||||
|
||||
case *types.Interface:
|
||||
// Interfaces are identical if they have the same set of methods, with
|
||||
// identical names and types, and they have the same set of type
|
||||
// restrictions. See go/types.identical for more details.
|
||||
var hash uint32 = 9103
|
||||
|
||||
// Hash methods.
|
||||
for i, n := 0, t.NumMethods(); i < n; i++ {
|
||||
// Method order is not significant.
|
||||
// Ignore m.Pkg().
|
||||
m := t.Method(i)
|
||||
// Use shallow hash on method signature to
|
||||
// avoid anonymous interface cycles.
|
||||
hash += 3*hashString(m.Name()) + 5*h.shallowHash(m.Type())
|
||||
}
|
||||
|
||||
// Hash type restrictions.
|
||||
terms, err := typeparams.InterfaceTermSet(t)
|
||||
// if err != nil t has invalid type restrictions.
|
||||
if err == nil {
|
||||
hash += h.hashTermSet(terms)
|
||||
}
|
||||
|
||||
return hash
|
||||
|
||||
case *types.Map:
|
||||
return 9109 + 2*h.hash(t.Key()) + 3*h.hash(t.Elem())
|
||||
|
||||
case *types.Chan:
|
||||
return 9127 + 2*uint32(t.Dir()) + 3*h.hash(t.Elem())
|
||||
|
||||
case *types.Named:
|
||||
hash := h.hashTypeName(t.Obj())
|
||||
targs := t.TypeArgs()
|
||||
for i := 0; i < targs.Len(); i++ {
|
||||
targ := targs.At(i)
|
||||
hash += 2 * h.hash(targ)
|
||||
}
|
||||
return hash
|
||||
|
||||
case *types.TypeParam:
|
||||
return h.hashTypeParam(t)
|
||||
|
||||
case *types.Tuple:
|
||||
return h.hashTuple(t)
|
||||
}
|
||||
|
||||
panic(fmt.Sprintf("%T: %v", t, t))
|
||||
}
|
||||
|
||||
func (h hasher) hashTuple(tuple *types.Tuple) uint32 {
|
||||
// See go/types.identicalTypes for rationale.
|
||||
n := tuple.Len()
|
||||
hash := 9137 + 2*uint32(n)
|
||||
for i := range n {
|
||||
hash += 3 * h.hash(tuple.At(i).Type())
|
||||
}
|
||||
return hash
|
||||
}
|
||||
|
||||
func (h hasher) hashUnion(t *types.Union) uint32 {
|
||||
// Hash type restrictions.
|
||||
terms, err := typeparams.UnionTermSet(t)
|
||||
// if err != nil t has invalid type restrictions. Fall back on a non-zero
|
||||
// hash.
|
||||
if err != nil {
|
||||
return 9151
|
||||
}
|
||||
return h.hashTermSet(terms)
|
||||
}
|
||||
|
||||
func (h hasher) hashTermSet(terms []*types.Term) uint32 {
|
||||
hash := 9157 + 2*uint32(len(terms))
|
||||
for _, term := range terms {
|
||||
// term order is not significant.
|
||||
termHash := h.hash(term.Type())
|
||||
if term.Tilde() {
|
||||
termHash *= 9161
|
||||
}
|
||||
hash += 3 * termHash
|
||||
}
|
||||
return hash
|
||||
}
|
||||
|
||||
// hashTypeParam returns the hash of a type parameter.
|
||||
func (h hasher) hashTypeParam(t *types.TypeParam) uint32 {
|
||||
// Within the signature of a generic function, TypeParams are
|
||||
// identical if they have the same index and constraint, so we
|
||||
// hash them based on index.
|
||||
//
|
||||
// When we are outside a generic function, free TypeParams are
|
||||
// identical iff they are the same object, so we can use a
|
||||
// more discriminating hash consistent with object identity.
|
||||
// This optimization saves [Map] about 4% when hashing all the
|
||||
// types.Info.Types in the forward closure of net/http.
|
||||
if !h.inGenericSig {
|
||||
// Optimization: outside a generic function signature,
|
||||
// use a more discrimating hash consistent with object identity.
|
||||
return h.hashTypeName(t.Obj())
|
||||
}
|
||||
return 9173 + 3*uint32(t.Index())
|
||||
}
|
||||
|
||||
var theSeed = maphash.MakeSeed()
|
||||
|
||||
// hashTypeName hashes the pointer of tname.
|
||||
func (hasher) hashTypeName(tname *types.TypeName) uint32 {
|
||||
// Since types.Identical uses == to compare TypeNames,
|
||||
// the Hash function uses maphash.Comparable.
|
||||
// TODO(adonovan): or will, when it becomes available in go1.24.
|
||||
// In the meantime we use the pointer's numeric value.
|
||||
//
|
||||
// hash := maphash.Comparable(theSeed, tname)
|
||||
//
|
||||
// (Another approach would be to hash the name and package
|
||||
// path, and whether or not it is a package-level typename. It
|
||||
// is rare for a package to define multiple local types with
|
||||
// the same name.)
|
||||
hash := uintptr(unsafe.Pointer(tname))
|
||||
return uint32(hash ^ (hash >> 32))
|
||||
}
|
||||
|
||||
// shallowHash computes a hash of t without looking at any of its
|
||||
// element Types, to avoid potential anonymous cycles in the types of
|
||||
// interface methods.
|
||||
//
|
||||
// When an unnamed non-empty interface type appears anywhere among the
|
||||
// arguments or results of an interface method, there is a potential
|
||||
// for endless recursion. Consider:
|
||||
//
|
||||
// type X interface { m() []*interface { X } }
|
||||
//
|
||||
// The problem is that the Methods of the interface in m's result type
|
||||
// include m itself; there is no mention of the named type X that
|
||||
// might help us break the cycle.
|
||||
// (See comment in go/types.identical, case *Interface, for more.)
|
||||
func (h hasher) shallowHash(t types.Type) uint32 {
|
||||
// t is the type of an interface method (Signature),
|
||||
// its params or results (Tuples), or their immediate
|
||||
// elements (mostly Slice, Pointer, Basic, Named),
|
||||
// so there's no need to optimize anything else.
|
||||
switch t := t.(type) {
|
||||
case *types.Alias:
|
||||
return h.shallowHash(types.Unalias(t))
|
||||
|
||||
case *types.Signature:
|
||||
var hash uint32 = 604171
|
||||
if t.Variadic() {
|
||||
hash *= 971767
|
||||
}
|
||||
// The Signature/Tuple recursion is always finite
|
||||
// and invariably shallow.
|
||||
return hash + 1062599*h.shallowHash(t.Params()) + 1282529*h.shallowHash(t.Results())
|
||||
|
||||
case *types.Tuple:
|
||||
n := t.Len()
|
||||
hash := 9137 + 2*uint32(n)
|
||||
for i := range n {
|
||||
hash += 53471161 * h.shallowHash(t.At(i).Type())
|
||||
}
|
||||
return hash
|
||||
|
||||
case *types.Basic:
|
||||
return 45212177 * uint32(t.Kind())
|
||||
|
||||
case *types.Array:
|
||||
return 1524181 + 2*uint32(t.Len())
|
||||
|
||||
case *types.Slice:
|
||||
return 2690201
|
||||
|
||||
case *types.Struct:
|
||||
return 3326489
|
||||
|
||||
case *types.Pointer:
|
||||
return 4393139
|
||||
|
||||
case *types.Union:
|
||||
return 562448657
|
||||
|
||||
case *types.Interface:
|
||||
return 2124679 // no recursion here
|
||||
|
||||
case *types.Map:
|
||||
return 9109
|
||||
|
||||
case *types.Chan:
|
||||
return 9127
|
||||
|
||||
case *types.Named:
|
||||
return h.hashTypeName(t.Obj())
|
||||
|
||||
case *types.TypeParam:
|
||||
return h.hashTypeParam(t)
|
||||
}
|
||||
panic(fmt.Sprintf("shallowHash: %T: %v", t, t))
|
||||
}
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
// Copyright 2014 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// This file implements a cache of method sets.
|
||||
|
||||
package typeutil
|
||||
|
||||
import (
|
||||
"go/types"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// A MethodSetCache records the method set of each type T for which
|
||||
// MethodSet(T) is called so that repeat queries are fast.
|
||||
// The zero value is a ready-to-use cache instance.
|
||||
type MethodSetCache struct {
|
||||
mu sync.Mutex
|
||||
named map[*types.Named]struct{ value, pointer *types.MethodSet } // method sets for named N and *N
|
||||
others map[types.Type]*types.MethodSet // all other types
|
||||
}
|
||||
|
||||
// MethodSet returns the method set of type T. It is thread-safe.
|
||||
//
|
||||
// If cache is nil, this function is equivalent to types.NewMethodSet(T).
|
||||
// Utility functions can thus expose an optional *MethodSetCache
|
||||
// parameter to clients that care about performance.
|
||||
func (cache *MethodSetCache) MethodSet(T types.Type) *types.MethodSet {
|
||||
if cache == nil {
|
||||
return types.NewMethodSet(T)
|
||||
}
|
||||
cache.mu.Lock()
|
||||
defer cache.mu.Unlock()
|
||||
|
||||
switch T := types.Unalias(T).(type) {
|
||||
case *types.Named:
|
||||
return cache.lookupNamed(T).value
|
||||
|
||||
case *types.Pointer:
|
||||
if N, ok := types.Unalias(T.Elem()).(*types.Named); ok {
|
||||
return cache.lookupNamed(N).pointer
|
||||
}
|
||||
}
|
||||
|
||||
// all other types
|
||||
// (The map uses pointer equivalence, not type identity.)
|
||||
mset := cache.others[T]
|
||||
if mset == nil {
|
||||
mset = types.NewMethodSet(T)
|
||||
if cache.others == nil {
|
||||
cache.others = make(map[types.Type]*types.MethodSet)
|
||||
}
|
||||
cache.others[T] = mset
|
||||
}
|
||||
return mset
|
||||
}
|
||||
|
||||
func (cache *MethodSetCache) lookupNamed(named *types.Named) struct{ value, pointer *types.MethodSet } {
|
||||
if cache.named == nil {
|
||||
cache.named = make(map[*types.Named]struct{ value, pointer *types.MethodSet })
|
||||
}
|
||||
// Avoid recomputing mset(*T) for each distinct Pointer
|
||||
// instance whose underlying type is a named type.
|
||||
msets, ok := cache.named[named]
|
||||
if !ok {
|
||||
msets.value = types.NewMethodSet(named)
|
||||
msets.pointer = types.NewMethodSet(types.NewPointer(named))
|
||||
cache.named[named] = msets
|
||||
}
|
||||
return msets
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue