Update logging for logrus

This commit is contained in:
Charlie Drage 2017-01-18 09:23:09 -05:00
parent 5837d0ad6e
commit c39e9b3cb0
146 changed files with 31301 additions and 4183 deletions

22
glide.lock generated
View File

@ -1,5 +1,5 @@
hash: fa2413eeb134e52459eccf2d588891d849a6cddc704cacd5e3e85fac9e6f5e28 hash: fa2413eeb134e52459eccf2d588891d849a6cddc704cacd5e3e85fac9e6f5e28
updated: 2017-01-13T01:50:16.861257324+05:30 updated: 2017-01-18T09:16:57.103796411-05:00
imports: imports:
- name: cloud.google.com/go - name: cloud.google.com/go
version: 3b1ae45394a234c385be014e9a488f2bb6eef821 version: 3b1ae45394a234c385be014e9a488f2bb6eef821
@ -210,7 +210,7 @@ imports:
- name: github.com/evanphx/json-patch - name: github.com/evanphx/json-patch
version: 465937c80b3c07a7c7ad20cc934898646a91c1de version: 465937c80b3c07a7c7ad20cc934898646a91c1de
- name: github.com/fatih/structs - name: github.com/fatih/structs
version: be738c8546f55b34e60125afa50ed73a9a9c460e version: a720dfa8df582c51dee1b36feabb906bde1588bd
- name: github.com/flynn/go-shlex - name: github.com/flynn/go-shlex
version: 3f9db97f856818214da2e1057f8ad84803971cff version: 3f9db97f856818214da2e1057f8ad84803971cff
- name: github.com/fsnotify/fsnotify - name: github.com/fsnotify/fsnotify
@ -351,13 +351,13 @@ imports:
- name: github.com/juju/ratelimit - name: github.com/juju/ratelimit
version: 77ed1c8a01217656d2080ad51981f6e99adaa177 version: 77ed1c8a01217656d2080ad51981f6e99adaa177
- name: github.com/magiconair/properties - name: github.com/magiconair/properties
version: 00ec919ecb56326853e2c1eee377fa324bc23a79 version: b3b15ef068fd0b17ddf408a23669f20811d194d2
- name: github.com/matttproud/golang_protobuf_extensions - name: github.com/matttproud/golang_protobuf_extensions
version: fc2b8d3a73c4867e51861bbdd5ae3c1f0869dd6a version: fc2b8d3a73c4867e51861bbdd5ae3c1f0869dd6a
subpackages: subpackages:
- pbutil - pbutil
- name: github.com/mitchellh/mapstructure - name: github.com/mitchellh/mapstructure
version: bfdb1a85537d60bc7e954e600c250219ea497417 version: ed105d635dfa9ea7133f7c79f1eb36203fc3a156
- name: github.com/openshift/origin - name: github.com/openshift/origin
version: b4e0954faa4a0d11d9c1a536b76ad4a8c0206b7c version: b4e0954faa4a0d11d9c1a536b76ad4a8c0206b7c
subpackages: subpackages:
@ -405,7 +405,7 @@ imports:
- name: github.com/pelletier/go-buffruneio - name: github.com/pelletier/go-buffruneio
version: df1e16fde7fc330a0ca68167c23bf7ed6ac31d6d version: df1e16fde7fc330a0ca68167c23bf7ed6ac31d6d
- name: github.com/pelletier/go-toml - name: github.com/pelletier/go-toml
version: 439fbba1f887c286024370cb4f281ba815c4c7d7 version: a1f048ba24490f9b0674a67e1ce995d685cddf4a
- name: github.com/prometheus/client_golang - name: github.com/prometheus/client_golang
version: e51041b3fa41cece0dca035740ba6411905be473 version: e51041b3fa41cece0dca035740ba6411905be473
subpackages: subpackages:
@ -423,7 +423,7 @@ imports:
- name: github.com/prometheus/procfs - name: github.com/prometheus/procfs
version: 454a56f35412459b5e684fd5ec0f9211b94f002a version: 454a56f35412459b5e684fd5ec0f9211b94f002a
- name: github.com/Sirupsen/logrus - name: github.com/Sirupsen/logrus
version: 4b6ea7319e214d98c938f12692336f7ca9348d6b version: 61e43dc76f7ee59a82bdf3d71033dc12bea4c77d
- name: github.com/spf13/afero - name: github.com/spf13/afero
version: 72b31426848c6ef12a7a8e216708cb0d1530f074 version: 72b31426848c6ef12a7a8e216708cb0d1530f074
subpackages: subpackages:
@ -431,11 +431,11 @@ imports:
- name: github.com/spf13/cast - name: github.com/spf13/cast
version: 56a7ecbeb18dde53c6db4bd96b541fd9741b8d44 version: 56a7ecbeb18dde53c6db4bd96b541fd9741b8d44
- name: github.com/spf13/cobra - name: github.com/spf13/cobra
version: 7c674d9e72017ed25f6d2b5e497a1368086b6a6f version: 1dd5ff2e11b6dca62fdcb275eb804b94607d8b06
- name: github.com/spf13/jwalterweatherman - name: github.com/spf13/jwalterweatherman
version: fa7ca7e836cf3a8bb4ebf799f472c12d7e903d66 version: fa7ca7e836cf3a8bb4ebf799f472c12d7e903d66
- name: github.com/spf13/pflag - name: github.com/spf13/pflag
version: 5ccb023bc27df288a957c5e994cd44fd19619465 version: 51268031d79952516489a9f8aa34e9709b98d946
- name: github.com/spf13/viper - name: github.com/spf13/viper
version: 5ed0fc31f7f453625df314d8e66b9791e8d13003 version: 5ed0fc31f7f453625df314d8e66b9791e8d13003
- name: github.com/ugorji/go - name: github.com/ugorji/go
@ -447,7 +447,7 @@ imports:
- name: github.com/xeipuuv/gojsonreference - name: github.com/xeipuuv/gojsonreference
version: e02fc20de94c78484cd5ffb007f8af96be030a45 version: e02fc20de94c78484cd5ffb007f8af96be030a45
- name: github.com/xeipuuv/gojsonschema - name: github.com/xeipuuv/gojsonschema
version: ac452913faa25c08bb78810d3e6f88b8a39f8f25 version: f06f290571ce81ab347174c6f7ad2e1865af41a7
- name: golang.org/x/net - name: golang.org/x/net
version: e90d6d0afc4c315a0d87a568ae68577cc15149a0 version: e90d6d0afc4c315a0d87a568ae68577cc15149a0
subpackages: subpackages:
@ -471,7 +471,7 @@ imports:
- jws - jws
- jwt - jwt
- name: golang.org/x/sys - name: golang.org/x/sys
version: 833a04a10549a95dc34458c195cbad61bbb6cb4d version: d75a52659825e75fff6158388dddc6a5b04f9ba5
subpackages: subpackages:
- unix - unix
- name: golang.org/x/text - name: golang.org/x/text
@ -513,7 +513,7 @@ imports:
- name: gopkg.in/inf.v0 - name: gopkg.in/inf.v0
version: 3887ee99ecf07df5b447e9b00d9c0b2adaa9f3e4 version: 3887ee99ecf07df5b447e9b00d9c0b2adaa9f3e4
- name: gopkg.in/yaml.v2 - name: gopkg.in/yaml.v2
version: a83829b6f1293c91addabc89d0571c246397bbf4 version: a5b47d31c556af34a302ce5d659e6fea44d90de0
- name: k8s.io/client-go - name: k8s.io/client-go
version: d72c0e162789e1bbb33c33cfa26858a1375efe01 version: d72c0e162789e1bbb33c33cfa26858a1375efe01
subpackages: subpackages:

64
vendor/github.com/Sirupsen/logrus/alt_exit.go generated vendored Normal file
View File

@ -0,0 +1,64 @@
package logrus
// The following code was sourced and modified from the
// https://bitbucket.org/tebeka/atexit package governed by the following license:
//
// Copyright (c) 2012 Miki Tebeka <miki.tebeka@gmail.com>.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
import (
"fmt"
"os"
)
var handlers = []func(){}
func runHandler(handler func()) {
defer func() {
if err := recover(); err != nil {
fmt.Fprintln(os.Stderr, "Error: Logrus exit handler error:", err)
}
}()
handler()
}
func runHandlers() {
for _, handler := range handlers {
runHandler(handler)
}
}
// Exit runs all the Logrus atexit handlers and then terminates the program using os.Exit(code)
func Exit(code int) {
runHandlers()
os.Exit(code)
}
// RegisterExitHandler adds a Logrus Exit handler, call logrus.Exit to invoke
// all handlers. The handlers will also be invoked when any Fatal log entry is
// made.
//
// This method is useful when a caller wishes to use logrus to log a fatal
// message but also needs to gracefully shutdown. An example usecase could be
// closing database connections, or sending a alert that the application is
// closing.
func RegisterExitHandler(handler func()) {
handlers = append(handlers, handler)
}

View File

@ -3,11 +3,21 @@ package logrus
import ( import (
"bytes" "bytes"
"fmt" "fmt"
"io"
"os" "os"
"sync"
"time" "time"
) )
var bufferPool *sync.Pool
func init() {
bufferPool = &sync.Pool{
New: func() interface{} {
return new(bytes.Buffer)
},
}
}
// Defines the key when adding errors using WithError. // Defines the key when adding errors using WithError.
var ErrorKey = "error" var ErrorKey = "error"
@ -29,6 +39,9 @@ type Entry struct {
// Message passed to Debug, Info, Warn, Error, Fatal or Panic // Message passed to Debug, Info, Warn, Error, Fatal or Panic
Message string Message string
// When formatter is called in entry.log(), an Buffer may be set to entry
Buffer *bytes.Buffer
} }
func NewEntry(logger *Logger) *Entry { func NewEntry(logger *Logger) *Entry {
@ -39,21 +52,15 @@ func NewEntry(logger *Logger) *Entry {
} }
} }
// Returns a reader for the entry, which is a proxy to the formatter.
func (entry *Entry) Reader() (*bytes.Buffer, error) {
serialized, err := entry.Logger.Formatter.Format(entry)
return bytes.NewBuffer(serialized), err
}
// Returns the string representation from the reader and ultimately the // Returns the string representation from the reader and ultimately the
// formatter. // formatter.
func (entry *Entry) String() (string, error) { func (entry *Entry) String() (string, error) {
reader, err := entry.Reader() serialized, err := entry.Logger.Formatter.Format(entry)
if err != nil { if err != nil {
return "", err return "", err
} }
str := string(serialized)
return reader.String(), err return str, nil
} }
// Add an error as single field (using the key defined in ErrorKey) to the Entry. // Add an error as single field (using the key defined in ErrorKey) to the Entry.
@ -81,6 +88,7 @@ func (entry *Entry) WithFields(fields Fields) *Entry {
// This function is not declared with a pointer value because otherwise // This function is not declared with a pointer value because otherwise
// race conditions will occur when using multiple goroutines // race conditions will occur when using multiple goroutines
func (entry Entry) log(level Level, msg string) { func (entry Entry) log(level Level, msg string) {
var buffer *bytes.Buffer
entry.Time = time.Now() entry.Time = time.Now()
entry.Level = level entry.Level = level
entry.Message = msg entry.Message = msg
@ -90,20 +98,23 @@ func (entry Entry) log(level Level, msg string) {
fmt.Fprintf(os.Stderr, "Failed to fire hook: %v\n", err) fmt.Fprintf(os.Stderr, "Failed to fire hook: %v\n", err)
entry.Logger.mu.Unlock() entry.Logger.mu.Unlock()
} }
buffer = bufferPool.Get().(*bytes.Buffer)
reader, err := entry.Reader() buffer.Reset()
defer bufferPool.Put(buffer)
entry.Buffer = buffer
serialized, err := entry.Logger.Formatter.Format(&entry)
entry.Buffer = nil
if err != nil { if err != nil {
entry.Logger.mu.Lock() entry.Logger.mu.Lock()
fmt.Fprintf(os.Stderr, "Failed to obtain reader, %v\n", err) fmt.Fprintf(os.Stderr, "Failed to obtain reader, %v\n", err)
entry.Logger.mu.Unlock() entry.Logger.mu.Unlock()
} } else {
entry.Logger.mu.Lock()
entry.Logger.mu.Lock() _, err = entry.Logger.Out.Write(serialized)
defer entry.Logger.mu.Unlock() if err != nil {
fmt.Fprintf(os.Stderr, "Failed to write to log, %v\n", err)
_, err = io.Copy(entry.Logger.Out, reader) }
if err != nil { entry.Logger.mu.Unlock()
fmt.Fprintf(os.Stderr, "Failed to write to log, %v\n", err)
} }
// To avoid Entry#log() returning a value that only would make sense for // To avoid Entry#log() returning a value that only would make sense for
@ -150,7 +161,7 @@ func (entry *Entry) Fatal(args ...interface{}) {
if entry.Logger.Level >= FatalLevel { if entry.Logger.Level >= FatalLevel {
entry.log(FatalLevel, fmt.Sprint(args...)) entry.log(FatalLevel, fmt.Sprint(args...))
} }
os.Exit(1) Exit(1)
} }
func (entry *Entry) Panic(args ...interface{}) { func (entry *Entry) Panic(args ...interface{}) {
@ -198,7 +209,7 @@ func (entry *Entry) Fatalf(format string, args ...interface{}) {
if entry.Logger.Level >= FatalLevel { if entry.Logger.Level >= FatalLevel {
entry.Fatal(fmt.Sprintf(format, args...)) entry.Fatal(fmt.Sprintf(format, args...))
} }
os.Exit(1) Exit(1)
} }
func (entry *Entry) Panicf(format string, args ...interface{}) { func (entry *Entry) Panicf(format string, args ...interface{}) {
@ -245,7 +256,7 @@ func (entry *Entry) Fatalln(args ...interface{}) {
if entry.Logger.Level >= FatalLevel { if entry.Logger.Level >= FatalLevel {
entry.Fatal(entry.sprintlnn(args...)) entry.Fatal(entry.sprintlnn(args...))
} }
os.Exit(1) Exit(1)
} }
func (entry *Entry) Panicln(args ...interface{}) { func (entry *Entry) Panicln(args ...interface{}) {

View File

@ -31,18 +31,15 @@ type Formatter interface {
// It's not exported because it's still using Data in an opinionated way. It's to // It's not exported because it's still using Data in an opinionated way. It's to
// avoid code duplication between the two default formatters. // avoid code duplication between the two default formatters.
func prefixFieldClashes(data Fields) { func prefixFieldClashes(data Fields) {
_, ok := data["time"] if t, ok := data["time"]; ok {
if ok { data["fields.time"] = t
data["fields.time"] = data["time"]
} }
_, ok = data["msg"] if m, ok := data["msg"]; ok {
if ok { data["fields.msg"] = m
data["fields.msg"] = data["msg"]
} }
_, ok = data["level"] if l, ok := data["level"]; ok {
if ok { data["fields.level"] = l
data["fields.level"] = data["level"]
} }
} }

View File

@ -5,9 +5,40 @@ import (
"fmt" "fmt"
) )
type fieldKey string
type FieldMap map[fieldKey]string
const (
FieldKeyMsg = "msg"
FieldKeyLevel = "level"
FieldKeyTime = "time"
)
func (f FieldMap) resolve(key fieldKey) string {
if k, ok := f[key]; ok {
return k
}
return string(key)
}
type JSONFormatter struct { type JSONFormatter struct {
// TimestampFormat sets the format used for marshaling timestamps. // TimestampFormat sets the format used for marshaling timestamps.
TimestampFormat string TimestampFormat string
// DisableTimestamp allows disabling automatic timestamps in output
DisableTimestamp bool
// FieldMap allows users to customize the names of keys for various fields.
// As an example:
// formatter := &JSONFormatter{
// FieldMap: FieldMap{
// FieldKeyTime: "@timestamp",
// FieldKeyLevel: "@level",
// FieldKeyLevel: "@message",
// },
// }
FieldMap FieldMap
} }
func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) { func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) {
@ -29,9 +60,11 @@ func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) {
timestampFormat = DefaultTimestampFormat timestampFormat = DefaultTimestampFormat
} }
data["time"] = entry.Time.Format(timestampFormat) if !f.DisableTimestamp {
data["msg"] = entry.Message data[f.FieldMap.resolve(FieldKeyTime)] = entry.Time.Format(timestampFormat)
data["level"] = entry.Level.String() }
data[f.FieldMap.resolve(FieldKeyMsg)] = entry.Message
data[f.FieldMap.resolve(FieldKeyLevel)] = entry.Level.String()
serialized, err := json.Marshal(data) serialized, err := json.Marshal(data)
if err != nil { if err != nil {

View File

@ -26,8 +26,31 @@ type Logger struct {
// to) `logrus.Info`, which allows Info(), Warn(), Error() and Fatal() to be // to) `logrus.Info`, which allows Info(), Warn(), Error() and Fatal() to be
// logged. `logrus.Debug` is useful in // logged. `logrus.Debug` is useful in
Level Level Level Level
// Used to sync writing to the log. // Used to sync writing to the log. Locking is enabled by Default
mu sync.Mutex mu MutexWrap
// Reusable empty entry
entryPool sync.Pool
}
type MutexWrap struct {
lock sync.Mutex
disabled bool
}
func (mw *MutexWrap) Lock() {
if !mw.disabled {
mw.lock.Lock()
}
}
func (mw *MutexWrap) Unlock() {
if !mw.disabled {
mw.lock.Unlock()
}
}
func (mw *MutexWrap) Disable() {
mw.disabled = true
} }
// Creates a new logger. Configuration should be set by changing `Formatter`, // Creates a new logger. Configuration should be set by changing `Formatter`,
@ -51,162 +74,235 @@ func New() *Logger {
} }
} }
// Adds a field to the log entry, note that you it doesn't log until you call func (logger *Logger) newEntry() *Entry {
entry, ok := logger.entryPool.Get().(*Entry)
if ok {
return entry
}
return NewEntry(logger)
}
func (logger *Logger) releaseEntry(entry *Entry) {
logger.entryPool.Put(entry)
}
// Adds a field to the log entry, note that it doesn't log until you call
// Debug, Print, Info, Warn, Fatal or Panic. It only creates a log entry. // Debug, Print, Info, Warn, Fatal or Panic. It only creates a log entry.
// If you want multiple fields, use `WithFields`. // If you want multiple fields, use `WithFields`.
func (logger *Logger) WithField(key string, value interface{}) *Entry { func (logger *Logger) WithField(key string, value interface{}) *Entry {
return NewEntry(logger).WithField(key, value) entry := logger.newEntry()
defer logger.releaseEntry(entry)
return entry.WithField(key, value)
} }
// Adds a struct of fields to the log entry. All it does is call `WithField` for // Adds a struct of fields to the log entry. All it does is call `WithField` for
// each `Field`. // each `Field`.
func (logger *Logger) WithFields(fields Fields) *Entry { func (logger *Logger) WithFields(fields Fields) *Entry {
return NewEntry(logger).WithFields(fields) entry := logger.newEntry()
defer logger.releaseEntry(entry)
return entry.WithFields(fields)
} }
// Add an error as single field to the log entry. All it does is call // Add an error as single field to the log entry. All it does is call
// `WithError` for the given `error`. // `WithError` for the given `error`.
func (logger *Logger) WithError(err error) *Entry { func (logger *Logger) WithError(err error) *Entry {
return NewEntry(logger).WithError(err) entry := logger.newEntry()
defer logger.releaseEntry(entry)
return entry.WithError(err)
} }
func (logger *Logger) Debugf(format string, args ...interface{}) { func (logger *Logger) Debugf(format string, args ...interface{}) {
if logger.Level >= DebugLevel { if logger.Level >= DebugLevel {
NewEntry(logger).Debugf(format, args...) entry := logger.newEntry()
entry.Debugf(format, args...)
logger.releaseEntry(entry)
} }
} }
func (logger *Logger) Infof(format string, args ...interface{}) { func (logger *Logger) Infof(format string, args ...interface{}) {
if logger.Level >= InfoLevel { if logger.Level >= InfoLevel {
NewEntry(logger).Infof(format, args...) entry := logger.newEntry()
entry.Infof(format, args...)
logger.releaseEntry(entry)
} }
} }
func (logger *Logger) Printf(format string, args ...interface{}) { func (logger *Logger) Printf(format string, args ...interface{}) {
NewEntry(logger).Printf(format, args...) entry := logger.newEntry()
entry.Printf(format, args...)
logger.releaseEntry(entry)
} }
func (logger *Logger) Warnf(format string, args ...interface{}) { func (logger *Logger) Warnf(format string, args ...interface{}) {
if logger.Level >= WarnLevel { if logger.Level >= WarnLevel {
NewEntry(logger).Warnf(format, args...) entry := logger.newEntry()
entry.Warnf(format, args...)
logger.releaseEntry(entry)
} }
} }
func (logger *Logger) Warningf(format string, args ...interface{}) { func (logger *Logger) Warningf(format string, args ...interface{}) {
if logger.Level >= WarnLevel { if logger.Level >= WarnLevel {
NewEntry(logger).Warnf(format, args...) entry := logger.newEntry()
entry.Warnf(format, args...)
logger.releaseEntry(entry)
} }
} }
func (logger *Logger) Errorf(format string, args ...interface{}) { func (logger *Logger) Errorf(format string, args ...interface{}) {
if logger.Level >= ErrorLevel { if logger.Level >= ErrorLevel {
NewEntry(logger).Errorf(format, args...) entry := logger.newEntry()
entry.Errorf(format, args...)
logger.releaseEntry(entry)
} }
} }
func (logger *Logger) Fatalf(format string, args ...interface{}) { func (logger *Logger) Fatalf(format string, args ...interface{}) {
if logger.Level >= FatalLevel { if logger.Level >= FatalLevel {
NewEntry(logger).Fatalf(format, args...) entry := logger.newEntry()
entry.Fatalf(format, args...)
logger.releaseEntry(entry)
} }
os.Exit(1) Exit(1)
} }
func (logger *Logger) Panicf(format string, args ...interface{}) { func (logger *Logger) Panicf(format string, args ...interface{}) {
if logger.Level >= PanicLevel { if logger.Level >= PanicLevel {
NewEntry(logger).Panicf(format, args...) entry := logger.newEntry()
entry.Panicf(format, args...)
logger.releaseEntry(entry)
} }
} }
func (logger *Logger) Debug(args ...interface{}) { func (logger *Logger) Debug(args ...interface{}) {
if logger.Level >= DebugLevel { if logger.Level >= DebugLevel {
NewEntry(logger).Debug(args...) entry := logger.newEntry()
entry.Debug(args...)
logger.releaseEntry(entry)
} }
} }
func (logger *Logger) Info(args ...interface{}) { func (logger *Logger) Info(args ...interface{}) {
if logger.Level >= InfoLevel { if logger.Level >= InfoLevel {
NewEntry(logger).Info(args...) entry := logger.newEntry()
entry.Info(args...)
logger.releaseEntry(entry)
} }
} }
func (logger *Logger) Print(args ...interface{}) { func (logger *Logger) Print(args ...interface{}) {
NewEntry(logger).Info(args...) entry := logger.newEntry()
entry.Info(args...)
logger.releaseEntry(entry)
} }
func (logger *Logger) Warn(args ...interface{}) { func (logger *Logger) Warn(args ...interface{}) {
if logger.Level >= WarnLevel { if logger.Level >= WarnLevel {
NewEntry(logger).Warn(args...) entry := logger.newEntry()
entry.Warn(args...)
logger.releaseEntry(entry)
} }
} }
func (logger *Logger) Warning(args ...interface{}) { func (logger *Logger) Warning(args ...interface{}) {
if logger.Level >= WarnLevel { if logger.Level >= WarnLevel {
NewEntry(logger).Warn(args...) entry := logger.newEntry()
entry.Warn(args...)
logger.releaseEntry(entry)
} }
} }
func (logger *Logger) Error(args ...interface{}) { func (logger *Logger) Error(args ...interface{}) {
if logger.Level >= ErrorLevel { if logger.Level >= ErrorLevel {
NewEntry(logger).Error(args...) entry := logger.newEntry()
entry.Error(args...)
logger.releaseEntry(entry)
} }
} }
func (logger *Logger) Fatal(args ...interface{}) { func (logger *Logger) Fatal(args ...interface{}) {
if logger.Level >= FatalLevel { if logger.Level >= FatalLevel {
NewEntry(logger).Fatal(args...) entry := logger.newEntry()
entry.Fatal(args...)
logger.releaseEntry(entry)
} }
os.Exit(1) Exit(1)
} }
func (logger *Logger) Panic(args ...interface{}) { func (logger *Logger) Panic(args ...interface{}) {
if logger.Level >= PanicLevel { if logger.Level >= PanicLevel {
NewEntry(logger).Panic(args...) entry := logger.newEntry()
entry.Panic(args...)
logger.releaseEntry(entry)
} }
} }
func (logger *Logger) Debugln(args ...interface{}) { func (logger *Logger) Debugln(args ...interface{}) {
if logger.Level >= DebugLevel { if logger.Level >= DebugLevel {
NewEntry(logger).Debugln(args...) entry := logger.newEntry()
entry.Debugln(args...)
logger.releaseEntry(entry)
} }
} }
func (logger *Logger) Infoln(args ...interface{}) { func (logger *Logger) Infoln(args ...interface{}) {
if logger.Level >= InfoLevel { if logger.Level >= InfoLevel {
NewEntry(logger).Infoln(args...) entry := logger.newEntry()
entry.Infoln(args...)
logger.releaseEntry(entry)
} }
} }
func (logger *Logger) Println(args ...interface{}) { func (logger *Logger) Println(args ...interface{}) {
NewEntry(logger).Println(args...) entry := logger.newEntry()
entry.Println(args...)
logger.releaseEntry(entry)
} }
func (logger *Logger) Warnln(args ...interface{}) { func (logger *Logger) Warnln(args ...interface{}) {
if logger.Level >= WarnLevel { if logger.Level >= WarnLevel {
NewEntry(logger).Warnln(args...) entry := logger.newEntry()
entry.Warnln(args...)
logger.releaseEntry(entry)
} }
} }
func (logger *Logger) Warningln(args ...interface{}) { func (logger *Logger) Warningln(args ...interface{}) {
if logger.Level >= WarnLevel { if logger.Level >= WarnLevel {
NewEntry(logger).Warnln(args...) entry := logger.newEntry()
entry.Warnln(args...)
logger.releaseEntry(entry)
} }
} }
func (logger *Logger) Errorln(args ...interface{}) { func (logger *Logger) Errorln(args ...interface{}) {
if logger.Level >= ErrorLevel { if logger.Level >= ErrorLevel {
NewEntry(logger).Errorln(args...) entry := logger.newEntry()
entry.Errorln(args...)
logger.releaseEntry(entry)
} }
} }
func (logger *Logger) Fatalln(args ...interface{}) { func (logger *Logger) Fatalln(args ...interface{}) {
if logger.Level >= FatalLevel { if logger.Level >= FatalLevel {
NewEntry(logger).Fatalln(args...) entry := logger.newEntry()
entry.Fatalln(args...)
logger.releaseEntry(entry)
} }
os.Exit(1) Exit(1)
} }
func (logger *Logger) Panicln(args ...interface{}) { func (logger *Logger) Panicln(args ...interface{}) {
if logger.Level >= PanicLevel { if logger.Level >= PanicLevel {
NewEntry(logger).Panicln(args...) entry := logger.newEntry()
entry.Panicln(args...)
logger.releaseEntry(entry)
} }
} }
//When file is opened with appending mode, it's safe to
//write concurrently to a file (within 4k message on Linux).
//In these cases user can choose to disable the lock.
func (logger *Logger) SetNoLock() {
logger.mu.Disable()
}

