mirror of https://github.com/grafana/grafana
Upgrade grafana-plugin-model (#19438)
* use grafana-plugin-model dependency that uses go modules * use grafana-plugin-model with updated hashicorp/go-plugin * use grafana-plugin-model with re-compiled protos * test using protoc-gen-go v1.2.0 tag * use grafana-plugin-model with re-compiled protos * chore: fix deprecation warning for lint * use latest grafana-plugin-model Fixes #19454pull/19488/head
parent
44de6812be
commit
93919427f8
@ -0,0 +1,63 @@ |
||||
// Go support for Protocol Buffers - Google's data interchange format
|
||||
//
|
||||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// https://github.com/golang/protobuf
|
||||
//
|
||||
// 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 Inc. 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.
|
||||
|
||||
package proto |
||||
|
||||
import "errors" |
||||
|
||||
// Deprecated: do not use.
|
||||
type Stats struct{ Emalloc, Dmalloc, Encode, Decode, Chit, Cmiss, Size uint64 } |
||||
|
||||
// Deprecated: do not use.
|
||||
func GetStats() Stats { return Stats{} } |
||||
|
||||
// Deprecated: do not use.
|
||||
func MarshalMessageSet(interface{}) ([]byte, error) { |
||||
return nil, errors.New("proto: not implemented") |
||||
} |
||||
|
||||
// Deprecated: do not use.
|
||||
func UnmarshalMessageSet([]byte, interface{}) error { |
||||
return errors.New("proto: not implemented") |
||||
} |
||||
|
||||
// Deprecated: do not use.
|
||||
func MarshalMessageSetJSON(interface{}) ([]byte, error) { |
||||
return nil, errors.New("proto: not implemented") |
||||
} |
||||
|
||||
// Deprecated: do not use.
|
||||
func UnmarshalMessageSetJSON([]byte, interface{}) error { |
||||
return errors.New("proto: not implemented") |
||||
} |
||||
|
||||
// Deprecated: do not use.
|
||||
func RegisterMessageSetType(Message, int32, string) {} |
||||
109
vendor/github.com/grafana/grafana-plugin-model/go/datasource/datasource.pb.go
generated
vendored
109
vendor/github.com/grafana/grafana-plugin-model/go/datasource/datasource.pb.go
generated
vendored
@ -1 +1,2 @@ |
||||
.DS_Store |
||||
.idea |
||||
|
||||
@ -0,0 +1 @@ |
||||
module github.com/hashicorp/yamux |
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,11 @@ |
||||
#!/usr/bin/make -f
|
||||
|
||||
test: |
||||
go test -timeout=1s -short ./...
|
||||
|
||||
compile: |
||||
go build ./...
|
||||
|
||||
build: test compile |
||||
|
||||
.PHONY: test compile build |
||||
@ -0,0 +1,3 @@ |
||||
module github.com/smartystreets/assertions |
||||
|
||||
go 1.12 |
||||
@ -0,0 +1,309 @@ |
||||
package assert |
||||
|
||||
import ( |
||||
"fmt" |
||||
"reflect" |
||||
) |
||||
|
||||
func compare(obj1, obj2 interface{}, kind reflect.Kind) (int, bool) { |
||||
switch kind { |
||||
case reflect.Int: |
||||
{ |
||||
intobj1 := obj1.(int) |
||||
intobj2 := obj2.(int) |
||||
if intobj1 > intobj2 { |
||||
return -1, true |
||||
} |
||||
if intobj1 == intobj2 { |
||||
return 0, true |
||||
} |
||||
if intobj1 < intobj2 { |
||||
return 1, true |
||||
} |
||||
} |
||||
case reflect.Int8: |
||||
{ |
||||
int8obj1 := obj1.(int8) |
||||
int8obj2 := obj2.(int8) |
||||
if int8obj1 > int8obj2 { |
||||
return -1, true |
||||
} |
||||
if int8obj1 == int8obj2 { |
||||
return 0, true |
||||
} |
||||
if int8obj1 < int8obj2 { |
||||
return 1, true |
||||
} |
||||
} |
||||
case reflect.Int16: |
||||
{ |
||||
int16obj1 := obj1.(int16) |
||||
int16obj2 := obj2.(int16) |
||||
if int16obj1 > int16obj2 { |
||||
return -1, true |
||||
} |
||||
if int16obj1 == int16obj2 { |
||||
return 0, true |
||||
} |
||||
if int16obj1 < int16obj2 { |
||||
return 1, true |
||||
} |
||||
} |
||||
case reflect.Int32: |
||||
{ |
||||
int32obj1 := obj1.(int32) |
||||
int32obj2 := obj2.(int32) |
||||
if int32obj1 > int32obj2 { |
||||
return -1, true |
||||
} |
||||
if int32obj1 == int32obj2 { |
||||
return 0, true |
||||
} |
||||
if int32obj1 < int32obj2 { |
||||
return 1, true |
||||
} |
||||
} |
||||
case reflect.Int64: |
||||
{ |
||||
int64obj1 := obj1.(int64) |
||||
int64obj2 := obj2.(int64) |
||||
if int64obj1 > int64obj2 { |
||||
return -1, true |
||||
} |
||||
if int64obj1 == int64obj2 { |
||||
return 0, true |
||||
} |
||||
if int64obj1 < int64obj2 { |
||||
return 1, true |
||||
} |
||||
} |
||||
case reflect.Uint: |
||||
{ |
||||
uintobj1 := obj1.(uint) |
||||
uintobj2 := obj2.(uint) |
||||
if uintobj1 > uintobj2 { |
||||
return -1, true |
||||
} |
||||
if uintobj1 == uintobj2 { |
||||
return 0, true |
||||
} |
||||
if uintobj1 < uintobj2 { |
||||
return 1, true |
||||
} |
||||
} |
||||
case reflect.Uint8: |
||||
{ |
||||
uint8obj1 := obj1.(uint8) |
||||
uint8obj2 := obj2.(uint8) |
||||
if uint8obj1 > uint8obj2 { |
||||
return -1, true |
||||
} |
||||
if uint8obj1 == uint8obj2 { |
||||
return 0, true |
||||
} |
||||
if uint8obj1 < uint8obj2 { |
||||
return 1, true |
||||
} |
||||
} |
||||
case reflect.Uint16: |
||||
{ |
||||
uint16obj1 := obj1.(uint16) |
||||
uint16obj2 := obj2.(uint16) |
||||
if uint16obj1 > uint16obj2 { |
||||
return -1, true |
||||
} |
||||
if uint16obj1 == uint16obj2 { |
||||
return 0, true |
||||
} |
||||
if uint16obj1 < uint16obj2 { |
||||
return 1, true |
||||
} |
||||
} |
||||
case reflect.Uint32: |
||||
{ |
||||
uint32obj1 := obj1.(uint32) |
||||
uint32obj2 := obj2.(uint32) |
||||
if uint32obj1 > uint32obj2 { |
||||
return -1, true |
||||
} |
||||
if uint32obj1 == uint32obj2 { |
||||
return 0, true |
||||
} |
||||
if uint32obj1 < uint32obj2 { |
||||
return 1, true |
||||
} |
||||
} |
||||
case reflect.Uint64: |
||||
{ |
||||
uint64obj1 := obj1.(uint64) |
||||
uint64obj2 := obj2.(uint64) |
||||
if uint64obj1 > uint64obj2 { |
||||
return -1, true |
||||
} |
||||
if uint64obj1 == uint64obj2 { |
||||
return 0, true |
||||
} |
||||
if uint64obj1 < uint64obj2 { |
||||
return 1, true |
||||
} |
||||
} |
||||
case reflect.Float32: |
||||
{ |
||||
float32obj1 := obj1.(float32) |
||||
float32obj2 := obj2.(float32) |
||||
if float32obj1 > float32obj2 { |
||||
return -1, true |
||||
} |
||||
if float32obj1 == float32obj2 { |
||||
return 0, true |
||||
} |
||||
if float32obj1 < float32obj2 { |
||||
return 1, true |
||||
} |
||||
} |
||||
case reflect.Float64: |
||||
{ |
||||
float64obj1 := obj1.(float64) |
||||
float64obj2 := obj2.(float64) |
||||
if float64obj1 > float64obj2 { |
||||
return -1, true |
||||
} |
||||
if float64obj1 == float64obj2 { |
||||
return 0, true |
||||
} |
||||
if float64obj1 < float64obj2 { |
||||
return 1, true |
||||
} |
||||
} |
||||
case reflect.String: |
||||
{ |
||||
stringobj1 := obj1.(string) |
||||
stringobj2 := obj2.(string) |
||||
if stringobj1 > stringobj2 { |
||||
return -1, true |
||||
} |
||||
if stringobj1 == stringobj2 { |
||||
return 0, true |
||||
} |
||||
if stringobj1 < stringobj2 { |
||||
return 1, true |
||||
} |
||||
} |
||||
} |
||||
|
||||
return 0, false |
||||
} |
||||
|
||||
// Greater asserts that the first element is greater than the second
|
||||
//
|
||||
// assert.Greater(t, 2, 1)
|
||||
// assert.Greater(t, float64(2), float64(1))
|
||||
// assert.Greater(t, "b", "a")
|
||||
func Greater(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) bool { |
||||
if h, ok := t.(tHelper); ok { |
||||
h.Helper() |
||||
} |
||||
|
||||
e1Kind := reflect.ValueOf(e1).Kind() |
||||
e2Kind := reflect.ValueOf(e2).Kind() |
||||
if e1Kind != e2Kind { |
||||
return Fail(t, "Elements should be the same type", msgAndArgs...) |
||||
} |
||||
|
||||
res, isComparable := compare(e1, e2, e1Kind) |
||||
if !isComparable { |
||||
return Fail(t, fmt.Sprintf("Can not compare type \"%s\"", reflect.TypeOf(e1)), msgAndArgs...) |
||||
} |
||||
|
||||
if res != -1 { |
||||
return Fail(t, fmt.Sprintf("\"%v\" is not greater than \"%v\"", e1, e2), msgAndArgs...) |
||||
} |
||||
|
||||
return true |
||||
} |
||||
|
||||
// GreaterOrEqual asserts that the first element is greater than or equal to the second
|
||||
//
|
||||
// assert.GreaterOrEqual(t, 2, 1)
|
||||
// assert.GreaterOrEqual(t, 2, 2)
|
||||
// assert.GreaterOrEqual(t, "b", "a")
|
||||
// assert.GreaterOrEqual(t, "b", "b")
|
||||
func GreaterOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) bool { |
||||
if h, ok := t.(tHelper); ok { |
||||
h.Helper() |
||||
} |
||||
|
||||
e1Kind := reflect.ValueOf(e1).Kind() |
||||
e2Kind := reflect.ValueOf(e2).Kind() |
||||
if e1Kind != e2Kind { |
||||
return Fail(t, "Elements should be the same type", msgAndArgs...) |
||||
} |
||||
|
||||
res, isComparable := compare(e1, e2, e1Kind) |
||||
if !isComparable { |
||||
return Fail(t, fmt.Sprintf("Can not compare type \"%s\"", reflect.TypeOf(e1)), msgAndArgs...) |
||||
} |
||||
|
||||
if res != -1 && res != 0 { |
||||
return Fail(t, fmt.Sprintf("\"%v\" is not greater than or equal to \"%v\"", e1, e2), msgAndArgs...) |
||||
} |
||||
|
||||
return true |
||||
} |
||||
|
||||
// Less asserts that the first element is less than the second
|
||||
//
|
||||
// assert.Less(t, 1, 2)
|
||||
// assert.Less(t, float64(1), float64(2))
|
||||
// assert.Less(t, "a", "b")
|
||||
func Less(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) bool { |
||||
if h, ok := t.(tHelper); ok { |
||||
h.Helper() |
||||
} |
||||
|
||||
e1Kind := reflect.ValueOf(e1).Kind() |
||||
e2Kind := reflect.ValueOf(e2).Kind() |
||||
if e1Kind != e2Kind { |
||||
return Fail(t, "Elements should be the same type", msgAndArgs...) |
||||
} |
||||
|
||||
res, isComparable := compare(e1, e2, e1Kind) |
||||
if !isComparable { |
||||
return Fail(t, fmt.Sprintf("Can not compare type \"%s\"", reflect.TypeOf(e1)), msgAndArgs...) |
||||
} |
||||
|
||||
if res != 1 { |
||||
return Fail(t, fmt.Sprintf("\"%v\" is not less than \"%v\"", e1, e2), msgAndArgs...) |
||||
} |
||||
|
||||
return true |
||||
} |
||||
|
||||
// LessOrEqual asserts that the first element is less than or equal to the second
|
||||
//
|
||||
// assert.LessOrEqual(t, 1, 2)
|
||||
// assert.LessOrEqual(t, 2, 2)
|
||||
// assert.LessOrEqual(t, "a", "b")
|
||||
// assert.LessOrEqual(t, "b", "b")
|
||||
func LessOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) bool { |
||||
if h, ok := t.(tHelper); ok { |
||||
h.Helper() |
||||
} |
||||
|
||||
e1Kind := reflect.ValueOf(e1).Kind() |
||||
e2Kind := reflect.ValueOf(e2).Kind() |
||||
if e1Kind != e2Kind { |
||||
return Fail(t, "Elements should be the same type", msgAndArgs...) |
||||
} |
||||
|
||||
res, isComparable := compare(e1, e2, e1Kind) |
||||
if !isComparable { |
||||
return Fail(t, fmt.Sprintf("Can not compare type \"%s\"", reflect.TypeOf(e1)), msgAndArgs...) |
||||
} |
||||
|
||||
if res != 1 && res != 0 { |
||||
return Fail(t, fmt.Sprintf("\"%v\" is not less than or equal to \"%v\"", e1, e2), msgAndArgs...) |
||||
} |
||||
|
||||
return true |
||||
} |
||||
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@ |
||||
{{.Comment}} |
||||
func {{.DocInfo.Name}}(t TestingT, {{.Params}}) { |
||||
if assert.{{.DocInfo.Name}}(t, {{.ForwardedParams}}) { return } |
||||
if h, ok := t.(tHelper); ok { h.Helper() } |
||||
if assert.{{.DocInfo.Name}}(t, {{.ForwardedParams}}) { return } |
||||
t.FailNow() |
||||
} |
||||
|
||||
@ -1 +0,0 @@ |
||||
TestSaveFile |
||||
@ -1 +0,0 @@ |
||||
TestSaveFileS |
||||
@ -1 +0,0 @@ |
||||
TestSaveFile |
||||
@ -1 +0,0 @@ |
||||
TestSaveFileS |
||||
@ -1 +0,0 @@ |
||||
TestSaveFile |
||||
@ -1 +0,0 @@ |
||||
TestSaveFileS |
||||
@ -0,0 +1,73 @@ |
||||
// Copyright 2019 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build go1.13
|
||||
|
||||
// Package ed25519 implements the Ed25519 signature algorithm. See
|
||||
// https://ed25519.cr.yp.to/.
|
||||
//
|
||||
// These functions are also compatible with the “Ed25519” function defined in
|
||||
// RFC 8032. However, unlike RFC 8032's formulation, this package's private key
|
||||
// representation includes a public key suffix to make multiple signing
|
||||
// operations with the same key more efficient. This package refers to the RFC
|
||||
// 8032 private key as the “seed”.
|
||||
//
|
||||
// Beginning with Go 1.13, the functionality of this package was moved to the
|
||||
// standard library as crypto/ed25519. This package only acts as a compatibility
|
||||
// wrapper.
|
||||
package ed25519 |
||||
|
||||
import ( |
||||
"crypto/ed25519" |
||||
"io" |
||||
) |
||||
|
||||
const ( |
||||
// PublicKeySize is the size, in bytes, of public keys as used in this package.
|
||||
PublicKeySize = 32 |
||||
// PrivateKeySize is the size, in bytes, of private keys as used in this package.
|
||||
PrivateKeySize = 64 |
||||
// SignatureSize is the size, in bytes, of signatures generated and verified by this package.
|
||||
SignatureSize = 64 |
||||
// SeedSize is the size, in bytes, of private key seeds. These are the private key representations used by RFC 8032.
|
||||
SeedSize = 32 |
||||
) |
||||
|
||||
// PublicKey is the type of Ed25519 public keys.
|
||||
//
|
||||
// This type is an alias for crypto/ed25519's PublicKey type.
|
||||
// See the crypto/ed25519 package for the methods on this type.
|
||||
type PublicKey = ed25519.PublicKey |
||||
|
||||
// PrivateKey is the type of Ed25519 private keys. It implements crypto.Signer.
|
||||
//
|
||||
// This type is an alias for crypto/ed25519's PrivateKey type.
|
||||
// See the crypto/ed25519 package for the methods on this type.
|
||||
type PrivateKey = ed25519.PrivateKey |
||||
|
||||
// GenerateKey generates a public/private key pair using entropy from rand.
|
||||
// If rand is nil, crypto/rand.Reader will be used.
|
||||
func GenerateKey(rand io.Reader) (PublicKey, PrivateKey, error) { |
||||
return ed25519.GenerateKey(rand) |
||||
} |
||||
|
||||
// NewKeyFromSeed calculates a private key from a seed. It will panic if
|
||||
// len(seed) is not SeedSize. This function is provided for interoperability
|
||||
// with RFC 8032. RFC 8032's private keys correspond to seeds in this
|
||||
// package.
|
||||
func NewKeyFromSeed(seed []byte) PrivateKey { |
||||
return ed25519.NewKeyFromSeed(seed) |
||||
} |
||||
|
||||
// Sign signs the message with privateKey and returns a signature. It will
|
||||
// panic if len(privateKey) is not PrivateKeySize.
|
||||
func Sign(privateKey PrivateKey, message []byte) []byte { |
||||
return ed25519.Sign(privateKey, message) |
||||
} |
||||
|
||||
// Verify reports whether sig is a valid signature of message by publicKey. It
|
||||
// will panic if len(publicKey) is not PublicKeySize.
|
||||
func Verify(publicKey PublicKey, message, sig []byte) bool { |
||||
return ed25519.Verify(publicKey, message, sig) |
||||
} |
||||
8
vendor/golang.org/x/net/idna/idna.go → vendor/golang.org/x/net/idna/idna10.0.0.go
generated
vendored
8
vendor/golang.org/x/net/idna/idna.go → vendor/golang.org/x/net/idna/idna10.0.0.go
generated
vendored
@ -0,0 +1,682 @@ |
||||
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
|
||||
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !go1.10
|
||||
|
||||
// Package idna implements IDNA2008 using the compatibility processing
|
||||
// defined by UTS (Unicode Technical Standard) #46, which defines a standard to
|
||||
// deal with the transition from IDNA2003.
|
||||
//
|
||||
// IDNA2008 (Internationalized Domain Names for Applications), is defined in RFC
|
||||
// 5890, RFC 5891, RFC 5892, RFC 5893 and RFC 5894.
|
||||
// UTS #46 is defined in https://www.unicode.org/reports/tr46.
|
||||
// See https://unicode.org/cldr/utility/idna.jsp for a visualization of the
|
||||
// differences between these two standards.
|
||||
package idna // import "golang.org/x/net/idna"
|
||||
|
||||
import ( |
||||
"fmt" |
||||
"strings" |
||||
"unicode/utf8" |
||||
|
||||
"golang.org/x/text/secure/bidirule" |
||||
"golang.org/x/text/unicode/norm" |
||||
) |
||||
|
||||
// NOTE: Unlike common practice in Go APIs, the functions will return a
|
||||
// sanitized domain name in case of errors. Browsers sometimes use a partially
|
||||
// evaluated string as lookup.
|
||||
// TODO: the current error handling is, in my opinion, the least opinionated.
|
||||
// Other strategies are also viable, though:
|
||||
// Option 1) Return an empty string in case of error, but allow the user to
|
||||
// specify explicitly which errors to ignore.
|
||||
// Option 2) Return the partially evaluated string if it is itself a valid
|
||||
// string, otherwise return the empty string in case of error.
|
||||
// Option 3) Option 1 and 2.
|
||||
// Option 4) Always return an empty string for now and implement Option 1 as
|
||||
// needed, and document that the return string may not be empty in case of
|
||||
// error in the future.
|
||||
// I think Option 1 is best, but it is quite opinionated.
|
||||
|
||||
// ToASCII is a wrapper for Punycode.ToASCII.
|
||||
func ToASCII(s string) (string, error) { |
||||
return Punycode.process(s, true) |
||||
} |
||||
|
||||
// ToUnicode is a wrapper for Punycode.ToUnicode.
|
||||
func ToUnicode(s string) (string, error) { |
||||
return Punycode.process(s, false) |
||||
} |
||||
|
||||
// An Option configures a Profile at creation time.
|
||||
type Option func(*options) |
||||
|
||||
// Transitional sets a Profile to use the Transitional mapping as defined in UTS
|
||||
// #46. This will cause, for example, "ß" to be mapped to "ss". Using the
|
||||
// transitional mapping provides a compromise between IDNA2003 and IDNA2008
|
||||
// compatibility. It is used by most browsers when resolving domain names. This
|
||||
// option is only meaningful if combined with MapForLookup.
|
||||
func Transitional(transitional bool) Option { |
||||
return func(o *options) { o.transitional = true } |
||||
} |
||||
|
||||
// VerifyDNSLength sets whether a Profile should fail if any of the IDN parts
|
||||
// are longer than allowed by the RFC.
|
||||
func VerifyDNSLength(verify bool) Option { |
||||
return func(o *options) { o.verifyDNSLength = verify } |
||||
} |
||||
|
||||
// RemoveLeadingDots removes leading label separators. Leading runes that map to
|
||||
// dots, such as U+3002 IDEOGRAPHIC FULL STOP, are removed as well.
|
||||
//
|
||||
// This is the behavior suggested by the UTS #46 and is adopted by some
|
||||
// browsers.
|
||||
func RemoveLeadingDots(remove bool) Option { |
||||
return func(o *options) { o.removeLeadingDots = remove } |
||||
} |
||||
|
||||
// ValidateLabels sets whether to check the mandatory label validation criteria
|
||||
// as defined in Section 5.4 of RFC 5891. This includes testing for correct use
|
||||
// of hyphens ('-'), normalization, validity of runes, and the context rules.
|
||||
func ValidateLabels(enable bool) Option { |
||||
return func(o *options) { |
||||
// Don't override existing mappings, but set one that at least checks
|
||||
// normalization if it is not set.
|
||||
if o.mapping == nil && enable { |
||||
o.mapping = normalize |
||||
} |
||||
o.trie = trie |
||||
o.validateLabels = enable |
||||
o.fromPuny = validateFromPunycode |
||||
} |
||||
} |
||||
|
||||
// StrictDomainName limits the set of permissable ASCII characters to those
|
||||
// allowed in domain names as defined in RFC 1034 (A-Z, a-z, 0-9 and the
|
||||
// hyphen). This is set by default for MapForLookup and ValidateForRegistration.
|
||||
//
|
||||
// This option is useful, for instance, for browsers that allow characters
|
||||
// outside this range, for example a '_' (U+005F LOW LINE). See
|
||||
// http://www.rfc-editor.org/std/std3.txt for more details This option
|
||||
// corresponds to the UseSTD3ASCIIRules option in UTS #46.
|
||||
func StrictDomainName(use bool) Option { |
||||
return func(o *options) { |
||||
o.trie = trie |
||||
o.useSTD3Rules = use |
||||
o.fromPuny = validateFromPunycode |
||||
} |
||||
} |
||||
|
||||
// NOTE: the following options pull in tables. The tables should not be linked
|
||||
// in as long as the options are not used.
|
||||
|
||||
// BidiRule enables the Bidi rule as defined in RFC 5893. Any application
|
||||
// that relies on proper validation of labels should include this rule.
|
||||
func BidiRule() Option { |
||||
return func(o *options) { o.bidirule = bidirule.ValidString } |
||||
} |
||||
|
||||
// ValidateForRegistration sets validation options to verify that a given IDN is
|
||||
// properly formatted for registration as defined by Section 4 of RFC 5891.
|
||||
func ValidateForRegistration() Option { |
||||
return func(o *options) { |
||||
o.mapping = validateRegistration |
||||
StrictDomainName(true)(o) |
||||
ValidateLabels(true)(o) |
||||
VerifyDNSLength(true)(o) |
||||
BidiRule()(o) |
||||
} |
||||
} |
||||
|
||||
// MapForLookup sets validation and mapping options such that a given IDN is
|
||||
// transformed for domain name lookup according to the requirements set out in
|
||||
// Section 5 of RFC 5891. The mappings follow the recommendations of RFC 5894,
|
||||
// RFC 5895 and UTS 46. It does not add the Bidi Rule. Use the BidiRule option
|
||||
// to add this check.
|
||||
//
|
||||
// The mappings include normalization and mapping case, width and other
|
||||
// compatibility mappings.
|
||||
func MapForLookup() Option { |
||||
return func(o *options) { |
||||
o.mapping = validateAndMap |
||||
StrictDomainName(true)(o) |
||||
ValidateLabels(true)(o) |
||||
RemoveLeadingDots(true)(o) |
||||
} |
||||
} |
||||
|
||||
type options struct { |
||||
transitional bool |
||||
useSTD3Rules bool |
||||
validateLabels bool |
||||
verifyDNSLength bool |
||||
removeLeadingDots bool |
||||
|
||||
trie *idnaTrie |
||||
|
||||
// fromPuny calls validation rules when converting A-labels to U-labels.
|
||||
fromPuny func(p *Profile, s string) error |
||||
|
||||
// mapping implements a validation and mapping step as defined in RFC 5895
|
||||
// or UTS 46, tailored to, for example, domain registration or lookup.
|
||||
mapping func(p *Profile, s string) (string, error) |
||||
|
||||
// bidirule, if specified, checks whether s conforms to the Bidi Rule
|
||||
// defined in RFC 5893.
|
||||
bidirule func(s string) bool |
||||
} |
||||
|
||||
// A Profile defines the configuration of a IDNA mapper.
|
||||
type Profile struct { |
||||
options |
||||
} |
||||
|
||||
func apply(o *options, opts []Option) { |
||||
for _, f := range opts { |
||||
f(o) |
||||
} |
||||
} |
||||
|
||||
// New creates a new Profile.
|
||||
//
|
||||
// With no options, the returned Profile is the most permissive and equals the
|
||||
// Punycode Profile. Options can be passed to further restrict the Profile. The
|
||||
// MapForLookup and ValidateForRegistration options set a collection of options,
|
||||
// for lookup and registration purposes respectively, which can be tailored by
|
||||
// adding more fine-grained options, where later options override earlier
|
||||
// options.
|
||||
func New(o ...Option) *Profile { |
||||
p := &Profile{} |
||||
apply(&p.options, o) |
||||
return p |
||||
} |
||||
|
||||
// ToASCII converts a domain or domain label to its ASCII form. For example,
|
||||
// ToASCII("bücher.example.com") is "xn--bcher-kva.example.com", and
|
||||
// ToASCII("golang") is "golang". If an error is encountered it will return
|
||||
// an error and a (partially) processed result.
|
||||
func (p *Profile) ToASCII(s string) (string, error) { |
||||
return p.process(s, true) |
||||
} |
||||
|
||||
// ToUnicode converts a domain or domain label to its Unicode form. For example,
|
||||
// ToUnicode("xn--bcher-kva.example.com") is "bücher.example.com", and
|
||||
// ToUnicode("golang") is "golang". If an error is encountered it will return
|
||||
// an error and a (partially) processed result.
|
||||
func (p *Profile) ToUnicode(s string) (string, error) { |
||||
pp := *p |
||||
pp.transitional = false |
||||
return pp.process(s, false) |
||||
} |
||||
|
||||
// String reports a string with a description of the profile for debugging
|
||||
// purposes. The string format may change with different versions.
|
||||
func (p *Profile) String() string { |
||||
s := "" |
||||
if p.transitional { |
||||
s = "Transitional" |
||||
} else { |
||||
s = "NonTransitional" |
||||
} |
||||
if p.useSTD3Rules { |
||||
s += ":UseSTD3Rules" |
||||
} |
||||
if p.validateLabels { |
||||
s += ":ValidateLabels" |
||||
} |
||||
if p.verifyDNSLength { |
||||
s += ":VerifyDNSLength" |
||||
} |
||||
return s |
||||
} |
||||
|
||||
var ( |
||||
// Punycode is a Profile that does raw punycode processing with a minimum
|
||||
// of validation.
|
||||
Punycode *Profile = punycode |
||||
|
||||
// Lookup is the recommended profile for looking up domain names, according
|
||||
// to Section 5 of RFC 5891. The exact configuration of this profile may
|
||||
// change over time.
|
||||
Lookup *Profile = lookup |
||||
|
||||
// Display is the recommended profile for displaying domain names.
|
||||
// The configuration of this profile may change over time.
|
||||
Display *Profile = display |
||||
|
||||
// Registration is the recommended profile for checking whether a given
|
||||
// IDN is valid for registration, according to Section 4 of RFC 5891.
|
||||
Registration *Profile = registration |
||||
|
||||
punycode = &Profile{} |
||||
lookup = &Profile{options{ |
||||
transitional: true, |
||||
useSTD3Rules: true, |
||||
validateLabels: true, |
||||
removeLeadingDots: true, |
||||
trie: trie, |
||||
fromPuny: validateFromPunycode, |
||||
mapping: validateAndMap, |
||||
bidirule: bidirule.ValidString, |
||||
}} |
||||
display = &Profile{options{ |
||||
useSTD3Rules: true, |
||||
validateLabels: true, |
||||
removeLeadingDots: true, |
||||
trie: trie, |
||||
fromPuny: validateFromPunycode, |
||||
mapping: validateAndMap, |
||||
bidirule: bidirule.ValidString, |
||||
}} |
||||
registration = &Profile{options{ |
||||
useSTD3Rules: true, |
||||
validateLabels: true, |
||||
verifyDNSLength: true, |
||||
trie: trie, |
||||
fromPuny: validateFromPunycode, |
||||
mapping: validateRegistration, |
||||
bidirule: bidirule.ValidString, |
||||
}} |
||||
|
||||
// TODO: profiles
|
||||
// Register: recommended for approving domain names: don't do any mappings
|
||||
// but rather reject on invalid input. Bundle or block deviation characters.
|
||||
) |
||||
|
||||
type labelError struct{ label, code_ string } |
||||
|
||||
func (e labelError) code() string { return e.code_ } |
||||
func (e labelError) Error() string { |
||||
return fmt.Sprintf("idna: invalid label %q", e.label) |
||||
} |
||||
|
||||
type runeError rune |
||||
|
||||
func (e runeError) code() string { return "P1" } |
||||
func (e runeError) Error() string { |
||||
return fmt.Sprintf("idna: disallowed rune %U", e) |
||||
} |
||||
|
||||
// process implements the algorithm described in section 4 of UTS #46,
|
||||
// see https://www.unicode.org/reports/tr46.
|
||||
func (p *Profile) process(s string, toASCII bool) (string, error) { |
||||
var err error |
||||
if p.mapping != nil { |
||||
s, err = p.mapping(p, s) |
||||
} |
||||
// Remove leading empty labels.
|
||||
if p.removeLeadingDots { |
||||
for ; len(s) > 0 && s[0] == '.'; s = s[1:] { |
||||
} |
||||
} |
||||
// It seems like we should only create this error on ToASCII, but the
|
||||
// UTS 46 conformance tests suggests we should always check this.
|
||||
if err == nil && p.verifyDNSLength && s == "" { |
||||
err = &labelError{s, "A4"} |
||||
} |
||||
labels := labelIter{orig: s} |
||||
for ; !labels.done(); labels.next() { |
||||
label := labels.label() |
||||
if label == "" { |
||||
// Empty labels are not okay. The label iterator skips the last
|
||||
// label if it is empty.
|
||||
if err == nil && p.verifyDNSLength { |
||||
err = &labelError{s, "A4"} |
||||
} |
||||
continue |
||||
} |
||||
if strings.HasPrefix(label, acePrefix) { |
||||
u, err2 := decode(label[len(acePrefix):]) |
||||
if err2 != nil { |
||||
if err == nil { |
||||
err = err2 |
||||
} |
||||
// Spec says keep the old label.
|
||||
continue |
||||
} |
||||
labels.set(u) |
||||
if err == nil && p.validateLabels { |
||||
err = p.fromPuny(p, u) |
||||
} |
||||
if err == nil { |
||||
// This should be called on NonTransitional, according to the
|
||||
// spec, but that currently does not have any effect. Use the
|
||||
// original profile to preserve options.
|
||||
err = p.validateLabel(u) |
||||
} |
||||
} else if err == nil { |
||||
err = p.validateLabel(label) |
||||
} |
||||
} |
||||
if toASCII { |
||||
for labels.reset(); !labels.done(); labels.next() { |
||||
label := labels.label() |
||||
if !ascii(label) { |
||||
a, err2 := encode(acePrefix, label) |
||||
if err == nil { |
||||
err = err2 |
||||
} |
||||
label = a |
||||
labels.set(a) |
||||
} |
||||
n := len(label) |
||||
if p.verifyDNSLength && err == nil && (n == 0 || n > 63) { |
||||
err = &labelError{label, "A4"} |
||||
} |
||||
} |
||||
} |
||||
s = labels.result() |
||||
if toASCII && p.verifyDNSLength && err == nil { |
||||
// Compute the length of the domain name minus the root label and its dot.
|
||||
n := len(s) |
||||
if n > 0 && s[n-1] == '.' { |
||||
n-- |
||||
} |
||||
if len(s) < 1 || n > 253 { |
||||
err = &labelError{s, "A4"} |
||||
} |
||||
} |
||||
return s, err |
||||
} |
||||
|
||||
func normalize(p *Profile, s string) (string, error) { |
||||
return norm.NFC.String(s), nil |
||||
} |
||||
|
||||
func validateRegistration(p *Profile, s string) (string, error) { |
||||
if !norm.NFC.IsNormalString(s) { |
||||
return s, &labelError{s, "V1"} |
||||
} |
||||
for i := 0; i < len(s); { |
||||
v, sz := trie.lookupString(s[i:]) |
||||
// Copy bytes not copied so far.
|
||||
switch p.simplify(info(v).category()) { |
||||
// TODO: handle the NV8 defined in the Unicode idna data set to allow
|
||||
// for strict conformance to IDNA2008.
|
||||
case valid, deviation: |
||||
case disallowed, mapped, unknown, ignored: |
||||
r, _ := utf8.DecodeRuneInString(s[i:]) |
||||
return s, runeError(r) |
||||
} |
||||
i += sz |
||||
} |
||||
return s, nil |
||||
} |
||||
|
||||
func validateAndMap(p *Profile, s string) (string, error) { |
||||
var ( |
||||
err error |
||||
b []byte |
||||
k int |
||||
) |
||||
for i := 0; i < len(s); { |
||||
v, sz := trie.lookupString(s[i:]) |
||||
start := i |
||||
i += sz |
||||
// Copy bytes not copied so far.
|
||||
switch p.simplify(info(v).category()) { |
||||
case valid: |
||||
continue |
||||
case disallowed: |
||||
if err == nil { |
||||
r, _ := utf8.DecodeRuneInString(s[start:]) |
||||
err = runeError(r) |
||||
} |
||||
continue |
||||
case mapped, deviation: |
||||
b = append(b, s[k:start]...) |
||||
b = info(v).appendMapping(b, s[start:i]) |
||||
case ignored: |
||||
b = append(b, s[k:start]...) |
||||
// drop the rune
|
||||
case unknown: |
||||
b = append(b, s[k:start]...) |
||||
b = append(b, "\ufffd"...) |
||||
} |
||||
k = i |
||||
} |
||||
if k == 0 { |
||||
// No changes so far.
|
||||
s = norm.NFC.String(s) |
||||
} else { |
||||
b = append(b, s[k:]...) |
||||
if norm.NFC.QuickSpan(b) != len(b) { |
||||
b = norm.NFC.Bytes(b) |
||||
} |
||||
// TODO: the punycode converters require strings as input.
|
||||
s = string(b) |
||||
} |
||||
return s, err |
||||
} |
||||
|
||||
// A labelIter allows iterating over domain name labels.
|
||||
type labelIter struct { |
||||
orig string |
||||
slice []string |
||||
curStart int |
||||
curEnd int |
||||
i int |
||||
} |
||||
|
||||
func (l *labelIter) reset() { |
||||
l.curStart = 0 |
||||
l.curEnd = 0 |
||||
l.i = 0 |
||||
} |
||||
|
||||
func (l *labelIter) done() bool { |
||||
return l.curStart >= len(l.orig) |
||||
} |
||||
|
||||
func (l *labelIter) result() string { |
||||
if l.slice != nil { |
||||
return strings.Join(l.slice, ".") |
||||
} |
||||
return l.orig |
||||
} |
||||
|
||||
func (l *labelIter) label() string { |
||||
if l.slice != nil { |
||||
return l.slice[l.i] |
||||
} |
||||
p := strings.IndexByte(l.orig[l.curStart:], '.') |
||||
l.curEnd = l.curStart + p |
||||
if p == -1 { |
||||
l.curEnd = len(l.orig) |
||||
} |
||||
return l.orig[l.curStart:l.curEnd] |
||||
} |
||||
|
||||
// next sets the value to the next label. It skips the last label if it is empty.
|
||||
func (l *labelIter) next() { |
||||
l.i++ |
||||
if l.slice != nil { |
||||
if l.i >= len(l.slice) || l.i == len(l.slice)-1 && l.slice[l.i] == "" { |
||||
l.curStart = len(l.orig) |
||||
} |
||||
} else { |
||||
l.curStart = l.curEnd + 1 |
||||
if l.curStart == len(l.orig)-1 && l.orig[l.curStart] == '.' { |
||||
l.curStart = len(l.orig) |
||||
} |
||||
} |
||||
} |
||||
|
||||
func (l *labelIter) set(s string) { |
||||
if l.slice == nil { |
||||
l.slice = strings.Split(l.orig, ".") |
||||
} |
||||
l.slice[l.i] = s |
||||
} |
||||
|
||||
// acePrefix is the ASCII Compatible Encoding prefix.
|
||||
const acePrefix = "xn--" |
||||
|
||||
func (p *Profile) simplify(cat category) category { |
||||
switch cat { |
||||
case disallowedSTD3Mapped: |
||||
if p.useSTD3Rules { |
||||
cat = disallowed |
||||
} else { |
||||
cat = mapped |
||||
} |
||||
case disallowedSTD3Valid: |
||||
if p.useSTD3Rules { |
||||
cat = disallowed |
||||
} else { |
||||
cat = valid |
||||
} |
||||
case deviation: |
||||
if !p.transitional { |
||||
cat = valid |
||||
} |
||||
case validNV8, validXV8: |
||||
// TODO: handle V2008
|
||||
cat = valid |
||||
} |
||||
return cat |
||||
} |
||||
|
||||
func validateFromPunycode(p *Profile, s string) error { |
||||
if !norm.NFC.IsNormalString(s) { |
||||
return &labelError{s, "V1"} |
||||
} |
||||
for i := 0; i < len(s); { |
||||
v, sz := trie.lookupString(s[i:]) |
||||
if c := p.simplify(info(v).category()); c != valid && c != deviation { |
||||
return &labelError{s, "V6"} |
||||
} |
||||
i += sz |
||||
} |
||||
return nil |
||||
} |
||||
|
||||
const ( |
||||
zwnj = "\u200c" |
||||
zwj = "\u200d" |
||||
) |
||||
|
||||
type joinState int8 |
||||
|
||||
const ( |
||||
stateStart joinState = iota |
||||
stateVirama |
||||
stateBefore |
||||
stateBeforeVirama |
||||
stateAfter |
||||
stateFAIL |
||||
) |
||||
|
||||
var joinStates = [][numJoinTypes]joinState{ |
||||
stateStart: { |
||||
joiningL: stateBefore, |
||||
joiningD: stateBefore, |
||||
joinZWNJ: stateFAIL, |
||||
joinZWJ: stateFAIL, |
||||
joinVirama: stateVirama, |
||||
}, |
||||
stateVirama: { |
||||
joiningL: stateBefore, |
||||
joiningD: stateBefore, |
||||
}, |
||||
stateBefore: { |
||||
joiningL: stateBefore, |
||||
joiningD: stateBefore, |
||||
joiningT: stateBefore, |
||||
joinZWNJ: stateAfter, |
||||
joinZWJ: stateFAIL, |
||||
joinVirama: stateBeforeVirama, |
||||
}, |
||||
stateBeforeVirama: { |
||||
joiningL: stateBefore, |
||||
joiningD: stateBefore, |
||||
joiningT: stateBefore, |
||||
}, |
||||
stateAfter: { |
||||
joiningL: stateFAIL, |
||||
joiningD: stateBefore, |
||||
joiningT: stateAfter, |
||||
joiningR: stateStart, |
||||
joinZWNJ: stateFAIL, |
||||
joinZWJ: stateFAIL, |
||||
joinVirama: stateAfter, // no-op as we can't accept joiners here
|
||||
}, |
||||
stateFAIL: { |
||||
0: stateFAIL, |
||||
joiningL: stateFAIL, |
||||
joiningD: stateFAIL, |
||||
joiningT: stateFAIL, |
||||
joiningR: stateFAIL, |
||||
joinZWNJ: stateFAIL, |
||||
joinZWJ: stateFAIL, |
||||
joinVirama: stateFAIL, |
||||
}, |
||||
} |
||||
|
||||
// validateLabel validates the criteria from Section 4.1. Item 1, 4, and 6 are
|
||||
// already implicitly satisfied by the overall implementation.
|
||||
func (p *Profile) validateLabel(s string) error { |
||||
if s == "" { |
||||
if p.verifyDNSLength { |
||||
return &labelError{s, "A4"} |
||||
} |
||||
return nil |
||||
} |
||||
if p.bidirule != nil && !p.bidirule(s) { |
||||
return &labelError{s, "B"} |
||||
} |
||||
if !p.validateLabels { |
||||
return nil |
||||
} |
||||
trie := p.trie // p.validateLabels is only set if trie is set.
|
||||
if len(s) > 4 && s[2] == '-' && s[3] == '-' { |
||||
return &labelError{s, "V2"} |
||||
} |
||||
if s[0] == '-' || s[len(s)-1] == '-' { |
||||
return &labelError{s, "V3"} |
||||
} |
||||
// TODO: merge the use of this in the trie.
|
||||
v, sz := trie.lookupString(s) |
||||
x := info(v) |
||||
if x.isModifier() { |
||||
return &labelError{s, "V5"} |
||||
} |
||||
// Quickly return in the absence of zero-width (non) joiners.
|
||||
if strings.Index(s, zwj) == -1 && strings.Index(s, zwnj) == -1 { |
||||
return nil |
||||
} |
||||
st := stateStart |
||||
for i := 0; ; { |
||||
jt := x.joinType() |
||||
if s[i:i+sz] == zwj { |
||||
jt = joinZWJ |
||||
} else if s[i:i+sz] == zwnj { |
||||
jt = joinZWNJ |
||||
} |
||||
st = joinStates[st][jt] |
||||
if x.isViramaModifier() { |
||||
st = joinStates[st][joinVirama] |
||||
} |
||||
if i += sz; i == len(s) { |
||||
break |
||||
} |
||||
v, sz = trie.lookupString(s[i:]) |
||||
x = info(v) |
||||
} |
||||
if st == stateFAIL || st == stateAfter { |
||||
return &labelError{s, "C"} |
||||
} |
||||
return nil |
||||
} |
||||
|
||||
func ascii(s string) bool { |
||||
for i := 0; i < len(s); i++ { |
||||
if s[i] >= utf8.RuneSelf { |
||||
return false |
||||
} |
||||
} |
||||
return true |
||||
} |
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,54 @@ |
||||
// Copyright 2019 The Go Authors. All rights reserved. |
||||
// Use of this source code is governed by a BSD-style |
||||
// license that can be found in the LICENSE file. |
||||
|
||||
// +build riscv64,!gccgo |
||||
|
||||
#include "textflag.h" |
||||
|
||||
// |
||||
// System calls for linux/riscv64. |
||||
// |
||||
// Where available, just jump to package syscall's implementation of |
||||
// these functions. |
||||
|
||||
TEXT ·Syscall(SB),NOSPLIT,$0-56 |
||||
JMP syscall·Syscall(SB) |
||||
|
||||
TEXT ·Syscall6(SB),NOSPLIT,$0-80 |
||||
JMP syscall·Syscall6(SB) |
||||
|
||||
TEXT ·SyscallNoError(SB),NOSPLIT,$0-48 |
||||
CALL runtime·entersyscall(SB) |
||||
MOV a1+8(FP), A0 |
||||
MOV a2+16(FP), A1 |
||||
MOV a3+24(FP), A2 |
||||
MOV $0, A3 |
||||
MOV $0, A4 |
||||
MOV $0, A5 |
||||
MOV $0, A6 |
||||
MOV trap+0(FP), A7 // syscall entry |
||||
ECALL |
||||
MOV A0, r1+32(FP) // r1 |
||||
MOV A1, r2+40(FP) // r2 |
||||
CALL runtime·exitsyscall(SB) |
||||
RET |
||||
|
||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56 |
||||
JMP syscall·RawSyscall(SB) |
||||
|
||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 |
||||
JMP syscall·RawSyscall6(SB) |
||||
|
||||
TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-48 |
||||
MOV a1+8(FP), A0 |
||||
MOV a2+16(FP), A1 |
||||
MOV a3+24(FP), A2 |
||||
MOV ZERO, A3 |
||||
MOV ZERO, A4 |
||||
MOV ZERO, A5 |
||||
MOV trap+0(FP), A7 // syscall entry |
||||
ECALL |
||||
MOV A0, r1+32(FP) |
||||
MOV A1, r2+40(FP) |
||||
RET |
||||
@ -0,0 +1,29 @@ |
||||
// Copyright 2019 The Go Authors. All rights reserved. |
||||
// Use of this source code is governed by a BSD-style |
||||
// license that can be found in the LICENSE file. |
||||
|
||||
// +build !gccgo |
||||
|
||||
#include "textflag.h" |
||||
|
||||
// |
||||
// System call support for arm64, OpenBSD |
||||
// |
||||
|
||||
// Just jump to package syscall's implementation for all these functions. |
||||
// The runtime may know about them. |
||||
|
||||
TEXT ·Syscall(SB),NOSPLIT,$0-56 |
||||
JMP syscall·Syscall(SB) |
||||
|
||||
TEXT ·Syscall6(SB),NOSPLIT,$0-80 |
||||
JMP syscall·Syscall6(SB) |
||||
|
||||
TEXT ·Syscall9(SB),NOSPLIT,$0-104 |
||||
JMP syscall·Syscall9(SB) |
||||
|
||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56 |
||||
JMP syscall·RawSyscall(SB) |
||||
|
||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 |
||||
JMP syscall·RawSyscall6(SB) |
||||
@ -0,0 +1,355 @@ |
||||
// Copyright 2019 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build ignore
|
||||
|
||||
// Parse the header files for OpenBSD and generate a Go usable sysctl MIB.
|
||||
//
|
||||
// Build a MIB with each entry being an array containing the level, type and
|
||||
// a hash that will contain additional entries if the current entry is a node.
|
||||
// We then walk this MIB and create a flattened sysctl name to OID hash.
|
||||
|
||||
package main |
||||
|
||||
import ( |
||||
"bufio" |
||||
"fmt" |
||||
"os" |
||||
"path/filepath" |
||||
"regexp" |
||||
"sort" |
||||
"strings" |
||||
) |
||||
|
||||
var ( |
||||
goos, goarch string |
||||
) |
||||
|
||||
// cmdLine returns this programs's commandline arguments.
|
||||
func cmdLine() string { |
||||
return "go run mksysctl_openbsd.go " + strings.Join(os.Args[1:], " ") |
||||
} |
||||
|
||||
// buildTags returns build tags.
|
||||
func buildTags() string { |
||||
return fmt.Sprintf("%s,%s", goarch, goos) |
||||
} |
||||
|
||||
// reMatch performs regular expression match and stores the substring slice to value pointed by m.
|
||||
func reMatch(re *regexp.Regexp, str string, m *[]string) bool { |
||||
*m = re.FindStringSubmatch(str) |
||||
if *m != nil { |
||||
return true |
||||
} |
||||
return false |
||||
} |
||||
|
||||
type nodeElement struct { |
||||
n int |
||||
t string |
||||
pE *map[string]nodeElement |
||||
} |
||||
|
||||
var ( |
||||
debugEnabled bool |
||||
mib map[string]nodeElement |
||||
node *map[string]nodeElement |
||||
nodeMap map[string]string |
||||
sysCtl []string |
||||
) |
||||
|
||||
var ( |
||||
ctlNames1RE = regexp.MustCompile(`^#define\s+(CTL_NAMES)\s+{`) |
||||
ctlNames2RE = regexp.MustCompile(`^#define\s+(CTL_(.*)_NAMES)\s+{`) |
||||
ctlNames3RE = regexp.MustCompile(`^#define\s+((.*)CTL_NAMES)\s+{`) |
||||
netInetRE = regexp.MustCompile(`^netinet/`) |
||||
netInet6RE = regexp.MustCompile(`^netinet6/`) |
||||
netRE = regexp.MustCompile(`^net/`) |
||||
bracesRE = regexp.MustCompile(`{.*}`) |
||||
ctlTypeRE = regexp.MustCompile(`{\s+"(\w+)",\s+(CTLTYPE_[A-Z]+)\s+}`) |
||||
fsNetKernRE = regexp.MustCompile(`^(fs|net|kern)_`) |
||||
) |
||||
|
||||
func debug(s string) { |
||||
if debugEnabled { |
||||
fmt.Fprintln(os.Stderr, s) |
||||
} |
||||
} |
||||
|
||||
// Walk the MIB and build a sysctl name to OID mapping.
|
||||
func buildSysctl(pNode *map[string]nodeElement, name string, oid []int) { |
||||
lNode := pNode // local copy of pointer to node
|
||||
var keys []string |
||||
for k := range *lNode { |
||||
keys = append(keys, k) |
||||
} |
||||
sort.Strings(keys) |
||||
|
||||
for _, key := range keys { |
||||
nodename := name |
||||
if name != "" { |
||||
nodename += "." |
||||
} |
||||
nodename += key |
||||
|
||||
nodeoid := append(oid, (*pNode)[key].n) |
||||
|
||||
if (*pNode)[key].t == `CTLTYPE_NODE` { |
||||
if _, ok := nodeMap[nodename]; ok { |
||||
lNode = &mib |
||||
ctlName := nodeMap[nodename] |
||||
for _, part := range strings.Split(ctlName, ".") { |
||||
lNode = ((*lNode)[part]).pE |
||||
} |
||||
} else { |
||||
lNode = (*pNode)[key].pE |
||||
} |
||||
buildSysctl(lNode, nodename, nodeoid) |
||||
} else if (*pNode)[key].t != "" { |
||||
oidStr := []string{} |
||||
for j := range nodeoid { |
||||
oidStr = append(oidStr, fmt.Sprintf("%d", nodeoid[j])) |
||||
} |
||||
text := "\t{ \"" + nodename + "\", []_C_int{ " + strings.Join(oidStr, ", ") + " } }, \n" |
||||
sysCtl = append(sysCtl, text) |
||||
} |
||||
} |
||||
} |
||||
|
||||
func main() { |
||||
// Get the OS (using GOOS_TARGET if it exist)
|
||||
goos = os.Getenv("GOOS_TARGET") |
||||
if goos == "" { |
||||
goos = os.Getenv("GOOS") |
||||
} |
||||
// Get the architecture (using GOARCH_TARGET if it exists)
|
||||
goarch = os.Getenv("GOARCH_TARGET") |
||||
if goarch == "" { |
||||
goarch = os.Getenv("GOARCH") |
||||
} |
||||
// Check if GOOS and GOARCH environment variables are defined
|
||||
if goarch == "" || goos == "" { |
||||
fmt.Fprintf(os.Stderr, "GOARCH or GOOS not defined in environment\n") |
||||
os.Exit(1) |
||||
} |
||||
|
||||
mib = make(map[string]nodeElement) |
||||
headers := [...]string{ |
||||
`sys/sysctl.h`, |
||||
`sys/socket.h`, |
||||
`sys/tty.h`, |
||||
`sys/malloc.h`, |
||||
`sys/mount.h`, |
||||
`sys/namei.h`, |
||||
`sys/sem.h`, |
||||
`sys/shm.h`, |
||||
`sys/vmmeter.h`, |
||||
`uvm/uvmexp.h`, |
||||
`uvm/uvm_param.h`, |
||||
`uvm/uvm_swap_encrypt.h`, |
||||
`ddb/db_var.h`, |
||||
`net/if.h`, |
||||
`net/if_pfsync.h`, |
||||
`net/pipex.h`, |
||||
`netinet/in.h`, |
||||
`netinet/icmp_var.h`, |
||||
`netinet/igmp_var.h`, |
||||
`netinet/ip_ah.h`, |
||||
`netinet/ip_carp.h`, |
||||
`netinet/ip_divert.h`, |
||||
`netinet/ip_esp.h`, |
||||
`netinet/ip_ether.h`, |
||||
`netinet/ip_gre.h`, |
||||
`netinet/ip_ipcomp.h`, |
||||
`netinet/ip_ipip.h`, |
||||
`netinet/pim_var.h`, |
||||
`netinet/tcp_var.h`, |
||||
`netinet/udp_var.h`, |
||||
`netinet6/in6.h`, |
||||
`netinet6/ip6_divert.h`, |
||||
`netinet6/pim6_var.h`, |
||||
`netinet/icmp6.h`, |
||||
`netmpls/mpls.h`, |
||||
} |
||||
|
||||
ctls := [...]string{ |
||||
`kern`, |
||||
`vm`, |
||||
`fs`, |
||||
`net`, |
||||
//debug /* Special handling required */
|
||||
`hw`, |
||||
//machdep /* Arch specific */
|
||||
`user`, |
||||
`ddb`, |
||||
//vfs /* Special handling required */
|
||||
`fs.posix`, |
||||
`kern.forkstat`, |
||||
`kern.intrcnt`, |
||||
`kern.malloc`, |
||||
`kern.nchstats`, |
||||
`kern.seminfo`, |
||||
`kern.shminfo`, |
||||
`kern.timecounter`, |
||||
`kern.tty`, |
||||
`kern.watchdog`, |
||||
`net.bpf`, |
||||
`net.ifq`, |
||||
`net.inet`, |
||||
`net.inet.ah`, |
||||
`net.inet.carp`, |
||||
`net.inet.divert`, |
||||
`net.inet.esp`, |
||||
`net.inet.etherip`, |
||||
`net.inet.gre`, |
||||
`net.inet.icmp`, |
||||
`net.inet.igmp`, |
||||
`net.inet.ip`, |
||||
`net.inet.ip.ifq`, |
||||
`net.inet.ipcomp`, |
||||
`net.inet.ipip`, |
||||
`net.inet.mobileip`, |
||||
`net.inet.pfsync`, |
||||
`net.inet.pim`, |
||||
`net.inet.tcp`, |
||||
`net.inet.udp`, |
||||
`net.inet6`, |
||||
`net.inet6.divert`, |
||||
`net.inet6.ip6`, |
||||
`net.inet6.icmp6`, |
||||
`net.inet6.pim6`, |
||||
`net.inet6.tcp6`, |
||||
`net.inet6.udp6`, |
||||
`net.mpls`, |
||||
`net.mpls.ifq`, |
||||
`net.key`, |
||||
`net.pflow`, |
||||
`net.pfsync`, |
||||
`net.pipex`, |
||||
`net.rt`, |
||||
`vm.swapencrypt`, |
||||
//vfsgenctl /* Special handling required */
|
||||
} |
||||
|
||||
// Node name "fixups"
|
||||
ctlMap := map[string]string{ |
||||
"ipproto": "net.inet", |
||||
"net.inet.ipproto": "net.inet", |
||||
"net.inet6.ipv6proto": "net.inet6", |
||||
"net.inet6.ipv6": "net.inet6.ip6", |
||||
"net.inet.icmpv6": "net.inet6.icmp6", |
||||
"net.inet6.divert6": "net.inet6.divert", |
||||
"net.inet6.tcp6": "net.inet.tcp", |
||||
"net.inet6.udp6": "net.inet.udp", |
||||
"mpls": "net.mpls", |
||||
"swpenc": "vm.swapencrypt", |
||||
} |
||||
|
||||
// Node mappings
|
||||
nodeMap = map[string]string{ |
||||
"net.inet.ip.ifq": "net.ifq", |
||||
"net.inet.pfsync": "net.pfsync", |
||||
"net.mpls.ifq": "net.ifq", |
||||
} |
||||
|
||||
mCtls := make(map[string]bool) |
||||
for _, ctl := range ctls { |
||||
mCtls[ctl] = true |
||||
} |
||||
|
||||
for _, header := range headers { |
||||
debug("Processing " + header) |
||||
file, err := os.Open(filepath.Join("/usr/include", header)) |
||||
if err != nil { |
||||
fmt.Fprintf(os.Stderr, "%v\n", err) |
||||
os.Exit(1) |
||||
} |
||||
s := bufio.NewScanner(file) |
||||
for s.Scan() { |
||||
var sub []string |
||||
if reMatch(ctlNames1RE, s.Text(), &sub) || |
||||
reMatch(ctlNames2RE, s.Text(), &sub) || |
||||
reMatch(ctlNames3RE, s.Text(), &sub) { |
||||
if sub[1] == `CTL_NAMES` { |
||||
// Top level.
|
||||
node = &mib |
||||
} else { |
||||
// Node.
|
||||
nodename := strings.ToLower(sub[2]) |
||||
ctlName := "" |
||||
if reMatch(netInetRE, header, &sub) { |
||||
ctlName = "net.inet." + nodename |
||||
} else if reMatch(netInet6RE, header, &sub) { |
||||
ctlName = "net.inet6." + nodename |
||||
} else if reMatch(netRE, header, &sub) { |
||||
ctlName = "net." + nodename |
||||
} else { |
||||
ctlName = nodename |
||||
ctlName = fsNetKernRE.ReplaceAllString(ctlName, `$1.`) |
||||
} |
||||
|
||||
if val, ok := ctlMap[ctlName]; ok { |
||||
ctlName = val |
||||
} |
||||
if _, ok := mCtls[ctlName]; !ok { |
||||
debug("Ignoring " + ctlName + "...") |
||||
continue |
||||
} |
||||
|
||||
// Walk down from the top of the MIB.
|
||||
node = &mib |
||||
for _, part := range strings.Split(ctlName, ".") { |
||||
if _, ok := (*node)[part]; !ok { |
||||
debug("Missing node " + part) |
||||
(*node)[part] = nodeElement{n: 0, t: "", pE: &map[string]nodeElement{}} |
||||
} |
||||
node = (*node)[part].pE |
||||
} |
||||
} |
||||
|
||||
// Populate current node with entries.
|
||||
i := -1 |
||||
for !strings.HasPrefix(s.Text(), "}") { |
||||
s.Scan() |
||||
if reMatch(bracesRE, s.Text(), &sub) { |
||||
i++ |
||||
} |
||||
if !reMatch(ctlTypeRE, s.Text(), &sub) { |
||||
continue |
||||
} |
||||
(*node)[sub[1]] = nodeElement{n: i, t: sub[2], pE: &map[string]nodeElement{}} |
||||
} |
||||
} |
||||
} |
||||
err = s.Err() |
||||
if err != nil { |
||||
fmt.Fprintf(os.Stderr, "%v\n", err) |
||||
os.Exit(1) |
||||
} |
||||
file.Close() |
||||
} |
||||
buildSysctl(&mib, "", []int{}) |
||||
|
||||
sort.Strings(sysCtl) |
||||
text := strings.Join(sysCtl, "") |
||||
|
||||
fmt.Printf(srcTemplate, cmdLine(), buildTags(), text) |
||||
} |
||||
|
||||
const srcTemplate = `// %s
|
||||
// Code generated by the command above; DO NOT EDIT.
|
||||
|
||||
// +build %s
|
||||
|
||||
package unix |
||||
|
||||
type mibentry struct { |
||||
ctlname string |
||||
ctloid []_C_int |
||||
} |
||||
|
||||
var sysctlMib = []mibentry { |
||||
%s |
||||
} |
||||
` |
||||
@ -1,265 +0,0 @@ |
||||
#!/usr/bin/env perl |
||||
|
||||
# Copyright 2011 The Go Authors. All rights reserved. |
||||
# Use of this source code is governed by a BSD-style |
||||
# license that can be found in the LICENSE file. |
||||
|
||||
# |
||||
# Parse the header files for OpenBSD and generate a Go usable sysctl MIB. |
||||
# |
||||
# Build a MIB with each entry being an array containing the level, type and |
||||
# a hash that will contain additional entries if the current entry is a node. |
||||
# We then walk this MIB and create a flattened sysctl name to OID hash. |
||||
# |
||||
|
||||
use strict; |
||||
|
||||
if($ENV{'GOARCH'} eq "" || $ENV{'GOOS'} eq "") { |
||||
print STDERR "GOARCH or GOOS not defined in environment\n"; |
||||
exit 1; |
||||
} |
||||
|
||||
my $debug = 0; |
||||
my %ctls = (); |
||||
|
||||
my @headers = qw ( |
||||
sys/sysctl.h |
||||
sys/socket.h |
||||
sys/tty.h |
||||
sys/malloc.h |
||||
sys/mount.h |
||||
sys/namei.h |
||||
sys/sem.h |
||||
sys/shm.h |
||||
sys/vmmeter.h |
||||
uvm/uvmexp.h |
||||
uvm/uvm_param.h |
||||
uvm/uvm_swap_encrypt.h |
||||
ddb/db_var.h |
||||
net/if.h |
||||
net/if_pfsync.h |
||||
net/pipex.h |
||||
netinet/in.h |
||||
netinet/icmp_var.h |
||||
netinet/igmp_var.h |
||||
netinet/ip_ah.h |
||||
netinet/ip_carp.h |
||||
netinet/ip_divert.h |
||||
netinet/ip_esp.h |
||||
netinet/ip_ether.h |
||||
netinet/ip_gre.h |
||||
netinet/ip_ipcomp.h |
||||
netinet/ip_ipip.h |
||||
netinet/pim_var.h |
||||
netinet/tcp_var.h |
||||
netinet/udp_var.h |
||||
netinet6/in6.h |
||||
netinet6/ip6_divert.h |
||||
netinet6/pim6_var.h |
||||
netinet/icmp6.h |
||||
netmpls/mpls.h |
||||
); |
||||
|
||||
my @ctls = qw ( |
||||
kern |
||||
vm |
||||
fs |
||||
net |
||||
#debug # Special handling required |
||||
hw |
||||
#machdep # Arch specific |
||||
user |
||||
ddb |
||||
#vfs # Special handling required |
||||
fs.posix |
||||
kern.forkstat |
||||
kern.intrcnt |
||||
kern.malloc |
||||
kern.nchstats |
||||
kern.seminfo |
||||
kern.shminfo |
||||
kern.timecounter |
||||
kern.tty |
||||
kern.watchdog |
||||
net.bpf |
||||
net.ifq |
||||
net.inet |
||||
net.inet.ah |
||||
net.inet.carp |
||||
net.inet.divert |
||||
net.inet.esp |
||||
net.inet.etherip |
||||
net.inet.gre |
||||
net.inet.icmp |
||||
net.inet.igmp |
||||
net.inet.ip |
||||
net.inet.ip.ifq |
||||
net.inet.ipcomp |
||||
net.inet.ipip |
||||
net.inet.mobileip |
||||
net.inet.pfsync |
||||
net.inet.pim |
||||
net.inet.tcp |
||||
net.inet.udp |
||||
net.inet6 |
||||
net.inet6.divert |
||||
net.inet6.ip6 |
||||
net.inet6.icmp6 |
||||
net.inet6.pim6 |
||||
net.inet6.tcp6 |
||||
net.inet6.udp6 |
||||
net.mpls |
||||
net.mpls.ifq |
||||
net.key |
||||
net.pflow |
||||
net.pfsync |
||||
net.pipex |
||||
net.rt |
||||
vm.swapencrypt |
||||
#vfsgenctl # Special handling required |
||||
); |
||||
|
||||
# Node name "fixups" |
||||
my %ctl_map = ( |
||||
"ipproto" => "net.inet", |
||||
"net.inet.ipproto" => "net.inet", |
||||
"net.inet6.ipv6proto" => "net.inet6", |
||||
"net.inet6.ipv6" => "net.inet6.ip6", |
||||
"net.inet.icmpv6" => "net.inet6.icmp6", |
||||
"net.inet6.divert6" => "net.inet6.divert", |
||||
"net.inet6.tcp6" => "net.inet.tcp", |
||||
"net.inet6.udp6" => "net.inet.udp", |
||||
"mpls" => "net.mpls", |
||||
"swpenc" => "vm.swapencrypt" |
||||
); |
||||
|
||||
# Node mappings |
||||
my %node_map = ( |
||||
"net.inet.ip.ifq" => "net.ifq", |
||||
"net.inet.pfsync" => "net.pfsync", |
||||
"net.mpls.ifq" => "net.ifq" |
||||
); |
||||
|
||||
my $ctlname; |
||||
my %mib = (); |
||||
my %sysctl = (); |
||||
my $node; |
||||
|
||||
sub debug() { |
||||
print STDERR "$_[0]\n" if $debug; |
||||
} |
||||
|
||||
# Walk the MIB and build a sysctl name to OID mapping. |
||||
sub build_sysctl() { |
||||
my ($node, $name, $oid) = @_; |
||||
my %node = %{$node}; |
||||
my @oid = @{$oid}; |
||||
|
||||
foreach my $key (sort keys %node) { |
||||
my @node = @{$node{$key}}; |
||||
my $nodename = $name.($name ne '' ? '.' : '').$key; |
||||
my @nodeoid = (@oid, $node[0]); |
||||
if ($node[1] eq 'CTLTYPE_NODE') { |
||||
if (exists $node_map{$nodename}) { |
||||
$node = \%mib; |
||||
$ctlname = $node_map{$nodename}; |
||||
foreach my $part (split /\./, $ctlname) { |
||||
$node = \%{@{$$node{$part}}[2]}; |
||||
} |
||||
} else { |
||||
$node = $node[2]; |
||||
} |
||||
&build_sysctl($node, $nodename, \@nodeoid); |
||||
} elsif ($node[1] ne '') { |
||||
$sysctl{$nodename} = \@nodeoid; |
||||
} |
||||
} |
||||
} |
||||
|
||||
foreach my $ctl (@ctls) { |
||||
$ctls{$ctl} = $ctl; |
||||
} |
||||
|
||||
# Build MIB |
||||
foreach my $header (@headers) { |
||||
&debug("Processing $header..."); |
||||
open HEADER, "/usr/include/$header" || |
||||
print STDERR "Failed to open $header\n"; |
||||
while (<HEADER>) { |
||||
if ($_ =~ /^#define\s+(CTL_NAMES)\s+{/ || |
||||
$_ =~ /^#define\s+(CTL_(.*)_NAMES)\s+{/ || |
||||
$_ =~ /^#define\s+((.*)CTL_NAMES)\s+{/) { |
||||
if ($1 eq 'CTL_NAMES') { |
||||
# Top level. |
||||
$node = \%mib; |
||||
} else { |
||||
# Node. |
||||
my $nodename = lc($2); |
||||
if ($header =~ /^netinet\//) { |
||||
$ctlname = "net.inet.$nodename"; |
||||
} elsif ($header =~ /^netinet6\//) { |
||||
$ctlname = "net.inet6.$nodename"; |
||||
} elsif ($header =~ /^net\//) { |
||||
$ctlname = "net.$nodename"; |
||||
} else { |
||||
$ctlname = "$nodename"; |
||||
$ctlname =~ s/^(fs|net|kern)_/$1\./; |
||||
} |
||||
if (exists $ctl_map{$ctlname}) { |
||||
$ctlname = $ctl_map{$ctlname}; |
||||
} |
||||
if (not exists $ctls{$ctlname}) { |
||||
&debug("Ignoring $ctlname..."); |
||||
next; |
||||
} |
||||
|
||||
# Walk down from the top of the MIB. |
||||
$node = \%mib; |
||||
foreach my $part (split /\./, $ctlname) { |
||||
if (not exists $$node{$part}) { |
||||
&debug("Missing node $part"); |
||||
$$node{$part} = [ 0, '', {} ]; |
||||
} |
||||
$node = \%{@{$$node{$part}}[2]}; |
||||
} |
||||
} |
||||
|
||||
# Populate current node with entries. |
||||
my $i = -1; |
||||
while (defined($_) && $_ !~ /^}/) { |
||||
$_ = <HEADER>; |
||||
$i++ if $_ =~ /{.*}/; |
||||
next if $_ !~ /{\s+"(\w+)",\s+(CTLTYPE_[A-Z]+)\s+}/; |
||||
$$node{$1} = [ $i, $2, {} ]; |
||||
} |
||||
} |
||||
} |
||||
close HEADER; |
||||
} |
||||
|
||||
&build_sysctl(\%mib, "", []); |
||||
|
||||
print <<EOF; |
||||
// mksysctl_openbsd.pl |
||||
// Code generated by the command above; DO NOT EDIT. |
||||
|
||||
// +build $ENV{'GOARCH'},$ENV{'GOOS'} |
||||
|
||||
package unix; |
||||
|
||||
type mibentry struct { |
||||
ctlname string |
||||
ctloid []_C_int |
||||
} |
||||
|
||||
var sysctlMib = []mibentry { |
||||
EOF |
||||
|
||||
foreach my $name (sort keys %sysctl) { |
||||
my @oid = @{$sysctl{$name}}; |
||||
print "\t{ \"$name\", []_C_int{ ", join(', ', @oid), " } }, \n"; |
||||
} |
||||
|
||||
print <<EOF; |
||||
} |
||||
EOF |
||||
@ -0,0 +1,12 @@ |
||||
// Copyright 2019 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build aix dragonfly freebsd linux netbsd openbsd
|
||||
|
||||
package unix |
||||
|
||||
// ReadDirent reads directory entries from fd and writes them into buf.
|
||||
func ReadDirent(fd int, buf []byte) (n int, err error) { |
||||
return Getdents(fd, buf) |
||||
} |
||||
@ -0,0 +1,19 @@ |
||||
// Copyright 2019 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build darwin
|
||||
|
||||
package unix |
||||
|
||||
import "unsafe" |
||||
|
||||
// ReadDirent reads directory entries from fd and writes them into buf.
|
||||
func ReadDirent(fd int, buf []byte) (n int, err error) { |
||||
// Final argument is (basep *uintptr) and the syscall doesn't take nil.
|
||||
// 64 bits should be enough. (32 bits isn't even on 386). Since the
|
||||
// actual system call is getdirentries64, 64 is a good guess.
|
||||
// TODO(rsc): Can we use a single global basep for all calls?
|
||||
var base = (*uintptr)(unsafe.Pointer(new(uint64))) |
||||
return Getdirentries(fd, buf, base) |
||||
} |
||||
@ -0,0 +1,37 @@ |
||||
// Copyright 2019 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build arm64,openbsd
|
||||
|
||||
package unix |
||||
|
||||
func setTimespec(sec, nsec int64) Timespec { |
||||
return Timespec{Sec: sec, Nsec: nsec} |
||||
} |
||||
|
||||
func setTimeval(sec, usec int64) Timeval { |
||||
return Timeval{Sec: sec, Usec: usec} |
||||
} |
||||
|
||||
func SetKevent(k *Kevent_t, fd, mode, flags int) { |
||||
k.Ident = uint64(fd) |
||||
k.Filter = int16(mode) |
||||
k.Flags = uint16(flags) |
||||
} |
||||
|
||||
func (iov *Iovec) SetLen(length int) { |
||||
iov.Len = uint64(length) |
||||
} |
||||
|
||||
func (msghdr *Msghdr) SetControllen(length int) { |
||||
msghdr.Controllen = uint32(length) |
||||
} |
||||
|
||||
func (cmsg *Cmsghdr) SetLen(length int) { |
||||
cmsg.Len = uint32(length) |
||||
} |
||||
|
||||
// SYS___SYSCTL is used by syscall_bsd.go for all BSDs, but in modern versions
|
||||
// of openbsd/amd64 the syscall is called sysctl instead of __sysctl.
|
||||
const SYS___SYSCTL = SYS_SYSCTL |
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue