Added support for Haystack tracing

This commit is contained in:
Alex Antonov 2019-05-08 17:14:04 -05:00 committed by Traefiker Bot
parent 681892148e
commit 9cf6827ccc
274 changed files with 38070 additions and 13436 deletions

40
Gopkg.lock generated
View file

@ -54,6 +54,14 @@
pruneopts = "NUT" pruneopts = "NUT"
revision = "a368813c5e648fee92e5f6c30e3944ff9d5e8895" revision = "a368813c5e648fee92e5f6c30e3944ff9d5e8895"
[[projects]]
digest = "1:be4a03871fbc5250d19bcbc2d2b21c3c58fd97b048de64ec1ff4c8e3890d4f1b"
name = "github.com/ExpediaDotCom/haystack-client-go"
packages = ["."]
pruneopts = "NUT"
revision = "e7edbdf53a61a82ed143809088ed582312ff7e36"
version = "0.2.3"
[[projects]] [[projects]]
digest = "1:ab7fee312bbdc8070d0325d841de8704cc78bf032b076200f1458659b74b8ed6" digest = "1:ab7fee312bbdc8070d0325d841de8704cc78bf032b076200f1458659b74b8ed6"
name = "github.com/JamesClonk/vultr" name = "github.com/JamesClonk/vultr"
@ -765,7 +773,7 @@
revision = "44145f04b68cf362d9c4df2182967c2275eaefed" revision = "44145f04b68cf362d9c4df2182967c2275eaefed"
[[projects]] [[projects]]
digest = "1:03e14cff610a8a58b774e36bd337fa979482be86aab01be81fb8bbd6d0f07fc8" digest = "1:2d0636a8c490d2272dd725db26f74a537111b99b9dbdda0d8b98febe63702aa4"
name = "github.com/golang/protobuf" name = "github.com/golang/protobuf"
packages = [ packages = [
"proto", "proto",
@ -775,8 +783,8 @@
"ptypes/timestamp", "ptypes/timestamp",
] ]
pruneopts = "NUT" pruneopts = "NUT"
revision = "b4deda0973fb4c70b50d226b1af49f3da59f5265" revision = "b5d812f8a3706043e23a9cd5babf2e5423744d30"
version = "v1.1.0" version = "v1.3.1"
[[projects]] [[projects]]
branch = "master" branch = "master"
@ -1724,15 +1732,14 @@
revision = "ec22f46f877b4505e0117eeaab541714644fdd28" revision = "ec22f46f877b4505e0117eeaab541714644fdd28"
[[projects]] [[projects]]
branch = "master" digest = "1:51bfac9fe01b6a949bfed6db70b00bada281f0d64e5296ec644163aa977bfee0"
digest = "1:4e67fdd7a13cbdb3c0dff0a7505abbdf4f42b12b27da350d66bffdc700db2899"
name = "golang.org/x/sys" name = "golang.org/x/sys"
packages = [ packages = [
"unix", "unix",
"windows", "windows",
] ]
pruneopts = "NUT" pruneopts = "NUT"
revision = "fff93fa7cd278d84afc205751523809c464168ab" revision = "1c9583448a9c3aa0f9a6a5241bf73c0bd8aafded"
[[projects]] [[projects]]
digest = "1:ca9ebfc1200ca7423d9778dba9cdd463704753541c99dc4896f15e0b8b2bf1e8" digest = "1:ca9ebfc1200ca7423d9778dba9cdd463704753541c99dc4896f15e0b8b2bf1e8"
@ -1823,22 +1830,31 @@
revision = "09f6ed296fc66555a25fe4ce95173148778dfa85" revision = "09f6ed296fc66555a25fe4ce95173148778dfa85"
[[projects]] [[projects]]
digest = "1:a840929a3a2d91282dc853cbd5f586069c14ae373247fb7d4cb4fa02b285326e" digest = "1:ffb498178a6bbe5a877e715cc85a40d5a712883d85f5bf05acf26dbd6c8f71e2"
name = "google.golang.org/grpc" name = "google.golang.org/grpc"
packages = [ packages = [
".", ".",
"balancer", "balancer",
"balancer/base", "balancer/base",
"balancer/roundrobin", "balancer/roundrobin",
"channelz", "binarylog/grpc_binarylog_v1",
"codes", "codes",
"connectivity", "connectivity",
"credentials", "credentials",
"credentials/internal",
"encoding", "encoding",
"encoding/proto", "encoding/proto",
"grpclb/grpc_lb_v1/messages",
"grpclog", "grpclog",
"internal", "internal",
"internal/backoff",
"internal/balancerload",
"internal/binarylog",
"internal/channelz",
"internal/envconfig",
"internal/grpcrand",
"internal/grpcsync",
"internal/syscall",
"internal/transport",
"keepalive", "keepalive",
"metadata", "metadata",
"naming", "naming",
@ -1849,11 +1865,10 @@
"stats", "stats",
"status", "status",
"tap", "tap",
"transport",
] ]
pruneopts = "NUT" pruneopts = "NUT"
revision = "41344da2231b913fa3d983840a57a6b1b7b631a1" revision = "25c4f928eaa6d96443009bd842389fb4fa48664e"
version = "v1.12.0" version = "v1.20.1"
[[projects]] [[projects]]
digest = "1:b886012746f19e2a7c6c3901ea9f86e8a5e32ff2b4407086f4f3181269976957" digest = "1:b886012746f19e2a7c6c3901ea9f86e8a5e32ff2b4407086f4f3181269976957"
@ -2215,6 +2230,7 @@
analyzer-version = 1 analyzer-version = 1
input-imports = [ input-imports = [
"github.com/BurntSushi/toml", "github.com/BurntSushi/toml",
"github.com/ExpediaDotCom/haystack-client-go",
"github.com/Masterminds/sprig", "github.com/Masterminds/sprig",
"github.com/NYTimes/gziphandler", "github.com/NYTimes/gziphandler",
"github.com/abbot/go-http-auth", "github.com/abbot/go-http-auth",

View file

@ -198,7 +198,15 @@ required = [
[[constraint]] [[constraint]]
name = "google.golang.org/grpc" name = "google.golang.org/grpc"
version = "1.5.2" version = "1.13.0"
[[override]]
name = "golang.org/x/sys"
revision = "1c9583448a9c3aa0f9a6a5241bf73c0bd8aafded"
[[constraint]]
name = "github.com/golang/protobuf"
version = "v1.3.0"
[[constraint]] [[constraint]]
name = "gopkg.in/fsnotify.v1" name = "gopkg.in/fsnotify.v1"
@ -282,3 +290,7 @@ required = [
[[constraint]] [[constraint]]
name = "github.com/instana/go-sensor" name = "github.com/instana/go-sensor"
version = "1.4.12" version = "1.4.12"
[[constraint]]
name = "github.com/ExpediaDotCom/haystack-client-go"
version = "0.2.3"

View file

@ -18,6 +18,7 @@ import (
"github.com/containous/traefik/pkg/provider/rest" "github.com/containous/traefik/pkg/provider/rest"
"github.com/containous/traefik/pkg/tls" "github.com/containous/traefik/pkg/tls"
"github.com/containous/traefik/pkg/tracing/datadog" "github.com/containous/traefik/pkg/tracing/datadog"
"github.com/containous/traefik/pkg/tracing/haystack"
"github.com/containous/traefik/pkg/tracing/instana" "github.com/containous/traefik/pkg/tracing/instana"
"github.com/containous/traefik/pkg/tracing/jaeger" "github.com/containous/traefik/pkg/tracing/jaeger"
"github.com/containous/traefik/pkg/tracing/zipkin" "github.com/containous/traefik/pkg/tracing/zipkin"
@ -109,13 +110,14 @@ type LifeCycle struct {
// Tracing holds the tracing configuration. // Tracing holds the tracing configuration.
type Tracing struct { type Tracing struct {
Backend string `description:"Selects the tracking backend ('jaeger','zipkin','datadog','instana')." export:"true"` Backend string `description:"Selects the tracking backend ('jaeger','zipkin','datadog','instana')." export:"true"`
ServiceName string `description:"Set the name for this service" export:"true"` ServiceName string `description:"Set the name for this service" export:"true"`
SpanNameLimit int `description:"Set the maximum character limit for Span names (default 0 = no limit)" export:"true"` SpanNameLimit int `description:"Set the maximum character limit for Span names (default 0 = no limit)" export:"true"`
Jaeger *jaeger.Config `description:"Settings for jaeger"` Jaeger *jaeger.Config `description:"Settings for jaeger"`
Zipkin *zipkin.Config `description:"Settings for zipkin"` Zipkin *zipkin.Config `description:"Settings for zipkin"`
DataDog *datadog.Config `description:"Settings for DataDog"` DataDog *datadog.Config `description:"Settings for DataDog"`
Instana *instana.Config `description:"Settings for Instana"` Instana *instana.Config `description:"Settings for Instana"`
Haystack *haystack.Config `description:"Settings for Haystack"`
} }
// Providers contains providers configuration // Providers contains providers configuration

View file

@ -0,0 +1,63 @@
package haystack
import (
"io"
"strings"
"time"
"github.com/ExpediaDotCom/haystack-client-go"
"github.com/containous/traefik/pkg/log"
"github.com/opentracing/opentracing-go"
)
// Name sets the name of this tracer
const Name = "haystack"
// Config provides configuration settings for a haystack tracer
type Config struct {
LocalAgentHost string `description:"Set haystack-agent's host that the reporter will used. Defaults to localhost" export:"false"`
LocalAgentPort int `description:"Set haystack-agent's port that the reporter will used. Defaults to 35000" export:"false"`
GlobalTag string `description:"Key:Value tag to be set on all the spans." export:"true"`
TraceIDHeaderName string `description:"Specifies the header name that will be used to store the trace ID.." export:"true"`
ParentIDHeaderName string `description:"Specifies the header name that will be used to store the parent ID." export:"true"`
SpanIDHeaderName string `description:"Specifies the header name that will be used to store the span ID." export:"true"`
BaggagePrefixHeaderName string `description:"specifies the header name prefix that will be used to store baggage items in a map." export:"true"`
}
// Setup sets up the tracer
func (c *Config) Setup(serviceName string) (opentracing.Tracer, io.Closer, error) {
tag := strings.SplitN(c.GlobalTag, ":", 2)
value := ""
if len(tag) == 2 {
value = tag[1]
}
host := "localhost"
port := 35000
if len(c.LocalAgentHost) > 0 {
host = c.LocalAgentHost
}
if c.LocalAgentPort > 0 {
port = c.LocalAgentPort
}
tracer, closer := haystack.NewTracer(serviceName, haystack.NewAgentDispatcher(host, port, 3*time.Second, 1000),
haystack.TracerOptionsFactory.Tag(tag[0], value),
haystack.TracerOptionsFactory.Propagator(opentracing.HTTPHeaders,
haystack.NewTextMapPropagator(haystack.PropagatorOpts{
TraceIDKEYName: c.TraceIDHeaderName,
ParentSpanIDKEYName: c.ParentIDHeaderName,
SpanIDKEYName: c.SpanIDHeaderName,
BaggagePrefixKEYName: c.BaggagePrefixHeaderName,
}, haystack.DefaultCodex{})),
haystack.TracerOptionsFactory.Logger(&haystackLogger{logger: log.WithoutContext()}),
)
// Without this, child spans are getting the NOOP tracer
opentracing.SetGlobalTracer(tracer)
log.WithoutContext().Debug("DataDog tracer configured")
return tracer, closer, nil
}

View file

@ -0,0 +1,25 @@
package haystack
import (
"github.com/containous/traefik/pkg/log"
)
/*NullLogger does nothing*/
type haystackLogger struct {
logger log.Logger
}
/*Error prints the error message*/
func (l haystackLogger) Error(format string, v ...interface{}) {
l.logger.Errorf(format, v)
}
/*Info prints the info message*/
func (l haystackLogger) Info(format string, v ...interface{}) {
l.logger.Infof(format, v)
}
/*Debug prints the info message*/
func (l haystackLogger) Debug(format string, v ...interface{}) {
l.logger.Debug(format, v)
}

View file

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor 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, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [2018] Expedia Group.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View file

@ -0,0 +1,356 @@
/*
* Copyright 2018 Expedia Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package haystack
import (
"fmt"
"os"
"os/signal"
"time"
"github.com/opentracing/opentracing-go/ext"
"github.com/opentracing/opentracing-go/log"
)
/*Dispatcher dispatches the span object*/
type Dispatcher interface {
Name() string
Dispatch(span *_Span)
DispatchProtoSpan(span *Span)
Close()
SetLogger(logger Logger)
}
/*InMemoryDispatcher implements the Dispatcher interface*/
type InMemoryDispatcher struct {
spans []*_Span
logger Logger
}
/*NewInMemoryDispatcher creates a new in memory dispatcher*/
func NewInMemoryDispatcher() Dispatcher {
return &InMemoryDispatcher{}
}
/*Name gives the Dispatcher name*/
func (d *InMemoryDispatcher) Name() string {
return "InMemoryDispatcher"
}
/*SetLogger sets the logger to use*/
func (d *InMemoryDispatcher) SetLogger(logger Logger) {
d.logger = logger
}
/*Dispatch dispatches the span object*/
func (d *InMemoryDispatcher) Dispatch(span *_Span) {
d.spans = append(d.spans, span)
}
/*DispatchProtoSpan dispatches proto span object*/
func (d *InMemoryDispatcher) DispatchProtoSpan(span *Span) {
/* not implemented */
}
/*Close down the inMemory dispatcher*/
func (d *InMemoryDispatcher) Close() {
d.spans = nil
}
/*FileDispatcher file dispatcher*/
type FileDispatcher struct {
fileHandle *os.File
logger Logger
}
/*NewFileDispatcher creates a new file dispatcher*/
func NewFileDispatcher(filename string) Dispatcher {
fd, err := os.OpenFile(filename, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0644)
if err != nil {
panic(err)
}
return &FileDispatcher{
fileHandle: fd,
}
}
/*Name gives the Dispatcher name*/
func (d *FileDispatcher) Name() string {
return "FileDispatcher"
}
/*SetLogger sets the logger to use*/
func (d *FileDispatcher) SetLogger(logger Logger) {
d.logger = logger
}
/*Dispatch dispatches the span object*/
func (d *FileDispatcher) Dispatch(span *_Span) {
_, err := d.fileHandle.WriteString(span.String() + "\n")
if err != nil {
panic(err)
}
}
/*DispatchProtoSpan dispatches proto span object*/
func (d *FileDispatcher) DispatchProtoSpan(span *Span) {
/* not implemented */
}
/*Close down the file dispatcher*/
func (d *FileDispatcher) Close() {
err := d.fileHandle.Close()
if err != nil {
panic(err)
}
}
/*RemoteDispatcher dispatcher, client can be grpc or http*/
type RemoteDispatcher struct {
client RemoteClient
timeout time.Duration
logger Logger
spanChannel chan *Span
}
/*NewHTTPDispatcher creates a new haystack-agent dispatcher*/
func NewHTTPDispatcher(url string, timeout time.Duration, headers map[string]string, maxQueueLength int) Dispatcher {
dispatcher := &RemoteDispatcher{
client: NewHTTPClient(url, headers, timeout),
timeout: timeout,
spanChannel: make(chan *Span, maxQueueLength),
}
go startListener(dispatcher)
return dispatcher
}
/*NewDefaultHTTPDispatcher creates a new http dispatcher*/
func NewDefaultHTTPDispatcher() Dispatcher {
return NewHTTPDispatcher("http://haystack-collector/span", 3*time.Second, make(map[string](string)), 1000)
}
/*NewAgentDispatcher creates a new haystack-agent dispatcher*/
func NewAgentDispatcher(host string, port int, timeout time.Duration, maxQueueLength int) Dispatcher {
dispatcher := &RemoteDispatcher{
client: NewGrpcClient(host, port, timeout),
timeout: timeout,
spanChannel: make(chan *Span, maxQueueLength),
}
go startListener(dispatcher)
return dispatcher
}
/*NewDefaultAgentDispatcher creates a new haystack-agent dispatcher*/
func NewDefaultAgentDispatcher() Dispatcher {
return NewAgentDispatcher("haystack-agent", 35000, 3*time.Second, 1000)
}
func startListener(dispatcher *RemoteDispatcher) {
signals := make(chan os.Signal, 1)
signal.Notify(signals, os.Interrupt, os.Kill)
for {
select {
case sp := <-dispatcher.spanChannel:
dispatcher.client.Send(sp)
case <-signals:
break
}
}
}
/*Name gives the Dispatcher name*/
func (d *RemoteDispatcher) Name() string {
return "RemoteDispatcher"
}
/*SetLogger sets the logger to use*/
func (d *RemoteDispatcher) SetLogger(logger Logger) {
d.logger = logger
d.client.SetLogger(logger)
}
/*Dispatch dispatches the span object*/
func (d *RemoteDispatcher) Dispatch(span *_Span) {
s := &Span{
TraceId: span.context.TraceID,
SpanId: span.context.SpanID,
ParentSpanId: span.context.ParentID,
ServiceName: span.ServiceName(),
OperationName: span.OperationName(),
StartTime: span.startTime.UnixNano() / int64(time.Microsecond),
Duration: span.duration.Nanoseconds() / int64(time.Microsecond),
Tags: d.tags(span),
Logs: d.logs(span),
}
d.spanChannel <- s
}
/*DispatchProtoSpan dispatches the proto span object*/
func (d *RemoteDispatcher) DispatchProtoSpan(s *Span) {
d.spanChannel <- s
}
func (d *RemoteDispatcher) logs(span *_Span) []*Log {
var spanLogs []*Log
for _, lg := range span.logs {
spanLogs = append(spanLogs, &Log{
Timestamp: lg.Timestamp.UnixNano() / int64(time.Microsecond),
Fields: d.logFieldsToTags(lg.Fields),
})
}
return spanLogs
}
func (d *RemoteDispatcher) logFieldsToTags(fields []log.Field) []*Tag {
var spanTags []*Tag
for _, field := range fields {
spanTags = append(spanTags, ConvertToProtoTag(field.Key(), field.Value()))
}
return spanTags
}
func (d *RemoteDispatcher) tags(span *_Span) []*Tag {
var spanTags []*Tag
for _, tag := range span.tags {
spanTags = append(spanTags, ConvertToProtoTag(tag.Key, tag.Value))
}
return spanTags
}
/*Close down the file dispatcher*/
func (d *RemoteDispatcher) Close() {
err := d.client.Close()
if err != nil {
d.logger.Error("Fail to close the haystack-agent dispatcher %v", err)
}
}
/*ConvertToProtoTag converts to proto tag*/
func ConvertToProtoTag(key string, value interface{}) *Tag {
switch v := value.(type) {
case string:
return &Tag{
Key: key,
Myvalue: &Tag_VStr{
VStr: value.(string),
},
Type: Tag_STRING,
}
case int:
return &Tag{
Key: key,
Myvalue: &Tag_VLong{
VLong: int64(value.(int)),
},
Type: Tag_LONG,
}
case int32:
return &Tag{
Key: key,
Myvalue: &Tag_VLong{
VLong: int64(value.(int32)),
},
Type: Tag_LONG,
}
case int16:
return &Tag{
Key: key,
Myvalue: &Tag_VLong{
VLong: int64(value.(int16)),
},
Type: Tag_LONG,
}
case int64:
return &Tag{
Key: key,
Myvalue: &Tag_VLong{
VLong: value.(int64),
},
Type: Tag_LONG,
}
case uint16:
return &Tag{
Key: key,
Myvalue: &Tag_VLong{
VLong: int64(value.(uint16)),
},
Type: Tag_LONG,
}
case uint32:
return &Tag{
Key: key,
Myvalue: &Tag_VLong{
VLong: int64(value.(uint32)),
},
Type: Tag_LONG,
}
case uint64:
return &Tag{
Key: key,
Myvalue: &Tag_VLong{
VLong: int64(value.(uint64)),
},
Type: Tag_LONG,
}
case float32:
return &Tag{
Key: key,
Myvalue: &Tag_VDouble{
VDouble: float64(value.(float32)),
},
Type: Tag_DOUBLE,
}
case float64:
return &Tag{
Key: key,
Myvalue: &Tag_VDouble{
VDouble: value.(float64),
},
Type: Tag_DOUBLE,
}
case bool:
return &Tag{
Key: key,
Myvalue: &Tag_VBool{
VBool: value.(bool),
},
Type: Tag_BOOL,
}
case []byte:
return &Tag{
Key: key,
Myvalue: &Tag_VBytes{
VBytes: value.([]byte),
},
Type: Tag_BINARY,
}
case ext.SpanKindEnum:
return &Tag{
Key: key,
Myvalue: &Tag_VStr{
VStr: string(value.(ext.SpanKindEnum)),
},
Type: Tag_STRING,
}
default:
panic(fmt.Errorf("unknown format %v", v))
}
}

View file

@ -0,0 +1,37 @@
/*
* Copyright 2018 Expedia Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package haystack
/*Logger defines a new logger interface*/
type Logger interface {
Info(format string, v ...interface{})
Error(format string, v ...interface{})
Debug(format string, v ...interface{})
}
/*NullLogger does nothing*/
type NullLogger struct{}
/*Error prints the error message*/
func (logger NullLogger) Error(format string, v ...interface{}) {}
/*Info prints the info message*/
func (logger NullLogger) Info(format string, v ...interface{}) {}
/*Debug prints the info message*/
func (logger NullLogger) Debug(format string, v ...interface{}) {}

View file

@ -0,0 +1,193 @@
/*
* Copyright 2018 Expedia Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package haystack
import (
"fmt"
"net/url"
"strings"
"github.com/opentracing/opentracing-go"
)
/*Propagator defines the interface for injecting and extracing the SpanContext from the carrier*/
type Propagator interface {
// Inject takes `SpanContext` and injects it into `carrier`
Inject(ctx *SpanContext, carrier interface{}) error
// Extract `SpanContext` from the `carrier`
Extract(carrier interface{}) (*SpanContext, error)
}
/*Codex defines the interface for encoding and decoding the propagated data*/
type Codex interface {
Encode(value string) string
Decode(value string) string
}
/*DefaultCodex is a no op*/
type DefaultCodex struct{}
/*Encode a no-op for encoding the value*/
func (c DefaultCodex) Encode(value string) string { return value }
/*Decode a no-op for decoding the value*/
func (c DefaultCodex) Decode(value string) string { return value }
/*URLCodex encodes decodes a url*/
type URLCodex struct{}
/*Encode a no-op for encoding the value*/
func (c URLCodex) Encode(value string) string { return url.QueryEscape(value) }
/*Decode a no-op for decoding the value*/
func (c URLCodex) Decode(value string) string {
decoded, err := url.QueryUnescape(value)
if err == nil {
return decoded
}
return ""
}
/*PropagatorOpts defines the options need by a propagator*/
type PropagatorOpts struct {
TraceIDKEYName string
SpanIDKEYName string
ParentSpanIDKEYName string
BaggagePrefixKEYName string
}
var defaultPropagatorOpts = PropagatorOpts{}
var defaultCodex = DefaultCodex{}
/*TraceIDKEY returns the trace id key in the propagator*/
func (p *PropagatorOpts) TraceIDKEY() string {
if p.TraceIDKEYName != "" {
return p.TraceIDKEYName
}
return "Trace-ID"
}
/*SpanIDKEY returns the span id key in the propagator*/
func (p *PropagatorOpts) SpanIDKEY() string {
if p.SpanIDKEYName != "" {
return p.SpanIDKEYName
}
return "Span-ID"
}
/*ParentSpanIDKEY returns the parent span id key in the propagator*/
func (p *PropagatorOpts) ParentSpanIDKEY() string {
if p.ParentSpanIDKEYName != "" {
return p.ParentSpanIDKEYName
}
return "Parent-ID"
}
/*BaggageKeyPrefix returns the baggage key prefix*/
func (p *PropagatorOpts) BaggageKeyPrefix() string {
if p.BaggagePrefixKEYName != "" {
return p.BaggagePrefixKEYName
}
return "Baggage-"
}
/*TextMapPropagator implements Propagator interface*/
type TextMapPropagator struct {
opts PropagatorOpts
codex Codex
}
/*Inject injects the span context in the carrier*/
func (p *TextMapPropagator) Inject(ctx *SpanContext, carrier interface{}) error {
textMapWriter, ok := carrier.(opentracing.TextMapWriter)
if !ok {
return opentracing.ErrInvalidCarrier
}
textMapWriter.Set(p.opts.TraceIDKEY(), ctx.TraceID)
textMapWriter.Set(p.opts.SpanIDKEY(), ctx.SpanID)
textMapWriter.Set(p.opts.ParentSpanIDKEY(), ctx.ParentID)
ctx.ForeachBaggageItem(func(key, value string) bool {
textMapWriter.Set(fmt.Sprintf("%s%s", p.opts.BaggageKeyPrefix(), key), p.codex.Encode(ctx.Baggage[key]))
return true
})
return nil
}
/*Extract the span context from the carrier*/
func (p *TextMapPropagator) Extract(carrier interface{}) (*SpanContext, error) {
textMapReader, ok := carrier.(opentracing.TextMapReader)
if !ok {
return nil, opentracing.ErrInvalidCarrier
}
baggageKeyLowerCasePrefix := strings.ToLower(p.opts.BaggageKeyPrefix())
traceIDKeyLowerCase := strings.ToLower(p.opts.TraceIDKEY())
spanIDKeyLowerCase := strings.ToLower(p.opts.SpanIDKEY())
parentSpanIDKeyLowerCase := strings.ToLower(p.opts.ParentSpanIDKEY())
traceID := ""
spanID := ""
parentSpanID := ""
baggage := make(map[string]string)
err := textMapReader.ForeachKey(func(k, v string) error {
lcKey := strings.ToLower(k)
if strings.HasPrefix(lcKey, baggageKeyLowerCasePrefix) {
keySansPrefix := lcKey[len(p.opts.BaggageKeyPrefix()):]
baggage[keySansPrefix] = p.codex.Decode(v)
} else if lcKey == traceIDKeyLowerCase {
traceID = v
} else if lcKey == spanIDKeyLowerCase {
spanID = v
} else if lcKey == parentSpanIDKeyLowerCase {
parentSpanID = v
}
return nil
})
if err != nil {
return nil, err
}
return &SpanContext{
TraceID: traceID,
SpanID: spanID,
ParentID: parentSpanID,
Baggage: baggage,
IsExtractedContext: true,
}, nil
}
/*NewDefaultTextMapPropagator returns a default text map propagator*/
func NewDefaultTextMapPropagator() *TextMapPropagator {
return NewTextMapPropagator(defaultPropagatorOpts, defaultCodex)
}
/*NewTextMapPropagator returns a text map propagator*/
func NewTextMapPropagator(opts PropagatorOpts, codex Codex) *TextMapPropagator {
return &TextMapPropagator{
opts: opts,
codex: codex,
}
}

View file

@ -0,0 +1,165 @@
/*
* Copyright 2018 Expedia Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package haystack
import (
"bytes"
"fmt"
"io/ioutil"
"net/http"
"time"
"github.com/golang/protobuf/proto"
context "golang.org/x/net/context"
grpc "google.golang.org/grpc"
)
/*RemoteClient remote client*/
type RemoteClient interface {
Send(span *Span)
Close() error
SetLogger(logger Logger)
}
/*GrpcClient grpc client*/
type GrpcClient struct {
conn *grpc.ClientConn
client SpanAgentClient
timeout time.Duration
logger Logger
}
/*NewGrpcClient returns a new grpc client*/
func NewGrpcClient(host string, port int, timeout time.Duration) *GrpcClient {
targetHost := fmt.Sprintf("%s:%d", host, port)
conn, err := grpc.Dial(targetHost, grpc.WithInsecure())
if err != nil {
panic(fmt.Sprintf("fail to connect to agent with error: %v", err))
}
return &GrpcClient{
conn: conn,
client: NewSpanAgentClient(conn),
timeout: timeout,
}
}
/*Send a proto span to grpc server*/
func (c *GrpcClient) Send(span *Span) {
ctx, cancel := context.WithTimeout(context.Background(), c.timeout)
defer cancel()
result, err := c.client.Dispatch(ctx, span)
if err != nil {
c.logger.Error("Fail to dispatch to haystack-agent with error %v", err)
} else if result.GetCode() != DispatchResult_SUCCESS {
c.logger.Error(fmt.Sprintf("Fail to dispatch to haystack-agent with error code: %d, message :%s", result.GetCode(), result.GetErrorMessage()))
} else {
c.logger.Debug(fmt.Sprintf("span [%v] has been successfully dispatched to haystack", span))
}
}
/*Close the grpc client*/
func (c *GrpcClient) Close() error {
return c.conn.Close()
}
/*SetLogger sets the logger*/
func (c *GrpcClient) SetLogger(logger Logger) {
c.logger = logger
}
/*HTTPClient a http client*/
type HTTPClient struct {
url string
headers map[string]string
client *http.Client
logger Logger
}
/*NewHTTPClient returns a new http client*/
func NewHTTPClient(url string, headers map[string]string, timeout time.Duration) *HTTPClient {
httpClient := &http.Client{
Timeout: timeout,
}
return &HTTPClient{
url: url,
headers: headers,
client: httpClient,
}
}
/*Send a proto span to http server*/
func (c *HTTPClient) Send(span *Span) {
serializedBytes, marshalErr := proto.Marshal(span)
if marshalErr != nil {
c.logger.Error("Fail to serialize the span to proto bytes, error=%v", marshalErr)
return
}
postRequest, requestErr := http.NewRequest(http.MethodPost, c.url, bytes.NewReader(serializedBytes))
if requestErr != nil {
c.logger.Error("Fail to create request for posting span to haystack server, error=%v", requestErr)
return
}
if c.headers != nil {
for k, v := range c.headers {
postRequest.Header.Add(k, v)
}
}
resp, err := c.client.Do(postRequest)
if err != nil {
c.logger.Error("Fail to dispatch to haystack http server, error=%v", err)
}
defer func() {
closeErr := resp.Body.Close()
if closeErr != nil {
/* do nothing */
}
}()
respBytes, respErr := ioutil.ReadAll(resp.Body)
if respErr != nil {
c.logger.Error("Fail to read the http response from haystack server, error=%v", respErr)
return
}
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
c.logger.Error("Fail to dispatch the span to haystack http server with statusCode=%d , payload=%s", resp.StatusCode, string(respBytes))
} else {
c.logger.Debug(fmt.Sprintf("span [%v] has been successfully dispatched to haystack, response=%s", span, string(respBytes)))
}
}
/*Close the http client*/
func (c *HTTPClient) Close() error {
return nil
}
/*SetLogger sets the logger*/
func (c *HTTPClient) SetLogger(logger Logger) {
c.logger = logger
}

View file

@ -0,0 +1,164 @@
/*
* Copyright 2018 Expedia Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package haystack
import (
"encoding/json"
"time"
"github.com/opentracing/opentracing-go"
"github.com/opentracing/opentracing-go/log"
)
/*_Span implements opentracing.Span*/
type _Span struct {
tracer *Tracer
context *SpanContext
operationName string
// startTime is the timestamp indicating when the span began, with microseconds precision.
startTime time.Time
// duration returns duration of the span with microseconds precision.
duration time.Duration
tags []opentracing.Tag
logs []opentracing.LogRecord
}
// SetOperationName sets or changes the operation name.
func (span *_Span) SetOperationName(operationName string) opentracing.Span {
span.operationName = operationName
return span
}
// SetTag implements SetTag() of opentracing.Span
func (span *_Span) SetTag(key string, value interface{}) opentracing.Span {
span.tags = append(span.tags,
opentracing.Tag{
Key: key,
Value: value,
})
return span
}
// LogFields implements opentracing.Span API
func (span *_Span) LogFields(fields ...log.Field) {
log := opentracing.LogRecord{
Fields: fields,
Timestamp: time.Now(),
}
span.logs = append(span.logs, log)
}
// LogKV implements opentracing.Span API
func (span *_Span) LogKV(alternatingKeyValues ...interface{}) {
fields, err := log.InterleavedKVToFields(alternatingKeyValues...)
if err != nil {
span.LogFields(log.Error(err), log.String("function", "LogKV"))
return
}
span.LogFields(fields...)
}
// LogEvent implements opentracing.Span API
func (span *_Span) LogEvent(event string) {
span.Log(opentracing.LogData{Event: event})
}
// LogEventWithPayload implements opentracing.Span API
func (span *_Span) LogEventWithPayload(event string, payload interface{}) {
span.Log(opentracing.LogData{Event: event, Payload: payload})
}
// Log implements opentracing.Span API
func (span *_Span) Log(ld opentracing.LogData) {
span.logs = append(span.logs, ld.ToLogRecord())
}
// SetBaggageItem implements SetBaggageItem() of opentracing.SpanContext
func (span *_Span) SetBaggageItem(key, value string) opentracing.Span {
span.context = span.context.WithBaggageItem(key, value)
span.LogFields(log.String("event", "baggage"), log.String("payload", key), log.String("payload", value))
return span
}
// BaggageItem implements BaggageItem() of opentracing.SpanContext
func (span *_Span) BaggageItem(key string) string {
return span.context.Baggage[key]
}
// Finish implements opentracing.Span API
func (span *_Span) Finish() {
span.FinishWithOptions(opentracing.FinishOptions{})
}
// FinishWithOptions implements opentracing.Span API
func (span *_Span) FinishWithOptions(options opentracing.FinishOptions) {
if options.FinishTime.IsZero() {
options.FinishTime = span.tracer.timeNow()
}
span.duration = options.FinishTime.Sub(span.startTime)
if options.LogRecords != nil {
span.logs = append(span.logs, options.LogRecords...)
}
for _, ld := range options.BulkLogData {
span.logs = append(span.logs, ld.ToLogRecord())
}
span.tracer.DispatchSpan(span)
}
// Context implements opentracing.Span API
func (span *_Span) Context() opentracing.SpanContext {
return span.context
}
/*Tracer returns the tracer*/
func (span *_Span) Tracer() opentracing.Tracer {
return span.tracer
}
/*OperationName allows retrieving current operation name*/
func (span *_Span) OperationName() string {
return span.operationName
}
/*ServiceName returns the name of the service*/
func (span *_Span) ServiceName() string {
return span.tracer.serviceName
}
func (span *_Span) String() string {
data, err := json.Marshal(map[string]interface{}{
"traceId": span.context.TraceID,
"spanId": span.context.SpanID,
"parentSpanId": span.context.ParentID,
"operationName": span.OperationName(),
"serviceName": span.ServiceName(),
"tags": span.Tags(),
"logs": span.logs,
})
if err != nil {
panic(err)
}
return string(data)
}
func (span *_Span) Tags() []opentracing.Tag {
return span.tags
}

View file

@ -0,0 +1,433 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: span.proto
package haystack
import (
fmt "fmt"
proto "github.com/golang/protobuf/proto"
math "math"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
// TagType denotes the type of a Tag's value.
type Tag_TagType int32
const (
Tag_STRING Tag_TagType = 0
Tag_DOUBLE Tag_TagType = 1
Tag_BOOL Tag_TagType = 2
Tag_LONG Tag_TagType = 3
Tag_BINARY Tag_TagType = 4
)
var Tag_TagType_name = map[int32]string{
0: "STRING",
1: "DOUBLE",
2: "BOOL",
3: "LONG",
4: "BINARY",
}
var Tag_TagType_value = map[string]int32{
"STRING": 0,
"DOUBLE": 1,
"BOOL": 2,
"LONG": 3,
"BINARY": 4,
}
func (x Tag_TagType) String() string {
return proto.EnumName(Tag_TagType_name, int32(x))
}
func (Tag_TagType) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_fc5f2b88b579999f, []int{2, 0}
}
// Span represents a unit of work performed by a service.
type Span struct {
TraceId string `protobuf:"bytes,1,opt,name=traceId,proto3" json:"traceId,omitempty"`
SpanId string `protobuf:"bytes,2,opt,name=spanId,proto3" json:"spanId,omitempty"`
ParentSpanId string `protobuf:"bytes,3,opt,name=parentSpanId,proto3" json:"parentSpanId,omitempty"`
ServiceName string `protobuf:"bytes,4,opt,name=serviceName,proto3" json:"serviceName,omitempty"`
OperationName string `protobuf:"bytes,5,opt,name=operationName,proto3" json:"operationName,omitempty"`
StartTime int64 `protobuf:"varint,6,opt,name=startTime,proto3" json:"startTime,omitempty"`
Duration int64 `protobuf:"varint,7,opt,name=duration,proto3" json:"duration,omitempty"`
Logs []*Log `protobuf:"bytes,8,rep,name=logs,proto3" json:"logs,omitempty"`
Tags []*Tag `protobuf:"bytes,9,rep,name=tags,proto3" json:"tags,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *Span) Reset() { *m = Span{} }
func (m *Span) String() string { return proto.CompactTextString(m) }
func (*Span) ProtoMessage() {}
func (*Span) Descriptor() ([]byte, []int) {
return fileDescriptor_fc5f2b88b579999f, []int{0}
}
func (m *Span) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Span.Unmarshal(m, b)
}
func (m *Span) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_Span.Marshal(b, m, deterministic)
}
func (m *Span) XXX_Merge(src proto.Message) {
xxx_messageInfo_Span.Merge(m, src)
}
func (m *Span) XXX_Size() int {
return xxx_messageInfo_Span.Size(m)
}
func (m *Span) XXX_DiscardUnknown() {
xxx_messageInfo_Span.DiscardUnknown(m)
}
var xxx_messageInfo_Span proto.InternalMessageInfo
func (m *Span) GetTraceId() string {
if m != nil {
return m.TraceId
}
return ""
}
func (m *Span) GetSpanId() string {
if m != nil {
return m.SpanId
}
return ""
}
func (m *Span) GetParentSpanId() string {
if m != nil {
return m.ParentSpanId
}
return ""
}
func (m *Span) GetServiceName() string {
if m != nil {
return m.ServiceName
}
return ""
}
func (m *Span) GetOperationName() string {
if m != nil {
return m.OperationName
}
return ""
}
func (m *Span) GetStartTime() int64 {
if m != nil {
return m.StartTime
}
return 0
}
func (m *Span) GetDuration() int64 {
if m != nil {
return m.Duration
}
return 0
}
func (m *Span) GetLogs() []*Log {
if m != nil {
return m.Logs
}
return nil
}
func (m *Span) GetTags() []*Tag {
if m != nil {
return m.Tags
}
return nil
}
// Log is a timestamped event with a set of tags.
type Log struct {
Timestamp int64 `protobuf:"varint,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
Fields []*Tag `protobuf:"bytes,2,rep,name=fields,proto3" json:"fields,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *Log) Reset() { *m = Log{} }
func (m *Log) String() string { return proto.CompactTextString(m) }
func (*Log) ProtoMessage() {}
func (*Log) Descriptor() ([]byte, []int) {
return fileDescriptor_fc5f2b88b579999f, []int{1}
}
func (m *Log) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Log.Unmarshal(m, b)
}
func (m *Log) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_Log.Marshal(b, m, deterministic)
}
func (m *Log) XXX_Merge(src proto.Message) {
xxx_messageInfo_Log.Merge(m, src)
}
func (m *Log) XXX_Size() int {
return xxx_messageInfo_Log.Size(m)
}
func (m *Log) XXX_DiscardUnknown() {
xxx_messageInfo_Log.DiscardUnknown(m)
}
var xxx_messageInfo_Log proto.InternalMessageInfo
func (m *Log) GetTimestamp() int64 {
if m != nil {
return m.Timestamp
}
return 0
}
func (m *Log) GetFields() []*Tag {
if m != nil {
return m.Fields
}
return nil
}
// Tag is a strongly typed key/value pair. We use 'oneof' protobuf attribute to represent the possible tagTypes
type Tag struct {
Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
Type Tag_TagType `protobuf:"varint,2,opt,name=type,proto3,enum=Tag_TagType" json:"type,omitempty"`
// Types that are valid to be assigned to Myvalue:
// *Tag_VStr
// *Tag_VLong
// *Tag_VDouble
// *Tag_VBool
// *Tag_VBytes
Myvalue isTag_Myvalue `protobuf_oneof:"myvalue"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *Tag) Reset() { *m = Tag{} }
func (m *Tag) String() string { return proto.CompactTextString(m) }
func (*Tag) ProtoMessage() {}
func (*Tag) Descriptor() ([]byte, []int) {
return fileDescriptor_fc5f2b88b579999f, []int{2}
}
func (m *Tag) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Tag.Unmarshal(m, b)
}
func (m *Tag) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_Tag.Marshal(b, m, deterministic)
}
func (m *Tag) XXX_Merge(src proto.Message) {
xxx_messageInfo_Tag.Merge(m, src)
}
func (m *Tag) XXX_Size() int {
return xxx_messageInfo_Tag.Size(m)
}
func (m *Tag) XXX_DiscardUnknown() {
xxx_messageInfo_Tag.DiscardUnknown(m)
}
var xxx_messageInfo_Tag proto.InternalMessageInfo
func (m *Tag) GetKey() string {
if m != nil {
return m.Key
}
return ""
}
func (m *Tag) GetType() Tag_TagType {
if m != nil {
return m.Type
}
return Tag_STRING
}
type isTag_Myvalue interface {
isTag_Myvalue()
}
type Tag_VStr struct {
VStr string `protobuf:"bytes,3,opt,name=vStr,proto3,oneof"`
}
type Tag_VLong struct {
VLong int64 `protobuf:"varint,4,opt,name=vLong,proto3,oneof"`
}
type Tag_VDouble struct {
VDouble float64 `protobuf:"fixed64,5,opt,name=vDouble,proto3,oneof"`
}
type Tag_VBool struct {
VBool bool `protobuf:"varint,6,opt,name=vBool,proto3,oneof"`
}
type Tag_VBytes struct {
VBytes []byte `protobuf:"bytes,7,opt,name=vBytes,proto3,oneof"`
}
func (*Tag_VStr) isTag_Myvalue() {}
func (*Tag_VLong) isTag_Myvalue() {}
func (*Tag_VDouble) isTag_Myvalue() {}
func (*Tag_VBool) isTag_Myvalue() {}
func (*Tag_VBytes) isTag_Myvalue() {}
func (m *Tag) GetMyvalue() isTag_Myvalue {
if m != nil {
return m.Myvalue
}
return nil
}
func (m *Tag) GetVStr() string {
if x, ok := m.GetMyvalue().(*Tag_VStr); ok {
return x.VStr
}
return ""
}
func (m *Tag) GetVLong() int64 {
if x, ok := m.GetMyvalue().(*Tag_VLong); ok {
return x.VLong
}
return 0
}
func (m *Tag) GetVDouble() float64 {
if x, ok := m.GetMyvalue().(*Tag_VDouble); ok {
return x.VDouble
}
return 0
}
func (m *Tag) GetVBool() bool {
if x, ok := m.GetMyvalue().(*Tag_VBool); ok {
return x.VBool
}
return false
}
func (m *Tag) GetVBytes() []byte {
if x, ok := m.GetMyvalue().(*Tag_VBytes); ok {
return x.VBytes
}
return nil
}
// XXX_OneofWrappers is for the internal use of the proto package.
func (*Tag) XXX_OneofWrappers() []interface{} {
return []interface{}{
(*Tag_VStr)(nil),
(*Tag_VLong)(nil),
(*Tag_VDouble)(nil),
(*Tag_VBool)(nil),
(*Tag_VBytes)(nil),
}
}
// You can optionally use Batch to send a collection of spans. Spans may not necessarily belong to one traceId.
type Batch struct {
Spans []*Span `protobuf:"bytes,1,rep,name=spans,proto3" json:"spans,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *Batch) Reset() { *m = Batch{} }
func (m *Batch) String() string { return proto.CompactTextString(m) }
func (*Batch) ProtoMessage() {}
func (*Batch) Descriptor() ([]byte, []int) {
return fileDescriptor_fc5f2b88b579999f, []int{3}
}
func (m *Batch) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Batch.Unmarshal(m, b)
}
func (m *Batch) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_Batch.Marshal(b, m, deterministic)
}
func (m *Batch) XXX_Merge(src proto.Message) {
xxx_messageInfo_Batch.Merge(m, src)
}
func (m *Batch) XXX_Size() int {
return xxx_messageInfo_Batch.Size(m)
}
func (m *Batch) XXX_DiscardUnknown() {
xxx_messageInfo_Batch.DiscardUnknown(m)
}
var xxx_messageInfo_Batch proto.InternalMessageInfo
func (m *Batch) GetSpans() []*Span {
if m != nil {
return m.Spans
}
return nil
}
func init() {
proto.RegisterEnum("Tag_TagType", Tag_TagType_name, Tag_TagType_value)
proto.RegisterType((*Span)(nil), "Span")
proto.RegisterType((*Log)(nil), "Log")
proto.RegisterType((*Tag)(nil), "Tag")
proto.RegisterType((*Batch)(nil), "Batch")
}
func init() { proto.RegisterFile("span.proto", fileDescriptor_fc5f2b88b579999f) }
var fileDescriptor_fc5f2b88b579999f = []byte{
// 456 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x54, 0x92, 0xcd, 0x8a, 0x9c, 0x40,
0x14, 0x85, 0xdb, 0xf6, 0xb7, 0xef, 0x74, 0x82, 0x14, 0x61, 0x28, 0x26, 0xb3, 0x10, 0x19, 0x42,
0xaf, 0x5c, 0x4c, 0x9e, 0xa0, 0x65, 0xc2, 0x74, 0x83, 0x74, 0x87, 0x6a, 0xb3, 0x48, 0x76, 0x35,
0x5a, 0x71, 0x64, 0xd4, 0x2a, 0xac, 0x6a, 0x89, 0xeb, 0xbc, 0x41, 0x9e, 0x38, 0x54, 0xe9, 0xfc,
0x2d, 0x84, 0x7b, 0xbe, 0x73, 0xaf, 0xca, 0xe1, 0x00, 0x48, 0x41, 0xbb, 0x44, 0xf4, 0x5c, 0xf1,
0xf8, 0xdf, 0x12, 0x9c, 0x93, 0xa0, 0x1d, 0xc2, 0xe0, 0xab, 0x9e, 0x16, 0x6c, 0x5f, 0x62, 0x2b,
0xb2, 0x36, 0x2b, 0xf2, 0x2c, 0xd1, 0x25, 0x78, 0xfa, 0x60, 0x5f, 0xe2, 0xa5, 0x31, 0x66, 0x85,
0x62, 0x58, 0x0b, 0xda, 0xb3, 0x4e, 0x9d, 0x26, 0xd7, 0x36, 0xee, 0x3b, 0x86, 0x22, 0xb8, 0x90,
0xac, 0x1f, 0xea, 0x82, 0x1d, 0x68, 0xcb, 0xb0, 0x63, 0x56, 0xde, 0x22, 0x74, 0x03, 0x1f, 0xb8,
0x60, 0x3d, 0x55, 0x35, 0xef, 0xcc, 0x8e, 0x6b, 0x76, 0xde, 0x43, 0x74, 0x0d, 0x2b, 0xa9, 0x68,
0xaf, 0xf2, 0xba, 0x65, 0xd8, 0x8b, 0xac, 0x8d, 0x4d, 0x5e, 0x01, 0xba, 0x82, 0xa0, 0x3c, 0x4f,
0xdb, 0xd8, 0x37, 0xe6, 0x8b, 0x46, 0x18, 0x9c, 0x86, 0x57, 0x12, 0x07, 0x91, 0xbd, 0xb9, 0xb8,
0x75, 0x92, 0x8c, 0x57, 0xc4, 0x10, 0xed, 0x28, 0x5a, 0x49, 0xbc, 0x9a, 0x9d, 0x9c, 0x56, 0xc4,
0x90, 0x78, 0x0b, 0x76, 0xc6, 0x2b, 0xfd, 0x51, 0x55, 0xb7, 0x4c, 0x2a, 0xda, 0x0a, 0x13, 0x8a,
0x4d, 0x5e, 0x01, 0xba, 0x06, 0xef, 0x77, 0xcd, 0x9a, 0x52, 0xe2, 0xe5, 0x9b, 0x17, 0xcc, 0x2c,
0xfe, 0xbb, 0x04, 0x3b, 0xa7, 0x15, 0x0a, 0xc1, 0x7e, 0x62, 0xe3, 0x1c, 0xa9, 0x1e, 0x51, 0x04,
0x8e, 0x1a, 0x05, 0x33, 0x61, 0x7e, 0xbc, 0x5d, 0xeb, 0x2b, 0xfd, 0xe4, 0xa3, 0x60, 0xc4, 0x38,
0xe8, 0x13, 0x38, 0xc3, 0x49, 0xf5, 0x53, 0xa0, 0xbb, 0x05, 0x31, 0x0a, 0x5d, 0x82, 0x3b, 0x64,
0xbc, 0xab, 0x4c, 0x88, 0xf6, 0x6e, 0x41, 0x26, 0x89, 0xae, 0xc0, 0x1f, 0xee, 0xf8, 0xf9, 0xa1,
0x99, 0xa2, 0xb3, 0x76, 0x0b, 0xf2, 0x0c, 0xcc, 0x4d, 0xca, 0x79, 0x63, 0x22, 0x0b, 0xcc, 0x8d,
0x96, 0x08, 0x83, 0x37, 0xa4, 0xa3, 0x62, 0xd2, 0xc4, 0xb5, 0xde, 0x2d, 0xc8, 0xac, 0xe3, 0x2d,
0xf8, 0xf3, 0xcf, 0x20, 0x00, 0xef, 0x94, 0x93, 0xfd, 0xe1, 0x3e, 0x5c, 0xe8, 0xf9, 0xee, 0xf8,
0x23, 0xcd, 0xbe, 0x85, 0x16, 0x0a, 0xc0, 0x49, 0x8f, 0xc7, 0x2c, 0x5c, 0xea, 0x29, 0x3b, 0x1e,
0xee, 0x43, 0x5b, 0xfb, 0xe9, 0xfe, 0xb0, 0x25, 0x3f, 0x43, 0x27, 0x5d, 0x81, 0xdf, 0x8e, 0x03,
0x6d, 0xce, 0x2c, 0xbe, 0x01, 0x37, 0xa5, 0xaa, 0x78, 0x44, 0x9f, 0xc1, 0xd5, 0xad, 0x91, 0xd8,
0x32, 0x59, 0xb9, 0x89, 0xee, 0x07, 0x99, 0x58, 0xfa, 0x05, 0x70, 0xc1, 0xdb, 0x84, 0xfd, 0x11,
0xac, 0xac, 0x69, 0xc2, 0x05, 0xeb, 0x12, 0x5d, 0xbe, 0xba, 0xab, 0xbe, 0x5b, 0xbf, 0x82, 0x47,
0x3a, 0x4a, 0x45, 0x8b, 0xa7, 0x07, 0xcf, 0x54, 0xf6, 0xeb, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
0xdd, 0x60, 0xee, 0x6b, 0xc0, 0x02, 0x00, 0x00,
}

View file

@ -0,0 +1,197 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: spanAgent.proto
package haystack
import (
context "context"
fmt "fmt"
proto "github.com/golang/protobuf/proto"
grpc "google.golang.org/grpc"
math "math"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
type DispatchResult_ResultCode int32
const (
DispatchResult_SUCCESS DispatchResult_ResultCode = 0
DispatchResult_UNKNOWN_ERROR DispatchResult_ResultCode = 1
DispatchResult_RATE_LIMIT_ERROR DispatchResult_ResultCode = 2
)
var DispatchResult_ResultCode_name = map[int32]string{
0: "SUCCESS",
1: "UNKNOWN_ERROR",
2: "RATE_LIMIT_ERROR",
}
var DispatchResult_ResultCode_value = map[string]int32{
"SUCCESS": 0,
"UNKNOWN_ERROR": 1,
"RATE_LIMIT_ERROR": 2,
}
func (x DispatchResult_ResultCode) String() string {
return proto.EnumName(DispatchResult_ResultCode_name, int32(x))
}
func (DispatchResult_ResultCode) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_5a4cb81dd7dcc459, []int{0, 0}
}
type DispatchResult struct {
Code DispatchResult_ResultCode `protobuf:"varint,1,opt,name=code,proto3,enum=DispatchResult_ResultCode" json:"code,omitempty"`
ErrorMessage string `protobuf:"bytes,2,opt,name=error_message,json=errorMessage,proto3" json:"error_message,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *DispatchResult) Reset() { *m = DispatchResult{} }
func (m *DispatchResult) String() string { return proto.CompactTextString(m) }
func (*DispatchResult) ProtoMessage() {}
func (*DispatchResult) Descriptor() ([]byte, []int) {
return fileDescriptor_5a4cb81dd7dcc459, []int{0}
}
func (m *DispatchResult) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_DispatchResult.Unmarshal(m, b)
}
func (m *DispatchResult) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_DispatchResult.Marshal(b, m, deterministic)
}
func (m *DispatchResult) XXX_Merge(src proto.Message) {
xxx_messageInfo_DispatchResult.Merge(m, src)
}
func (m *DispatchResult) XXX_Size() int {
return xxx_messageInfo_DispatchResult.Size(m)
}
func (m *DispatchResult) XXX_DiscardUnknown() {
xxx_messageInfo_DispatchResult.DiscardUnknown(m)
}
var xxx_messageInfo_DispatchResult proto.InternalMessageInfo
func (m *DispatchResult) GetCode() DispatchResult_ResultCode {
if m != nil {
return m.Code
}
return DispatchResult_SUCCESS
}
func (m *DispatchResult) GetErrorMessage() string {
if m != nil {
return m.ErrorMessage
}
return ""
}
func init() {
proto.RegisterEnum("DispatchResult_ResultCode", DispatchResult_ResultCode_name, DispatchResult_ResultCode_value)
proto.RegisterType((*DispatchResult)(nil), "DispatchResult")
}
func init() { proto.RegisterFile("spanAgent.proto", fileDescriptor_5a4cb81dd7dcc459) }
var fileDescriptor_5a4cb81dd7dcc459 = []byte{
// 254 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x5c, 0x90, 0xc1, 0x4a, 0xf3, 0x40,
0x10, 0xc7, 0xbf, 0x2d, 0x9f, 0xda, 0x8e, 0xb6, 0x8d, 0x8b, 0x87, 0x92, 0x53, 0x89, 0x97, 0x9e,
0x56, 0xa9, 0x4f, 0xd0, 0xc6, 0x1c, 0x8a, 0x36, 0x95, 0x4d, 0x8b, 0xe0, 0x25, 0x8c, 0x9b, 0x21,
0x0d, 0xda, 0xec, 0xb2, 0xbb, 0x82, 0x3e, 0x92, 0x6f, 0x29, 0x4d, 0x2a, 0xa2, 0xa7, 0x19, 0x7e,
0x33, 0x03, 0xff, 0xf9, 0xc1, 0xd0, 0x19, 0xac, 0x67, 0x25, 0xd5, 0x5e, 0x18, 0xab, 0xbd, 0x0e,
0x61, 0x0f, 0xda, 0x3e, 0xfa, 0x64, 0x30, 0xb8, 0xad, 0x9c, 0x41, 0xaf, 0xb6, 0x92, 0xdc, 0xdb,
0xab, 0xe7, 0x02, 0xfe, 0x2b, 0x5d, 0xd0, 0x88, 0x8d, 0xd9, 0x64, 0x30, 0x0d, 0xc5, 0xef, 0xb1,
0x68, 0x4b, 0xac, 0x0b, 0x92, 0xcd, 0x1e, 0xbf, 0x84, 0x3e, 0x59, 0xab, 0x6d, 0xbe, 0x23, 0xe7,
0xb0, 0xa4, 0x51, 0x67, 0xcc, 0x26, 0x3d, 0x79, 0xd6, 0xc0, 0x65, 0xcb, 0xa2, 0x39, 0xc0, 0xcf,
0x21, 0x3f, 0x85, 0x93, 0x6c, 0x13, 0xc7, 0x49, 0x96, 0x05, 0xff, 0xf8, 0x39, 0xf4, 0x37, 0xe9,
0x5d, 0xba, 0x7a, 0x4c, 0xf3, 0x44, 0xca, 0x95, 0x0c, 0x18, 0xbf, 0x80, 0x40, 0xce, 0xd6, 0x49,
0x7e, 0xbf, 0x58, 0x2e, 0xd6, 0x07, 0xda, 0x99, 0x5e, 0x41, 0x2f, 0xfb, 0x7e, 0x85, 0x47, 0xd0,
0x2d, 0x0e, 0xc1, 0xf8, 0x91, 0xd8, 0xf3, 0x70, 0xf8, 0x27, 0xea, 0xfc, 0x1a, 0x22, 0xa5, 0x77,
0x82, 0xde, 0x0d, 0x15, 0x15, 0x0a, 0x6d, 0xa8, 0x16, 0xde, 0xa2, 0xaa, 0xea, 0x52, 0x60, 0x23,
0x04, 0x4d, 0xf5, 0xc0, 0x9e, 0xba, 0x5b, 0xfc, 0x70, 0x1e, 0xd5, 0xcb, 0xf3, 0x71, 0x63, 0xe5,
0xe6, 0x2b, 0x00, 0x00, 0xff, 0xff, 0x30, 0xb9, 0x7d, 0x07, 0x34, 0x01, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConn
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion4
// SpanAgentClient is the client API for SpanAgent service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type SpanAgentClient interface {
Dispatch(ctx context.Context, in *Span, opts ...grpc.CallOption) (*DispatchResult, error)
}
type spanAgentClient struct {
cc *grpc.ClientConn
}
func NewSpanAgentClient(cc *grpc.ClientConn) SpanAgentClient {
return &spanAgentClient{cc}
}
func (c *spanAgentClient) Dispatch(ctx context.Context, in *Span, opts ...grpc.CallOption) (*DispatchResult, error) {
out := new(DispatchResult)
err := c.cc.Invoke(ctx, "/SpanAgent/dispatch", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// SpanAgentServer is the server API for SpanAgent service.
type SpanAgentServer interface {
Dispatch(context.Context, *Span) (*DispatchResult, error)
}
func RegisterSpanAgentServer(s *grpc.Server, srv SpanAgentServer) {
s.RegisterService(&_SpanAgent_serviceDesc, srv)
}
func _SpanAgent_Dispatch_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(Span)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(SpanAgentServer).Dispatch(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/SpanAgent/Dispatch",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SpanAgentServer).Dispatch(ctx, req.(*Span))
}
return interceptor(ctx, in, info, handler)
}
var _SpanAgent_serviceDesc = grpc.ServiceDesc{
ServiceName: "SpanAgent",
HandlerType: (*SpanAgentServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "dispatch",
Handler: _SpanAgent_Dispatch_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "spanAgent.proto",
}

View file

@ -0,0 +1,80 @@
/*
* Copyright 2018 Expedia Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package haystack
import (
"fmt"
)
/*SpanContext implements opentracing.spanContext*/
type SpanContext struct {
// traceID represents globally unique ID of the trace.
TraceID string
// spanID represents span ID that must be unique within its trace
SpanID string
// parentID refers to the ID of the parent span.
// Should be empty if the current span is a root span.
ParentID string
//Context baggage. The is a snapshot in time.
Baggage map[string]string
// set to true if extracted using a extractor in tracer
IsExtractedContext bool
}
// IsValid indicates whether this context actually represents a valid trace.
func (context SpanContext) IsValid() bool {
return context.TraceID != "" && context.SpanID != ""
}
/*ForeachBaggageItem implements opentracing.spancontext*/
func (context SpanContext) ForeachBaggageItem(handler func(k, v string) bool) {
for k, v := range context.Baggage {
if !handler(k, v) {
break
}
}
}
// WithBaggageItem creates a new context with an extra baggage item.
func (context SpanContext) WithBaggageItem(key, value string) *SpanContext {
var newBaggage map[string]string
if context.Baggage == nil {
newBaggage = map[string]string{key: value}
} else {
newBaggage = make(map[string]string, len(context.Baggage)+1)
for k, v := range context.Baggage {
newBaggage[k] = v
}
newBaggage[key] = value
}
return &SpanContext{
TraceID: context.TraceID,
SpanID: context.SpanID,
ParentID: context.ParentID,
Baggage: newBaggage,
}
}
/*ToString represents the string*/
func (context SpanContext) ToString() string {
return fmt.Sprintf("%+v", context)
}

View file

@ -0,0 +1,214 @@
/*
* Copyright 2018 Expedia Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package haystack
import (
"io"
"time"
"github.com/google/uuid"
"github.com/opentracing/opentracing-go"
"github.com/opentracing/opentracing-go/ext"
)
/*Tracer implements the opentracing.tracer*/
type Tracer struct {
serviceName string
logger Logger
dispatcher Dispatcher
commonTags []opentracing.Tag
timeNow func() time.Time
idGenerator func() string
propagators map[interface{}]Propagator
useDualSpanMode bool
}
/*NewTracer creates a new tracer*/
func NewTracer(
serviceName string,
dispatcher Dispatcher,
options ...TracerOption,
) (opentracing.Tracer, io.Closer) {
tracer := &Tracer{
serviceName: serviceName,
dispatcher: dispatcher,
useDualSpanMode: false,
}
tracer.propagators = make(map[interface{}]Propagator)
tracer.propagators[opentracing.TextMap] = NewDefaultTextMapPropagator()
tracer.propagators[opentracing.HTTPHeaders] = NewTextMapPropagator(PropagatorOpts{}, URLCodex{})
for _, option := range options {
option(tracer)
}
if tracer.timeNow == nil {
tracer.timeNow = time.Now
}
if tracer.logger == nil {
tracer.logger = NullLogger{}
}
if tracer.idGenerator == nil {
tracer.idGenerator = func() string {
_uuid, err := uuid.NewUUID()
if err != nil {
panic(err)
}
return _uuid.String()
}
}
dispatcher.SetLogger(tracer.logger)
return tracer, tracer
}
/*StartSpan starts a new span*/
func (tracer *Tracer) StartSpan(
operationName string,
options ...opentracing.StartSpanOption,
) opentracing.Span {
sso := opentracing.StartSpanOptions{}
for _, o := range options {
o.Apply(&sso)
}
if sso.StartTime.IsZero() {
sso.StartTime = tracer.timeNow()
}
var followsFromIsParent = false
var parent *SpanContext
for _, ref := range sso.References {
if ref.Type == opentracing.ChildOfRef {
if parent == nil || followsFromIsParent {
parent = ref.ReferencedContext.(*SpanContext)
}
} else if ref.Type == opentracing.FollowsFromRef {
if parent == nil {
parent = ref.ReferencedContext.(*SpanContext)
followsFromIsParent = true
}
}
}
spanContext := tracer.createSpanContext(parent, tracer.isServerSpan(sso.Tags))
span := &_Span{
tracer: tracer,
context: spanContext,
operationName: operationName,
startTime: sso.StartTime,
duration: 0,
}
for _, tag := range tracer.Tags() {
span.SetTag(tag.Key, tag.Value)
}
for k, v := range sso.Tags {
span.SetTag(k, v)
}
return span
}
func (tracer *Tracer) isServerSpan(spanTags map[string]interface{}) bool {
if spanKind, ok := spanTags[string(ext.SpanKind)]; ok && spanKind == "server" {
return true
}
return false
}
func (tracer *Tracer) createSpanContext(parent *SpanContext, isServerSpan bool) *SpanContext {
if parent == nil || !parent.IsValid() {
return &SpanContext{
TraceID: tracer.idGenerator(),
SpanID: tracer.idGenerator(),
}
}
// This is a check to see if the tracer is configured to support single
// single span type (Zipkin style shared span id) or
// dual span type (client and server having their own span ids ).
// a. If tracer is not of dualSpanType and if it is a server span then we
// just return the parent context with the same shared span ids
// b. If tracer is not of dualSpanType and if the parent context is an extracted one from the wire
// then we assume this is the first span in the server and so just return the parent context
// with the same shared span ids
if !tracer.useDualSpanMode && (isServerSpan || parent.IsExtractedContext) {
return &SpanContext{
TraceID: parent.TraceID,
SpanID: parent.SpanID,
ParentID: parent.ParentID,
Baggage: parent.Baggage,
IsExtractedContext: false,
}
}
return &SpanContext{
TraceID: parent.TraceID,
SpanID: tracer.idGenerator(),
ParentID: parent.SpanID,
Baggage: parent.Baggage,
IsExtractedContext: false,
}
}
/*Inject implements Inject() method of opentracing.Tracer*/
func (tracer *Tracer) Inject(ctx opentracing.SpanContext, format interface{}, carrier interface{}) error {
c, ok := ctx.(*SpanContext)
if !ok {
return opentracing.ErrInvalidSpanContext
}
if injector, ok := tracer.propagators[format]; ok {
return injector.Inject(c, carrier)
}
return opentracing.ErrUnsupportedFormat
}
/*Extract implements Extract() method of opentracing.Tracer*/
func (tracer *Tracer) Extract(
format interface{},
carrier interface{},
) (opentracing.SpanContext, error) {
if extractor, ok := tracer.propagators[format]; ok {
return extractor.Extract(carrier)
}
return nil, opentracing.ErrUnsupportedFormat
}
/*Tags return all common tags */
func (tracer *Tracer) Tags() []opentracing.Tag {
return tracer.commonTags
}
/*DispatchSpan dispatches the span to a dispatcher*/
func (tracer *Tracer) DispatchSpan(span *_Span) {
if tracer.dispatcher != nil {
tracer.dispatcher.Dispatch(span)
}
}
/*Close closes the tracer*/
func (tracer *Tracer) Close() error {
if tracer.dispatcher != nil {
tracer.dispatcher.Close()
}
return nil
}

View file

@ -0,0 +1,59 @@
/*
* Copyright 2018 Expedia Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package haystack
import (
"github.com/opentracing/opentracing-go"
)
// TracerOption is a function that sets some option on the tracer
type TracerOption func(tracer *Tracer)
/*TracerOptions a list of tracer options*/
type TracerOptions struct{}
/*TracerOptionsFactory factory to create multiple tracer options*/
var TracerOptionsFactory TracerOptions
/*Propagator registers a new Propagator*/
func (t TracerOptions) Propagator(format interface{}, propagator Propagator) TracerOption {
return func(tracer *Tracer) {
tracer.propagators[format] = propagator
}
}
/*Tag adds a common tag in every span*/
func (t TracerOptions) Tag(key string, value interface{}) TracerOption {
return func(tracer *Tracer) {
tracer.commonTags = append(tracer.commonTags, opentracing.Tag{Key: key, Value: value})
}
}
/*Logger set the logger type*/
func (t TracerOptions) Logger(logger Logger) TracerOption {
return func(tracer *Tracer) {
tracer.logger = logger
}
}
/*UseDualSpanMode sets the tracer in dual span mode*/
func (t TracerOptions) UseDualSpanMode() TracerOption {
return func(tracer *Tracer) {
tracer.useDualSpanMode = true
}
}

View file

@ -1,7 +1,4 @@
Go support for Protocol Buffers - Google's data interchange format
Copyright 2010 The Go Authors. All rights reserved. Copyright 2010 The Go Authors. All rights reserved.
https://github.com/golang/protobuf
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are modification, are permitted provided that the following conditions are

View file

@ -186,7 +186,6 @@ func (p *Buffer) DecodeVarint() (x uint64, err error) {
if b&0x80 == 0 { if b&0x80 == 0 {
goto done goto done
} }
// x -= 0x80 << 63 // Always zero.
return 0, errOverflow return 0, errOverflow

63
vendor/github.com/golang/protobuf/proto/deprecated.go generated vendored Normal file
View file

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

View file

@ -37,27 +37,9 @@ package proto
import ( import (
"errors" "errors"
"fmt"
"reflect" "reflect"
) )
// RequiredNotSetError is the error returned if Marshal is called with
// a protocol buffer struct whose required fields have not
// all been initialized. It is also the error returned if Unmarshal is
// called with an encoded protocol buffer that does not include all the
// required fields.
//
// When printed, RequiredNotSetError reports the first unset required field in a
// message. If the field cannot be precisely determined, it is reported as
// "{Unknown}".
type RequiredNotSetError struct {
field string
}
func (e *RequiredNotSetError) Error() string {
return fmt.Sprintf("proto: required field %q not set", e.field)
}
var ( var (
// errRepeatedHasNil is the error returned if Marshal is called with // errRepeatedHasNil is the error returned if Marshal is called with
// a struct with a repeated field containing a nil element. // a struct with a repeated field containing a nil element.

View file

@ -246,7 +246,8 @@ func equalExtMap(base reflect.Type, em1, em2 map[int32]Extension) bool {
return false return false
} }
m1, m2 := e1.value, e2.value m1 := extensionAsLegacyType(e1.value)
m2 := extensionAsLegacyType(e2.value)
if m1 == nil && m2 == nil { if m1 == nil && m2 == nil {
// Both have only encoded form. // Both have only encoded form.

View file

@ -185,9 +185,25 @@ type Extension struct {
// extension will have only enc set. When such an extension is // extension will have only enc set. When such an extension is
// accessed using GetExtension (or GetExtensions) desc and value // accessed using GetExtension (or GetExtensions) desc and value
// will be set. // will be set.
desc *ExtensionDesc desc *ExtensionDesc
// value is a concrete value for the extension field. Let the type of
// desc.ExtensionType be the "API type" and the type of Extension.value
// be the "storage type". The API type and storage type are the same except:
// * For scalars (except []byte), the API type uses *T,
// while the storage type uses T.
// * For repeated fields, the API type uses []T, while the storage type
// uses *[]T.
//
// The reason for the divergence is so that the storage type more naturally
// matches what is expected of when retrieving the values through the
// protobuf reflection APIs.
//
// The value may only be populated if desc is also populated.
value interface{} value interface{}
enc []byte
// enc is the raw bytes for the extension field.
enc []byte
} }
// SetRawExtension is for testing only. // SetRawExtension is for testing only.
@ -334,7 +350,7 @@ func GetExtension(pb Message, extension *ExtensionDesc) (interface{}, error) {
// descriptors with the same field number. // descriptors with the same field number.
return nil, errors.New("proto: descriptor conflict") return nil, errors.New("proto: descriptor conflict")
} }
return e.value, nil return extensionAsLegacyType(e.value), nil
} }
if extension.ExtensionType == nil { if extension.ExtensionType == nil {
@ -349,11 +365,11 @@ func GetExtension(pb Message, extension *ExtensionDesc) (interface{}, error) {
// Remember the decoded version and drop the encoded version. // Remember the decoded version and drop the encoded version.
// That way it is safe to mutate what we return. // That way it is safe to mutate what we return.
e.value = v e.value = extensionAsStorageType(v)
e.desc = extension e.desc = extension
e.enc = nil e.enc = nil
emap[extension.Field] = e emap[extension.Field] = e
return e.value, nil return extensionAsLegacyType(e.value), nil
} }
// defaultExtensionValue returns the default value for extension. // defaultExtensionValue returns the default value for extension.
@ -488,7 +504,7 @@ func SetExtension(pb Message, extension *ExtensionDesc, value interface{}) error
} }
typ := reflect.TypeOf(extension.ExtensionType) typ := reflect.TypeOf(extension.ExtensionType)
if typ != reflect.TypeOf(value) { if typ != reflect.TypeOf(value) {
return errors.New("proto: bad extension value type") return fmt.Errorf("proto: bad extension value type. got: %T, want: %T", value, extension.ExtensionType)
} }
// nil extension values need to be caught early, because the // nil extension values need to be caught early, because the
// encoder can't distinguish an ErrNil due to a nil extension // encoder can't distinguish an ErrNil due to a nil extension
@ -500,7 +516,7 @@ func SetExtension(pb Message, extension *ExtensionDesc, value interface{}) error
} }
extmap := epb.extensionsWrite() extmap := epb.extensionsWrite()
extmap[extension.Field] = Extension{desc: extension, value: value} extmap[extension.Field] = Extension{desc: extension, value: extensionAsStorageType(value)}
return nil return nil
} }
@ -541,3 +557,51 @@ func RegisterExtension(desc *ExtensionDesc) {
func RegisteredExtensions(pb Message) map[int32]*ExtensionDesc { func RegisteredExtensions(pb Message) map[int32]*ExtensionDesc {
return extensionMaps[reflect.TypeOf(pb).Elem()] return extensionMaps[reflect.TypeOf(pb).Elem()]
} }
// extensionAsLegacyType converts an value in the storage type as the API type.
// See Extension.value.
func extensionAsLegacyType(v interface{}) interface{} {
switch rv := reflect.ValueOf(v); rv.Kind() {
case reflect.Bool, reflect.Int32, reflect.Int64, reflect.Uint32, reflect.Uint64, reflect.Float32, reflect.Float64, reflect.String:
// Represent primitive types as a pointer to the value.
rv2 := reflect.New(rv.Type())
rv2.Elem().Set(rv)
v = rv2.Interface()
case reflect.Ptr:
// Represent slice types as the value itself.
switch rv.Type().Elem().Kind() {
case reflect.Slice:
if rv.IsNil() {
v = reflect.Zero(rv.Type().Elem()).Interface()
} else {
v = rv.Elem().Interface()
}
}
}
return v
}
// extensionAsStorageType converts an value in the API type as the storage type.
// See Extension.value.
func extensionAsStorageType(v interface{}) interface{} {
switch rv := reflect.ValueOf(v); rv.Kind() {
case reflect.Ptr:
// Represent slice types as the value itself.
switch rv.Type().Elem().Kind() {
case reflect.Bool, reflect.Int32, reflect.Int64, reflect.Uint32, reflect.Uint64, reflect.Float32, reflect.Float64, reflect.String:
if rv.IsNil() {
v = reflect.Zero(rv.Type().Elem()).Interface()
} else {
v = rv.Elem().Interface()
}
}
case reflect.Slice:
// Represent slice types as a pointer to the value.
if rv.Type().Elem().Kind() != reflect.Uint8 {
rv2 := reflect.New(rv.Type())
rv2.Elem().Set(rv)
v = rv2.Interface()
}
}
return v
}

View file

@ -265,7 +265,6 @@ package proto
import ( import (
"encoding/json" "encoding/json"
"errors"
"fmt" "fmt"
"log" "log"
"reflect" "reflect"
@ -274,7 +273,66 @@ import (
"sync" "sync"
) )
var errInvalidUTF8 = errors.New("proto: invalid UTF-8 string") // RequiredNotSetError is an error type returned by either Marshal or Unmarshal.
// Marshal reports this when a required field is not initialized.
// Unmarshal reports this when a required field is missing from the wire data.
type RequiredNotSetError struct{ field string }
func (e *RequiredNotSetError) Error() string {
if e.field == "" {
return fmt.Sprintf("proto: required field not set")
}
return fmt.Sprintf("proto: required field %q not set", e.field)
}
func (e *RequiredNotSetError) RequiredNotSet() bool {
return true
}
type invalidUTF8Error struct{ field string }
func (e *invalidUTF8Error) Error() string {
if e.field == "" {
return "proto: invalid UTF-8 detected"
}
return fmt.Sprintf("proto: field %q contains invalid UTF-8", e.field)
}
func (e *invalidUTF8Error) InvalidUTF8() bool {
return true
}
// errInvalidUTF8 is a sentinel error to identify fields with invalid UTF-8.
// This error should not be exposed to the external API as such errors should
// be recreated with the field information.
var errInvalidUTF8 = &invalidUTF8Error{}
// isNonFatal reports whether the error is either a RequiredNotSet error
// or a InvalidUTF8 error.
func isNonFatal(err error) bool {
if re, ok := err.(interface{ RequiredNotSet() bool }); ok && re.RequiredNotSet() {
return true
}
if re, ok := err.(interface{ InvalidUTF8() bool }); ok && re.InvalidUTF8() {
return true
}
return false
}
type nonFatal struct{ E error }
// Merge merges err into nf and reports whether it was successful.
// Otherwise it returns false for any fatal non-nil errors.
func (nf *nonFatal) Merge(err error) (ok bool) {
if err == nil {
return true // not an error
}
if !isNonFatal(err) {
return false // fatal error
}
if nf.E == nil {
nf.E = err // store first instance of non-fatal error
}
return true
}
// Message is implemented by generated protocol buffer messages. // Message is implemented by generated protocol buffer messages.
type Message interface { type Message interface {
@ -283,26 +341,6 @@ type Message interface {
ProtoMessage() ProtoMessage()
} }
// Stats records allocation details about the protocol buffer encoders
// and decoders. Useful for tuning the library itself.
type Stats struct {
Emalloc uint64 // mallocs in encode
Dmalloc uint64 // mallocs in decode
Encode uint64 // number of encodes
Decode uint64 // number of decodes
Chit uint64 // number of cache hits
Cmiss uint64 // number of cache misses
Size uint64 // number of sizes
}
// Set to true to enable stats collection.
const collectStats = false
var stats Stats
// GetStats returns a copy of the global Stats structure.
func GetStats() Stats { return stats }
// A Buffer is a buffer manager for marshaling and unmarshaling // A Buffer is a buffer manager for marshaling and unmarshaling
// protocol buffers. It may be reused between invocations to // protocol buffers. It may be reused between invocations to
// reduce memory usage. It is not necessary to use a Buffer; // reduce memory usage. It is not necessary to use a Buffer;
@ -902,13 +940,19 @@ func isProto3Zero(v reflect.Value) bool {
return false return false
} }
// ProtoPackageIsVersion2 is referenced from generated protocol buffer files const (
// to assert that that code is compatible with this version of the proto package. // ProtoPackageIsVersion3 is referenced from generated protocol buffer files
const ProtoPackageIsVersion2 = true // to assert that that code is compatible with this version of the proto package.
ProtoPackageIsVersion3 = true
// ProtoPackageIsVersion1 is referenced from generated protocol buffer files // ProtoPackageIsVersion2 is referenced from generated protocol buffer files
// to assert that that code is compatible with this version of the proto package. // to assert that that code is compatible with this version of the proto package.
const ProtoPackageIsVersion1 = true ProtoPackageIsVersion2 = true
// ProtoPackageIsVersion1 is referenced from generated protocol buffer files
// to assert that that code is compatible with this version of the proto package.
ProtoPackageIsVersion1 = true
)
// InternalMessageInfo is a type used internally by generated .pb.go files. // InternalMessageInfo is a type used internally by generated .pb.go files.
// This type is not intended to be used by non-generated code. // This type is not intended to be used by non-generated code.

View file

@ -36,13 +36,7 @@ package proto
*/ */
import ( import (
"bytes"
"encoding/json"
"errors" "errors"
"fmt"
"reflect"
"sort"
"sync"
) )
// errNoMessageTypeID occurs when a protocol buffer does not have a message type ID. // errNoMessageTypeID occurs when a protocol buffer does not have a message type ID.
@ -145,46 +139,9 @@ func skipVarint(buf []byte) []byte {
return buf[i+1:] return buf[i+1:]
} }
// MarshalMessageSet encodes the extension map represented by m in the message set wire format. // unmarshalMessageSet decodes the extension map encoded in buf in the message set wire format.
// It is called by generated Marshal methods on protocol buffer messages with the message_set_wire_format option.
func MarshalMessageSet(exts interface{}) ([]byte, error) {
return marshalMessageSet(exts, false)
}
// marshaMessageSet implements above function, with the opt to turn on / off deterministic during Marshal.
func marshalMessageSet(exts interface{}, deterministic bool) ([]byte, error) {
switch exts := exts.(type) {
case *XXX_InternalExtensions:
var u marshalInfo
siz := u.sizeMessageSet(exts)
b := make([]byte, 0, siz)
return u.appendMessageSet(b, exts, deterministic)
case map[int32]Extension:
// This is an old-style extension map.
// Wrap it in a new-style XXX_InternalExtensions.
ie := XXX_InternalExtensions{
p: &struct {
mu sync.Mutex
extensionMap map[int32]Extension
}{
extensionMap: exts,
},
}
var u marshalInfo
siz := u.sizeMessageSet(&ie)
b := make([]byte, 0, siz)
return u.appendMessageSet(b, &ie, deterministic)
default:
return nil, errors.New("proto: not an extension map")
}
}
// UnmarshalMessageSet decodes the extension map encoded in buf in the message set wire format.
// It is called by Unmarshal methods on protocol buffer messages with the message_set_wire_format option. // It is called by Unmarshal methods on protocol buffer messages with the message_set_wire_format option.
func UnmarshalMessageSet(buf []byte, exts interface{}) error { func unmarshalMessageSet(buf []byte, exts interface{}) error {
var m map[int32]Extension var m map[int32]Extension
switch exts := exts.(type) { switch exts := exts.(type) {
case *XXX_InternalExtensions: case *XXX_InternalExtensions:
@ -222,93 +179,3 @@ func UnmarshalMessageSet(buf []byte, exts interface{}) error {
} }
return nil return nil
} }
// MarshalMessageSetJSON encodes the extension map represented by m in JSON format.
// It is called by generated MarshalJSON methods on protocol buffer messages with the message_set_wire_format option.
func MarshalMessageSetJSON(exts interface{}) ([]byte, error) {
var m map[int32]Extension
switch exts := exts.(type) {
case *XXX_InternalExtensions:
var mu sync.Locker
m, mu = exts.extensionsRead()
if m != nil {
// Keep the extensions map locked until we're done marshaling to prevent
// races between marshaling and unmarshaling the lazily-{en,de}coded
// values.
mu.Lock()
defer mu.Unlock()
}
case map[int32]Extension:
m = exts
default:
return nil, errors.New("proto: not an extension map")
}
var b bytes.Buffer
b.WriteByte('{')
// Process the map in key order for deterministic output.
ids := make([]int32, 0, len(m))
for id := range m {
ids = append(ids, id)
}
sort.Sort(int32Slice(ids)) // int32Slice defined in text.go
for i, id := range ids {
ext := m[id]
msd, ok := messageSetMap[id]
if !ok {
// Unknown type; we can't render it, so skip it.
continue
}
if i > 0 && b.Len() > 1 {
b.WriteByte(',')
}
fmt.Fprintf(&b, `"[%s]":`, msd.name)
x := ext.value
if x == nil {
x = reflect.New(msd.t.Elem()).Interface()
if err := Unmarshal(ext.enc, x.(Message)); err != nil {
return nil, err
}
}
d, err := json.Marshal(x)
if err != nil {
return nil, err
}
b.Write(d)
}
b.WriteByte('}')
return b.Bytes(), nil
}
// UnmarshalMessageSetJSON decodes the extension map encoded in buf in JSON format.
// It is called by generated UnmarshalJSON methods on protocol buffer messages with the message_set_wire_format option.
func UnmarshalMessageSetJSON(buf []byte, exts interface{}) error {
// Common-case fast path.
if len(buf) == 0 || bytes.Equal(buf, []byte("{}")) {
return nil
}
// This is fairly tricky, and it's not clear that it is needed.
return errors.New("TODO: UnmarshalMessageSetJSON not yet implemented")
}
// A global registry of types that can be used in a MessageSet.
var messageSetMap = make(map[int32]messageSetDesc)
type messageSetDesc struct {
t reflect.Type // pointer to struct
name string
}
// RegisterMessageSetType is called from the generated code.
func RegisterMessageSetType(m Message, fieldNum int32, name string) {
messageSetMap[fieldNum] = messageSetDesc{
t: reflect.TypeOf(m),
name: name,
}
}

View file

@ -79,10 +79,13 @@ func toPointer(i *Message) pointer {
// toAddrPointer converts an interface to a pointer that points to // toAddrPointer converts an interface to a pointer that points to
// the interface data. // the interface data.
func toAddrPointer(i *interface{}, isptr bool) pointer { func toAddrPointer(i *interface{}, isptr, deref bool) pointer {
v := reflect.ValueOf(*i) v := reflect.ValueOf(*i)
u := reflect.New(v.Type()) u := reflect.New(v.Type())
u.Elem().Set(v) u.Elem().Set(v)
if deref {
u = u.Elem()
}
return pointer{v: u} return pointer{v: u}
} }

View file

@ -85,16 +85,21 @@ func toPointer(i *Message) pointer {
// toAddrPointer converts an interface to a pointer that points to // toAddrPointer converts an interface to a pointer that points to
// the interface data. // the interface data.
func toAddrPointer(i *interface{}, isptr bool) pointer { func toAddrPointer(i *interface{}, isptr, deref bool) (p pointer) {
// Super-tricky - read or get the address of data word of interface value. // Super-tricky - read or get the address of data word of interface value.
if isptr { if isptr {
// The interface is of pointer type, thus it is a direct interface. // The interface is of pointer type, thus it is a direct interface.
// The data word is the pointer data itself. We take its address. // The data word is the pointer data itself. We take its address.
return pointer{p: unsafe.Pointer(uintptr(unsafe.Pointer(i)) + ptrSize)} p = pointer{p: unsafe.Pointer(uintptr(unsafe.Pointer(i)) + ptrSize)}
} else {
// The interface is not of pointer type. The data word is the pointer
// to the data.
p = pointer{p: (*[2]unsafe.Pointer)(unsafe.Pointer(i))[1]}
} }
// The interface is not of pointer type. The data word is the pointer if deref {
// to the data. p.p = *(*unsafe.Pointer)(p.p)
return pointer{p: (*[2]unsafe.Pointer)(unsafe.Pointer(i))[1]} }
return p
} }
// valToPointer converts v to a pointer. v must be of pointer type. // valToPointer converts v to a pointer. v must be of pointer type.

View file

@ -139,7 +139,7 @@ type Properties struct {
Repeated bool Repeated bool
Packed bool // relevant for repeated primitives only Packed bool // relevant for repeated primitives only
Enum string // set for enum types only Enum string // set for enum types only
proto3 bool // whether this is known to be a proto3 field; set for []byte only proto3 bool // whether this is known to be a proto3 field
oneof bool // whether this is a oneof field oneof bool // whether this is a oneof field
Default string // default value Default string // default value
@ -148,9 +148,9 @@ type Properties struct {
stype reflect.Type // set for struct types only stype reflect.Type // set for struct types only
sprop *StructProperties // set for struct types only sprop *StructProperties // set for struct types only
mtype reflect.Type // set for map types only mtype reflect.Type // set for map types only
mkeyprop *Properties // set for map types only MapKeyProp *Properties // set for map types only
mvalprop *Properties // set for map types only MapValProp *Properties // set for map types only
} }
// String formats the properties in the protobuf struct field tag style. // String formats the properties in the protobuf struct field tag style.
@ -275,16 +275,16 @@ func (p *Properties) setFieldProps(typ reflect.Type, f *reflect.StructField, loc
case reflect.Map: case reflect.Map:
p.mtype = t1 p.mtype = t1
p.mkeyprop = &Properties{} p.MapKeyProp = &Properties{}
p.mkeyprop.init(reflect.PtrTo(p.mtype.Key()), "Key", f.Tag.Get("protobuf_key"), nil, lockGetProp) p.MapKeyProp.init(reflect.PtrTo(p.mtype.Key()), "Key", f.Tag.Get("protobuf_key"), nil, lockGetProp)
p.mvalprop = &Properties{} p.MapValProp = &Properties{}
vtype := p.mtype.Elem() vtype := p.mtype.Elem()
if vtype.Kind() != reflect.Ptr && vtype.Kind() != reflect.Slice { if vtype.Kind() != reflect.Ptr && vtype.Kind() != reflect.Slice {
// The value type is not a message (*T) or bytes ([]byte), // The value type is not a message (*T) or bytes ([]byte),
// so we need encoders for the pointer to this type. // so we need encoders for the pointer to this type.
vtype = reflect.PtrTo(vtype) vtype = reflect.PtrTo(vtype)
} }
p.mvalprop.init(vtype, "Value", f.Tag.Get("protobuf_val"), nil, lockGetProp) p.MapValProp.init(vtype, "Value", f.Tag.Get("protobuf_val"), nil, lockGetProp)
} }
if p.stype != nil { if p.stype != nil {
@ -334,9 +334,6 @@ func GetProperties(t reflect.Type) *StructProperties {
sprop, ok := propertiesMap[t] sprop, ok := propertiesMap[t]
propertiesMu.RUnlock() propertiesMu.RUnlock()
if ok { if ok {
if collectStats {
stats.Chit++
}
return sprop return sprop
} }
@ -346,17 +343,20 @@ func GetProperties(t reflect.Type) *StructProperties {
return sprop return sprop
} }
type (
oneofFuncsIface interface {
XXX_OneofFuncs() (func(Message, *Buffer) error, func(Message, int, int, *Buffer) (bool, error), func(Message) int, []interface{})
}
oneofWrappersIface interface {
XXX_OneofWrappers() []interface{}
}
)
// getPropertiesLocked requires that propertiesMu is held. // getPropertiesLocked requires that propertiesMu is held.
func getPropertiesLocked(t reflect.Type) *StructProperties { func getPropertiesLocked(t reflect.Type) *StructProperties {
if prop, ok := propertiesMap[t]; ok { if prop, ok := propertiesMap[t]; ok {
if collectStats {
stats.Chit++
}
return prop return prop
} }
if collectStats {
stats.Cmiss++
}
prop := new(StructProperties) prop := new(StructProperties)
// in case of recursive protos, fill this in now. // in case of recursive protos, fill this in now.
@ -391,13 +391,14 @@ func getPropertiesLocked(t reflect.Type) *StructProperties {
// Re-order prop.order. // Re-order prop.order.
sort.Sort(prop) sort.Sort(prop)
type oneofMessage interface { var oots []interface{}
XXX_OneofFuncs() (func(Message, *Buffer) error, func(Message, int, int, *Buffer) (bool, error), func(Message) int, []interface{}) switch m := reflect.Zero(reflect.PtrTo(t)).Interface().(type) {
case oneofFuncsIface:
_, _, _, oots = m.XXX_OneofFuncs()
case oneofWrappersIface:
oots = m.XXX_OneofWrappers()
} }
if om, ok := reflect.Zero(reflect.PtrTo(t)).Interface().(oneofMessage); ok { if len(oots) > 0 {
var oots []interface{}
_, _, _, oots = om.XXX_OneofFuncs()
// Interpret oneof metadata. // Interpret oneof metadata.
prop.OneofTypes = make(map[string]*OneofProperties) prop.OneofTypes = make(map[string]*OneofProperties)
for _, oot := range oots { for _, oot := range oots {

View file

@ -87,6 +87,7 @@ type marshalElemInfo struct {
sizer sizer sizer sizer
marshaler marshaler marshaler marshaler
isptr bool // elem is pointer typed, thus interface of this type is a direct interface (extension only) isptr bool // elem is pointer typed, thus interface of this type is a direct interface (extension only)
deref bool // dereference the pointer before operating on it; implies isptr
} }
var ( var (
@ -231,7 +232,7 @@ func (u *marshalInfo) marshal(b []byte, ptr pointer, deterministic bool) ([]byte
return b, err return b, err
} }
var err, errreq error var err, errLater error
// The old marshaler encodes extensions at beginning. // The old marshaler encodes extensions at beginning.
if u.extensions.IsValid() { if u.extensions.IsValid() {
e := ptr.offset(u.extensions).toExtensions() e := ptr.offset(u.extensions).toExtensions()
@ -252,11 +253,13 @@ func (u *marshalInfo) marshal(b []byte, ptr pointer, deterministic bool) ([]byte
} }
} }
for _, f := range u.fields { for _, f := range u.fields {
if f.required && errreq == nil { if f.required {
if ptr.offset(f.field).getPointer().isNil() { if ptr.offset(f.field).getPointer().isNil() {
// Required field is not set. // Required field is not set.
// We record the error but keep going, to give a complete marshaling. // We record the error but keep going, to give a complete marshaling.
errreq = &RequiredNotSetError{f.name} if errLater == nil {
errLater = &RequiredNotSetError{f.name}
}
continue continue
} }
} }
@ -269,14 +272,21 @@ func (u *marshalInfo) marshal(b []byte, ptr pointer, deterministic bool) ([]byte
if err1, ok := err.(*RequiredNotSetError); ok { if err1, ok := err.(*RequiredNotSetError); ok {
// Required field in submessage is not set. // Required field in submessage is not set.
// We record the error but keep going, to give a complete marshaling. // We record the error but keep going, to give a complete marshaling.
if errreq == nil { if errLater == nil {
errreq = &RequiredNotSetError{f.name + "." + err1.field} errLater = &RequiredNotSetError{f.name + "." + err1.field}
} }
continue continue
} }
if err == errRepeatedHasNil { if err == errRepeatedHasNil {
err = errors.New("proto: repeated field " + f.name + " has nil element") err = errors.New("proto: repeated field " + f.name + " has nil element")
} }
if err == errInvalidUTF8 {
if errLater == nil {
fullName := revProtoTypes[reflect.PtrTo(u.typ)] + "." + f.name
errLater = &invalidUTF8Error{fullName}
}
continue
}
return b, err return b, err
} }
} }
@ -284,7 +294,7 @@ func (u *marshalInfo) marshal(b []byte, ptr pointer, deterministic bool) ([]byte
s := *ptr.offset(u.unrecognized).toBytes() s := *ptr.offset(u.unrecognized).toBytes()
b = append(b, s...) b = append(b, s...)
} }
return b, errreq return b, errLater
} }
// computeMarshalInfo initializes the marshal info. // computeMarshalInfo initializes the marshal info.
@ -311,8 +321,11 @@ func (u *marshalInfo) computeMarshalInfo() {
// get oneof implementers // get oneof implementers
var oneofImplementers []interface{} var oneofImplementers []interface{}
if m, ok := reflect.Zero(reflect.PtrTo(t)).Interface().(oneofMessage); ok { switch m := reflect.Zero(reflect.PtrTo(t)).Interface().(type) {
case oneofFuncsIface:
_, _, _, oneofImplementers = m.XXX_OneofFuncs() _, _, _, oneofImplementers = m.XXX_OneofFuncs()
case oneofWrappersIface:
oneofImplementers = m.XXX_OneofWrappers()
} }
n := t.NumField() n := t.NumField()
@ -398,13 +411,22 @@ func (u *marshalInfo) getExtElemInfo(desc *ExtensionDesc) *marshalElemInfo {
panic("tag is not an integer") panic("tag is not an integer")
} }
wt := wiretype(tags[0]) wt := wiretype(tags[0])
if t.Kind() == reflect.Ptr && t.Elem().Kind() != reflect.Struct {
t = t.Elem()
}
sizer, marshaler := typeMarshaler(t, tags, false, false) sizer, marshaler := typeMarshaler(t, tags, false, false)
var deref bool
if t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8 {
t = reflect.PtrTo(t)
deref = true
}
e = &marshalElemInfo{ e = &marshalElemInfo{
wiretag: uint64(tag)<<3 | wt, wiretag: uint64(tag)<<3 | wt,
tagsize: SizeVarint(uint64(tag) << 3), tagsize: SizeVarint(uint64(tag) << 3),
sizer: sizer, sizer: sizer,
marshaler: marshaler, marshaler: marshaler,
isptr: t.Kind() == reflect.Ptr, isptr: t.Kind() == reflect.Ptr,
deref: deref,
} }
// update cache // update cache
@ -439,7 +461,7 @@ func (fi *marshalFieldInfo) computeMarshalFieldInfo(f *reflect.StructField) {
func (fi *marshalFieldInfo) computeOneofFieldInfo(f *reflect.StructField, oneofImplementers []interface{}) { func (fi *marshalFieldInfo) computeOneofFieldInfo(f *reflect.StructField, oneofImplementers []interface{}) {
fi.field = toField(f) fi.field = toField(f)
fi.wiretag = 1<<31 - 1 // Use a large tag number, make oneofs sorted at the end. This tag will not appear on the wire. fi.wiretag = math.MaxInt32 // Use a large tag number, make oneofs sorted at the end. This tag will not appear on the wire.
fi.isPointer = true fi.isPointer = true
fi.sizer, fi.marshaler = makeOneOfMarshaler(fi, f) fi.sizer, fi.marshaler = makeOneOfMarshaler(fi, f)
fi.oneofElems = make(map[reflect.Type]*marshalElemInfo) fi.oneofElems = make(map[reflect.Type]*marshalElemInfo)
@ -467,10 +489,6 @@ func (fi *marshalFieldInfo) computeOneofFieldInfo(f *reflect.StructField, oneofI
} }
} }
type oneofMessage interface {
XXX_OneofFuncs() (func(Message, *Buffer) error, func(Message, int, int, *Buffer) (bool, error), func(Message) int, []interface{})
}
// wiretype returns the wire encoding of the type. // wiretype returns the wire encoding of the type.
func wiretype(encoding string) uint64 { func wiretype(encoding string) uint64 {
switch encoding { switch encoding {
@ -530,6 +548,7 @@ func typeMarshaler(t reflect.Type, tags []string, nozero, oneof bool) (sizer, ma
packed := false packed := false
proto3 := false proto3 := false
validateUTF8 := true
for i := 2; i < len(tags); i++ { for i := 2; i < len(tags); i++ {
if tags[i] == "packed" { if tags[i] == "packed" {
packed = true packed = true
@ -538,6 +557,7 @@ func typeMarshaler(t reflect.Type, tags []string, nozero, oneof bool) (sizer, ma
proto3 = true proto3 = true
} }
} }
validateUTF8 = validateUTF8 && proto3
switch t.Kind() { switch t.Kind() {
case reflect.Bool: case reflect.Bool:
@ -735,6 +755,18 @@ func typeMarshaler(t reflect.Type, tags []string, nozero, oneof bool) (sizer, ma
} }
return sizeFloat64Value, appendFloat64Value return sizeFloat64Value, appendFloat64Value
case reflect.String: case reflect.String:
if validateUTF8 {
if pointer {
return sizeStringPtr, appendUTF8StringPtr
}
if slice {
return sizeStringSlice, appendUTF8StringSlice
}
if nozero {
return sizeStringValueNoZero, appendUTF8StringValueNoZero
}
return sizeStringValue, appendUTF8StringValue
}
if pointer { if pointer {
return sizeStringPtr, appendStringPtr return sizeStringPtr, appendStringPtr
} }
@ -1984,9 +2016,6 @@ func appendBoolPackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byt
} }
func appendStringValue(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { func appendStringValue(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
v := *ptr.toString() v := *ptr.toString()
if !utf8.ValidString(v) {
return nil, errInvalidUTF8
}
b = appendVarint(b, wiretag) b = appendVarint(b, wiretag)
b = appendVarint(b, uint64(len(v))) b = appendVarint(b, uint64(len(v)))
b = append(b, v...) b = append(b, v...)
@ -1997,9 +2026,6 @@ func appendStringValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]b
if v == "" { if v == "" {
return b, nil return b, nil
} }
if !utf8.ValidString(v) {
return nil, errInvalidUTF8
}
b = appendVarint(b, wiretag) b = appendVarint(b, wiretag)
b = appendVarint(b, uint64(len(v))) b = appendVarint(b, uint64(len(v)))
b = append(b, v...) b = append(b, v...)
@ -2011,24 +2037,83 @@ func appendStringPtr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, err
return b, nil return b, nil
} }
v := *p v := *p
if !utf8.ValidString(v) {
return nil, errInvalidUTF8
}
b = appendVarint(b, wiretag) b = appendVarint(b, wiretag)
b = appendVarint(b, uint64(len(v))) b = appendVarint(b, uint64(len(v)))
b = append(b, v...) b = append(b, v...)
return b, nil return b, nil
} }
func appendStringSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { func appendStringSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
s := *ptr.toStringSlice()
for _, v := range s {
b = appendVarint(b, wiretag)
b = appendVarint(b, uint64(len(v)))
b = append(b, v...)
}
return b, nil
}
func appendUTF8StringValue(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
var invalidUTF8 bool
v := *ptr.toString()
if !utf8.ValidString(v) {
invalidUTF8 = true
}
b = appendVarint(b, wiretag)
b = appendVarint(b, uint64(len(v)))
b = append(b, v...)
if invalidUTF8 {
return b, errInvalidUTF8
}
return b, nil
}
func appendUTF8StringValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
var invalidUTF8 bool
v := *ptr.toString()
if v == "" {
return b, nil
}
if !utf8.ValidString(v) {
invalidUTF8 = true
}
b = appendVarint(b, wiretag)
b = appendVarint(b, uint64(len(v)))
b = append(b, v...)
if invalidUTF8 {
return b, errInvalidUTF8
}
return b, nil
}
func appendUTF8StringPtr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
var invalidUTF8 bool
p := *ptr.toStringPtr()
if p == nil {
return b, nil
}
v := *p
if !utf8.ValidString(v) {
invalidUTF8 = true
}
b = appendVarint(b, wiretag)
b = appendVarint(b, uint64(len(v)))
b = append(b, v...)
if invalidUTF8 {
return b, errInvalidUTF8
}
return b, nil
}
func appendUTF8StringSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
var invalidUTF8 bool
s := *ptr.toStringSlice() s := *ptr.toStringSlice()
for _, v := range s { for _, v := range s {
if !utf8.ValidString(v) { if !utf8.ValidString(v) {
return nil, errInvalidUTF8 invalidUTF8 = true
} }
b = appendVarint(b, wiretag) b = appendVarint(b, wiretag)
b = appendVarint(b, uint64(len(v))) b = appendVarint(b, uint64(len(v)))
b = append(b, v...) b = append(b, v...)
} }
if invalidUTF8 {
return b, errInvalidUTF8
}
return b, nil return b, nil
} }
func appendBytes(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { func appendBytes(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
@ -2107,7 +2192,8 @@ func makeGroupSliceMarshaler(u *marshalInfo) (sizer, marshaler) {
}, },
func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
s := ptr.getPointerSlice() s := ptr.getPointerSlice()
var err, errreq error var err error
var nerr nonFatal
for _, v := range s { for _, v := range s {
if v.isNil() { if v.isNil() {
return b, errRepeatedHasNil return b, errRepeatedHasNil
@ -2115,22 +2201,14 @@ func makeGroupSliceMarshaler(u *marshalInfo) (sizer, marshaler) {
b = appendVarint(b, wiretag) // start group b = appendVarint(b, wiretag) // start group
b, err = u.marshal(b, v, deterministic) b, err = u.marshal(b, v, deterministic)
b = appendVarint(b, wiretag+(WireEndGroup-WireStartGroup)) // end group b = appendVarint(b, wiretag+(WireEndGroup-WireStartGroup)) // end group
if err != nil { if !nerr.Merge(err) {
if _, ok := err.(*RequiredNotSetError); ok {
// Required field in submessage is not set.
// We record the error but keep going, to give a complete marshaling.
if errreq == nil {
errreq = err
}
continue
}
if err == ErrNil { if err == ErrNil {
err = errRepeatedHasNil err = errRepeatedHasNil
} }
return b, err return b, err
} }
} }
return b, errreq return b, nerr.E
} }
} }
@ -2174,7 +2252,8 @@ func makeMessageSliceMarshaler(u *marshalInfo) (sizer, marshaler) {
}, },
func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
s := ptr.getPointerSlice() s := ptr.getPointerSlice()
var err, errreq error var err error
var nerr nonFatal
for _, v := range s { for _, v := range s {
if v.isNil() { if v.isNil() {
return b, errRepeatedHasNil return b, errRepeatedHasNil
@ -2184,22 +2263,14 @@ func makeMessageSliceMarshaler(u *marshalInfo) (sizer, marshaler) {
b = appendVarint(b, uint64(siz)) b = appendVarint(b, uint64(siz))
b, err = u.marshal(b, v, deterministic) b, err = u.marshal(b, v, deterministic)
if err != nil { if !nerr.Merge(err) {
if _, ok := err.(*RequiredNotSetError); ok {
// Required field in submessage is not set.
// We record the error but keep going, to give a complete marshaling.
if errreq == nil {
errreq = err
}
continue
}
if err == ErrNil { if err == ErrNil {
err = errRepeatedHasNil err = errRepeatedHasNil
} }
return b, err return b, err
} }
} }
return b, errreq return b, nerr.E
} }
} }
@ -2223,14 +2294,33 @@ func makeMapMarshaler(f *reflect.StructField) (sizer, marshaler) {
// value. // value.
// Key cannot be pointer-typed. // Key cannot be pointer-typed.
valIsPtr := valType.Kind() == reflect.Ptr valIsPtr := valType.Kind() == reflect.Ptr
// If value is a message with nested maps, calling
// valSizer in marshal may be quadratic. We should use
// cached version in marshal (but not in size).
// If value is not message type, we don't have size cache,
// but it cannot be nested either. Just use valSizer.
valCachedSizer := valSizer
if valIsPtr && valType.Elem().Kind() == reflect.Struct {
u := getMarshalInfo(valType.Elem())
valCachedSizer = func(ptr pointer, tagsize int) int {
// Same as message sizer, but use cache.
p := ptr.getPointer()
if p.isNil() {
return 0
}
siz := u.cachedsize(p)
return siz + SizeVarint(uint64(siz)) + tagsize
}
}
return func(ptr pointer, tagsize int) int { return func(ptr pointer, tagsize int) int {
m := ptr.asPointerTo(t).Elem() // the map m := ptr.asPointerTo(t).Elem() // the map
n := 0 n := 0
for _, k := range m.MapKeys() { for _, k := range m.MapKeys() {
ki := k.Interface() ki := k.Interface()
vi := m.MapIndex(k).Interface() vi := m.MapIndex(k).Interface()
kaddr := toAddrPointer(&ki, false) // pointer to key kaddr := toAddrPointer(&ki, false, false) // pointer to key
vaddr := toAddrPointer(&vi, valIsPtr) // pointer to value vaddr := toAddrPointer(&vi, valIsPtr, false) // pointer to value
siz := keySizer(kaddr, 1) + valSizer(vaddr, 1) // tag of key = 1 (size=1), tag of val = 2 (size=1) siz := keySizer(kaddr, 1) + valSizer(vaddr, 1) // tag of key = 1 (size=1), tag of val = 2 (size=1)
n += siz + SizeVarint(uint64(siz)) + tagsize n += siz + SizeVarint(uint64(siz)) + tagsize
} }
@ -2243,24 +2333,26 @@ func makeMapMarshaler(f *reflect.StructField) (sizer, marshaler) {
if len(keys) > 1 && deterministic { if len(keys) > 1 && deterministic {
sort.Sort(mapKeys(keys)) sort.Sort(mapKeys(keys))
} }
var nerr nonFatal
for _, k := range keys { for _, k := range keys {
ki := k.Interface() ki := k.Interface()
vi := m.MapIndex(k).Interface() vi := m.MapIndex(k).Interface()
kaddr := toAddrPointer(&ki, false) // pointer to key kaddr := toAddrPointer(&ki, false, false) // pointer to key
vaddr := toAddrPointer(&vi, valIsPtr) // pointer to value vaddr := toAddrPointer(&vi, valIsPtr, false) // pointer to value
b = appendVarint(b, tag) b = appendVarint(b, tag)
siz := keySizer(kaddr, 1) + valSizer(vaddr, 1) // tag of key = 1 (size=1), tag of val = 2 (size=1) siz := keySizer(kaddr, 1) + valCachedSizer(vaddr, 1) // tag of key = 1 (size=1), tag of val = 2 (size=1)
b = appendVarint(b, uint64(siz)) b = appendVarint(b, uint64(siz))
b, err = keyMarshaler(b, kaddr, keyWireTag, deterministic) b, err = keyMarshaler(b, kaddr, keyWireTag, deterministic)
if err != nil { if !nerr.Merge(err) {
return b, err return b, err
} }
b, err = valMarshaler(b, vaddr, valWireTag, deterministic) b, err = valMarshaler(b, vaddr, valWireTag, deterministic)
if err != nil && err != ErrNil { // allow nil value in map if err != ErrNil && !nerr.Merge(err) { // allow nil value in map
return b, err return b, err
} }
} }
return b, nil return b, nerr.E
} }
} }
@ -2316,7 +2408,7 @@ func (u *marshalInfo) sizeExtensions(ext *XXX_InternalExtensions) int {
// the last time this function was called. // the last time this function was called.
ei := u.getExtElemInfo(e.desc) ei := u.getExtElemInfo(e.desc)
v := e.value v := e.value
p := toAddrPointer(&v, ei.isptr) p := toAddrPointer(&v, ei.isptr, ei.deref)
n += ei.sizer(p, ei.tagsize) n += ei.sizer(p, ei.tagsize)
} }
mu.Unlock() mu.Unlock()
@ -2333,6 +2425,7 @@ func (u *marshalInfo) appendExtensions(b []byte, ext *XXX_InternalExtensions, de
defer mu.Unlock() defer mu.Unlock()
var err error var err error
var nerr nonFatal
// Fast-path for common cases: zero or one extensions. // Fast-path for common cases: zero or one extensions.
// Don't bother sorting the keys. // Don't bother sorting the keys.
@ -2350,13 +2443,13 @@ func (u *marshalInfo) appendExtensions(b []byte, ext *XXX_InternalExtensions, de
ei := u.getExtElemInfo(e.desc) ei := u.getExtElemInfo(e.desc)
v := e.value v := e.value
p := toAddrPointer(&v, ei.isptr) p := toAddrPointer(&v, ei.isptr, ei.deref)
b, err = ei.marshaler(b, p, ei.wiretag, deterministic) b, err = ei.marshaler(b, p, ei.wiretag, deterministic)
if err != nil { if !nerr.Merge(err) {
return b, err return b, err
} }
} }
return b, nil return b, nerr.E
} }
// Sort the keys to provide a deterministic encoding. // Sort the keys to provide a deterministic encoding.
@ -2381,13 +2474,13 @@ func (u *marshalInfo) appendExtensions(b []byte, ext *XXX_InternalExtensions, de
ei := u.getExtElemInfo(e.desc) ei := u.getExtElemInfo(e.desc)
v := e.value v := e.value
p := toAddrPointer(&v, ei.isptr) p := toAddrPointer(&v, ei.isptr, ei.deref)
b, err = ei.marshaler(b, p, ei.wiretag, deterministic) b, err = ei.marshaler(b, p, ei.wiretag, deterministic)
if err != nil { if !nerr.Merge(err) {
return b, err return b, err
} }
} }
return b, nil return b, nerr.E
} }
// message set format is: // message set format is:
@ -2426,7 +2519,7 @@ func (u *marshalInfo) sizeMessageSet(ext *XXX_InternalExtensions) int {
ei := u.getExtElemInfo(e.desc) ei := u.getExtElemInfo(e.desc)
v := e.value v := e.value
p := toAddrPointer(&v, ei.isptr) p := toAddrPointer(&v, ei.isptr, ei.deref)
n += ei.sizer(p, 1) // message, tag = 3 (size=1) n += ei.sizer(p, 1) // message, tag = 3 (size=1)
} }
mu.Unlock() mu.Unlock()
@ -2444,6 +2537,7 @@ func (u *marshalInfo) appendMessageSet(b []byte, ext *XXX_InternalExtensions, de
defer mu.Unlock() defer mu.Unlock()
var err error var err error
var nerr nonFatal
// Fast-path for common cases: zero or one extensions. // Fast-path for common cases: zero or one extensions.
// Don't bother sorting the keys. // Don't bother sorting the keys.
@ -2468,14 +2562,14 @@ func (u *marshalInfo) appendMessageSet(b []byte, ext *XXX_InternalExtensions, de
ei := u.getExtElemInfo(e.desc) ei := u.getExtElemInfo(e.desc)
v := e.value v := e.value
p := toAddrPointer(&v, ei.isptr) p := toAddrPointer(&v, ei.isptr, ei.deref)
b, err = ei.marshaler(b, p, 3<<3|WireBytes, deterministic) b, err = ei.marshaler(b, p, 3<<3|WireBytes, deterministic)
if err != nil { if !nerr.Merge(err) {
return b, err return b, err
} }
b = append(b, 1<<3|WireEndGroup) b = append(b, 1<<3|WireEndGroup)
} }
return b, nil return b, nerr.E
} }
// Sort the keys to provide a deterministic encoding. // Sort the keys to provide a deterministic encoding.
@ -2506,14 +2600,14 @@ func (u *marshalInfo) appendMessageSet(b []byte, ext *XXX_InternalExtensions, de
ei := u.getExtElemInfo(e.desc) ei := u.getExtElemInfo(e.desc)
v := e.value v := e.value
p := toAddrPointer(&v, ei.isptr) p := toAddrPointer(&v, ei.isptr, ei.deref)
b, err = ei.marshaler(b, p, 3<<3|WireBytes, deterministic) b, err = ei.marshaler(b, p, 3<<3|WireBytes, deterministic)
b = append(b, 1<<3|WireEndGroup) b = append(b, 1<<3|WireEndGroup)
if err != nil { if !nerr.Merge(err) {
return b, err return b, err
} }
} }
return b, nil return b, nerr.E
} }
// sizeV1Extensions computes the size of encoded data for a V1-API extension field. // sizeV1Extensions computes the size of encoded data for a V1-API extension field.
@ -2536,7 +2630,7 @@ func (u *marshalInfo) sizeV1Extensions(m map[int32]Extension) int {
ei := u.getExtElemInfo(e.desc) ei := u.getExtElemInfo(e.desc)
v := e.value v := e.value
p := toAddrPointer(&v, ei.isptr) p := toAddrPointer(&v, ei.isptr, ei.deref)
n += ei.sizer(p, ei.tagsize) n += ei.sizer(p, ei.tagsize)
} }
return n return n
@ -2556,6 +2650,7 @@ func (u *marshalInfo) appendV1Extensions(b []byte, m map[int32]Extension, determ
sort.Ints(keys) sort.Ints(keys)
var err error var err error
var nerr nonFatal
for _, k := range keys { for _, k := range keys {
e := m[int32(k)] e := m[int32(k)]
if e.value == nil || e.desc == nil { if e.value == nil || e.desc == nil {
@ -2570,13 +2665,13 @@ func (u *marshalInfo) appendV1Extensions(b []byte, m map[int32]Extension, determ
ei := u.getExtElemInfo(e.desc) ei := u.getExtElemInfo(e.desc)
v := e.value v := e.value
p := toAddrPointer(&v, ei.isptr) p := toAddrPointer(&v, ei.isptr, ei.deref)
b, err = ei.marshaler(b, p, ei.wiretag, deterministic) b, err = ei.marshaler(b, p, ei.wiretag, deterministic)
if err != nil { if !nerr.Merge(err) {
return b, err return b, err
} }
} }
return b, nil return b, nerr.E
} }
// newMarshaler is the interface representing objects that can marshal themselves. // newMarshaler is the interface representing objects that can marshal themselves.

View file

@ -97,6 +97,8 @@ type unmarshalFieldInfo struct {
// if a required field, contains a single set bit at this field's index in the required field list. // if a required field, contains a single set bit at this field's index in the required field list.
reqMask uint64 reqMask uint64
name string // name of the field, for error reporting
} }
var ( var (
@ -134,10 +136,10 @@ func (u *unmarshalInfo) unmarshal(m pointer, b []byte) error {
u.computeUnmarshalInfo() u.computeUnmarshalInfo()
} }
if u.isMessageSet { if u.isMessageSet {
return UnmarshalMessageSet(b, m.offset(u.extensions).toExtensions()) return unmarshalMessageSet(b, m.offset(u.extensions).toExtensions())
} }
var reqMask uint64 // bitmask of required fields we've seen. var reqMask uint64 // bitmask of required fields we've seen.
var rnse *RequiredNotSetError // an instance of a RequiredNotSetError returned by a submessage. var errLater error
for len(b) > 0 { for len(b) > 0 {
// Read tag and wire type. // Read tag and wire type.
// Special case 1 and 2 byte varints. // Special case 1 and 2 byte varints.
@ -176,11 +178,20 @@ func (u *unmarshalInfo) unmarshal(m pointer, b []byte) error {
if r, ok := err.(*RequiredNotSetError); ok { if r, ok := err.(*RequiredNotSetError); ok {
// Remember this error, but keep parsing. We need to produce // Remember this error, but keep parsing. We need to produce
// a full parse even if a required field is missing. // a full parse even if a required field is missing.
rnse = r if errLater == nil {
errLater = r
}
reqMask |= f.reqMask reqMask |= f.reqMask
continue continue
} }
if err != errInternalBadWireType { if err != errInternalBadWireType {
if err == errInvalidUTF8 {
if errLater == nil {
fullName := revProtoTypes[reflect.PtrTo(u.typ)] + "." + f.name
errLater = &invalidUTF8Error{fullName}
}
continue
}
return err return err
} }
// Fragments with bad wire type are treated as unknown fields. // Fragments with bad wire type are treated as unknown fields.
@ -239,20 +250,16 @@ func (u *unmarshalInfo) unmarshal(m pointer, b []byte) error {
emap[int32(tag)] = e emap[int32(tag)] = e
} }
} }
if rnse != nil { if reqMask != u.reqMask && errLater == nil {
// A required field of a submessage/group is missing. Return that error.
return rnse
}
if reqMask != u.reqMask {
// A required field of this message is missing. // A required field of this message is missing.
for _, n := range u.reqFields { for _, n := range u.reqFields {
if reqMask&1 == 0 { if reqMask&1 == 0 {
return &RequiredNotSetError{n} errLater = &RequiredNotSetError{n}
} }
reqMask >>= 1 reqMask >>= 1
} }
} }
return nil return errLater
} }
// computeUnmarshalInfo fills in u with information for use // computeUnmarshalInfo fills in u with information for use
@ -351,43 +358,52 @@ func (u *unmarshalInfo) computeUnmarshalInfo() {
} }
// Store the info in the correct slot in the message. // Store the info in the correct slot in the message.
u.setTag(tag, toField(&f), unmarshal, reqMask) u.setTag(tag, toField(&f), unmarshal, reqMask, name)
} }
// Find any types associated with oneof fields. // Find any types associated with oneof fields.
// TODO: XXX_OneofFuncs returns more info than we need. Get rid of some of it? var oneofImplementers []interface{}
fn := reflect.Zero(reflect.PtrTo(t)).MethodByName("XXX_OneofFuncs") switch m := reflect.Zero(reflect.PtrTo(t)).Interface().(type) {
if fn.IsValid() { case oneofFuncsIface:
res := fn.Call(nil)[3] // last return value from XXX_OneofFuncs: []interface{} _, _, _, oneofImplementers = m.XXX_OneofFuncs()
for i := res.Len() - 1; i >= 0; i-- { case oneofWrappersIface:
v := res.Index(i) // interface{} oneofImplementers = m.XXX_OneofWrappers()
tptr := reflect.ValueOf(v.Interface()).Type() // *Msg_X }
typ := tptr.Elem() // Msg_X for _, v := range oneofImplementers {
tptr := reflect.TypeOf(v) // *Msg_X
typ := tptr.Elem() // Msg_X
f := typ.Field(0) // oneof implementers have one field f := typ.Field(0) // oneof implementers have one field
baseUnmarshal := fieldUnmarshaler(&f) baseUnmarshal := fieldUnmarshaler(&f)
tagstr := strings.Split(f.Tag.Get("protobuf"), ",")[1] tags := strings.Split(f.Tag.Get("protobuf"), ",")
tag, err := strconv.Atoi(tagstr) fieldNum, err := strconv.Atoi(tags[1])
if err != nil { if err != nil {
panic("protobuf tag field not an integer: " + tagstr) panic("protobuf tag field not an integer: " + tags[1])
} }
var name string
// Find the oneof field that this struct implements. for _, tag := range tags {
// Might take O(n^2) to process all of the oneofs, but who cares. if strings.HasPrefix(tag, "name=") {
for _, of := range oneofFields { name = strings.TrimPrefix(tag, "name=")
if tptr.Implements(of.ityp) { break
// We have found the corresponding interface for this struct.
// That lets us know where this struct should be stored
// when we encounter it during unmarshaling.
unmarshal := makeUnmarshalOneof(typ, of.ityp, baseUnmarshal)
u.setTag(tag, of.field, unmarshal, 0)
}
} }
} }
// Find the oneof field that this struct implements.
// Might take O(n^2) to process all of the oneofs, but who cares.
for _, of := range oneofFields {
if tptr.Implements(of.ityp) {
// We have found the corresponding interface for this struct.
// That lets us know where this struct should be stored
// when we encounter it during unmarshaling.
unmarshal := makeUnmarshalOneof(typ, of.ityp, baseUnmarshal)
u.setTag(fieldNum, of.field, unmarshal, 0, name)
}
}
} }
// Get extension ranges, if any. // Get extension ranges, if any.
fn = reflect.Zero(reflect.PtrTo(t)).MethodByName("ExtensionRangeArray") fn := reflect.Zero(reflect.PtrTo(t)).MethodByName("ExtensionRangeArray")
if fn.IsValid() { if fn.IsValid() {
if !u.extensions.IsValid() && !u.oldExtensions.IsValid() { if !u.extensions.IsValid() && !u.oldExtensions.IsValid() {
panic("a message with extensions, but no extensions field in " + t.Name()) panic("a message with extensions, but no extensions field in " + t.Name())
@ -401,7 +417,7 @@ func (u *unmarshalInfo) computeUnmarshalInfo() {
// [0 0] is [tag=0/wiretype=varint varint-encoded-0]. // [0 0] is [tag=0/wiretype=varint varint-encoded-0].
u.setTag(0, zeroField, func(b []byte, f pointer, w int) ([]byte, error) { u.setTag(0, zeroField, func(b []byte, f pointer, w int) ([]byte, error) {
return nil, fmt.Errorf("proto: %s: illegal tag 0 (wire type %d)", t, w) return nil, fmt.Errorf("proto: %s: illegal tag 0 (wire type %d)", t, w)
}, 0) }, 0, "")
// Set mask for required field check. // Set mask for required field check.
u.reqMask = uint64(1)<<uint(len(u.reqFields)) - 1 u.reqMask = uint64(1)<<uint(len(u.reqFields)) - 1
@ -413,8 +429,9 @@ func (u *unmarshalInfo) computeUnmarshalInfo() {
// tag = tag # for field // tag = tag # for field
// field/unmarshal = unmarshal info for that field. // field/unmarshal = unmarshal info for that field.
// reqMask = if required, bitmask for field position in required field list. 0 otherwise. // reqMask = if required, bitmask for field position in required field list. 0 otherwise.
func (u *unmarshalInfo) setTag(tag int, field field, unmarshal unmarshaler, reqMask uint64) { // name = short name of the field.
i := unmarshalFieldInfo{field: field, unmarshal: unmarshal, reqMask: reqMask} func (u *unmarshalInfo) setTag(tag int, field field, unmarshal unmarshaler, reqMask uint64, name string) {
i := unmarshalFieldInfo{field: field, unmarshal: unmarshal, reqMask: reqMask, name: name}
n := u.typ.NumField() n := u.typ.NumField()
if tag >= 0 && (tag < 16 || tag < 2*n) { // TODO: what are the right numbers here? if tag >= 0 && (tag < 16 || tag < 2*n) { // TODO: what are the right numbers here?
for len(u.dense) <= tag { for len(u.dense) <= tag {
@ -442,11 +459,17 @@ func typeUnmarshaler(t reflect.Type, tags string) unmarshaler {
tagArray := strings.Split(tags, ",") tagArray := strings.Split(tags, ",")
encoding := tagArray[0] encoding := tagArray[0]
name := "unknown" name := "unknown"
proto3 := false
validateUTF8 := true
for _, tag := range tagArray[3:] { for _, tag := range tagArray[3:] {
if strings.HasPrefix(tag, "name=") { if strings.HasPrefix(tag, "name=") {
name = tag[5:] name = tag[5:]
} }
if tag == "proto3" {
proto3 = true
}
} }
validateUTF8 = validateUTF8 && proto3
// Figure out packaging (pointer, slice, or both) // Figure out packaging (pointer, slice, or both)
slice := false slice := false
@ -594,6 +617,15 @@ func typeUnmarshaler(t reflect.Type, tags string) unmarshaler {
} }
return unmarshalBytesValue return unmarshalBytesValue
case reflect.String: case reflect.String:
if validateUTF8 {
if pointer {
return unmarshalUTF8StringPtr
}
if slice {
return unmarshalUTF8StringSlice
}
return unmarshalUTF8StringValue
}
if pointer { if pointer {
return unmarshalStringPtr return unmarshalStringPtr
} }
@ -1448,9 +1480,6 @@ func unmarshalStringValue(b []byte, f pointer, w int) ([]byte, error) {
return nil, io.ErrUnexpectedEOF return nil, io.ErrUnexpectedEOF
} }
v := string(b[:x]) v := string(b[:x])
if !utf8.ValidString(v) {
return nil, errInvalidUTF8
}
*f.toString() = v *f.toString() = v
return b[x:], nil return b[x:], nil
} }
@ -1468,9 +1497,6 @@ func unmarshalStringPtr(b []byte, f pointer, w int) ([]byte, error) {
return nil, io.ErrUnexpectedEOF return nil, io.ErrUnexpectedEOF
} }
v := string(b[:x]) v := string(b[:x])
if !utf8.ValidString(v) {
return nil, errInvalidUTF8
}
*f.toStringPtr() = &v *f.toStringPtr() = &v
return b[x:], nil return b[x:], nil
} }
@ -1488,14 +1514,72 @@ func unmarshalStringSlice(b []byte, f pointer, w int) ([]byte, error) {
return nil, io.ErrUnexpectedEOF return nil, io.ErrUnexpectedEOF
} }
v := string(b[:x]) v := string(b[:x])
if !utf8.ValidString(v) {
return nil, errInvalidUTF8
}
s := f.toStringSlice() s := f.toStringSlice()
*s = append(*s, v) *s = append(*s, v)
return b[x:], nil return b[x:], nil
} }
func unmarshalUTF8StringValue(b []byte, f pointer, w int) ([]byte, error) {
if w != WireBytes {
return b, errInternalBadWireType
}
x, n := decodeVarint(b)
if n == 0 {
return nil, io.ErrUnexpectedEOF
}
b = b[n:]
if x > uint64(len(b)) {
return nil, io.ErrUnexpectedEOF
}
v := string(b[:x])
*f.toString() = v
if !utf8.ValidString(v) {
return b[x:], errInvalidUTF8
}
return b[x:], nil
}
func unmarshalUTF8StringPtr(b []byte, f pointer, w int) ([]byte, error) {
if w != WireBytes {
return b, errInternalBadWireType
}
x, n := decodeVarint(b)
if n == 0 {
return nil, io.ErrUnexpectedEOF
}
b = b[n:]
if x > uint64(len(b)) {
return nil, io.ErrUnexpectedEOF
}
v := string(b[:x])
*f.toStringPtr() = &v
if !utf8.ValidString(v) {
return b[x:], errInvalidUTF8
}
return b[x:], nil
}
func unmarshalUTF8StringSlice(b []byte, f pointer, w int) ([]byte, error) {
if w != WireBytes {
return b, errInternalBadWireType
}
x, n := decodeVarint(b)
if n == 0 {
return nil, io.ErrUnexpectedEOF
}
b = b[n:]
if x > uint64(len(b)) {
return nil, io.ErrUnexpectedEOF
}
v := string(b[:x])
s := f.toStringSlice()
*s = append(*s, v)
if !utf8.ValidString(v) {
return b[x:], errInvalidUTF8
}
return b[x:], nil
}
var emptyBuf [0]byte var emptyBuf [0]byte
func unmarshalBytesValue(b []byte, f pointer, w int) ([]byte, error) { func unmarshalBytesValue(b []byte, f pointer, w int) ([]byte, error) {
@ -1674,6 +1758,7 @@ func makeUnmarshalMap(f *reflect.StructField) unmarshaler {
// Maps will be somewhat slow. Oh well. // Maps will be somewhat slow. Oh well.
// Read key and value from data. // Read key and value from data.
var nerr nonFatal
k := reflect.New(kt) k := reflect.New(kt)
v := reflect.New(vt) v := reflect.New(vt)
for len(b) > 0 { for len(b) > 0 {
@ -1694,7 +1779,7 @@ func makeUnmarshalMap(f *reflect.StructField) unmarshaler {
err = errInternalBadWireType // skip unknown tag err = errInternalBadWireType // skip unknown tag
} }
if err == nil { if nerr.Merge(err) {
continue continue
} }
if err != errInternalBadWireType { if err != errInternalBadWireType {
@ -1717,7 +1802,7 @@ func makeUnmarshalMap(f *reflect.StructField) unmarshaler {
// Insert into map. // Insert into map.
m.SetMapIndex(k.Elem(), v.Elem()) m.SetMapIndex(k.Elem(), v.Elem())
return r, nil return r, nerr.E
} }
} }
@ -1743,15 +1828,16 @@ func makeUnmarshalOneof(typ, ityp reflect.Type, unmarshal unmarshaler) unmarshal
// Unmarshal data into holder. // Unmarshal data into holder.
// We unmarshal into the first field of the holder object. // We unmarshal into the first field of the holder object.
var err error var err error
var nerr nonFatal
b, err = unmarshal(b, valToPointer(v).offset(field0), w) b, err = unmarshal(b, valToPointer(v).offset(field0), w)
if err != nil { if !nerr.Merge(err) {
return nil, err return nil, err
} }
// Write pointer to holder into target field. // Write pointer to holder into target field.
f.asPointerTo(ityp).Elem().Set(v) f.asPointerTo(ityp).Elem().Set(v)
return b, nil return b, nerr.E
} }
} }
@ -1864,7 +1950,7 @@ func encodeVarint(b []byte, x uint64) []byte {
// If there is an error, it returns 0,0. // If there is an error, it returns 0,0.
func decodeVarint(b []byte) (uint64, int) { func decodeVarint(b []byte) (uint64, int) {
var x, y uint64 var x, y uint64
if len(b) <= 0 { if len(b) == 0 {
goto bad goto bad
} }
x = uint64(b[0]) x = uint64(b[0])

View file

@ -353,7 +353,7 @@ func (tm *TextMarshaler) writeStruct(w *textWriter, sv reflect.Value) error {
return err return err
} }
} }
if err := tm.writeAny(w, key, props.mkeyprop); err != nil { if err := tm.writeAny(w, key, props.MapKeyProp); err != nil {
return err return err
} }
if err := w.WriteByte('\n'); err != nil { if err := w.WriteByte('\n'); err != nil {
@ -370,7 +370,7 @@ func (tm *TextMarshaler) writeStruct(w *textWriter, sv reflect.Value) error {
return err return err
} }
} }
if err := tm.writeAny(w, val, props.mvalprop); err != nil { if err := tm.writeAny(w, val, props.MapValProp); err != nil {
return err return err
} }
if err := w.WriteByte('\n'); err != nil { if err := w.WriteByte('\n'); err != nil {

View file

@ -630,17 +630,17 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) error {
if err := p.consumeToken(":"); err != nil { if err := p.consumeToken(":"); err != nil {
return err return err
} }
if err := p.readAny(key, props.mkeyprop); err != nil { if err := p.readAny(key, props.MapKeyProp); err != nil {
return err return err
} }
if err := p.consumeOptionalSeparator(); err != nil { if err := p.consumeOptionalSeparator(); err != nil {
return err return err
} }
case "value": case "value":
if err := p.checkForColon(props.mvalprop, dst.Type().Elem()); err != nil { if err := p.checkForColon(props.MapValProp, dst.Type().Elem()); err != nil {
return err return err
} }
if err := p.readAny(val, props.mvalprop); err != nil { if err := p.readAny(val, props.MapValProp); err != nil {
return err return err
} }
if err := p.consumeOptionalSeparator(); err != nil { if err := p.consumeOptionalSeparator(); err != nil {

View file

@ -130,10 +130,12 @@ func UnmarshalAny(any *any.Any, pb proto.Message) error {
// Is returns true if any value contains a given message type. // Is returns true if any value contains a given message type.
func Is(any *any.Any, pb proto.Message) bool { func Is(any *any.Any, pb proto.Message) bool {
aname, err := AnyMessageName(any) // The following is equivalent to AnyMessageName(any) == proto.MessageName(pb),
if err != nil { // but it avoids scanning TypeUrl for the slash.
if any == nil {
return false return false
} }
name := proto.MessageName(pb)
return aname == proto.MessageName(pb) prefix := len(any.TypeUrl) - len(name)
return prefix >= 1 && any.TypeUrl[prefix-1] == '/' && any.TypeUrl[prefix:] == name
} }

View file

@ -1,11 +1,13 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// source: google/protobuf/any.proto // source: google/protobuf/any.proto
package any // import "github.com/golang/protobuf/ptypes/any" package any
import proto "github.com/golang/protobuf/proto" import (
import fmt "fmt" fmt "fmt"
import math "math" proto "github.com/golang/protobuf/proto"
math "math"
)
// Reference imports to suppress errors if they are not otherwise used. // Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal var _ = proto.Marshal
@ -16,7 +18,7 @@ var _ = math.Inf
// is compatible with the proto package it is being compiled against. // is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the // A compilation error at this line likely means your copy of the
// proto package needs to be updated. // proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
// `Any` contains an arbitrary serialized protocol buffer message along with a // `Any` contains an arbitrary serialized protocol buffer message along with a
// URL that describes the type of the serialized message. // URL that describes the type of the serialized message.
@ -99,17 +101,18 @@ const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
// } // }
// //
type Any struct { type Any struct {
// A URL/resource name whose content describes the type of the // A URL/resource name that uniquely identifies the type of the serialized
// serialized protocol buffer message. // protocol buffer message. The last segment of the URL's path must represent
// the fully qualified name of the type (as in
// `path/google.protobuf.Duration`). The name should be in a canonical form
// (e.g., leading "." is not accepted).
// //
// For URLs which use the scheme `http`, `https`, or no scheme, the // In practice, teams usually precompile into the binary all types that they
// following restrictions and interpretations apply: // expect it to use in the context of Any. However, for URLs which use the
// scheme `http`, `https`, or no scheme, one can optionally set up a type
// server that maps type URLs to message definitions as follows:
// //
// * If no scheme is provided, `https` is assumed. // * If no scheme is provided, `https` is assumed.
// * The last segment of the URL's path must represent the fully
// qualified name of the type (as in `path/google.protobuf.Duration`).
// The name should be in a canonical form (e.g., leading "." is
// not accepted).
// * An HTTP GET on the URL must yield a [google.protobuf.Type][] // * An HTTP GET on the URL must yield a [google.protobuf.Type][]
// value in binary format, or produce an error. // value in binary format, or produce an error.
// * Applications are allowed to cache lookup results based on the // * Applications are allowed to cache lookup results based on the
@ -118,10 +121,14 @@ type Any struct {
// on changes to types. (Use versioned type names to manage // on changes to types. (Use versioned type names to manage
// breaking changes.) // breaking changes.)
// //
// Note: this functionality is not currently available in the official
// protobuf release, and it is not used for type URLs beginning with
// type.googleapis.com.
//
// Schemes other than `http`, `https` (or the empty scheme) might be // Schemes other than `http`, `https` (or the empty scheme) might be
// used with implementation specific semantics. // used with implementation specific semantics.
// //
TypeUrl string `protobuf:"bytes,1,opt,name=type_url,json=typeUrl" json:"type_url,omitempty"` TypeUrl string `protobuf:"bytes,1,opt,name=type_url,json=typeUrl,proto3" json:"type_url,omitempty"`
// Must be a valid serialized protocol buffer of the above specified type. // Must be a valid serialized protocol buffer of the above specified type.
Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"`
@ -133,17 +140,19 @@ func (m *Any) Reset() { *m = Any{} }
func (m *Any) String() string { return proto.CompactTextString(m) } func (m *Any) String() string { return proto.CompactTextString(m) }
func (*Any) ProtoMessage() {} func (*Any) ProtoMessage() {}
func (*Any) Descriptor() ([]byte, []int) { func (*Any) Descriptor() ([]byte, []int) {
return fileDescriptor_any_744b9ca530f228db, []int{0} return fileDescriptor_b53526c13ae22eb4, []int{0}
} }
func (*Any) XXX_WellKnownType() string { return "Any" } func (*Any) XXX_WellKnownType() string { return "Any" }
func (m *Any) XXX_Unmarshal(b []byte) error { func (m *Any) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Any.Unmarshal(m, b) return xxx_messageInfo_Any.Unmarshal(m, b)
} }
func (m *Any) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { func (m *Any) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_Any.Marshal(b, m, deterministic) return xxx_messageInfo_Any.Marshal(b, m, deterministic)
} }
func (dst *Any) XXX_Merge(src proto.Message) { func (m *Any) XXX_Merge(src proto.Message) {
xxx_messageInfo_Any.Merge(dst, src) xxx_messageInfo_Any.Merge(m, src)
} }
func (m *Any) XXX_Size() int { func (m *Any) XXX_Size() int {
return xxx_messageInfo_Any.Size(m) return xxx_messageInfo_Any.Size(m)
@ -172,9 +181,9 @@ func init() {
proto.RegisterType((*Any)(nil), "google.protobuf.Any") proto.RegisterType((*Any)(nil), "google.protobuf.Any")
} }
func init() { proto.RegisterFile("google/protobuf/any.proto", fileDescriptor_any_744b9ca530f228db) } func init() { proto.RegisterFile("google/protobuf/any.proto", fileDescriptor_b53526c13ae22eb4) }
var fileDescriptor_any_744b9ca530f228db = []byte{ var fileDescriptor_b53526c13ae22eb4 = []byte{
// 185 bytes of a gzipped FileDescriptorProto // 185 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x4c, 0xcf, 0xcf, 0x4f, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x4c, 0xcf, 0xcf, 0x4f,
0xcf, 0x49, 0xd5, 0x2f, 0x28, 0xca, 0x2f, 0xc9, 0x4f, 0x2a, 0x4d, 0xd3, 0x4f, 0xcc, 0xab, 0xd4, 0xcf, 0x49, 0xd5, 0x2f, 0x28, 0xca, 0x2f, 0xc9, 0x4f, 0x2a, 0x4d, 0xd3, 0x4f, 0xcc, 0xab, 0xd4,

View file

@ -82,7 +82,7 @@ func Duration(p *durpb.Duration) (time.Duration, error) {
return 0, fmt.Errorf("duration: %v is out of range for time.Duration", p) return 0, fmt.Errorf("duration: %v is out of range for time.Duration", p)
} }
if p.Nanos != 0 { if p.Nanos != 0 {
d += time.Duration(p.Nanos) d += time.Duration(p.Nanos) * time.Nanosecond
if (d < 0) != (p.Nanos < 0) { if (d < 0) != (p.Nanos < 0) {
return 0, fmt.Errorf("duration: %v is out of range for time.Duration", p) return 0, fmt.Errorf("duration: %v is out of range for time.Duration", p)
} }

View file

@ -1,11 +1,13 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// source: google/protobuf/duration.proto // source: google/protobuf/duration.proto
package duration // import "github.com/golang/protobuf/ptypes/duration" package duration
import proto "github.com/golang/protobuf/proto" import (
import fmt "fmt" fmt "fmt"
import math "math" proto "github.com/golang/protobuf/proto"
math "math"
)
// Reference imports to suppress errors if they are not otherwise used. // Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal var _ = proto.Marshal
@ -16,7 +18,7 @@ var _ = math.Inf
// is compatible with the proto package it is being compiled against. // is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the // A compilation error at this line likely means your copy of the
// proto package needs to be updated. // proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
// A Duration represents a signed, fixed-length span of time represented // A Duration represents a signed, fixed-length span of time represented
// as a count of seconds and fractions of seconds at nanosecond // as a count of seconds and fractions of seconds at nanosecond
@ -82,14 +84,14 @@ type Duration struct {
// Signed seconds of the span of time. Must be from -315,576,000,000 // Signed seconds of the span of time. Must be from -315,576,000,000
// to +315,576,000,000 inclusive. Note: these bounds are computed from: // to +315,576,000,000 inclusive. Note: these bounds are computed from:
// 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years // 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years
Seconds int64 `protobuf:"varint,1,opt,name=seconds" json:"seconds,omitempty"` Seconds int64 `protobuf:"varint,1,opt,name=seconds,proto3" json:"seconds,omitempty"`
// Signed fractions of a second at nanosecond resolution of the span // Signed fractions of a second at nanosecond resolution of the span
// of time. Durations less than one second are represented with a 0 // of time. Durations less than one second are represented with a 0
// `seconds` field and a positive or negative `nanos` field. For durations // `seconds` field and a positive or negative `nanos` field. For durations
// of one second or more, a non-zero value for the `nanos` field must be // of one second or more, a non-zero value for the `nanos` field must be
// of the same sign as the `seconds` field. Must be from -999,999,999 // of the same sign as the `seconds` field. Must be from -999,999,999
// to +999,999,999 inclusive. // to +999,999,999 inclusive.
Nanos int32 `protobuf:"varint,2,opt,name=nanos" json:"nanos,omitempty"` Nanos int32 `protobuf:"varint,2,opt,name=nanos,proto3" json:"nanos,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"` XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"` XXX_sizecache int32 `json:"-"`
@ -99,17 +101,19 @@ func (m *Duration) Reset() { *m = Duration{} }
func (m *Duration) String() string { return proto.CompactTextString(m) } func (m *Duration) String() string { return proto.CompactTextString(m) }
func (*Duration) ProtoMessage() {} func (*Duration) ProtoMessage() {}
func (*Duration) Descriptor() ([]byte, []int) { func (*Duration) Descriptor() ([]byte, []int) {
return fileDescriptor_duration_e7d612259e3f0613, []int{0} return fileDescriptor_23597b2ebd7ac6c5, []int{0}
} }
func (*Duration) XXX_WellKnownType() string { return "Duration" } func (*Duration) XXX_WellKnownType() string { return "Duration" }
func (m *Duration) XXX_Unmarshal(b []byte) error { func (m *Duration) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Duration.Unmarshal(m, b) return xxx_messageInfo_Duration.Unmarshal(m, b)
} }
func (m *Duration) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { func (m *Duration) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_Duration.Marshal(b, m, deterministic) return xxx_messageInfo_Duration.Marshal(b, m, deterministic)
} }
func (dst *Duration) XXX_Merge(src proto.Message) { func (m *Duration) XXX_Merge(src proto.Message) {
xxx_messageInfo_Duration.Merge(dst, src) xxx_messageInfo_Duration.Merge(m, src)
} }
func (m *Duration) XXX_Size() int { func (m *Duration) XXX_Size() int {
return xxx_messageInfo_Duration.Size(m) return xxx_messageInfo_Duration.Size(m)
@ -138,11 +142,9 @@ func init() {
proto.RegisterType((*Duration)(nil), "google.protobuf.Duration") proto.RegisterType((*Duration)(nil), "google.protobuf.Duration")
} }
func init() { func init() { proto.RegisterFile("google/protobuf/duration.proto", fileDescriptor_23597b2ebd7ac6c5) }
proto.RegisterFile("google/protobuf/duration.proto", fileDescriptor_duration_e7d612259e3f0613)
}
var fileDescriptor_duration_e7d612259e3f0613 = []byte{ var fileDescriptor_23597b2ebd7ac6c5 = []byte{
// 190 bytes of a gzipped FileDescriptorProto // 190 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x4b, 0xcf, 0xcf, 0x4f, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x4b, 0xcf, 0xcf, 0x4f,
0xcf, 0x49, 0xd5, 0x2f, 0x28, 0xca, 0x2f, 0xc9, 0x4f, 0x2a, 0x4d, 0xd3, 0x4f, 0x29, 0x2d, 0x4a, 0xcf, 0x49, 0xd5, 0x2f, 0x28, 0xca, 0x2f, 0xc9, 0x4f, 0x2a, 0x4d, 0xd3, 0x4f, 0x29, 0x2d, 0x4a,

View file

@ -111,11 +111,9 @@ func TimestampNow() *tspb.Timestamp {
// TimestampProto converts the time.Time to a google.protobuf.Timestamp proto. // TimestampProto converts the time.Time to a google.protobuf.Timestamp proto.
// It returns an error if the resulting Timestamp is invalid. // It returns an error if the resulting Timestamp is invalid.
func TimestampProto(t time.Time) (*tspb.Timestamp, error) { func TimestampProto(t time.Time) (*tspb.Timestamp, error) {
seconds := t.Unix()
nanos := int32(t.Sub(time.Unix(seconds, 0)))
ts := &tspb.Timestamp{ ts := &tspb.Timestamp{
Seconds: seconds, Seconds: t.Unix(),
Nanos: nanos, Nanos: int32(t.Nanosecond()),
} }
if err := validateTimestamp(ts); err != nil { if err := validateTimestamp(ts); err != nil {
return nil, err return nil, err

View file

@ -1,11 +1,13 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// source: google/protobuf/timestamp.proto // source: google/protobuf/timestamp.proto
package timestamp // import "github.com/golang/protobuf/ptypes/timestamp" package timestamp
import proto "github.com/golang/protobuf/proto" import (
import fmt "fmt" fmt "fmt"
import math "math" proto "github.com/golang/protobuf/proto"
math "math"
)
// Reference imports to suppress errors if they are not otherwise used. // Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal var _ = proto.Marshal
@ -16,7 +18,7 @@ var _ = math.Inf
// is compatible with the proto package it is being compiled against. // is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the // A compilation error at this line likely means your copy of the
// proto package needs to be updated. // proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
// A Timestamp represents a point in time independent of any time zone // A Timestamp represents a point in time independent of any time zone
// or calendar, represented as seconds and fractions of seconds at // or calendar, represented as seconds and fractions of seconds at
@ -81,7 +83,9 @@ const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
// {hour}, {min}, and {sec} are zero-padded to two digits each. The fractional // {hour}, {min}, and {sec} are zero-padded to two digits each. The fractional
// seconds, which can go up to 9 digits (i.e. up to 1 nanosecond resolution), // seconds, which can go up to 9 digits (i.e. up to 1 nanosecond resolution),
// are optional. The "Z" suffix indicates the timezone ("UTC"); the timezone // are optional. The "Z" suffix indicates the timezone ("UTC"); the timezone
// is required, though only UTC (as indicated by "Z") is presently supported. // is required. A proto3 JSON serializer should always use UTC (as indicated by
// "Z") when printing the Timestamp type and a proto3 JSON parser should be
// able to accept both UTC and other timezones (as indicated by an offset).
// //
// For example, "2017-01-15T01:30:15.01Z" encodes 15.01 seconds past // For example, "2017-01-15T01:30:15.01Z" encodes 15.01 seconds past
// 01:30 UTC on January 15, 2017. // 01:30 UTC on January 15, 2017.
@ -92,20 +96,20 @@ const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
// to this format using [`strftime`](https://docs.python.org/2/library/time.html#time.strftime) // to this format using [`strftime`](https://docs.python.org/2/library/time.html#time.strftime)
// with the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one // with the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one
// can use the Joda Time's [`ISODateTimeFormat.dateTime()`]( // can use the Joda Time's [`ISODateTimeFormat.dateTime()`](
// http://www.joda.org/joda-time/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime--) // http://www.joda.org/joda-time/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime--
// to obtain a formatter capable of generating timestamps in this format. // ) to obtain a formatter capable of generating timestamps in this format.
// //
// //
type Timestamp struct { type Timestamp struct {
// Represents seconds of UTC time since Unix epoch // Represents seconds of UTC time since Unix epoch
// 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to // 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to
// 9999-12-31T23:59:59Z inclusive. // 9999-12-31T23:59:59Z inclusive.
Seconds int64 `protobuf:"varint,1,opt,name=seconds" json:"seconds,omitempty"` Seconds int64 `protobuf:"varint,1,opt,name=seconds,proto3" json:"seconds,omitempty"`
// Non-negative fractions of a second at nanosecond resolution. Negative // Non-negative fractions of a second at nanosecond resolution. Negative
// second values with fractions must still have non-negative nanos values // second values with fractions must still have non-negative nanos values
// that count forward in time. Must be from 0 to 999,999,999 // that count forward in time. Must be from 0 to 999,999,999
// inclusive. // inclusive.
Nanos int32 `protobuf:"varint,2,opt,name=nanos" json:"nanos,omitempty"` Nanos int32 `protobuf:"varint,2,opt,name=nanos,proto3" json:"nanos,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"` XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"` XXX_sizecache int32 `json:"-"`
@ -115,17 +119,19 @@ func (m *Timestamp) Reset() { *m = Timestamp{} }
func (m *Timestamp) String() string { return proto.CompactTextString(m) } func (m *Timestamp) String() string { return proto.CompactTextString(m) }
func (*Timestamp) ProtoMessage() {} func (*Timestamp) ProtoMessage() {}
func (*Timestamp) Descriptor() ([]byte, []int) { func (*Timestamp) Descriptor() ([]byte, []int) {
return fileDescriptor_timestamp_b826e8e5fba671a8, []int{0} return fileDescriptor_292007bbfe81227e, []int{0}
} }
func (*Timestamp) XXX_WellKnownType() string { return "Timestamp" } func (*Timestamp) XXX_WellKnownType() string { return "Timestamp" }
func (m *Timestamp) XXX_Unmarshal(b []byte) error { func (m *Timestamp) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Timestamp.Unmarshal(m, b) return xxx_messageInfo_Timestamp.Unmarshal(m, b)
} }
func (m *Timestamp) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { func (m *Timestamp) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_Timestamp.Marshal(b, m, deterministic) return xxx_messageInfo_Timestamp.Marshal(b, m, deterministic)
} }
func (dst *Timestamp) XXX_Merge(src proto.Message) { func (m *Timestamp) XXX_Merge(src proto.Message) {
xxx_messageInfo_Timestamp.Merge(dst, src) xxx_messageInfo_Timestamp.Merge(m, src)
} }
func (m *Timestamp) XXX_Size() int { func (m *Timestamp) XXX_Size() int {
return xxx_messageInfo_Timestamp.Size(m) return xxx_messageInfo_Timestamp.Size(m)
@ -154,11 +160,9 @@ func init() {
proto.RegisterType((*Timestamp)(nil), "google.protobuf.Timestamp") proto.RegisterType((*Timestamp)(nil), "google.protobuf.Timestamp")
} }
func init() { func init() { proto.RegisterFile("google/protobuf/timestamp.proto", fileDescriptor_292007bbfe81227e) }
proto.RegisterFile("google/protobuf/timestamp.proto", fileDescriptor_timestamp_b826e8e5fba671a8)
}
var fileDescriptor_timestamp_b826e8e5fba671a8 = []byte{ var fileDescriptor_292007bbfe81227e = []byte{
// 191 bytes of a gzipped FileDescriptorProto // 191 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x4f, 0xcf, 0xcf, 0x4f, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x4f, 0xcf, 0xcf, 0x4f,
0xcf, 0x49, 0xd5, 0x2f, 0x28, 0xca, 0x2f, 0xc9, 0x4f, 0x2a, 0x4d, 0xd3, 0x2f, 0xc9, 0xcc, 0x4d, 0xcf, 0x49, 0xd5, 0x2f, 0x28, 0xca, 0x2f, 0xc9, 0x4f, 0x2a, 0x4d, 0xd3, 0x2f, 0xc9, 0xcc, 0x4d,

View file

@ -16,7 +16,7 @@ const cpuSetSize = _CPU_SETSIZE / _NCPUBITS
type CPUSet [cpuSetSize]cpuMask type CPUSet [cpuSetSize]cpuMask
func schedAffinity(trap uintptr, pid int, set *CPUSet) error { func schedAffinity(trap uintptr, pid int, set *CPUSet) error {
_, _, e := RawSyscall(trap, uintptr(pid), uintptr(unsafe.Sizeof(set)), uintptr(unsafe.Pointer(set))) _, _, e := RawSyscall(trap, uintptr(pid), uintptr(unsafe.Sizeof(*set)), uintptr(unsafe.Pointer(set)))
if e != 0 { if e != 0 {
return errnoErr(e) return errnoErr(e)
} }

14
vendor/golang.org/x/sys/unix/aliases.go generated vendored Normal file
View file

@ -0,0 +1,14 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build darwin dragonfly freebsd linux netbsd openbsd solaris
// +build go1.9
package unix
import "syscall"
type Signal = syscall.Signal
type Errno = syscall.Errno
type SysProcAttr = syscall.SysProcAttr

View file

@ -13,17 +13,17 @@
// Just jump to package syscall's implementation for all these functions. // Just jump to package syscall's implementation for all these functions.
// The runtime may know about them. // The runtime may know about them.
TEXT ·Syscall(SB),NOSPLIT,$0-64 TEXT ·Syscall(SB),NOSPLIT,$0-56
JMP syscall·Syscall(SB) JMP syscall·Syscall(SB)
TEXT ·Syscall6(SB),NOSPLIT,$0-88 TEXT ·Syscall6(SB),NOSPLIT,$0-80
JMP syscall·Syscall6(SB) JMP syscall·Syscall6(SB)
TEXT ·Syscall9(SB),NOSPLIT,$0-112 TEXT ·Syscall9(SB),NOSPLIT,$0-104
JMP syscall·Syscall9(SB) JMP syscall·Syscall9(SB)
TEXT ·RawSyscall(SB),NOSPLIT,$0-64 TEXT ·RawSyscall(SB),NOSPLIT,$0-56
JMP syscall·RawSyscall(SB) JMP syscall·RawSyscall(SB)
TEXT ·RawSyscall6(SB),NOSPLIT,$0-88 TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
JMP syscall·RawSyscall6(SB) JMP syscall·RawSyscall6(SB)

View file

@ -7,7 +7,7 @@
package unix package unix
import ( import (
errorspkg "errors" "errors"
"fmt" "fmt"
) )
@ -60,26 +60,26 @@ func CapRightsSet(rights *CapRights, setrights []uint64) error {
n := caparsize(rights) n := caparsize(rights)
if n < capArSizeMin || n > capArSizeMax { if n < capArSizeMin || n > capArSizeMax {
return errorspkg.New("bad rights size") return errors.New("bad rights size")
} }
for _, right := range setrights { for _, right := range setrights {
if caprver(right) != CAP_RIGHTS_VERSION_00 { if caprver(right) != CAP_RIGHTS_VERSION_00 {
return errorspkg.New("bad right version") return errors.New("bad right version")
} }
i, err := rightToIndex(right) i, err := rightToIndex(right)
if err != nil { if err != nil {
return err return err
} }
if i >= n { if i >= n {
return errorspkg.New("index overflow") return errors.New("index overflow")
} }
if capidxbit(rights.Rights[i]) != capidxbit(right) { if capidxbit(rights.Rights[i]) != capidxbit(right) {
return errorspkg.New("index mismatch") return errors.New("index mismatch")
} }
rights.Rights[i] |= right rights.Rights[i] |= right
if capidxbit(rights.Rights[i]) != capidxbit(right) { if capidxbit(rights.Rights[i]) != capidxbit(right) {
return errorspkg.New("index mismatch (after assign)") return errors.New("index mismatch (after assign)")
} }
} }
@ -95,26 +95,26 @@ func CapRightsClear(rights *CapRights, clearrights []uint64) error {
n := caparsize(rights) n := caparsize(rights)
if n < capArSizeMin || n > capArSizeMax { if n < capArSizeMin || n > capArSizeMax {
return errorspkg.New("bad rights size") return errors.New("bad rights size")
} }
for _, right := range clearrights { for _, right := range clearrights {
if caprver(right) != CAP_RIGHTS_VERSION_00 { if caprver(right) != CAP_RIGHTS_VERSION_00 {
return errorspkg.New("bad right version") return errors.New("bad right version")
} }
i, err := rightToIndex(right) i, err := rightToIndex(right)
if err != nil { if err != nil {
return err return err
} }
if i >= n { if i >= n {
return errorspkg.New("index overflow") return errors.New("index overflow")
} }
if capidxbit(rights.Rights[i]) != capidxbit(right) { if capidxbit(rights.Rights[i]) != capidxbit(right) {
return errorspkg.New("index mismatch") return errors.New("index mismatch")
} }
rights.Rights[i] &= ^(right & 0x01FFFFFFFFFFFFFF) rights.Rights[i] &= ^(right & 0x01FFFFFFFFFFFFFF)
if capidxbit(rights.Rights[i]) != capidxbit(right) { if capidxbit(rights.Rights[i]) != capidxbit(right) {
return errorspkg.New("index mismatch (after assign)") return errors.New("index mismatch (after assign)")
} }
} }
@ -130,22 +130,22 @@ func CapRightsIsSet(rights *CapRights, setrights []uint64) (bool, error) {
n := caparsize(rights) n := caparsize(rights)
if n < capArSizeMin || n > capArSizeMax { if n < capArSizeMin || n > capArSizeMax {
return false, errorspkg.New("bad rights size") return false, errors.New("bad rights size")
} }
for _, right := range setrights { for _, right := range setrights {
if caprver(right) != CAP_RIGHTS_VERSION_00 { if caprver(right) != CAP_RIGHTS_VERSION_00 {
return false, errorspkg.New("bad right version") return false, errors.New("bad right version")
} }
i, err := rightToIndex(right) i, err := rightToIndex(right)
if err != nil { if err != nil {
return false, err return false, err
} }
if i >= n { if i >= n {
return false, errorspkg.New("index overflow") return false, errors.New("index overflow")
} }
if capidxbit(rights.Rights[i]) != capidxbit(right) { if capidxbit(rights.Rights[i]) != capidxbit(right) {
return false, errorspkg.New("index mismatch") return false, errors.New("index mismatch")
} }
if (rights.Rights[i] & right) != right { if (rights.Rights[i] & right) != right {
return false, nil return false, nil

View file

@ -6,97 +6,12 @@
package unix package unix
import "unsafe" import "syscall"
// readInt returns the size-bytes unsigned integer in native byte order at offset off.
func readInt(b []byte, off, size uintptr) (u uint64, ok bool) {
if len(b) < int(off+size) {
return 0, false
}
if isBigEndian {
return readIntBE(b[off:], size), true
}
return readIntLE(b[off:], size), true
}
func readIntBE(b []byte, size uintptr) uint64 {
switch size {
case 1:
return uint64(b[0])
case 2:
_ = b[1] // bounds check hint to compiler; see golang.org/issue/14808
return uint64(b[1]) | uint64(b[0])<<8
case 4:
_ = b[3] // bounds check hint to compiler; see golang.org/issue/14808
return uint64(b[3]) | uint64(b[2])<<8 | uint64(b[1])<<16 | uint64(b[0])<<24
case 8:
_ = b[7] // bounds check hint to compiler; see golang.org/issue/14808
return uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 |
uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56
default:
panic("syscall: readInt with unsupported size")
}
}
func readIntLE(b []byte, size uintptr) uint64 {
switch size {
case 1:
return uint64(b[0])
case 2:
_ = b[1] // bounds check hint to compiler; see golang.org/issue/14808
return uint64(b[0]) | uint64(b[1])<<8
case 4:
_ = b[3] // bounds check hint to compiler; see golang.org/issue/14808
return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24
case 8:
_ = b[7] // bounds check hint to compiler; see golang.org/issue/14808
return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 |
uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56
default:
panic("syscall: readInt with unsupported size")
}
}
// ParseDirent parses up to max directory entries in buf, // ParseDirent parses up to max directory entries in buf,
// appending the names to names. It returns the number of // appending the names to names. It returns the number of
// bytes consumed from buf, the number of entries added // bytes consumed from buf, the number of entries added
// to names, and the new names slice. // to names, and the new names slice.
func ParseDirent(buf []byte, max int, names []string) (consumed int, count int, newnames []string) { func ParseDirent(buf []byte, max int, names []string) (consumed int, count int, newnames []string) {
origlen := len(buf) return syscall.ParseDirent(buf, max, names)
count = 0
for max != 0 && len(buf) > 0 {
reclen, ok := direntReclen(buf)
if !ok || reclen > uint64(len(buf)) {
return origlen, count, names
}
rec := buf[:reclen]
buf = buf[reclen:]
ino, ok := direntIno(rec)
if !ok {
break
}
if ino == 0 { // File absent in directory.
continue
}
const namoff = uint64(unsafe.Offsetof(Dirent{}.Name))
namlen, ok := direntNamlen(rec)
if !ok || namoff+namlen > uint64(len(rec)) {
break
}
name := rec[namoff : namoff+namlen]
for i, c := range name {
if c == 0 {
name = name[:i]
break
}
}
// Check for useless names before allocating a string.
if string(name) == "." || string(name) == ".." {
continue
}
max--
count++
names = append(names, string(name))
}
return origlen - len(buf), count, names
} }

View file

@ -12,6 +12,16 @@ import "unsafe"
// systems by flock_linux_32bit.go to be SYS_FCNTL64. // systems by flock_linux_32bit.go to be SYS_FCNTL64.
var fcntl64Syscall uintptr = SYS_FCNTL var fcntl64Syscall uintptr = SYS_FCNTL
// FcntlInt performs a fcntl syscall on fd with the provided command and argument.
func FcntlInt(fd uintptr, cmd, arg int) (int, error) {
valptr, _, errno := Syscall(fcntl64Syscall, fd, uintptr(cmd), uintptr(arg))
var err error
if errno != 0 {
err = errno
}
return int(valptr), err
}
// FcntlFlock performs a fcntl syscall for the F_GETLK, F_SETLK or F_SETLKW command. // FcntlFlock performs a fcntl syscall for the F_GETLK, F_SETLK or F_SETLKW command.
func FcntlFlock(fd uintptr, cmd int, lk *Flock_t) error { func FcntlFlock(fd uintptr, cmd int, lk *Flock_t) error {
_, _, errno := Syscall(fcntl64Syscall, fd, uintptr(cmd), uintptr(unsafe.Pointer(lk))) _, _, errno := Syscall(fcntl64Syscall, fd, uintptr(cmd), uintptr(unsafe.Pointer(lk)))

View file

@ -36,12 +36,3 @@ gccgoRealSyscallNoError(uintptr_t trap, uintptr_t a1, uintptr_t a2, uintptr_t a3
{ {
return syscall(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9); return syscall(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9);
} }
// Define the use function in C so that it is not inlined.
extern void use(void *) __asm__ (GOSYM_PREFIX GOPKGPATH ".use") __attribute__((noinline));
void
use(void *p __attribute__ ((unused)))
{
}

30
vendor/golang.org/x/sys/unix/ioctl.go generated vendored Normal file
View file

@ -0,0 +1,30 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build darwin dragonfly freebsd linux netbsd openbsd solaris
package unix
import "runtime"
// IoctlSetWinsize performs an ioctl on fd with a *Winsize argument.
//
// To change fd's window size, the req argument should be TIOCSWINSZ.
func IoctlSetWinsize(fd int, req uint, value *Winsize) error {
// TODO: if we get the chance, remove the req parameter and
// hardcode TIOCSWINSZ.
err := ioctlSetWinsize(fd, req, value)
runtime.KeepAlive(value)
return err
}
// IoctlSetTermios performs an ioctl on fd with a *Termios.
//
// The req value will usually be TCSETA or TIOCSETA.
func IoctlSetTermios(fd int, req uint, value *Termios) error {
// TODO: if we get the chance, remove the req parameter.
err := ioctlSetTermios(fd, req, value)
runtime.KeepAlive(value)
return err
}

View file

@ -42,6 +42,10 @@ func main() {
log.Fatal(err) log.Fatal(err)
} }
// Intentionally export __val fields in Fsid and Sigset_t
valRegex := regexp.MustCompile(`type (Fsid|Sigset_t) struct {(\s+)X__val(\s+\S+\s+)}`)
b = valRegex.ReplaceAll(b, []byte("type $1 struct {${2}Val$3}"))
// If we have empty Ptrace structs, we should delete them. Only s390x emits // If we have empty Ptrace structs, we should delete them. Only s390x emits
// nonempty Ptrace structs. // nonempty Ptrace structs.
ptraceRexexp := regexp.MustCompile(`type Ptrace((Psw|Fpregs|Per) struct {\s*})`) ptraceRexexp := regexp.MustCompile(`type Ptrace((Psw|Fpregs|Per) struct {\s*})`)
@ -65,16 +69,13 @@ func main() {
spareFieldsRegex := regexp.MustCompile(`X__spare\S*`) spareFieldsRegex := regexp.MustCompile(`X__spare\S*`)
b = spareFieldsRegex.ReplaceAll(b, []byte("_")) b = spareFieldsRegex.ReplaceAll(b, []byte("_"))
// We refuse to export private fields on s390x // Remove cgo padding fields
if goarch == "s390x" && goos == "linux" { removePaddingFieldsRegex := regexp.MustCompile(`Pad_cgo_\d+`)
// Remove cgo padding fields b = removePaddingFieldsRegex.ReplaceAll(b, []byte("_"))
removeFieldsRegex := regexp.MustCompile(`Pad_cgo_\d+`)
b = removeFieldsRegex.ReplaceAll(b, []byte("_"))
// Remove padding, hidden, or unused fields // Remove padding, hidden, or unused fields
removeFieldsRegex = regexp.MustCompile(`X_\S+`) removeFieldsRegex = regexp.MustCompile(`\b(X_\S+|Padding)`)
b = removeFieldsRegex.ReplaceAll(b, []byte("_")) b = removeFieldsRegex.ReplaceAll(b, []byte("_"))
}
// Remove the first line of warning from cgo // Remove the first line of warning from cgo
b = b[bytes.IndexByte(b, '\n')+1:] b = b[bytes.IndexByte(b, '\n')+1:]

View file

@ -8,31 +8,88 @@
package unix package unix
import ( import (
"errors"
"fmt"
"strconv"
"syscall" "syscall"
"unsafe" "unsafe"
) )
const ( const (
SYS_PLEDGE = 108 _SYS_PLEDGE = 108
) )
// Pledge implements the pledge syscall. For more information see pledge(2). // Pledge implements the pledge syscall.
func Pledge(promises string, paths []string) error { //
promisesPtr, err := syscall.BytePtrFromString(promises) // The pledge syscall does not accept execpromises on OpenBSD releases
// before 6.3.
//
// execpromises must be empty when Pledge is called on OpenBSD
// releases predating 6.3, otherwise an error will be returned.
//
// For more information see pledge(2).
func Pledge(promises, execpromises string) error {
maj, min, err := majmin()
if err != nil { if err != nil {
return err return err
} }
promisesUnsafe, pathsUnsafe := unsafe.Pointer(promisesPtr), unsafe.Pointer(nil)
if paths != nil { // If OpenBSD <= 5.9, pledge is not available.
var pathsPtr []*byte if (maj == 5 && min != 9) || maj < 5 {
if pathsPtr, err = syscall.SlicePtrFromStrings(paths); err != nil { return fmt.Errorf("pledge syscall is not available on OpenBSD %d.%d", maj, min)
}
// If OpenBSD <= 6.2 and execpromises is not empty
// return an error - execpromises is not available before 6.3
if (maj < 6 || (maj == 6 && min <= 2)) && execpromises != "" {
return fmt.Errorf("cannot use execpromises on OpenBSD %d.%d", maj, min)
}
pptr, err := syscall.BytePtrFromString(promises)
if err != nil {
return err
}
// This variable will hold either a nil unsafe.Pointer or
// an unsafe.Pointer to a string (execpromises).
var expr unsafe.Pointer
// If we're running on OpenBSD > 6.2, pass execpromises to the syscall.
if maj > 6 || (maj == 6 && min > 2) {
exptr, err := syscall.BytePtrFromString(execpromises)
if err != nil {
return err return err
} }
pathsUnsafe = unsafe.Pointer(&pathsPtr[0]) expr = unsafe.Pointer(exptr)
} }
_, _, e := syscall.Syscall(SYS_PLEDGE, uintptr(promisesUnsafe), uintptr(pathsUnsafe), 0)
_, _, e := syscall.Syscall(_SYS_PLEDGE, uintptr(unsafe.Pointer(pptr)), uintptr(expr), 0)
if e != 0 { if e != 0 {
return e return e
} }
return nil return nil
} }
// majmin returns major and minor version number for an OpenBSD system.
func majmin() (major int, minor int, err error) {
var v Utsname
err = Uname(&v)
if err != nil {
return
}
major, err = strconv.Atoi(string(v.Release[0]))
if err != nil {
err = errors.New("cannot parse major version number returned by uname")
return
}
minor, err = strconv.Atoi(string(v.Release[2]))
if err != nil {
err = errors.New("cannot parse minor version number returned by uname")
return
}
return
}

View file

@ -11,24 +11,27 @@
// system, set $GOOS and $GOARCH to the desired system. For example, if // system, set $GOOS and $GOARCH to the desired system. For example, if
// you want to view documentation for freebsd/arm on linux/amd64, set $GOOS // you want to view documentation for freebsd/arm on linux/amd64, set $GOOS
// to freebsd and $GOARCH to arm. // to freebsd and $GOARCH to arm.
//
// The primary use of this package is inside other packages that provide a more // The primary use of this package is inside other packages that provide a more
// portable interface to the system, such as "os", "time" and "net". Use // portable interface to the system, such as "os", "time" and "net". Use
// those packages rather than this one if you can. // those packages rather than this one if you can.
//
// For details of the functions and data types in this package consult // For details of the functions and data types in this package consult
// the manuals for the appropriate operating system. // the manuals for the appropriate operating system.
//
// These calls return err == nil to indicate success; otherwise // These calls return err == nil to indicate success; otherwise
// err represents an operating system error describing the failure and // err represents an operating system error describing the failure and
// holds a value of type syscall.Errno. // holds a value of type syscall.Errno.
package unix // import "golang.org/x/sys/unix" package unix // import "golang.org/x/sys/unix"
import "strings"
// ByteSliceFromString returns a NUL-terminated slice of bytes // ByteSliceFromString returns a NUL-terminated slice of bytes
// containing the text of s. If s contains a NUL byte at any // containing the text of s. If s contains a NUL byte at any
// location, it returns (nil, EINVAL). // location, it returns (nil, EINVAL).
func ByteSliceFromString(s string) ([]byte, error) { func ByteSliceFromString(s string) ([]byte, error) {
for i := 0; i < len(s); i++ { if strings.IndexByte(s, 0) != -1 {
if s[i] == 0 { return nil, EINVAL
return nil, EINVAL
}
} }
a := make([]byte, len(s)+1) a := make([]byte, len(s)+1)
copy(a, s) copy(a, s)

View file

@ -206,7 +206,7 @@ func (sa *SockaddrDatalink) sockaddr() (unsafe.Pointer, _Socklen, error) {
return unsafe.Pointer(&sa.raw), SizeofSockaddrDatalink, nil return unsafe.Pointer(&sa.raw), SizeofSockaddrDatalink, nil
} }
func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, error) { func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
switch rsa.Addr.Family { switch rsa.Addr.Family {
case AF_LINK: case AF_LINK:
pp := (*RawSockaddrDatalink)(unsafe.Pointer(rsa)) pp := (*RawSockaddrDatalink)(unsafe.Pointer(rsa))
@ -286,7 +286,7 @@ func Accept(fd int) (nfd int, sa Sockaddr, err error) {
Close(nfd) Close(nfd)
return 0, nil, ECONNABORTED return 0, nil, ECONNABORTED
} }
sa, err = anyToSockaddr(&rsa) sa, err = anyToSockaddr(fd, &rsa)
if err != nil { if err != nil {
Close(nfd) Close(nfd)
nfd = 0 nfd = 0
@ -306,52 +306,11 @@ func Getsockname(fd int) (sa Sockaddr, err error) {
rsa.Addr.Family = AF_UNIX rsa.Addr.Family = AF_UNIX
rsa.Addr.Len = SizeofSockaddrUnix rsa.Addr.Len = SizeofSockaddrUnix
} }
return anyToSockaddr(&rsa) return anyToSockaddr(fd, &rsa)
} }
//sysnb socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) //sysnb socketpair(domain int, typ int, proto int, fd *[2]int32) (err error)
func GetsockoptByte(fd, level, opt int) (value byte, err error) {
var n byte
vallen := _Socklen(1)
err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen)
return n, err
}
func GetsockoptInet4Addr(fd, level, opt int) (value [4]byte, err error) {
vallen := _Socklen(4)
err = getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen)
return value, err
}
func GetsockoptIPMreq(fd, level, opt int) (*IPMreq, error) {
var value IPMreq
vallen := _Socklen(SizeofIPMreq)
err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
return &value, err
}
func GetsockoptIPv6Mreq(fd, level, opt int) (*IPv6Mreq, error) {
var value IPv6Mreq
vallen := _Socklen(SizeofIPv6Mreq)
err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
return &value, err
}
func GetsockoptIPv6MTUInfo(fd, level, opt int) (*IPv6MTUInfo, error) {
var value IPv6MTUInfo
vallen := _Socklen(SizeofIPv6MTUInfo)
err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
return &value, err
}
func GetsockoptICMPv6Filter(fd, level, opt int) (*ICMPv6Filter, error) {
var value ICMPv6Filter
vallen := _Socklen(SizeofICMPv6Filter)
err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
return &value, err
}
// GetsockoptString returns the string value of the socket option opt for the // GetsockoptString returns the string value of the socket option opt for the
// socket associated with fd at the given socket level. // socket associated with fd at the given socket level.
func GetsockoptString(fd, level, opt int) (string, error) { func GetsockoptString(fd, level, opt int) (string, error) {
@ -397,7 +356,7 @@ func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from
recvflags = int(msg.Flags) recvflags = int(msg.Flags)
// source address is only specified if the socket is unconnected // source address is only specified if the socket is unconnected
if rsa.Addr.Family != AF_UNSPEC { if rsa.Addr.Family != AF_UNSPEC {
from, err = anyToSockaddr(&rsa) from, err = anyToSockaddr(fd, &rsa)
} }
return return
} }

View file

@ -13,7 +13,7 @@
package unix package unix
import ( import (
errorspkg "errors" "errors"
"syscall" "syscall"
"unsafe" "unsafe"
) )
@ -36,6 +36,7 @@ func Getwd() (string, error) {
return "", ENOTSUP return "", ENOTSUP
} }
// SockaddrDatalink implements the Sockaddr interface for AF_LINK type sockets.
type SockaddrDatalink struct { type SockaddrDatalink struct {
Len uint8 Len uint8
Family uint8 Family uint8
@ -76,18 +77,6 @@ func nametomib(name string) (mib []_C_int, err error) {
return buf[0 : n/siz], nil return buf[0 : n/siz], nil
} }
func direntIno(buf []byte) (uint64, bool) {
return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino))
}
func direntReclen(buf []byte) (uint64, bool) {
return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
}
func direntNamlen(buf []byte) (uint64, bool) {
return readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen))
}
//sys ptrace(request int, pid int, addr uintptr, data uintptr) (err error) //sys ptrace(request int, pid int, addr uintptr, data uintptr) (err error)
func PtraceAttach(pid int) (err error) { return ptrace(PT_ATTACH, pid, 0, 0) } func PtraceAttach(pid int) (err error) { return ptrace(PT_ATTACH, pid, 0, 0) }
func PtraceDetach(pid int) (err error) { return ptrace(PT_DETACH, pid, 0, 0) } func PtraceDetach(pid int) (err error) { return ptrace(PT_DETACH, pid, 0, 0) }
@ -109,7 +98,7 @@ type attrList struct {
func getAttrList(path string, attrList attrList, attrBuf []byte, options uint) (attrs [][]byte, err error) { func getAttrList(path string, attrList attrList, attrBuf []byte, options uint) (attrs [][]byte, err error) {
if len(attrBuf) < 4 { if len(attrBuf) < 4 {
return nil, errorspkg.New("attrBuf too small") return nil, errors.New("attrBuf too small")
} }
attrList.bitmapCount = attrBitMapCount attrList.bitmapCount = attrBitMapCount
@ -145,12 +134,12 @@ func getAttrList(path string, attrList attrList, attrBuf []byte, options uint) (
for i := uint32(0); int(i) < len(dat); { for i := uint32(0); int(i) < len(dat); {
header := dat[i:] header := dat[i:]
if len(header) < 8 { if len(header) < 8 {
return attrs, errorspkg.New("truncated attribute header") return attrs, errors.New("truncated attribute header")
} }
datOff := *(*int32)(unsafe.Pointer(&header[0])) datOff := *(*int32)(unsafe.Pointer(&header[0]))
attrLen := *(*uint32)(unsafe.Pointer(&header[4])) attrLen := *(*uint32)(unsafe.Pointer(&header[4]))
if datOff < 0 || uint32(datOff)+attrLen > uint32(len(dat)) { if datOff < 0 || uint32(datOff)+attrLen > uint32(len(dat)) {
return attrs, errorspkg.New("truncated results; attrBuf too small") return attrs, errors.New("truncated results; attrBuf too small")
} }
end := uint32(datOff) + attrLen end := uint32(datOff) + attrLen
attrs = append(attrs, dat[datOff:end]) attrs = append(attrs, dat[datOff:end])
@ -187,6 +176,112 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
return return
} }
func xattrPointer(dest []byte) *byte {
// It's only when dest is set to NULL that the OS X implementations of
// getxattr() and listxattr() return the current sizes of the named attributes.
// An empty byte array is not sufficient. To maintain the same behaviour as the
// linux implementation, we wrap around the system calls and pass in NULL when
// dest is empty.
var destp *byte
if len(dest) > 0 {
destp = &dest[0]
}
return destp
}
//sys getxattr(path string, attr string, dest *byte, size int, position uint32, options int) (sz int, err error)
func Getxattr(path string, attr string, dest []byte) (sz int, err error) {
return getxattr(path, attr, xattrPointer(dest), len(dest), 0, 0)
}
func Lgetxattr(link string, attr string, dest []byte) (sz int, err error) {
return getxattr(link, attr, xattrPointer(dest), len(dest), 0, XATTR_NOFOLLOW)
}
//sys fgetxattr(fd int, attr string, dest *byte, size int, position uint32, options int) (sz int, err error)
func Fgetxattr(fd int, attr string, dest []byte) (sz int, err error) {
return fgetxattr(fd, attr, xattrPointer(dest), len(dest), 0, 0)
}
//sys setxattr(path string, attr string, data *byte, size int, position uint32, options int) (err error)
func Setxattr(path string, attr string, data []byte, flags int) (err error) {
// The parameters for the OS X implementation vary slightly compared to the
// linux system call, specifically the position parameter:
//
// linux:
// int setxattr(
// const char *path,
// const char *name,
// const void *value,
// size_t size,
// int flags
// );
//
// darwin:
// int setxattr(
// const char *path,
// const char *name,
// void *value,
// size_t size,
// u_int32_t position,
// int options
// );
//
// position specifies the offset within the extended attribute. In the
// current implementation, only the resource fork extended attribute makes
// use of this argument. For all others, position is reserved. We simply
// default to setting it to zero.
return setxattr(path, attr, xattrPointer(data), len(data), 0, flags)
}
func Lsetxattr(link string, attr string, data []byte, flags int) (err error) {
return setxattr(link, attr, xattrPointer(data), len(data), 0, flags|XATTR_NOFOLLOW)
}
//sys fsetxattr(fd int, attr string, data *byte, size int, position uint32, options int) (err error)
func Fsetxattr(fd int, attr string, data []byte, flags int) (err error) {
return fsetxattr(fd, attr, xattrPointer(data), len(data), 0, 0)
}
//sys removexattr(path string, attr string, options int) (err error)
func Removexattr(path string, attr string) (err error) {
// We wrap around and explicitly zero out the options provided to the OS X
// implementation of removexattr, we do so for interoperability with the
// linux variant.
return removexattr(path, attr, 0)
}
func Lremovexattr(link string, attr string) (err error) {
return removexattr(link, attr, XATTR_NOFOLLOW)
}
//sys fremovexattr(fd int, attr string, options int) (err error)
func Fremovexattr(fd int, attr string) (err error) {
return fremovexattr(fd, attr, 0)
}
//sys listxattr(path string, dest *byte, size int, options int) (sz int, err error)
func Listxattr(path string, dest []byte) (sz int, err error) {
return listxattr(path, xattrPointer(dest), len(dest), 0)
}
func Llistxattr(link string, dest []byte) (sz int, err error) {
return listxattr(link, xattrPointer(dest), len(dest), XATTR_NOFOLLOW)
}
//sys flistxattr(fd int, dest *byte, size int, options int) (sz int, err error)
func Flistxattr(fd int, dest []byte) (sz int, err error) {
return flistxattr(fd, xattrPointer(dest), len(dest), 0)
}
func setattrlistTimes(path string, times []Timespec, flags int) error { func setattrlistTimes(path string, times []Timespec, flags int) error {
_p0, err := BytePtrFromString(path) _p0, err := BytePtrFromString(path)
if err != nil { if err != nil {
@ -242,11 +337,11 @@ func IoctlSetInt(fd int, req uint, value int) error {
return ioctl(fd, req, uintptr(value)) return ioctl(fd, req, uintptr(value))
} }
func IoctlSetWinsize(fd int, req uint, value *Winsize) error { func ioctlSetWinsize(fd int, req uint, value *Winsize) error {
return ioctl(fd, req, uintptr(unsafe.Pointer(value))) return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
} }
func IoctlSetTermios(fd int, req uint, value *Termios) error { func ioctlSetTermios(fd int, req uint, value *Termios) error {
return ioctl(fd, req, uintptr(unsafe.Pointer(value))) return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
} }
@ -341,6 +436,7 @@ func Uname(uname *Utsname) error {
//sys Flock(fd int, how int) (err error) //sys Flock(fd int, how int) (err error)
//sys Fpathconf(fd int, name int) (val int, err error) //sys Fpathconf(fd int, name int) (val int, err error)
//sys Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64 //sys Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64
//sys Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) = SYS_FSTATAT64
//sys Fstatfs(fd int, stat *Statfs_t) (err error) = SYS_FSTATFS64 //sys Fstatfs(fd int, stat *Statfs_t) (err error) = SYS_FSTATFS64
//sys Fsync(fd int) (err error) //sys Fsync(fd int) (err error)
//sys Ftruncate(fd int, length int64) (err error) //sys Ftruncate(fd int, length int64) (err error)
@ -457,14 +553,6 @@ func Uname(uname *Utsname) error {
// Watchevent // Watchevent
// Waitevent // Waitevent
// Modwatch // Modwatch
// Getxattr
// Fgetxattr
// Setxattr
// Fsetxattr
// Removexattr
// Fremovexattr
// Listxattr
// Flistxattr
// Fsctl // Fsctl
// Initgroups // Initgroups
// Posix_spawn // Posix_spawn

View file

@ -14,6 +14,7 @@ package unix
import "unsafe" import "unsafe"
// SockaddrDatalink implements the Sockaddr interface for AF_LINK type sockets.
type SockaddrDatalink struct { type SockaddrDatalink struct {
Len uint8 Len uint8
Family uint8 Family uint8
@ -56,22 +57,6 @@ func nametomib(name string) (mib []_C_int, err error) {
return buf[0 : n/siz], nil return buf[0 : n/siz], nil
} }
func direntIno(buf []byte) (uint64, bool) {
return readInt(buf, unsafe.Offsetof(Dirent{}.Fileno), unsafe.Sizeof(Dirent{}.Fileno))
}
func direntReclen(buf []byte) (uint64, bool) {
namlen, ok := direntNamlen(buf)
if !ok {
return 0, false
}
return (16 + namlen + 1 + 7) &^ 7, true
}
func direntNamlen(buf []byte) (uint64, bool) {
return readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen))
}
//sysnb pipe() (r int, w int, err error) //sysnb pipe() (r int, w int, err error)
func Pipe(p []int) (err error) { func Pipe(p []int) (err error) {
@ -102,7 +87,7 @@ func Accept4(fd, flags int) (nfd int, sa Sockaddr, err error) {
if len > SizeofSockaddrAny { if len > SizeofSockaddrAny {
panic("RawSockaddrAny too small") panic("RawSockaddrAny too small")
} }
sa, err = anyToSockaddr(&rsa) sa, err = anyToSockaddr(fd, &rsa)
if err != nil { if err != nil {
Close(nfd) Close(nfd)
nfd = 0 nfd = 0
@ -158,11 +143,11 @@ func IoctlSetInt(fd int, req uint, value int) error {
return ioctl(fd, req, uintptr(value)) return ioctl(fd, req, uintptr(value))
} }
func IoctlSetWinsize(fd int, req uint, value *Winsize) error { func ioctlSetWinsize(fd int, req uint, value *Winsize) error {
return ioctl(fd, req, uintptr(unsafe.Pointer(value))) return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
} }
func IoctlSetTermios(fd int, req uint, value *Termios) error { func ioctlSetTermios(fd int, req uint, value *Termios) error {
return ioctl(fd, req, uintptr(unsafe.Pointer(value))) return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
} }
@ -266,10 +251,12 @@ func Uname(uname *Utsname) error {
//sys Fchdir(fd int) (err error) //sys Fchdir(fd int) (err error)
//sys Fchflags(fd int, flags int) (err error) //sys Fchflags(fd int, flags int) (err error)
//sys Fchmod(fd int, mode uint32) (err error) //sys Fchmod(fd int, mode uint32) (err error)
//sys Fchmodat(dirfd int, path string, mode uint32, flags int) (err error)
//sys Fchown(fd int, uid int, gid int) (err error) //sys Fchown(fd int, uid int, gid int) (err error)
//sys Flock(fd int, how int) (err error) //sys Flock(fd int, how int) (err error)
//sys Fpathconf(fd int, name int) (val int, err error) //sys Fpathconf(fd int, name int) (val int, err error)
//sys Fstat(fd int, stat *Stat_t) (err error) //sys Fstat(fd int, stat *Stat_t) (err error)
//sys Fstatat(fd int, path string, stat *Stat_t, flags int) (err error)
//sys Fstatfs(fd int, stat *Statfs_t) (err error) //sys Fstatfs(fd int, stat *Statfs_t) (err error)
//sys Fsync(fd int) (err error) //sys Fsync(fd int) (err error)
//sys Ftruncate(fd int, length int64) (err error) //sys Ftruncate(fd int, length int64) (err error)

View file

@ -12,8 +12,11 @@
package unix package unix
import "unsafe" import (
"unsafe"
)
// SockaddrDatalink implements the Sockaddr interface for AF_LINK type sockets.
type SockaddrDatalink struct { type SockaddrDatalink struct {
Len uint8 Len uint8
Family uint8 Family uint8
@ -54,18 +57,6 @@ func nametomib(name string) (mib []_C_int, err error) {
return buf[0 : n/siz], nil return buf[0 : n/siz], nil
} }
func direntIno(buf []byte) (uint64, bool) {
return readInt(buf, unsafe.Offsetof(Dirent{}.Fileno), unsafe.Sizeof(Dirent{}.Fileno))
}
func direntReclen(buf []byte) (uint64, bool) {
return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
}
func direntNamlen(buf []byte) (uint64, bool) {
return readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen))
}
//sysnb pipe() (r int, w int, err error) //sysnb pipe() (r int, w int, err error)
func Pipe(p []int) (err error) { func Pipe(p []int) (err error) {
@ -97,7 +88,7 @@ func Accept4(fd, flags int) (nfd int, sa Sockaddr, err error) {
if len > SizeofSockaddrAny { if len > SizeofSockaddrAny {
panic("RawSockaddrAny too small") panic("RawSockaddrAny too small")
} }
sa, err = anyToSockaddr(&rsa) sa, err = anyToSockaddr(fd, &rsa)
if err != nil { if err != nil {
Close(nfd) Close(nfd)
nfd = 0 nfd = 0
@ -142,232 +133,6 @@ func setattrlistTimes(path string, times []Timespec, flags int) error {
return ENOSYS return ENOSYS
} }
// Derive extattr namespace and attribute name
func xattrnamespace(fullattr string) (ns int, attr string, err error) {
s := -1
for idx, val := range fullattr {
if val == '.' {
s = idx
break
}
}
if s == -1 {
return -1, "", ENOATTR
}
namespace := fullattr[0:s]
attr = fullattr[s+1:]
switch namespace {
case "user":
return EXTATTR_NAMESPACE_USER, attr, nil
case "system":
return EXTATTR_NAMESPACE_SYSTEM, attr, nil
default:
return -1, "", ENOATTR
}
}
func initxattrdest(dest []byte, idx int) (d unsafe.Pointer) {
if len(dest) > idx {
return unsafe.Pointer(&dest[idx])
} else {
return unsafe.Pointer(_zero)
}
}
// FreeBSD implements its own syscalls to handle extended attributes
func Getxattr(file string, attr string, dest []byte) (sz int, err error) {
d := initxattrdest(dest, 0)
destsize := len(dest)
nsid, a, err := xattrnamespace(attr)
if err != nil {
return -1, err
}
return ExtattrGetFile(file, nsid, a, uintptr(d), destsize)
}
func Fgetxattr(fd int, attr string, dest []byte) (sz int, err error) {
d := initxattrdest(dest, 0)
destsize := len(dest)
nsid, a, err := xattrnamespace(attr)
if err != nil {
return -1, err
}
return ExtattrGetFd(fd, nsid, a, uintptr(d), destsize)
}
func Lgetxattr(link string, attr string, dest []byte) (sz int, err error) {
d := initxattrdest(dest, 0)
destsize := len(dest)
nsid, a, err := xattrnamespace(attr)
if err != nil {
return -1, err
}
return ExtattrGetLink(link, nsid, a, uintptr(d), destsize)
}
// flags are unused on FreeBSD
func Fsetxattr(fd int, attr string, data []byte, flags int) (err error) {
d := unsafe.Pointer(&data[0])
datasiz := len(data)
nsid, a, err := xattrnamespace(attr)
if err != nil {
return
}
_, err = ExtattrSetFd(fd, nsid, a, uintptr(d), datasiz)
return
}
func Setxattr(file string, attr string, data []byte, flags int) (err error) {
d := unsafe.Pointer(&data[0])
datasiz := len(data)
nsid, a, err := xattrnamespace(attr)
if err != nil {
return
}
_, err = ExtattrSetFile(file, nsid, a, uintptr(d), datasiz)
return
}
func Lsetxattr(link string, attr string, data []byte, flags int) (err error) {
d := unsafe.Pointer(&data[0])
datasiz := len(data)
nsid, a, err := xattrnamespace(attr)
if err != nil {
return
}
_, err = ExtattrSetLink(link, nsid, a, uintptr(d), datasiz)
return
}
func Removexattr(file string, attr string) (err error) {
nsid, a, err := xattrnamespace(attr)
if err != nil {
return
}
err = ExtattrDeleteFile(file, nsid, a)
return
}
func Fremovexattr(fd int, attr string) (err error) {
nsid, a, err := xattrnamespace(attr)
if err != nil {
return
}
err = ExtattrDeleteFd(fd, nsid, a)
return
}
func Lremovexattr(link string, attr string) (err error) {
nsid, a, err := xattrnamespace(attr)
if err != nil {
return
}
err = ExtattrDeleteLink(link, nsid, a)
return
}
func Listxattr(file string, dest []byte) (sz int, err error) {
d := initxattrdest(dest, 0)
destsiz := len(dest)
// FreeBSD won't allow you to list xattrs from multiple namespaces
s := 0
for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} {
stmp, e := ExtattrListFile(file, nsid, uintptr(d), destsiz)
/* Errors accessing system attrs are ignored so that
* we can implement the Linux-like behavior of omitting errors that
* we don't have read permissions on
*
* Linux will still error if we ask for user attributes on a file that
* we don't have read permissions on, so don't ignore those errors
*/
if e != nil && e == EPERM && nsid != EXTATTR_NAMESPACE_USER {
continue
} else if e != nil {
return s, e
}
s += stmp
destsiz -= s
if destsiz < 0 {
destsiz = 0
}
d = initxattrdest(dest, s)
}
return s, nil
}
func Flistxattr(fd int, dest []byte) (sz int, err error) {
d := initxattrdest(dest, 0)
destsiz := len(dest)
s := 0
for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} {
stmp, e := ExtattrListFd(fd, nsid, uintptr(d), destsiz)
if e != nil && e == EPERM && nsid != EXTATTR_NAMESPACE_USER {
continue
} else if e != nil {
return s, e
}
s += stmp
destsiz -= s
if destsiz < 0 {
destsiz = 0
}
d = initxattrdest(dest, s)
}
return s, nil
}
func Llistxattr(link string, dest []byte) (sz int, err error) {
d := initxattrdest(dest, 0)
destsiz := len(dest)
s := 0
for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} {
stmp, e := ExtattrListLink(link, nsid, uintptr(d), destsiz)
if e != nil && e == EPERM && nsid != EXTATTR_NAMESPACE_USER {
continue
} else if e != nil {
return s, e
}
s += stmp
destsiz -= s
if destsiz < 0 {
destsiz = 0
}
d = initxattrdest(dest, s)
}
return s, nil
}
//sys ioctl(fd int, req uint, arg uintptr) (err error) //sys ioctl(fd int, req uint, arg uintptr) (err error)
// ioctl itself should not be exposed directly, but additional get/set // ioctl itself should not be exposed directly, but additional get/set
@ -379,11 +144,11 @@ func IoctlSetInt(fd int, req uint, value int) error {
return ioctl(fd, req, uintptr(value)) return ioctl(fd, req, uintptr(value))
} }
func IoctlSetWinsize(fd int, req uint, value *Winsize) error { func ioctlSetWinsize(fd int, req uint, value *Winsize) error {
return ioctl(fd, req, uintptr(unsafe.Pointer(value))) return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
} }
func IoctlSetTermios(fd int, req uint, value *Termios) error { func ioctlSetTermios(fd int, req uint, value *Termios) error {
return ioctl(fd, req, uintptr(unsafe.Pointer(value))) return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
} }
@ -493,6 +258,7 @@ func Uname(uname *Utsname) error {
//sys Flock(fd int, how int) (err error) //sys Flock(fd int, how int) (err error)
//sys Fpathconf(fd int, name int) (val int, err error) //sys Fpathconf(fd int, name int) (val int, err error)
//sys Fstat(fd int, stat *Stat_t) (err error) //sys Fstat(fd int, stat *Stat_t) (err error)
//sys Fstatat(fd int, path string, stat *Stat_t, flags int) (err error)
//sys Fstatfs(fd int, stat *Statfs_t) (err error) //sys Fstatfs(fd int, stat *Statfs_t) (err error)
//sys Fsync(fd int) (err error) //sys Fsync(fd int) (err error)
//sys Ftruncate(fd int, length int64) (err error) //sys Ftruncate(fd int, length int64) (err error)
@ -616,14 +382,6 @@ func Uname(uname *Utsname) error {
// Watchevent // Watchevent
// Waitevent // Waitevent
// Modwatch // Modwatch
// Getxattr
// Fgetxattr
// Setxattr
// Fsetxattr
// Removexattr
// Fremovexattr
// Listxattr
// Flistxattr
// Fsctl // Fsctl
// Initgroups // Initgroups
// Posix_spawn // Posix_spawn

View file

@ -16,13 +16,6 @@ import (
"unsafe" "unsafe"
) )
// SyscallNoError may be used instead of Syscall for syscalls that don't fail.
func SyscallNoError(trap, a1, a2, a3 uintptr) (r1, r2 uintptr)
// RawSyscallNoError may be used instead of RawSyscall for syscalls that don't
// fail.
func RawSyscallNoError(trap, a1, a2, a3 uintptr) (r1, r2 uintptr)
/* /*
* Wrapped * Wrapped
*/ */
@ -68,11 +61,11 @@ func IoctlSetInt(fd int, req uint, value int) error {
return ioctl(fd, req, uintptr(value)) return ioctl(fd, req, uintptr(value))
} }
func IoctlSetWinsize(fd int, req uint, value *Winsize) error { func ioctlSetWinsize(fd int, req uint, value *Winsize) error {
return ioctl(fd, req, uintptr(unsafe.Pointer(value))) return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
} }
func IoctlSetTermios(fd int, req uint, value *Termios) error { func ioctlSetTermios(fd int, req uint, value *Termios) error {
return ioctl(fd, req, uintptr(unsafe.Pointer(value))) return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
} }
@ -155,8 +148,6 @@ func Unlink(path string) error {
//sys Unlinkat(dirfd int, path string, flags int) (err error) //sys Unlinkat(dirfd int, path string, flags int) (err error)
//sys utimes(path string, times *[2]Timeval) (err error)
func Utimes(path string, tv []Timeval) error { func Utimes(path string, tv []Timeval) error {
if tv == nil { if tv == nil {
err := utimensat(AT_FDCWD, path, nil, 0) err := utimensat(AT_FDCWD, path, nil, 0)
@ -214,20 +205,14 @@ func UtimesNanoAt(dirfd int, path string, ts []Timespec, flags int) error {
return utimensat(dirfd, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), flags) return utimensat(dirfd, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), flags)
} }
//sys futimesat(dirfd int, path *byte, times *[2]Timeval) (err error)
func Futimesat(dirfd int, path string, tv []Timeval) error { func Futimesat(dirfd int, path string, tv []Timeval) error {
pathp, err := BytePtrFromString(path)
if err != nil {
return err
}
if tv == nil { if tv == nil {
return futimesat(dirfd, pathp, nil) return futimesat(dirfd, path, nil)
} }
if len(tv) != 2 { if len(tv) != 2 {
return EINVAL return EINVAL
} }
return futimesat(dirfd, pathp, (*[2]Timeval)(unsafe.Pointer(&tv[0]))) return futimesat(dirfd, path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
} }
func Futimes(fd int, tv []Timeval) (err error) { func Futimes(fd int, tv []Timeval) (err error) {
@ -420,6 +405,7 @@ func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) {
return unsafe.Pointer(&sa.raw), sl, nil return unsafe.Pointer(&sa.raw), sl, nil
} }
// SockaddrLinklayer implements the Sockaddr interface for AF_PACKET type sockets.
type SockaddrLinklayer struct { type SockaddrLinklayer struct {
Protocol uint16 Protocol uint16
Ifindex int Ifindex int
@ -446,6 +432,7 @@ func (sa *SockaddrLinklayer) sockaddr() (unsafe.Pointer, _Socklen, error) {
return unsafe.Pointer(&sa.raw), SizeofSockaddrLinklayer, nil return unsafe.Pointer(&sa.raw), SizeofSockaddrLinklayer, nil
} }
// SockaddrNetlink implements the Sockaddr interface for AF_NETLINK type sockets.
type SockaddrNetlink struct { type SockaddrNetlink struct {
Family uint16 Family uint16
Pad uint16 Pad uint16
@ -462,6 +449,8 @@ func (sa *SockaddrNetlink) sockaddr() (unsafe.Pointer, _Socklen, error) {
return unsafe.Pointer(&sa.raw), SizeofSockaddrNetlink, nil return unsafe.Pointer(&sa.raw), SizeofSockaddrNetlink, nil
} }
// SockaddrHCI implements the Sockaddr interface for AF_BLUETOOTH type sockets
// using the HCI protocol.
type SockaddrHCI struct { type SockaddrHCI struct {
Dev uint16 Dev uint16
Channel uint16 Channel uint16
@ -475,6 +464,72 @@ func (sa *SockaddrHCI) sockaddr() (unsafe.Pointer, _Socklen, error) {
return unsafe.Pointer(&sa.raw), SizeofSockaddrHCI, nil return unsafe.Pointer(&sa.raw), SizeofSockaddrHCI, nil
} }
// SockaddrL2 implements the Sockaddr interface for AF_BLUETOOTH type sockets
// using the L2CAP protocol.
type SockaddrL2 struct {
PSM uint16
CID uint16
Addr [6]uint8
AddrType uint8
raw RawSockaddrL2
}
func (sa *SockaddrL2) sockaddr() (unsafe.Pointer, _Socklen, error) {
sa.raw.Family = AF_BLUETOOTH
psm := (*[2]byte)(unsafe.Pointer(&sa.raw.Psm))
psm[0] = byte(sa.PSM)
psm[1] = byte(sa.PSM >> 8)
for i := 0; i < len(sa.Addr); i++ {
sa.raw.Bdaddr[i] = sa.Addr[len(sa.Addr)-1-i]
}
cid := (*[2]byte)(unsafe.Pointer(&sa.raw.Cid))
cid[0] = byte(sa.CID)
cid[1] = byte(sa.CID >> 8)
sa.raw.Bdaddr_type = sa.AddrType
return unsafe.Pointer(&sa.raw), SizeofSockaddrL2, nil
}
// SockaddrRFCOMM implements the Sockaddr interface for AF_BLUETOOTH type sockets
// using the RFCOMM protocol.
//
// Server example:
//
// fd, _ := Socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM)
// _ = unix.Bind(fd, &unix.SockaddrRFCOMM{
// Channel: 1,
// Addr: [6]uint8{0, 0, 0, 0, 0, 0}, // BDADDR_ANY or 00:00:00:00:00:00
// })
// _ = Listen(fd, 1)
// nfd, sa, _ := Accept(fd)
// fmt.Printf("conn addr=%v fd=%d", sa.(*unix.SockaddrRFCOMM).Addr, nfd)
// Read(nfd, buf)
//
// Client example:
//
// fd, _ := Socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM)
// _ = Connect(fd, &SockaddrRFCOMM{
// Channel: 1,
// Addr: [6]byte{0x11, 0x22, 0x33, 0xaa, 0xbb, 0xcc}, // CC:BB:AA:33:22:11
// })
// Write(fd, []byte(`hello`))
type SockaddrRFCOMM struct {
// Addr represents a bluetooth address, byte ordering is little-endian.
Addr [6]uint8
// Channel is a designated bluetooth channel, only 1-30 are available for use.
// Since Linux 2.6.7 and further zero value is the first available channel.
Channel uint8
raw RawSockaddrRFCOMM
}
func (sa *SockaddrRFCOMM) sockaddr() (unsafe.Pointer, _Socklen, error) {
sa.raw.Family = AF_BLUETOOTH
sa.raw.Channel = sa.Channel
sa.raw.Bdaddr = sa.Addr
return unsafe.Pointer(&sa.raw), SizeofSockaddrRFCOMM, nil
}
// SockaddrCAN implements the Sockaddr interface for AF_CAN type sockets. // SockaddrCAN implements the Sockaddr interface for AF_CAN type sockets.
// The RxID and TxID fields are used for transport protocol addressing in // The RxID and TxID fields are used for transport protocol addressing in
// (CAN_TP16, CAN_TP20, CAN_MCNET, and CAN_ISOTP), they can be left with // (CAN_TP16, CAN_TP20, CAN_MCNET, and CAN_ISOTP), they can be left with
@ -637,7 +692,7 @@ func (sa *SockaddrVM) sockaddr() (unsafe.Pointer, _Socklen, error) {
return unsafe.Pointer(&sa.raw), SizeofSockaddrVM, nil return unsafe.Pointer(&sa.raw), SizeofSockaddrVM, nil
} }
func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, error) { func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
switch rsa.Addr.Family { switch rsa.Addr.Family {
case AF_NETLINK: case AF_NETLINK:
pp := (*RawSockaddrNetlink)(unsafe.Pointer(rsa)) pp := (*RawSockaddrNetlink)(unsafe.Pointer(rsa))
@ -714,6 +769,30 @@ func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, error) {
Port: pp.Port, Port: pp.Port,
} }
return sa, nil return sa, nil
case AF_BLUETOOTH:
proto, err := GetsockoptInt(fd, SOL_SOCKET, SO_PROTOCOL)
if err != nil {
return nil, err
}
// only BTPROTO_L2CAP and BTPROTO_RFCOMM can accept connections
switch proto {
case BTPROTO_L2CAP:
pp := (*RawSockaddrL2)(unsafe.Pointer(rsa))
sa := &SockaddrL2{
PSM: pp.Psm,
CID: pp.Cid,
Addr: pp.Bdaddr,
AddrType: pp.Bdaddr_type,
}
return sa, nil
case BTPROTO_RFCOMM:
pp := (*RawSockaddrRFCOMM)(unsafe.Pointer(rsa))
sa := &SockaddrRFCOMM{
Channel: pp.Channel,
Addr: pp.Bdaddr,
}
return sa, nil
}
} }
return nil, EAFNOSUPPORT return nil, EAFNOSUPPORT
} }
@ -725,7 +804,7 @@ func Accept(fd int) (nfd int, sa Sockaddr, err error) {
if err != nil { if err != nil {
return return
} }
sa, err = anyToSockaddr(&rsa) sa, err = anyToSockaddr(fd, &rsa)
if err != nil { if err != nil {
Close(nfd) Close(nfd)
nfd = 0 nfd = 0
@ -743,7 +822,7 @@ func Accept4(fd int, flags int) (nfd int, sa Sockaddr, err error) {
if len > SizeofSockaddrAny { if len > SizeofSockaddrAny {
panic("RawSockaddrAny too small") panic("RawSockaddrAny too small")
} }
sa, err = anyToSockaddr(&rsa) sa, err = anyToSockaddr(fd, &rsa)
if err != nil { if err != nil {
Close(nfd) Close(nfd)
nfd = 0 nfd = 0
@ -757,20 +836,7 @@ func Getsockname(fd int) (sa Sockaddr, err error) {
if err = getsockname(fd, &rsa, &len); err != nil { if err = getsockname(fd, &rsa, &len); err != nil {
return return
} }
return anyToSockaddr(&rsa) return anyToSockaddr(fd, &rsa)
}
func GetsockoptInet4Addr(fd, level, opt int) (value [4]byte, err error) {
vallen := _Socklen(4)
err = getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen)
return value, err
}
func GetsockoptIPMreq(fd, level, opt int) (*IPMreq, error) {
var value IPMreq
vallen := _Socklen(SizeofIPMreq)
err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
return &value, err
} }
func GetsockoptIPMreqn(fd, level, opt int) (*IPMreqn, error) { func GetsockoptIPMreqn(fd, level, opt int) (*IPMreqn, error) {
@ -780,27 +846,6 @@ func GetsockoptIPMreqn(fd, level, opt int) (*IPMreqn, error) {
return &value, err return &value, err
} }
func GetsockoptIPv6Mreq(fd, level, opt int) (*IPv6Mreq, error) {
var value IPv6Mreq
vallen := _Socklen(SizeofIPv6Mreq)
err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
return &value, err
}
func GetsockoptIPv6MTUInfo(fd, level, opt int) (*IPv6MTUInfo, error) {
var value IPv6MTUInfo
vallen := _Socklen(SizeofIPv6MTUInfo)
err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
return &value, err
}
func GetsockoptICMPv6Filter(fd, level, opt int) (*ICMPv6Filter, error) {
var value ICMPv6Filter
vallen := _Socklen(SizeofICMPv6Filter)
err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
return &value, err
}
func GetsockoptUcred(fd, level, opt int) (*Ucred, error) { func GetsockoptUcred(fd, level, opt int) (*Ucred, error) {
var value Ucred var value Ucred
vallen := _Socklen(SizeofUcred) vallen := _Socklen(SizeofUcred)
@ -956,15 +1001,17 @@ func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from
} }
var dummy byte var dummy byte
if len(oob) > 0 { if len(oob) > 0 {
var sockType int if len(p) == 0 {
sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE) var sockType int
if err != nil { sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE)
return if err != nil {
} return
// receive at least one normal byte }
if sockType != SOCK_DGRAM && len(p) == 0 { // receive at least one normal byte
iov.Base = &dummy if sockType != SOCK_DGRAM {
iov.SetLen(1) iov.Base = &dummy
iov.SetLen(1)
}
} }
msg.Control = &oob[0] msg.Control = &oob[0]
msg.SetControllen(len(oob)) msg.SetControllen(len(oob))
@ -978,7 +1025,7 @@ func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from
recvflags = int(msg.Flags) recvflags = int(msg.Flags)
// source address is only specified if the socket is unconnected // source address is only specified if the socket is unconnected
if rsa.Addr.Family != AF_UNSPEC { if rsa.Addr.Family != AF_UNSPEC {
from, err = anyToSockaddr(&rsa) from, err = anyToSockaddr(fd, &rsa)
} }
return return
} }
@ -1008,15 +1055,17 @@ func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error)
} }
var dummy byte var dummy byte
if len(oob) > 0 { if len(oob) > 0 {
var sockType int if len(p) == 0 {
sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE) var sockType int
if err != nil { sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE)
return 0, err if err != nil {
} return 0, err
// send at least one normal byte }
if sockType != SOCK_DGRAM && len(p) == 0 { // send at least one normal byte
iov.Base = &dummy if sockType != SOCK_DGRAM {
iov.SetLen(1) iov.Base = &dummy
iov.SetLen(1)
}
} }
msg.Control = &oob[0] msg.Control = &oob[0]
msg.SetControllen(len(oob)) msg.SetControllen(len(oob))
@ -1197,22 +1246,6 @@ func ReadDirent(fd int, buf []byte) (n int, err error) {
return Getdents(fd, buf) return Getdents(fd, buf)
} }
func direntIno(buf []byte) (uint64, bool) {
return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino))
}
func direntReclen(buf []byte) (uint64, bool) {
return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
}
func direntNamlen(buf []byte) (uint64, bool) {
reclen, ok := direntReclen(buf)
if !ok {
return 0, false
}
return reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true
}
//sys mount(source string, target string, fstype string, flags uintptr, data *byte) (err error) //sys mount(source string, target string, fstype string, flags uintptr, data *byte) (err error)
func Mount(source string, target string, fstype string, flags uintptr, data string) (err error) { func Mount(source string, target string, fstype string, flags uintptr, data string) (err error) {
@ -1245,19 +1278,21 @@ func Mount(source string, target string, fstype string, flags uintptr, data stri
//sys CopyFileRange(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error) //sys CopyFileRange(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error)
//sys Dup(oldfd int) (fd int, err error) //sys Dup(oldfd int) (fd int, err error)
//sys Dup3(oldfd int, newfd int, flags int) (err error) //sys Dup3(oldfd int, newfd int, flags int) (err error)
//sysnb EpollCreate(size int) (fd int, err error)
//sysnb EpollCreate1(flag int) (fd int, err error) //sysnb EpollCreate1(flag int) (fd int, err error)
//sysnb EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error) //sysnb EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error)
//sys Eventfd(initval uint, flags int) (fd int, err error) = SYS_EVENTFD2 //sys Eventfd(initval uint, flags int) (fd int, err error) = SYS_EVENTFD2
//sys Exit(code int) = SYS_EXIT_GROUP //sys Exit(code int) = SYS_EXIT_GROUP
//sys Faccessat(dirfd int, path string, mode uint32, flags int) (err error)
//sys Fallocate(fd int, mode uint32, off int64, len int64) (err error) //sys Fallocate(fd int, mode uint32, off int64, len int64) (err error)
//sys Fchdir(fd int) (err error) //sys Fchdir(fd int) (err error)
//sys Fchmod(fd int, mode uint32) (err error) //sys Fchmod(fd int, mode uint32) (err error)
//sys Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) //sys Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error)
//sys fcntl(fd int, cmd int, arg int) (val int, err error) //sys fcntl(fd int, cmd int, arg int) (val int, err error)
//sys Fdatasync(fd int) (err error) //sys Fdatasync(fd int) (err error)
//sys Fgetxattr(fd int, attr string, dest []byte) (sz int, err error)
//sys Flistxattr(fd int, dest []byte) (sz int, err error)
//sys Flock(fd int, how int) (err error) //sys Flock(fd int, how int) (err error)
//sys Fremovexattr(fd int, attr string) (err error)
//sys Fsetxattr(fd int, attr string, dest []byte, flags int) (err error)
//sys Fsync(fd int) (err error) //sys Fsync(fd int) (err error)
//sys Getdents(fd int, buf []byte) (n int, err error) = SYS_GETDENTS64 //sys Getdents(fd int, buf []byte) (n int, err error) = SYS_GETDENTS64
//sysnb Getpgid(pid int) (pgid int, err error) //sysnb Getpgid(pid int) (pgid int, err error)
@ -1288,6 +1323,7 @@ func Getpgrp() (pid int) {
//sys Mkdirat(dirfd int, path string, mode uint32) (err error) //sys Mkdirat(dirfd int, path string, mode uint32) (err error)
//sys Mknodat(dirfd int, path string, mode uint32, dev int) (err error) //sys Mknodat(dirfd int, path string, mode uint32, dev int) (err error)
//sys Nanosleep(time *Timespec, leftover *Timespec) (err error) //sys Nanosleep(time *Timespec, leftover *Timespec) (err error)
//sys PerfEventOpen(attr *PerfEventAttr, pid int, cpu int, groupFd int, flags int) (fd int, err error)
//sys PivotRoot(newroot string, putold string) (err error) = SYS_PIVOT_ROOT //sys PivotRoot(newroot string, putold string) (err error) = SYS_PIVOT_ROOT
//sysnb prlimit(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) = SYS_PRLIMIT64 //sysnb prlimit(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) = SYS_PRLIMIT64
//sys Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (err error) //sys Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (err error)
@ -1295,6 +1331,7 @@ func Getpgrp() (pid int) {
//sys read(fd int, p []byte) (n int, err error) //sys read(fd int, p []byte) (n int, err error)
//sys Removexattr(path string, attr string) (err error) //sys Removexattr(path string, attr string) (err error)
//sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) //sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)
//sys Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) (err error)
//sys RequestKey(keyType string, description string, callback string, destRingid int) (id int, err error) //sys RequestKey(keyType string, description string, callback string, destRingid int) (id int, err error)
//sys Setdomainname(p []byte) (err error) //sys Setdomainname(p []byte) (err error)
//sys Sethostname(p []byte) (err error) //sys Sethostname(p []byte) (err error)
@ -1329,7 +1366,6 @@ func Setgid(uid int) (err error) {
//sysnb Uname(buf *Utsname) (err error) //sysnb Uname(buf *Utsname) (err error)
//sys Unmount(target string, flags int) (err error) = SYS_UMOUNT2 //sys Unmount(target string, flags int) (err error) = SYS_UMOUNT2
//sys Unshare(flags int) (err error) //sys Unshare(flags int) (err error)
//sys Ustat(dev int, ubuf *Ustat_t) (err error)
//sys write(fd int, p []byte) (n int, err error) //sys write(fd int, p []byte) (n int, err error)
//sys exitThread(code int) (err error) = SYS_EXIT //sys exitThread(code int) (err error) = SYS_EXIT
//sys readlen(fd int, p *byte, np int) (n int, err error) = SYS_READ //sys readlen(fd int, p *byte, np int) (n int, err error) = SYS_READ
@ -1379,6 +1415,77 @@ func Vmsplice(fd int, iovs []Iovec, flags int) (int, error) {
return int(n), nil return int(n), nil
} }
//sys faccessat(dirfd int, path string, mode uint32) (err error)
func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {
if flags & ^(AT_SYMLINK_NOFOLLOW|AT_EACCESS) != 0 {
return EINVAL
}
// The Linux kernel faccessat system call does not take any flags.
// The glibc faccessat implements the flags itself; see
// https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/faccessat.c;hb=HEAD
// Because people naturally expect syscall.Faccessat to act
// like C faccessat, we do the same.
if flags == 0 {
return faccessat(dirfd, path, mode)
}
var st Stat_t
if err := Fstatat(dirfd, path, &st, flags&AT_SYMLINK_NOFOLLOW); err != nil {
return err
}
mode &= 7
if mode == 0 {
return nil
}
var uid int
if flags&AT_EACCESS != 0 {
uid = Geteuid()
} else {
uid = Getuid()
}
if uid == 0 {
if mode&1 == 0 {
// Root can read and write any file.
return nil
}
if st.Mode&0111 != 0 {
// Root can execute any file that anybody can execute.
return nil
}
return EACCES
}
var fmode uint32
if uint32(uid) == st.Uid {
fmode = (st.Mode >> 6) & 7
} else {
var gid int
if flags&AT_EACCESS != 0 {
gid = Getegid()
} else {
gid = Getgid()
}
if uint32(gid) == st.Gid {
fmode = (st.Mode >> 3) & 7
} else {
fmode = st.Mode & 7
}
}
if fmode&mode == mode {
return nil
}
return EACCES
}
/* /*
* Unimplemented * Unimplemented
*/ */
@ -1398,11 +1505,7 @@ func Vmsplice(fd int, iovs []Iovec, flags int) (int, error) {
// EpollPwait // EpollPwait
// EpollWaitOld // EpollWaitOld
// Execve // Execve
// Fgetxattr
// Flistxattr
// Fork // Fork
// Fremovexattr
// Fsetxattr
// Futex // Futex
// GetKernelSyms // GetKernelSyms
// GetMempolicy // GetMempolicy

View file

@ -10,7 +10,6 @@
package unix package unix
import ( import (
"syscall"
"unsafe" "unsafe"
) )
@ -51,6 +50,8 @@ func Pipe2(p []int, flags int) (err error) {
// 64-bit file system and 32-bit uid calls // 64-bit file system and 32-bit uid calls
// (386 default is 32-bit file system and 16-bit uid). // (386 default is 32-bit file system and 16-bit uid).
//sys Dup2(oldfd int, newfd int) (err error) //sys Dup2(oldfd int, newfd int) (err error)
//sysnb EpollCreate(size int) (fd int, err error)
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64_64 //sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64_64
//sys Fchown(fd int, uid int, gid int) (err error) = SYS_FCHOWN32 //sys Fchown(fd int, uid int, gid int) (err error) = SYS_FCHOWN32
//sys Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64 //sys Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64
@ -78,12 +79,12 @@ func Pipe2(p []int, flags int) (err error) {
//sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64 //sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64
//sys SyncFileRange(fd int, off int64, n int64, flags int) (err error) //sys SyncFileRange(fd int, off int64, n int64, flags int) (err error)
//sys Truncate(path string, length int64) (err error) = SYS_TRUNCATE64 //sys Truncate(path string, length int64) (err error) = SYS_TRUNCATE64
//sys Ustat(dev int, ubuf *Ustat_t) (err error)
//sysnb getgroups(n int, list *_Gid_t) (nn int, err error) = SYS_GETGROUPS32 //sysnb getgroups(n int, list *_Gid_t) (nn int, err error) = SYS_GETGROUPS32
//sysnb setgroups(n int, list *_Gid_t) (err error) = SYS_SETGROUPS32 //sysnb setgroups(n int, list *_Gid_t) (err error) = SYS_SETGROUPS32
//sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) = SYS__NEWSELECT //sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) = SYS__NEWSELECT
//sys mmap2(addr uintptr, length uintptr, prot int, flags int, fd int, pageOffset uintptr) (xaddr uintptr, err error) //sys mmap2(addr uintptr, length uintptr, prot int, flags int, fd int, pageOffset uintptr) (xaddr uintptr, err error)
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
//sys Pause() (err error) //sys Pause() (err error)
func mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) { func mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) {
@ -157,10 +158,6 @@ func Setrlimit(resource int, rlim *Rlimit) (err error) {
return setrlimit(resource, &rl) return setrlimit(resource, &rl)
} }
// Underlying system call writes to newoffset via pointer.
// Implemented in assembly to avoid allocation.
func seek(fd int, offset int64, whence int) (newoffset int64, err syscall.Errno)
func Seek(fd int, offset int64, whence int) (newoffset int64, err error) { func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
newoffset, errno := seek(fd, offset, whence) newoffset, errno := seek(fd, offset, whence)
if errno != 0 { if errno != 0 {
@ -169,11 +166,11 @@ func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
return newoffset, nil return newoffset, nil
} }
// Vsyscalls on amd64. //sys futimesat(dirfd int, path string, times *[2]Timeval) (err error)
//sysnb Gettimeofday(tv *Timeval) (err error) //sysnb Gettimeofday(tv *Timeval) (err error)
//sysnb Time(t *Time_t) (tt Time_t, err error) //sysnb Time(t *Time_t) (tt Time_t, err error)
//sys Utime(path string, buf *Utimbuf) (err error) //sys Utime(path string, buf *Utimbuf) (err error)
//sys utimes(path string, times *[2]Timeval) (err error)
// On x86 Linux, all the socket calls go through an extra indirection, // On x86 Linux, all the socket calls go through an extra indirection,
// I think because the 5-register system call interface can't handle // I think because the 5-register system call interface can't handle
@ -206,9 +203,6 @@ const (
_SENDMMSG = 20 _SENDMMSG = 20
) )
func socketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (n int, err syscall.Errno)
func rawsocketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (n int, err syscall.Errno)
func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) { func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
fd, e := socketcall(_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0) fd, e := socketcall(_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0)
if e != 0 { if e != 0 {

View file

@ -7,6 +7,7 @@
package unix package unix
//sys Dup2(oldfd int, newfd int) (err error) //sys Dup2(oldfd int, newfd int) (err error)
//sysnb EpollCreate(size int) (fd int, err error)
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) //sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64 //sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64
//sys Fchown(fd int, uid int, gid int) (err error) //sys Fchown(fd int, uid int, gid int) (err error)
@ -29,7 +30,15 @@ package unix
//sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64 //sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
//sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64 //sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
//sys Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK //sys Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK
//sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error)
func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) {
var ts *Timespec
if timeout != nil {
ts = &Timespec{Sec: timeout.Sec, Nsec: timeout.Usec * 1000}
}
return Pselect(nfd, r, w, e, ts, nil)
}
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) //sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
//sys Setfsgid(gid int) (err error) //sys Setfsgid(gid int) (err error)
//sys Setfsuid(uid int) (err error) //sys Setfsuid(uid int) (err error)
@ -40,10 +49,16 @@ package unix
//sysnb Setreuid(ruid int, euid int) (err error) //sysnb Setreuid(ruid int, euid int) (err error)
//sys Shutdown(fd int, how int) (err error) //sys Shutdown(fd int, how int) (err error)
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error) //sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
//sys Stat(path string, stat *Stat_t) (err error)
func Stat(path string, stat *Stat_t) (err error) {
// Use fstatat, because Android's seccomp policy blocks stat.
return Fstatat(AT_FDCWD, path, stat, 0)
}
//sys Statfs(path string, buf *Statfs_t) (err error) //sys Statfs(path string, buf *Statfs_t) (err error)
//sys SyncFileRange(fd int, off int64, n int64, flags int) (err error) //sys SyncFileRange(fd int, off int64, n int64, flags int) (err error)
//sys Truncate(path string, length int64) (err error) //sys Truncate(path string, length int64) (err error)
//sys Ustat(dev int, ubuf *Ustat_t) (err error)
//sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) //sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error)
//sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) //sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error)
//sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) //sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
@ -62,6 +77,8 @@ package unix
//sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error) //sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error)
//sys mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) //sys mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error)
//sys futimesat(dirfd int, path string, times *[2]Timeval) (err error)
func Gettimeofday(tv *Timeval) (err error) { func Gettimeofday(tv *Timeval) (err error) {
errno := gettimeofday(tv) errno := gettimeofday(tv)
if errno != 0 { if errno != 0 {
@ -83,6 +100,7 @@ func Time(t *Time_t) (tt Time_t, err error) {
} }
//sys Utime(path string, buf *Utimbuf) (err error) //sys Utime(path string, buf *Utimbuf) (err error)
//sys utimes(path string, times *[2]Timeval) (err error)
func setTimespec(sec, nsec int64) Timespec { func setTimespec(sec, nsec int64) Timespec {
return Timespec{Sec: sec, Nsec: nsec} return Timespec{Sec: sec, Nsec: nsec}

View file

@ -75,6 +75,8 @@ func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
// 64-bit file system and 32-bit uid calls // 64-bit file system and 32-bit uid calls
// (16-bit uid calls are not always supported in newer kernels) // (16-bit uid calls are not always supported in newer kernels)
//sys Dup2(oldfd int, newfd int) (err error) //sys Dup2(oldfd int, newfd int) (err error)
//sysnb EpollCreate(size int) (fd int, err error)
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
//sys Fchown(fd int, uid int, gid int) (err error) = SYS_FCHOWN32 //sys Fchown(fd int, uid int, gid int) (err error) = SYS_FCHOWN32
//sys Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64 //sys Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64
//sys Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_FSTATAT64 //sys Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_FSTATAT64
@ -86,6 +88,7 @@ func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
//sys Lchown(path string, uid int, gid int) (err error) = SYS_LCHOWN32 //sys Lchown(path string, uid int, gid int) (err error) = SYS_LCHOWN32
//sys Listen(s int, n int) (err error) //sys Listen(s int, n int) (err error)
//sys Lstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64 //sys Lstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64
//sys Pause() (err error)
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = SYS_SENDFILE64 //sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = SYS_SENDFILE64
//sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) = SYS__NEWSELECT //sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) = SYS__NEWSELECT
//sys Setfsgid(gid int) (err error) = SYS_SETFSGID32 //sys Setfsgid(gid int) (err error) = SYS_SETFSGID32
@ -97,11 +100,10 @@ func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
//sys Shutdown(fd int, how int) (err error) //sys Shutdown(fd int, how int) (err error)
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error) //sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error)
//sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64 //sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64
//sys Ustat(dev int, ubuf *Ustat_t) (err error)
// Vsyscalls on amd64. //sys futimesat(dirfd int, path string, times *[2]Timeval) (err error)
//sysnb Gettimeofday(tv *Timeval) (err error) //sysnb Gettimeofday(tv *Timeval) (err error)
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
//sys Pause() (err error)
func Time(t *Time_t) (Time_t, error) { func Time(t *Time_t) (Time_t, error) {
var tv Timeval var tv Timeval
@ -123,6 +125,8 @@ func Utime(path string, buf *Utimbuf) error {
return Utimes(path, tv) return Utimes(path, tv)
} }
//sys utimes(path string, times *[2]Timeval) (err error)
//sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64 //sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
//sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64 //sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
//sys Truncate(path string, length int64) (err error) = SYS_TRUNCATE64 //sys Truncate(path string, length int64) (err error) = SYS_TRUNCATE64

View file

@ -6,7 +6,17 @@
package unix package unix
import "unsafe"
func EpollCreate(size int) (fd int, err error) {
if size <= 0 {
return -1, EINVAL
}
return EpollCreate1(0)
}
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) = SYS_EPOLL_PWAIT //sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) = SYS_EPOLL_PWAIT
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64
//sys Fchown(fd int, uid int, gid int) (err error) //sys Fchown(fd int, uid int, gid int) (err error)
//sys Fstat(fd int, stat *Stat_t) (err error) //sys Fstat(fd int, stat *Stat_t) (err error)
//sys Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) //sys Fstatat(fd int, path string, stat *Stat_t, flags int) (err error)
@ -23,8 +33,11 @@ package unix
//sys Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK //sys Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK
func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) { func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) {
ts := Timespec{Sec: timeout.Sec, Nsec: timeout.Usec * 1000} var ts *Timespec
return Pselect(nfd, r, w, e, &ts, nil) if timeout != nil {
ts = &Timespec{Sec: timeout.Sec, Nsec: timeout.Usec * 1000}
}
return Pselect(nfd, r, w, e, ts, nil)
} }
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) //sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
@ -53,6 +66,11 @@ func Lstat(path string, stat *Stat_t) (err error) {
//sys Statfs(path string, buf *Statfs_t) (err error) //sys Statfs(path string, buf *Statfs_t) (err error)
//sys SyncFileRange(fd int, off int64, n int64, flags int) (err error) //sys SyncFileRange(fd int, off int64, n int64, flags int) (err error)
//sys Truncate(path string, length int64) (err error) //sys Truncate(path string, length int64) (err error)
func Ustat(dev int, ubuf *Ustat_t) (err error) {
return ENOSYS
}
//sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) //sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error)
//sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) //sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error)
//sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) //sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
@ -81,6 +99,18 @@ func setTimeval(sec, usec int64) Timeval {
return Timeval{Sec: sec, Usec: usec} return Timeval{Sec: sec, Usec: usec}
} }
func futimesat(dirfd int, path string, tv *[2]Timeval) (err error) {
if tv == nil {
return utimensat(dirfd, path, nil, 0)
}
ts := []Timespec{
NsecToTimespec(TimevalToNsec(tv[0])),
NsecToTimespec(TimevalToNsec(tv[1])),
}
return utimensat(dirfd, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
}
func Time(t *Time_t) (Time_t, error) { func Time(t *Time_t) (Time_t, error) {
var tv Timeval var tv Timeval
err := Gettimeofday(&tv) err := Gettimeofday(&tv)
@ -101,6 +131,18 @@ func Utime(path string, buf *Utimbuf) error {
return Utimes(path, tv) return Utimes(path, tv)
} }
func utimes(path string, tv *[2]Timeval) (err error) {
if tv == nil {
return utimensat(AT_FDCWD, path, nil, 0)
}
ts := []Timespec{
NsecToTimespec(TimevalToNsec(tv[0])),
NsecToTimespec(TimevalToNsec(tv[1])),
}
return utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
}
func Pipe(p []int) (err error) { func Pipe(p []int) (err error) {
if len(p) != 2 { if len(p) != 2 {
return EINVAL return EINVAL
@ -157,22 +199,6 @@ func Pause() (err error) {
return return
} }
// TODO(dfc): constants that should be in zsysnum_linux_arm64.go, remove
// these when the deprecated syscalls that the syscall package relies on
// are removed.
const (
SYS_GETPGRP = 1060
SYS_UTIMES = 1037
SYS_FUTIMESAT = 1066
SYS_PAUSE = 1061
SYS_USTAT = 1070
SYS_UTIME = 1063
SYS_LCHOWN = 1032
SYS_TIME = 1062
SYS_EPOLL_CREATE = 1042
SYS_EPOLL_WAIT = 1069
)
func Poll(fds []PollFd, timeout int) (n int, err error) { func Poll(fds []PollFd, timeout int) (n int, err error) {
var ts *Timespec var ts *Timespec
if timeout >= 0 { if timeout >= 0 {

14
vendor/golang.org/x/sys/unix/syscall_linux_gc.go generated vendored Normal file
View file

@ -0,0 +1,14 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build linux,!gccgo
package unix
// SyscallNoError may be used instead of Syscall for syscalls that don't fail.
func SyscallNoError(trap, a1, a2, a3 uintptr) (r1, r2 uintptr)
// RawSyscallNoError may be used instead of RawSyscall for syscalls that don't
// fail.
func RawSyscallNoError(trap, a1, a2, a3 uintptr) (r1, r2 uintptr)

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

@ -0,0 +1,16 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build linux,!gccgo,386
package unix
import "syscall"
// Underlying system call writes to newoffset via pointer.
// Implemented in assembly to avoid allocation.
func seek(fd int, offset int64, whence int) (newoffset int64, err syscall.Errno)
func socketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (n int, err syscall.Errno)
func rawsocketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (n int, err syscall.Errno)

View file

@ -0,0 +1,30 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build linux,gccgo,386
package unix
import (
"syscall"
"unsafe"
)
func seek(fd int, offset int64, whence int) (int64, syscall.Errno) {
var newoffset int64
offsetLow := uint32(offset & 0xffffffff)
offsetHigh := uint32((offset >> 32) & 0xffffffff)
_, _, err := Syscall6(SYS__LLSEEK, uintptr(fd), uintptr(offsetHigh), uintptr(offsetLow), uintptr(unsafe.Pointer(&newoffset)), uintptr(whence), 0)
return newoffset, err
}
func socketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (int, syscall.Errno) {
fd, _, err := Syscall(SYS_SOCKETCALL, uintptr(call), uintptr(unsafe.Pointer(&a0)), 0)
return int(fd), err
}
func rawsocketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (int, syscall.Errno) {
fd, _, err := RawSyscall(SYS_SOCKETCALL, uintptr(call), uintptr(unsafe.Pointer(&a0)), 0)
return int(fd), err
}

View file

@ -0,0 +1,20 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build linux,gccgo,arm
package unix
import (
"syscall"
"unsafe"
)
func seek(fd int, offset int64, whence int) (int64, syscall.Errno) {
var newoffset int64
offsetLow := uint32(offset & 0xffffffff)
offsetHigh := uint32((offset >> 32) & 0xffffffff)
_, _, err := Syscall6(SYS__LLSEEK, uintptr(fd), uintptr(offsetHigh), uintptr(offsetLow), uintptr(unsafe.Pointer(&newoffset)), uintptr(whence), 0)
return newoffset, err
}

View file

@ -8,7 +8,9 @@
package unix package unix
//sys Dup2(oldfd int, newfd int) (err error) //sys Dup2(oldfd int, newfd int) (err error)
//sysnb EpollCreate(size int) (fd int, err error)
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) //sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64
//sys Fchown(fd int, uid int, gid int) (err error) //sys Fchown(fd int, uid int, gid int) (err error)
//sys Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_NEWFSTATAT //sys Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_NEWFSTATAT
//sys Fstatfs(fd int, buf *Statfs_t) (err error) //sys Fstatfs(fd int, buf *Statfs_t) (err error)
@ -26,8 +28,11 @@ package unix
//sys Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK //sys Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK
func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) { func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) {
ts := Timespec{Sec: timeout.Sec, Nsec: timeout.Usec * 1000} var ts *Timespec
return Pselect(nfd, r, w, e, &ts, nil) if timeout != nil {
ts = &Timespec{Sec: timeout.Sec, Nsec: timeout.Usec * 1000}
}
return Pselect(nfd, r, w, e, ts, nil)
} }
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) //sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
@ -43,6 +48,7 @@ func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err
//sys Statfs(path string, buf *Statfs_t) (err error) //sys Statfs(path string, buf *Statfs_t) (err error)
//sys SyncFileRange(fd int, off int64, n int64, flags int) (err error) //sys SyncFileRange(fd int, off int64, n int64, flags int) (err error)
//sys Truncate(path string, length int64) (err error) //sys Truncate(path string, length int64) (err error)
//sys Ustat(dev int, ubuf *Ustat_t) (err error)
//sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) //sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error)
//sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) //sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error)
//sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) //sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
@ -61,6 +67,7 @@ func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err
//sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error) //sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error)
//sys mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) //sys mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error)
//sys futimesat(dirfd int, path string, times *[2]Timeval) (err error)
//sysnb Gettimeofday(tv *Timeval) (err error) //sysnb Gettimeofday(tv *Timeval) (err error)
func Time(t *Time_t) (tt Time_t, err error) { func Time(t *Time_t) (tt Time_t, err error) {
@ -76,6 +83,7 @@ func Time(t *Time_t) (tt Time_t, err error) {
} }
//sys Utime(path string, buf *Utimbuf) (err error) //sys Utime(path string, buf *Utimbuf) (err error)
//sys utimes(path string, times *[2]Timeval) (err error)
func setTimespec(sec, nsec int64) Timespec { func setTimespec(sec, nsec int64) Timespec {
return Timespec{Sec: sec, Nsec: nsec} return Timespec{Sec: sec, Nsec: nsec}

View file

@ -15,6 +15,9 @@ import (
func Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno) func Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)
//sys Dup2(oldfd int, newfd int) (err error) //sys Dup2(oldfd int, newfd int) (err error)
//sysnb EpollCreate(size int) (fd int, err error)
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64
//sys Fchown(fd int, uid int, gid int) (err error) //sys Fchown(fd int, uid int, gid int) (err error)
//sys Ftruncate(fd int, length int64) (err error) = SYS_FTRUNCATE64 //sys Ftruncate(fd int, length int64) (err error) = SYS_FTRUNCATE64
//sysnb Getegid() (egid int) //sysnb Getegid() (egid int)
@ -32,13 +35,12 @@ func Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr,
//sysnb Setregid(rgid int, egid int) (err error) //sysnb Setregid(rgid int, egid int) (err error)
//sysnb Setresgid(rgid int, egid int, sgid int) (err error) //sysnb Setresgid(rgid int, egid int, sgid int) (err error)
//sysnb Setresuid(ruid int, euid int, suid int) (err error) //sysnb Setresuid(ruid int, euid int, suid int) (err error)
//sysnb Setreuid(ruid int, euid int) (err error) //sysnb Setreuid(ruid int, euid int) (err error)
//sys Shutdown(fd int, how int) (err error) //sys Shutdown(fd int, how int) (err error)
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error) //sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error)
//sys SyncFileRange(fd int, off int64, n int64, flags int) (err error) //sys SyncFileRange(fd int, off int64, n int64, flags int) (err error)
//sys Truncate(path string, length int64) (err error) = SYS_TRUNCATE64 //sys Truncate(path string, length int64) (err error) = SYS_TRUNCATE64
//sys Ustat(dev int, ubuf *Ustat_t) (err error)
//sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) //sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error)
//sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) //sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error)
//sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) //sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
@ -60,16 +62,17 @@ func Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr,
//sys Ioperm(from int, num int, on int) (err error) //sys Ioperm(from int, num int, on int) (err error)
//sys Iopl(level int) (err error) //sys Iopl(level int) (err error)
//sys futimesat(dirfd int, path string, times *[2]Timeval) (err error)
//sysnb Gettimeofday(tv *Timeval) (err error) //sysnb Gettimeofday(tv *Timeval) (err error)
//sysnb Time(t *Time_t) (tt Time_t, err error) //sysnb Time(t *Time_t) (tt Time_t, err error)
//sys Utime(path string, buf *Utimbuf) (err error)
//sys utimes(path string, times *[2]Timeval) (err error)
//sys Lstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64 //sys Lstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64
//sys Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64 //sys Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64
//sys Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_FSTATAT64 //sys Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_FSTATAT64
//sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64 //sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64
//sys Utime(path string, buf *Utimbuf) (err error)
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
//sys Pause() (err error) //sys Pause() (err error)
func Fstatfs(fd int, buf *Statfs_t) (err error) { func Fstatfs(fd int, buf *Statfs_t) (err error) {
@ -121,14 +124,13 @@ func Pipe2(p []int, flags int) (err error) {
return return
} }
//sysnb pipe() (p1 int, p2 int, err error)
func Pipe(p []int) (err error) { func Pipe(p []int) (err error) {
if len(p) != 2 { if len(p) != 2 {
return EINVAL return EINVAL
} }
var pp [2]_C_int p[0], p[1], err = pipe()
err = pipe2(&pp, 0)
p[0] = int(pp[0])
p[1] = int(pp[1])
return return
} }

View file

@ -7,8 +7,10 @@
package unix package unix
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
//sys Dup2(oldfd int, newfd int) (err error) //sys Dup2(oldfd int, newfd int) (err error)
//sysnb EpollCreate(size int) (fd int, err error)
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64
//sys Fchown(fd int, uid int, gid int) (err error) //sys Fchown(fd int, uid int, gid int) (err error)
//sys Fstat(fd int, stat *Stat_t) (err error) //sys Fstat(fd int, stat *Stat_t) (err error)
//sys Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_NEWFSTATAT //sys Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_NEWFSTATAT
@ -44,6 +46,7 @@ package unix
//sys Statfs(path string, buf *Statfs_t) (err error) //sys Statfs(path string, buf *Statfs_t) (err error)
//sys SyncFileRange(fd int, off int64, n int64, flags int) (err error) = SYS_SYNC_FILE_RANGE2 //sys SyncFileRange(fd int, off int64, n int64, flags int) (err error) = SYS_SYNC_FILE_RANGE2
//sys Truncate(path string, length int64) (err error) //sys Truncate(path string, length int64) (err error)
//sys Ustat(dev int, ubuf *Ustat_t) (err error)
//sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) //sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error)
//sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) //sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error)
//sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) //sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
@ -62,10 +65,11 @@ package unix
//sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error) //sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error)
//sys mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) //sys mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error)
//sys futimesat(dirfd int, path string, times *[2]Timeval) (err error)
//sysnb Gettimeofday(tv *Timeval) (err error) //sysnb Gettimeofday(tv *Timeval) (err error)
//sysnb Time(t *Time_t) (tt Time_t, err error) //sysnb Time(t *Time_t) (tt Time_t, err error)
//sys Utime(path string, buf *Utimbuf) (err error) //sys Utime(path string, buf *Utimbuf) (err error)
//sys utimes(path string, times *[2]Timeval) (err error)
func setTimespec(sec, nsec int64) Timespec { func setTimespec(sec, nsec int64) Timespec {
return Timespec{Sec: sec, Nsec: nsec} return Timespec{Sec: sec, Nsec: nsec}

View file

@ -11,6 +11,7 @@ import (
) )
//sys Dup2(oldfd int, newfd int) (err error) //sys Dup2(oldfd int, newfd int) (err error)
//sysnb EpollCreate(size int) (fd int, err error)
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) //sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64 //sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64
//sys Fchown(fd int, uid int, gid int) (err error) //sys Fchown(fd int, uid int, gid int) (err error)
@ -44,9 +45,11 @@ import (
//sys Statfs(path string, buf *Statfs_t) (err error) //sys Statfs(path string, buf *Statfs_t) (err error)
//sys SyncFileRange(fd int, off int64, n int64, flags int) (err error) //sys SyncFileRange(fd int, off int64, n int64, flags int) (err error)
//sys Truncate(path string, length int64) (err error) //sys Truncate(path string, length int64) (err error)
//sys Ustat(dev int, ubuf *Ustat_t) (err error)
//sysnb getgroups(n int, list *_Gid_t) (nn int, err error) //sysnb getgroups(n int, list *_Gid_t) (nn int, err error)
//sysnb setgroups(n int, list *_Gid_t) (err error) //sysnb setgroups(n int, list *_Gid_t) (err error)
//sys futimesat(dirfd int, path string, times *[2]Timeval) (err error)
//sysnb Gettimeofday(tv *Timeval) (err error) //sysnb Gettimeofday(tv *Timeval) (err error)
func Time(t *Time_t) (tt Time_t, err error) { func Time(t *Time_t) (tt Time_t, err error) {
@ -62,6 +65,7 @@ func Time(t *Time_t) (tt Time_t, err error) {
} }
//sys Utime(path string, buf *Utimbuf) (err error) //sys Utime(path string, buf *Utimbuf) (err error)
//sys utimes(path string, times *[2]Timeval) (err error)
func setTimespec(sec, nsec int64) Timespec { func setTimespec(sec, nsec int64) Timespec {
return Timespec{Sec: sec, Nsec: nsec} return Timespec{Sec: sec, Nsec: nsec}

View file

@ -7,6 +7,7 @@
package unix package unix
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) //sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64
//sys Dup2(oldfd int, newfd int) (err error) //sys Dup2(oldfd int, newfd int) (err error)
//sys Fchown(fd int, uid int, gid int) (err error) //sys Fchown(fd int, uid int, gid int) (err error)
//sys Fstat(fd int, stat *Stat_t) (err error) //sys Fstat(fd int, stat *Stat_t) (err error)
@ -67,6 +68,7 @@ func Iopl(level int) (err error) {
return ENOSYS return ENOSYS
} }
//sys futimesat(dirfd int, path string, times *[2]Timeval) (err error)
//sysnb Gettimeofday(tv *Timeval) (err error) //sysnb Gettimeofday(tv *Timeval) (err error)
func Time(t *Time_t) (tt Time_t, err error) { func Time(t *Time_t) (tt Time_t, err error) {
@ -82,6 +84,7 @@ func Time(t *Time_t) (tt Time_t, err error) {
} }
//sys Utime(path string, buf *Utimbuf) (err error) //sys Utime(path string, buf *Utimbuf) (err error)
//sys utimes(path string, times *[2]Timeval) (err error)
func setTimespec(sec, nsec int64) Timespec { func setTimespec(sec, nsec int64) Timespec {
return Timespec{Sec: sec, Nsec: nsec} return Timespec{Sec: sec, Nsec: nsec}

View file

@ -17,6 +17,7 @@ import (
"unsafe" "unsafe"
) )
// SockaddrDatalink implements the Sockaddr interface for AF_LINK type sockets.
type SockaddrDatalink struct { type SockaddrDatalink struct {
Len uint8 Len uint8
Family uint8 Family uint8
@ -92,18 +93,6 @@ func nametomib(name string) (mib []_C_int, err error) {
return mib, nil return mib, nil
} }
func direntIno(buf []byte) (uint64, bool) {
return readInt(buf, unsafe.Offsetof(Dirent{}.Fileno), unsafe.Sizeof(Dirent{}.Fileno))
}
func direntReclen(buf []byte) (uint64, bool) {
return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
}
func direntNamlen(buf []byte) (uint64, bool) {
return readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen))
}
//sysnb pipe() (fd1 int, fd2 int, err error) //sysnb pipe() (fd1 int, fd2 int, err error)
func Pipe(p []int) (err error) { func Pipe(p []int) (err error) {
if len(p) != 2 { if len(p) != 2 {
@ -156,11 +145,11 @@ func IoctlSetInt(fd int, req uint, value int) error {
return ioctl(fd, req, uintptr(value)) return ioctl(fd, req, uintptr(value))
} }
func IoctlSetWinsize(fd int, req uint, value *Winsize) error { func ioctlSetWinsize(fd int, req uint, value *Winsize) error {
return ioctl(fd, req, uintptr(unsafe.Pointer(value))) return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
} }
func IoctlSetTermios(fd int, req uint, value *Termios) error { func ioctlSetTermios(fd int, req uint, value *Termios) error {
return ioctl(fd, req, uintptr(unsafe.Pointer(value))) return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
} }
@ -244,13 +233,29 @@ func Uname(uname *Utsname) error {
//sys Dup(fd int) (nfd int, err error) //sys Dup(fd int) (nfd int, err error)
//sys Dup2(from int, to int) (err error) //sys Dup2(from int, to int) (err error)
//sys Exit(code int) //sys Exit(code int)
//sys ExtattrGetFd(fd int, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error)
//sys ExtattrSetFd(fd int, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error)
//sys ExtattrDeleteFd(fd int, attrnamespace int, attrname string) (err error)
//sys ExtattrListFd(fd int, attrnamespace int, data uintptr, nbytes int) (ret int, err error)
//sys ExtattrGetFile(file string, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error)
//sys ExtattrSetFile(file string, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error)
//sys ExtattrDeleteFile(file string, attrnamespace int, attrname string) (err error)
//sys ExtattrListFile(file string, attrnamespace int, data uintptr, nbytes int) (ret int, err error)
//sys ExtattrGetLink(link string, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error)
//sys ExtattrSetLink(link string, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error)
//sys ExtattrDeleteLink(link string, attrnamespace int, attrname string) (err error)
//sys ExtattrListLink(link string, attrnamespace int, data uintptr, nbytes int) (ret int, err error)
//sys Faccessat(dirfd int, path string, mode uint32, flags int) (err error)
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_POSIX_FADVISE
//sys Fchdir(fd int) (err error) //sys Fchdir(fd int) (err error)
//sys Fchflags(fd int, flags int) (err error) //sys Fchflags(fd int, flags int) (err error)
//sys Fchmod(fd int, mode uint32) (err error) //sys Fchmod(fd int, mode uint32) (err error)
//sys Fchmodat(dirfd int, path string, mode uint32, flags int) (err error)
//sys Fchown(fd int, uid int, gid int) (err error) //sys Fchown(fd int, uid int, gid int) (err error)
//sys Flock(fd int, how int) (err error) //sys Flock(fd int, how int) (err error)
//sys Fpathconf(fd int, name int) (val int, err error) //sys Fpathconf(fd int, name int) (val int, err error)
//sys Fstat(fd int, stat *Stat_t) (err error) //sys Fstat(fd int, stat *Stat_t) (err error)
//sys Fstatat(fd int, path string, stat *Stat_t, flags int) (err error)
//sys Fsync(fd int) (err error) //sys Fsync(fd int) (err error)
//sys Ftruncate(fd int, length int64) (err error) //sys Ftruncate(fd int, length int64) (err error)
//sysnb Getegid() (egid int) //sysnb Getegid() (egid int)
@ -331,7 +336,6 @@ func Uname(uname *Utsname) error {
// __msync13 // __msync13
// __ntp_gettime30 // __ntp_gettime30
// __posix_chown // __posix_chown
// __posix_fadvise50
// __posix_fchown // __posix_fchown
// __posix_lchown // __posix_lchown
// __posix_rename // __posix_rename

View file

@ -18,6 +18,7 @@ import (
"unsafe" "unsafe"
) )
// SockaddrDatalink implements the Sockaddr interface for AF_LINK type sockets.
type SockaddrDatalink struct { type SockaddrDatalink struct {
Len uint8 Len uint8
Family uint8 Family uint8
@ -42,18 +43,6 @@ func nametomib(name string) (mib []_C_int, err error) {
return nil, EINVAL return nil, EINVAL
} }
func direntIno(buf []byte) (uint64, bool) {
return readInt(buf, unsafe.Offsetof(Dirent{}.Fileno), unsafe.Sizeof(Dirent{}.Fileno))
}
func direntReclen(buf []byte) (uint64, bool) {
return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
}
func direntNamlen(buf []byte) (uint64, bool) {
return readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen))
}
//sysnb pipe(p *[2]_C_int) (err error) //sysnb pipe(p *[2]_C_int) (err error)
func Pipe(p []int) (err error) { func Pipe(p []int) (err error) {
if len(p) != 2 { if len(p) != 2 {
@ -124,11 +113,11 @@ func IoctlSetInt(fd int, req uint, value int) error {
return ioctl(fd, req, uintptr(value)) return ioctl(fd, req, uintptr(value))
} }
func IoctlSetWinsize(fd int, req uint, value *Winsize) error { func ioctlSetWinsize(fd int, req uint, value *Winsize) error {
return ioctl(fd, req, uintptr(unsafe.Pointer(value))) return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
} }
func IoctlSetTermios(fd int, req uint, value *Termios) error { func ioctlSetTermios(fd int, req uint, value *Termios) error {
return ioctl(fd, req, uintptr(unsafe.Pointer(value))) return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
} }
@ -212,13 +201,16 @@ func Uname(uname *Utsname) error {
//sys Dup(fd int) (nfd int, err error) //sys Dup(fd int) (nfd int, err error)
//sys Dup2(from int, to int) (err error) //sys Dup2(from int, to int) (err error)
//sys Exit(code int) //sys Exit(code int)
//sys Faccessat(dirfd int, path string, mode uint32, flags int) (err error)
//sys Fchdir(fd int) (err error) //sys Fchdir(fd int) (err error)
//sys Fchflags(fd int, flags int) (err error) //sys Fchflags(fd int, flags int) (err error)
//sys Fchmod(fd int, mode uint32) (err error) //sys Fchmod(fd int, mode uint32) (err error)
//sys Fchmodat(dirfd int, path string, mode uint32, flags int) (err error)
//sys Fchown(fd int, uid int, gid int) (err error) //sys Fchown(fd int, uid int, gid int) (err error)
//sys Flock(fd int, how int) (err error) //sys Flock(fd int, how int) (err error)
//sys Fpathconf(fd int, name int) (val int, err error) //sys Fpathconf(fd int, name int) (val int, err error)
//sys Fstat(fd int, stat *Stat_t) (err error) //sys Fstat(fd int, stat *Stat_t) (err error)
//sys Fstatat(fd int, path string, stat *Stat_t, flags int) (err error)
//sys Fstatfs(fd int, stat *Statfs_t) (err error) //sys Fstatfs(fd int, stat *Statfs_t) (err error)
//sys Fsync(fd int) (err error) //sys Fsync(fd int) (err error)
//sys Ftruncate(fd int, length int64) (err error) //sys Ftruncate(fd int, length int64) (err error)
@ -231,6 +223,7 @@ func Uname(uname *Utsname) error {
//sysnb Getppid() (ppid int) //sysnb Getppid() (ppid int)
//sys Getpriority(which int, who int) (prio int, err error) //sys Getpriority(which int, who int) (prio int, err error)
//sysnb Getrlimit(which int, lim *Rlimit) (err error) //sysnb Getrlimit(which int, lim *Rlimit) (err error)
//sysnb Getrtable() (rtable int, err error)
//sysnb Getrusage(who int, rusage *Rusage) (err error) //sysnb Getrusage(who int, rusage *Rusage) (err error)
//sysnb Getsid(pid int) (sid int, err error) //sysnb Getsid(pid int) (sid int, err error)
//sysnb Gettimeofday(tv *Timeval) (err error) //sysnb Gettimeofday(tv *Timeval) (err error)
@ -268,6 +261,7 @@ func Uname(uname *Utsname) error {
//sysnb Setresgid(rgid int, egid int, sgid int) (err error) //sysnb Setresgid(rgid int, egid int, sgid int) (err error)
//sysnb Setresuid(ruid int, euid int, suid int) (err error) //sysnb Setresuid(ruid int, euid int, suid int) (err error)
//sysnb Setrlimit(which int, lim *Rlimit) (err error) //sysnb Setrlimit(which int, lim *Rlimit) (err error)
//sysnb Setrtable(rtable int) (err error)
//sysnb Setsid() (pid int, err error) //sysnb Setsid() (pid int, err error)
//sysnb Settimeofday(tp *Timeval) (err error) //sysnb Settimeofday(tp *Timeval) (err error)
//sysnb Setuid(uid int) (err error) //sysnb Setuid(uid int) (err error)
@ -316,7 +310,6 @@ func Uname(uname *Utsname) error {
// getlogin // getlogin
// getresgid // getresgid
// getresuid // getresuid
// getrtable
// getthrid // getthrid
// ktrace // ktrace
// lfs_bmapv // lfs_bmapv
@ -352,7 +345,6 @@ func Uname(uname *Utsname) error {
// semop // semop
// setgroups // setgroups
// setitimer // setitimer
// setrtable
// setsockopt // setsockopt
// shmat // shmat
// shmctl // shmctl

View file

@ -31,3 +31,7 @@ func (msghdr *Msghdr) SetControllen(length int) {
func (cmsg *Cmsghdr) SetLen(length int) { func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint32(length) 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

View file

@ -23,6 +23,7 @@ type syscallFunc uintptr
func rawSysvicall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno) func rawSysvicall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno)
func sysvicall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno) func sysvicall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno)
// SockaddrDatalink implements the Sockaddr interface for AF_LINK type sockets.
type SockaddrDatalink struct { type SockaddrDatalink struct {
Family uint16 Family uint16
Index uint16 Index uint16
@ -34,22 +35,6 @@ type SockaddrDatalink struct {
raw RawSockaddrDatalink raw RawSockaddrDatalink
} }
func direntIno(buf []byte) (uint64, bool) {
return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino))
}
func direntReclen(buf []byte) (uint64, bool) {
return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
}
func direntNamlen(buf []byte) (uint64, bool) {
reclen, ok := direntReclen(buf)
if !ok {
return 0, false
}
return reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true
}
//sysnb pipe(p *[2]_C_int) (n int, err error) //sysnb pipe(p *[2]_C_int) (n int, err error)
func Pipe(p []int) (err error) { func Pipe(p []int) (err error) {
@ -127,7 +112,7 @@ func Getsockname(fd int) (sa Sockaddr, err error) {
if err = getsockname(fd, &rsa, &len); err != nil { if err = getsockname(fd, &rsa, &len); err != nil {
return return
} }
return anyToSockaddr(&rsa) return anyToSockaddr(fd, &rsa)
} }
// GetsockoptString returns the string value of the socket option opt for the // GetsockoptString returns the string value of the socket option opt for the
@ -327,6 +312,16 @@ func UtimesNanoAt(dirfd int, path string, ts []Timespec, flags int) error {
//sys fcntl(fd int, cmd int, arg int) (val int, err error) //sys fcntl(fd int, cmd int, arg int) (val int, err error)
// FcntlInt performs a fcntl syscall on fd with the provided command and argument.
func FcntlInt(fd uintptr, cmd, arg int) (int, error) {
valptr, _, errno := sysvicall6(uintptr(unsafe.Pointer(&procfcntl)), 3, uintptr(fd), uintptr(cmd), uintptr(arg), 0, 0, 0)
var err error
if errno != 0 {
err = errno
}
return int(valptr), err
}
// FcntlFlock performs a fcntl syscall for the F_GETLK, F_SETLK or F_SETLKW command. // FcntlFlock performs a fcntl syscall for the F_GETLK, F_SETLK or F_SETLKW command.
func FcntlFlock(fd uintptr, cmd int, lk *Flock_t) error { func FcntlFlock(fd uintptr, cmd int, lk *Flock_t) error {
_, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procfcntl)), 3, uintptr(fd), uintptr(cmd), uintptr(unsafe.Pointer(lk)), 0, 0, 0) _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procfcntl)), 3, uintptr(fd), uintptr(cmd), uintptr(unsafe.Pointer(lk)), 0, 0, 0)
@ -365,7 +360,7 @@ func Futimes(fd int, tv []Timeval) error {
return futimesat(fd, nil, (*[2]Timeval)(unsafe.Pointer(&tv[0]))) return futimesat(fd, nil, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
} }
func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, error) { func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
switch rsa.Addr.Family { switch rsa.Addr.Family {
case AF_UNIX: case AF_UNIX:
pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa)) pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))
@ -416,7 +411,7 @@ func Accept(fd int) (nfd int, sa Sockaddr, err error) {
if nfd == -1 { if nfd == -1 {
return return
} }
sa, err = anyToSockaddr(&rsa) sa, err = anyToSockaddr(fd, &rsa)
if err != nil { if err != nil {
Close(nfd) Close(nfd)
nfd = 0 nfd = 0
@ -453,7 +448,7 @@ func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from
oobn = int(msg.Accrightslen) oobn = int(msg.Accrightslen)
// source address is only specified if the socket is unconnected // source address is only specified if the socket is unconnected
if rsa.Addr.Family != AF_UNSPEC { if rsa.Addr.Family != AF_UNSPEC {
from, err = anyToSockaddr(&rsa) from, err = anyToSockaddr(fd, &rsa)
} }
return return
} }
@ -545,11 +540,11 @@ func IoctlSetInt(fd int, req uint, value int) (err error) {
return ioctl(fd, req, uintptr(value)) return ioctl(fd, req, uintptr(value))
} }
func IoctlSetWinsize(fd int, req uint, value *Winsize) (err error) { func ioctlSetWinsize(fd int, req uint, value *Winsize) (err error) {
return ioctl(fd, req, uintptr(unsafe.Pointer(value))) return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
} }
func IoctlSetTermios(fd int, req uint, value *Termios) (err error) { func ioctlSetTermios(fd int, req uint, value *Termios) (err error) {
return ioctl(fd, req, uintptr(unsafe.Pointer(value))) return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
} }
@ -604,15 +599,17 @@ func Poll(fds []PollFd, timeout int) (n int, err error) {
//sys Dup(fd int) (nfd int, err error) //sys Dup(fd int) (nfd int, err error)
//sys Dup2(oldfd int, newfd int) (err error) //sys Dup2(oldfd int, newfd int) (err error)
//sys Exit(code int) //sys Exit(code int)
//sys Faccessat(dirfd int, path string, mode uint32, flags int) (err error)
//sys Fchdir(fd int) (err error) //sys Fchdir(fd int) (err error)
//sys Fchmod(fd int, mode uint32) (err error) //sys Fchmod(fd int, mode uint32) (err error)
//sys Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) //sys Fchmodat(dirfd int, path string, mode uint32, flags int) (err error)
//sys Fchown(fd int, uid int, gid int) (err error) //sys Fchown(fd int, uid int, gid int) (err error)
//sys Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) //sys Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error)
//sys Fdatasync(fd int) (err error) //sys Fdatasync(fd int) (err error)
//sys Flock(fd int, how int) (err error) //sys Flock(fd int, how int) (err error)
//sys Fpathconf(fd int, name int) (val int, err error) //sys Fpathconf(fd int, name int) (val int, err error)
//sys Fstat(fd int, stat *Stat_t) (err error) //sys Fstat(fd int, stat *Stat_t) (err error)
//sys Fstatat(fd int, path string, stat *Stat_t, flags int) (err error)
//sys Fstatvfs(fd int, vfsstat *Statvfs_t) (err error) //sys Fstatvfs(fd int, vfsstat *Statvfs_t) (err error)
//sys Getdents(fd int, buf []byte, basep *uintptr) (n int, err error) //sys Getdents(fd int, buf []byte, basep *uintptr) (n int, err error)
//sysnb Getgid() (gid int) //sysnb Getgid() (gid int)
@ -690,6 +687,7 @@ func Poll(fds []PollFd, timeout int) (n int, err error) {
//sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) = libsocket.__xnet_connect //sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) = libsocket.__xnet_connect
//sys mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) //sys mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error)
//sys munmap(addr uintptr, length uintptr) (err error) //sys munmap(addr uintptr, length uintptr) (err error)
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = libsendfile.sendfile
//sys sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) = libsocket.__xnet_sendto //sys sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) = libsocket.__xnet_sendto
//sys socket(domain int, typ int, proto int) (fd int, err error) = libsocket.__xnet_socket //sys socket(domain int, typ int, proto int) (fd int, err error) = libsocket.__xnet_socket
//sysnb socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) = libsocket.__xnet_socketpair //sysnb socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) = libsocket.__xnet_socketpair

View file

@ -21,8 +21,3 @@ func (iov *Iovec) SetLen(length int) {
func (cmsg *Cmsghdr) SetLen(length int) { func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint32(length) cmsg.Len = uint32(length)
} }
func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
// TODO(aram): implement this, see issue 5847.
panic("unimplemented")
}

View file

@ -7,7 +7,9 @@
package unix package unix
import ( import (
"bytes"
"runtime" "runtime"
"sort"
"sync" "sync"
"syscall" "syscall"
"unsafe" "unsafe"
@ -50,15 +52,35 @@ func errnoErr(e syscall.Errno) error {
return e return e
} }
// clen returns the index of the first NULL byte in n or len(n) if n contains no // ErrnoName returns the error name for error number e.
// NULL byte or len(n) if n contains no NULL byte func ErrnoName(e syscall.Errno) string {
func clen(n []byte) int { i := sort.Search(len(errorList), func(i int) bool {
for i := 0; i < len(n); i++ { return errorList[i].num >= e
if n[i] == 0 { })
return i if i < len(errorList) && errorList[i].num == e {
} return errorList[i].name
} }
return len(n) return ""
}
// SignalName returns the signal name for signal number s.
func SignalName(s syscall.Signal) string {
i := sort.Search(len(signalList), func(i int) bool {
return signalList[i].num >= s
})
if i < len(signalList) && signalList[i].num == s {
return signalList[i].name
}
return ""
}
// clen returns the index of the first NULL byte in n or len(n) if n contains no NULL byte.
func clen(n []byte) int {
i := bytes.IndexByte(n, 0)
if i == -1 {
i = len(n)
}
return i
} }
// Mmap manager, for use by operating system-specific implementations. // Mmap manager, for use by operating system-specific implementations.
@ -149,16 +171,19 @@ func Write(fd int, p []byte) (n int, err error) {
// creation of IPv6 sockets to return EAFNOSUPPORT. // creation of IPv6 sockets to return EAFNOSUPPORT.
var SocketDisableIPv6 bool var SocketDisableIPv6 bool
// Sockaddr represents a socket address.
type Sockaddr interface { type Sockaddr interface {
sockaddr() (ptr unsafe.Pointer, len _Socklen, err error) // lowercase; only we can define Sockaddrs sockaddr() (ptr unsafe.Pointer, len _Socklen, err error) // lowercase; only we can define Sockaddrs
} }
// SockaddrInet4 implements the Sockaddr interface for AF_INET type sockets.
type SockaddrInet4 struct { type SockaddrInet4 struct {
Port int Port int
Addr [4]byte Addr [4]byte
raw RawSockaddrInet4 raw RawSockaddrInet4
} }
// SockaddrInet6 implements the Sockaddr interface for AF_INET6 type sockets.
type SockaddrInet6 struct { type SockaddrInet6 struct {
Port int Port int
ZoneId uint32 ZoneId uint32
@ -166,6 +191,7 @@ type SockaddrInet6 struct {
raw RawSockaddrInet6 raw RawSockaddrInet6
} }
// SockaddrUnix implements the Sockaddr interface for AF_UNIX type sockets.
type SockaddrUnix struct { type SockaddrUnix struct {
Name string Name string
raw RawSockaddrUnix raw RawSockaddrUnix
@ -193,7 +219,14 @@ func Getpeername(fd int) (sa Sockaddr, err error) {
if err = getpeername(fd, &rsa, &len); err != nil { if err = getpeername(fd, &rsa, &len); err != nil {
return return
} }
return anyToSockaddr(&rsa) return anyToSockaddr(fd, &rsa)
}
func GetsockoptByte(fd, level, opt int) (value byte, err error) {
var n byte
vallen := _Socklen(1)
err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen)
return n, err
} }
func GetsockoptInt(fd, level, opt int) (value int, err error) { func GetsockoptInt(fd, level, opt int) (value int, err error) {
@ -203,6 +236,54 @@ func GetsockoptInt(fd, level, opt int) (value int, err error) {
return int(n), err return int(n), err
} }
func GetsockoptInet4Addr(fd, level, opt int) (value [4]byte, err error) {
vallen := _Socklen(4)
err = getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen)
return value, err
}
func GetsockoptIPMreq(fd, level, opt int) (*IPMreq, error) {
var value IPMreq
vallen := _Socklen(SizeofIPMreq)
err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
return &value, err
}
func GetsockoptIPv6Mreq(fd, level, opt int) (*IPv6Mreq, error) {
var value IPv6Mreq
vallen := _Socklen(SizeofIPv6Mreq)
err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
return &value, err
}
func GetsockoptIPv6MTUInfo(fd, level, opt int) (*IPv6MTUInfo, error) {
var value IPv6MTUInfo
vallen := _Socklen(SizeofIPv6MTUInfo)
err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
return &value, err
}
func GetsockoptICMPv6Filter(fd, level, opt int) (*ICMPv6Filter, error) {
var value ICMPv6Filter
vallen := _Socklen(SizeofICMPv6Filter)
err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
return &value, err
}
func GetsockoptLinger(fd, level, opt int) (*Linger, error) {
var linger Linger
vallen := _Socklen(SizeofLinger)
err := getsockopt(fd, level, opt, unsafe.Pointer(&linger), &vallen)
return &linger, err
}
func GetsockoptTimeval(fd, level, opt int) (*Timeval, error) {
var tv Timeval
vallen := _Socklen(unsafe.Sizeof(tv))
err := getsockopt(fd, level, opt, unsafe.Pointer(&tv), &vallen)
return &tv, err
}
func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) { func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) {
var rsa RawSockaddrAny var rsa RawSockaddrAny
var len _Socklen = SizeofSockaddrAny var len _Socklen = SizeofSockaddrAny
@ -210,7 +291,7 @@ func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) {
return return
} }
if rsa.Addr.Family != AF_UNSPEC { if rsa.Addr.Family != AF_UNSPEC {
from, err = anyToSockaddr(&rsa) from, err = anyToSockaddr(fd, &rsa)
} }
return return
} }
@ -302,3 +383,12 @@ func SetNonblock(fd int, nonblocking bool) (err error) {
_, err = fcntl(fd, F_SETFL, flag) _, err = fcntl(fd, F_SETFL, flag)
return err return err
} }
// Exec calls execve(2), which replaces the calling executable in the process
// tree. argv0 should be the full path to an executable ("/bin/ls") and the
// executable name should also be the first argument in argv (["ls", "-l"]).
// envv are the environment variables that should be passed to the new
// process (["USER=go", "PWD=/tmp"]).
func Exec(argv0 string, argv []string, envv []string) error {
return syscall.Exec(argv0, argv, envv)
}

View file

@ -100,23 +100,6 @@ type _Gid_t C.gid_t
// Files // Files
const ( // Directory mode bits
S_IFMT = C.S_IFMT
S_IFIFO = C.S_IFIFO
S_IFCHR = C.S_IFCHR
S_IFDIR = C.S_IFDIR
S_IFBLK = C.S_IFBLK
S_IFREG = C.S_IFREG
S_IFLNK = C.S_IFLNK
S_IFSOCK = C.S_IFSOCK
S_ISUID = C.S_ISUID
S_ISGID = C.S_ISGID
S_ISVTX = C.S_ISVTX
S_IRUSR = C.S_IRUSR
S_IWUSR = C.S_IWUSR
S_IXUSR = C.S_IXUSR
)
type Stat_t C.struct_stat type Stat_t C.struct_stat
type Statfs_t C.struct_statfs type Statfs_t C.struct_statfs

View file

@ -189,23 +189,6 @@ type _Gid_t C.gid_t
// Files // Files
const ( // Directory mode bits
S_IFMT = C.S_IFMT
S_IFIFO = C.S_IFIFO
S_IFCHR = C.S_IFCHR
S_IFDIR = C.S_IFDIR
S_IFBLK = C.S_IFBLK
S_IFREG = C.S_IFREG
S_IFLNK = C.S_IFLNK
S_IFSOCK = C.S_IFSOCK
S_ISUID = C.S_ISUID
S_ISGID = C.S_ISGID
S_ISVTX = C.S_ISVTX
S_IRUSR = C.S_IRUSR
S_IWUSR = C.S_IWUSR
S_IXUSR = C.S_IXUSR
)
type Stat_t C.struct_stat8 type Stat_t C.struct_stat8
type Statfs_t C.struct_statfs type Statfs_t C.struct_statfs

View file

@ -118,6 +118,17 @@ const (
PathMax = C.PATH_MAX PathMax = C.PATH_MAX
) )
// Advice to Fadvise
const (
FADV_NORMAL = C.POSIX_FADV_NORMAL
FADV_RANDOM = C.POSIX_FADV_RANDOM
FADV_SEQUENTIAL = C.POSIX_FADV_SEQUENTIAL
FADV_WILLNEED = C.POSIX_FADV_WILLNEED
FADV_DONTNEED = C.POSIX_FADV_DONTNEED
FADV_NOREUSE = C.POSIX_FADV_NOREUSE
)
// Sockets // Sockets
type RawSockaddrInet4 C.struct_sockaddr_in type RawSockaddrInet4 C.struct_sockaddr_in

View file

@ -101,23 +101,6 @@ type _Gid_t C.gid_t
// Files // Files
const ( // Directory mode bits
S_IFMT = C.S_IFMT
S_IFIFO = C.S_IFIFO
S_IFCHR = C.S_IFCHR
S_IFDIR = C.S_IFDIR
S_IFBLK = C.S_IFBLK
S_IFREG = C.S_IFREG
S_IFLNK = C.S_IFLNK
S_IFSOCK = C.S_IFSOCK
S_ISUID = C.S_ISUID
S_ISGID = C.S_ISGID
S_ISVTX = C.S_ISVTX
S_IRUSR = C.S_IRUSR
S_IWUSR = C.S_IWUSR
S_IXUSR = C.S_IXUSR
)
type Stat_t C.struct_stat type Stat_t C.struct_stat
type Statfs_t C.struct_statfs type Statfs_t C.struct_statfs

231
vendor/golang.org/x/sys/unix/xattr_bsd.go generated vendored Normal file
View file

@ -0,0 +1,231 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build freebsd netbsd
package unix
import (
"strings"
"unsafe"
)
// Derive extattr namespace and attribute name
func xattrnamespace(fullattr string) (ns int, attr string, err error) {
s := strings.IndexByte(fullattr, '.')
if s == -1 {
return -1, "", ENOATTR
}
namespace := fullattr[0:s]
attr = fullattr[s+1:]
switch namespace {
case "user":
return EXTATTR_NAMESPACE_USER, attr, nil
case "system":
return EXTATTR_NAMESPACE_SYSTEM, attr, nil
default:
return -1, "", ENOATTR
}
}
func initxattrdest(dest []byte, idx int) (d unsafe.Pointer) {
if len(dest) > idx {
return unsafe.Pointer(&dest[idx])
} else {
return unsafe.Pointer(_zero)
}
}
// FreeBSD and NetBSD implement their own syscalls to handle extended attributes
func Getxattr(file string, attr string, dest []byte) (sz int, err error) {
d := initxattrdest(dest, 0)
destsize := len(dest)
nsid, a, err := xattrnamespace(attr)
if err != nil {
return -1, err
}
return ExtattrGetFile(file, nsid, a, uintptr(d), destsize)
}
func Fgetxattr(fd int, attr string, dest []byte) (sz int, err error) {
d := initxattrdest(dest, 0)
destsize := len(dest)
nsid, a, err := xattrnamespace(attr)
if err != nil {
return -1, err
}
return ExtattrGetFd(fd, nsid, a, uintptr(d), destsize)
}
func Lgetxattr(link string, attr string, dest []byte) (sz int, err error) {
d := initxattrdest(dest, 0)
destsize := len(dest)
nsid, a, err := xattrnamespace(attr)
if err != nil {
return -1, err
}
return ExtattrGetLink(link, nsid, a, uintptr(d), destsize)
}
// flags are unused on FreeBSD
func Fsetxattr(fd int, attr string, data []byte, flags int) (err error) {
d := unsafe.Pointer(&data[0])
datasiz := len(data)
nsid, a, err := xattrnamespace(attr)
if err != nil {
return
}
_, err = ExtattrSetFd(fd, nsid, a, uintptr(d), datasiz)
return
}
func Setxattr(file string, attr string, data []byte, flags int) (err error) {
d := unsafe.Pointer(&data[0])
datasiz := len(data)
nsid, a, err := xattrnamespace(attr)
if err != nil {
return
}
_, err = ExtattrSetFile(file, nsid, a, uintptr(d), datasiz)
return
}
func Lsetxattr(link string, attr string, data []byte, flags int) (err error) {
d := unsafe.Pointer(&data[0])
datasiz := len(data)
nsid, a, err := xattrnamespace(attr)
if err != nil {
return
}
_, err = ExtattrSetLink(link, nsid, a, uintptr(d), datasiz)
return
}
func Removexattr(file string, attr string) (err error) {
nsid, a, err := xattrnamespace(attr)
if err != nil {
return
}
err = ExtattrDeleteFile(file, nsid, a)
return
}
func Fremovexattr(fd int, attr string) (err error) {
nsid, a, err := xattrnamespace(attr)
if err != nil {
return
}
err = ExtattrDeleteFd(fd, nsid, a)
return
}
func Lremovexattr(link string, attr string) (err error) {
nsid, a, err := xattrnamespace(attr)
if err != nil {
return
}
err = ExtattrDeleteLink(link, nsid, a)
return
}
func Listxattr(file string, dest []byte) (sz int, err error) {
d := initxattrdest(dest, 0)
destsiz := len(dest)
// FreeBSD won't allow you to list xattrs from multiple namespaces
s := 0
for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} {
stmp, e := ExtattrListFile(file, nsid, uintptr(d), destsiz)
/* Errors accessing system attrs are ignored so that
* we can implement the Linux-like behavior of omitting errors that
* we don't have read permissions on
*
* Linux will still error if we ask for user attributes on a file that
* we don't have read permissions on, so don't ignore those errors
*/
if e != nil && e == EPERM && nsid != EXTATTR_NAMESPACE_USER {
continue
} else if e != nil {
return s, e
}
s += stmp
destsiz -= s
if destsiz < 0 {
destsiz = 0
}
d = initxattrdest(dest, s)
}
return s, nil
}
func Flistxattr(fd int, dest []byte) (sz int, err error) {
d := initxattrdest(dest, 0)
destsiz := len(dest)
s := 0
for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} {
stmp, e := ExtattrListFd(fd, nsid, uintptr(d), destsiz)
if e != nil && e == EPERM && nsid != EXTATTR_NAMESPACE_USER {
continue
} else if e != nil {
return s, e
}
s += stmp
destsiz -= s
if destsiz < 0 {
destsiz = 0
}
d = initxattrdest(dest, s)
}
return s, nil
}
func Llistxattr(link string, dest []byte) (sz int, err error) {
d := initxattrdest(dest, 0)
destsiz := len(dest)
s := 0
for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} {
stmp, e := ExtattrListLink(link, nsid, uintptr(d), destsiz)
if e != nil && e == EPERM && nsid != EXTATTR_NAMESPACE_USER {
continue
} else if e != nil {
return s, e
}
s += stmp
destsiz -= s
if destsiz < 0 {
destsiz = 0
}
d = initxattrdest(dest, s)
}
return s, nil
}

View file

@ -1473,6 +1473,12 @@ const (
WORDSIZE = 0x20 WORDSIZE = 0x20
WSTOPPED = 0x8 WSTOPPED = 0x8
WUNTRACED = 0x2 WUNTRACED = 0x2
XATTR_CREATE = 0x2
XATTR_NODEFAULT = 0x10
XATTR_NOFOLLOW = 0x1
XATTR_NOSECURITY = 0x8
XATTR_REPLACE = 0x4
XATTR_SHOWCOMPRESSION = 0x20
) )
// Errors // Errors
@ -1624,146 +1630,154 @@ const (
) )
// Error table // Error table
var errors = [...]string{ var errorList = [...]struct {
1: "operation not permitted", num syscall.Errno
2: "no such file or directory", name string
3: "no such process", desc string
4: "interrupted system call", }{
5: "input/output error", {1, "EPERM", "operation not permitted"},
6: "device not configured", {2, "ENOENT", "no such file or directory"},
7: "argument list too long", {3, "ESRCH", "no such process"},
8: "exec format error", {4, "EINTR", "interrupted system call"},
9: "bad file descriptor", {5, "EIO", "input/output error"},
10: "no child processes", {6, "ENXIO", "device not configured"},
11: "resource deadlock avoided", {7, "E2BIG", "argument list too long"},
12: "cannot allocate memory", {8, "ENOEXEC", "exec format error"},
13: "permission denied", {9, "EBADF", "bad file descriptor"},
14: "bad address", {10, "ECHILD", "no child processes"},
15: "block device required", {11, "EDEADLK", "resource deadlock avoided"},
16: "resource busy", {12, "ENOMEM", "cannot allocate memory"},
17: "file exists", {13, "EACCES", "permission denied"},
18: "cross-device link", {14, "EFAULT", "bad address"},
19: "operation not supported by device", {15, "ENOTBLK", "block device required"},
20: "not a directory", {16, "EBUSY", "resource busy"},
21: "is a directory", {17, "EEXIST", "file exists"},
22: "invalid argument", {18, "EXDEV", "cross-device link"},
23: "too many open files in system", {19, "ENODEV", "operation not supported by device"},
24: "too many open files", {20, "ENOTDIR", "not a directory"},
25: "inappropriate ioctl for device", {21, "EISDIR", "is a directory"},
26: "text file busy", {22, "EINVAL", "invalid argument"},
27: "file too large", {23, "ENFILE", "too many open files in system"},
28: "no space left on device", {24, "EMFILE", "too many open files"},
29: "illegal seek", {25, "ENOTTY", "inappropriate ioctl for device"},
30: "read-only file system", {26, "ETXTBSY", "text file busy"},
31: "too many links", {27, "EFBIG", "file too large"},
32: "broken pipe", {28, "ENOSPC", "no space left on device"},
33: "numerical argument out of domain", {29, "ESPIPE", "illegal seek"},
34: "result too large", {30, "EROFS", "read-only file system"},
35: "resource temporarily unavailable", {31, "EMLINK", "too many links"},
36: "operation now in progress", {32, "EPIPE", "broken pipe"},
37: "operation already in progress", {33, "EDOM", "numerical argument out of domain"},
38: "socket operation on non-socket", {34, "ERANGE", "result too large"},
39: "destination address required", {35, "EAGAIN", "resource temporarily unavailable"},
40: "message too long", {36, "EINPROGRESS", "operation now in progress"},
41: "protocol wrong type for socket", {37, "EALREADY", "operation already in progress"},
42: "protocol not available", {38, "ENOTSOCK", "socket operation on non-socket"},
43: "protocol not supported", {39, "EDESTADDRREQ", "destination address required"},
44: "socket type not supported", {40, "EMSGSIZE", "message too long"},
45: "operation not supported", {41, "EPROTOTYPE", "protocol wrong type for socket"},
46: "protocol family not supported", {42, "ENOPROTOOPT", "protocol not available"},
47: "address family not supported by protocol family", {43, "EPROTONOSUPPORT", "protocol not supported"},
48: "address already in use", {44, "ESOCKTNOSUPPORT", "socket type not supported"},
49: "can't assign requested address", {45, "ENOTSUP", "operation not supported"},
50: "network is down", {46, "EPFNOSUPPORT", "protocol family not supported"},
51: "network is unreachable", {47, "EAFNOSUPPORT", "address family not supported by protocol family"},
52: "network dropped connection on reset", {48, "EADDRINUSE", "address already in use"},
53: "software caused connection abort", {49, "EADDRNOTAVAIL", "can't assign requested address"},
54: "connection reset by peer", {50, "ENETDOWN", "network is down"},
55: "no buffer space available", {51, "ENETUNREACH", "network is unreachable"},
56: "socket is already connected", {52, "ENETRESET", "network dropped connection on reset"},
57: "socket is not connected", {53, "ECONNABORTED", "software caused connection abort"},
58: "can't send after socket shutdown", {54, "ECONNRESET", "connection reset by peer"},
59: "too many references: can't splice", {55, "ENOBUFS", "no buffer space available"},
60: "operation timed out", {56, "EISCONN", "socket is already connected"},
61: "connection refused", {57, "ENOTCONN", "socket is not connected"},
62: "too many levels of symbolic links", {58, "ESHUTDOWN", "can't send after socket shutdown"},
63: "file name too long", {59, "ETOOMANYREFS", "too many references: can't splice"},
64: "host is down", {60, "ETIMEDOUT", "operation timed out"},
65: "no route to host", {61, "ECONNREFUSED", "connection refused"},
66: "directory not empty", {62, "ELOOP", "too many levels of symbolic links"},
67: "too many processes", {63, "ENAMETOOLONG", "file name too long"},
68: "too many users", {64, "EHOSTDOWN", "host is down"},
69: "disc quota exceeded", {65, "EHOSTUNREACH", "no route to host"},
70: "stale NFS file handle", {66, "ENOTEMPTY", "directory not empty"},
71: "too many levels of remote in path", {67, "EPROCLIM", "too many processes"},
72: "RPC struct is bad", {68, "EUSERS", "too many users"},
73: "RPC version wrong", {69, "EDQUOT", "disc quota exceeded"},
74: "RPC prog. not avail", {70, "ESTALE", "stale NFS file handle"},
75: "program version wrong", {71, "EREMOTE", "too many levels of remote in path"},
76: "bad procedure for program", {72, "EBADRPC", "RPC struct is bad"},
77: "no locks available", {73, "ERPCMISMATCH", "RPC version wrong"},
78: "function not implemented", {74, "EPROGUNAVAIL", "RPC prog. not avail"},
79: "inappropriate file type or format", {75, "EPROGMISMATCH", "program version wrong"},
80: "authentication error", {76, "EPROCUNAVAIL", "bad procedure for program"},
81: "need authenticator", {77, "ENOLCK", "no locks available"},
82: "device power is off", {78, "ENOSYS", "function not implemented"},
83: "device error", {79, "EFTYPE", "inappropriate file type or format"},
84: "value too large to be stored in data type", {80, "EAUTH", "authentication error"},
85: "bad executable (or shared library)", {81, "ENEEDAUTH", "need authenticator"},
86: "bad CPU type in executable", {82, "EPWROFF", "device power is off"},
87: "shared library version mismatch", {83, "EDEVERR", "device error"},
88: "malformed Mach-o file", {84, "EOVERFLOW", "value too large to be stored in data type"},
89: "operation canceled", {85, "EBADEXEC", "bad executable (or shared library)"},
90: "identifier removed", {86, "EBADARCH", "bad CPU type in executable"},
91: "no message of desired type", {87, "ESHLIBVERS", "shared library version mismatch"},
92: "illegal byte sequence", {88, "EBADMACHO", "malformed Mach-o file"},
93: "attribute not found", {89, "ECANCELED", "operation canceled"},
94: "bad message", {90, "EIDRM", "identifier removed"},
95: "EMULTIHOP (Reserved)", {91, "ENOMSG", "no message of desired type"},
96: "no message available on STREAM", {92, "EILSEQ", "illegal byte sequence"},
97: "ENOLINK (Reserved)", {93, "ENOATTR", "attribute not found"},
98: "no STREAM resources", {94, "EBADMSG", "bad message"},
99: "not a STREAM", {95, "EMULTIHOP", "EMULTIHOP (Reserved)"},
100: "protocol error", {96, "ENODATA", "no message available on STREAM"},
101: "STREAM ioctl timeout", {97, "ENOLINK", "ENOLINK (Reserved)"},
102: "operation not supported on socket", {98, "ENOSR", "no STREAM resources"},
103: "policy not found", {99, "ENOSTR", "not a STREAM"},
104: "state not recoverable", {100, "EPROTO", "protocol error"},
105: "previous owner died", {101, "ETIME", "STREAM ioctl timeout"},
106: "interface output queue is full", {102, "EOPNOTSUPP", "operation not supported on socket"},
{103, "ENOPOLICY", "policy not found"},
{104, "ENOTRECOVERABLE", "state not recoverable"},
{105, "EOWNERDEAD", "previous owner died"},
{106, "EQFULL", "interface output queue is full"},
} }
// Signal table // Signal table
var signals = [...]string{ var signalList = [...]struct {
1: "hangup", num syscall.Signal
2: "interrupt", name string
3: "quit", desc string
4: "illegal instruction", }{
5: "trace/BPT trap", {1, "SIGHUP", "hangup"},
6: "abort trap", {2, "SIGINT", "interrupt"},
7: "EMT trap", {3, "SIGQUIT", "quit"},
8: "floating point exception", {4, "SIGILL", "illegal instruction"},
9: "killed", {5, "SIGTRAP", "trace/BPT trap"},
10: "bus error", {6, "SIGABRT", "abort trap"},
11: "segmentation fault", {7, "SIGEMT", "EMT trap"},
12: "bad system call", {8, "SIGFPE", "floating point exception"},
13: "broken pipe", {9, "SIGKILL", "killed"},
14: "alarm clock", {10, "SIGBUS", "bus error"},
15: "terminated", {11, "SIGSEGV", "segmentation fault"},
16: "urgent I/O condition", {12, "SIGSYS", "bad system call"},
17: "suspended (signal)", {13, "SIGPIPE", "broken pipe"},
18: "suspended", {14, "SIGALRM", "alarm clock"},
19: "continued", {15, "SIGTERM", "terminated"},
20: "child exited", {16, "SIGURG", "urgent I/O condition"},
21: "stopped (tty input)", {17, "SIGSTOP", "suspended (signal)"},
22: "stopped (tty output)", {18, "SIGTSTP", "suspended"},
23: "I/O possible", {19, "SIGCONT", "continued"},
24: "cputime limit exceeded", {20, "SIGCHLD", "child exited"},
25: "filesize limit exceeded", {21, "SIGTTIN", "stopped (tty input)"},
26: "virtual timer expired", {22, "SIGTTOU", "stopped (tty output)"},
27: "profiling timer expired", {23, "SIGIO", "I/O possible"},
28: "window size changes", {24, "SIGXCPU", "cputime limit exceeded"},
29: "information request", {25, "SIGXFSZ", "filesize limit exceeded"},
30: "user defined signal 1", {26, "SIGVTALRM", "virtual timer expired"},
31: "user defined signal 2", {27, "SIGPROF", "profiling timer expired"},
{28, "SIGWINCH", "window size changes"},
{29, "SIGINFO", "information request"},
{30, "SIGUSR1", "user defined signal 1"},
{31, "SIGUSR2", "user defined signal 2"},
} }

View file

@ -1473,6 +1473,12 @@ const (
WORDSIZE = 0x40 WORDSIZE = 0x40
WSTOPPED = 0x8 WSTOPPED = 0x8
WUNTRACED = 0x2 WUNTRACED = 0x2
XATTR_CREATE = 0x2
XATTR_NODEFAULT = 0x10
XATTR_NOFOLLOW = 0x1
XATTR_NOSECURITY = 0x8
XATTR_REPLACE = 0x4
XATTR_SHOWCOMPRESSION = 0x20
) )
// Errors // Errors
@ -1624,146 +1630,154 @@ const (
) )
// Error table // Error table
var errors = [...]string{ var errorList = [...]struct {
1: "operation not permitted", num syscall.Errno
2: "no such file or directory", name string
3: "no such process", desc string
4: "interrupted system call", }{
5: "input/output error", {1, "EPERM", "operation not permitted"},
6: "device not configured", {2, "ENOENT", "no such file or directory"},
7: "argument list too long", {3, "ESRCH", "no such process"},
8: "exec format error", {4, "EINTR", "interrupted system call"},
9: "bad file descriptor", {5, "EIO", "input/output error"},
10: "no child processes", {6, "ENXIO", "device not configured"},
11: "resource deadlock avoided", {7, "E2BIG", "argument list too long"},
12: "cannot allocate memory", {8, "ENOEXEC", "exec format error"},
13: "permission denied", {9, "EBADF", "bad file descriptor"},
14: "bad address", {10, "ECHILD", "no child processes"},
15: "block device required", {11, "EDEADLK", "resource deadlock avoided"},
16: "resource busy", {12, "ENOMEM", "cannot allocate memory"},
17: "file exists", {13, "EACCES", "permission denied"},
18: "cross-device link", {14, "EFAULT", "bad address"},
19: "operation not supported by device", {15, "ENOTBLK", "block device required"},
20: "not a directory", {16, "EBUSY", "resource busy"},
21: "is a directory", {17, "EEXIST", "file exists"},
22: "invalid argument", {18, "EXDEV", "cross-device link"},
23: "too many open files in system", {19, "ENODEV", "operation not supported by device"},
24: "too many open files", {20, "ENOTDIR", "not a directory"},
25: "inappropriate ioctl for device", {21, "EISDIR", "is a directory"},
26: "text file busy", {22, "EINVAL", "invalid argument"},
27: "file too large", {23, "ENFILE", "too many open files in system"},
28: "no space left on device", {24, "EMFILE", "too many open files"},
29: "illegal seek", {25, "ENOTTY", "inappropriate ioctl for device"},
30: "read-only file system", {26, "ETXTBSY", "text file busy"},
31: "too many links", {27, "EFBIG", "file too large"},
32: "broken pipe", {28, "ENOSPC", "no space left on device"},
33: "numerical argument out of domain", {29, "ESPIPE", "illegal seek"},
34: "result too large", {30, "EROFS", "read-only file system"},
35: "resource temporarily unavailable", {31, "EMLINK", "too many links"},
36: "operation now in progress", {32, "EPIPE", "broken pipe"},
37: "operation already in progress", {33, "EDOM", "numerical argument out of domain"},
38: "socket operation on non-socket", {34, "ERANGE", "result too large"},
39: "destination address required", {35, "EAGAIN", "resource temporarily unavailable"},
40: "message too long", {36, "EINPROGRESS", "operation now in progress"},
41: "protocol wrong type for socket", {37, "EALREADY", "operation already in progress"},
42: "protocol not available", {38, "ENOTSOCK", "socket operation on non-socket"},
43: "protocol not supported", {39, "EDESTADDRREQ", "destination address required"},
44: "socket type not supported", {40, "EMSGSIZE", "message too long"},
45: "operation not supported", {41, "EPROTOTYPE", "protocol wrong type for socket"},
46: "protocol family not supported", {42, "ENOPROTOOPT", "protocol not available"},
47: "address family not supported by protocol family", {43, "EPROTONOSUPPORT", "protocol not supported"},
48: "address already in use", {44, "ESOCKTNOSUPPORT", "socket type not supported"},
49: "can't assign requested address", {45, "ENOTSUP", "operation not supported"},
50: "network is down", {46, "EPFNOSUPPORT", "protocol family not supported"},
51: "network is unreachable", {47, "EAFNOSUPPORT", "address family not supported by protocol family"},
52: "network dropped connection on reset", {48, "EADDRINUSE", "address already in use"},
53: "software caused connection abort", {49, "EADDRNOTAVAIL", "can't assign requested address"},
54: "connection reset by peer", {50, "ENETDOWN", "network is down"},
55: "no buffer space available", {51, "ENETUNREACH", "network is unreachable"},
56: "socket is already connected", {52, "ENETRESET", "network dropped connection on reset"},
57: "socket is not connected", {53, "ECONNABORTED", "software caused connection abort"},
58: "can't send after socket shutdown", {54, "ECONNRESET", "connection reset by peer"},
59: "too many references: can't splice", {55, "ENOBUFS", "no buffer space available"},
60: "operation timed out", {56, "EISCONN", "socket is already connected"},
61: "connection refused", {57, "ENOTCONN", "socket is not connected"},
62: "too many levels of symbolic links", {58, "ESHUTDOWN", "can't send after socket shutdown"},
63: "file name too long", {59, "ETOOMANYREFS", "too many references: can't splice"},
64: "host is down", {60, "ETIMEDOUT", "operation timed out"},
65: "no route to host", {61, "ECONNREFUSED", "connection refused"},
66: "directory not empty", {62, "ELOOP", "too many levels of symbolic links"},
67: "too many processes", {63, "ENAMETOOLONG", "file name too long"},
68: "too many users", {64, "EHOSTDOWN", "host is down"},
69: "disc quota exceeded", {65, "EHOSTUNREACH", "no route to host"},
70: "stale NFS file handle", {66, "ENOTEMPTY", "directory not empty"},
71: "too many levels of remote in path", {67, "EPROCLIM", "too many processes"},
72: "RPC struct is bad", {68, "EUSERS", "too many users"},
73: "RPC version wrong", {69, "EDQUOT", "disc quota exceeded"},
74: "RPC prog. not avail", {70, "ESTALE", "stale NFS file handle"},
75: "program version wrong", {71, "EREMOTE", "too many levels of remote in path"},
76: "bad procedure for program", {72, "EBADRPC", "RPC struct is bad"},
77: "no locks available", {73, "ERPCMISMATCH", "RPC version wrong"},
78: "function not implemented", {74, "EPROGUNAVAIL", "RPC prog. not avail"},
79: "inappropriate file type or format", {75, "EPROGMISMATCH", "program version wrong"},
80: "authentication error", {76, "EPROCUNAVAIL", "bad procedure for program"},
81: "need authenticator", {77, "ENOLCK", "no locks available"},
82: "device power is off", {78, "ENOSYS", "function not implemented"},
83: "device error", {79, "EFTYPE", "inappropriate file type or format"},
84: "value too large to be stored in data type", {80, "EAUTH", "authentication error"},
85: "bad executable (or shared library)", {81, "ENEEDAUTH", "need authenticator"},
86: "bad CPU type in executable", {82, "EPWROFF", "device power is off"},
87: "shared library version mismatch", {83, "EDEVERR", "device error"},
88: "malformed Mach-o file", {84, "EOVERFLOW", "value too large to be stored in data type"},
89: "operation canceled", {85, "EBADEXEC", "bad executable (or shared library)"},
90: "identifier removed", {86, "EBADARCH", "bad CPU type in executable"},
91: "no message of desired type", {87, "ESHLIBVERS", "shared library version mismatch"},
92: "illegal byte sequence", {88, "EBADMACHO", "malformed Mach-o file"},
93: "attribute not found", {89, "ECANCELED", "operation canceled"},
94: "bad message", {90, "EIDRM", "identifier removed"},
95: "EMULTIHOP (Reserved)", {91, "ENOMSG", "no message of desired type"},
96: "no message available on STREAM", {92, "EILSEQ", "illegal byte sequence"},
97: "ENOLINK (Reserved)", {93, "ENOATTR", "attribute not found"},
98: "no STREAM resources", {94, "EBADMSG", "bad message"},
99: "not a STREAM", {95, "EMULTIHOP", "EMULTIHOP (Reserved)"},
100: "protocol error", {96, "ENODATA", "no message available on STREAM"},
101: "STREAM ioctl timeout", {97, "ENOLINK", "ENOLINK (Reserved)"},
102: "operation not supported on socket", {98, "ENOSR", "no STREAM resources"},
103: "policy not found", {99, "ENOSTR", "not a STREAM"},
104: "state not recoverable", {100, "EPROTO", "protocol error"},
105: "previous owner died", {101, "ETIME", "STREAM ioctl timeout"},
106: "interface output queue is full", {102, "EOPNOTSUPP", "operation not supported on socket"},
{103, "ENOPOLICY", "policy not found"},
{104, "ENOTRECOVERABLE", "state not recoverable"},
{105, "EOWNERDEAD", "previous owner died"},
{106, "EQFULL", "interface output queue is full"},
} }
// Signal table // Signal table
var signals = [...]string{ var signalList = [...]struct {
1: "hangup", num syscall.Signal
2: "interrupt", name string
3: "quit", desc string
4: "illegal instruction", }{
5: "trace/BPT trap", {1, "SIGHUP", "hangup"},
6: "abort trap", {2, "SIGINT", "interrupt"},
7: "EMT trap", {3, "SIGQUIT", "quit"},
8: "floating point exception", {4, "SIGILL", "illegal instruction"},
9: "killed", {5, "SIGTRAP", "trace/BPT trap"},
10: "bus error", {6, "SIGABRT", "abort trap"},
11: "segmentation fault", {7, "SIGEMT", "EMT trap"},
12: "bad system call", {8, "SIGFPE", "floating point exception"},
13: "broken pipe", {9, "SIGKILL", "killed"},
14: "alarm clock", {10, "SIGBUS", "bus error"},
15: "terminated", {11, "SIGSEGV", "segmentation fault"},
16: "urgent I/O condition", {12, "SIGSYS", "bad system call"},
17: "suspended (signal)", {13, "SIGPIPE", "broken pipe"},
18: "suspended", {14, "SIGALRM", "alarm clock"},
19: "continued", {15, "SIGTERM", "terminated"},
20: "child exited", {16, "SIGURG", "urgent I/O condition"},
21: "stopped (tty input)", {17, "SIGSTOP", "suspended (signal)"},
22: "stopped (tty output)", {18, "SIGTSTP", "suspended"},
23: "I/O possible", {19, "SIGCONT", "continued"},
24: "cputime limit exceeded", {20, "SIGCHLD", "child exited"},
25: "filesize limit exceeded", {21, "SIGTTIN", "stopped (tty input)"},
26: "virtual timer expired", {22, "SIGTTOU", "stopped (tty output)"},
27: "profiling timer expired", {23, "SIGIO", "I/O possible"},
28: "window size changes", {24, "SIGXCPU", "cputime limit exceeded"},
29: "information request", {25, "SIGXFSZ", "filesize limit exceeded"},
30: "user defined signal 1", {26, "SIGVTALRM", "virtual timer expired"},
31: "user defined signal 2", {27, "SIGPROF", "profiling timer expired"},
{28, "SIGWINCH", "window size changes"},
{29, "SIGINFO", "information request"},
{30, "SIGUSR1", "user defined signal 1"},
{31, "SIGUSR2", "user defined signal 2"},
} }

View file

@ -1473,6 +1473,12 @@ const (
WORDSIZE = 0x40 WORDSIZE = 0x40
WSTOPPED = 0x8 WSTOPPED = 0x8
WUNTRACED = 0x2 WUNTRACED = 0x2
XATTR_CREATE = 0x2
XATTR_NODEFAULT = 0x10
XATTR_NOFOLLOW = 0x1
XATTR_NOSECURITY = 0x8
XATTR_REPLACE = 0x4
XATTR_SHOWCOMPRESSION = 0x20
) )
// Errors // Errors
@ -1624,146 +1630,154 @@ const (
) )
// Error table // Error table
var errors = [...]string{ var errorList = [...]struct {
1: "operation not permitted", num syscall.Errno
2: "no such file or directory", name string
3: "no such process", desc string
4: "interrupted system call", }{
5: "input/output error", {1, "EPERM", "operation not permitted"},
6: "device not configured", {2, "ENOENT", "no such file or directory"},
7: "argument list too long", {3, "ESRCH", "no such process"},
8: "exec format error", {4, "EINTR", "interrupted system call"},
9: "bad file descriptor", {5, "EIO", "input/output error"},
10: "no child processes", {6, "ENXIO", "device not configured"},
11: "resource deadlock avoided", {7, "E2BIG", "argument list too long"},
12: "cannot allocate memory", {8, "ENOEXEC", "exec format error"},
13: "permission denied", {9, "EBADF", "bad file descriptor"},
14: "bad address", {10, "ECHILD", "no child processes"},
15: "block device required", {11, "EDEADLK", "resource deadlock avoided"},
16: "resource busy", {12, "ENOMEM", "cannot allocate memory"},
17: "file exists", {13, "EACCES", "permission denied"},
18: "cross-device link", {14, "EFAULT", "bad address"},
19: "operation not supported by device", {15, "ENOTBLK", "block device required"},
20: "not a directory", {16, "EBUSY", "resource busy"},
21: "is a directory", {17, "EEXIST", "file exists"},
22: "invalid argument", {18, "EXDEV", "cross-device link"},
23: "too many open files in system", {19, "ENODEV", "operation not supported by device"},
24: "too many open files", {20, "ENOTDIR", "not a directory"},
25: "inappropriate ioctl for device", {21, "EISDIR", "is a directory"},
26: "text file busy", {22, "EINVAL", "invalid argument"},
27: "file too large", {23, "ENFILE", "too many open files in system"},
28: "no space left on device", {24, "EMFILE", "too many open files"},
29: "illegal seek", {25, "ENOTTY", "inappropriate ioctl for device"},
30: "read-only file system", {26, "ETXTBSY", "text file busy"},
31: "too many links", {27, "EFBIG", "file too large"},
32: "broken pipe", {28, "ENOSPC", "no space left on device"},
33: "numerical argument out of domain", {29, "ESPIPE", "illegal seek"},
34: "result too large", {30, "EROFS", "read-only file system"},
35: "resource temporarily unavailable", {31, "EMLINK", "too many links"},
36: "operation now in progress", {32, "EPIPE", "broken pipe"},
37: "operation already in progress", {33, "EDOM", "numerical argument out of domain"},
38: "socket operation on non-socket", {34, "ERANGE", "result too large"},
39: "destination address required", {35, "EAGAIN", "resource temporarily unavailable"},
40: "message too long", {36, "EINPROGRESS", "operation now in progress"},
41: "protocol wrong type for socket", {37, "EALREADY", "operation already in progress"},
42: "protocol not available", {38, "ENOTSOCK", "socket operation on non-socket"},
43: "protocol not supported", {39, "EDESTADDRREQ", "destination address required"},
44: "socket type not supported", {40, "EMSGSIZE", "message too long"},
45: "operation not supported", {41, "EPROTOTYPE", "protocol wrong type for socket"},
46: "protocol family not supported", {42, "ENOPROTOOPT", "protocol not available"},
47: "address family not supported by protocol family", {43, "EPROTONOSUPPORT", "protocol not supported"},
48: "address already in use", {44, "ESOCKTNOSUPPORT", "socket type not supported"},
49: "can't assign requested address", {45, "ENOTSUP", "operation not supported"},
50: "network is down", {46, "EPFNOSUPPORT", "protocol family not supported"},
51: "network is unreachable", {47, "EAFNOSUPPORT", "address family not supported by protocol family"},
52: "network dropped connection on reset", {48, "EADDRINUSE", "address already in use"},
53: "software caused connection abort", {49, "EADDRNOTAVAIL", "can't assign requested address"},
54: "connection reset by peer", {50, "ENETDOWN", "network is down"},
55: "no buffer space available", {51, "ENETUNREACH", "network is unreachable"},
56: "socket is already connected", {52, "ENETRESET", "network dropped connection on reset"},
57: "socket is not connected", {53, "ECONNABORTED", "software caused connection abort"},
58: "can't send after socket shutdown", {54, "ECONNRESET", "connection reset by peer"},
59: "too many references: can't splice", {55, "ENOBUFS", "no buffer space available"},
60: "operation timed out", {56, "EISCONN", "socket is already connected"},
61: "connection refused", {57, "ENOTCONN", "socket is not connected"},
62: "too many levels of symbolic links", {58, "ESHUTDOWN", "can't send after socket shutdown"},
63: "file name too long", {59, "ETOOMANYREFS", "too many references: can't splice"},
64: "host is down", {60, "ETIMEDOUT", "operation timed out"},
65: "no route to host", {61, "ECONNREFUSED", "connection refused"},
66: "directory not empty", {62, "ELOOP", "too many levels of symbolic links"},
67: "too many processes", {63, "ENAMETOOLONG", "file name too long"},
68: "too many users", {64, "EHOSTDOWN", "host is down"},
69: "disc quota exceeded", {65, "EHOSTUNREACH", "no route to host"},
70: "stale NFS file handle", {66, "ENOTEMPTY", "directory not empty"},
71: "too many levels of remote in path", {67, "EPROCLIM", "too many processes"},
72: "RPC struct is bad", {68, "EUSERS", "too many users"},
73: "RPC version wrong", {69, "EDQUOT", "disc quota exceeded"},
74: "RPC prog. not avail", {70, "ESTALE", "stale NFS file handle"},
75: "program version wrong", {71, "EREMOTE", "too many levels of remote in path"},
76: "bad procedure for program", {72, "EBADRPC", "RPC struct is bad"},
77: "no locks available", {73, "ERPCMISMATCH", "RPC version wrong"},
78: "function not implemented", {74, "EPROGUNAVAIL", "RPC prog. not avail"},
79: "inappropriate file type or format", {75, "EPROGMISMATCH", "program version wrong"},
80: "authentication error", {76, "EPROCUNAVAIL", "bad procedure for program"},
81: "need authenticator", {77, "ENOLCK", "no locks available"},
82: "device power is off", {78, "ENOSYS", "function not implemented"},
83: "device error", {79, "EFTYPE", "inappropriate file type or format"},
84: "value too large to be stored in data type", {80, "EAUTH", "authentication error"},
85: "bad executable (or shared library)", {81, "ENEEDAUTH", "need authenticator"},
86: "bad CPU type in executable", {82, "EPWROFF", "device power is off"},
87: "shared library version mismatch", {83, "EDEVERR", "device error"},
88: "malformed Mach-o file", {84, "EOVERFLOW", "value too large to be stored in data type"},
89: "operation canceled", {85, "EBADEXEC", "bad executable (or shared library)"},
90: "identifier removed", {86, "EBADARCH", "bad CPU type in executable"},
91: "no message of desired type", {87, "ESHLIBVERS", "shared library version mismatch"},
92: "illegal byte sequence", {88, "EBADMACHO", "malformed Mach-o file"},
93: "attribute not found", {89, "ECANCELED", "operation canceled"},
94: "bad message", {90, "EIDRM", "identifier removed"},
95: "EMULTIHOP (Reserved)", {91, "ENOMSG", "no message of desired type"},
96: "no message available on STREAM", {92, "EILSEQ", "illegal byte sequence"},
97: "ENOLINK (Reserved)", {93, "ENOATTR", "attribute not found"},
98: "no STREAM resources", {94, "EBADMSG", "bad message"},
99: "not a STREAM", {95, "EMULTIHOP", "EMULTIHOP (Reserved)"},
100: "protocol error", {96, "ENODATA", "no message available on STREAM"},
101: "STREAM ioctl timeout", {97, "ENOLINK", "ENOLINK (Reserved)"},
102: "operation not supported on socket", {98, "ENOSR", "no STREAM resources"},
103: "policy not found", {99, "ENOSTR", "not a STREAM"},
104: "state not recoverable", {100, "EPROTO", "protocol error"},
105: "previous owner died", {101, "ETIME", "STREAM ioctl timeout"},
106: "interface output queue is full", {102, "EOPNOTSUPP", "operation not supported on socket"},
{103, "ENOPOLICY", "policy not found"},
{104, "ENOTRECOVERABLE", "state not recoverable"},
{105, "EOWNERDEAD", "previous owner died"},
{106, "EQFULL", "interface output queue is full"},
} }
// Signal table // Signal table
var signals = [...]string{ var signalList = [...]struct {
1: "hangup", num syscall.Signal
2: "interrupt", name string
3: "quit", desc string
4: "illegal instruction", }{
5: "trace/BPT trap", {1, "SIGHUP", "hangup"},
6: "abort trap", {2, "SIGINT", "interrupt"},
7: "EMT trap", {3, "SIGQUIT", "quit"},
8: "floating point exception", {4, "SIGILL", "illegal instruction"},
9: "killed", {5, "SIGTRAP", "trace/BPT trap"},
10: "bus error", {6, "SIGABRT", "abort trap"},
11: "segmentation fault", {7, "SIGEMT", "EMT trap"},
12: "bad system call", {8, "SIGFPE", "floating point exception"},
13: "broken pipe", {9, "SIGKILL", "killed"},
14: "alarm clock", {10, "SIGBUS", "bus error"},
15: "terminated", {11, "SIGSEGV", "segmentation fault"},
16: "urgent I/O condition", {12, "SIGSYS", "bad system call"},
17: "suspended (signal)", {13, "SIGPIPE", "broken pipe"},
18: "suspended", {14, "SIGALRM", "alarm clock"},
19: "continued", {15, "SIGTERM", "terminated"},
20: "child exited", {16, "SIGURG", "urgent I/O condition"},
21: "stopped (tty input)", {17, "SIGSTOP", "suspended (signal)"},
22: "stopped (tty output)", {18, "SIGTSTP", "suspended"},
23: "I/O possible", {19, "SIGCONT", "continued"},
24: "cputime limit exceeded", {20, "SIGCHLD", "child exited"},
25: "filesize limit exceeded", {21, "SIGTTIN", "stopped (tty input)"},
26: "virtual timer expired", {22, "SIGTTOU", "stopped (tty output)"},
27: "profiling timer expired", {23, "SIGIO", "I/O possible"},
28: "window size changes", {24, "SIGXCPU", "cputime limit exceeded"},
29: "information request", {25, "SIGXFSZ", "filesize limit exceeded"},
30: "user defined signal 1", {26, "SIGVTALRM", "virtual timer expired"},
31: "user defined signal 2", {27, "SIGPROF", "profiling timer expired"},
{28, "SIGWINCH", "window size changes"},
{29, "SIGINFO", "information request"},
{30, "SIGUSR1", "user defined signal 1"},
{31, "SIGUSR2", "user defined signal 2"},
} }

View file

@ -1473,6 +1473,12 @@ const (
WORDSIZE = 0x40 WORDSIZE = 0x40
WSTOPPED = 0x8 WSTOPPED = 0x8
WUNTRACED = 0x2 WUNTRACED = 0x2
XATTR_CREATE = 0x2
XATTR_NODEFAULT = 0x10
XATTR_NOFOLLOW = 0x1
XATTR_NOSECURITY = 0x8
XATTR_REPLACE = 0x4
XATTR_SHOWCOMPRESSION = 0x20
) )
// Errors // Errors
@ -1624,146 +1630,154 @@ const (
) )
// Error table // Error table
var errors = [...]string{ var errorList = [...]struct {
1: "operation not permitted", num syscall.Errno
2: "no such file or directory", name string
3: "no such process", desc string
4: "interrupted system call", }{
5: "input/output error", {1, "EPERM", "operation not permitted"},
6: "device not configured", {2, "ENOENT", "no such file or directory"},
7: "argument list too long", {3, "ESRCH", "no such process"},
8: "exec format error", {4, "EINTR", "interrupted system call"},
9: "bad file descriptor", {5, "EIO", "input/output error"},
10: "no child processes", {6, "ENXIO", "device not configured"},
11: "resource deadlock avoided", {7, "E2BIG", "argument list too long"},
12: "cannot allocate memory", {8, "ENOEXEC", "exec format error"},
13: "permission denied", {9, "EBADF", "bad file descriptor"},
14: "bad address", {10, "ECHILD", "no child processes"},
15: "block device required", {11, "EDEADLK", "resource deadlock avoided"},
16: "resource busy", {12, "ENOMEM", "cannot allocate memory"},
17: "file exists", {13, "EACCES", "permission denied"},
18: "cross-device link", {14, "EFAULT", "bad address"},
19: "operation not supported by device", {15, "ENOTBLK", "block device required"},
20: "not a directory", {16, "EBUSY", "resource busy"},
21: "is a directory", {17, "EEXIST", "file exists"},
22: "invalid argument", {18, "EXDEV", "cross-device link"},
23: "too many open files in system", {19, "ENODEV", "operation not supported by device"},
24: "too many open files", {20, "ENOTDIR", "not a directory"},
25: "inappropriate ioctl for device", {21, "EISDIR", "is a directory"},
26: "text file busy", {22, "EINVAL", "invalid argument"},
27: "file too large", {23, "ENFILE", "too many open files in system"},
28: "no space left on device", {24, "EMFILE", "too many open files"},
29: "illegal seek", {25, "ENOTTY", "inappropriate ioctl for device"},
30: "read-only file system", {26, "ETXTBSY", "text file busy"},
31: "too many links", {27, "EFBIG", "file too large"},
32: "broken pipe", {28, "ENOSPC", "no space left on device"},
33: "numerical argument out of domain", {29, "ESPIPE", "illegal seek"},
34: "result too large", {30, "EROFS", "read-only file system"},
35: "resource temporarily unavailable", {31, "EMLINK", "too many links"},
36: "operation now in progress", {32, "EPIPE", "broken pipe"},
37: "operation already in progress", {33, "EDOM", "numerical argument out of domain"},
38: "socket operation on non-socket", {34, "ERANGE", "result too large"},
39: "destination address required", {35, "EAGAIN", "resource temporarily unavailable"},
40: "message too long", {36, "EINPROGRESS", "operation now in progress"},
41: "protocol wrong type for socket", {37, "EALREADY", "operation already in progress"},
42: "protocol not available", {38, "ENOTSOCK", "socket operation on non-socket"},
43: "protocol not supported", {39, "EDESTADDRREQ", "destination address required"},
44: "socket type not supported", {40, "EMSGSIZE", "message too long"},
45: "operation not supported", {41, "EPROTOTYPE", "protocol wrong type for socket"},
46: "protocol family not supported", {42, "ENOPROTOOPT", "protocol not available"},
47: "address family not supported by protocol family", {43, "EPROTONOSUPPORT", "protocol not supported"},
48: "address already in use", {44, "ESOCKTNOSUPPORT", "socket type not supported"},
49: "can't assign requested address", {45, "ENOTSUP", "operation not supported"},
50: "network is down", {46, "EPFNOSUPPORT", "protocol family not supported"},
51: "network is unreachable", {47, "EAFNOSUPPORT", "address family not supported by protocol family"},
52: "network dropped connection on reset", {48, "EADDRINUSE", "address already in use"},
53: "software caused connection abort", {49, "EADDRNOTAVAIL", "can't assign requested address"},
54: "connection reset by peer", {50, "ENETDOWN", "network is down"},
55: "no buffer space available", {51, "ENETUNREACH", "network is unreachable"},
56: "socket is already connected", {52, "ENETRESET", "network dropped connection on reset"},
57: "socket is not connected", {53, "ECONNABORTED", "software caused connection abort"},
58: "can't send after socket shutdown", {54, "ECONNRESET", "connection reset by peer"},
59: "too many references: can't splice", {55, "ENOBUFS", "no buffer space available"},
60: "operation timed out", {56, "EISCONN", "socket is already connected"},
61: "connection refused", {57, "ENOTCONN", "socket is not connected"},
62: "too many levels of symbolic links", {58, "ESHUTDOWN", "can't send after socket shutdown"},
63: "file name too long", {59, "ETOOMANYREFS", "too many references: can't splice"},
64: "host is down", {60, "ETIMEDOUT", "operation timed out"},
65: "no route to host", {61, "ECONNREFUSED", "connection refused"},
66: "directory not empty", {62, "ELOOP", "too many levels of symbolic links"},
67: "too many processes", {63, "ENAMETOOLONG", "file name too long"},
68: "too many users", {64, "EHOSTDOWN", "host is down"},
69: "disc quota exceeded", {65, "EHOSTUNREACH", "no route to host"},
70: "stale NFS file handle", {66, "ENOTEMPTY", "directory not empty"},
71: "too many levels of remote in path", {67, "EPROCLIM", "too many processes"},
72: "RPC struct is bad", {68, "EUSERS", "too many users"},
73: "RPC version wrong", {69, "EDQUOT", "disc quota exceeded"},
74: "RPC prog. not avail", {70, "ESTALE", "stale NFS file handle"},
75: "program version wrong", {71, "EREMOTE", "too many levels of remote in path"},
76: "bad procedure for program", {72, "EBADRPC", "RPC struct is bad"},
77: "no locks available", {73, "ERPCMISMATCH", "RPC version wrong"},
78: "function not implemented", {74, "EPROGUNAVAIL", "RPC prog. not avail"},
79: "inappropriate file type or format", {75, "EPROGMISMATCH", "program version wrong"},
80: "authentication error", {76, "EPROCUNAVAIL", "bad procedure for program"},
81: "need authenticator", {77, "ENOLCK", "no locks available"},
82: "device power is off", {78, "ENOSYS", "function not implemented"},
83: "device error", {79, "EFTYPE", "inappropriate file type or format"},
84: "value too large to be stored in data type", {80, "EAUTH", "authentication error"},
85: "bad executable (or shared library)", {81, "ENEEDAUTH", "need authenticator"},
86: "bad CPU type in executable", {82, "EPWROFF", "device power is off"},
87: "shared library version mismatch", {83, "EDEVERR", "device error"},
88: "malformed Mach-o file", {84, "EOVERFLOW", "value too large to be stored in data type"},
89: "operation canceled", {85, "EBADEXEC", "bad executable (or shared library)"},
90: "identifier removed", {86, "EBADARCH", "bad CPU type in executable"},
91: "no message of desired type", {87, "ESHLIBVERS", "shared library version mismatch"},
92: "illegal byte sequence", {88, "EBADMACHO", "malformed Mach-o file"},
93: "attribute not found", {89, "ECANCELED", "operation canceled"},
94: "bad message", {90, "EIDRM", "identifier removed"},
95: "EMULTIHOP (Reserved)", {91, "ENOMSG", "no message of desired type"},
96: "no message available on STREAM", {92, "EILSEQ", "illegal byte sequence"},
97: "ENOLINK (Reserved)", {93, "ENOATTR", "attribute not found"},
98: "no STREAM resources", {94, "EBADMSG", "bad message"},
99: "not a STREAM", {95, "EMULTIHOP", "EMULTIHOP (Reserved)"},
100: "protocol error", {96, "ENODATA", "no message available on STREAM"},
101: "STREAM ioctl timeout", {97, "ENOLINK", "ENOLINK (Reserved)"},
102: "operation not supported on socket", {98, "ENOSR", "no STREAM resources"},
103: "policy not found", {99, "ENOSTR", "not a STREAM"},
104: "state not recoverable", {100, "EPROTO", "protocol error"},
105: "previous owner died", {101, "ETIME", "STREAM ioctl timeout"},
106: "interface output queue is full", {102, "EOPNOTSUPP", "operation not supported on socket"},
{103, "ENOPOLICY", "policy not found"},
{104, "ENOTRECOVERABLE", "state not recoverable"},
{105, "EOWNERDEAD", "previous owner died"},
{106, "EQFULL", "interface output queue is full"},
} }
// Signal table // Signal table
var signals = [...]string{ var signalList = [...]struct {
1: "hangup", num syscall.Signal
2: "interrupt", name string
3: "quit", desc string
4: "illegal instruction", }{
5: "trace/BPT trap", {1, "SIGHUP", "hangup"},
6: "abort trap", {2, "SIGINT", "interrupt"},
7: "EMT trap", {3, "SIGQUIT", "quit"},
8: "floating point exception", {4, "SIGILL", "illegal instruction"},
9: "killed", {5, "SIGTRAP", "trace/BPT trap"},
10: "bus error", {6, "SIGABRT", "abort trap"},
11: "segmentation fault", {7, "SIGEMT", "EMT trap"},
12: "bad system call", {8, "SIGFPE", "floating point exception"},
13: "broken pipe", {9, "SIGKILL", "killed"},
14: "alarm clock", {10, "SIGBUS", "bus error"},
15: "terminated", {11, "SIGSEGV", "segmentation fault"},
16: "urgent I/O condition", {12, "SIGSYS", "bad system call"},
17: "suspended (signal)", {13, "SIGPIPE", "broken pipe"},
18: "suspended", {14, "SIGALRM", "alarm clock"},
19: "continued", {15, "SIGTERM", "terminated"},
20: "child exited", {16, "SIGURG", "urgent I/O condition"},
21: "stopped (tty input)", {17, "SIGSTOP", "suspended (signal)"},
22: "stopped (tty output)", {18, "SIGTSTP", "suspended"},
23: "I/O possible", {19, "SIGCONT", "continued"},
24: "cputime limit exceeded", {20, "SIGCHLD", "child exited"},
25: "filesize limit exceeded", {21, "SIGTTIN", "stopped (tty input)"},
26: "virtual timer expired", {22, "SIGTTOU", "stopped (tty output)"},
27: "profiling timer expired", {23, "SIGIO", "I/O possible"},
28: "window size changes", {24, "SIGXCPU", "cputime limit exceeded"},
29: "information request", {25, "SIGXFSZ", "filesize limit exceeded"},
30: "user defined signal 1", {26, "SIGVTALRM", "virtual timer expired"},
31: "user defined signal 2", {27, "SIGPROF", "profiling timer expired"},
{28, "SIGWINCH", "window size changes"},
{29, "SIGINFO", "information request"},
{30, "SIGUSR1", "user defined signal 1"},
{31, "SIGUSR2", "user defined signal 2"},
} }

View file

@ -3,7 +3,7 @@
// +build amd64,dragonfly // +build amd64,dragonfly
// Created by cgo -godefs - DO NOT EDIT // Code generated by cmd/cgo -godefs; DO NOT EDIT.
// cgo -godefs -- -m64 _const.go // cgo -godefs -- -m64 _const.go
package unix package unix
@ -980,7 +980,10 @@ const (
RLIMIT_CPU = 0x0 RLIMIT_CPU = 0x0
RLIMIT_DATA = 0x2 RLIMIT_DATA = 0x2
RLIMIT_FSIZE = 0x1 RLIMIT_FSIZE = 0x1
RLIMIT_MEMLOCK = 0x6
RLIMIT_NOFILE = 0x8 RLIMIT_NOFILE = 0x8
RLIMIT_NPROC = 0x7
RLIMIT_RSS = 0x5
RLIMIT_STACK = 0x3 RLIMIT_STACK = 0x3
RLIM_INFINITY = 0x7fffffffffffffff RLIM_INFINITY = 0x7fffffffffffffff
RTAX_AUTHOR = 0x6 RTAX_AUTHOR = 0x6
@ -1165,6 +1168,36 @@ const (
SO_TIMESTAMP = 0x400 SO_TIMESTAMP = 0x400
SO_TYPE = 0x1008 SO_TYPE = 0x1008
SO_USELOOPBACK = 0x40 SO_USELOOPBACK = 0x40
S_BLKSIZE = 0x200
S_IEXEC = 0x40
S_IFBLK = 0x6000
S_IFCHR = 0x2000
S_IFDB = 0x9000
S_IFDIR = 0x4000
S_IFIFO = 0x1000
S_IFLNK = 0xa000
S_IFMT = 0xf000
S_IFREG = 0x8000
S_IFSOCK = 0xc000
S_IFWHT = 0xe000
S_IREAD = 0x100
S_IRGRP = 0x20
S_IROTH = 0x4
S_IRUSR = 0x100
S_IRWXG = 0x38
S_IRWXO = 0x7
S_IRWXU = 0x1c0
S_ISGID = 0x400
S_ISTXT = 0x200
S_ISUID = 0x800
S_ISVTX = 0x200
S_IWGRP = 0x10
S_IWOTH = 0x2
S_IWRITE = 0x80
S_IWUSR = 0x80
S_IXGRP = 0x8
S_IXOTH = 0x1
S_IXUSR = 0x40
TCIFLUSH = 0x1 TCIFLUSH = 0x1
TCIOFF = 0x3 TCIOFF = 0x3
TCIOFLUSH = 0x3 TCIOFLUSH = 0x3
@ -1434,142 +1467,150 @@ const (
) )
// Error table // Error table
var errors = [...]string{ var errorList = [...]struct {
1: "operation not permitted", num syscall.Errno
2: "no such file or directory", name string
3: "no such process", desc string
4: "interrupted system call", }{
5: "input/output error", {1, "EPERM", "operation not permitted"},
6: "device not configured", {2, "ENOENT", "no such file or directory"},
7: "argument list too long", {3, "ESRCH", "no such process"},
8: "exec format error", {4, "EINTR", "interrupted system call"},
9: "bad file descriptor", {5, "EIO", "input/output error"},
10: "no child processes", {6, "ENXIO", "device not configured"},
11: "resource deadlock avoided", {7, "E2BIG", "argument list too long"},
12: "cannot allocate memory", {8, "ENOEXEC", "exec format error"},
13: "permission denied", {9, "EBADF", "bad file descriptor"},
14: "bad address", {10, "ECHILD", "no child processes"},
15: "block device required", {11, "EDEADLK", "resource deadlock avoided"},
16: "device busy", {12, "ENOMEM", "cannot allocate memory"},
17: "file exists", {13, "EACCES", "permission denied"},
18: "cross-device link", {14, "EFAULT", "bad address"},
19: "operation not supported by device", {15, "ENOTBLK", "block device required"},
20: "not a directory", {16, "EBUSY", "device busy"},
21: "is a directory", {17, "EEXIST", "file exists"},
22: "invalid argument", {18, "EXDEV", "cross-device link"},
23: "too many open files in system", {19, "ENODEV", "operation not supported by device"},
24: "too many open files", {20, "ENOTDIR", "not a directory"},
25: "inappropriate ioctl for device", {21, "EISDIR", "is a directory"},
26: "text file busy", {22, "EINVAL", "invalid argument"},
27: "file too large", {23, "ENFILE", "too many open files in system"},
28: "no space left on device", {24, "EMFILE", "too many open files"},
29: "illegal seek", {25, "ENOTTY", "inappropriate ioctl for device"},
30: "read-only file system", {26, "ETXTBSY", "text file busy"},
31: "too many links", {27, "EFBIG", "file too large"},
32: "broken pipe", {28, "ENOSPC", "no space left on device"},
33: "numerical argument out of domain", {29, "ESPIPE", "illegal seek"},
34: "result too large", {30, "EROFS", "read-only file system"},
35: "resource temporarily unavailable", {31, "EMLINK", "too many links"},
36: "operation now in progress", {32, "EPIPE", "broken pipe"},
37: "operation already in progress", {33, "EDOM", "numerical argument out of domain"},
38: "socket operation on non-socket", {34, "ERANGE", "result too large"},
39: "destination address required", {35, "EWOULDBLOCK", "resource temporarily unavailable"},
40: "message too long", {36, "EINPROGRESS", "operation now in progress"},
41: "protocol wrong type for socket", {37, "EALREADY", "operation already in progress"},
42: "protocol not available", {38, "ENOTSOCK", "socket operation on non-socket"},
43: "protocol not supported", {39, "EDESTADDRREQ", "destination address required"},
44: "socket type not supported", {40, "EMSGSIZE", "message too long"},
45: "operation not supported", {41, "EPROTOTYPE", "protocol wrong type for socket"},
46: "protocol family not supported", {42, "ENOPROTOOPT", "protocol not available"},
47: "address family not supported by protocol family", {43, "EPROTONOSUPPORT", "protocol not supported"},
48: "address already in use", {44, "ESOCKTNOSUPPORT", "socket type not supported"},
49: "can't assign requested address", {45, "EOPNOTSUPP", "operation not supported"},
50: "network is down", {46, "EPFNOSUPPORT", "protocol family not supported"},
51: "network is unreachable", {47, "EAFNOSUPPORT", "address family not supported by protocol family"},
52: "network dropped connection on reset", {48, "EADDRINUSE", "address already in use"},
53: "software caused connection abort", {49, "EADDRNOTAVAIL", "can't assign requested address"},
54: "connection reset by peer", {50, "ENETDOWN", "network is down"},
55: "no buffer space available", {51, "ENETUNREACH", "network is unreachable"},
56: "socket is already connected", {52, "ENETRESET", "network dropped connection on reset"},
57: "socket is not connected", {53, "ECONNABORTED", "software caused connection abort"},
58: "can't send after socket shutdown", {54, "ECONNRESET", "connection reset by peer"},
59: "too many references: can't splice", {55, "ENOBUFS", "no buffer space available"},
60: "operation timed out", {56, "EISCONN", "socket is already connected"},
61: "connection refused", {57, "ENOTCONN", "socket is not connected"},
62: "too many levels of symbolic links", {58, "ESHUTDOWN", "can't send after socket shutdown"},
63: "file name too long", {59, "ETOOMANYREFS", "too many references: can't splice"},
64: "host is down", {60, "ETIMEDOUT", "operation timed out"},
65: "no route to host", {61, "ECONNREFUSED", "connection refused"},
66: "directory not empty", {62, "ELOOP", "too many levels of symbolic links"},
67: "too many processes", {63, "ENAMETOOLONG", "file name too long"},
68: "too many users", {64, "EHOSTDOWN", "host is down"},
69: "disc quota exceeded", {65, "EHOSTUNREACH", "no route to host"},
70: "stale NFS file handle", {66, "ENOTEMPTY", "directory not empty"},
71: "too many levels of remote in path", {67, "EPROCLIM", "too many processes"},
72: "RPC struct is bad", {68, "EUSERS", "too many users"},
73: "RPC version wrong", {69, "EDQUOT", "disc quota exceeded"},
74: "RPC prog. not avail", {70, "ESTALE", "stale NFS file handle"},
75: "program version wrong", {71, "EREMOTE", "too many levels of remote in path"},
76: "bad procedure for program", {72, "EBADRPC", "RPC struct is bad"},
77: "no locks available", {73, "ERPCMISMATCH", "RPC version wrong"},
78: "function not implemented", {74, "EPROGUNAVAIL", "RPC prog. not avail"},
79: "inappropriate file type or format", {75, "EPROGMISMATCH", "program version wrong"},
80: "authentication error", {76, "EPROCUNAVAIL", "bad procedure for program"},
81: "need authenticator", {77, "ENOLCK", "no locks available"},
82: "identifier removed", {78, "ENOSYS", "function not implemented"},
83: "no message of desired type", {79, "EFTYPE", "inappropriate file type or format"},
84: "value too large to be stored in data type", {80, "EAUTH", "authentication error"},
85: "operation canceled", {81, "ENEEDAUTH", "need authenticator"},
86: "illegal byte sequence", {82, "EIDRM", "identifier removed"},
87: "attribute not found", {83, "ENOMSG", "no message of desired type"},
88: "programming error", {84, "EOVERFLOW", "value too large to be stored in data type"},
89: "bad message", {85, "ECANCELED", "operation canceled"},
90: "multihop attempted", {86, "EILSEQ", "illegal byte sequence"},
91: "link has been severed", {87, "ENOATTR", "attribute not found"},
92: "protocol error", {88, "EDOOFUS", "programming error"},
93: "no medium found", {89, "EBADMSG", "bad message"},
94: "unknown error: 94", {90, "EMULTIHOP", "multihop attempted"},
95: "unknown error: 95", {91, "ENOLINK", "link has been severed"},
96: "unknown error: 96", {92, "EPROTO", "protocol error"},
97: "unknown error: 97", {93, "ENOMEDIUM", "no medium found"},
98: "unknown error: 98", {94, "EUNUSED94", "unknown error: 94"},
99: "unknown error: 99", {95, "EUNUSED95", "unknown error: 95"},
{96, "EUNUSED96", "unknown error: 96"},
{97, "EUNUSED97", "unknown error: 97"},
{98, "EUNUSED98", "unknown error: 98"},
{99, "ELAST", "unknown error: 99"},
} }
// Signal table // Signal table
var signals = [...]string{ var signalList = [...]struct {
1: "hangup", num syscall.Signal
2: "interrupt", name string
3: "quit", desc string
4: "illegal instruction", }{
5: "trace/BPT trap", {1, "SIGHUP", "hangup"},
6: "abort trap", {2, "SIGINT", "interrupt"},
7: "EMT trap", {3, "SIGQUIT", "quit"},
8: "floating point exception", {4, "SIGILL", "illegal instruction"},
9: "killed", {5, "SIGTRAP", "trace/BPT trap"},
10: "bus error", {6, "SIGIOT", "abort trap"},
11: "segmentation fault", {7, "SIGEMT", "EMT trap"},
12: "bad system call", {8, "SIGFPE", "floating point exception"},
13: "broken pipe", {9, "SIGKILL", "killed"},
14: "alarm clock", {10, "SIGBUS", "bus error"},
15: "terminated", {11, "SIGSEGV", "segmentation fault"},
16: "urgent I/O condition", {12, "SIGSYS", "bad system call"},
17: "suspended (signal)", {13, "SIGPIPE", "broken pipe"},
18: "suspended", {14, "SIGALRM", "alarm clock"},
19: "continued", {15, "SIGTERM", "terminated"},
20: "child exited", {16, "SIGURG", "urgent I/O condition"},
21: "stopped (tty input)", {17, "SIGSTOP", "suspended (signal)"},
22: "stopped (tty output)", {18, "SIGTSTP", "suspended"},
23: "I/O possible", {19, "SIGCONT", "continued"},
24: "cputime limit exceeded", {20, "SIGCHLD", "child exited"},
25: "filesize limit exceeded", {21, "SIGTTIN", "stopped (tty input)"},
26: "virtual timer expired", {22, "SIGTTOU", "stopped (tty output)"},
27: "profiling timer expired", {23, "SIGIO", "I/O possible"},
28: "window size changes", {24, "SIGXCPU", "cputime limit exceeded"},
29: "information request", {25, "SIGXFSZ", "filesize limit exceeded"},
30: "user defined signal 1", {26, "SIGVTALRM", "virtual timer expired"},
31: "user defined signal 2", {27, "SIGPROF", "profiling timer expired"},
32: "thread Scheduler", {28, "SIGWINCH", "window size changes"},
33: "checkPoint", {29, "SIGINFO", "information request"},
34: "checkPointExit", {30, "SIGUSR1", "user defined signal 1"},
{31, "SIGUSR2", "user defined signal 2"},
{32, "SIGTHR", "thread Scheduler"},
{33, "SIGCKPT", "checkPoint"},
{34, "SIGCKPTEXIT", "checkPointExit"},
} }

View file

@ -1345,6 +1345,35 @@ const (
SO_USELOOPBACK = 0x40 SO_USELOOPBACK = 0x40
SO_USER_COOKIE = 0x1015 SO_USER_COOKIE = 0x1015
SO_VENDOR = 0x80000000 SO_VENDOR = 0x80000000
S_BLKSIZE = 0x200
S_IEXEC = 0x40
S_IFBLK = 0x6000
S_IFCHR = 0x2000
S_IFDIR = 0x4000
S_IFIFO = 0x1000
S_IFLNK = 0xa000
S_IFMT = 0xf000
S_IFREG = 0x8000
S_IFSOCK = 0xc000
S_IFWHT = 0xe000
S_IREAD = 0x100
S_IRGRP = 0x20
S_IROTH = 0x4
S_IRUSR = 0x100
S_IRWXG = 0x38
S_IRWXO = 0x7
S_IRWXU = 0x1c0
S_ISGID = 0x400
S_ISTXT = 0x200
S_ISUID = 0x800
S_ISVTX = 0x200
S_IWGRP = 0x10
S_IWOTH = 0x2
S_IWRITE = 0x80
S_IWUSR = 0x80
S_IXGRP = 0x8
S_IXOTH = 0x1
S_IXUSR = 0x40
TAB0 = 0x0 TAB0 = 0x0
TAB3 = 0x4 TAB3 = 0x4
TABDLY = 0x4 TABDLY = 0x4
@ -1619,138 +1648,146 @@ const (
) )
// Error table // Error table
var errors = [...]string{ var errorList = [...]struct {
1: "operation not permitted", num syscall.Errno
2: "no such file or directory", name string
3: "no such process", desc string
4: "interrupted system call", }{
5: "input/output error", {1, "EPERM", "operation not permitted"},
6: "device not configured", {2, "ENOENT", "no such file or directory"},
7: "argument list too long", {3, "ESRCH", "no such process"},
8: "exec format error", {4, "EINTR", "interrupted system call"},
9: "bad file descriptor", {5, "EIO", "input/output error"},
10: "no child processes", {6, "ENXIO", "device not configured"},
11: "resource deadlock avoided", {7, "E2BIG", "argument list too long"},
12: "cannot allocate memory", {8, "ENOEXEC", "exec format error"},
13: "permission denied", {9, "EBADF", "bad file descriptor"},
14: "bad address", {10, "ECHILD", "no child processes"},
15: "block device required", {11, "EDEADLK", "resource deadlock avoided"},
16: "device busy", {12, "ENOMEM", "cannot allocate memory"},
17: "file exists", {13, "EACCES", "permission denied"},
18: "cross-device link", {14, "EFAULT", "bad address"},
19: "operation not supported by device", {15, "ENOTBLK", "block device required"},
20: "not a directory", {16, "EBUSY", "device busy"},
21: "is a directory", {17, "EEXIST", "file exists"},
22: "invalid argument", {18, "EXDEV", "cross-device link"},
23: "too many open files in system", {19, "ENODEV", "operation not supported by device"},
24: "too many open files", {20, "ENOTDIR", "not a directory"},
25: "inappropriate ioctl for device", {21, "EISDIR", "is a directory"},
26: "text file busy", {22, "EINVAL", "invalid argument"},
27: "file too large", {23, "ENFILE", "too many open files in system"},
28: "no space left on device", {24, "EMFILE", "too many open files"},
29: "illegal seek", {25, "ENOTTY", "inappropriate ioctl for device"},
30: "read-only file system", {26, "ETXTBSY", "text file busy"},
31: "too many links", {27, "EFBIG", "file too large"},
32: "broken pipe", {28, "ENOSPC", "no space left on device"},
33: "numerical argument out of domain", {29, "ESPIPE", "illegal seek"},
34: "result too large", {30, "EROFS", "read-only file system"},
35: "resource temporarily unavailable", {31, "EMLINK", "too many links"},
36: "operation now in progress", {32, "EPIPE", "broken pipe"},
37: "operation already in progress", {33, "EDOM", "numerical argument out of domain"},
38: "socket operation on non-socket", {34, "ERANGE", "result too large"},
39: "destination address required", {35, "EAGAIN", "resource temporarily unavailable"},
40: "message too long", {36, "EINPROGRESS", "operation now in progress"},
41: "protocol wrong type for socket", {37, "EALREADY", "operation already in progress"},
42: "protocol not available", {38, "ENOTSOCK", "socket operation on non-socket"},
43: "protocol not supported", {39, "EDESTADDRREQ", "destination address required"},
44: "socket type not supported", {40, "EMSGSIZE", "message too long"},
45: "operation not supported", {41, "EPROTOTYPE", "protocol wrong type for socket"},
46: "protocol family not supported", {42, "ENOPROTOOPT", "protocol not available"},
47: "address family not supported by protocol family", {43, "EPROTONOSUPPORT", "protocol not supported"},
48: "address already in use", {44, "ESOCKTNOSUPPORT", "socket type not supported"},
49: "can't assign requested address", {45, "EOPNOTSUPP", "operation not supported"},
50: "network is down", {46, "EPFNOSUPPORT", "protocol family not supported"},
51: "network is unreachable", {47, "EAFNOSUPPORT", "address family not supported by protocol family"},
52: "network dropped connection on reset", {48, "EADDRINUSE", "address already in use"},
53: "software caused connection abort", {49, "EADDRNOTAVAIL", "can't assign requested address"},
54: "connection reset by peer", {50, "ENETDOWN", "network is down"},
55: "no buffer space available", {51, "ENETUNREACH", "network is unreachable"},
56: "socket is already connected", {52, "ENETRESET", "network dropped connection on reset"},
57: "socket is not connected", {53, "ECONNABORTED", "software caused connection abort"},
58: "can't send after socket shutdown", {54, "ECONNRESET", "connection reset by peer"},
59: "too many references: can't splice", {55, "ENOBUFS", "no buffer space available"},
60: "operation timed out", {56, "EISCONN", "socket is already connected"},
61: "connection refused", {57, "ENOTCONN", "socket is not connected"},
62: "too many levels of symbolic links", {58, "ESHUTDOWN", "can't send after socket shutdown"},
63: "file name too long", {59, "ETOOMANYREFS", "too many references: can't splice"},
64: "host is down", {60, "ETIMEDOUT", "operation timed out"},
65: "no route to host", {61, "ECONNREFUSED", "connection refused"},
66: "directory not empty", {62, "ELOOP", "too many levels of symbolic links"},
67: "too many processes", {63, "ENAMETOOLONG", "file name too long"},
68: "too many users", {64, "EHOSTDOWN", "host is down"},
69: "disc quota exceeded", {65, "EHOSTUNREACH", "no route to host"},
70: "stale NFS file handle", {66, "ENOTEMPTY", "directory not empty"},
71: "too many levels of remote in path", {67, "EPROCLIM", "too many processes"},
72: "RPC struct is bad", {68, "EUSERS", "too many users"},
73: "RPC version wrong", {69, "EDQUOT", "disc quota exceeded"},
74: "RPC prog. not avail", {70, "ESTALE", "stale NFS file handle"},
75: "program version wrong", {71, "EREMOTE", "too many levels of remote in path"},
76: "bad procedure for program", {72, "EBADRPC", "RPC struct is bad"},
77: "no locks available", {73, "ERPCMISMATCH", "RPC version wrong"},
78: "function not implemented", {74, "EPROGUNAVAIL", "RPC prog. not avail"},
79: "inappropriate file type or format", {75, "EPROGMISMATCH", "program version wrong"},
80: "authentication error", {76, "EPROCUNAVAIL", "bad procedure for program"},
81: "need authenticator", {77, "ENOLCK", "no locks available"},
82: "identifier removed", {78, "ENOSYS", "function not implemented"},
83: "no message of desired type", {79, "EFTYPE", "inappropriate file type or format"},
84: "value too large to be stored in data type", {80, "EAUTH", "authentication error"},
85: "operation canceled", {81, "ENEEDAUTH", "need authenticator"},
86: "illegal byte sequence", {82, "EIDRM", "identifier removed"},
87: "attribute not found", {83, "ENOMSG", "no message of desired type"},
88: "programming error", {84, "EOVERFLOW", "value too large to be stored in data type"},
89: "bad message", {85, "ECANCELED", "operation canceled"},
90: "multihop attempted", {86, "EILSEQ", "illegal byte sequence"},
91: "link has been severed", {87, "ENOATTR", "attribute not found"},
92: "protocol error", {88, "EDOOFUS", "programming error"},
93: "capabilities insufficient", {89, "EBADMSG", "bad message"},
94: "not permitted in capability mode", {90, "EMULTIHOP", "multihop attempted"},
95: "state not recoverable", {91, "ENOLINK", "link has been severed"},
96: "previous owner died", {92, "EPROTO", "protocol error"},
{93, "ENOTCAPABLE", "capabilities insufficient"},
{94, "ECAPMODE", "not permitted in capability mode"},
{95, "ENOTRECOVERABLE", "state not recoverable"},
{96, "EOWNERDEAD", "previous owner died"},
} }
// Signal table // Signal table
var signals = [...]string{ var signalList = [...]struct {
1: "hangup", num syscall.Signal
2: "interrupt", name string
3: "quit", desc string
4: "illegal instruction", }{
5: "trace/BPT trap", {1, "SIGHUP", "hangup"},
6: "abort trap", {2, "SIGINT", "interrupt"},
7: "EMT trap", {3, "SIGQUIT", "quit"},
8: "floating point exception", {4, "SIGILL", "illegal instruction"},
9: "killed", {5, "SIGTRAP", "trace/BPT trap"},
10: "bus error", {6, "SIGIOT", "abort trap"},
11: "segmentation fault", {7, "SIGEMT", "EMT trap"},
12: "bad system call", {8, "SIGFPE", "floating point exception"},
13: "broken pipe", {9, "SIGKILL", "killed"},
14: "alarm clock", {10, "SIGBUS", "bus error"},
15: "terminated", {11, "SIGSEGV", "segmentation fault"},
16: "urgent I/O condition", {12, "SIGSYS", "bad system call"},
17: "suspended (signal)", {13, "SIGPIPE", "broken pipe"},
18: "suspended", {14, "SIGALRM", "alarm clock"},
19: "continued", {15, "SIGTERM", "terminated"},
20: "child exited", {16, "SIGURG", "urgent I/O condition"},
21: "stopped (tty input)", {17, "SIGSTOP", "suspended (signal)"},
22: "stopped (tty output)", {18, "SIGTSTP", "suspended"},
23: "I/O possible", {19, "SIGCONT", "continued"},
24: "cputime limit exceeded", {20, "SIGCHLD", "child exited"},
25: "filesize limit exceeded", {21, "SIGTTIN", "stopped (tty input)"},
26: "virtual timer expired", {22, "SIGTTOU", "stopped (tty output)"},
27: "profiling timer expired", {23, "SIGIO", "I/O possible"},
28: "window size changes", {24, "SIGXCPU", "cputime limit exceeded"},
29: "information request", {25, "SIGXFSZ", "filesize limit exceeded"},
30: "user defined signal 1", {26, "SIGVTALRM", "virtual timer expired"},
31: "user defined signal 2", {27, "SIGPROF", "profiling timer expired"},
32: "unknown signal", {28, "SIGWINCH", "window size changes"},
33: "unknown signal", {29, "SIGINFO", "information request"},
{30, "SIGUSR1", "user defined signal 1"},
{31, "SIGUSR2", "user defined signal 2"},
{32, "SIGTHR", "unknown signal"},
{33, "SIGLIBRT", "unknown signal"},
} }

View file

@ -1346,6 +1346,35 @@ const (
SO_USELOOPBACK = 0x40 SO_USELOOPBACK = 0x40
SO_USER_COOKIE = 0x1015 SO_USER_COOKIE = 0x1015
SO_VENDOR = 0x80000000 SO_VENDOR = 0x80000000
S_BLKSIZE = 0x200
S_IEXEC = 0x40
S_IFBLK = 0x6000
S_IFCHR = 0x2000
S_IFDIR = 0x4000
S_IFIFO = 0x1000
S_IFLNK = 0xa000
S_IFMT = 0xf000
S_IFREG = 0x8000
S_IFSOCK = 0xc000
S_IFWHT = 0xe000
S_IREAD = 0x100
S_IRGRP = 0x20
S_IROTH = 0x4
S_IRUSR = 0x100
S_IRWXG = 0x38
S_IRWXO = 0x7
S_IRWXU = 0x1c0
S_ISGID = 0x400
S_ISTXT = 0x200
S_ISUID = 0x800
S_ISVTX = 0x200
S_IWGRP = 0x10
S_IWOTH = 0x2
S_IWRITE = 0x80
S_IWUSR = 0x80
S_IXGRP = 0x8
S_IXOTH = 0x1
S_IXUSR = 0x40
TAB0 = 0x0 TAB0 = 0x0
TAB3 = 0x4 TAB3 = 0x4
TABDLY = 0x4 TABDLY = 0x4
@ -1620,138 +1649,146 @@ const (
) )
// Error table // Error table
var errors = [...]string{ var errorList = [...]struct {
1: "operation not permitted", num syscall.Errno
2: "no such file or directory", name string
3: "no such process", desc string
4: "interrupted system call", }{
5: "input/output error", {1, "EPERM", "operation not permitted"},
6: "device not configured", {2, "ENOENT", "no such file or directory"},
7: "argument list too long", {3, "ESRCH", "no such process"},
8: "exec format error", {4, "EINTR", "interrupted system call"},
9: "bad file descriptor", {5, "EIO", "input/output error"},
10: "no child processes", {6, "ENXIO", "device not configured"},
11: "resource deadlock avoided", {7, "E2BIG", "argument list too long"},
12: "cannot allocate memory", {8, "ENOEXEC", "exec format error"},
13: "permission denied", {9, "EBADF", "bad file descriptor"},
14: "bad address", {10, "ECHILD", "no child processes"},
15: "block device required", {11, "EDEADLK", "resource deadlock avoided"},
16: "device busy", {12, "ENOMEM", "cannot allocate memory"},
17: "file exists", {13, "EACCES", "permission denied"},
18: "cross-device link", {14, "EFAULT", "bad address"},
19: "operation not supported by device", {15, "ENOTBLK", "block device required"},
20: "not a directory", {16, "EBUSY", "device busy"},
21: "is a directory", {17, "EEXIST", "file exists"},
22: "invalid argument", {18, "EXDEV", "cross-device link"},
23: "too many open files in system", {19, "ENODEV", "operation not supported by device"},
24: "too many open files", {20, "ENOTDIR", "not a directory"},
25: "inappropriate ioctl for device", {21, "EISDIR", "is a directory"},
26: "text file busy", {22, "EINVAL", "invalid argument"},
27: "file too large", {23, "ENFILE", "too many open files in system"},
28: "no space left on device", {24, "EMFILE", "too many open files"},
29: "illegal seek", {25, "ENOTTY", "inappropriate ioctl for device"},
30: "read-only file system", {26, "ETXTBSY", "text file busy"},
31: "too many links", {27, "EFBIG", "file too large"},
32: "broken pipe", {28, "ENOSPC", "no space left on device"},
33: "numerical argument out of domain", {29, "ESPIPE", "illegal seek"},
34: "result too large", {30, "EROFS", "read-only file system"},
35: "resource temporarily unavailable", {31, "EMLINK", "too many links"},
36: "operation now in progress", {32, "EPIPE", "broken pipe"},
37: "operation already in progress", {33, "EDOM", "numerical argument out of domain"},
38: "socket operation on non-socket", {34, "ERANGE", "result too large"},
39: "destination address required", {35, "EAGAIN", "resource temporarily unavailable"},
40: "message too long", {36, "EINPROGRESS", "operation now in progress"},
41: "protocol wrong type for socket", {37, "EALREADY", "operation already in progress"},
42: "protocol not available", {38, "ENOTSOCK", "socket operation on non-socket"},
43: "protocol not supported", {39, "EDESTADDRREQ", "destination address required"},
44: "socket type not supported", {40, "EMSGSIZE", "message too long"},
45: "operation not supported", {41, "EPROTOTYPE", "protocol wrong type for socket"},
46: "protocol family not supported", {42, "ENOPROTOOPT", "protocol not available"},
47: "address family not supported by protocol family", {43, "EPROTONOSUPPORT", "protocol not supported"},
48: "address already in use", {44, "ESOCKTNOSUPPORT", "socket type not supported"},
49: "can't assign requested address", {45, "EOPNOTSUPP", "operation not supported"},
50: "network is down", {46, "EPFNOSUPPORT", "protocol family not supported"},
51: "network is unreachable", {47, "EAFNOSUPPORT", "address family not supported by protocol family"},
52: "network dropped connection on reset", {48, "EADDRINUSE", "address already in use"},
53: "software caused connection abort", {49, "EADDRNOTAVAIL", "can't assign requested address"},
54: "connection reset by peer", {50, "ENETDOWN", "network is down"},
55: "no buffer space available", {51, "ENETUNREACH", "network is unreachable"},
56: "socket is already connected", {52, "ENETRESET", "network dropped connection on reset"},
57: "socket is not connected", {53, "ECONNABORTED", "software caused connection abort"},
58: "can't send after socket shutdown", {54, "ECONNRESET", "connection reset by peer"},
59: "too many references: can't splice", {55, "ENOBUFS", "no buffer space available"},
60: "operation timed out", {56, "EISCONN", "socket is already connected"},
61: "connection refused", {57, "ENOTCONN", "socket is not connected"},
62: "too many levels of symbolic links", {58, "ESHUTDOWN", "can't send after socket shutdown"},
63: "file name too long", {59, "ETOOMANYREFS", "too many references: can't splice"},
64: "host is down", {60, "ETIMEDOUT", "operation timed out"},
65: "no route to host", {61, "ECONNREFUSED", "connection refused"},
66: "directory not empty", {62, "ELOOP", "too many levels of symbolic links"},
67: "too many processes", {63, "ENAMETOOLONG", "file name too long"},
68: "too many users", {64, "EHOSTDOWN", "host is down"},
69: "disc quota exceeded", {65, "EHOSTUNREACH", "no route to host"},
70: "stale NFS file handle", {66, "ENOTEMPTY", "directory not empty"},
71: "too many levels of remote in path", {67, "EPROCLIM", "too many processes"},
72: "RPC struct is bad", {68, "EUSERS", "too many users"},
73: "RPC version wrong", {69, "EDQUOT", "disc quota exceeded"},
74: "RPC prog. not avail", {70, "ESTALE", "stale NFS file handle"},
75: "program version wrong", {71, "EREMOTE", "too many levels of remote in path"},
76: "bad procedure for program", {72, "EBADRPC", "RPC struct is bad"},
77: "no locks available", {73, "ERPCMISMATCH", "RPC version wrong"},
78: "function not implemented", {74, "EPROGUNAVAIL", "RPC prog. not avail"},
79: "inappropriate file type or format", {75, "EPROGMISMATCH", "program version wrong"},
80: "authentication error", {76, "EPROCUNAVAIL", "bad procedure for program"},
81: "need authenticator", {77, "ENOLCK", "no locks available"},
82: "identifier removed", {78, "ENOSYS", "function not implemented"},
83: "no message of desired type", {79, "EFTYPE", "inappropriate file type or format"},
84: "value too large to be stored in data type", {80, "EAUTH", "authentication error"},
85: "operation canceled", {81, "ENEEDAUTH", "need authenticator"},
86: "illegal byte sequence", {82, "EIDRM", "identifier removed"},
87: "attribute not found", {83, "ENOMSG", "no message of desired type"},
88: "programming error", {84, "EOVERFLOW", "value too large to be stored in data type"},
89: "bad message", {85, "ECANCELED", "operation canceled"},
90: "multihop attempted", {86, "EILSEQ", "illegal byte sequence"},
91: "link has been severed", {87, "ENOATTR", "attribute not found"},
92: "protocol error", {88, "EDOOFUS", "programming error"},
93: "capabilities insufficient", {89, "EBADMSG", "bad message"},
94: "not permitted in capability mode", {90, "EMULTIHOP", "multihop attempted"},
95: "state not recoverable", {91, "ENOLINK", "link has been severed"},
96: "previous owner died", {92, "EPROTO", "protocol error"},
{93, "ENOTCAPABLE", "capabilities insufficient"},
{94, "ECAPMODE", "not permitted in capability mode"},
{95, "ENOTRECOVERABLE", "state not recoverable"},
{96, "EOWNERDEAD", "previous owner died"},
} }
// Signal table // Signal table
var signals = [...]string{ var signalList = [...]struct {
1: "hangup", num syscall.Signal
2: "interrupt", name string
3: "quit", desc string
4: "illegal instruction", }{
5: "trace/BPT trap", {1, "SIGHUP", "hangup"},
6: "abort trap", {2, "SIGINT", "interrupt"},
7: "EMT trap", {3, "SIGQUIT", "quit"},
8: "floating point exception", {4, "SIGILL", "illegal instruction"},
9: "killed", {5, "SIGTRAP", "trace/BPT trap"},
10: "bus error", {6, "SIGIOT", "abort trap"},
11: "segmentation fault", {7, "SIGEMT", "EMT trap"},
12: "bad system call", {8, "SIGFPE", "floating point exception"},
13: "broken pipe", {9, "SIGKILL", "killed"},
14: "alarm clock", {10, "SIGBUS", "bus error"},
15: "terminated", {11, "SIGSEGV", "segmentation fault"},
16: "urgent I/O condition", {12, "SIGSYS", "bad system call"},
17: "suspended (signal)", {13, "SIGPIPE", "broken pipe"},
18: "suspended", {14, "SIGALRM", "alarm clock"},
19: "continued", {15, "SIGTERM", "terminated"},
20: "child exited", {16, "SIGURG", "urgent I/O condition"},
21: "stopped (tty input)", {17, "SIGSTOP", "suspended (signal)"},
22: "stopped (tty output)", {18, "SIGTSTP", "suspended"},
23: "I/O possible", {19, "SIGCONT", "continued"},
24: "cputime limit exceeded", {20, "SIGCHLD", "child exited"},
25: "filesize limit exceeded", {21, "SIGTTIN", "stopped (tty input)"},
26: "virtual timer expired", {22, "SIGTTOU", "stopped (tty output)"},
27: "profiling timer expired", {23, "SIGIO", "I/O possible"},
28: "window size changes", {24, "SIGXCPU", "cputime limit exceeded"},
29: "information request", {25, "SIGXFSZ", "filesize limit exceeded"},
30: "user defined signal 1", {26, "SIGVTALRM", "virtual timer expired"},
31: "user defined signal 2", {27, "SIGPROF", "profiling timer expired"},
32: "unknown signal", {28, "SIGWINCH", "window size changes"},
33: "unknown signal", {29, "SIGINFO", "information request"},
{30, "SIGUSR1", "user defined signal 1"},
{31, "SIGUSR2", "user defined signal 2"},
{32, "SIGTHR", "unknown signal"},
{33, "SIGLIBRT", "unknown signal"},
} }

View file

@ -1354,6 +1354,35 @@ const (
SO_USELOOPBACK = 0x40 SO_USELOOPBACK = 0x40
SO_USER_COOKIE = 0x1015 SO_USER_COOKIE = 0x1015
SO_VENDOR = 0x80000000 SO_VENDOR = 0x80000000
S_BLKSIZE = 0x200
S_IEXEC = 0x40
S_IFBLK = 0x6000
S_IFCHR = 0x2000
S_IFDIR = 0x4000
S_IFIFO = 0x1000
S_IFLNK = 0xa000
S_IFMT = 0xf000
S_IFREG = 0x8000
S_IFSOCK = 0xc000
S_IFWHT = 0xe000
S_IREAD = 0x100
S_IRGRP = 0x20
S_IROTH = 0x4
S_IRUSR = 0x100
S_IRWXG = 0x38
S_IRWXO = 0x7
S_IRWXU = 0x1c0
S_ISGID = 0x400
S_ISTXT = 0x200
S_ISUID = 0x800
S_ISVTX = 0x200
S_IWGRP = 0x10
S_IWOTH = 0x2
S_IWRITE = 0x80
S_IWUSR = 0x80
S_IXGRP = 0x8
S_IXOTH = 0x1
S_IXUSR = 0x40
TAB0 = 0x0 TAB0 = 0x0
TAB3 = 0x4 TAB3 = 0x4
TABDLY = 0x4 TABDLY = 0x4
@ -1628,138 +1657,146 @@ const (
) )
// Error table // Error table
var errors = [...]string{ var errorList = [...]struct {
1: "operation not permitted", num syscall.Errno
2: "no such file or directory", name string
3: "no such process", desc string
4: "interrupted system call", }{
5: "input/output error", {1, "EPERM", "operation not permitted"},
6: "device not configured", {2, "ENOENT", "no such file or directory"},
7: "argument list too long", {3, "ESRCH", "no such process"},
8: "exec format error", {4, "EINTR", "interrupted system call"},
9: "bad file descriptor", {5, "EIO", "input/output error"},
10: "no child processes", {6, "ENXIO", "device not configured"},
11: "resource deadlock avoided", {7, "E2BIG", "argument list too long"},
12: "cannot allocate memory", {8, "ENOEXEC", "exec format error"},
13: "permission denied", {9, "EBADF", "bad file descriptor"},
14: "bad address", {10, "ECHILD", "no child processes"},
15: "block device required", {11, "EDEADLK", "resource deadlock avoided"},
16: "device busy", {12, "ENOMEM", "cannot allocate memory"},
17: "file exists", {13, "EACCES", "permission denied"},
18: "cross-device link", {14, "EFAULT", "bad address"},
19: "operation not supported by device", {15, "ENOTBLK", "block device required"},
20: "not a directory", {16, "EBUSY", "device busy"},
21: "is a directory", {17, "EEXIST", "file exists"},
22: "invalid argument", {18, "EXDEV", "cross-device link"},
23: "too many open files in system", {19, "ENODEV", "operation not supported by device"},
24: "too many open files", {20, "ENOTDIR", "not a directory"},
25: "inappropriate ioctl for device", {21, "EISDIR", "is a directory"},
26: "text file busy", {22, "EINVAL", "invalid argument"},
27: "file too large", {23, "ENFILE", "too many open files in system"},
28: "no space left on device", {24, "EMFILE", "too many open files"},
29: "illegal seek", {25, "ENOTTY", "inappropriate ioctl for device"},
30: "read-only file system", {26, "ETXTBSY", "text file busy"},
31: "too many links", {27, "EFBIG", "file too large"},
32: "broken pipe", {28, "ENOSPC", "no space left on device"},
33: "numerical argument out of domain", {29, "ESPIPE", "illegal seek"},
34: "result too large", {30, "EROFS", "read-only file system"},
35: "resource temporarily unavailable", {31, "EMLINK", "too many links"},
36: "operation now in progress", {32, "EPIPE", "broken pipe"},
37: "operation already in progress", {33, "EDOM", "numerical argument out of domain"},
38: "socket operation on non-socket", {34, "ERANGE", "result too large"},
39: "destination address required", {35, "EAGAIN", "resource temporarily unavailable"},
40: "message too long", {36, "EINPROGRESS", "operation now in progress"},
41: "protocol wrong type for socket", {37, "EALREADY", "operation already in progress"},
42: "protocol not available", {38, "ENOTSOCK", "socket operation on non-socket"},
43: "protocol not supported", {39, "EDESTADDRREQ", "destination address required"},
44: "socket type not supported", {40, "EMSGSIZE", "message too long"},
45: "operation not supported", {41, "EPROTOTYPE", "protocol wrong type for socket"},
46: "protocol family not supported", {42, "ENOPROTOOPT", "protocol not available"},
47: "address family not supported by protocol family", {43, "EPROTONOSUPPORT", "protocol not supported"},
48: "address already in use", {44, "ESOCKTNOSUPPORT", "socket type not supported"},
49: "can't assign requested address", {45, "EOPNOTSUPP", "operation not supported"},
50: "network is down", {46, "EPFNOSUPPORT", "protocol family not supported"},
51: "network is unreachable", {47, "EAFNOSUPPORT", "address family not supported by protocol family"},
52: "network dropped connection on reset", {48, "EADDRINUSE", "address already in use"},
53: "software caused connection abort", {49, "EADDRNOTAVAIL", "can't assign requested address"},
54: "connection reset by peer", {50, "ENETDOWN", "network is down"},
55: "no buffer space available", {51, "ENETUNREACH", "network is unreachable"},
56: "socket is already connected", {52, "ENETRESET", "network dropped connection on reset"},
57: "socket is not connected", {53, "ECONNABORTED", "software caused connection abort"},
58: "can't send after socket shutdown", {54, "ECONNRESET", "connection reset by peer"},
59: "too many references: can't splice", {55, "ENOBUFS", "no buffer space available"},
60: "operation timed out", {56, "EISCONN", "socket is already connected"},
61: "connection refused", {57, "ENOTCONN", "socket is not connected"},
62: "too many levels of symbolic links", {58, "ESHUTDOWN", "can't send after socket shutdown"},
63: "file name too long", {59, "ETOOMANYREFS", "too many references: can't splice"},
64: "host is down", {60, "ETIMEDOUT", "operation timed out"},
65: "no route to host", {61, "ECONNREFUSED", "connection refused"},
66: "directory not empty", {62, "ELOOP", "too many levels of symbolic links"},
67: "too many processes", {63, "ENAMETOOLONG", "file name too long"},
68: "too many users", {64, "EHOSTDOWN", "host is down"},
69: "disc quota exceeded", {65, "EHOSTUNREACH", "no route to host"},
70: "stale NFS file handle", {66, "ENOTEMPTY", "directory not empty"},
71: "too many levels of remote in path", {67, "EPROCLIM", "too many processes"},
72: "RPC struct is bad", {68, "EUSERS", "too many users"},
73: "RPC version wrong", {69, "EDQUOT", "disc quota exceeded"},
74: "RPC prog. not avail", {70, "ESTALE", "stale NFS file handle"},
75: "program version wrong", {71, "EREMOTE", "too many levels of remote in path"},
76: "bad procedure for program", {72, "EBADRPC", "RPC struct is bad"},
77: "no locks available", {73, "ERPCMISMATCH", "RPC version wrong"},
78: "function not implemented", {74, "EPROGUNAVAIL", "RPC prog. not avail"},
79: "inappropriate file type or format", {75, "EPROGMISMATCH", "program version wrong"},
80: "authentication error", {76, "EPROCUNAVAIL", "bad procedure for program"},
81: "need authenticator", {77, "ENOLCK", "no locks available"},
82: "identifier removed", {78, "ENOSYS", "function not implemented"},
83: "no message of desired type", {79, "EFTYPE", "inappropriate file type or format"},
84: "value too large to be stored in data type", {80, "EAUTH", "authentication error"},
85: "operation canceled", {81, "ENEEDAUTH", "need authenticator"},
86: "illegal byte sequence", {82, "EIDRM", "identifier removed"},
87: "attribute not found", {83, "ENOMSG", "no message of desired type"},
88: "programming error", {84, "EOVERFLOW", "value too large to be stored in data type"},
89: "bad message", {85, "ECANCELED", "operation canceled"},
90: "multihop attempted", {86, "EILSEQ", "illegal byte sequence"},
91: "link has been severed", {87, "ENOATTR", "attribute not found"},
92: "protocol error", {88, "EDOOFUS", "programming error"},
93: "capabilities insufficient", {89, "EBADMSG", "bad message"},
94: "not permitted in capability mode", {90, "EMULTIHOP", "multihop attempted"},
95: "state not recoverable", {91, "ENOLINK", "link has been severed"},
96: "previous owner died", {92, "EPROTO", "protocol error"},
{93, "ENOTCAPABLE", "capabilities insufficient"},
{94, "ECAPMODE", "not permitted in capability mode"},
{95, "ENOTRECOVERABLE", "state not recoverable"},
{96, "EOWNERDEAD", "previous owner died"},
} }
// Signal table // Signal table
var signals = [...]string{ var signalList = [...]struct {
1: "hangup", num syscall.Signal
2: "interrupt", name string
3: "quit", desc string
4: "illegal instruction", }{
5: "trace/BPT trap", {1, "SIGHUP", "hangup"},
6: "abort trap", {2, "SIGINT", "interrupt"},
7: "EMT trap", {3, "SIGQUIT", "quit"},
8: "floating point exception", {4, "SIGILL", "illegal instruction"},
9: "killed", {5, "SIGTRAP", "trace/BPT trap"},
10: "bus error", {6, "SIGIOT", "abort trap"},
11: "segmentation fault", {7, "SIGEMT", "EMT trap"},
12: "bad system call", {8, "SIGFPE", "floating point exception"},
13: "broken pipe", {9, "SIGKILL", "killed"},
14: "alarm clock", {10, "SIGBUS", "bus error"},
15: "terminated", {11, "SIGSEGV", "segmentation fault"},
16: "urgent I/O condition", {12, "SIGSYS", "bad system call"},
17: "suspended (signal)", {13, "SIGPIPE", "broken pipe"},
18: "suspended", {14, "SIGALRM", "alarm clock"},
19: "continued", {15, "SIGTERM", "terminated"},
20: "child exited", {16, "SIGURG", "urgent I/O condition"},
21: "stopped (tty input)", {17, "SIGSTOP", "suspended (signal)"},
22: "stopped (tty output)", {18, "SIGTSTP", "suspended"},
23: "I/O possible", {19, "SIGCONT", "continued"},
24: "cputime limit exceeded", {20, "SIGCHLD", "child exited"},
25: "filesize limit exceeded", {21, "SIGTTIN", "stopped (tty input)"},
26: "virtual timer expired", {22, "SIGTTOU", "stopped (tty output)"},
27: "profiling timer expired", {23, "SIGIO", "I/O possible"},
28: "window size changes", {24, "SIGXCPU", "cputime limit exceeded"},
29: "information request", {25, "SIGXFSZ", "filesize limit exceeded"},
30: "user defined signal 1", {26, "SIGVTALRM", "virtual timer expired"},
31: "user defined signal 2", {27, "SIGPROF", "profiling timer expired"},
32: "unknown signal", {28, "SIGWINCH", "window size changes"},
33: "unknown signal", {29, "SIGINFO", "information request"},
{30, "SIGUSR1", "user defined signal 1"},
{31, "SIGUSR2", "user defined signal 2"},
{32, "SIGTHR", "unknown signal"},
{33, "SIGLIBRT", "unknown signal"},
} }

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,5 @@
// mkerrors.sh -m64 // mkerrors.sh -m64
// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT // Code generated by the command above; DO NOT EDIT.
// +build sparc64,linux // +build sparc64,linux

View file

@ -159,6 +159,7 @@ const (
CLONE_VFORK = 0x4000 CLONE_VFORK = 0x4000
CLONE_VM = 0x100 CLONE_VM = 0x100
CREAD = 0x800 CREAD = 0x800
CRTSCTS = 0x10000
CS5 = 0x0 CS5 = 0x0
CS6 = 0x100 CS6 = 0x100
CS7 = 0x200 CS7 = 0x200
@ -549,6 +550,10 @@ const (
EV_ONESHOT = 0x10 EV_ONESHOT = 0x10
EV_SYSFLAGS = 0xf000 EV_SYSFLAGS = 0xf000
EXTA = 0x4b00 EXTA = 0x4b00
EXTATTR_CMD_START = 0x1
EXTATTR_CMD_STOP = 0x2
EXTATTR_NAMESPACE_SYSTEM = 0x2
EXTATTR_NAMESPACE_USER = 0x1
EXTB = 0x9600 EXTB = 0x9600
EXTPROC = 0x800 EXTPROC = 0x800
FD_CLOEXEC = 0x1 FD_CLOEXEC = 0x1
@ -1583,137 +1588,145 @@ const (
) )
// Error table // Error table
var errors = [...]string{ var errorList = [...]struct {
1: "operation not permitted", num syscall.Errno
2: "no such file or directory", name string
3: "no such process", desc string
4: "interrupted system call", }{
5: "input/output error", {1, "EPERM", "operation not permitted"},
6: "device not configured", {2, "ENOENT", "no such file or directory"},
7: "argument list too long", {3, "ESRCH", "no such process"},
8: "exec format error", {4, "EINTR", "interrupted system call"},
9: "bad file descriptor", {5, "EIO", "input/output error"},
10: "no child processes", {6, "ENXIO", "device not configured"},
11: "resource deadlock avoided", {7, "E2BIG", "argument list too long"},
12: "cannot allocate memory", {8, "ENOEXEC", "exec format error"},
13: "permission denied", {9, "EBADF", "bad file descriptor"},
14: "bad address", {10, "ECHILD", "no child processes"},
15: "block device required", {11, "EDEADLK", "resource deadlock avoided"},
16: "device busy", {12, "ENOMEM", "cannot allocate memory"},
17: "file exists", {13, "EACCES", "permission denied"},
18: "cross-device link", {14, "EFAULT", "bad address"},
19: "operation not supported by device", {15, "ENOTBLK", "block device required"},
20: "not a directory", {16, "EBUSY", "device busy"},
21: "is a directory", {17, "EEXIST", "file exists"},
22: "invalid argument", {18, "EXDEV", "cross-device link"},
23: "too many open files in system", {19, "ENODEV", "operation not supported by device"},
24: "too many open files", {20, "ENOTDIR", "not a directory"},
25: "inappropriate ioctl for device", {21, "EISDIR", "is a directory"},
26: "text file busy", {22, "EINVAL", "invalid argument"},
27: "file too large", {23, "ENFILE", "too many open files in system"},
28: "no space left on device", {24, "EMFILE", "too many open files"},
29: "illegal seek", {25, "ENOTTY", "inappropriate ioctl for device"},
30: "read-only file system", {26, "ETXTBSY", "text file busy"},
31: "too many links", {27, "EFBIG", "file too large"},
32: "broken pipe", {28, "ENOSPC", "no space left on device"},
33: "numerical argument out of domain", {29, "ESPIPE", "illegal seek"},
34: "result too large or too small", {30, "EROFS", "read-only file system"},
35: "resource temporarily unavailable", {31, "EMLINK", "too many links"},
36: "operation now in progress", {32, "EPIPE", "broken pipe"},
37: "operation already in progress", {33, "EDOM", "numerical argument out of domain"},
38: "socket operation on non-socket", {34, "ERANGE", "result too large or too small"},
39: "destination address required", {35, "EAGAIN", "resource temporarily unavailable"},
40: "message too long", {36, "EINPROGRESS", "operation now in progress"},
41: "protocol wrong type for socket", {37, "EALREADY", "operation already in progress"},
42: "protocol option not available", {38, "ENOTSOCK", "socket operation on non-socket"},
43: "protocol not supported", {39, "EDESTADDRREQ", "destination address required"},
44: "socket type not supported", {40, "EMSGSIZE", "message too long"},
45: "operation not supported", {41, "EPROTOTYPE", "protocol wrong type for socket"},
46: "protocol family not supported", {42, "ENOPROTOOPT", "protocol option not available"},
47: "address family not supported by protocol family", {43, "EPROTONOSUPPORT", "protocol not supported"},
48: "address already in use", {44, "ESOCKTNOSUPPORT", "socket type not supported"},
49: "can't assign requested address", {45, "EOPNOTSUPP", "operation not supported"},
50: "network is down", {46, "EPFNOSUPPORT", "protocol family not supported"},
51: "network is unreachable", {47, "EAFNOSUPPORT", "address family not supported by protocol family"},
52: "network dropped connection on reset", {48, "EADDRINUSE", "address already in use"},
53: "software caused connection abort", {49, "EADDRNOTAVAIL", "can't assign requested address"},
54: "connection reset by peer", {50, "ENETDOWN", "network is down"},
55: "no buffer space available", {51, "ENETUNREACH", "network is unreachable"},
56: "socket is already connected", {52, "ENETRESET", "network dropped connection on reset"},
57: "socket is not connected", {53, "ECONNABORTED", "software caused connection abort"},
58: "can't send after socket shutdown", {54, "ECONNRESET", "connection reset by peer"},
59: "too many references: can't splice", {55, "ENOBUFS", "no buffer space available"},
60: "connection timed out", {56, "EISCONN", "socket is already connected"},
61: "connection refused", {57, "ENOTCONN", "socket is not connected"},
62: "too many levels of symbolic links", {58, "ESHUTDOWN", "can't send after socket shutdown"},
63: "file name too long", {59, "ETOOMANYREFS", "too many references: can't splice"},
64: "host is down", {60, "ETIMEDOUT", "connection timed out"},
65: "no route to host", {61, "ECONNREFUSED", "connection refused"},
66: "directory not empty", {62, "ELOOP", "too many levels of symbolic links"},
67: "too many processes", {63, "ENAMETOOLONG", "file name too long"},
68: "too many users", {64, "EHOSTDOWN", "host is down"},
69: "disc quota exceeded", {65, "EHOSTUNREACH", "no route to host"},
70: "stale NFS file handle", {66, "ENOTEMPTY", "directory not empty"},
71: "too many levels of remote in path", {67, "EPROCLIM", "too many processes"},
72: "RPC struct is bad", {68, "EUSERS", "too many users"},
73: "RPC version wrong", {69, "EDQUOT", "disc quota exceeded"},
74: "RPC prog. not avail", {70, "ESTALE", "stale NFS file handle"},
75: "program version wrong", {71, "EREMOTE", "too many levels of remote in path"},
76: "bad procedure for program", {72, "EBADRPC", "RPC struct is bad"},
77: "no locks available", {73, "ERPCMISMATCH", "RPC version wrong"},
78: "function not implemented", {74, "EPROGUNAVAIL", "RPC prog. not avail"},
79: "inappropriate file type or format", {75, "EPROGMISMATCH", "program version wrong"},
80: "authentication error", {76, "EPROCUNAVAIL", "bad procedure for program"},
81: "need authenticator", {77, "ENOLCK", "no locks available"},
82: "identifier removed", {78, "ENOSYS", "function not implemented"},
83: "no message of desired type", {79, "EFTYPE", "inappropriate file type or format"},
84: "value too large to be stored in data type", {80, "EAUTH", "authentication error"},
85: "illegal byte sequence", {81, "ENEEDAUTH", "need authenticator"},
86: "not supported", {82, "EIDRM", "identifier removed"},
87: "operation Canceled", {83, "ENOMSG", "no message of desired type"},
88: "bad or Corrupt message", {84, "EOVERFLOW", "value too large to be stored in data type"},
89: "no message available", {85, "EILSEQ", "illegal byte sequence"},
90: "no STREAM resources", {86, "ENOTSUP", "not supported"},
91: "not a STREAM", {87, "ECANCELED", "operation Canceled"},
92: "STREAM ioctl timeout", {88, "EBADMSG", "bad or Corrupt message"},
93: "attribute not found", {89, "ENODATA", "no message available"},
94: "multihop attempted", {90, "ENOSR", "no STREAM resources"},
95: "link has been severed", {91, "ENOSTR", "not a STREAM"},
96: "protocol error", {92, "ETIME", "STREAM ioctl timeout"},
{93, "ENOATTR", "attribute not found"},
{94, "EMULTIHOP", "multihop attempted"},
{95, "ENOLINK", "link has been severed"},
{96, "ELAST", "protocol error"},
} }
// Signal table // Signal table
var signals = [...]string{ var signalList = [...]struct {
1: "hangup", num syscall.Signal
2: "interrupt", name string
3: "quit", desc string
4: "illegal instruction", }{
5: "trace/BPT trap", {1, "SIGHUP", "hangup"},
6: "abort trap", {2, "SIGINT", "interrupt"},
7: "EMT trap", {3, "SIGQUIT", "quit"},
8: "floating point exception", {4, "SIGILL", "illegal instruction"},
9: "killed", {5, "SIGTRAP", "trace/BPT trap"},
10: "bus error", {6, "SIGIOT", "abort trap"},
11: "segmentation fault", {7, "SIGEMT", "EMT trap"},
12: "bad system call", {8, "SIGFPE", "floating point exception"},
13: "broken pipe", {9, "SIGKILL", "killed"},
14: "alarm clock", {10, "SIGBUS", "bus error"},
15: "terminated", {11, "SIGSEGV", "segmentation fault"},
16: "urgent I/O condition", {12, "SIGSYS", "bad system call"},
17: "stopped (signal)", {13, "SIGPIPE", "broken pipe"},
18: "stopped", {14, "SIGALRM", "alarm clock"},
19: "continued", {15, "SIGTERM", "terminated"},
20: "child exited", {16, "SIGURG", "urgent I/O condition"},
21: "stopped (tty input)", {17, "SIGSTOP", "stopped (signal)"},
22: "stopped (tty output)", {18, "SIGTSTP", "stopped"},
23: "I/O possible", {19, "SIGCONT", "continued"},
24: "cputime limit exceeded", {20, "SIGCHLD", "child exited"},
25: "filesize limit exceeded", {21, "SIGTTIN", "stopped (tty input)"},
26: "virtual timer expired", {22, "SIGTTOU", "stopped (tty output)"},
27: "profiling timer expired", {23, "SIGIO", "I/O possible"},
28: "window size changes", {24, "SIGXCPU", "cputime limit exceeded"},
29: "information request", {25, "SIGXFSZ", "filesize limit exceeded"},
30: "user defined signal 1", {26, "SIGVTALRM", "virtual timer expired"},
31: "user defined signal 2", {27, "SIGPROF", "profiling timer expired"},
32: "power fail/restart", {28, "SIGWINCH", "window size changes"},
{29, "SIGINFO", "information request"},
{30, "SIGUSR1", "user defined signal 1"},
{31, "SIGUSR2", "user defined signal 2"},
{32, "SIGPWR", "power fail/restart"},
} }

View file

@ -159,6 +159,7 @@ const (
CLONE_VFORK = 0x4000 CLONE_VFORK = 0x4000
CLONE_VM = 0x100 CLONE_VM = 0x100
CREAD = 0x800 CREAD = 0x800
CRTSCTS = 0x10000
CS5 = 0x0 CS5 = 0x0
CS6 = 0x100 CS6 = 0x100
CS7 = 0x200 CS7 = 0x200
@ -539,6 +540,10 @@ const (
EV_ONESHOT = 0x10 EV_ONESHOT = 0x10
EV_SYSFLAGS = 0xf000 EV_SYSFLAGS = 0xf000
EXTA = 0x4b00 EXTA = 0x4b00
EXTATTR_CMD_START = 0x1
EXTATTR_CMD_STOP = 0x2
EXTATTR_NAMESPACE_SYSTEM = 0x2
EXTATTR_NAMESPACE_USER = 0x1
EXTB = 0x9600 EXTB = 0x9600
EXTPROC = 0x800 EXTPROC = 0x800
FD_CLOEXEC = 0x1 FD_CLOEXEC = 0x1
@ -1573,137 +1578,145 @@ const (
) )
// Error table // Error table
var errors = [...]string{ var errorList = [...]struct {
1: "operation not permitted", num syscall.Errno
2: "no such file or directory", name string
3: "no such process", desc string
4: "interrupted system call", }{
5: "input/output error", {1, "EPERM", "operation not permitted"},
6: "device not configured", {2, "ENOENT", "no such file or directory"},
7: "argument list too long", {3, "ESRCH", "no such process"},
8: "exec format error", {4, "EINTR", "interrupted system call"},
9: "bad file descriptor", {5, "EIO", "input/output error"},
10: "no child processes", {6, "ENXIO", "device not configured"},
11: "resource deadlock avoided", {7, "E2BIG", "argument list too long"},
12: "cannot allocate memory", {8, "ENOEXEC", "exec format error"},
13: "permission denied", {9, "EBADF", "bad file descriptor"},
14: "bad address", {10, "ECHILD", "no child processes"},
15: "block device required", {11, "EDEADLK", "resource deadlock avoided"},
16: "device busy", {12, "ENOMEM", "cannot allocate memory"},
17: "file exists", {13, "EACCES", "permission denied"},
18: "cross-device link", {14, "EFAULT", "bad address"},
19: "operation not supported by device", {15, "ENOTBLK", "block device required"},
20: "not a directory", {16, "EBUSY", "device busy"},
21: "is a directory", {17, "EEXIST", "file exists"},
22: "invalid argument", {18, "EXDEV", "cross-device link"},
23: "too many open files in system", {19, "ENODEV", "operation not supported by device"},
24: "too many open files", {20, "ENOTDIR", "not a directory"},
25: "inappropriate ioctl for device", {21, "EISDIR", "is a directory"},
26: "text file busy", {22, "EINVAL", "invalid argument"},
27: "file too large", {23, "ENFILE", "too many open files in system"},
28: "no space left on device", {24, "EMFILE", "too many open files"},
29: "illegal seek", {25, "ENOTTY", "inappropriate ioctl for device"},
30: "read-only file system", {26, "ETXTBSY", "text file busy"},
31: "too many links", {27, "EFBIG", "file too large"},
32: "broken pipe", {28, "ENOSPC", "no space left on device"},
33: "numerical argument out of domain", {29, "ESPIPE", "illegal seek"},
34: "result too large or too small", {30, "EROFS", "read-only file system"},
35: "resource temporarily unavailable", {31, "EMLINK", "too many links"},
36: "operation now in progress", {32, "EPIPE", "broken pipe"},
37: "operation already in progress", {33, "EDOM", "numerical argument out of domain"},
38: "socket operation on non-socket", {34, "ERANGE", "result too large or too small"},
39: "destination address required", {35, "EAGAIN", "resource temporarily unavailable"},
40: "message too long", {36, "EINPROGRESS", "operation now in progress"},
41: "protocol wrong type for socket", {37, "EALREADY", "operation already in progress"},
42: "protocol option not available", {38, "ENOTSOCK", "socket operation on non-socket"},
43: "protocol not supported", {39, "EDESTADDRREQ", "destination address required"},
44: "socket type not supported", {40, "EMSGSIZE", "message too long"},
45: "operation not supported", {41, "EPROTOTYPE", "protocol wrong type for socket"},
46: "protocol family not supported", {42, "ENOPROTOOPT", "protocol option not available"},
47: "address family not supported by protocol family", {43, "EPROTONOSUPPORT", "protocol not supported"},
48: "address already in use", {44, "ESOCKTNOSUPPORT", "socket type not supported"},
49: "can't assign requested address", {45, "EOPNOTSUPP", "operation not supported"},
50: "network is down", {46, "EPFNOSUPPORT", "protocol family not supported"},
51: "network is unreachable", {47, "EAFNOSUPPORT", "address family not supported by protocol family"},
52: "network dropped connection on reset", {48, "EADDRINUSE", "address already in use"},
53: "software caused connection abort", {49, "EADDRNOTAVAIL", "can't assign requested address"},
54: "connection reset by peer", {50, "ENETDOWN", "network is down"},
55: "no buffer space available", {51, "ENETUNREACH", "network is unreachable"},
56: "socket is already connected", {52, "ENETRESET", "network dropped connection on reset"},
57: "socket is not connected", {53, "ECONNABORTED", "software caused connection abort"},
58: "can't send after socket shutdown", {54, "ECONNRESET", "connection reset by peer"},
59: "too many references: can't splice", {55, "ENOBUFS", "no buffer space available"},
60: "connection timed out", {56, "EISCONN", "socket is already connected"},
61: "connection refused", {57, "ENOTCONN", "socket is not connected"},
62: "too many levels of symbolic links", {58, "ESHUTDOWN", "can't send after socket shutdown"},
63: "file name too long", {59, "ETOOMANYREFS", "too many references: can't splice"},
64: "host is down", {60, "ETIMEDOUT", "connection timed out"},
65: "no route to host", {61, "ECONNREFUSED", "connection refused"},
66: "directory not empty", {62, "ELOOP", "too many levels of symbolic links"},
67: "too many processes", {63, "ENAMETOOLONG", "file name too long"},
68: "too many users", {64, "EHOSTDOWN", "host is down"},
69: "disc quota exceeded", {65, "EHOSTUNREACH", "no route to host"},
70: "stale NFS file handle", {66, "ENOTEMPTY", "directory not empty"},
71: "too many levels of remote in path", {67, "EPROCLIM", "too many processes"},
72: "RPC struct is bad", {68, "EUSERS", "too many users"},
73: "RPC version wrong", {69, "EDQUOT", "disc quota exceeded"},
74: "RPC prog. not avail", {70, "ESTALE", "stale NFS file handle"},
75: "program version wrong", {71, "EREMOTE", "too many levels of remote in path"},
76: "bad procedure for program", {72, "EBADRPC", "RPC struct is bad"},
77: "no locks available", {73, "ERPCMISMATCH", "RPC version wrong"},
78: "function not implemented", {74, "EPROGUNAVAIL", "RPC prog. not avail"},
79: "inappropriate file type or format", {75, "EPROGMISMATCH", "program version wrong"},
80: "authentication error", {76, "EPROCUNAVAIL", "bad procedure for program"},
81: "need authenticator", {77, "ENOLCK", "no locks available"},
82: "identifier removed", {78, "ENOSYS", "function not implemented"},
83: "no message of desired type", {79, "EFTYPE", "inappropriate file type or format"},
84: "value too large to be stored in data type", {80, "EAUTH", "authentication error"},
85: "illegal byte sequence", {81, "ENEEDAUTH", "need authenticator"},
86: "not supported", {82, "EIDRM", "identifier removed"},
87: "operation Canceled", {83, "ENOMSG", "no message of desired type"},
88: "bad or Corrupt message", {84, "EOVERFLOW", "value too large to be stored in data type"},
89: "no message available", {85, "EILSEQ", "illegal byte sequence"},
90: "no STREAM resources", {86, "ENOTSUP", "not supported"},
91: "not a STREAM", {87, "ECANCELED", "operation Canceled"},
92: "STREAM ioctl timeout", {88, "EBADMSG", "bad or Corrupt message"},
93: "attribute not found", {89, "ENODATA", "no message available"},
94: "multihop attempted", {90, "ENOSR", "no STREAM resources"},
95: "link has been severed", {91, "ENOSTR", "not a STREAM"},
96: "protocol error", {92, "ETIME", "STREAM ioctl timeout"},
{93, "ENOATTR", "attribute not found"},
{94, "EMULTIHOP", "multihop attempted"},
{95, "ENOLINK", "link has been severed"},
{96, "ELAST", "protocol error"},
} }
// Signal table // Signal table
var signals = [...]string{ var signalList = [...]struct {
1: "hangup", num syscall.Signal
2: "interrupt", name string
3: "quit", desc string
4: "illegal instruction", }{
5: "trace/BPT trap", {1, "SIGHUP", "hangup"},
6: "abort trap", {2, "SIGINT", "interrupt"},
7: "EMT trap", {3, "SIGQUIT", "quit"},
8: "floating point exception", {4, "SIGILL", "illegal instruction"},
9: "killed", {5, "SIGTRAP", "trace/BPT trap"},
10: "bus error", {6, "SIGIOT", "abort trap"},
11: "segmentation fault", {7, "SIGEMT", "EMT trap"},
12: "bad system call", {8, "SIGFPE", "floating point exception"},
13: "broken pipe", {9, "SIGKILL", "killed"},
14: "alarm clock", {10, "SIGBUS", "bus error"},
15: "terminated", {11, "SIGSEGV", "segmentation fault"},
16: "urgent I/O condition", {12, "SIGSYS", "bad system call"},
17: "stopped (signal)", {13, "SIGPIPE", "broken pipe"},
18: "stopped", {14, "SIGALRM", "alarm clock"},
19: "continued", {15, "SIGTERM", "terminated"},
20: "child exited", {16, "SIGURG", "urgent I/O condition"},
21: "stopped (tty input)", {17, "SIGSTOP", "stopped (signal)"},
22: "stopped (tty output)", {18, "SIGTSTP", "stopped"},
23: "I/O possible", {19, "SIGCONT", "continued"},
24: "cputime limit exceeded", {20, "SIGCHLD", "child exited"},
25: "filesize limit exceeded", {21, "SIGTTIN", "stopped (tty input)"},
26: "virtual timer expired", {22, "SIGTTOU", "stopped (tty output)"},
27: "profiling timer expired", {23, "SIGIO", "I/O possible"},
28: "window size changes", {24, "SIGXCPU", "cputime limit exceeded"},
29: "information request", {25, "SIGXFSZ", "filesize limit exceeded"},
30: "user defined signal 1", {26, "SIGVTALRM", "virtual timer expired"},
31: "user defined signal 2", {27, "SIGPROF", "profiling timer expired"},
32: "power fail/restart", {28, "SIGWINCH", "window size changes"},
{29, "SIGINFO", "information request"},
{30, "SIGUSR1", "user defined signal 1"},
{31, "SIGUSR2", "user defined signal 2"},
{32, "SIGPWR", "power fail/restart"},
} }

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