View File

@ -0,0 +1,8 @@
// +build appengine
package logrus
// IsTerminal returns true if stderr's file descriptor is a terminal.
func IsTerminal() bool {
return true
}

View File

@ -1,4 +1,5 @@
// +build darwin freebsd openbsd netbsd dragonfly // +build darwin freebsd openbsd netbsd dragonfly
// +build !appengine
package logrus package logrus

View File

@ -3,6 +3,8 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build !appengine
package logrus package logrus
import "syscall" import "syscall"

View File

@ -4,6 +4,7 @@
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build linux darwin freebsd openbsd netbsd dragonfly // +build linux darwin freebsd openbsd netbsd dragonfly
// +build !appengine
package logrus package logrus

View File

@ -1,4 +1,4 @@
// +build solaris // +build solaris,!appengine
package logrus package logrus

View File

@ -3,7 +3,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build windows // +build windows,!appengine
package logrus package logrus

View File

@ -28,10 +28,6 @@ func init() {
isTerminal = IsTerminal() isTerminal = IsTerminal()
} }
func miniTS() int {
return int(time.Since(baseTimestamp) / time.Second)
}
type TextFormatter struct { type TextFormatter struct {
// Set to true to bypass checking for a TTY before outputting colors. // Set to true to bypass checking for a TTY before outputting colors.
ForceColors bool ForceColors bool
@ -57,7 +53,8 @@ type TextFormatter struct {
} }
func (f *TextFormatter) Format(entry *Entry) ([]byte, error) { func (f *TextFormatter) Format(entry *Entry) ([]byte, error) {
var keys []string = make([]string, 0, len(entry.Data)) var b *bytes.Buffer
keys := make([]string, 0, len(entry.Data))
for k := range entry.Data { for k := range entry.Data {
keys = append(keys, k) keys = append(keys, k)
} }
@ -65,8 +62,11 @@ func (f *TextFormatter) Format(entry *Entry) ([]byte, error) {
if !f.DisableSorting { if !f.DisableSorting {
sort.Strings(keys) sort.Strings(keys)
} }
if entry.Buffer != nil {
b := &bytes.Buffer{} b = entry.Buffer
} else {
b = &bytes.Buffer{}
}
prefixFieldClashes(entry.Data) prefixFieldClashes(entry.Data)
@ -111,14 +111,17 @@ func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys []strin
levelText := strings.ToUpper(entry.Level.String())[0:4] levelText := strings.ToUpper(entry.Level.String())[0:4]
if !f.FullTimestamp { if f.DisableTimestamp {
fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%04d] %-44s ", levelColor, levelText, miniTS(), entry.Message) fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m %-44s ", levelColor, levelText, entry.Message)
} else if !f.FullTimestamp {
fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%04d] %-44s ", levelColor, levelText, int(entry.Time.Sub(baseTimestamp)/time.Second), entry.Message)
} else { } else {
fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%s] %-44s ", levelColor, levelText, entry.Time.Format(timestampFormat), entry.Message) fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%s] %-44s ", levelColor, levelText, entry.Time.Format(timestampFormat), entry.Message)
} }
for _, k := range keys { for _, k := range keys {
v := entry.Data[k] v := entry.Data[k]
fmt.Fprintf(b, " \x1b[%dm%s\x1b[0m=%+v", levelColor, k, v) fmt.Fprintf(b, " \x1b[%dm%s\x1b[0m=", levelColor, k)
f.appendValue(b, v)
} }
} }
@ -128,34 +131,36 @@ func needsQuoting(text string) bool {
(ch >= 'A' && ch <= 'Z') || (ch >= 'A' && ch <= 'Z') ||
(ch >= '0' && ch <= '9') || (ch >= '0' && ch <= '9') ||
ch == '-' || ch == '.') { ch == '-' || ch == '.') {
return false return true
} }
} }
return true return false
} }
func (f *TextFormatter) appendKeyValue(b *bytes.Buffer, key string, value interface{}) { func (f *TextFormatter) appendKeyValue(b *bytes.Buffer, key string, value interface{}) {
b.WriteString(key) b.WriteString(key)
b.WriteByte('=') b.WriteByte('=')
f.appendValue(b, value)
b.WriteByte(' ')
}
func (f *TextFormatter) appendValue(b *bytes.Buffer, value interface{}) {
switch value := value.(type) { switch value := value.(type) {
case string: case string:
if needsQuoting(value) { if !needsQuoting(value) {
b.WriteString(value) b.WriteString(value)
} else { } else {
fmt.Fprintf(b, "%q", value) fmt.Fprintf(b, "%q", value)
} }
case error: case error:
errmsg := value.Error() errmsg := value.Error()
if needsQuoting(errmsg) { if !needsQuoting(errmsg) {
b.WriteString(errmsg) b.WriteString(errmsg)
} else { } else {
fmt.Fprintf(b, "%q", value) fmt.Fprintf(b, "%q", errmsg)
} }
default: default:
fmt.Fprint(b, value) fmt.Fprint(b, value)
} }
b.WriteByte(' ')
} }

View File

@ -7,18 +7,40 @@ import (
) )
func (logger *Logger) Writer() *io.PipeWriter { func (logger *Logger) Writer() *io.PipeWriter {
return logger.WriterLevel(InfoLevel)
}
func (logger *Logger) WriterLevel(level Level) *io.PipeWriter {
reader, writer := io.Pipe() reader, writer := io.Pipe()
go logger.writerScanner(reader) var printFunc func(args ...interface{})
switch level {
case DebugLevel:
printFunc = logger.Debug
case InfoLevel:
printFunc = logger.Info
case WarnLevel:
printFunc = logger.Warn
case ErrorLevel:
printFunc = logger.Error
case FatalLevel:
printFunc = logger.Fatal
case PanicLevel:
printFunc = logger.Panic
default:
printFunc = logger.Print
}
go logger.writerScanner(reader, printFunc)
runtime.SetFinalizer(writer, writerFinalizer) runtime.SetFinalizer(writer, writerFinalizer)
return writer return writer
} }
func (logger *Logger) writerScanner(reader *io.PipeReader) { func (logger *Logger) writerScanner(reader *io.PipeReader, printFunc func(args ...interface{})) {
scanner := bufio.NewScanner(reader) scanner := bufio.NewScanner(reader)
for scanner.Scan() { for scanner.Scan() {
logger.Print(scanner.Text()) printFunc(scanner.Text())
} }
if err := scanner.Err(); err != nil { if err := scanner.Err(); err != nil {
logger.Errorf("Error while reading from Writer: %s", err) logger.Errorf("Error while reading from Writer: %s", err)

View File

@ -431,7 +431,7 @@ func strctVal(s interface{}) reflect.Value {
v := reflect.ValueOf(s) v := reflect.ValueOf(s)
// if pointer get the underlying element≤ // if pointer get the underlying element≤
if v.Kind() == reflect.Ptr { for v.Kind() == reflect.Ptr {
v = v.Elem() v = v.Elem()
} }
@ -530,15 +530,22 @@ func (s *Struct) nested(val reflect.Value) interface{} {
finalVal = m finalVal = m
} }
case reflect.Map: case reflect.Map:
v := val.Type().Elem() // get the element type of the map
if v.Kind() == reflect.Ptr { mapElem := val.Type()
v = v.Elem() switch val.Type().Kind() {
case reflect.Ptr, reflect.Array, reflect.Map,
reflect.Slice, reflect.Chan:
mapElem = val.Type().Elem()
if mapElem.Kind() == reflect.Ptr {
mapElem = mapElem.Elem()
}
} }
// only iterate over struct types, ie: map[string]StructType, // only iterate over struct types, ie: map[string]StructType,
// map[string][]StructType, // map[string][]StructType,
if v.Kind() == reflect.Struct || if mapElem.Kind() == reflect.Struct ||
(v.Kind() == reflect.Slice && v.Elem().Kind() == reflect.Struct) { (mapElem.Kind() == reflect.Slice &&
mapElem.Elem().Kind() == reflect.Struct) {
m := make(map[string]interface{}, val.Len()) m := make(map[string]interface{}, val.Len())
for _, k := range val.MapKeys() { for _, k := range val.MapKeys() {
m[k.String()] = s.nested(val.MapIndex(k)) m[k.String()] = s.nested(val.MapIndex(k))
@ -558,7 +565,10 @@ func (s *Struct) nested(val reflect.Value) interface{} {
// TODO(arslan): should this be optional? // TODO(arslan): should this be optional?
// do not iterate of non struct types, just pass the value. Ie: []int, // do not iterate of non struct types, just pass the value. Ie: []int,
// []string, co... We only iterate further if it's a struct. // []string, co... We only iterate further if it's a struct.
if val.Type().Elem().Kind() != reflect.Struct { // i.e []foo or []*foo
if val.Type().Elem().Kind() != reflect.Struct &&
!(val.Type().Elem().Kind() == reflect.Ptr &&
val.Type().Elem().Elem().Kind() == reflect.Struct) {
finalVal = val.Interface() finalVal = val.Interface()
break break
} }

View File

@ -1,4 +1,4 @@
// Copyright 2016 Frank Schroeder. All rights reserved. // Copyright 2017 Frank Schroeder. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
@ -158,16 +158,16 @@ func dec(p *Properties, key string, def *string, opts map[string]string, v refle
// keydef returns the property key and the default value based on the // keydef returns the property key and the default value based on the
// name of the struct field and the options in the tag. // name of the struct field and the options in the tag.
keydef := func(f reflect.StructField) (string, *string, map[string]string) { keydef := func(f reflect.StructField) (string, *string, map[string]string) {
key, opts := parseTag(f.Tag.Get("properties")) _key, _opts := parseTag(f.Tag.Get("properties"))
var def *string var _def *string
if d, ok := opts["default"]; ok { if d, ok := _opts["default"]; ok {
def = &d _def = &d
} }
if key != "" { if _key != "" {
return key, def, opts return _key, _def, _opts
} }
return f.Name, def, opts return f.Name, _def, _opts
} }
switch { switch {
@ -223,7 +223,7 @@ func dec(p *Properties, key string, def *string, opts map[string]string, v refle
case isMap(t): case isMap(t):
valT := t.Elem() valT := t.Elem()
m := reflect.MakeMap(t) m := reflect.MakeMap(t)
for postfix, _ := range p.FilterStripPrefix(key + ".").m { for postfix := range p.FilterStripPrefix(key + ".").m {
pp := strings.SplitN(postfix, ".", 2) pp := strings.SplitN(postfix, ".", 2)
mk, mv := pp[0], reflect.New(valT) mk, mv := pp[0], reflect.New(valT)
if err := dec(p, key+"."+mk, nil, nil, mv); err != nil { if err := dec(p, key+"."+mk, nil, nil, mv); err != nil {
@ -274,7 +274,6 @@ func isArray(t reflect.Type) bool { return t.Kind() == reflect.Array || t.Kin
func isBool(t reflect.Type) bool { return t.Kind() == reflect.Bool } func isBool(t reflect.Type) bool { return t.Kind() == reflect.Bool }
func isDuration(t reflect.Type) bool { return t == reflect.TypeOf(time.Second) } func isDuration(t reflect.Type) bool { return t == reflect.TypeOf(time.Second) }
func isMap(t reflect.Type) bool { return t.Kind() == reflect.Map } func isMap(t reflect.Type) bool { return t.Kind() == reflect.Map }
func isNumeric(t reflect.Type) bool { return isInt(t) || isUint(t) || isFloat(t) }
func isPtr(t reflect.Type) bool { return t.Kind() == reflect.Ptr } func isPtr(t reflect.Type) bool { return t.Kind() == reflect.Ptr }
func isString(t reflect.Type) bool { return t.Kind() == reflect.String } func isString(t reflect.Type) bool { return t.Kind() == reflect.String }
func isStruct(t reflect.Type) bool { return t.Kind() == reflect.Struct } func isStruct(t reflect.Type) bool { return t.Kind() == reflect.Struct }

View File

@ -1,4 +1,4 @@
// Copyright 2016 Frank Schroeder. All rights reserved. // Copyright 2017 Frank Schroeder. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.

View File

@ -1,4 +1,4 @@
// Copyright 2016 Frank Schroeder. All rights reserved. // Copyright 2017 Frank Schroeder. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.

View File

@ -1,4 +1,4 @@
// Copyright 2016 Frank Schroeder. All rights reserved. // Copyright 2017 Frank Schroeder. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// //
@ -72,7 +72,7 @@ type lexer struct {
// next returns the next rune in the input. // next returns the next rune in the input.
func (l *lexer) next() rune { func (l *lexer) next() rune {
if int(l.pos) >= len(l.input) { if l.pos >= len(l.input) {
l.width = 0 l.width = 0
return eof return eof
} }
@ -96,8 +96,8 @@ func (l *lexer) backup() {
// emit passes an item back to the client. // emit passes an item back to the client.
func (l *lexer) emit(t itemType) { func (l *lexer) emit(t itemType) {
item := item{t, l.start, string(l.runes)} i := item{t, l.start, string(l.runes)}
l.items <- item l.items <- i
l.start = l.pos l.start = l.pos
l.runes = l.runes[:0] l.runes = l.runes[:0]
} }
@ -114,7 +114,7 @@ func (l *lexer) appendRune(r rune) {
// accept consumes the next rune if it's from the valid set. // accept consumes the next rune if it's from the valid set.
func (l *lexer) accept(valid string) bool { func (l *lexer) accept(valid string) bool {
if strings.IndexRune(valid, l.next()) >= 0 { if strings.ContainsRune(valid, l.next()) {
return true return true
} }
l.backup() l.backup()
@ -123,7 +123,7 @@ func (l *lexer) accept(valid string) bool {
// acceptRun consumes a run of runes from the valid set. // acceptRun consumes a run of runes from the valid set.
func (l *lexer) acceptRun(valid string) { func (l *lexer) acceptRun(valid string) {
for strings.IndexRune(valid, l.next()) >= 0 { for strings.ContainsRune(valid, l.next()) {
} }
l.backup() l.backup()
} }
@ -156,9 +156,9 @@ func (l *lexer) errorf(format string, args ...interface{}) stateFn {
// nextItem returns the next item from the input. // nextItem returns the next item from the input.
func (l *lexer) nextItem() item { func (l *lexer) nextItem() item {
item := <-l.items i := <-l.items
l.lastPos = item.pos l.lastPos = i.pos
return item return i
} }
// lex creates a new scanner for the input string. // lex creates a new scanner for the input string.
@ -279,8 +279,7 @@ func lexValue(l *lexer) stateFn {
for { for {
switch r := l.next(); { switch r := l.next(); {
case isEscape(r): case isEscape(r):
r := l.peek() if isEOL(l.peek()) {
if isEOL(r) {
l.next() l.next()
l.acceptRun(whitespace) l.acceptRun(whitespace)
} else { } else {

View File

@ -1,4 +1,4 @@
// Copyright 2016 Frank Schroeder. All rights reserved. // Copyright 2017 Frank Schroeder. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
@ -98,7 +98,7 @@ func MustLoadURL(url string) *Properties {
return must(LoadURL(url)) return must(LoadURL(url))
} }
// MustLoadFiles reads the content of multiple URLs in the given order into a // MustLoadURLs reads the content of multiple URLs in the given order into a
// Properties struct and panics on error. If 'ignoreMissing' is true then a 404 // Properties struct and panics on error. If 'ignoreMissing' is true then a 404
// status code will not be reported as error. // status code will not be reported as error.
func MustLoadURLs(urls []string, ignoreMissing bool) *Properties { func MustLoadURLs(urls []string, ignoreMissing bool) *Properties {
@ -172,10 +172,12 @@ func loadURL(url string, ignoreMissing bool) (*Properties, error) {
return nil, fmt.Errorf("properties: %s returned %d", url, resp.StatusCode) return nil, fmt.Errorf("properties: %s returned %d", url, resp.StatusCode)
} }
body, err := ioutil.ReadAll(resp.Body) body, err := ioutil.ReadAll(resp.Body)
resp.Body.Close()
if err != nil { if err != nil {
return nil, fmt.Errorf("properties: %s error reading response. %s", url, err) return nil, fmt.Errorf("properties: %s error reading response. %s", url, err)
} }
if err = resp.Body.Close(); err != nil {
return nil, fmt.Errorf("properties: %s error reading response. %s", url, err)
}
ct := resp.Header.Get("Content-Type") ct := resp.Header.Get("Content-Type")
var enc Encoding var enc Encoding

View File

@ -1,4 +1,4 @@
// Copyright 2016 Frank Schroeder. All rights reserved. // Copyright 2017 Frank Schroeder. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.

View File

@ -1,4 +1,4 @@
// Copyright 2016 Frank Schroeder. All rights reserved. // Copyright 2017 Frank Schroeder. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
@ -28,8 +28,10 @@ type ErrorHandlerFunc func(error)
// functions. The default is LogFatalHandler. // functions. The default is LogFatalHandler.
var ErrorHandler ErrorHandlerFunc = LogFatalHandler var ErrorHandler ErrorHandlerFunc = LogFatalHandler
// LogHandlerFunc defines the function prototype for logging errors.
type LogHandlerFunc func(fmt string, args ...interface{}) type LogHandlerFunc func(fmt string, args ...interface{})
// LogPrintf defines a log handler which uses log.Printf.
var LogPrintf LogHandlerFunc = log.Printf var LogPrintf LogHandlerFunc = log.Printf
// LogFatalHandler handles the error by logging a fatal error and exiting. // LogFatalHandler handles the error by logging a fatal error and exiting.
@ -444,6 +446,8 @@ func (p *Properties) FilterRegexp(re *regexp.Regexp) *Properties {
pp := NewProperties() pp := NewProperties()
for _, k := range p.k { for _, k := range p.k {
if re.MatchString(k) { if re.MatchString(k) {
// TODO(fs): we are ignoring the error which flags a circular reference.
// TODO(fs): since we are just copying a subset of keys this cannot happen (fingers crossed)
pp.Set(k, p.m[k]) pp.Set(k, p.m[k])
} }
} }
@ -456,6 +460,8 @@ func (p *Properties) FilterPrefix(prefix string) *Properties {
pp := NewProperties() pp := NewProperties()
for _, k := range p.k { for _, k := range p.k {
if strings.HasPrefix(k, prefix) { if strings.HasPrefix(k, prefix) {
// TODO(fs): we are ignoring the error which flags a circular reference.
// TODO(fs): since we are just copying a subset of keys this cannot happen (fingers crossed)
pp.Set(k, p.m[k]) pp.Set(k, p.m[k])
} }
} }
@ -469,6 +475,9 @@ func (p *Properties) FilterStripPrefix(prefix string) *Properties {
n := len(prefix) n := len(prefix)
for _, k := range p.k { for _, k := range p.k {
if len(k) > len(prefix) && strings.HasPrefix(k, prefix) { if len(k) > len(prefix) && strings.HasPrefix(k, prefix) {
// TODO(fs): we are ignoring the error which flags a circular reference.
// TODO(fs): since we are modifying keys I am not entirely sure whether we can create a circular reference
// TODO(fs): this function should probably return an error but the signature is fixed
pp.Set(k[n:], p.m[k]) pp.Set(k[n:], p.m[k])
} }
} }
@ -483,9 +492,7 @@ func (p *Properties) Len() int {
// Keys returns all keys in the same order as in the input. // Keys returns all keys in the same order as in the input.
func (p *Properties) Keys() []string { func (p *Properties) Keys() []string {
keys := make([]string, len(p.k)) keys := make([]string, len(p.k))
for i, k := range p.k { copy(keys, p.k)
keys[i] = k
}
return keys return keys
} }

View File

@ -1,4 +1,4 @@
// Copyright 2016 Frank Schroeder. All rights reserved. // Copyright 2017 Frank Schroeder. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.

View File

@ -202,7 +202,7 @@ func (d *Decoder) decode(name string, data interface{}, val reflect.Value) error
d.config.DecodeHook, d.config.DecodeHook,
dataVal.Type(), val.Type(), data) dataVal.Type(), val.Type(), data)
if err != nil { if err != nil {
return err return fmt.Errorf("error decoding '%s': %s", name, err)
} }
} }
@ -229,6 +229,8 @@ func (d *Decoder) decode(name string, data interface{}, val reflect.Value) error
err = d.decodePtr(name, data, val) err = d.decodePtr(name, data, val)
case reflect.Slice: case reflect.Slice:
err = d.decodeSlice(name, data, val) err = d.decodeSlice(name, data, val)
case reflect.Func:
err = d.decodeFunc(name, data, val)
default: default:
// If we reached this point then we weren't able to decode it // If we reached this point then we weren't able to decode it
return fmt.Errorf("%s: unsupported type: %s", name, dataKind) return fmt.Errorf("%s: unsupported type: %s", name, dataKind)
@ -547,7 +549,7 @@ func (d *Decoder) decodePtr(name string, data interface{}, val reflect.Value) er
valType := val.Type() valType := val.Type()
valElemType := valType.Elem() valElemType := valType.Elem()
realVal:=val realVal := val
if realVal.IsNil() || d.config.ZeroFields { if realVal.IsNil() || d.config.ZeroFields {
realVal = reflect.New(valElemType) realVal = reflect.New(valElemType)
} }
@ -560,6 +562,19 @@ func (d *Decoder) decodePtr(name string, data interface{}, val reflect.Value) er
return nil return nil
} }
func (d *Decoder) decodeFunc(name string, data interface{}, val reflect.Value) error {
// Create an element of the concrete (non pointer) type and decode
// into that. Then set the value of the pointer to this type.
dataVal := reflect.Indirect(reflect.ValueOf(data))
if val.Type() != dataVal.Type() {
return fmt.Errorf(
"'%s' expected type '%s', got unconvertible type '%s'",
name, val.Type(), dataVal.Type())
}
val.Set(dataVal)
return nil
}
func (d *Decoder) decodeSlice(name string, data interface{}, val reflect.Value) error { func (d *Decoder) decodeSlice(name string, data interface{}, val reflect.Value) error {
dataVal := reflect.Indirect(reflect.ValueOf(data)) dataVal := reflect.Indirect(reflect.ValueOf(data))
dataValKind := dataVal.Kind() dataValKind := dataVal.Kind()
@ -567,7 +582,7 @@ func (d *Decoder) decodeSlice(name string, data interface{}, val reflect.Value)
valElemType := valType.Elem() valElemType := valType.Elem()
sliceType := reflect.SliceOf(valElemType) sliceType := reflect.SliceOf(valElemType)
valSlice:=val valSlice := val
if valSlice.IsNil() || d.config.ZeroFields { if valSlice.IsNil() || d.config.ZeroFields {
// Check input type // Check input type

View File

@ -87,7 +87,7 @@ func toTomlValue(item interface{}, indent int) string {
case nil: case nil:
return "" return ""
default: default:
panic(fmt.Sprintf("unsupported value type %T: %v", value, value)) panic(fmt.Errorf("unsupported value type %T: %v", value, value))
} }
} }
@ -154,6 +154,23 @@ func (t *TomlTree) toToml(indent, keyspace string) string {
return strings.Join(resultChunks, "") return strings.Join(resultChunks, "")
} }
// Same as ToToml(), but does not panic and returns an error
func (t *TomlTree) toTomlSafe(indent, keyspace string) (result string, err error) {
defer func() {
if r := recover(); r != nil {
result = ""
switch x := r.(type) {
case error:
err = x
default:
err = fmt.Errorf("unknown panic: %s", r)
}
}
}()
result = t.toToml(indent, keyspace)
return
}
func convertMapStringString(in map[string]string) map[string]interface{} { func convertMapStringString(in map[string]string) map[string]interface{} {
result := make(map[string]interface{}, len(in)) result := make(map[string]interface{}, len(in))
for k, v := range in { for k, v := range in {
@ -170,15 +187,18 @@ func convertMapInterfaceInterface(in map[interface{}]interface{}) map[string]int
return result return result
} }
// ToString is an alias for String // ToString generates a human-readable representation of the current tree.
func (t *TomlTree) ToString() string { // Output spans multiple lines, and is suitable for ingest by a TOML parser.
return t.String() // If the conversion cannot be performed, ToString returns a non-nil error.
func (t *TomlTree) ToString() (string, error) {
return t.toTomlSafe("", "")
} }
// String generates a human-readable representation of the current tree. // String generates a human-readable representation of the current tree.
// Output spans multiple lines, and is suitable for ingest by a TOML parser // Alias of ToString.
func (t *TomlTree) String() string { func (t *TomlTree) String() string {
return t.toToml("", "") result, _ := t.ToString()
return result
} }
// ToMap recursively generates a representation of the current tree using map[string]interface{}. // ToMap recursively generates a representation of the current tree using map[string]interface{}.

View File

@ -11,7 +11,7 @@ import (
) )
const ( const (
BashCompFilenameExt = "cobra_annotation_bash_completion_filename_extentions" BashCompFilenameExt = "cobra_annotation_bash_completion_filename_extensions"
BashCompCustom = "cobra_annotation_bash_completion_custom" BashCompCustom = "cobra_annotation_bash_completion_custom"
BashCompOneRequiredFlag = "cobra_annotation_bash_completion_one_required_flag" BashCompOneRequiredFlag = "cobra_annotation_bash_completion_one_required_flag"
BashCompSubdirsInDir = "cobra_annotation_bash_completion_subdirs_in_dir" BashCompSubdirsInDir = "cobra_annotation_bash_completion_subdirs_in_dir"
@ -401,10 +401,8 @@ func writeLocalNonPersistentFlag(flag *pflag.Flag, w io.Writer) error {
format += "=" format += "="
} }
format += "\")\n" format += "\")\n"
if _, err := fmt.Fprintf(w, format, name); err != nil { _, err := fmt.Fprintf(w, format, name)
return err return err
}
return nil
} }
func writeFlags(cmd *Command, w io.Writer) error { func writeFlags(cmd *Command, w io.Writer) error {

View File

@ -37,38 +37,36 @@ var templateFuncs = template.FuncMap{
var initializers []func() var initializers []func()
// automatic prefix matching can be a dangerous thing to automatically enable in CLI tools. // Automatic prefix matching can be a dangerous thing to automatically enable in CLI tools.
// Set this to true to enable it // Set this to true to enable it.
var EnablePrefixMatching = false var EnablePrefixMatching = false
//EnableCommandSorting controls sorting of the slice of commands, which is turned on by default. // EnableCommandSorting controls sorting of the slice of commands, which is turned on by default.
//To disable sorting, set it to false. // To disable sorting, set it to false.
var EnableCommandSorting = true var EnableCommandSorting = true
//AddTemplateFunc adds a template function that's available to Usage and Help // AddTemplateFunc adds a template function that's available to Usage and Help
//template generation. // template generation.
func AddTemplateFunc(name string, tmplFunc interface{}) { func AddTemplateFunc(name string, tmplFunc interface{}) {
templateFuncs[name] = tmplFunc templateFuncs[name] = tmplFunc
} }
//AddTemplateFuncs adds multiple template functions availalble to Usage and // AddTemplateFuncs adds multiple template functions availalble to Usage and
//Help template generation. // Help template generation.
func AddTemplateFuncs(tmplFuncs template.FuncMap) { func AddTemplateFuncs(tmplFuncs template.FuncMap) {
for k, v := range tmplFuncs { for k, v := range tmplFuncs {
templateFuncs[k] = v templateFuncs[k] = v
} }
} }
//OnInitialize takes a series of func() arguments and appends them to a slice of func(). // OnInitialize takes a series of func() arguments and appends them to a slice of func().
func OnInitialize(y ...func()) { func OnInitialize(y ...func()) {
for _, x := range y { initializers = append(initializers, y...)
initializers = append(initializers, x)
}
} }
//Gt takes two types and checks whether the first type is greater than the second. In case of types Arrays, Chans, // Gt takes two types and checks whether the first type is greater than the second. In case of types Arrays, Chans,
//Maps and Slices, Gt will compare their lengths. Ints are compared directly while strings are first parsed as // Maps and Slices, Gt will compare their lengths. Ints are compared directly while strings are first parsed as
//ints and then compared. // ints and then compared.
func Gt(a interface{}, b interface{}) bool { func Gt(a interface{}, b interface{}) bool {
var left, right int64 var left, right int64
av := reflect.ValueOf(a) av := reflect.ValueOf(a)
@ -96,7 +94,7 @@ func Gt(a interface{}, b interface{}) bool {
return left > right return left > right
} }
//Eq takes two types and checks whether they are equal. Supported types are int and string. Unsupported types will panic. // Eq takes two types and checks whether they are equal. Supported types are int and string. Unsupported types will panic.
func Eq(a interface{}, b interface{}) bool { func Eq(a interface{}, b interface{}) bool {
av := reflect.ValueOf(a) av := reflect.ValueOf(a)
bv := reflect.ValueOf(b) bv := reflect.ValueOf(b)
@ -116,7 +114,7 @@ func trimRightSpace(s string) string {
return strings.TrimRightFunc(s, unicode.IsSpace) return strings.TrimRightFunc(s, unicode.IsSpace)
} }
// appendIfNotPresent will append stringToAppend to the end of s, but only if it's not yet present in s // appendIfNotPresent will append stringToAppend to the end of s, but only if it's not yet present in s.
func appendIfNotPresent(s, stringToAppend string) string { func appendIfNotPresent(s, stringToAppend string) string {
if strings.Contains(s, stringToAppend) { if strings.Contains(s, stringToAppend) {
return s return s
@ -124,7 +122,7 @@ func appendIfNotPresent(s, stringToAppend string) string {
return s + " " + stringToAppend return s + " " + stringToAppend
} }
//rpad adds padding to the right of a string // rpad adds padding to the right of a string.
func rpad(s string, padding int) string { func rpad(s string, padding int) string {
template := fmt.Sprintf("%%-%ds", padding) template := fmt.Sprintf("%%-%ds", padding)
return fmt.Sprintf(template, s) return fmt.Sprintf(template, s)
@ -138,7 +136,7 @@ func tmpl(w io.Writer, text string, data interface{}) error {
return t.Execute(w, data) return t.Execute(w, data)
} }
// ld compares two strings and returns the levenshtein distance between them // ld compares two strings and returns the levenshtein distance between them.
func ld(s, t string, ignoreCase bool) int { func ld(s, t string, ignoreCase bool) int {
if ignoreCase { if ignoreCase {
s = strings.ToLower(s) s = strings.ToLower(s)

View File

@ -109,10 +109,11 @@ type Command struct {
flagErrorBuf *bytes.Buffer flagErrorBuf *bytes.Buffer
args []string // actual args parsed from flags args []string // actual args parsed from flags
output *io.Writer // out writer if set in SetOutput(w) output *io.Writer // out writer if set in SetOutput(w)
usageFunc func(*Command) error // Usage can be defined by application usageFunc func(*Command) error // Usage can be defined by application
usageTemplate string // Can be defined by Application usageTemplate string // Can be defined by Application
flagErrorFunc func(*Command, error) error
helpTemplate string // Can be defined by Application helpTemplate string // Can be defined by Application
helpFunc func(*Command, []string) // Help can be defined by application helpFunc func(*Command, []string) // Help can be defined by application
helpCommand *Command // The help command helpCommand *Command // The help command
@ -140,16 +141,22 @@ func (c *Command) SetOutput(output io.Writer) {
c.output = &output c.output = &output
} }
// Usage can be defined by application // Usage can be defined by application.
func (c *Command) SetUsageFunc(f func(*Command) error) { func (c *Command) SetUsageFunc(f func(*Command) error) {
c.usageFunc = f c.usageFunc = f
} }
// Can be defined by Application // Can be defined by Application.
func (c *Command) SetUsageTemplate(s string) { func (c *Command) SetUsageTemplate(s string) {
c.usageTemplate = s c.usageTemplate = s
} }
// SetFlagErrorFunc sets a function to generate an error when flag parsing
// fails
func (c *Command) SetFlagErrorFunc(f func(*Command, error) error) {
c.flagErrorFunc = f
}
// Can be defined by Application // Can be defined by Application
func (c *Command) SetHelpFunc(f func(*Command, []string)) { func (c *Command) SetHelpFunc(f func(*Command, []string)) {
c.helpFunc = f c.helpFunc = f
@ -159,7 +166,7 @@ func (c *Command) SetHelpCommand(cmd *Command) {
c.helpCommand = cmd c.helpCommand = cmd
} }
// Can be defined by Application // Can be defined by Application.
func (c *Command) SetHelpTemplate(s string) { func (c *Command) SetHelpTemplate(s string) {
c.helpTemplate = s c.helpTemplate = s
} }
@ -195,7 +202,7 @@ func (c *Command) getOut(def io.Writer) io.Writer {
} }
// UsageFunc returns either the function set by SetUsageFunc for this command // UsageFunc returns either the function set by SetUsageFunc for this command
// or a parent, or it returns a default usage function // or a parent, or it returns a default usage function.
func (c *Command) UsageFunc() (f func(*Command) error) { func (c *Command) UsageFunc() (f func(*Command) error) {
if c.usageFunc != nil { if c.usageFunc != nil {
return c.usageFunc return c.usageFunc
@ -214,22 +221,18 @@ func (c *Command) UsageFunc() (f func(*Command) error) {
} }
} }
// Output the usage for the command // Usage puts out the usage for the command.
// Used when a user provides invalid input // Used when a user provides invalid input.
// Can be defined by user by overriding UsageFunc // Can be defined by user by overriding UsageFunc.
func (c *Command) Usage() error { func (c *Command) Usage() error {
return c.UsageFunc()(c) return c.UsageFunc()(c)
} }
// HelpFunc returns either the function set by SetHelpFunc for this command // HelpFunc returns either the function set by SetHelpFunc for this command
// or a parent, or it returns a function with default help behavior // or a parent, or it returns a function with default help behavior.
func (c *Command) HelpFunc() func(*Command, []string) { func (c *Command) HelpFunc() func(*Command, []string) {
cmd := c if helpFunc := c.checkHelpFunc(); helpFunc != nil {
for cmd != nil { return helpFunc
if cmd.helpFunc != nil {
return cmd.helpFunc
}
cmd = cmd.parent
} }
return func(*Command, []string) { return func(*Command, []string) {
c.mergePersistentFlags() c.mergePersistentFlags()
@ -240,9 +243,23 @@ func (c *Command) HelpFunc() func(*Command, []string) {
} }
} }
// Output the help for the command // checkHelpFunc checks if there is helpFunc in ancestors of c.
// Used when a user calls help [command] func (c *Command) checkHelpFunc() func(*Command, []string) {
// Can be defined by user by overriding HelpFunc if c == nil {
return nil
}
if c.helpFunc != nil {
return c.helpFunc
}
if c.HasParent() {
return c.parent.checkHelpFunc()
}
return nil
}
// Help puts out the help for the command.
// Used when a user calls help [command].
// Can be defined by user by overriding HelpFunc.
func (c *Command) Help() error { func (c *Command) Help() error {
c.HelpFunc()(c, []string{}) c.HelpFunc()(c, []string{})
return nil return nil
@ -257,6 +274,22 @@ func (c *Command) UsageString() string {
return bb.String() return bb.String()
} }
// FlagErrorFunc returns either the function set by SetFlagErrorFunc for this
// command or a parent, or it returns a function which returns the original
// error.
func (c *Command) FlagErrorFunc() (f func(*Command, error) error) {
if c.flagErrorFunc != nil {
return c.flagErrorFunc
}
if c.HasParent() {
return c.parent.FlagErrorFunc()
}
return func(c *Command, err error) error {
return err
}
}
var minUsagePadding = 25 var minUsagePadding = 25
func (c *Command) UsagePadding() int { func (c *Command) UsagePadding() int {
@ -333,7 +366,7 @@ func (c *Command) HelpTemplate() string {
{{end}}{{if or .Runnable .HasSubCommands}}{{.UsageString}}{{end}}` {{end}}{{if or .Runnable .HasSubCommands}}{{.UsageString}}{{end}}`
} }
// Really only used when casting a command to a commander // Really only used when casting a command to a commander.
func (c *Command) resetChildrensParents() { func (c *Command) resetChildrensParents() {
for _, x := range c.commands { for _, x := range c.commands {
x.parent = c x.parent = c
@ -553,7 +586,7 @@ func (c *Command) execute(a []string) (err error) {
err = c.ParseFlags(a) err = c.ParseFlags(a)
if err != nil { if err != nil {
return err return c.FlagErrorFunc()(c, err)
} }
// If help is called, regardless of other flags, return we want help // If help is called, regardless of other flags, return we want help
// Also say we need help if the command isn't runnable. // Also say we need help if the command isn't runnable.
@ -712,6 +745,7 @@ func (c *Command) ExecuteC() (cmd *Command, err error) {
} }
func (c *Command) initHelpFlag() { func (c *Command) initHelpFlag() {
c.mergePersistentFlags()
if c.Flags().Lookup("help") == nil { if c.Flags().Lookup("help") == nil {
c.Flags().BoolP("help", "h", false, "help for "+c.Name()) c.Flags().BoolP("help", "h", false, "help for "+c.Name())
} }
@ -745,13 +779,13 @@ func (c *Command) initHelpCmd() {
c.AddCommand(c.helpCommand) c.AddCommand(c.helpCommand)
} }
// Used for testing // Used for testing.
func (c *Command) ResetCommands() { func (c *Command) ResetCommands() {
c.commands = nil c.commands = nil
c.helpCommand = nil c.helpCommand = nil
} }
// Sorts commands by their names // Sorts commands by their names.
type commandSorterByName []*Command type commandSorterByName []*Command
func (c commandSorterByName) Len() int { return len(c) } func (c commandSorterByName) Len() int { return len(c) }
@ -831,18 +865,18 @@ main:
} }
} }
// Print is a convenience method to Print to the defined output, fallback to Stderr if not set // Print is a convenience method to Print to the defined output, fallback to Stderr if not set.
func (c *Command) Print(i ...interface{}) { func (c *Command) Print(i ...interface{}) {
fmt.Fprint(c.OutOrStderr(), i...) fmt.Fprint(c.OutOrStderr(), i...)
} }
// Println is a convenience method to Println to the defined output, fallback to Stderr if not set // Println is a convenience method to Println to the defined output, fallback to Stderr if not set.
func (c *Command) Println(i ...interface{}) { func (c *Command) Println(i ...interface{}) {
str := fmt.Sprintln(i...) str := fmt.Sprintln(i...)
c.Print(str) c.Print(str)
} }
// Printf is a convenience method to Printf to the defined output, fallback to Stderr if not set // Printf is a convenience method to Printf to the defined output, fallback to Stderr if not set.
func (c *Command) Printf(format string, i ...interface{}) { func (c *Command) Printf(format string, i ...interface{}) {
str := fmt.Sprintf(format, i...) str := fmt.Sprintf(format, i...)
c.Print(str) c.Print(str)
@ -859,7 +893,7 @@ func (c *Command) CommandPath() string {
return str return str
} }
//The full usage for a given command (including parents) // UseLine puts out the full usage for a given command (including parents).
func (c *Command) UseLine() string { func (c *Command) UseLine() string {
str := "" str := ""
if c.HasParent() { if c.HasParent() {
@ -869,7 +903,7 @@ func (c *Command) UseLine() string {
} }
// For use in determining which flags have been assigned to which commands // For use in determining which flags have been assigned to which commands
// and which persist // and which persist.
func (c *Command) DebugFlags() { func (c *Command) DebugFlags() {
c.Println("DebugFlags called on", c.Name()) c.Println("DebugFlags called on", c.Name())
var debugflags func(*Command) var debugflags func(*Command)
@ -944,18 +978,18 @@ func (c *Command) HasExample() bool {
return len(c.Example) > 0 return len(c.Example) > 0
} }
// Runnable determines if the command is itself runnable // Runnable determines if the command is itself runnable.
func (c *Command) Runnable() bool { func (c *Command) Runnable() bool {
return c.Run != nil || c.RunE != nil return c.Run != nil || c.RunE != nil
} }
// HasSubCommands determines if the command has children commands // HasSubCommands determines if the command has children commands.
func (c *Command) HasSubCommands() bool { func (c *Command) HasSubCommands() bool {
return len(c.commands) > 0 return len(c.commands) > 0
} }
// IsAvailableCommand determines if a command is available as a non-help command // IsAvailableCommand determines if a command is available as a non-help command
// (this includes all non deprecated/hidden commands) // (this includes all non deprecated/hidden commands).
func (c *Command) IsAvailableCommand() bool { func (c *Command) IsAvailableCommand() bool {
if len(c.Deprecated) != 0 || c.Hidden { if len(c.Deprecated) != 0 || c.Hidden {
return false return false
@ -974,7 +1008,7 @@ func (c *Command) IsAvailableCommand() bool {
// IsHelpCommand determines if a command is a 'help' command; a help command is // IsHelpCommand determines if a command is a 'help' command; a help command is
// determined by the fact that it is NOT runnable/hidden/deprecated, and has no // determined by the fact that it is NOT runnable/hidden/deprecated, and has no
// sub commands that are runnable/hidden/deprecated // sub commands that are runnable/hidden/deprecated.
func (c *Command) IsHelpCommand() bool { func (c *Command) IsHelpCommand() bool {
// if a command is runnable, deprecated, or hidden it is not a 'help' command // if a command is runnable, deprecated, or hidden it is not a 'help' command
@ -993,9 +1027,9 @@ func (c *Command) IsHelpCommand() bool {
return true return true
} }
// HasHelpSubCommands determines if a command has any avilable 'help' sub commands // HasHelpSubCommands determines if a command has any available 'help' sub commands
// that need to be shown in the usage/help default template under 'additional help // that need to be shown in the usage/help default template under 'additional help
// topics' // topics'.
func (c *Command) HasHelpSubCommands() bool { func (c *Command) HasHelpSubCommands() bool {
// return true on the first found available 'help' sub command // return true on the first found available 'help' sub command
@ -1010,7 +1044,7 @@ func (c *Command) HasHelpSubCommands() bool {
} }
// HasAvailableSubCommands determines if a command has available sub commands that // HasAvailableSubCommands determines if a command has available sub commands that
// need to be shown in the usage/help default template under 'available commands' // need to be shown in the usage/help default template under 'available commands'.
func (c *Command) HasAvailableSubCommands() bool { func (c *Command) HasAvailableSubCommands() bool {
// return true on the first found available (non deprecated/help/hidden) // return true on the first found available (non deprecated/help/hidden)
@ -1026,17 +1060,18 @@ func (c *Command) HasAvailableSubCommands() bool {
return false return false
} }
// Determine if the command is a child command // HasParent determines if the command is a child command.
func (c *Command) HasParent() bool { func (c *Command) HasParent() bool {
return c.parent != nil return c.parent != nil
} }
// GlobalNormalizationFunc returns the global normalization function or nil if doesn't exists // GlobalNormalizationFunc returns the global normalization function or nil if doesn't exists.
func (c *Command) GlobalNormalizationFunc() func(f *flag.FlagSet, name string) flag.NormalizedName { func (c *Command) GlobalNormalizationFunc() func(f *flag.FlagSet, name string) flag.NormalizedName {
return c.globNormFunc return c.globNormFunc
} }
// Get the complete FlagSet that applies to this command (local and persistent declared here and by all parents) // Flage returns the complete FlagSet that applies
// to this command (local and persistent declared here and by all parents).
func (c *Command) Flags() *flag.FlagSet { func (c *Command) Flags() *flag.FlagSet {
if c.flags == nil { if c.flags == nil {
c.flags = flag.NewFlagSet(c.Name(), flag.ContinueOnError) c.flags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)
@ -1048,7 +1083,7 @@ func (c *Command) Flags() *flag.FlagSet {
return c.flags return c.flags
} }
// LocalNonPersistentFlags are flags specific to this command which will NOT persist to subcommands // LocalNonPersistentFlags are flags specific to this command which will NOT persist to subcommands.
func (c *Command) LocalNonPersistentFlags() *flag.FlagSet { func (c *Command) LocalNonPersistentFlags() *flag.FlagSet {
persistentFlags := c.PersistentFlags() persistentFlags := c.PersistentFlags()
@ -1061,7 +1096,7 @@ func (c *Command) LocalNonPersistentFlags() *flag.FlagSet {
return out return out
} }
// Get the local FlagSet specifically set in the current command // LocalFlags returns the local FlagSet specifically set in the current command.
func (c *Command) LocalFlags() *flag.FlagSet { func (c *Command) LocalFlags() *flag.FlagSet {
c.mergePersistentFlags() c.mergePersistentFlags()
@ -1079,7 +1114,7 @@ func (c *Command) LocalFlags() *flag.FlagSet {
return local return local
} }
// All Flags which were inherited from parents commands // InheritedFlags returns all flags which were inherited from parents commands.
func (c *Command) InheritedFlags() *flag.FlagSet { func (c *Command) InheritedFlags() *flag.FlagSet {
c.mergePersistentFlags() c.mergePersistentFlags()
@ -1108,12 +1143,12 @@ func (c *Command) InheritedFlags() *flag.FlagSet {
return inherited return inherited
} }
// All Flags which were not inherited from parent commands // NonInheritedFlags returns all flags which were not inherited from parent commands.
func (c *Command) NonInheritedFlags() *flag.FlagSet { func (c *Command) NonInheritedFlags() *flag.FlagSet {
return c.LocalFlags() return c.LocalFlags()
} }
// Get the Persistent FlagSet specifically set in the current command // PersistentFlags returns the persistent FlagSet specifically set in the current command.
func (c *Command) PersistentFlags() *flag.FlagSet { func (c *Command) PersistentFlags() *flag.FlagSet {
if c.pflags == nil { if c.pflags == nil {
c.pflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError) c.pflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)
@ -1125,7 +1160,7 @@ func (c *Command) PersistentFlags() *flag.FlagSet {
return c.pflags return c.pflags
} }
// For use in testing // ResetFlags is used in testing.
func (c *Command) ResetFlags() { func (c *Command) ResetFlags() {
c.flagErrorBuf = new(bytes.Buffer) c.flagErrorBuf = new(bytes.Buffer)
c.flagErrorBuf.Reset() c.flagErrorBuf.Reset()
@ -1135,50 +1170,50 @@ func (c *Command) ResetFlags() {
c.pflags.SetOutput(c.flagErrorBuf) c.pflags.SetOutput(c.flagErrorBuf)
} }
// Does the command contain any flags (local plus persistent from the entire structure) // Does the command contain any flags (local plus persistent from the entire structure).
func (c *Command) HasFlags() bool { func (c *Command) HasFlags() bool {
return c.Flags().HasFlags() return c.Flags().HasFlags()
} }
// Does the command contain persistent flags // Does the command contain persistent flags.
func (c *Command) HasPersistentFlags() bool { func (c *Command) HasPersistentFlags() bool {
return c.PersistentFlags().HasFlags() return c.PersistentFlags().HasFlags()
} }
// Does the command has flags specifically declared locally // Does the command has flags specifically declared locally.
func (c *Command) HasLocalFlags() bool { func (c *Command) HasLocalFlags() bool {
return c.LocalFlags().HasFlags() return c.LocalFlags().HasFlags()
} }
// Does the command have flags inherited from its parent command // Does the command have flags inherited from its parent command.
func (c *Command) HasInheritedFlags() bool { func (c *Command) HasInheritedFlags() bool {
return c.InheritedFlags().HasFlags() return c.InheritedFlags().HasFlags()
} }
// Does the command contain any flags (local plus persistent from the entire // Does the command contain any flags (local plus persistent from the entire
// structure) which are not hidden or deprecated // structure) which are not hidden or deprecated.
func (c *Command) HasAvailableFlags() bool { func (c *Command) HasAvailableFlags() bool {
return c.Flags().HasAvailableFlags() return c.Flags().HasAvailableFlags()
} }
// Does the command contain persistent flags which are not hidden or deprecated // Does the command contain persistent flags which are not hidden or deprecated.
func (c *Command) HasAvailablePersistentFlags() bool { func (c *Command) HasAvailablePersistentFlags() bool {
return c.PersistentFlags().HasAvailableFlags() return c.PersistentFlags().HasAvailableFlags()
} }
// Does the command has flags specifically declared locally which are not hidden // Does the command has flags specifically declared locally which are not hidden
// or deprecated // or deprecated.
func (c *Command) HasAvailableLocalFlags() bool { func (c *Command) HasAvailableLocalFlags() bool {
return c.LocalFlags().HasAvailableFlags() return c.LocalFlags().HasAvailableFlags()
} }
// Does the command have flags inherited from its parent command which are // Does the command have flags inherited from its parent command which are
// not hidden or deprecated // not hidden or deprecated.
func (c *Command) HasAvailableInheritedFlags() bool { func (c *Command) HasAvailableInheritedFlags() bool {
return c.InheritedFlags().HasAvailableFlags() return c.InheritedFlags().HasAvailableFlags()
} }
// Flag climbs up the command tree looking for matching flag // Flag climbs up the command tree looking for matching flag.
func (c *Command) Flag(name string) (flag *flag.Flag) { func (c *Command) Flag(name string) (flag *flag.Flag) {
flag = c.Flags().Lookup(name) flag = c.Flags().Lookup(name)
@ -1189,7 +1224,7 @@ func (c *Command) Flag(name string) (flag *flag.Flag) {
return return
} }
// recursively find matching persistent flag // Recursively find matching persistent flag.
func (c *Command) persistentFlag(name string) (flag *flag.Flag) { func (c *Command) persistentFlag(name string) (flag *flag.Flag) {
if c.HasPersistentFlags() { if c.HasPersistentFlags() {
flag = c.PersistentFlags().Lookup(name) flag = c.PersistentFlags().Lookup(name)
@ -1201,7 +1236,7 @@ func (c *Command) persistentFlag(name string) (flag *flag.Flag) {
return return
} }
// ParseFlags parses persistent flag tree & local flags // ParseFlags parses persistent flag tree and local flags.
func (c *Command) ParseFlags(args []string) (err error) { func (c *Command) ParseFlags(args []string) (err error) {
if c.DisableFlagParsing { if c.DisableFlagParsing {
return nil return nil
@ -1211,7 +1246,7 @@ func (c *Command) ParseFlags(args []string) (err error) {
return return
} }
// Parent returns a commands parent command // Parent returns a commands parent command.
func (c *Command) Parent() *Command { func (c *Command) Parent() *Command {
return c.parent return c.parent
} }

View File

@ -752,7 +752,7 @@ func containsShorthand(arg, shorthand string) bool {
return strings.Contains(arg, shorthand) return strings.Contains(arg, shorthand)
} }
func (f *FlagSet) parseLongArg(s string, args []string) (a []string, err error) { func (f *FlagSet) parseLongArg(s string, args []string, fn parseFunc) (a []string, err error) {
a = args a = args
name := s[2:] name := s[2:]
if len(name) == 0 || name[0] == '-' || name[0] == '=' { if len(name) == 0 || name[0] == '-' || name[0] == '=' {
@ -786,11 +786,11 @@ func (f *FlagSet) parseLongArg(s string, args []string) (a []string, err error)
err = f.failf("flag needs an argument: %s", s) err = f.failf("flag needs an argument: %s", s)
return return
} }
err = f.setFlag(flag, value, s) err = fn(flag, value, s)
return return
} }
func (f *FlagSet) parseSingleShortArg(shorthands string, args []string) (outShorts string, outArgs []string, err error) { func (f *FlagSet) parseSingleShortArg(shorthands string, args []string, fn parseFunc) (outShorts string, outArgs []string, err error) {
if strings.HasPrefix(shorthands, "test.") { if strings.HasPrefix(shorthands, "test.") {
return return
} }
@ -825,16 +825,16 @@ func (f *FlagSet) parseSingleShortArg(shorthands string, args []string) (outShor
err = f.failf("flag needs an argument: %q in -%s", c, shorthands) err = f.failf("flag needs an argument: %q in -%s", c, shorthands)
return return
} }
err = f.setFlag(flag, value, shorthands) err = fn(flag, value, shorthands)
return return
} }
func (f *FlagSet) parseShortArg(s string, args []string) (a []string, err error) { func (f *FlagSet) parseShortArg(s string, args []string, fn parseFunc) (a []string, err error) {
a = args a = args
shorthands := s[1:] shorthands := s[1:]
for len(shorthands) > 0 { for len(shorthands) > 0 {
shorthands, a, err = f.parseSingleShortArg(shorthands, args) shorthands, a, err = f.parseSingleShortArg(shorthands, args, fn)
if err != nil { if err != nil {
return return
} }
@ -843,7 +843,7 @@ func (f *FlagSet) parseShortArg(s string, args []string) (a []string, err error)
return return
} }
func (f *FlagSet) parseArgs(args []string) (err error) { func (f *FlagSet) parseArgs(args []string, fn parseFunc) (err error) {
for len(args) > 0 { for len(args) > 0 {
s := args[0] s := args[0]
args = args[1:] args = args[1:]
@ -863,9 +863,9 @@ func (f *FlagSet) parseArgs(args []string) (err error) {
f.args = append(f.args, args...) f.args = append(f.args, args...)
break break
} }
args, err = f.parseLongArg(s, args) args, err = f.parseLongArg(s, args, fn)
} else { } else {
args, err = f.parseShortArg(s, args) args, err = f.parseShortArg(s, args, fn)
} }
if err != nil { if err != nil {
return return
@ -881,7 +881,41 @@ func (f *FlagSet) parseArgs(args []string) (err error) {
func (f *FlagSet) Parse(arguments []string) error { func (f *FlagSet) Parse(arguments []string) error {
f.parsed = true f.parsed = true
f.args = make([]string, 0, len(arguments)) f.args = make([]string, 0, len(arguments))
err := f.parseArgs(arguments)
assign := func(flag *Flag, value, origArg string) error {
return f.setFlag(flag, value, origArg)
}
err := f.parseArgs(arguments, assign)
if err != nil {
switch f.errorHandling {
case ContinueOnError:
return err
case ExitOnError:
os.Exit(2)
case PanicOnError:
panic(err)
}
}
return nil
}
type parseFunc func(flag *Flag, value, origArg string) error
// ParseAll parses flag definitions from the argument list, which should not
// include the command name. The arguments for fn are flag and value. Must be
// called after all flags in the FlagSet are defined and before flags are
// accessed by the program. The return value will be ErrHelp if -help was set
// but not defined.
func (f *FlagSet) ParseAll(arguments []string, fn func(flag *Flag, value string) error) error {
f.parsed = true
f.args = make([]string, 0, len(arguments))
assign := func(flag *Flag, value, origArg string) error {
return fn(flag, value)
}
err := f.parseArgs(arguments, assign)
if err != nil { if err != nil {
switch f.errorHandling { switch f.errorHandling {
case ContinueOnError: case ContinueOnError:
@ -907,6 +941,14 @@ func Parse() {
CommandLine.Parse(os.Args[1:]) CommandLine.Parse(os.Args[1:])
} }
// ParseAll parses the command-line flags from os.Args[1:] and called fn for each.
// The arguments for fn are flag and value. Must be called after all flags are
// defined and before flags are accessed by the program.
func ParseAll(fn func(flag *Flag, value string) error) {
// Ignore errors; CommandLine is set for ExitOnError.
CommandLine.ParseAll(os.Args[1:], fn)
}
// SetInterspersed sets whether to support interspersed option/non-option arguments. // SetInterspersed sets whether to support interspersed option/non-option arguments.
func SetInterspersed(interspersed bool) { func SetInterspersed(interspersed bool) {
CommandLine.SetInterspersed(interspersed) CommandLine.SetInterspersed(interspersed)

View File

@ -1,10 +1,20 @@
package gojsonschema package gojsonschema
import ( import (
"fmt" "bytes"
"strings" "sync"
"text/template"
) )
var errorTemplates errorTemplate = errorTemplate{template.New("errors-new"),sync.RWMutex{}}
// template.Template is not thread-safe for writing, so some locking is done
// sync.RWMutex is used for efficiently locking when new templates are created
type errorTemplate struct {
*template.Template
sync.RWMutex
}
type ( type (
// RequiredError. ErrorDetails: property string // RequiredError. ErrorDetails: property string
RequiredError struct { RequiredError struct {
@ -230,13 +240,35 @@ func newError(err ResultError, context *jsonContext, value interface{}, locale l
err.SetDescription(formatErrorDescription(d, details)) err.SetDescription(formatErrorDescription(d, details))
} }
// formatErrorDescription takes a string in this format: %field% is required // formatErrorDescription takes a string in the default text/template
// and converts it to a string with replacements. The fields come from // format and converts it to a string with replacements. The fields come
// the ErrorDetails struct and vary for each type of error. // from the ErrorDetails struct and vary for each type of error.
func formatErrorDescription(s string, details ErrorDetails) string { func formatErrorDescription(s string, details ErrorDetails) string {
for name, val := range details {
s = strings.Replace(s, "%"+strings.ToLower(name)+"%", fmt.Sprintf("%v", val), -1) var tpl *template.Template
var descrAsBuffer bytes.Buffer
var err error
errorTemplates.RLock()
tpl = errorTemplates.Lookup(s)
errorTemplates.RUnlock()
if tpl == nil {
errorTemplates.Lock()
tpl = errorTemplates.New(s)
tpl, err = tpl.Parse(s)
errorTemplates.Unlock()
if err != nil {
return err.Error()
}
} }
return s err = tpl.Execute(&descrAsBuffer, details)
if err != nil {
return err.Error()
}
return descrAsBuffer.String()
} }

View File

@ -5,6 +5,7 @@ import (
"net/url" "net/url"
"reflect" "reflect"
"regexp" "regexp"
"strings"
"time" "time"
) )
@ -59,6 +60,9 @@ type (
// UUIDFormatChecker validates a UUID is in the correct format // UUIDFormatChecker validates a UUID is in the correct format
UUIDFormatChecker struct{} UUIDFormatChecker struct{}
// RegexFormatChecker validates a regex is in the correct format
RegexFormatChecker struct{}
) )
var ( var (
@ -73,6 +77,7 @@ var (
"ipv6": IPV6FormatChecker{}, "ipv6": IPV6FormatChecker{},
"uri": URIFormatChecker{}, "uri": URIFormatChecker{},
"uuid": UUIDFormatChecker{}, "uuid": UUIDFormatChecker{},
"regex": RegexFormatChecker{},
}, },
} }
@ -80,7 +85,7 @@ var (
rxEmail = regexp.MustCompile("^(((([a-zA-Z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])+(\\.([a-zA-Z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])+)*)|((\\x22)((((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(([\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(\\([\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}]))))*(((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(\\x22)))@((([a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(([a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])([a-zA-Z]|\\d|-|\\.|_|~|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])*([a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])))\\.)+(([a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(([a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])([a-zA-Z]|\\d|-|\\.|_|~|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])*([a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])))\\.?$") rxEmail = regexp.MustCompile("^(((([a-zA-Z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])+(\\.([a-zA-Z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])+)*)|((\\x22)((((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(([\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(\\([\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}]))))*(((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(\\x22)))@((([a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(([a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])([a-zA-Z]|\\d|-|\\.|_|~|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])*([a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])))\\.)+(([a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(([a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])([a-zA-Z]|\\d|-|\\.|_|~|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])*([a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])))\\.?$")
// Regex credit: https://www.socketloop.com/tutorials/golang-validate-hostname // Regex credit: https://www.socketloop.com/tutorials/golang-validate-hostname
rxHostname = regexp.MustCompile(`^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$`) rxHostname = regexp.MustCompile(`^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]))*$`)
rxUUID = regexp.MustCompile("^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$") rxUUID = regexp.MustCompile("^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$")
) )
@ -132,13 +137,13 @@ func (f EmailFormatChecker) IsFormat(input string) bool {
// Credit: https://github.com/asaskevich/govalidator // Credit: https://github.com/asaskevich/govalidator
func (f IPV4FormatChecker) IsFormat(input string) bool { func (f IPV4FormatChecker) IsFormat(input string) bool {
ip := net.ParseIP(input) ip := net.ParseIP(input)
return ip != nil && ip.To4() != nil return ip != nil && strings.Contains(input, ".")
} }
// Credit: https://github.com/asaskevich/govalidator // Credit: https://github.com/asaskevich/govalidator
func (f IPV6FormatChecker) IsFormat(input string) bool { func (f IPV6FormatChecker) IsFormat(input string) bool {
ip := net.ParseIP(input) ip := net.ParseIP(input)
return ip != nil && ip.To4() == nil return ip != nil && strings.Contains(input, ":")
} }
func (f DateTimeFormatChecker) IsFormat(input string) bool { func (f DateTimeFormatChecker) IsFormat(input string) bool {
@ -169,9 +174,21 @@ func (f URIFormatChecker) IsFormat(input string) bool {
} }
func (f HostnameFormatChecker) IsFormat(input string) bool { func (f HostnameFormatChecker) IsFormat(input string) bool {
return rxHostname.MatchString(input) return rxHostname.MatchString(input) && len(input) < 256
} }
func (f UUIDFormatChecker) IsFormat(input string) bool { func (f UUIDFormatChecker) IsFormat(input string) bool {
return rxUUID.MatchString(input) return rxUUID.MatchString(input)
} }
// IsFormat implements FormatChecker interface.
func (f RegexFormatChecker) IsFormat(input string) bool {
if input == "" {
return true
}
_, err := regexp.Compile(input)
if err != nil {
return false
}
return true
}

View File

@ -33,6 +33,7 @@ import (
"io" "io"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"os"
"path/filepath" "path/filepath"
"runtime" "runtime"
"strings" "strings"
@ -40,34 +41,92 @@ import (
"github.com/xeipuuv/gojsonreference" "github.com/xeipuuv/gojsonreference"
) )
var osFS = osFileSystem(os.Open)
// JSON loader interface // JSON loader interface
type JSONLoader interface { type JSONLoader interface {
jsonSource() interface{} JsonSource() interface{}
loadJSON() (interface{}, error) LoadJSON() (interface{}, error)
loadSchema() (*Schema, error) JsonReference() (gojsonreference.JsonReference, error)
LoaderFactory() JSONLoaderFactory
}
type JSONLoaderFactory interface {
New(source string) JSONLoader
}
type DefaultJSONLoaderFactory struct {
}
type FileSystemJSONLoaderFactory struct {
fs http.FileSystem
}
func (d DefaultJSONLoaderFactory) New(source string) JSONLoader {
return &jsonReferenceLoader{
fs: osFS,
source: source,
}
}
func (f FileSystemJSONLoaderFactory) New(source string) JSONLoader {
return &jsonReferenceLoader{
fs: f.fs,
source: source,
}
}
// osFileSystem is a functional wrapper for os.Open that implements http.FileSystem.
type osFileSystem func(string) (*os.File, error)
func (o osFileSystem) Open(name string) (http.File, error) {
return o(name)
} }
// JSON Reference loader // JSON Reference loader
// references are used to load JSONs from files and HTTP // references are used to load JSONs from files and HTTP
type jsonReferenceLoader struct { type jsonReferenceLoader struct {
fs http.FileSystem
source string source string
} }
func (l *jsonReferenceLoader) jsonSource() interface{} { func (l *jsonReferenceLoader) JsonSource() interface{} {
return l.source return l.source
} }
func NewReferenceLoader(source string) *jsonReferenceLoader { func (l *jsonReferenceLoader) JsonReference() (gojsonreference.JsonReference, error) {
return &jsonReferenceLoader{source: source} return gojsonreference.NewJsonReference(l.JsonSource().(string))
} }
func (l *jsonReferenceLoader) loadJSON() (interface{}, error) { func (l *jsonReferenceLoader) LoaderFactory() JSONLoaderFactory {
return &FileSystemJSONLoaderFactory{
fs: l.fs,
}
}
// NewReferenceLoader returns a JSON reference loader using the given source and the local OS file system.
func NewReferenceLoader(source string) *jsonReferenceLoader {
return &jsonReferenceLoader{
fs: osFS,
source: source,
}
}
// NewReferenceLoaderFileSystem returns a JSON reference loader using the given source and file system.
func NewReferenceLoaderFileSystem(source string, fs http.FileSystem) *jsonReferenceLoader {
return &jsonReferenceLoader{
fs: fs,
source: source,
}
}
func (l *jsonReferenceLoader) LoadJSON() (interface{}, error) {
var err error var err error
reference, err := gojsonreference.NewJsonReference(l.jsonSource().(string)) reference, err := gojsonreference.NewJsonReference(l.JsonSource().(string))
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -79,7 +138,7 @@ func (l *jsonReferenceLoader) loadJSON() (interface{}, error) {
if reference.HasFileScheme { if reference.HasFileScheme {
filename := strings.Replace(refToUrl.String(), "file://", "", -1) filename := strings.Replace(refToUrl.GetUrl().Path, "file://", "", -1)
if runtime.GOOS == "windows" { if runtime.GOOS == "windows" {
// on Windows, a file URL may have an extra leading slash, use slashes // on Windows, a file URL may have an extra leading slash, use slashes
// instead of backslashes, and have spaces escaped // instead of backslashes, and have spaces escaped
@ -87,7 +146,6 @@ func (l *jsonReferenceLoader) loadJSON() (interface{}, error) {
filename = filename[1:] filename = filename[1:]
} }
filename = filepath.FromSlash(filename) filename = filepath.FromSlash(filename)
filename = strings.Replace(filename, "%20", " ", -1)
} }
document, err = l.loadFromFile(filename) document, err = l.loadFromFile(filename)
@ -108,33 +166,6 @@ func (l *jsonReferenceLoader) loadJSON() (interface{}, error) {
} }
func (l *jsonReferenceLoader) loadSchema() (*Schema, error) {
var err error
d := Schema{}
d.pool = newSchemaPool()
d.referencePool = newSchemaReferencePool()
d.documentReference, err = gojsonreference.NewJsonReference(l.jsonSource().(string))
if err != nil {
return nil, err
}
spd, err := d.pool.GetDocument(d.documentReference)
if err != nil {
return nil, err
}
err = d.parse(spd.Document)
if err != nil {
return nil, err
}
return &d, nil
}
func (l *jsonReferenceLoader) loadFromHTTP(address string) (interface{}, error) { func (l *jsonReferenceLoader) loadFromHTTP(address string) (interface{}, error) {
resp, err := http.Get(address) resp, err := http.Get(address)
@ -157,8 +188,13 @@ func (l *jsonReferenceLoader) loadFromHTTP(address string) (interface{}, error)
} }
func (l *jsonReferenceLoader) loadFromFile(path string) (interface{}, error) { func (l *jsonReferenceLoader) loadFromFile(path string) (interface{}, error) {
f, err := l.fs.Open(path)
if err != nil {
return nil, err
}
defer f.Close()
bodyBuff, err := ioutil.ReadFile(path) bodyBuff, err := ioutil.ReadAll(f)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -173,45 +209,52 @@ type jsonStringLoader struct {
source string source string
} }
func (l *jsonStringLoader) jsonSource() interface{} { func (l *jsonStringLoader) JsonSource() interface{} {
return l.source return l.source
} }
func (l *jsonStringLoader) JsonReference() (gojsonreference.JsonReference, error) {
return gojsonreference.NewJsonReference("#")
}
func (l *jsonStringLoader) LoaderFactory() JSONLoaderFactory {
return &DefaultJSONLoaderFactory{}
}
func NewStringLoader(source string) *jsonStringLoader { func NewStringLoader(source string) *jsonStringLoader {
return &jsonStringLoader{source: source} return &jsonStringLoader{source: source}
} }
func (l *jsonStringLoader) loadJSON() (interface{}, error) { func (l *jsonStringLoader) LoadJSON() (interface{}, error) {
return decodeJsonUsingNumber(strings.NewReader(l.jsonSource().(string))) return decodeJsonUsingNumber(strings.NewReader(l.JsonSource().(string)))
} }
func (l *jsonStringLoader) loadSchema() (*Schema, error) { // JSON bytes loader
var err error type jsonBytesLoader struct {
source []byte
}
document, err := l.loadJSON() func (l *jsonBytesLoader) JsonSource() interface{} {
if err != nil { return l.source
return nil, err }
}
d := Schema{} func (l *jsonBytesLoader) JsonReference() (gojsonreference.JsonReference, error) {
d.pool = newSchemaPool() return gojsonreference.NewJsonReference("#")
d.referencePool = newSchemaReferencePool() }
d.documentReference, err = gojsonreference.NewJsonReference("#")
d.pool.SetStandaloneDocument(document)
if err != nil {
return nil, err
}
err = d.parse(document) func (l *jsonBytesLoader) LoaderFactory() JSONLoaderFactory {
if err != nil { return &DefaultJSONLoaderFactory{}
return nil, err }
}
return &d, nil func NewBytesLoader(source []byte) *jsonBytesLoader {
return &jsonBytesLoader{source: source}
}
func (l *jsonBytesLoader) LoadJSON() (interface{}, error) {
return decodeJsonUsingNumber(bytes.NewReader(l.JsonSource().([]byte)))
} }
// JSON Go (types) loader // JSON Go (types) loader
@ -221,19 +264,27 @@ type jsonGoLoader struct {
source interface{} source interface{}
} }
func (l *jsonGoLoader) jsonSource() interface{} { func (l *jsonGoLoader) JsonSource() interface{} {
return l.source return l.source
} }
func (l *jsonGoLoader) JsonReference() (gojsonreference.JsonReference, error) {
return gojsonreference.NewJsonReference("#")
}
func (l *jsonGoLoader) LoaderFactory() JSONLoaderFactory {
return &DefaultJSONLoaderFactory{}
}
func NewGoLoader(source interface{}) *jsonGoLoader { func NewGoLoader(source interface{}) *jsonGoLoader {
return &jsonGoLoader{source: source} return &jsonGoLoader{source: source}
} }
func (l *jsonGoLoader) loadJSON() (interface{}, error) { func (l *jsonGoLoader) LoadJSON() (interface{}, error) {
// convert it to a compliant JSON first to avoid types "mismatches" // convert it to a compliant JSON first to avoid types "mismatches"
jsonBytes, err := json.Marshal(l.jsonSource()) jsonBytes, err := json.Marshal(l.JsonSource())
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -242,33 +293,6 @@ func (l *jsonGoLoader) loadJSON() (interface{}, error) {
} }
func (l *jsonGoLoader) loadSchema() (*Schema, error) {
var err error
document, err := l.loadJSON()
if err != nil {
return nil, err
}
d := Schema{}
d.pool = newSchemaPool()
d.referencePool = newSchemaReferencePool()
d.documentReference, err = gojsonreference.NewJsonReference("#")
d.pool.SetStandaloneDocument(document)
if err != nil {
return nil, err
}
err = d.parse(document)
if err != nil {
return nil, err
}
return &d, nil
}
func decodeJsonUsingNumber(r io.Reader) (interface{}, error) { func decodeJsonUsingNumber(r io.Reader) (interface{}, error) {
var document interface{} var document interface{}

View File

@ -37,6 +37,7 @@ type (
MissingDependency() string MissingDependency() string
Internal() string Internal() string
Enum() string Enum() string
ArrayNotEnoughItems() string
ArrayNoAdditionalItems() string ArrayNoAdditionalItems() string
ArrayMinItems() string ArrayMinItems() string
ArrayMaxItems() string ArrayMaxItems() string
@ -83,11 +84,11 @@ type (
) )
func (l DefaultLocale) Required() string { func (l DefaultLocale) Required() string {
return `%property% is required` return `{{.property}} is required`
} }
func (l DefaultLocale) InvalidType() string { func (l DefaultLocale) InvalidType() string {
return `Invalid type. Expected: %expected%, given: %given%` return `Invalid type. Expected: {{.expected}}, given: {{.given}}`
} }
func (l DefaultLocale) NumberAnyOf() string { func (l DefaultLocale) NumberAnyOf() string {
@ -107,157 +108,161 @@ func (l DefaultLocale) NumberNot() string {
} }
func (l DefaultLocale) MissingDependency() string { func (l DefaultLocale) MissingDependency() string {
return `Has a dependency on %dependency%` return `Has a dependency on {{.dependency}}`
} }
func (l DefaultLocale) Internal() string { func (l DefaultLocale) Internal() string {
return `Internal Error %error%` return `Internal Error {{.error}}`
} }
func (l DefaultLocale) Enum() string { func (l DefaultLocale) Enum() string {
return `%field% must be one of the following: %allowed%` return `{{.field}} must be one of the following: {{.allowed}}`
} }
func (l DefaultLocale) ArrayNoAdditionalItems() string { func (l DefaultLocale) ArrayNoAdditionalItems() string {
return `No additional items allowed on array` return `No additional items allowed on array`
} }
func (l DefaultLocale) ArrayNotEnoughItems() string {
return `Not enough items on array to match positional list of schema`
}
func (l DefaultLocale) ArrayMinItems() string { func (l DefaultLocale) ArrayMinItems() string {
return `Array must have at least %min% items` return `Array must have at least {{.min}} items`
} }
func (l DefaultLocale) ArrayMaxItems() string { func (l DefaultLocale) ArrayMaxItems() string {
return `Array must have at most %max% items` return `Array must have at most {{.max}} items`
} }
func (l DefaultLocale) Unique() string { func (l DefaultLocale) Unique() string {
return `%type% items must be unique` return `{{.type}} items must be unique`
} }
func (l DefaultLocale) ArrayMinProperties() string { func (l DefaultLocale) ArrayMinProperties() string {
return `Must have at least %min% properties` return `Must have at least {{.min}} properties`
} }
func (l DefaultLocale) ArrayMaxProperties() string { func (l DefaultLocale) ArrayMaxProperties() string {
return `Must have at most %max% properties` return `Must have at most {{.max}} properties`
} }
func (l DefaultLocale) AdditionalPropertyNotAllowed() string { func (l DefaultLocale) AdditionalPropertyNotAllowed() string {
return `Additional property %property% is not allowed` return `Additional property {{.property}} is not allowed`
} }
func (l DefaultLocale) InvalidPropertyPattern() string { func (l DefaultLocale) InvalidPropertyPattern() string {
return `Property "%property%" does not match pattern %pattern%` return `Property "{{.property}}" does not match pattern {{.pattern}}`
} }
func (l DefaultLocale) StringGTE() string { func (l DefaultLocale) StringGTE() string {
return `String length must be greater than or equal to %min%` return `String length must be greater than or equal to {{.min}}`
} }
func (l DefaultLocale) StringLTE() string { func (l DefaultLocale) StringLTE() string {
return `String length must be less than or equal to %max%` return `String length must be less than or equal to {{.max}}`
} }
func (l DefaultLocale) DoesNotMatchPattern() string { func (l DefaultLocale) DoesNotMatchPattern() string {
return `Does not match pattern '%pattern%'` return `Does not match pattern '{{.pattern}}'`
} }
func (l DefaultLocale) DoesNotMatchFormat() string { func (l DefaultLocale) DoesNotMatchFormat() string {
return `Does not match format '%format%'` return `Does not match format '{{.format}}'`
} }
func (l DefaultLocale) MultipleOf() string { func (l DefaultLocale) MultipleOf() string {
return `Must be a multiple of %multiple%` return `Must be a multiple of {{.multiple}}`
} }
func (l DefaultLocale) NumberGTE() string { func (l DefaultLocale) NumberGTE() string {
return `Must be greater than or equal to %min%` return `Must be greater than or equal to {{.min}}`
} }
func (l DefaultLocale) NumberGT() string { func (l DefaultLocale) NumberGT() string {
return `Must be greater than %min%` return `Must be greater than {{.min}}`
} }
func (l DefaultLocale) NumberLTE() string { func (l DefaultLocale) NumberLTE() string {
return `Must be less than or equal to %max%` return `Must be less than or equal to {{.max}}`
} }
func (l DefaultLocale) NumberLT() string { func (l DefaultLocale) NumberLT() string {
return `Must be less than %max%` return `Must be less than {{.max}}`
} }
// Schema validators // Schema validators
func (l DefaultLocale) RegexPattern() string { func (l DefaultLocale) RegexPattern() string {
return `Invalid regex pattern '%pattern%'` return `Invalid regex pattern '{{.pattern}}'`
} }
func (l DefaultLocale) GreaterThanZero() string { func (l DefaultLocale) GreaterThanZero() string {
return `%number% must be strictly greater than 0` return `{{.number}} must be strictly greater than 0`
} }
func (l DefaultLocale) MustBeOfA() string { func (l DefaultLocale) MustBeOfA() string {
return `%x% must be of a %y%` return `{{.x}} must be of a {{.y}}`
} }
func (l DefaultLocale) MustBeOfAn() string { func (l DefaultLocale) MustBeOfAn() string {
return `%x% must be of an %y%` return `{{.x}} must be of an {{.y}}`
} }
func (l DefaultLocale) CannotBeUsedWithout() string { func (l DefaultLocale) CannotBeUsedWithout() string {
return `%x% cannot be used without %y%` return `{{.x}} cannot be used without {{.y}}`
} }
func (l DefaultLocale) CannotBeGT() string { func (l DefaultLocale) CannotBeGT() string {
return `%x% cannot be greater than %y%` return `{{.x}} cannot be greater than {{.y}}`
} }
func (l DefaultLocale) MustBeOfType() string { func (l DefaultLocale) MustBeOfType() string {
return `%key% must be of type %type%` return `{{.key}} must be of type {{.type}}`
} }
func (l DefaultLocale) MustBeValidRegex() string { func (l DefaultLocale) MustBeValidRegex() string {
return `%key% must be a valid regex` return `{{.key}} must be a valid regex`
} }
func (l DefaultLocale) MustBeValidFormat() string { func (l DefaultLocale) MustBeValidFormat() string {
return `%key% must be a valid format %given%` return `{{.key}} must be a valid format {{.given}}`
} }
func (l DefaultLocale) MustBeGTEZero() string { func (l DefaultLocale) MustBeGTEZero() string {
return `%key% must be greater than or equal to 0` return `{{.key}} must be greater than or equal to 0`
} }
func (l DefaultLocale) KeyCannotBeGreaterThan() string { func (l DefaultLocale) KeyCannotBeGreaterThan() string {
return `%key% cannot be greater than %y%` return `{{.key}} cannot be greater than {{.y}}`
} }
func (l DefaultLocale) KeyItemsMustBeOfType() string { func (l DefaultLocale) KeyItemsMustBeOfType() string {
return `%key% items must be %type%` return `{{.key}} items must be {{.type}}`
} }
func (l DefaultLocale) KeyItemsMustBeUnique() string { func (l DefaultLocale) KeyItemsMustBeUnique() string {
return `%key% items must be unique` return `{{.key}} items must be unique`
} }
func (l DefaultLocale) ReferenceMustBeCanonical() string { func (l DefaultLocale) ReferenceMustBeCanonical() string {
return `Reference %reference% must be canonical` return `Reference {{.reference}} must be canonical`
} }
func (l DefaultLocale) NotAValidType() string { func (l DefaultLocale) NotAValidType() string {
return `%type% is not a valid type -- ` return `{{.type}} is not a valid type -- `
} }
func (l DefaultLocale) Duplicated() string { func (l DefaultLocale) Duplicated() string {
return `%type% type is duplicated` return `{{.type}} type is duplicated`
} }
func (l DefaultLocale) httpBadStatus() string { func (l DefaultLocale) httpBadStatus() string {
return `Could not read schema from HTTP, response status is %status%` return `Could not read schema from HTTP, response status is {{.status}}`
} }
// Replacement options: field, description, context, value // Replacement options: field, description, context, value
func (l DefaultLocale) ErrorFormat() string { func (l DefaultLocale) ErrorFormat() string {
return `%field%: %description%` return `{{.field}}: {{.description}}`
} }
const ( const (

View File

@ -48,6 +48,7 @@ type (
Value() interface{} Value() interface{}
SetDetails(ErrorDetails) SetDetails(ErrorDetails)
Details() ErrorDetails Details() ErrorDetails
String() string
} }
// ResultErrorFields holds the fields for each ResultError implementation. // ResultErrorFields holds the fields for each ResultError implementation.
@ -126,7 +127,7 @@ func (v ResultErrorFields) String() string {
valueString := fmt.Sprintf("%v", v.value) valueString := fmt.Sprintf("%v", v.value)
// marshal the go value value to json // marshal the go value value to json
if v.Value == nil { if v.value == nil {
valueString = TYPE_NULL valueString = TYPE_NULL
} else { } else {
if vs, err := marshalToJsonString(v.value); err == nil { if vs, err := marshalToJsonString(v.value); err == nil {

View File

@ -42,7 +42,39 @@ var (
) )
func NewSchema(l JSONLoader) (*Schema, error) { func NewSchema(l JSONLoader) (*Schema, error) {
return l.loadSchema() ref, err := l.JsonReference()
if err != nil {
return nil, err
}
d := Schema{}
d.pool = newSchemaPool(l.LoaderFactory())
d.documentReference = ref
d.referencePool = newSchemaReferencePool()
var doc interface{}
if ref.String() != "" {
// Get document from schema pool
spd, err := d.pool.GetDocument(d.documentReference)
if err != nil {
return nil, err
}
doc = spd.Document
} else {
// Load JSON directly
doc, err = l.LoadJSON()
if err != nil {
return nil, err
}
d.pool.SetStandaloneDocument(doc)
}
err = d.parse(doc)
if err != nil {
return nil, err
}
return &d, nil
} }
type Schema struct { type Schema struct {
@ -116,14 +148,27 @@ func (d *Schema) parseSchema(documentNode interface{}, currentSchema *subSchema)
} }
if k, ok := m[KEY_REF].(string); ok { if k, ok := m[KEY_REF].(string); ok {
if sch, ok := d.referencePool.Get(currentSchema.ref.String() + k); ok { jsonReference, err := gojsonreference.NewJsonReference(k)
if err != nil {
return err
}
if jsonReference.HasFullUrl {
currentSchema.ref = &jsonReference
} else {
inheritedReference, err := currentSchema.ref.Inherits(jsonReference)
if err != nil {
return err
}
currentSchema.ref = inheritedReference
}
if sch, ok := d.referencePool.Get(currentSchema.ref.String() + k); ok {
currentSchema.refSchema = sch currentSchema.refSchema = sch
} else { } else {
err := d.parseReference(documentNode, currentSchema, k)
var err error
err = d.parseReference(documentNode, currentSchema, k)
if err != nil { if err != nil {
return err return err
} }
@ -755,30 +800,10 @@ func (d *Schema) parseSchema(documentNode interface{}, currentSchema *subSchema)
return nil return nil
} }
func (d *Schema) parseReference(documentNode interface{}, currentSchema *subSchema, reference string) (e error) { func (d *Schema) parseReference(documentNode interface{}, currentSchema *subSchema, reference string) error {
var err error
jsonReference, err := gojsonreference.NewJsonReference(reference)
if err != nil {
return err
}
standaloneDocument := d.pool.GetStandaloneDocument()
if jsonReference.HasFullUrl {
currentSchema.ref = &jsonReference
} else {
inheritedReference, err := currentSchema.ref.Inherits(jsonReference)
if err != nil {
return err
}
currentSchema.ref = inheritedReference
}
jsonPointer := currentSchema.ref.GetPointer()
var refdDocumentNode interface{} var refdDocumentNode interface{}
jsonPointer := currentSchema.ref.GetPointer()
standaloneDocument := d.pool.GetStandaloneDocument()
if standaloneDocument != nil { if standaloneDocument != nil {
@ -789,8 +814,6 @@ func (d *Schema) parseReference(documentNode interface{}, currentSchema *subSche
} }
} else { } else {
var err error
dsp, err := d.pool.GetDocument(*currentSchema.ref) dsp, err := d.pool.GetDocument(*currentSchema.ref)
if err != nil { if err != nil {
return err return err
@ -812,11 +835,10 @@ func (d *Schema) parseReference(documentNode interface{}, currentSchema *subSche
// returns the loaded referenced subSchema for the caller to update its current subSchema // returns the loaded referenced subSchema for the caller to update its current subSchema
newSchemaDocument := refdDocumentNode.(map[string]interface{}) newSchemaDocument := refdDocumentNode.(map[string]interface{})
newSchema := &subSchema{property: KEY_REF, parent: currentSchema, ref: currentSchema.ref} newSchema := &subSchema{property: KEY_REF, parent: currentSchema, ref: currentSchema.ref}
d.referencePool.Add(currentSchema.ref.String()+reference, newSchema) d.referencePool.Add(currentSchema.ref.String()+reference, newSchema)
err = d.parseSchema(newSchemaDocument, newSchema) err := d.parseSchema(newSchemaDocument, newSchema)
if err != nil { if err != nil {
return err return err
} }

View File

@ -39,13 +39,15 @@ type schemaPoolDocument struct {
type schemaPool struct { type schemaPool struct {
schemaPoolDocuments map[string]*schemaPoolDocument schemaPoolDocuments map[string]*schemaPoolDocument
standaloneDocument interface{} standaloneDocument interface{}
jsonLoaderFactory JSONLoaderFactory
} }
func newSchemaPool() *schemaPool { func newSchemaPool(f JSONLoaderFactory) *schemaPool {
p := &schemaPool{} p := &schemaPool{}
p.schemaPoolDocuments = make(map[string]*schemaPoolDocument) p.schemaPoolDocuments = make(map[string]*schemaPoolDocument)
p.standaloneDocument = nil p.standaloneDocument = nil
p.jsonLoaderFactory = f
return p return p
} }
@ -93,8 +95,8 @@ func (p *schemaPool) GetDocument(reference gojsonreference.JsonReference) (*sche
return spd, nil return spd, nil
} }
jsonReferenceLoader := NewReferenceLoader(reference.String()) jsonReferenceLoader := p.jsonLoaderFactory.New(reference.String())
document, err := jsonReferenceLoader.loadJSON() document, err := jsonReferenceLoader.LoadJSON()
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -214,7 +214,7 @@ func (s *subSchema) PatternPropertiesString() string {
} }
patternPropertiesKeySlice := []string{} patternPropertiesKeySlice := []string{}
for pk, _ := range s.patternProperties { for pk := range s.patternProperties {
patternPropertiesKeySlice = append(patternPropertiesKeySlice, `"`+pk+`"`) patternPropertiesKeySlice = append(patternPropertiesKeySlice, `"`+pk+`"`)
} }

View File

@ -34,7 +34,12 @@ import (
) )
func isKind(what interface{}, kind reflect.Kind) bool { func isKind(what interface{}, kind reflect.Kind) bool {
return reflect.ValueOf(what).Kind() == kind target := what
if isJsonNumber(what) {
// JSON Numbers are strings!
target = *mustBeNumber(what)
}
return reflect.ValueOf(target).Kind() == kind
} }
func existsMapKey(m map[string]interface{}, k string) bool { func existsMapKey(m map[string]interface{}, k string) bool {
@ -77,13 +82,14 @@ func checkJsonNumber(what interface{}) (isValidFloat64 bool, isValidInt64 bool,
jsonNumber := what.(json.Number) jsonNumber := what.(json.Number)
_, errFloat64 := jsonNumber.Float64() f64, errFloat64 := jsonNumber.Float64()
_, errInt64 := jsonNumber.Int64() s64 := strconv.FormatFloat(f64, 'f', -1, 64)
_, errInt64 := strconv.ParseInt(s64, 10, 64)
isValidFloat64 = errFloat64 == nil isValidFloat64 = errFloat64 == nil
isValidInt64 = errInt64 == nil isValidInt64 = errInt64 == nil
_, errInt32 := strconv.ParseInt(jsonNumber.String(), 10, 32) _, errInt32 := strconv.ParseInt(s64, 10, 32)
isValidInt32 = isValidInt64 && errInt32 == nil isValidInt32 = isValidInt64 && errInt32 == nil
return return

View File

@ -55,7 +55,7 @@ func (v *Schema) Validate(l JSONLoader) (*Result, error) {
// load document // load document
root, err := l.loadJSON() root, err := l.LoadJSON()
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -412,7 +412,7 @@ func (v *subSchema) validateArray(currentSubSchema *subSchema, value []interface
internalLog(" %v", value) internalLog(" %v", value)
} }
nbItems := len(value) nbValues := len(value)
// TODO explain // TODO explain
if currentSubSchema.itemsChildrenIsSingleSchema { if currentSubSchema.itemsChildrenIsSingleSchema {
@ -425,15 +425,18 @@ func (v *subSchema) validateArray(currentSubSchema *subSchema, value []interface
if currentSubSchema.itemsChildren != nil && len(currentSubSchema.itemsChildren) > 0 { if currentSubSchema.itemsChildren != nil && len(currentSubSchema.itemsChildren) > 0 {
nbItems := len(currentSubSchema.itemsChildren) nbItems := len(currentSubSchema.itemsChildren)
nbValues := len(value)
if nbItems == nbValues { // while we have both schemas and values, check them against each other
for i := 0; i != nbItems; i++ { for i := 0; i != nbItems && i != nbValues; i++ {
subContext := newJsonContext(strconv.Itoa(i), context) subContext := newJsonContext(strconv.Itoa(i), context)
validationResult := currentSubSchema.itemsChildren[i].subValidateWithContext(value[i], subContext) validationResult := currentSubSchema.itemsChildren[i].subValidateWithContext(value[i], subContext)
result.mergeErrors(validationResult) result.mergeErrors(validationResult)
} }
} else if nbItems < nbValues {
if nbItems < nbValues {
// we have less schemas than elements in the instance array,
// but that might be ok if "additionalItems" is specified.
switch currentSubSchema.additionalItems.(type) { switch currentSubSchema.additionalItems.(type) {
case bool: case bool:
if !currentSubSchema.additionalItems.(bool) { if !currentSubSchema.additionalItems.(bool) {
@ -453,7 +456,7 @@ func (v *subSchema) validateArray(currentSubSchema *subSchema, value []interface
// minItems & maxItems // minItems & maxItems
if currentSubSchema.minItems != nil { if currentSubSchema.minItems != nil {
if nbItems < int(*currentSubSchema.minItems) { if nbValues < int(*currentSubSchema.minItems) {
result.addError( result.addError(
new(ArrayMinItemsError), new(ArrayMinItemsError),
context, context,
@ -463,7 +466,7 @@ func (v *subSchema) validateArray(currentSubSchema *subSchema, value []interface
} }
} }
if currentSubSchema.maxItems != nil { if currentSubSchema.maxItems != nil {
if nbItems > int(*currentSubSchema.maxItems) { if nbValues > int(*currentSubSchema.maxItems) {
result.addError( result.addError(
new(ArrayMaxItemsError), new(ArrayMaxItemsError),
context, context,
@ -776,22 +779,22 @@ func (v *subSchema) validateNumber(currentSubSchema *subSchema, value interface{
if currentSubSchema.exclusiveMaximum { if currentSubSchema.exclusiveMaximum {
if float64Value >= *currentSubSchema.maximum { if float64Value >= *currentSubSchema.maximum {
result.addError( result.addError(
new(NumberLTEError), new(NumberLTError),
context, context,
resultErrorFormatJsonNumber(number), resultErrorFormatJsonNumber(number),
ErrorDetails{ ErrorDetails{
"min": resultErrorFormatNumber(*currentSubSchema.maximum), "max": resultErrorFormatNumber(*currentSubSchema.maximum),
}, },
) )
} }
} else { } else {
if float64Value > *currentSubSchema.maximum { if float64Value > *currentSubSchema.maximum {
result.addError( result.addError(
new(NumberLTError), new(NumberLTEError),
context, context,
resultErrorFormatJsonNumber(number), resultErrorFormatJsonNumber(number),
ErrorDetails{ ErrorDetails{
"min": resultErrorFormatNumber(*currentSubSchema.maximum), "max": resultErrorFormatNumber(*currentSubSchema.maximum),
}, },
) )
} }
@ -803,22 +806,22 @@ func (v *subSchema) validateNumber(currentSubSchema *subSchema, value interface{
if currentSubSchema.exclusiveMinimum { if currentSubSchema.exclusiveMinimum {
if float64Value <= *currentSubSchema.minimum { if float64Value <= *currentSubSchema.minimum {
result.addError( result.addError(
new(NumberGTEError), new(NumberGTError),
context, context,
resultErrorFormatJsonNumber(number), resultErrorFormatJsonNumber(number),
ErrorDetails{ ErrorDetails{
"max": resultErrorFormatNumber(*currentSubSchema.minimum), "min": resultErrorFormatNumber(*currentSubSchema.minimum),
}, },
) )
} }
} else { } else {
if float64Value < *currentSubSchema.minimum { if float64Value < *currentSubSchema.minimum {
result.addError( result.addError(
new(NumberGTError), new(NumberGTEError),
context, context,
resultErrorFormatJsonNumber(number), resultErrorFormatJsonNumber(number),
ErrorDetails{ ErrorDetails{
"max": resultErrorFormatNumber(*currentSubSchema.minimum), "min": resultErrorFormatNumber(*currentSubSchema.minimum),
}, },
) )
} }

View File

@ -1,29 +1,28 @@
// Copyright 2009 The Go Authors. All rights reserved. // Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build linux
// +build mips64 mips64le
// +build !gccgo // +build !gccgo
#include "textflag.h" #include "textflag.h"
// //
// System call support for 386, FreeBSD // System calls for mips64, Linux
// //
// 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-32 TEXT ·Syscall(SB),NOSPLIT,$0-56
JMP syscall·Syscall(SB) JMP syscall·Syscall(SB)
TEXT ·Syscall6(SB),NOSPLIT,$0-44 TEXT ·Syscall6(SB),NOSPLIT,$0-80
JMP syscall·Syscall6(SB) JMP syscall·Syscall6(SB)
TEXT ·Syscall9(SB),NOSPLIT,$0-56 TEXT ·RawSyscall(SB),NOSPLIT,$0-56
JMP syscall·Syscall9(SB)
TEXT ·RawSyscall(SB),NOSPLIT,$0-32
JMP syscall·RawSyscall(SB) JMP syscall·RawSyscall(SB)
TEXT ·RawSyscall6(SB),NOSPLIT,$0-44 TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
JMP syscall·RawSyscall6(SB) JMP syscall·RawSyscall6(SB)

31
vendor/golang.org/x/sys/unix/asm_linux_mipsx.s generated vendored Normal file
View File

@ -0,0 +1,31 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build linux
// +build mips mipsle
// +build !gccgo
#include "textflag.h"
//
// System calls for mips, Linux
//
// Just jump to package syscall's implementation for all these functions.
// The runtime may know about them.
TEXT ·Syscall(SB),NOSPLIT,$0-28
JMP syscall·Syscall(SB)
TEXT ·Syscall6(SB),NOSPLIT,$0-40
JMP syscall·Syscall6(SB)
TEXT ·Syscall9(SB),NOSPLIT,$0-52
JMP syscall·Syscall9(SB)
TEXT ·RawSyscall(SB),NOSPLIT,$0-28
JMP syscall·RawSyscall(SB)
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
JMP syscall·RawSyscall6(SB)

28
vendor/golang.org/x/sys/unix/asm_linux_s390x.s generated vendored Normal file
View File

@ -0,0 +1,28 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build s390x
// +build linux
// +build !gccgo
#include "textflag.h"
//
// System calls for s390x, Linux
//
// Just jump to package syscall's implementation for all these functions.
// The runtime may know about them.
TEXT ·Syscall(SB),NOSPLIT,$0-56
BR syscall·Syscall(SB)
TEXT ·Syscall6(SB),NOSPLIT,$0-80
BR syscall·Syscall6(SB)
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
BR syscall·RawSyscall(SB)
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
BR syscall·RawSyscall6(SB)

35
vendor/golang.org/x/sys/unix/bluetooth_linux.go generated vendored Normal file
View File

@ -0,0 +1,35 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Bluetooth sockets and messages
package unix
// Bluetooth Protocols
const (
BTPROTO_L2CAP = 0
BTPROTO_HCI = 1
BTPROTO_SCO = 2
BTPROTO_RFCOMM = 3
BTPROTO_BNEP = 4
BTPROTO_CMTP = 5
BTPROTO_HIDP = 6
BTPROTO_AVDTP = 7
)
const (
HCI_CHANNEL_RAW = 0
HCI_CHANNEL_USER = 1
HCI_CHANNEL_MONITOR = 2
HCI_CHANNEL_CONTROL = 3
)
// Socketoption Level
const (
SOL_BLUETOOTH = 0x112
SOL_HCI = 0x0
SOL_L2CAP = 0x6
SOL_RFCOMM = 0x12
SOL_SCO = 0x11
)

View File

@ -1,4 +1,4 @@
// +build linux,386 linux,arm // +build linux,386 linux,arm linux,mips linux,mipsle
// Copyright 2014 The Go Authors. All rights reserved. // Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style

20
vendor/golang.org/x/sys/unix/gccgo_linux_sparc64.go generated vendored Normal file
View File

@ -0,0 +1,20 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build gccgo,linux,sparc64
package unix
import "syscall"
//extern sysconf
func realSysconf(name int) int64
func sysconf(name int) (n int64, err syscall.Errno) {
r := realSysconf(name)
if r < 0 {
return 0, syscall.GetErrno()
}
return r, 0
}

62
vendor/golang.org/x/sys/unix/mkpost.go generated vendored Normal file
View File

@ -0,0 +1,62 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build ignore
// mkpost processes the output of cgo -godefs to
// modify the generated types. It is used to clean up
// the sys API in an architecture specific manner.
//
// mkpost is run after cgo -godefs by mkall.sh.
package main
import (
"fmt"
"go/format"
"io/ioutil"
"log"
"os"
"regexp"
)
func main() {
b, err := ioutil.ReadAll(os.Stdin)
if err != nil {
log.Fatal(err)
}
s := string(b)
goarch := os.Getenv("GOARCH")
goos := os.Getenv("GOOS")
if goarch == "s390x" && goos == "linux" {
// Export the types of PtraceRegs fields.
re := regexp.MustCompile("ptrace(Psw|Fpregs|Per)")
s = re.ReplaceAllString(s, "Ptrace$1")
// Replace padding fields inserted by cgo with blank identifiers.
re = regexp.MustCompile("Pad_cgo[A-Za-z0-9_]*")
s = re.ReplaceAllString(s, "_")
// Replace other unwanted fields with blank identifiers.
re = regexp.MustCompile("X_[A-Za-z0-9_]*")
s = re.ReplaceAllString(s, "_")
// Replace the control_regs union with a blank identifier for now.
re = regexp.MustCompile("(Control_regs)\\s+\\[0\\]uint64")
s = re.ReplaceAllString(s, "_ [0]uint64")
}
// gofmt
b, err = format.Source([]byte(s))
if err != nil {
log.Fatal(err)
}
// Append this command to the header to show where the new file
// came from.
re := regexp.MustCompile("(cgo -godefs [a-zA-Z0-9_]+\\.go.*)")
b = re.ReplaceAll(b, []byte("$1 | go run mkpost.go"))
fmt.Printf("%s", b)
}

View File

@ -62,7 +62,7 @@ func ParseSocketControlMessage(b []byte) ([]SocketControlMessage, error) {
func socketControlMessageHeaderAndData(b []byte) (*Cmsghdr, []byte, error) { func socketControlMessageHeaderAndData(b []byte) (*Cmsghdr, []byte, error) {
h := (*Cmsghdr)(unsafe.Pointer(&b[0])) h := (*Cmsghdr)(unsafe.Pointer(&b[0]))
if h.Len < SizeofCmsghdr || int(h.Len) > len(b) { if h.Len < SizeofCmsghdr || uint64(h.Len) > uint64(len(b)) {
return nil, nil, EINVAL return nil, nil, EINVAL
} }
return h, b[cmsgAlignOf(SizeofCmsghdr):h.Len], nil return h, b[cmsgAlignOf(SizeofCmsghdr):h.Len], nil

View File

@ -68,6 +68,8 @@ func (tv *Timeval) Nano() int64 {
return int64(tv.Sec)*1e9 + int64(tv.Usec)*1000 return int64(tv.Sec)*1e9 + int64(tv.Usec)*1000
} }
func TimevalToNsec(tv Timeval) int64 { return int64(tv.Sec)*1e9 + int64(tv.Usec)*1e3 }
// use is a no-op, but the compiler cannot see that it is. // use is a no-op, but the compiler cannot see that it is.
// Calling use(p) ensures that p is kept live until that point. // Calling use(p) ensures that p is kept live until that point.
//go:noescape //go:noescape

View File

@ -470,25 +470,11 @@ func Sysctl(name string) (string, error) {
} }
func SysctlArgs(name string, args ...int) (string, error) { func SysctlArgs(name string, args ...int) (string, error) {
mib, err := sysctlmib(name, args...) buf, err := SysctlRaw(name, args...)
if err != nil { if err != nil {
return "", err return "", err
} }
n := len(buf)
// Find size.
n := uintptr(0)
if err := sysctl(mib, nil, &n, nil, 0); err != nil {
return "", err
}
if n == 0 {
return "", nil
}
// Read into buffer of that size.
buf := make([]byte, n)
if err := sysctl(mib, &buf[0], &n, nil, 0); err != nil {
return "", err
}
// Throw away terminating NUL. // Throw away terminating NUL.
if n > 0 && buf[n-1] == '\x00' { if n > 0 && buf[n-1] == '\x00' {

View File

@ -144,6 +144,7 @@ func getAttrList(path string, attrList attrList, attrBuf []byte, options uint) (
uintptr(options), uintptr(options),
0, 0,
) )
use(unsafe.Pointer(_p0))
if e1 != 0 { if e1 != 0 {
return nil, e1 return nil, e1
} }
@ -196,6 +197,7 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
bufsize = unsafe.Sizeof(Statfs_t{}) * uintptr(len(buf)) bufsize = unsafe.Sizeof(Statfs_t{}) * uintptr(len(buf))
} }
r0, _, e1 := Syscall(SYS_GETFSSTAT64, uintptr(_p0), bufsize, uintptr(flags)) r0, _, e1 := Syscall(SYS_GETFSSTAT64, uintptr(_p0), bufsize, uintptr(flags))
use(unsafe.Pointer(_p0))
n = int(r0) n = int(r0)
if e1 != 0 { if e1 != 0 {
err = e1 err = e1

View File

@ -21,8 +21,6 @@ func NsecToTimespec(nsec int64) (ts Timespec) {
return return
} }
func TimevalToNsec(tv Timeval) int64 { return int64(tv.Sec)*1e9 + int64(tv.Usec)*1e3 }
func NsecToTimeval(nsec int64) (tv Timeval) { func NsecToTimeval(nsec int64) (tv Timeval) {
nsec += 999 // round up to microsecond nsec += 999 // round up to microsecond
tv.Usec = int32(nsec % 1e9 / 1e3) tv.Usec = int32(nsec % 1e9 / 1e3)

View File

@ -23,8 +23,6 @@ func NsecToTimespec(nsec int64) (ts Timespec) {
return return
} }
func TimevalToNsec(tv Timeval) int64 { return int64(tv.Sec)*1e9 + int64(tv.Usec)*1e3 }
func NsecToTimeval(nsec int64) (tv Timeval) { func NsecToTimeval(nsec int64) (tv Timeval) {
nsec += 999 // round up to microsecond nsec += 999 // round up to microsecond
tv.Usec = int32(nsec % 1e9 / 1e3) tv.Usec = int32(nsec % 1e9 / 1e3)

View File

@ -19,8 +19,6 @@ func NsecToTimespec(nsec int64) (ts Timespec) {
return return
} }
func TimevalToNsec(tv Timeval) int64 { return int64(tv.Sec)*1e9 + int64(tv.Usec)*1e3 }
func NsecToTimeval(nsec int64) (tv Timeval) { func NsecToTimeval(nsec int64) (tv Timeval) {
nsec += 999 // round up to microsecond nsec += 999 // round up to microsecond
tv.Usec = int32(nsec % 1e9 / 1e3) tv.Usec = int32(nsec % 1e9 / 1e3)

View File

@ -21,8 +21,6 @@ func NsecToTimespec(nsec int64) (ts Timespec) {
return return
} }
func TimevalToNsec(tv Timeval) int64 { return int64(tv.Sec)*1e9 + int64(tv.Usec)*1e3 }
func NsecToTimeval(nsec int64) (tv Timeval) { func NsecToTimeval(nsec int64) (tv Timeval) {
nsec += 999 // round up to microsecond nsec += 999 // round up to microsecond
tv.Usec = int32(nsec % 1e9 / 1e3) tv.Usec = int32(nsec % 1e9 / 1e3)

View File

@ -109,6 +109,7 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
bufsize = unsafe.Sizeof(Statfs_t{}) * uintptr(len(buf)) bufsize = unsafe.Sizeof(Statfs_t{}) * uintptr(len(buf))
} }
r0, _, e1 := Syscall(SYS_GETFSSTAT, uintptr(_p0), bufsize, uintptr(flags)) r0, _, e1 := Syscall(SYS_GETFSSTAT, uintptr(_p0), bufsize, uintptr(flags))
use(unsafe.Pointer(_p0))
n = int(r0) n = int(r0)
if e1 != 0 { if e1 != 0 {
err = e1 err = e1

View File

@ -1,63 +0,0 @@
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build 386,dragonfly
package unix
import (
"syscall"
"unsafe"
)
func Getpagesize() int { return 4096 }
func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
func NsecToTimespec(nsec int64) (ts Timespec) {
ts.Sec = int32(nsec / 1e9)
ts.Nsec = int32(nsec % 1e9)
return
}
func TimevalToNsec(tv Timeval) int64 { return int64(tv.Sec)*1e9 + int64(tv.Usec)*1e3 }
func NsecToTimeval(nsec int64) (tv Timeval) {
nsec += 999 // round up to microsecond
tv.Usec = int32(nsec % 1e9 / 1e3)
tv.Sec = int32(nsec / 1e9)
return
}
func SetKevent(k *Kevent_t, fd, mode, flags int) {
k.Ident = uint32(fd)
k.Filter = int16(mode)
k.Flags = uint16(flags)
}
func (iov *Iovec) SetLen(length int) {
iov.Len = uint32(length)
}
func (msghdr *Msghdr) SetControllen(length int) {
msghdr.Controllen = uint32(length)
}
func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint32(length)
}
func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
var writtenOut uint64 = 0
_, _, e1 := Syscall9(SYS_SENDFILE, uintptr(infd), uintptr(outfd), uintptr(*offset), uintptr((*offset)>>32), uintptr(count), 0, uintptr(unsafe.Pointer(&writtenOut)), 0, 0)
written = int(writtenOut)
if e1 != 0 {
err = e1
}
return
}
func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)

View File

@ -21,8 +21,6 @@ func NsecToTimespec(nsec int64) (ts Timespec) {
return return
} }
func TimevalToNsec(tv Timeval) int64 { return int64(tv.Sec)*1e9 + int64(tv.Usec)*1e3 }
func NsecToTimeval(nsec int64) (tv Timeval) { func NsecToTimeval(nsec int64) (tv Timeval) {
nsec += 999 // round up to microsecond nsec += 999 // round up to microsecond
tv.Usec = nsec % 1e9 / 1e3 tv.Usec = nsec % 1e9 / 1e3

View File

@ -129,6 +129,7 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
bufsize = unsafe.Sizeof(Statfs_t{}) * uintptr(len(buf)) bufsize = unsafe.Sizeof(Statfs_t{}) * uintptr(len(buf))
} }
r0, _, e1 := Syscall(SYS_GETFSSTAT, uintptr(_p0), bufsize, uintptr(flags)) r0, _, e1 := Syscall(SYS_GETFSSTAT, uintptr(_p0), bufsize, uintptr(flags))
use(unsafe.Pointer(_p0))
n = int(r0) n = int(r0)
if e1 != 0 { if e1 != 0 {
err = e1 err = e1

View File

@ -21,8 +21,6 @@ func NsecToTimespec(nsec int64) (ts Timespec) {
return return
} }
func TimevalToNsec(tv Timeval) int64 { return int64(tv.Sec)*1e9 + int64(tv.Usec)*1e3 }
func NsecToTimeval(nsec int64) (tv Timeval) { func NsecToTimeval(nsec int64) (tv Timeval) {
nsec += 999 // round up to microsecond nsec += 999 // round up to microsecond
tv.Usec = int32(nsec % 1e9 / 1e3) tv.Usec = int32(nsec % 1e9 / 1e3)

View File

@ -21,8 +21,6 @@ func NsecToTimespec(nsec int64) (ts Timespec) {
return return
} }
func TimevalToNsec(tv Timeval) int64 { return int64(tv.Sec)*1e9 + int64(tv.Usec)*1e3 }
func NsecToTimeval(nsec int64) (tv Timeval) { func NsecToTimeval(nsec int64) (tv Timeval) {
nsec += 999 // round up to microsecond nsec += 999 // round up to microsecond
tv.Usec = nsec % 1e9 / 1e3 tv.Usec = nsec % 1e9 / 1e3

View File

@ -21,8 +21,6 @@ func NsecToTimespec(nsec int64) (ts Timespec) {
return return
} }
func TimevalToNsec(tv Timeval) int64 { return tv.Sec*1e9 + int64(tv.Usec)*1e3 }
func NsecToTimeval(nsec int64) (tv Timeval) { func NsecToTimeval(nsec int64) (tv Timeval) {
nsec += 999 // round up to microsecond nsec += 999 // round up to microsecond
tv.Usec = int32(nsec % 1e9 / 1e3) tv.Usec = int32(nsec % 1e9 / 1e3)

View File

@ -36,10 +36,10 @@ func Creat(path string, mode uint32) (fd int, err error) {
return Open(path, O_CREAT|O_WRONLY|O_TRUNC, mode) return Open(path, O_CREAT|O_WRONLY|O_TRUNC, mode)
} }
//sys linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error) //sys Linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error)
func Link(oldpath string, newpath string) (err error) { func Link(oldpath string, newpath string) (err error) {
return linkat(AT_FDCWD, oldpath, AT_FDCWD, newpath, 0) return Linkat(AT_FDCWD, oldpath, AT_FDCWD, newpath, 0)
} }
func Mkdir(path string, mode uint32) (err error) { func Mkdir(path string, mode uint32) (err error) {
@ -60,10 +60,19 @@ func Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error)
return openat(dirfd, path, flags|O_LARGEFILE, mode) return openat(dirfd, path, flags|O_LARGEFILE, mode)
} }
//sys readlinkat(dirfd int, path string, buf []byte) (n int, err error) //sys ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error)
func Ppoll(fds []PollFd, timeout *Timespec, sigmask *Sigset_t) (n int, err error) {
if len(fds) == 0 {
return ppoll(nil, 0, timeout, sigmask)
}
return ppoll(&fds[0], len(fds), timeout, sigmask)
}
//sys Readlinkat(dirfd int, path string, buf []byte) (n int, err error)
func Readlink(path string, buf []byte) (n int, err error) { func Readlink(path string, buf []byte) (n int, err error) {
return readlinkat(AT_FDCWD, path, buf) return Readlinkat(AT_FDCWD, path, buf)
} }
func Rename(oldpath string, newpath string) (err error) { func Rename(oldpath string, newpath string) (err error) {
@ -71,34 +80,41 @@ func Rename(oldpath string, newpath string) (err error) {
} }
func Rmdir(path string) error { func Rmdir(path string) error {
return unlinkat(AT_FDCWD, path, AT_REMOVEDIR) return Unlinkat(AT_FDCWD, path, AT_REMOVEDIR)
} }
//sys symlinkat(oldpath string, newdirfd int, newpath string) (err error) //sys Symlinkat(oldpath string, newdirfd int, newpath string) (err error)
func Symlink(oldpath string, newpath string) (err error) { func Symlink(oldpath string, newpath string) (err error) {
return symlinkat(oldpath, AT_FDCWD, newpath) return Symlinkat(oldpath, AT_FDCWD, newpath)
} }
func Unlink(path string) error { func Unlink(path string) error {
return unlinkat(AT_FDCWD, path, 0) return Unlinkat(AT_FDCWD, path, 0)
} }
//sys unlinkat(dirfd int, path string, flags int) (err error) //sys Unlinkat(dirfd int, path string, flags int) (err error)
func Unlinkat(dirfd int, path string) error {
return unlinkat(dirfd, path, 0)
}
//sys utimes(path string, times *[2]Timeval) (err error) //sys utimes(path string, times *[2]Timeval) (err error)
func Utimes(path string, tv []Timeval) (err error) { func Utimes(path string, tv []Timeval) error {
if tv == nil { if tv == nil {
err := utimensat(AT_FDCWD, path, nil, 0)
if err != ENOSYS {
return err
}
return utimes(path, nil) return utimes(path, nil)
} }
if len(tv) != 2 { if len(tv) != 2 {
return EINVAL return EINVAL
} }
var ts [2]Timespec
ts[0] = NsecToTimespec(TimevalToNsec(tv[0]))
ts[1] = NsecToTimespec(TimevalToNsec(tv[1]))
err := utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
if err != ENOSYS {
return err
}
return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0]))) return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
} }
@ -123,8 +139,7 @@ func UtimesNano(path string, ts []Timespec) error {
// in 2.6.22, Released, 8 July 2007) then fall back to utimes // in 2.6.22, Released, 8 July 2007) then fall back to utimes
var tv [2]Timeval var tv [2]Timeval
for i := 0; i < 2; i++ { for i := 0; i < 2; i++ {
tv[i].Sec = ts[i].Sec tv[i] = NsecToTimeval(TimespecToNsec(ts[i]))
tv[i].Usec = ts[i].Nsec / 1000
} }
return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0]))) return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
} }
@ -383,6 +398,60 @@ func (sa *SockaddrNetlink) sockaddr() (unsafe.Pointer, _Socklen, error) {
return unsafe.Pointer(&sa.raw), SizeofSockaddrNetlink, nil return unsafe.Pointer(&sa.raw), SizeofSockaddrNetlink, nil
} }
type SockaddrHCI struct {
Dev uint16
Channel uint16
raw RawSockaddrHCI
}
func (sa *SockaddrHCI) sockaddr() (unsafe.Pointer, _Socklen, error) {
sa.raw.Family = AF_BLUETOOTH
sa.raw.Dev = sa.Dev
sa.raw.Channel = sa.Channel
return unsafe.Pointer(&sa.raw), SizeofSockaddrHCI, nil
}
// SockaddrCAN implements the Sockaddr interface for AF_CAN type sockets.
// 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
// zero values for CAN_RAW and CAN_BCM sockets as they have no meaning.
//
// The SockaddrCAN struct must be bound to the socket file descriptor
// using Bind before the CAN socket can be used.
//
// // Read one raw CAN frame
// fd, _ := Socket(AF_CAN, SOCK_RAW, CAN_RAW)
// addr := &SockaddrCAN{Ifindex: index}
// Bind(fd, addr)
// frame := make([]byte, 16)
// Read(fd, frame)
//
// The full SocketCAN documentation can be found in the linux kernel
// archives at: https://www.kernel.org/doc/Documentation/networking/can.txt
type SockaddrCAN struct {
Ifindex int
RxID uint32
TxID uint32
raw RawSockaddrCAN
}
func (sa *SockaddrCAN) sockaddr() (unsafe.Pointer, _Socklen, error) {
if sa.Ifindex < 0 || sa.Ifindex > 0x7fffffff {
return nil, 0, EINVAL
}
sa.raw.Family = AF_CAN
sa.raw.Ifindex = int32(sa.Ifindex)
rx := (*[4]byte)(unsafe.Pointer(&sa.RxID))
for i := 0; i < 4; i++ {
sa.raw.Addr[i] = rx[i]
}
tx := (*[4]byte)(unsafe.Pointer(&sa.TxID))
for i := 0; i < 4; i++ {
sa.raw.Addr[i+4] = tx[i]
}
return unsafe.Pointer(&sa.raw), SizeofSockaddrCAN, nil
}
func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, error) { func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, error) {
switch rsa.Addr.Family { switch rsa.Addr.Family {
case AF_NETLINK: case AF_NETLINK:
@ -848,7 +917,6 @@ func Mount(source string, target string, fstype string, flags uintptr, data stri
//sysnb EpollCreate(size int) (fd 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 EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
//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 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)
@ -872,6 +940,7 @@ func Getpgrp() (pid int) {
//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 Getrusage(who int, rusage *Rusage) (err error) //sysnb Getrusage(who int, rusage *Rusage) (err error)
//sysnb Getsid(pid int) (sid int, err error)
//sysnb Gettid() (tid int) //sysnb Gettid() (tid int)
//sys Getxattr(path string, attr string, dest []byte) (sz int, err error) //sys Getxattr(path string, attr string, dest []byte) (sz int, err error)
//sys InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error) //sys InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error)
@ -883,9 +952,8 @@ 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 Pause() (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, old *Rlimit, newlimit *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)
//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)
@ -895,6 +963,7 @@ func Getpgrp() (pid int) {
//sysnb Setpgid(pid int, pgid int) (err error) //sysnb Setpgid(pid int, pgid int) (err error)
//sysnb Setsid() (pid int, err error) //sysnb Setsid() (pid int, err error)
//sysnb Settimeofday(tv *Timeval) (err error) //sysnb Settimeofday(tv *Timeval) (err error)
//sys Setns(fd int, nstype int) (err error)
// issue 1435. // issue 1435.
// On linux Setuid and Setgid only affects the current thread, not the process. // On linux Setuid and Setgid only affects the current thread, not the process.
@ -921,7 +990,6 @@ func Setgid(uid int) (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 Ustat(dev int, ubuf *Ustat_t) (err error)
//sys Utime(path string, buf *Utimbuf) (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
@ -1021,8 +1089,6 @@ func Munmap(b []byte) (err error) {
// Newfstatat // Newfstatat
// Nfsservctl // Nfsservctl
// Personality // Personality
// Poll
// Ppoll
// Pselect6 // Pselect6
// Ptrace // Ptrace
// Putpmsg // Putpmsg

View File

@ -24,8 +24,6 @@ func NsecToTimespec(nsec int64) (ts Timespec) {
return return
} }
func TimevalToNsec(tv Timeval) int64 { return int64(tv.Sec)*1e9 + int64(tv.Usec)*1e3 }
func NsecToTimeval(nsec int64) (tv Timeval) { func NsecToTimeval(nsec int64) (tv Timeval) {
nsec += 999 // round up to microsecond nsec += 999 // round up to microsecond
tv.Sec = int32(nsec / 1e9) tv.Sec = int32(nsec / 1e9)
@ -93,6 +91,8 @@ func Pipe2(p []int, flags int) (err error) {
//sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) = SYS__NEWSELECT //sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) = SYS__NEWSELECT
//sys 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)
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) {
page := uintptr(offset / 4096) page := uintptr(offset / 4096)
@ -181,6 +181,8 @@ func Seek(fd int, offset int64, whence int) (newoffset int64, 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)
// 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
// the 6-argument calls like sendto and recvfrom. Instead the // the 6-argument calls like sendto and recvfrom. Instead the
@ -386,3 +388,12 @@ 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 poll(fds *PollFd, nfds int, timeout int) (n int, err error)
func Poll(fds []PollFd, timeout int) (n int, err error) {
if len(fds) == 0 {
return poll(nil, 0, timeout)
}
return poll(&fds[0], len(fds), timeout)
}

View File

@ -6,9 +6,8 @@
package unix package unix
import "syscall"
//sys Dup2(oldfd int, newfd int) (err error) //sys Dup2(oldfd int, newfd 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)
//sys Fstat(fd int, stat *Stat_t) (err error) //sys Fstat(fd int, stat *Stat_t) (err error)
@ -25,6 +24,7 @@ import "syscall"
//sys Lchown(path string, uid int, gid int) (err error) //sys Lchown(path string, uid int, gid int) (err error)
//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 Lstat(path string, stat *Stat_t) (err error)
//sys Pause() (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 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
@ -61,9 +61,6 @@ import "syscall"
//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)
//go:noescape
func gettimeofday(tv *Timeval) (err syscall.Errno)
func Gettimeofday(tv *Timeval) (err error) { func Gettimeofday(tv *Timeval) (err error) {
errno := gettimeofday(tv) errno := gettimeofday(tv)
if errno != 0 { if errno != 0 {
@ -86,6 +83,8 @@ func Time(t *Time_t) (tt Time_t, err error) {
return Time_t(tv.Sec), nil return Time_t(tv.Sec), nil
} }
//sys Utime(path string, buf *Utimbuf) (err error)
func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
func NsecToTimespec(nsec int64) (ts Timespec) { func NsecToTimespec(nsec int64) (ts Timespec) {
@ -94,8 +93,6 @@ func NsecToTimespec(nsec int64) (ts Timespec) {
return return
} }
func TimevalToNsec(tv Timeval) int64 { return int64(tv.Sec)*1e9 + int64(tv.Usec)*1e3 }
func NsecToTimeval(nsec int64) (tv Timeval) { func NsecToTimeval(nsec int64) (tv Timeval) {
nsec += 999 // round up to microsecond nsec += 999 // round up to microsecond
tv.Sec = nsec / 1e9 tv.Sec = nsec / 1e9
@ -144,3 +141,12 @@ func (msghdr *Msghdr) SetControllen(length int) {
func (cmsg *Cmsghdr) SetLen(length int) { func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint64(length) cmsg.Len = uint64(length)
} }
//sys poll(fds *PollFd, nfds int, timeout int) (n int, err error)
func Poll(fds []PollFd, timeout int) (n int, err error) {
if len(fds) == 0 {
return poll(nil, 0, timeout)
}
return poll(&fds[0], len(fds), timeout)
}

13
vendor/golang.org/x/sys/unix/syscall_linux_amd64_gc.go generated vendored Normal file
View File

@ -0,0 +1,13 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build amd64,linux
// +build !gccgo
package unix
import "syscall"
//go:noescape
func gettimeofday(tv *Timeval) (err syscall.Errno)

View File

@ -108,7 +108,28 @@ func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
// Vsyscalls on amd64. // Vsyscalls on amd64.
//sysnb Gettimeofday(tv *Timeval) (err error) //sysnb Gettimeofday(tv *Timeval) (err error)
//sysnb Time(t *Time_t) (tt Time_t, 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) {
var tv Timeval
err := Gettimeofday(&tv)
if err != nil {
return 0, err
}
if t != nil {
*t = Time_t(tv.Sec)
}
return Time_t(tv.Sec), nil
}
func Utime(path string, buf *Utimbuf) error {
tv := []Timeval{
{Sec: buf.Actime},
{Sec: buf.Modtime},
}
return Utimes(path, tv)
}
//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
@ -158,7 +179,7 @@ type rlimit32 struct {
Max uint32 Max uint32
} }
//sysnb getrlimit(resource int, rlim *rlimit32) (err error) = SYS_GETRLIMIT //sysnb getrlimit(resource int, rlim *rlimit32) (err error) = SYS_UGETRLIMIT
const rlimInf32 = ^uint32(0) const rlimInf32 = ^uint32(0)
const rlimInf64 = ^uint64(0) const rlimInf64 = ^uint64(0)
@ -231,3 +252,12 @@ 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 poll(fds *PollFd, nfds int, timeout int) (n int, err error)
func Poll(fds []PollFd, timeout int) (n int, err error) {
if len(fds) == 0 {
return poll(nil, 0, timeout)
}
return poll(&fds[0], len(fds), timeout)
}

View File

@ -6,8 +6,7 @@
package unix package unix
const _SYS_dup = SYS_DUP3 //sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) = SYS_EPOLL_PWAIT
//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)
@ -70,7 +69,6 @@ func Lstat(path string, stat *Stat_t) (err error) {
func Getpagesize() int { return 65536 } func Getpagesize() int { return 65536 }
//sysnb Gettimeofday(tv *Timeval) (err error) //sysnb Gettimeofday(tv *Timeval) (err error)
//sysnb Time(t *Time_t) (tt Time_t, err error)
func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
@ -80,8 +78,6 @@ func NsecToTimespec(nsec int64) (ts Timespec) {
return return
} }
func TimevalToNsec(tv Timeval) int64 { return int64(tv.Sec)*1e9 + int64(tv.Usec)*1e3 }
func NsecToTimeval(nsec int64) (tv Timeval) { func NsecToTimeval(nsec int64) (tv Timeval) {
nsec += 999 // round up to microsecond nsec += 999 // round up to microsecond
tv.Sec = nsec / 1e9 tv.Sec = nsec / 1e9
@ -89,6 +85,26 @@ func NsecToTimeval(nsec int64) (tv Timeval) {
return return
} }
func Time(t *Time_t) (Time_t, error) {
var tv Timeval
err := Gettimeofday(&tv)
if err != nil {
return 0, err
}
if t != nil {
*t = Time_t(tv.Sec)
}
return Time_t(tv.Sec), nil
}
func Utime(path string, buf *Utimbuf) error {
tv := []Timeval{
{Sec: buf.Actime},
{Sec: buf.Modtime},
}
return Utimes(path, tv)
}
func Pipe(p []int) (err error) { func Pipe(p []int) (err error) {
if len(p) != 2 { if len(p) != 2 {
return EINVAL return EINVAL
@ -133,6 +149,18 @@ func InotifyInit() (fd int, err error) {
return InotifyInit1(0) return InotifyInit1(0)
} }
func Dup2(oldfd int, newfd int) (err error) {
return Dup3(oldfd, newfd, 0)
}
func Pause() (err error) {
_, _, e1 := Syscall6(SYS_PPOLL, 0, 0, 0, 0, 0, 0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
// TODO(dfc): constants that should be in zsysnum_linux_arm64.go, remove // TODO(dfc): constants that should be in zsysnum_linux_arm64.go, remove
// these when the deprecated syscalls that the syscall package relies on // these when the deprecated syscalls that the syscall package relies on
// are removed. // are removed.
@ -148,3 +176,15 @@ const (
SYS_EPOLL_CREATE = 1042 SYS_EPOLL_CREATE = 1042
SYS_EPOLL_WAIT = 1069 SYS_EPOLL_WAIT = 1069
) )
func Poll(fds []PollFd, timeout int) (n int, err error) {
var ts *Timespec
if timeout >= 0 {
ts = new(Timespec)
*ts = NsecToTimespec(int64(timeout) * 1e6)
}
if len(fds) == 0 {
return ppoll(nil, 0, ts, nil)
}
return ppoll(&fds[0], len(fds), ts, nil)
}

208
vendor/golang.org/x/sys/unix/syscall_linux_mips64x.go generated vendored Normal file
View File

@ -0,0 +1,208 @@
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build linux
// +build mips64 mips64le
package unix
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
//sys Fchown(fd int, uid int, gid int) (err error)
//sys Fstatfs(fd int, buf *Statfs_t) (err error)
//sys Ftruncate(fd int, length int64) (err error)
//sysnb Getegid() (egid int)
//sysnb Geteuid() (euid int)
//sysnb Getgid() (gid int)
//sysnb Getrlimit(resource int, rlim *Rlimit) (err error)
//sysnb Getuid() (uid int)
//sys Lchown(path string, uid int, gid int) (err error)
//sys Listen(s int, n int) (err error)
//sys Pause() (err error)
//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 Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK
//sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) = SYS_PSELECT6
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
//sys Setfsgid(gid int) (err error)
//sys Setfsuid(uid int) (err error)
//sysnb Setregid(rgid int, egid int) (err error)
//sysnb Setresgid(rgid int, egid int, sgid int) (err error)
//sysnb Setresuid(ruid int, euid int, suid int) (err error)
//sysnb Setrlimit(resource int, rlim *Rlimit) (err error)
//sysnb Setreuid(ruid int, euid int) (err error)
//sys Shutdown(fd int, how int) (err error)
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
//sys Statfs(path string, buf *Statfs_t) (err error)
//sys SyncFileRange(fd int, off int64, n int64, flags int) (err error)
//sys Truncate(path string, length int64) (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 bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
//sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
//sysnb getgroups(n int, list *_Gid_t) (nn int, err error)
//sysnb setgroups(n int, list *_Gid_t) (err error)
//sys getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error)
//sys setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error)
//sysnb socket(domain int, typ int, proto int) (fd int, err error)
//sysnb socketpair(domain int, typ int, proto int, fd *[2]int32) (err error)
//sysnb getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)
//sysnb getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)
//sys recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error)
//sys sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error)
//sys recvmsg(s int, msg *Msghdr, flags int) (n int, err error)
//sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error)
//sys mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error)
func Getpagesize() int { return 65536 }
//sysnb Gettimeofday(tv *Timeval) (err error)
func Time(t *Time_t) (tt Time_t, err error) {
var tv Timeval
err = Gettimeofday(&tv)
if err != nil {
return 0, err
}
if t != nil {
*t = Time_t(tv.Sec)
}
return Time_t(tv.Sec), nil
}
//sys Utime(path string, buf *Utimbuf) (err error)
func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
func NsecToTimespec(nsec int64) (ts Timespec) {
ts.Sec = nsec / 1e9
ts.Nsec = nsec % 1e9
return
}
func NsecToTimeval(nsec int64) (tv Timeval) {
nsec += 999 // round up to microsecond
tv.Sec = nsec / 1e9
tv.Usec = nsec % 1e9 / 1e3
return
}
func Pipe(p []int) (err error) {
if len(p) != 2 {
return EINVAL
}
var pp [2]_C_int
err = pipe2(&pp, 0)
p[0] = int(pp[0])
p[1] = int(pp[1])
return
}
//sysnb pipe2(p *[2]_C_int, flags int) (err error)
func Pipe2(p []int, flags int) (err error) {
if len(p) != 2 {
return EINVAL
}
var pp [2]_C_int
err = pipe2(&pp, flags)
p[0] = int(pp[0])
p[1] = int(pp[1])
return
}
func Ioperm(from int, num int, on int) (err error) {
return ENOSYS
}
func Iopl(level int) (err error) {
return ENOSYS
}
type stat_t struct {
Dev uint32
Pad0 [3]int32
Ino uint64
Mode uint32
Nlink uint32
Uid uint32
Gid uint32
Rdev uint32
Pad1 [3]uint32
Size int64
Atime uint32
Atime_nsec uint32
Mtime uint32
Mtime_nsec uint32
Ctime uint32
Ctime_nsec uint32
Blksize uint32
Pad2 uint32
Blocks int64
}
//sys fstat(fd int, st *stat_t) (err error)
//sys lstat(path string, st *stat_t) (err error)
//sys stat(path string, st *stat_t) (err error)
func Fstat(fd int, s *Stat_t) (err error) {
st := &stat_t{}
err = fstat(fd, st)
fillStat_t(s, st)
return
}
func Lstat(path string, s *Stat_t) (err error) {
st := &stat_t{}
err = lstat(path, st)
fillStat_t(s, st)
return
}
func Stat(path string, s *Stat_t) (err error) {
st := &stat_t{}
err = stat(path, st)
fillStat_t(s, st)
return
}
func fillStat_t(s *Stat_t, st *stat_t) {
s.Dev = st.Dev
s.Ino = st.Ino
s.Mode = st.Mode
s.Nlink = st.Nlink
s.Uid = st.Uid
s.Gid = st.Gid
s.Rdev = st.Rdev
s.Size = st.Size
s.Atim = Timespec{int64(st.Atime), int64(st.Atime_nsec)}
s.Mtim = Timespec{int64(st.Mtime), int64(st.Mtime_nsec)}
s.Ctim = Timespec{int64(st.Ctime), int64(st.Ctime_nsec)}
s.Blksize = st.Blksize
s.Blocks = st.Blocks
}
func (r *PtraceRegs) PC() uint64 { return r.Regs[64] }
func (r *PtraceRegs) SetPC(pc uint64) { r.Regs[64] = pc }
func (iov *Iovec) SetLen(length int) {
iov.Len = uint64(length)
}
func (msghdr *Msghdr) SetControllen(length int) {
msghdr.Controllen = uint64(length)
}
func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint64(length)
}
//sys poll(fds *PollFd, nfds int, timeout int) (n int, err error)
func Poll(fds []PollFd, timeout int) (n int, err error) {
if len(fds) == 0 {
return poll(nil, 0, timeout)
}
return poll(&fds[0], len(fds), timeout)
}

241
vendor/golang.org/x/sys/unix/syscall_linux_mipsx.go generated vendored Normal file
View File

@ -0,0 +1,241 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build linux
// +build mips mipsle
package unix
import (
"syscall"
"unsafe"
)
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 Fchown(fd int, uid int, gid int) (err error)
//sys Ftruncate(fd int, length int64) (err error) = SYS_FTRUNCATE64
//sysnb Getegid() (egid int)
//sysnb Geteuid() (euid int)
//sysnb Getgid() (gid int)
//sysnb Getuid() (uid int)
//sys Lchown(path string, uid int, gid int) (err error)
//sys Listen(s int, n int) (err error)
//sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
//sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
//sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) = SYS__NEWSELECT
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = SYS_SENDFILE64
//sys Setfsgid(gid int) (err error)
//sys Setfsuid(uid int) (err error)
//sysnb Setregid(rgid int, egid int) (err error)
//sysnb Setresgid(rgid int, egid int, sgid int) (err error)
//sysnb Setresuid(ruid int, euid int, suid int) (err error)
//sysnb Setreuid(ruid int, euid int) (err error)
//sys Shutdown(fd int, how int) (err error)
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
//sys SyncFileRange(fd int, off int64, n int64, flags int) (err error)
//sys Truncate(path string, length int64) (err error) = SYS_TRUNCATE64
//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 bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
//sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
//sysnb getgroups(n int, list *_Gid_t) (nn int, err error)
//sysnb setgroups(n int, list *_Gid_t) (err error)
//sys getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error)
//sys setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error)
//sysnb socket(domain int, typ int, proto int) (fd int, err error)
//sysnb socketpair(domain int, typ int, proto int, fd *[2]int32) (err error)
//sysnb getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)
//sysnb getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)
//sys recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error)
//sys sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error)
//sys recvmsg(s int, msg *Msghdr, flags int) (n int, err error)
//sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error)
//sysnb InotifyInit() (fd int, err error)
//sys Ioperm(from int, num int, on int) (err error)
//sys Iopl(level int) (err error)
//sysnb Gettimeofday(tv *Timeval) (err error)
//sysnb Time(t *Time_t) (tt Time_t, err error)
//sys Lstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64
//sys Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64
//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)
func Fstatfs(fd int, buf *Statfs_t) (err error) {
_, _, e := Syscall(SYS_FSTATFS64, uintptr(fd), unsafe.Sizeof(*buf), uintptr(unsafe.Pointer(buf)))
use(unsafe.Pointer(buf))
if e != 0 {
err = errnoErr(e)
}
return
}
func Statfs(path string, buf *Statfs_t) (err error) {
p, err := BytePtrFromString(path)
if err != nil {
return err
}
_, _, e := Syscall(SYS_STATFS64, uintptr(unsafe.Pointer(p)), unsafe.Sizeof(*buf), uintptr(unsafe.Pointer(buf)))
use(unsafe.Pointer(p))
if e != 0 {
err = errnoErr(e)
}
return
}
func Seek(fd int, offset int64, whence int) (off int64, err error) {
_, _, e := Syscall6(SYS__LLSEEK, uintptr(fd), uintptr(offset>>32), uintptr(offset), uintptr(unsafe.Pointer(&off)), uintptr(whence), 0)
if e != 0 {
err = errnoErr(e)
}
return
}
func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
func NsecToTimespec(nsec int64) (ts Timespec) {
ts.Sec = int32(nsec / 1e9)
ts.Nsec = int32(nsec % 1e9)
return
}
func NsecToTimeval(nsec int64) (tv Timeval) {
nsec += 999 // round up to microsecond
tv.Sec = int32(nsec / 1e9)
tv.Usec = int32(nsec % 1e9 / 1e3)
return
}
//sysnb pipe2(p *[2]_C_int, flags int) (err error)
func Pipe2(p []int, flags int) (err error) {
if len(p) != 2 {
return EINVAL
}
var pp [2]_C_int
err = pipe2(&pp, flags)
p[0] = int(pp[0])
p[1] = int(pp[1])
return
}
func Pipe(p []int) (err error) {
if len(p) != 2 {
return EINVAL
}
var pp [2]_C_int
err = pipe2(&pp, 0)
p[0] = int(pp[0])
p[1] = int(pp[1])
return
}
//sys mmap2(addr uintptr, length uintptr, prot int, flags int, fd int, pageOffset uintptr) (xaddr uintptr, err error)
func mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) {
page := uintptr(offset / 4096)
if offset != int64(page)*4096 {
return 0, EINVAL
}
return mmap2(addr, length, prot, flags, fd, page)
}
const rlimInf32 = ^uint32(0)
const rlimInf64 = ^uint64(0)
type rlimit32 struct {
Cur uint32
Max uint32
}
//sysnb getrlimit(resource int, rlim *rlimit32) (err error) = SYS_GETRLIMIT
func Getrlimit(resource int, rlim *Rlimit) (err error) {
err = prlimit(0, resource, nil, rlim)
if err != ENOSYS {
return err
}
rl := rlimit32{}
err = getrlimit(resource, &rl)
if err != nil {
return
}
if rl.Cur == rlimInf32 {
rlim.Cur = rlimInf64
} else {
rlim.Cur = uint64(rl.Cur)
}
if rl.Max == rlimInf32 {
rlim.Max = rlimInf64
} else {
rlim.Max = uint64(rl.Max)
}
return
}
//sysnb setrlimit(resource int, rlim *rlimit32) (err error) = SYS_SETRLIMIT
func Setrlimit(resource int, rlim *Rlimit) (err error) {
err = prlimit(0, resource, rlim, nil)
if err != ENOSYS {
return err
}
rl := rlimit32{}
if rlim.Cur == rlimInf64 {
rl.Cur = rlimInf32
} else if rlim.Cur < uint64(rlimInf32) {
rl.Cur = uint32(rlim.Cur)
} else {
return EINVAL
}
if rlim.Max == rlimInf64 {
rl.Max = rlimInf32
} else if rlim.Max < uint64(rlimInf32) {
rl.Max = uint32(rlim.Max)
} else {
return EINVAL
}
return setrlimit(resource, &rl)
}
func (r *PtraceRegs) PC() uint64 { return uint64(r.Regs[64]) }
func (r *PtraceRegs) SetPC(pc uint64) { r.Regs[64] = uint32(pc) }
func (iov *Iovec) SetLen(length int) {
iov.Len = uint32(length)
}
func (msghdr *Msghdr) SetControllen(length int) {
msghdr.Controllen = uint32(length)
}
func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint32(length)
}
//sys poll(fds *PollFd, nfds int, timeout int) (n int, err error)
func Poll(fds []PollFd, timeout int) (n int, err error) {
if len(fds) == 0 {
return poll(nil, 0, timeout)
}
return poll(&fds[0], len(fds), timeout)
}
func Getpagesize() int { return 4096 }

View File

@ -7,6 +7,8 @@
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 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 Fstatfs(fd int, buf *Statfs_t) (err error) //sys Fstatfs(fd int, buf *Statfs_t) (err error)
@ -16,11 +18,13 @@ package unix
//sysnb Getgid() (gid int) //sysnb Getgid() (gid int)
//sysnb Getrlimit(resource int, rlim *Rlimit) (err error) = SYS_UGETRLIMIT //sysnb Getrlimit(resource int, rlim *Rlimit) (err error) = SYS_UGETRLIMIT
//sysnb Getuid() (uid int) //sysnb Getuid() (uid int)
//sysnb InotifyInit() (fd int, err error)
//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 Lchown(path string, uid int, gid int) (err error) //sys Lchown(path string, uid int, gid int) (err error)
//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 Lstat(path string, stat *Stat_t) (err error)
//sys Pause() (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 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
@ -62,6 +66,8 @@ func Getpagesize() int { return 65536 }
//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)
func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
func NsecToTimespec(nsec int64) (ts Timespec) { func NsecToTimespec(nsec int64) (ts Timespec) {
@ -70,8 +76,6 @@ func NsecToTimespec(nsec int64) (ts Timespec) {
return return
} }
func TimevalToNsec(tv Timeval) int64 { return int64(tv.Sec)*1e9 + int64(tv.Usec)*1e3 }
func NsecToTimeval(nsec int64) (tv Timeval) { func NsecToTimeval(nsec int64) (tv Timeval) {
nsec += 999 // round up to microsecond nsec += 999 // round up to microsecond
tv.Sec = nsec / 1e9 tv.Sec = nsec / 1e9
@ -94,3 +98,38 @@ func (msghdr *Msghdr) SetControllen(length int) {
func (cmsg *Cmsghdr) SetLen(length int) { func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint64(length) cmsg.Len = uint64(length)
} }
//sysnb pipe(p *[2]_C_int) (err error)
func Pipe(p []int) (err error) {
if len(p) != 2 {
return EINVAL
}
var pp [2]_C_int
err = pipe(&pp)
p[0] = int(pp[0])
p[1] = int(pp[1])
return
}
//sysnb pipe2(p *[2]_C_int, flags int) (err error)
func Pipe2(p []int, flags int) (err error) {
if len(p) != 2 {
return EINVAL
}
var pp [2]_C_int
err = pipe2(&pp, flags)
p[0] = int(pp[0])
p[1] = int(pp[1])
return
}
//sys poll(fds *PollFd, nfds int, timeout int) (n int, err error)
func Poll(fds []PollFd, timeout int) (n int, err error) {
if len(fds) == 0 {
return poll(nil, 0, timeout)
}
return poll(&fds[0], len(fds), timeout)
}

329
vendor/golang.org/x/sys/unix/syscall_linux_s390x.go generated vendored Normal file
View File

@ -0,0 +1,329 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build s390x,linux
package unix
import (
"unsafe"
)
//sys Dup2(oldfd int, newfd 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 Fstat(fd int, stat *Stat_t) (err error)
//sys Fstatfs(fd int, buf *Statfs_t) (err error)
//sys Ftruncate(fd int, length int64) (err error)
//sysnb Getegid() (egid int)
//sysnb Geteuid() (euid int)
//sysnb Getgid() (gid int)
//sysnb Getrlimit(resource int, rlim *Rlimit) (err error)
//sysnb Getuid() (uid int)
//sysnb InotifyInit() (fd int, err error)
//sys Lchown(path string, uid int, gid int) (err error)
//sys Lstat(path string, stat *Stat_t) (err error)
//sys Pause() (err error)
//sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
//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 Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error)
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
//sys Setfsgid(gid int) (err error)
//sys Setfsuid(uid int) (err error)
//sysnb Setregid(rgid int, egid int) (err error)
//sysnb Setresgid(rgid int, egid int, sgid int) (err error)
//sysnb Setresuid(ruid int, euid int, suid int) (err error)
//sysnb Setrlimit(resource int, rlim *Rlimit) (err error)
//sysnb Setreuid(ruid int, euid int) (err error)
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
//sys Stat(path string, stat *Stat_t) (err error)
//sys Statfs(path string, buf *Statfs_t) (err error)
//sys SyncFileRange(fd int, off int64, n int64, flags int) (err error)
//sys Truncate(path string, length int64) (err error)
//sysnb getgroups(n int, list *_Gid_t) (nn int, err error)
//sysnb setgroups(n int, list *_Gid_t) (err error)
func Getpagesize() int { return 4096 }
//sysnb Gettimeofday(tv *Timeval) (err error)
func Time(t *Time_t) (tt Time_t, err error) {
var tv Timeval
err = Gettimeofday(&tv)
if err != nil {
return 0, err
}
if t != nil {
*t = Time_t(tv.Sec)
}
return Time_t(tv.Sec), nil
}
//sys Utime(path string, buf *Utimbuf) (err error)
func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
func NsecToTimespec(nsec int64) (ts Timespec) {
ts.Sec = nsec / 1e9
ts.Nsec = nsec % 1e9
return
}
func NsecToTimeval(nsec int64) (tv Timeval) {
nsec += 999 // round up to microsecond
tv.Sec = nsec / 1e9
tv.Usec = nsec % 1e9 / 1e3
return
}
//sysnb pipe2(p *[2]_C_int, flags int) (err error)
func Pipe(p []int) (err error) {
if len(p) != 2 {
return EINVAL
}
var pp [2]_C_int
err = pipe2(&pp, 0) // pipe2 is the same as pipe when flags are set to 0.
p[0] = int(pp[0])
p[1] = int(pp[1])
return
}
func Pipe2(p []int, flags int) (err error) {
if len(p) != 2 {
return EINVAL
}
var pp [2]_C_int
err = pipe2(&pp, flags)
p[0] = int(pp[0])
p[1] = int(pp[1])
return
}
func Ioperm(from int, num int, on int) (err error) {
return ENOSYS
}
func Iopl(level int) (err error) {
return ENOSYS
}
func (r *PtraceRegs) PC() uint64 { return r.Psw.Addr }
func (r *PtraceRegs) SetPC(pc uint64) { r.Psw.Addr = pc }
func (iov *Iovec) SetLen(length int) {
iov.Len = uint64(length)
}
func (msghdr *Msghdr) SetControllen(length int) {
msghdr.Controllen = uint64(length)
}
func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint64(length)
}
// Linux on s390x uses the old mmap interface, which requires arguments to be passed in a struct.
// mmap2 also requires arguments to be passed in a struct; it is currently not exposed in <asm/unistd.h>.
func mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) {
mmap_args := [6]uintptr{addr, length, uintptr(prot), uintptr(flags), uintptr(fd), uintptr(offset)}
r0, _, e1 := Syscall(SYS_MMAP, uintptr(unsafe.Pointer(&mmap_args[0])), 0, 0)
use(unsafe.Pointer(&mmap_args[0]))
xaddr = uintptr(r0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
// On s390x Linux, all the socket calls go through an extra indirection.
// The arguments to the underlying system call (SYS_SOCKETCALL) are the
// number below and a pointer to an array of uintptr.
const (
// see linux/net.h
netSocket = 1
netBind = 2
netConnect = 3
netListen = 4
netAccept = 5
netGetSockName = 6
netGetPeerName = 7
netSocketPair = 8
netSend = 9
netRecv = 10
netSendTo = 11
netRecvFrom = 12
netShutdown = 13
netSetSockOpt = 14
netGetSockOpt = 15
netSendMsg = 16
netRecvMsg = 17
netAccept4 = 18
netRecvMMsg = 19
netSendMMsg = 20
)
func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (int, error) {
args := [3]uintptr{uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))}
fd, _, err := Syscall(SYS_SOCKETCALL, netAccept, uintptr(unsafe.Pointer(&args)), 0)
if err != 0 {
return 0, err
}
return int(fd), nil
}
func accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (int, error) {
args := [4]uintptr{uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags)}
fd, _, err := Syscall(SYS_SOCKETCALL, netAccept4, uintptr(unsafe.Pointer(&args)), 0)
if err != 0 {
return 0, err
}
return int(fd), nil
}
func getsockname(s int, rsa *RawSockaddrAny, addrlen *_Socklen) error {
args := [3]uintptr{uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))}
_, _, err := RawSyscall(SYS_SOCKETCALL, netGetSockName, uintptr(unsafe.Pointer(&args)), 0)
if err != 0 {
return err
}
return nil
}
func getpeername(s int, rsa *RawSockaddrAny, addrlen *_Socklen) error {
args := [3]uintptr{uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))}
_, _, err := RawSyscall(SYS_SOCKETCALL, netGetPeerName, uintptr(unsafe.Pointer(&args)), 0)
if err != 0 {
return err
}
return nil
}
func socketpair(domain int, typ int, flags int, fd *[2]int32) error {
args := [4]uintptr{uintptr(domain), uintptr(typ), uintptr(flags), uintptr(unsafe.Pointer(fd))}
_, _, err := RawSyscall(SYS_SOCKETCALL, netSocketPair, uintptr(unsafe.Pointer(&args)), 0)
if err != 0 {
return err
}
return nil
}
func bind(s int, addr unsafe.Pointer, addrlen _Socklen) error {
args := [3]uintptr{uintptr(s), uintptr(addr), uintptr(addrlen)}
_, _, err := Syscall(SYS_SOCKETCALL, netBind, uintptr(unsafe.Pointer(&args)), 0)
if err != 0 {
return err
}
return nil
}
func connect(s int, addr unsafe.Pointer, addrlen _Socklen) error {
args := [3]uintptr{uintptr(s), uintptr(addr), uintptr(addrlen)}
_, _, err := Syscall(SYS_SOCKETCALL, netConnect, uintptr(unsafe.Pointer(&args)), 0)
if err != 0 {
return err
}
return nil
}
func socket(domain int, typ int, proto int) (int, error) {
args := [3]uintptr{uintptr(domain), uintptr(typ), uintptr(proto)}
fd, _, err := RawSyscall(SYS_SOCKETCALL, netSocket, uintptr(unsafe.Pointer(&args)), 0)
if err != 0 {
return 0, err
}
return int(fd), nil
}
func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) error {
args := [5]uintptr{uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen))}
_, _, err := Syscall(SYS_SOCKETCALL, netGetSockOpt, uintptr(unsafe.Pointer(&args)), 0)
if err != 0 {
return err
}
return nil
}
func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) error {
args := [4]uintptr{uintptr(s), uintptr(level), uintptr(name), uintptr(val)}
_, _, err := Syscall(SYS_SOCKETCALL, netSetSockOpt, uintptr(unsafe.Pointer(&args)), 0)
if err != 0 {
return err
}
return nil
}
func recvfrom(s int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (int, error) {
var base uintptr
if len(p) > 0 {
base = uintptr(unsafe.Pointer(&p[0]))
}
args := [6]uintptr{uintptr(s), base, uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen))}
n, _, err := Syscall(SYS_SOCKETCALL, netRecvFrom, uintptr(unsafe.Pointer(&args)), 0)
if err != 0 {
return 0, err
}
return int(n), nil
}
func sendto(s int, p []byte, flags int, to unsafe.Pointer, addrlen _Socklen) error {
var base uintptr
if len(p) > 0 {
base = uintptr(unsafe.Pointer(&p[0]))
}
args := [6]uintptr{uintptr(s), base, uintptr(len(p)), uintptr(flags), uintptr(to), uintptr(addrlen)}
_, _, err := Syscall(SYS_SOCKETCALL, netSendTo, uintptr(unsafe.Pointer(&args)), 0)
if err != 0 {
return err
}
return nil
}
func recvmsg(s int, msg *Msghdr, flags int) (int, error) {
args := [3]uintptr{uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags)}
n, _, err := Syscall(SYS_SOCKETCALL, netRecvMsg, uintptr(unsafe.Pointer(&args)), 0)
if err != 0 {
return 0, err
}
return int(n), nil
}
func sendmsg(s int, msg *Msghdr, flags int) (int, error) {
args := [3]uintptr{uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags)}
n, _, err := Syscall(SYS_SOCKETCALL, netSendMsg, uintptr(unsafe.Pointer(&args)), 0)
if err != 0 {
return 0, err
}
return int(n), nil
}
func Listen(s int, n int) error {
args := [2]uintptr{uintptr(s), uintptr(n)}
_, _, err := Syscall(SYS_SOCKETCALL, netListen, uintptr(unsafe.Pointer(&args)), 0)
if err != 0 {
return err
}
return nil
}
func Shutdown(s, how int) error {
args := [2]uintptr{uintptr(s), uintptr(how)}
_, _, err := Syscall(SYS_SOCKETCALL, netShutdown, uintptr(unsafe.Pointer(&args)), 0)
if err != 0 {
return err
}
return nil
}
//sys poll(fds *PollFd, nfds int, timeout int) (n int, err error)
func Poll(fds []PollFd, timeout int) (n int, err error) {
if len(fds) == 0 {
return poll(nil, 0, timeout)
}
return poll(&fds[0], len(fds), timeout)
}

169
vendor/golang.org/x/sys/unix/syscall_linux_sparc64.go generated vendored Normal file
View File

@ -0,0 +1,169 @@
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build sparc64,linux
package unix
import (
"sync/atomic"
"syscall"
)
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
//sys Dup2(oldfd int, newfd int) (err error)
//sys Fchown(fd int, uid int, gid int) (err error)
//sys Fstat(fd int, stat *Stat_t) (err error)
//sys Fstatfs(fd int, buf *Statfs_t) (err error)
//sys Ftruncate(fd int, length int64) (err error)
//sysnb Getegid() (egid int)
//sysnb Geteuid() (euid int)
//sysnb Getgid() (gid int)
//sysnb Getrlimit(resource int, rlim *Rlimit) (err error)
//sysnb Getuid() (uid int)
//sysnb InotifyInit() (fd int, err error)
//sys Lchown(path string, uid int, gid int) (err error)
//sys Listen(s int, n int) (err error)
//sys Lstat(path string, stat *Stat_t) (err error)
//sys Pause() (err error)
//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 Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK
//sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error)
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
//sys Setfsgid(gid int) (err error)
//sys Setfsuid(uid int) (err error)
//sysnb Setregid(rgid int, egid int) (err error)
//sysnb Setresgid(rgid int, egid int, sgid int) (err error)
//sysnb Setresuid(ruid int, euid int, suid int) (err error)
//sysnb Setrlimit(resource int, rlim *Rlimit) (err error)
//sysnb Setreuid(ruid int, euid int) (err error)
//sys Shutdown(fd int, how int) (err error)
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
//sys Stat(path string, stat *Stat_t) (err error)
//sys Statfs(path string, buf *Statfs_t) (err error)
//sys SyncFileRange(fd int, off int64, n int64, flags int) (err error)
//sys Truncate(path string, length int64) (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 bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
//sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
//sysnb getgroups(n int, list *_Gid_t) (nn int, err error)
//sysnb setgroups(n int, list *_Gid_t) (err error)
//sys getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error)
//sys setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error)
//sysnb socket(domain int, typ int, proto int) (fd int, err error)
//sysnb socketpair(domain int, typ int, proto int, fd *[2]int32) (err error)
//sysnb getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)
//sysnb getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)
//sys recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error)
//sys sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error)
//sys recvmsg(s int, msg *Msghdr, flags int) (n int, err error)
//sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error)
//sys mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error)
func sysconf(name int) (n int64, err syscall.Errno)
// pageSize caches the value of Getpagesize, since it can't change
// once the system is booted.
var pageSize int64 // accessed atomically
func Getpagesize() int {
n := atomic.LoadInt64(&pageSize)
if n == 0 {
n, _ = sysconf(_SC_PAGESIZE)
atomic.StoreInt64(&pageSize, n)
}
return int(n)
}
func Ioperm(from int, num int, on int) (err error) {
return ENOSYS
}
func Iopl(level int) (err error) {
return ENOSYS
}
//sysnb Gettimeofday(tv *Timeval) (err error)
func Time(t *Time_t) (tt Time_t, err error) {
var tv Timeval
err = Gettimeofday(&tv)
if err != nil {
return 0, err
}
if t != nil {
*t = Time_t(tv.Sec)
}
return Time_t(tv.Sec), nil
}
//sys Utime(path string, buf *Utimbuf) (err error)
func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
func NsecToTimespec(nsec int64) (ts Timespec) {
ts.Sec = nsec / 1e9
ts.Nsec = nsec % 1e9
return
}
func NsecToTimeval(nsec int64) (tv Timeval) {
nsec += 999 // round up to microsecond
tv.Sec = nsec / 1e9
tv.Usec = int32(nsec % 1e9 / 1e3)
return
}
func (r *PtraceRegs) PC() uint64 { return r.Tpc }
func (r *PtraceRegs) SetPC(pc uint64) { r.Tpc = pc }
func (iov *Iovec) SetLen(length int) {
iov.Len = uint64(length)
}
func (msghdr *Msghdr) SetControllen(length int) {
msghdr.Controllen = uint64(length)
}
func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint64(length)
}
//sysnb pipe(p *[2]_C_int) (err error)
func Pipe(p []int) (err error) {
if len(p) != 2 {
return EINVAL
}
var pp [2]_C_int
err = pipe(&pp)
p[0] = int(pp[0])
p[1] = int(pp[1])
return
}
//sysnb pipe2(p *[2]_C_int, flags int) (err error)
func Pipe2(p []int, flags int) (err error) {
if len(p) != 2 {
return EINVAL
}
var pp [2]_C_int
err = pipe2(&pp, flags)
p[0] = int(pp[0])
p[1] = int(pp[1])
return
}
//sys poll(fds *PollFd, nfds int, timeout int) (n int, err error)
func Poll(fds []PollFd, timeout int) (n int, err error) {
if len(fds) == 0 {
return poll(nil, 0, timeout)
}
return poll(&fds[0], len(fds), timeout)
}

View File

@ -16,8 +16,6 @@ func NsecToTimespec(nsec int64) (ts Timespec) {
return return
} }
func TimevalToNsec(tv Timeval) int64 { return int64(tv.Sec)*1e9 + int64(tv.Usec)*1e3 }
func NsecToTimeval(nsec int64) (tv Timeval) { func NsecToTimeval(nsec int64) (tv Timeval) {
nsec += 999 // round up to microsecond nsec += 999 // round up to microsecond
tv.Usec = int32(nsec % 1e9 / 1e3) tv.Usec = int32(nsec % 1e9 / 1e3)

View File

@ -16,8 +16,6 @@ func NsecToTimespec(nsec int64) (ts Timespec) {
return return
} }
func TimevalToNsec(tv Timeval) int64 { return int64(tv.Sec)*1e9 + int64(tv.Usec)*1e3 }
func NsecToTimeval(nsec int64) (tv Timeval) { func NsecToTimeval(nsec int64) (tv Timeval) {
nsec += 999 // round up to microsecond nsec += 999 // round up to microsecond
tv.Usec = int32(nsec % 1e9 / 1e3) tv.Usec = int32(nsec % 1e9 / 1e3)

View File

@ -16,8 +16,6 @@ func NsecToTimespec(nsec int64) (ts Timespec) {
return return
} }
func TimevalToNsec(tv Timeval) int64 { return int64(tv.Sec)*1e9 + int64(tv.Usec)*1e3 }
func NsecToTimeval(nsec int64) (tv Timeval) { func NsecToTimeval(nsec int64) (tv Timeval) {
nsec += 999 // round up to microsecond nsec += 999 // round up to microsecond
tv.Usec = int32(nsec % 1e9 / 1e3) tv.Usec = int32(nsec % 1e9 / 1e3)

View File

@ -111,6 +111,7 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
bufsize = unsafe.Sizeof(Statfs_t{}) * uintptr(len(buf)) bufsize = unsafe.Sizeof(Statfs_t{}) * uintptr(len(buf))
} }
r0, _, e1 := Syscall(SYS_GETFSSTAT, uintptr(_p0), bufsize, uintptr(flags)) r0, _, e1 := Syscall(SYS_GETFSSTAT, uintptr(_p0), bufsize, uintptr(flags))
use(unsafe.Pointer(_p0))
n = int(r0) n = int(r0)
if e1 != 0 { if e1 != 0 {
err = e1 err = e1

View File

@ -16,8 +16,6 @@ func NsecToTimespec(nsec int64) (ts Timespec) {
return return
} }
func TimevalToNsec(tv Timeval) int64 { return int64(tv.Sec)*1e9 + int64(tv.Usec)*1e3 }
func NsecToTimeval(nsec int64) (tv Timeval) { func NsecToTimeval(nsec int64) (tv Timeval) {
nsec += 999 // round up to microsecond nsec += 999 // round up to microsecond
tv.Usec = int32(nsec % 1e9 / 1e3) tv.Usec = int32(nsec % 1e9 / 1e3)

View File

@ -16,8 +16,6 @@ func NsecToTimespec(nsec int64) (ts Timespec) {
return return
} }
func TimevalToNsec(tv Timeval) int64 { return int64(tv.Sec)*1e9 + int64(tv.Usec)*1e3 }
func NsecToTimeval(nsec int64) (tv Timeval) { func NsecToTimeval(nsec int64) (tv Timeval) {
nsec += 999 // round up to microsecond nsec += 999 // round up to microsecond
tv.Usec = nsec % 1e9 / 1e3 tv.Usec = nsec % 1e9 / 1e3

View File

@ -72,18 +72,20 @@ func ParseDirent(buf []byte, max int, names []string) (consumed int, count int,
return origlen - len(buf), count, names return origlen - len(buf), count, names
} }
func pipe() (r uintptr, w uintptr, err uintptr) //sysnb pipe(p *[2]_C_int) (n 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
} }
r0, w0, e1 := pipe() var pp [2]_C_int
if e1 != 0 { n, err := pipe(&pp)
err = syscall.Errno(e1) if n != 0 {
return err
} }
p[0], p[1] = int(r0), int(w0) p[0] = int(pp[0])
return p[1] = int(pp[1])
return nil
} }
func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) { func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {
@ -269,24 +271,34 @@ func (w WaitStatus) StopSignal() syscall.Signal {
func (w WaitStatus) TrapCause() int { return -1 } func (w WaitStatus) TrapCause() int { return -1 }
func wait4(pid uintptr, wstatus *WaitStatus, options uintptr, rusage *Rusage) (wpid uintptr, err uintptr) //sys wait4(pid int32, statusp *_C_int, options int, rusage *Rusage) (wpid int32, err error)
func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) { func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (int, error) {
r0, e1 := wait4(uintptr(pid), wstatus, uintptr(options), rusage) var status _C_int
if e1 != 0 { rpid, err := wait4(int32(pid), &status, options, rusage)
err = syscall.Errno(e1) wpid := int(rpid)
if wpid == -1 {
return wpid, err
} }
return int(r0), err if wstatus != nil {
*wstatus = WaitStatus(status)
}
return wpid, nil
} }
func gethostname() (name string, err uintptr) //sys gethostname(buf []byte) (n int, err error)
func Gethostname() (name string, err error) { func Gethostname() (name string, err error) {
name, e1 := gethostname() var buf [MaxHostNameLen]byte
if e1 != 0 { n, err := gethostname(buf[:])
err = syscall.Errno(e1) if n != 0 {
return "", err
} }
return name, err n = clen(buf[:])
if n < 1 {
return "", EFAULT
}
return string(buf[:n]), nil
} }
//sys utimes(path string, times *[2]Timeval) (err error) //sys utimes(path string, times *[2]Timeval) (err error)
@ -649,7 +661,7 @@ func IoctlGetTermio(fd int, req int) (*Termio, error) {
//sysnb Uname(buf *Utsname) (err error) //sysnb Uname(buf *Utsname) (err error)
//sys Unmount(target string, flags int) (err error) = libc.umount //sys Unmount(target string, flags int) (err error) = libc.umount
//sys Unlink(path string) (err error) //sys Unlink(path string) (err error)
//sys Unlinkat(dirfd int, path string) (err error) //sys Unlinkat(dirfd int, path string, flags int) (err error)
//sys Ustat(dev int, ubuf *Ustat_t) (err error) //sys Ustat(dev int, ubuf *Ustat_t) (err error)
//sys Utime(path string, buf *Utimbuf) (err error) //sys Utime(path string, buf *Utimbuf) (err error)
//sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) = libsocket.bind //sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) = libsocket.bind

View File

@ -14,8 +14,6 @@ func NsecToTimespec(nsec int64) (ts Timespec) {
return return
} }
func TimevalToNsec(tv Timeval) int64 { return int64(tv.Sec)*1e9 + int64(tv.Usec)*1e3 }
func NsecToTimeval(nsec int64) (tv Timeval) { func NsecToTimeval(nsec int64) (tv Timeval) {
nsec += 999 // round up to microsecond nsec += 999 // round up to microsecond
tv.Usec = nsec % 1e9 / 1e3 tv.Usec = nsec % 1e9 / 1e3

View File

@ -49,11 +49,6 @@ func errnoErr(e syscall.Errno) error {
return e return e
} }
func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno)
func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno)
func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno)
func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno)
// Mmap manager, for use by operating system-specific implementations. // Mmap manager, for use by operating system-specific implementations.
type mmapper struct { type mmapper struct {

15
vendor/golang.org/x/sys/unix/syscall_unix_gc.go generated vendored Normal file
View File

@ -0,0 +1,15 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build darwin dragonfly freebsd linux netbsd openbsd solaris
// +build !gccgo
package unix
import "syscall"
func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno)
func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno)
func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno)
func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno)

View File

@ -24,6 +24,7 @@ package unix
#include <netinet/in.h> #include <netinet/in.h>
#include <netinet/tcp.h> #include <netinet/tcp.h>
#include <netpacket/packet.h> #include <netpacket/packet.h>
#include <poll.h>
#include <signal.h> #include <signal.h>
#include <stdio.h> #include <stdio.h>
#include <sys/epoll.h> #include <sys/epoll.h>
@ -55,6 +56,9 @@ package unix
#include <unistd.h> #include <unistd.h>
#include <ustat.h> #include <ustat.h>
#include <utime.h> #include <utime.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#include <linux/can.h>
#ifdef TCSETS2 #ifdef TCSETS2
// On systems that have "struct termios2" use this as type Termios. // On systems that have "struct termios2" use this as type Termios.
@ -98,17 +102,36 @@ typedef struct user_regs PtraceRegs;
typedef struct user_pt_regs PtraceRegs; typedef struct user_pt_regs PtraceRegs;
#elif defined(__powerpc64__) #elif defined(__powerpc64__)
typedef struct pt_regs PtraceRegs; typedef struct pt_regs PtraceRegs;
#elif defined(__mips__)
typedef struct user PtraceRegs;
#elif defined(__s390x__)
typedef struct _user_regs_struct PtraceRegs;
#elif defined(__sparc__)
#include <asm/ptrace.h>
typedef struct pt_regs PtraceRegs;
#else #else
typedef struct user_regs_struct PtraceRegs; typedef struct user_regs_struct PtraceRegs;
#endif #endif
#if defined(__s390x__)
typedef struct _user_psw_struct ptracePsw;
typedef struct _user_fpregs_struct ptraceFpregs;
typedef struct _user_per_struct ptracePer;
#else
typedef struct {} ptracePsw;
typedef struct {} ptraceFpregs;
typedef struct {} ptracePer;
#endif
// The real epoll_event is a union, and godefs doesn't handle it well. // The real epoll_event is a union, and godefs doesn't handle it well.
struct my_epoll_event { struct my_epoll_event {
uint32_t events; uint32_t events;
#ifdef __ARM_EABI__ #if defined(__ARM_EABI__) || defined(__aarch64__) || (defined(__mips__) && _MIPS_SIM == _ABIO32)
// padding is not specified in linux/eventpoll.h but added to conform to the // padding is not specified in linux/eventpoll.h but added to conform to the
// alignment requirements of EABI // alignment requirements of EABI
int32_t padFd; int32_t padFd;
#elif defined(__powerpc64__) || defined(__s390x__) || defined(__sparc__)
int32_t _padFd;
#endif #endif
int32_t fd; int32_t fd;
int32_t pad; int32_t pad;
@ -194,6 +217,10 @@ type RawSockaddrLinklayer C.struct_sockaddr_ll
type RawSockaddrNetlink C.struct_sockaddr_nl type RawSockaddrNetlink C.struct_sockaddr_nl
type RawSockaddrHCI C.struct_sockaddr_hci
type RawSockaddrCAN C.struct_sockaddr_can
type RawSockaddr C.struct_sockaddr type RawSockaddr C.struct_sockaddr
type RawSockaddrAny C.struct_sockaddr_any type RawSockaddrAny C.struct_sockaddr_any
@ -233,6 +260,8 @@ const (
SizeofSockaddrUnix = C.sizeof_struct_sockaddr_un SizeofSockaddrUnix = C.sizeof_struct_sockaddr_un
SizeofSockaddrLinklayer = C.sizeof_struct_sockaddr_ll SizeofSockaddrLinklayer = C.sizeof_struct_sockaddr_ll
SizeofSockaddrNetlink = C.sizeof_struct_sockaddr_nl SizeofSockaddrNetlink = C.sizeof_struct_sockaddr_nl
SizeofSockaddrHCI = C.sizeof_struct_sockaddr_hci
SizeofSockaddrCAN = C.sizeof_struct_sockaddr_can
SizeofLinger = C.sizeof_struct_linger SizeofLinger = C.sizeof_struct_linger
SizeofIPMreq = C.sizeof_struct_ip_mreq SizeofIPMreq = C.sizeof_struct_ip_mreq
SizeofIPMreqn = C.sizeof_struct_ip_mreqn SizeofIPMreqn = C.sizeof_struct_ip_mreqn
@ -383,6 +412,13 @@ const SizeofInotifyEvent = C.sizeof_struct_inotify_event
// Register structures // Register structures
type PtraceRegs C.PtraceRegs type PtraceRegs C.PtraceRegs
// Structures contained in PtraceRegs on s390x (exported by mkpost.go)
type ptracePsw C.ptracePsw
type ptraceFpregs C.ptraceFpregs
type ptracePer C.ptracePer
// Misc // Misc
type FdSet C.fd_set type FdSet C.fd_set
@ -398,9 +434,28 @@ type EpollEvent C.struct_my_epoll_event
const ( const (
AT_FDCWD = C.AT_FDCWD AT_FDCWD = C.AT_FDCWD
AT_REMOVEDIR = C.AT_REMOVEDIR AT_REMOVEDIR = C.AT_REMOVEDIR
AT_SYMLINK_FOLLOW = C.AT_SYMLINK_FOLLOW
AT_SYMLINK_NOFOLLOW = C.AT_SYMLINK_NOFOLLOW AT_SYMLINK_NOFOLLOW = C.AT_SYMLINK_NOFOLLOW
) )
type PollFd C.struct_pollfd
const (
POLLIN = C.POLLIN
POLLPRI = C.POLLPRI
POLLOUT = C.POLLOUT
POLLRDHUP = C.POLLRDHUP
POLLERR = C.POLLERR
POLLHUP = C.POLLHUP
POLLNVAL = C.POLLNVAL
)
type Sigset_t C.sigset_t
// sysconf information
const _SC_PAGESIZE = C._SC_PAGESIZE
// Terminal handling // Terminal handling
type Termios C.termios_t type Termios C.termios_t

View File

@ -22,6 +22,7 @@ package unix
#define __USE_LEGACY_PROTOTYPES__ // iovec #define __USE_LEGACY_PROTOTYPES__ // iovec
#include <dirent.h> #include <dirent.h>
#include <fcntl.h> #include <fcntl.h>
#include <netdb.h>
#include <limits.h> #include <limits.h>
#include <signal.h> #include <signal.h>
#include <termios.h> #include <termios.h>
@ -81,6 +82,7 @@ const (
sizeofLong = C.sizeof_long sizeofLong = C.sizeof_long
sizeofLongLong = C.sizeof_longlong sizeofLongLong = C.sizeof_longlong
PathMax = C.PATH_MAX PathMax = C.PATH_MAX
MaxHostNameLen = C.MAXHOSTNAMELEN
) )
// Basic types // Basic types

File diff suppressed because it is too large Load Diff

View File

@ -190,6 +190,25 @@ const (
BS0 = 0x0 BS0 = 0x0
BS1 = 0x2000 BS1 = 0x2000
BSDLY = 0x2000 BSDLY = 0x2000
CAN_BCM = 0x2
CAN_EFF_FLAG = 0x80000000
CAN_EFF_ID_BITS = 0x1d
CAN_EFF_MASK = 0x1fffffff
CAN_ERR_FLAG = 0x20000000
CAN_ERR_MASK = 0x1fffffff
CAN_INV_FILTER = 0x20000000
CAN_ISOTP = 0x6
CAN_MAX_DLC = 0x8
CAN_MAX_DLEN = 0x8
CAN_MCNET = 0x5
CAN_MTU = 0x10
CAN_NPROTO = 0x7
CAN_RAW = 0x1
CAN_RTR_FLAG = 0x40000000
CAN_SFF_ID_BITS = 0xb
CAN_SFF_MASK = 0x7ff
CAN_TP16 = 0x3
CAN_TP20 = 0x4
CBAUD = 0x100f CBAUD = 0x100f
CBAUDEX = 0x1000 CBAUDEX = 0x1000
CFLUSH = 0xf CFLUSH = 0xf
@ -216,6 +235,7 @@ const (
CLONE_FILES = 0x400 CLONE_FILES = 0x400
CLONE_FS = 0x200 CLONE_FS = 0x200
CLONE_IO = 0x80000000 CLONE_IO = 0x80000000
CLONE_NEWCGROUP = 0x2000000
CLONE_NEWIPC = 0x8000000 CLONE_NEWIPC = 0x8000000
CLONE_NEWNET = 0x40000000 CLONE_NEWNET = 0x40000000
CLONE_NEWNS = 0x20000 CLONE_NEWNS = 0x20000
@ -826,6 +846,7 @@ const (
O_RDWR = 0x2 O_RDWR = 0x2
O_RSYNC = 0x101000 O_RSYNC = 0x101000
O_SYNC = 0x101000 O_SYNC = 0x101000
O_TMPFILE = 0x410000
O_TRUNC = 0x200 O_TRUNC = 0x200
O_WRONLY = 0x1 O_WRONLY = 0x1
PACKET_ADD_MEMBERSHIP = 0x1 PACKET_ADD_MEMBERSHIP = 0x1

View File

@ -190,6 +190,25 @@ const (
BS0 = 0x0 BS0 = 0x0
BS1 = 0x2000 BS1 = 0x2000
BSDLY = 0x2000 BSDLY = 0x2000
CAN_BCM = 0x2
CAN_EFF_FLAG = 0x80000000
CAN_EFF_ID_BITS = 0x1d
CAN_EFF_MASK = 0x1fffffff
CAN_ERR_FLAG = 0x20000000
CAN_ERR_MASK = 0x1fffffff
CAN_INV_FILTER = 0x20000000
CAN_ISOTP = 0x6
CAN_MAX_DLC = 0x8
CAN_MAX_DLEN = 0x8
CAN_MCNET = 0x5
CAN_MTU = 0x10
CAN_NPROTO = 0x7
CAN_RAW = 0x1
CAN_RTR_FLAG = 0x40000000
CAN_SFF_ID_BITS = 0xb
CAN_SFF_MASK = 0x7ff
CAN_TP16 = 0x3
CAN_TP20 = 0x4
CBAUD = 0x100f CBAUD = 0x100f
CBAUDEX = 0x1000 CBAUDEX = 0x1000
CFLUSH = 0xf CFLUSH = 0xf
@ -216,6 +235,7 @@ const (
CLONE_FILES = 0x400 CLONE_FILES = 0x400
CLONE_FS = 0x200 CLONE_FS = 0x200
CLONE_IO = 0x80000000 CLONE_IO = 0x80000000
CLONE_NEWCGROUP = 0x2000000
CLONE_NEWIPC = 0x8000000 CLONE_NEWIPC = 0x8000000
CLONE_NEWNET = 0x40000000 CLONE_NEWNET = 0x40000000
CLONE_NEWNS = 0x20000 CLONE_NEWNS = 0x20000
@ -826,6 +846,7 @@ const (
O_RDWR = 0x2 O_RDWR = 0x2
O_RSYNC = 0x101000 O_RSYNC = 0x101000
O_SYNC = 0x101000 O_SYNC = 0x101000
O_TMPFILE = 0x410000
O_TRUNC = 0x200 O_TRUNC = 0x200
O_WRONLY = 0x1 O_WRONLY = 0x1
PACKET_ADD_MEMBERSHIP = 0x1 PACKET_ADD_MEMBERSHIP = 0x1

View File

@ -186,6 +186,25 @@ const (
BS0 = 0x0 BS0 = 0x0
BS1 = 0x2000 BS1 = 0x2000
BSDLY = 0x2000 BSDLY = 0x2000
CAN_BCM = 0x2
CAN_EFF_FLAG = 0x80000000
CAN_EFF_ID_BITS = 0x1d
CAN_EFF_MASK = 0x1fffffff
CAN_ERR_FLAG = 0x20000000
CAN_ERR_MASK = 0x1fffffff
CAN_INV_FILTER = 0x20000000
CAN_ISOTP = 0x6
CAN_MAX_DLC = 0x8
CAN_MAX_DLEN = 0x8
CAN_MCNET = 0x5
CAN_MTU = 0x10
CAN_NPROTO = 0x7
CAN_RAW = 0x1
CAN_RTR_FLAG = 0x40000000
CAN_SFF_ID_BITS = 0xb
CAN_SFF_MASK = 0x7ff
CAN_TP16 = 0x3
CAN_TP20 = 0x4
CBAUD = 0x100f CBAUD = 0x100f
CBAUDEX = 0x1000 CBAUDEX = 0x1000
CFLUSH = 0xf CFLUSH = 0xf
@ -212,6 +231,7 @@ const (
CLONE_FILES = 0x400 CLONE_FILES = 0x400
CLONE_FS = 0x200 CLONE_FS = 0x200
CLONE_IO = 0x80000000 CLONE_IO = 0x80000000
CLONE_NEWCGROUP = 0x2000000
CLONE_NEWIPC = 0x8000000 CLONE_NEWIPC = 0x8000000
CLONE_NEWNET = 0x40000000 CLONE_NEWNET = 0x40000000
CLONE_NEWNS = 0x20000 CLONE_NEWNS = 0x20000

View File

@ -196,6 +196,25 @@ const (
BS0 = 0x0 BS0 = 0x0
BS1 = 0x2000 BS1 = 0x2000
BSDLY = 0x2000 BSDLY = 0x2000
CAN_BCM = 0x2
CAN_EFF_FLAG = 0x80000000
CAN_EFF_ID_BITS = 0x1d
CAN_EFF_MASK = 0x1fffffff
CAN_ERR_FLAG = 0x20000000
CAN_ERR_MASK = 0x1fffffff
CAN_INV_FILTER = 0x20000000
CAN_ISOTP = 0x6
CAN_MAX_DLC = 0x8
CAN_MAX_DLEN = 0x8
CAN_MCNET = 0x5
CAN_MTU = 0x10
CAN_NPROTO = 0x7
CAN_RAW = 0x1
CAN_RTR_FLAG = 0x40000000
CAN_SFF_ID_BITS = 0xb
CAN_SFF_MASK = 0x7ff
CAN_TP16 = 0x3
CAN_TP20 = 0x4
CBAUD = 0x100f CBAUD = 0x100f
CBAUDEX = 0x1000 CBAUDEX = 0x1000
CFLUSH = 0xf CFLUSH = 0xf
@ -222,6 +241,7 @@ const (
CLONE_FILES = 0x400 CLONE_FILES = 0x400
CLONE_FS = 0x200 CLONE_FS = 0x200
CLONE_IO = 0x80000000 CLONE_IO = 0x80000000
CLONE_NEWCGROUP = 0x2000000
CLONE_NEWIPC = 0x8000000 CLONE_NEWIPC = 0x8000000
CLONE_NEWNET = 0x40000000 CLONE_NEWNET = 0x40000000
CLONE_NEWNS = 0x20000 CLONE_NEWNS = 0x20000

1814
vendor/golang.org/x/sys/unix/zerrors_linux_mips.go generated vendored Normal file

File diff suppressed because it is too large Load Diff

1917
vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go generated vendored Normal file

File diff suppressed because it is too large Load Diff

1917
vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go generated vendored Normal file

File diff suppressed because it is too large Load Diff

2020
vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go generated vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -197,6 +197,25 @@ const (
BS0 = 0x0 BS0 = 0x0
BS1 = 0x8000 BS1 = 0x8000
BSDLY = 0x8000 BSDLY = 0x8000
CAN_BCM = 0x2
CAN_EFF_FLAG = 0x80000000
CAN_EFF_ID_BITS = 0x1d
CAN_EFF_MASK = 0x1fffffff
CAN_ERR_FLAG = 0x20000000
CAN_ERR_MASK = 0x1fffffff
CAN_INV_FILTER = 0x20000000
CAN_ISOTP = 0x6
CAN_MAX_DLC = 0x8
CAN_MAX_DLEN = 0x8
CAN_MCNET = 0x5
CAN_MTU = 0x10
CAN_NPROTO = 0x7
CAN_RAW = 0x1
CAN_RTR_FLAG = 0x40000000
CAN_SFF_ID_BITS = 0xb
CAN_SFF_MASK = 0x7ff
CAN_TP16 = 0x3
CAN_TP20 = 0x4
CBAUD = 0xff CBAUD = 0xff
CBAUDEX = 0x0 CBAUDEX = 0x0
CFLUSH = 0xf CFLUSH = 0xf
@ -223,6 +242,7 @@ const (
CLONE_FILES = 0x400 CLONE_FILES = 0x400
CLONE_FS = 0x200 CLONE_FS = 0x200
CLONE_IO = 0x80000000 CLONE_IO = 0x80000000
CLONE_NEWCGROUP = 0x2000000
CLONE_NEWIPC = 0x8000000 CLONE_NEWIPC = 0x8000000
CLONE_NEWNET = 0x40000000 CLONE_NEWNET = 0x40000000
CLONE_NEWNS = 0x20000 CLONE_NEWNS = 0x20000

View File

@ -196,6 +196,25 @@ const (
BS0 = 0x0 BS0 = 0x0
BS1 = 0x8000 BS1 = 0x8000
BSDLY = 0x8000 BSDLY = 0x8000
CAN_BCM = 0x2
CAN_EFF_FLAG = 0x80000000
CAN_EFF_ID_BITS = 0x1d
CAN_EFF_MASK = 0x1fffffff
CAN_ERR_FLAG = 0x20000000
CAN_ERR_MASK = 0x1fffffff
CAN_INV_FILTER = 0x20000000
CAN_ISOTP = 0x6
CAN_MAX_DLC = 0x8
CAN_MAX_DLEN = 0x8
CAN_MCNET = 0x5
CAN_MTU = 0x10
CAN_NPROTO = 0x7
CAN_RAW = 0x1
CAN_RTR_FLAG = 0x40000000
CAN_SFF_ID_BITS = 0xb
CAN_SFF_MASK = 0x7ff
CAN_TP16 = 0x3
CAN_TP20 = 0x4
CBAUD = 0xff CBAUD = 0xff
CBAUDEX = 0x0 CBAUDEX = 0x0
CFLUSH = 0xf CFLUSH = 0xf
@ -222,6 +241,7 @@ const (
CLONE_FILES = 0x400 CLONE_FILES = 0x400
CLONE_FS = 0x200 CLONE_FS = 0x200
CLONE_IO = 0x80000000 CLONE_IO = 0x80000000
CLONE_NEWCGROUP = 0x2000000
CLONE_NEWIPC = 0x8000000 CLONE_NEWIPC = 0x8000000
CLONE_NEWNET = 0x40000000 CLONE_NEWNET = 0x40000000
CLONE_NEWNS = 0x20000 CLONE_NEWNS = 0x20000

2046
vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go generated vendored Normal file

File diff suppressed because it is too large Load Diff

2096
vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go generated vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -222,6 +222,7 @@ func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr)
_p0 = unsafe.Pointer(&_zero) _p0 = unsafe.Pointer(&_zero)
} }
_, _, e1 := Syscall6(SYS___SYSCTL, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen)) _, _, e1 := Syscall6(SYS___SYSCTL, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
use(_p0)
if e1 != 0 { if e1 != 0 {
err = errnoErr(e1) err = errnoErr(e1)
} }

View File

@ -222,6 +222,7 @@ func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr)
_p0 = unsafe.Pointer(&_zero) _p0 = unsafe.Pointer(&_zero)
} }
_, _, e1 := Syscall6(SYS___SYSCTL, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen)) _, _, e1 := Syscall6(SYS___SYSCTL, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
use(_p0)
if e1 != 0 { if e1 != 0 {
err = errnoErr(e1) err = errnoErr(e1)
} }

View File

@ -222,6 +222,7 @@ func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr)
_p0 = unsafe.Pointer(&_zero) _p0 = unsafe.Pointer(&_zero)
} }
_, _, e1 := Syscall6(SYS___SYSCTL, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen)) _, _, e1 := Syscall6(SYS___SYSCTL, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
use(_p0)
if e1 != 0 { if e1 != 0 {
err = errnoErr(e1) err = errnoErr(e1)
} }

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