diff --git a/glide.lock b/glide.lock
index 6eaed216..a78ff2ef 100644
--- a/glide.lock
+++ b/glide.lock
@@ -1,5 +1,5 @@
-hash: 90e72dd70a9102940fc6126afc2d7d73ee79faaf75cecb3710b15f5a121c67ce
-updated: 2016-11-11T15:36:41.356471726+01:00
+hash: 3244008146f5de85e444b1e7e9b2ec760ad143127b4b193968a6d5e293039d1c
+updated: 2017-05-02T15:32:01.996561192-04:00
imports:
- name: github.com/beorn7/perks
version: b965b613227fddccbfffe13eae360ed3fa822f8d
@@ -21,7 +21,7 @@ imports:
subpackages:
- spew
- name: github.com/fatih/color
- version: 1b35f289c47d5c73c398cea8e006b7bcb6234a96
+ version: 87d4004f2ab62d0d255e0a38f1680aa534549fe3
- name: github.com/fernet/fernet-go
version: 1b2437bc582b3cfbb341ee5a29f8ef5b42912ff2
- name: github.com/go-sql-driver/mysql
@@ -80,14 +80,14 @@ imports:
version: 406e5b7bfd8201a36e2bb5f7bdae0b03380c2ce8
- name: github.com/remind101/migrate
version: d22d647232c20dbea6d2aa1dda7f2737cccce614
-- name: github.com/shiena/ansicolor
- version: a422bbe96644373c5753384a59d678f7d261ff10
+- name: github.com/sirupsen/logrus
+ version: ba1b36c82c5e05c4f912a88eab0dcd91a171688f
- name: github.com/stretchr/testify
version: 5b9da39b66e8e994455c2525c4421c8cc00a7f93
subpackages:
- assert
- name: github.com/tylerb/graceful
- version: 84177357ab104029f9237abcb52339a7b80760ef
+ version: 4654dfbb6ad53cb5e27f37d99b02e16c1872fbbb
- name: github.com/ziutek/mymysql
version: 75ce5fbba34b1912a3641adbd58cf317d7315821
subpackages:
@@ -98,6 +98,10 @@ imports:
version: 1d7a0b2100da090d8b02afcfb42f97e2c77e71a4
subpackages:
- netutil
+- name: golang.org/x/sys
+ version: 9ccfe848b9db8435a24c424abbc07a921adf1df5
+ subpackages:
+ - unix
- name: gopkg.in/yaml.v2
version: f7716cbe52baa25d2e9b0d0da546fcf909fc16b4
-devImports: []
+testImports: []
diff --git a/glide.yaml b/glide.yaml
index 80a1800f..bc583846 100644
--- a/glide.yaml
+++ b/glide.yaml
@@ -91,3 +91,5 @@ import:
version: ^0.1.0
- package: github.com/kr/text
- package: github.com/remind101/migrate
+- package: github.com/sirupsen/logrus
+ version: ^0.11.5
\ No newline at end of file
diff --git a/vendor/github.com/fatih/color/.travis.yml b/vendor/github.com/fatih/color/.travis.yml
index 2405aef3..57b4b57c 100644
--- a/vendor/github.com/fatih/color/.travis.yml
+++ b/vendor/github.com/fatih/color/.travis.yml
@@ -1,3 +1,5 @@
language: go
-go: 1.3
+go:
+ - 1.6
+ - tip
diff --git a/vendor/github.com/fatih/color/README.md b/vendor/github.com/fatih/color/README.md
index d6fb06a3..0921f98a 100644
--- a/vendor/github.com/fatih/color/README.md
+++ b/vendor/github.com/fatih/color/README.md
@@ -2,7 +2,10 @@
-Color lets you use colorized outputs in terms of [ANSI Escape Codes](http://en.wikipedia.org/wiki/ANSI_escape_code#Colors) in Go (Golang). It has support for Windows too! The API can be used in several ways, pick one that suits you.
+Color lets you use colorized outputs in terms of [ANSI Escape
+Codes](http://en.wikipedia.org/wiki/ANSI_escape_code#Colors) in Go (Golang). It
+has support for Windows too! The API can be used in several ways, pick one that
+suits you.
@@ -143,7 +146,7 @@ c.Println("This prints again cyan...")
## Credits
* [Fatih Arslan](https://github.com/fatih)
- * Windows support via @shiena: [ansicolor](https://github.com/shiena/ansicolor)
+ * Windows support via @mattn: [colorable](https://github.com/mattn/go-colorable)
## License
diff --git a/vendor/github.com/fatih/color/color.go b/vendor/github.com/fatih/color/color.go
index 6a8ee935..e3e99728 100644
--- a/vendor/github.com/fatih/color/color.go
+++ b/vendor/github.com/fatih/color/color.go
@@ -6,13 +6,15 @@ import (
"strconv"
"strings"
- "github.com/shiena/ansicolor"
+ "github.com/mattn/go-colorable"
+ "github.com/mattn/go-isatty"
)
-// NoColor defines if the output is colorized or not. By default it's set to
-// false. This is a global option and affects all colors. For more control over
-// each color block use the methods DisableColor() individually.
-var NoColor = false
+// NoColor defines if the output is colorized or not. It's dynamically set to
+// false or true based on the stdout's file descriptor referring to a terminal
+// or not. This is a global option and affects all colors. For more control
+// over each color block use the methods DisableColor() individually.
+var NoColor = !isatty.IsTerminal(os.Stdout.Fd())
// Color defines a custom color object which is defined by SGR parameters.
type Color struct {
@@ -51,6 +53,18 @@ const (
FgWhite
)
+// Foreground Hi-Intensity text colors
+const (
+ FgHiBlack Attribute = iota + 90
+ FgHiRed
+ FgHiGreen
+ FgHiYellow
+ FgHiBlue
+ FgHiMagenta
+ FgHiCyan
+ FgHiWhite
+)
+
// Background text colors
const (
BgBlack Attribute = iota + 40
@@ -63,6 +77,18 @@ const (
BgWhite
)
+// Background Hi-Intensity text colors
+const (
+ BgHiBlack Attribute = iota + 100
+ BgHiRed
+ BgHiGreen
+ BgHiYellow
+ BgHiBlue
+ BgHiMagenta
+ BgHiCyan
+ BgHiWhite
+)
+
// New returns a newly created color object.
func New(value ...Attribute) *Color {
c := &Color{params: make([]Attribute, 0)}
@@ -121,7 +147,7 @@ func (c *Color) prepend(value Attribute) {
// Output defines the standard output of the print functions. By default
// os.Stdout is used.
-var Output = ansicolor.NewAnsiColorWriter(os.Stdout)
+var Output = colorable.NewColorableStdout()
// Print formats using the default formats for its operands and writes to
// standard output. Spaces are added between operands when neither is a
@@ -180,7 +206,7 @@ func (c *Color) PrintlnFunc() func(a ...interface{}) {
// string. Windows users should use this in conjuction with color.Output, example:
//
// put := New(FgYellow).SprintFunc()
-// fmt.Ffprintf(color.Output, "This is a %s", put("warning"))
+// fmt.Fprintf(color.Output, "This is a %s", put("warning"))
func (c *Color) SprintFunc() func(a ...interface{}) string {
return func(a ...interface{}) string {
return c.wrap(fmt.Sprint(a...))
@@ -257,6 +283,31 @@ func (c *Color) isNoColorSet() bool {
return NoColor
}
+// Equals returns a boolean value indicating whether two colors are equal.
+func (c *Color) Equals(c2 *Color) bool {
+ if len(c.params) != len(c2.params) {
+ return false
+ }
+
+ for _, attr := range c.params {
+ if !c2.attrExists(attr) {
+ return false
+ }
+ }
+
+ return true
+}
+
+func (c *Color) attrExists(a Attribute) bool {
+ for _, attr := range c.params {
+ if attr == a {
+ return true
+ }
+ }
+
+ return false
+}
+
func boolPtr(v bool) *bool {
return &v
}
diff --git a/vendor/github.com/fatih/color/color_test.go b/vendor/github.com/fatih/color/color_test.go
index a1192b55..80285358 100644
--- a/vendor/github.com/fatih/color/color_test.go
+++ b/vendor/github.com/fatih/color/color_test.go
@@ -3,10 +3,9 @@ package color
import (
"bytes"
"fmt"
- "os"
"testing"
- "github.com/shiena/ansicolor"
+ "github.com/mattn/go-colorable"
)
// Testing colors is kinda different. First we test for given colors and their
@@ -16,6 +15,8 @@ func TestColor(t *testing.T) {
rb := new(bytes.Buffer)
Output = rb
+ NoColor = false
+
testColors := []struct {
text string
code Attribute
@@ -28,6 +29,14 @@ func TestColor(t *testing.T) {
{text: "magent", code: FgMagenta},
{text: "cyan", code: FgCyan},
{text: "white", code: FgWhite},
+ {text: "hblack", code: FgHiBlack},
+ {text: "hred", code: FgHiRed},
+ {text: "hgreen", code: FgHiGreen},
+ {text: "hyellow", code: FgHiYellow},
+ {text: "hblue", code: FgHiBlue},
+ {text: "hmagent", code: FgHiMagenta},
+ {text: "hcyan", code: FgHiCyan},
+ {text: "hwhite", code: FgHiWhite},
}
for _, c := range testColors {
@@ -46,6 +55,40 @@ func TestColor(t *testing.T) {
}
}
+func TestColorEquals(t *testing.T) {
+ fgblack1 := New(FgBlack)
+ fgblack2 := New(FgBlack)
+ bgblack := New(BgBlack)
+ fgbgblack := New(FgBlack, BgBlack)
+ fgblackbgred := New(FgBlack, BgRed)
+ fgred := New(FgRed)
+ bgred := New(BgRed)
+
+ if !fgblack1.Equals(fgblack2) {
+ t.Error("Two black colors are not equal")
+ }
+
+ if fgblack1.Equals(bgblack) {
+ t.Error("Fg and bg black colors are equal")
+ }
+
+ if fgblack1.Equals(fgbgblack) {
+ t.Error("Fg black equals fg/bg black color")
+ }
+
+ if fgblack1.Equals(fgred) {
+ t.Error("Fg black equals Fg red")
+ }
+
+ if fgblack1.Equals(bgred) {
+ t.Error("Fg black equals Bg red")
+ }
+
+ if fgblack1.Equals(fgblackbgred) {
+ t.Error("Fg black equals fg black bg red")
+ }
+}
+
func TestNoColor(t *testing.T) {
rb := new(bytes.Buffer)
Output = rb
@@ -62,6 +105,14 @@ func TestNoColor(t *testing.T) {
{text: "magent", code: FgMagenta},
{text: "cyan", code: FgCyan},
{text: "white", code: FgWhite},
+ {text: "hblack", code: FgHiBlack},
+ {text: "hred", code: FgHiRed},
+ {text: "hgreen", code: FgHiGreen},
+ {text: "hyellow", code: FgHiYellow},
+ {text: "hblue", code: FgHiBlue},
+ {text: "hmagent", code: FgHiMagenta},
+ {text: "hcyan", code: FgHiCyan},
+ {text: "hwhite", code: FgHiWhite},
}
for _, c := range testColors {
@@ -94,8 +145,7 @@ func TestNoColor(t *testing.T) {
func TestColorVisual(t *testing.T) {
// First Visual Test
- fmt.Println("")
- Output = ansicolor.NewAnsiColorWriter(os.Stdout)
+ Output = colorable.NewColorableStdout()
New(FgRed).Printf("red\t")
New(BgRed).Print(" ")
diff --git a/vendor/github.com/shiena/ansicolor/.gitignore b/vendor/github.com/shiena/ansicolor/.gitignore
deleted file mode 100644
index 69cec52c..00000000
--- a/vendor/github.com/shiena/ansicolor/.gitignore
+++ /dev/null
@@ -1,27 +0,0 @@
-# Created by http://www.gitignore.io
-
-### Go ###
-# Compiled Object files, Static and Dynamic libs (Shared Objects)
-*.o
-*.a
-*.so
-
-# Folders
-_obj
-_test
-
-# Architecture specific extensions/prefixes
-*.[568vq]
-[568vq].out
-
-*.cgo1.go
-*.cgo2.c
-_cgo_defun.c
-_cgo_gotypes.go
-_cgo_export.*
-
-_testmain.go
-
-*.exe
-*.test
-
diff --git a/vendor/github.com/shiena/ansicolor/README.md b/vendor/github.com/shiena/ansicolor/README.md
deleted file mode 100644
index cf2ae405..00000000
--- a/vendor/github.com/shiena/ansicolor/README.md
+++ /dev/null
@@ -1,101 +0,0 @@
-[](https://godoc.org/github.com/shiena/ansicolor)
-
-# ansicolor
-
-Ansicolor library provides color console in Windows as ANSICON for Golang.
-
-## Features
-
-|Escape sequence|Text attributes|
-|---------------|----|
-|\x1b[0m|All attributes off(color at startup)|
-|\x1b[1m|Bold on(enable foreground intensity)|
-|\x1b[4m|Underline on|
-|\x1b[5m|Blink on(enable background intensity)|
-|\x1b[21m|Bold off(disable foreground intensity)|
-|\x1b[24m|Underline off|
-|\x1b[25m|Blink off(disable background intensity)|
-
-|Escape sequence|Foreground colors|
-|---------------|----|
-|\x1b[30m|Black|
-|\x1b[31m|Red|
-|\x1b[32m|Green|
-|\x1b[33m|Yellow|
-|\x1b[34m|Blue|
-|\x1b[35m|Magenta|
-|\x1b[36m|Cyan|
-|\x1b[37m|White|
-|\x1b[39m|Default(foreground color at startup)|
-|\x1b[90m|Light Gray|
-|\x1b[91m|Light Red|
-|\x1b[92m|Light Green|
-|\x1b[93m|Light Yellow|
-|\x1b[94m|Light Blue|
-|\x1b[95m|Light Magenta|
-|\x1b[96m|Light Cyan|
-|\x1b[97m|Light White|
-
-|Escape sequence|Background colors|
-|---------------|----|
-|\x1b[40m|Black|
-|\x1b[41m|Red|
-|\x1b[42m|Green|
-|\x1b[43m|Yellow|
-|\x1b[44m|Blue|
-|\x1b[45m|Magenta|
-|\x1b[46m|Cyan|
-|\x1b[47m|White|
-|\x1b[49m|Default(background color at startup)|
-|\x1b[100m|Light Gray|
-|\x1b[101m|Light Red|
-|\x1b[102m|Light Green|
-|\x1b[103m|Light Yellow|
-|\x1b[104m|Light Blue|
-|\x1b[105m|Light Magenta|
-|\x1b[106m|Light Cyan|
-|\x1b[107m|Light White|
-
-## Example
-
-```go
-package main
-
-import (
- "fmt"
- "os"
-
- "github.com/shiena/ansicolor"
-)
-
-func main() {
- w := ansicolor.NewAnsiColorWriter(os.Stdout)
- text := "%sforeground %sbold%s %sbackground%s\n"
- fmt.Fprintf(w, text, "\x1b[31m", "\x1b[1m", "\x1b[21m", "\x1b[41;32m", "\x1b[0m")
- fmt.Fprintf(w, text, "\x1b[32m", "\x1b[1m", "\x1b[21m", "\x1b[42;31m", "\x1b[0m")
- fmt.Fprintf(w, text, "\x1b[33m", "\x1b[1m", "\x1b[21m", "\x1b[43;34m", "\x1b[0m")
- fmt.Fprintf(w, text, "\x1b[34m", "\x1b[1m", "\x1b[21m", "\x1b[44;33m", "\x1b[0m")
- fmt.Fprintf(w, text, "\x1b[35m", "\x1b[1m", "\x1b[21m", "\x1b[45;36m", "\x1b[0m")
- fmt.Fprintf(w, text, "\x1b[36m", "\x1b[1m", "\x1b[21m", "\x1b[46;35m", "\x1b[0m")
- fmt.Fprintf(w, text, "\x1b[37m", "\x1b[1m", "\x1b[21m", "\x1b[47;30m", "\x1b[0m")
-}
-```
-
-
-
-## See also:
-
-- https://github.com/daviddengcn/go-colortext
-- https://github.com/adoxa/ansicon
-- https://github.com/aslakhellesoy/wac
-- https://github.com/wsxiaoys/terminal
-- https://github.com/mattn/go-colorable
-
-## Contributing
-
-1. Fork it
-2. Create your feature branch (`git checkout -b my-new-feature`)
-3. Commit your changes (`git commit -am 'Add some feature'`)
-4. Push to the branch (`git push origin my-new-feature`)
-5. Create new Pull Request
-
diff --git a/vendor/github.com/shiena/ansicolor/ansicolor.go b/vendor/github.com/shiena/ansicolor/ansicolor.go
deleted file mode 100644
index 8551345b..00000000
--- a/vendor/github.com/shiena/ansicolor/ansicolor.go
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2014 shiena Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-// Package ansicolor provides color console in Windows as ANSICON.
-package ansicolor
-
-import "io"
-
-type outputMode int
-
-// DiscardNonColorEscSeq supports the divided color escape sequence.
-// But non-color escape sequence is not output.
-// Please use the OutputNonColorEscSeq If you want to output a non-color
-// escape sequences such as ncurses. However, it does not support the divided
-// color escape sequence.
-const (
- _ outputMode = iota
- DiscardNonColorEscSeq
- OutputNonColorEscSeq
-)
-
-// NewAnsiColorWriter creates and initializes a new ansiColorWriter
-// using io.Writer w as its initial contents.
-// In the console of Windows, which change the foreground and background
-// colors of the text by the escape sequence.
-// In the console of other systems, which writes to w all text.
-func NewAnsiColorWriter(w io.Writer) io.Writer {
- return NewModeAnsiColorWriter(w, DiscardNonColorEscSeq)
-}
-
-// NewModeAnsiColorWriter create and initializes a new ansiColorWriter
-// by specifying the outputMode.
-func NewModeAnsiColorWriter(w io.Writer, mode outputMode) io.Writer {
- if _, ok := w.(*ansiColorWriter); !ok {
- return &ansiColorWriter{
- w: w,
- mode: mode,
- }
- }
- return w
-}
diff --git a/vendor/github.com/shiena/ansicolor/ansicolor/main.go b/vendor/github.com/shiena/ansicolor/ansicolor/main.go
deleted file mode 100644
index d86cfc0f..00000000
--- a/vendor/github.com/shiena/ansicolor/ansicolor/main.go
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2014 shiena Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-/*
-
-The ansicolor command colors a console text by ANSI escape sequence like wac.
-
- $ go get github.com/shiena/ansicolor/ansicolor
-
-See also:
- https://github.com/aslakhellesoy/wac
-
-*/
-package main
-
-import (
- "io"
- "os"
-
- "github.com/shiena/ansicolor"
-)
-
-func main() {
- w := ansicolor.NewAnsiColorWriter(os.Stdout)
- io.Copy(w, os.Stdin)
-}
diff --git a/vendor/github.com/shiena/ansicolor/ansicolor_ansi.go b/vendor/github.com/shiena/ansicolor/ansicolor_ansi.go
deleted file mode 100644
index f4803bbb..00000000
--- a/vendor/github.com/shiena/ansicolor/ansicolor_ansi.go
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2014 shiena Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-// +build !windows
-
-package ansicolor
-
-import "io"
-
-type ansiColorWriter struct {
- w io.Writer
- mode outputMode
-}
-
-func (cw *ansiColorWriter) Write(p []byte) (int, error) {
- return cw.w.Write(p)
-}
diff --git a/vendor/github.com/shiena/ansicolor/ansicolor_test.go b/vendor/github.com/shiena/ansicolor/ansicolor_test.go
deleted file mode 100644
index fc76ed12..00000000
--- a/vendor/github.com/shiena/ansicolor/ansicolor_test.go
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2015 shiena Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package ansicolor_test
-
-import (
- "bytes"
- "testing"
-
- "github.com/shiena/ansicolor"
-)
-
-func TestNewAnsiColor1(t *testing.T) {
- inner := bytes.NewBufferString("")
- w := ansicolor.NewAnsiColorWriter(inner)
- if w == inner {
- t.Errorf("Get %#v, want %#v", w, inner)
- }
-}
-
-func TestNewAnsiColor2(t *testing.T) {
- inner := bytes.NewBufferString("")
- w1 := ansicolor.NewAnsiColorWriter(inner)
- w2 := ansicolor.NewAnsiColorWriter(w1)
- if w1 != w2 {
- t.Errorf("Get %#v, want %#v", w1, w2)
- }
-}
diff --git a/vendor/github.com/shiena/ansicolor/ansicolor_windows.go b/vendor/github.com/shiena/ansicolor/ansicolor_windows.go
deleted file mode 100644
index ff2ae0ef..00000000
--- a/vendor/github.com/shiena/ansicolor/ansicolor_windows.go
+++ /dev/null
@@ -1,417 +0,0 @@
-// Copyright 2014 shiena Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-// +build windows
-
-package ansicolor
-
-import (
- "bytes"
- "io"
- "strings"
- "syscall"
- "unsafe"
-)
-
-type csiState int
-
-const (
- outsideCsiCode csiState = iota
- firstCsiCode
- secondCsiCode
-)
-
-type parseResult int
-
-const (
- noConsole parseResult = iota
- changedColor
- unknown
-)
-
-type ansiColorWriter struct {
- w io.Writer
- mode outputMode
- state csiState
- paramStartBuf bytes.Buffer
- paramBuf bytes.Buffer
-}
-
-const (
- firstCsiChar byte = '\x1b'
- secondeCsiChar byte = '['
- separatorChar byte = ';'
- sgrCode byte = 'm'
-)
-
-const (
- foregroundBlue = uint16(0x0001)
- foregroundGreen = uint16(0x0002)
- foregroundRed = uint16(0x0004)
- foregroundIntensity = uint16(0x0008)
- backgroundBlue = uint16(0x0010)
- backgroundGreen = uint16(0x0020)
- backgroundRed = uint16(0x0040)
- backgroundIntensity = uint16(0x0080)
- underscore = uint16(0x8000)
-
- foregroundMask = foregroundBlue | foregroundGreen | foregroundRed | foregroundIntensity
- backgroundMask = backgroundBlue | backgroundGreen | backgroundRed | backgroundIntensity
-)
-
-const (
- ansiReset = "0"
- ansiIntensityOn = "1"
- ansiIntensityOff = "21"
- ansiUnderlineOn = "4"
- ansiUnderlineOff = "24"
- ansiBlinkOn = "5"
- ansiBlinkOff = "25"
-
- ansiForegroundBlack = "30"
- ansiForegroundRed = "31"
- ansiForegroundGreen = "32"
- ansiForegroundYellow = "33"
- ansiForegroundBlue = "34"
- ansiForegroundMagenta = "35"
- ansiForegroundCyan = "36"
- ansiForegroundWhite = "37"
- ansiForegroundDefault = "39"
-
- ansiBackgroundBlack = "40"
- ansiBackgroundRed = "41"
- ansiBackgroundGreen = "42"
- ansiBackgroundYellow = "43"
- ansiBackgroundBlue = "44"
- ansiBackgroundMagenta = "45"
- ansiBackgroundCyan = "46"
- ansiBackgroundWhite = "47"
- ansiBackgroundDefault = "49"
-
- ansiLightForegroundGray = "90"
- ansiLightForegroundRed = "91"
- ansiLightForegroundGreen = "92"
- ansiLightForegroundYellow = "93"
- ansiLightForegroundBlue = "94"
- ansiLightForegroundMagenta = "95"
- ansiLightForegroundCyan = "96"
- ansiLightForegroundWhite = "97"
-
- ansiLightBackgroundGray = "100"
- ansiLightBackgroundRed = "101"
- ansiLightBackgroundGreen = "102"
- ansiLightBackgroundYellow = "103"
- ansiLightBackgroundBlue = "104"
- ansiLightBackgroundMagenta = "105"
- ansiLightBackgroundCyan = "106"
- ansiLightBackgroundWhite = "107"
-)
-
-type drawType int
-
-const (
- foreground drawType = iota
- background
-)
-
-type winColor struct {
- code uint16
- drawType drawType
-}
-
-var colorMap = map[string]winColor{
- ansiForegroundBlack: {0, foreground},
- ansiForegroundRed: {foregroundRed, foreground},
- ansiForegroundGreen: {foregroundGreen, foreground},
- ansiForegroundYellow: {foregroundRed | foregroundGreen, foreground},
- ansiForegroundBlue: {foregroundBlue, foreground},
- ansiForegroundMagenta: {foregroundRed | foregroundBlue, foreground},
- ansiForegroundCyan: {foregroundGreen | foregroundBlue, foreground},
- ansiForegroundWhite: {foregroundRed | foregroundGreen | foregroundBlue, foreground},
- ansiForegroundDefault: {foregroundRed | foregroundGreen | foregroundBlue, foreground},
-
- ansiBackgroundBlack: {0, background},
- ansiBackgroundRed: {backgroundRed, background},
- ansiBackgroundGreen: {backgroundGreen, background},
- ansiBackgroundYellow: {backgroundRed | backgroundGreen, background},
- ansiBackgroundBlue: {backgroundBlue, background},
- ansiBackgroundMagenta: {backgroundRed | backgroundBlue, background},
- ansiBackgroundCyan: {backgroundGreen | backgroundBlue, background},
- ansiBackgroundWhite: {backgroundRed | backgroundGreen | backgroundBlue, background},
- ansiBackgroundDefault: {0, background},
-
- ansiLightForegroundGray: {foregroundIntensity, foreground},
- ansiLightForegroundRed: {foregroundIntensity | foregroundRed, foreground},
- ansiLightForegroundGreen: {foregroundIntensity | foregroundGreen, foreground},
- ansiLightForegroundYellow: {foregroundIntensity | foregroundRed | foregroundGreen, foreground},
- ansiLightForegroundBlue: {foregroundIntensity | foregroundBlue, foreground},
- ansiLightForegroundMagenta: {foregroundIntensity | foregroundRed | foregroundBlue, foreground},
- ansiLightForegroundCyan: {foregroundIntensity | foregroundGreen | foregroundBlue, foreground},
- ansiLightForegroundWhite: {foregroundIntensity | foregroundRed | foregroundGreen | foregroundBlue, foreground},
-
- ansiLightBackgroundGray: {backgroundIntensity, background},
- ansiLightBackgroundRed: {backgroundIntensity | backgroundRed, background},
- ansiLightBackgroundGreen: {backgroundIntensity | backgroundGreen, background},
- ansiLightBackgroundYellow: {backgroundIntensity | backgroundRed | backgroundGreen, background},
- ansiLightBackgroundBlue: {backgroundIntensity | backgroundBlue, background},
- ansiLightBackgroundMagenta: {backgroundIntensity | backgroundRed | backgroundBlue, background},
- ansiLightBackgroundCyan: {backgroundIntensity | backgroundGreen | backgroundBlue, background},
- ansiLightBackgroundWhite: {backgroundIntensity | backgroundRed | backgroundGreen | backgroundBlue, background},
-}
-
-var (
- kernel32 = syscall.NewLazyDLL("kernel32.dll")
- procSetConsoleTextAttribute = kernel32.NewProc("SetConsoleTextAttribute")
- procGetConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo")
- defaultAttr *textAttributes
-)
-
-func init() {
- screenInfo := getConsoleScreenBufferInfo(uintptr(syscall.Stdout))
- if screenInfo != nil {
- colorMap[ansiForegroundDefault] = winColor{
- screenInfo.WAttributes & (foregroundRed | foregroundGreen | foregroundBlue),
- foreground,
- }
- colorMap[ansiBackgroundDefault] = winColor{
- screenInfo.WAttributes & (backgroundRed | backgroundGreen | backgroundBlue),
- background,
- }
- defaultAttr = convertTextAttr(screenInfo.WAttributes)
- }
-}
-
-type coord struct {
- X, Y int16
-}
-
-type smallRect struct {
- Left, Top, Right, Bottom int16
-}
-
-type consoleScreenBufferInfo struct {
- DwSize coord
- DwCursorPosition coord
- WAttributes uint16
- SrWindow smallRect
- DwMaximumWindowSize coord
-}
-
-func getConsoleScreenBufferInfo(hConsoleOutput uintptr) *consoleScreenBufferInfo {
- var csbi consoleScreenBufferInfo
- ret, _, _ := procGetConsoleScreenBufferInfo.Call(
- hConsoleOutput,
- uintptr(unsafe.Pointer(&csbi)))
- if ret == 0 {
- return nil
- }
- return &csbi
-}
-
-func setConsoleTextAttribute(hConsoleOutput uintptr, wAttributes uint16) bool {
- ret, _, _ := procSetConsoleTextAttribute.Call(
- hConsoleOutput,
- uintptr(wAttributes))
- return ret != 0
-}
-
-type textAttributes struct {
- foregroundColor uint16
- backgroundColor uint16
- foregroundIntensity uint16
- backgroundIntensity uint16
- underscore uint16
- otherAttributes uint16
-}
-
-func convertTextAttr(winAttr uint16) *textAttributes {
- fgColor := winAttr & (foregroundRed | foregroundGreen | foregroundBlue)
- bgColor := winAttr & (backgroundRed | backgroundGreen | backgroundBlue)
- fgIntensity := winAttr & foregroundIntensity
- bgIntensity := winAttr & backgroundIntensity
- underline := winAttr & underscore
- otherAttributes := winAttr &^ (foregroundMask | backgroundMask | underscore)
- return &textAttributes{fgColor, bgColor, fgIntensity, bgIntensity, underline, otherAttributes}
-}
-
-func convertWinAttr(textAttr *textAttributes) uint16 {
- var winAttr uint16
- winAttr |= textAttr.foregroundColor
- winAttr |= textAttr.backgroundColor
- winAttr |= textAttr.foregroundIntensity
- winAttr |= textAttr.backgroundIntensity
- winAttr |= textAttr.underscore
- winAttr |= textAttr.otherAttributes
- return winAttr
-}
-
-func changeColor(param []byte) parseResult {
- screenInfo := getConsoleScreenBufferInfo(uintptr(syscall.Stdout))
- if screenInfo == nil {
- return noConsole
- }
-
- winAttr := convertTextAttr(screenInfo.WAttributes)
- strParam := string(param)
- if len(strParam) <= 0 {
- strParam = "0"
- }
- csiParam := strings.Split(strParam, string(separatorChar))
- for _, p := range csiParam {
- c, ok := colorMap[p]
- switch {
- case !ok:
- switch p {
- case ansiReset:
- winAttr.foregroundColor = defaultAttr.foregroundColor
- winAttr.backgroundColor = defaultAttr.backgroundColor
- winAttr.foregroundIntensity = defaultAttr.foregroundIntensity
- winAttr.backgroundIntensity = defaultAttr.backgroundIntensity
- winAttr.underscore = 0
- winAttr.otherAttributes = 0
- case ansiIntensityOn:
- winAttr.foregroundIntensity = foregroundIntensity
- case ansiIntensityOff:
- winAttr.foregroundIntensity = 0
- case ansiUnderlineOn:
- winAttr.underscore = underscore
- case ansiUnderlineOff:
- winAttr.underscore = 0
- case ansiBlinkOn:
- winAttr.backgroundIntensity = backgroundIntensity
- case ansiBlinkOff:
- winAttr.backgroundIntensity = 0
- default:
- // unknown code
- }
- case c.drawType == foreground:
- winAttr.foregroundColor = c.code
- case c.drawType == background:
- winAttr.backgroundColor = c.code
- }
- }
- winTextAttribute := convertWinAttr(winAttr)
- setConsoleTextAttribute(uintptr(syscall.Stdout), winTextAttribute)
-
- return changedColor
-}
-
-func parseEscapeSequence(command byte, param []byte) parseResult {
- if defaultAttr == nil {
- return noConsole
- }
-
- switch command {
- case sgrCode:
- return changeColor(param)
- default:
- return unknown
- }
-}
-
-func (cw *ansiColorWriter) flushBuffer() (int, error) {
- return cw.flushTo(cw.w)
-}
-
-func (cw *ansiColorWriter) resetBuffer() (int, error) {
- return cw.flushTo(nil)
-}
-
-func (cw *ansiColorWriter) flushTo(w io.Writer) (int, error) {
- var n1, n2 int
- var err error
-
- startBytes := cw.paramStartBuf.Bytes()
- cw.paramStartBuf.Reset()
- if w != nil {
- n1, err = cw.w.Write(startBytes)
- if err != nil {
- return n1, err
- }
- } else {
- n1 = len(startBytes)
- }
- paramBytes := cw.paramBuf.Bytes()
- cw.paramBuf.Reset()
- if w != nil {
- n2, err = cw.w.Write(paramBytes)
- if err != nil {
- return n1 + n2, err
- }
- } else {
- n2 = len(paramBytes)
- }
- return n1 + n2, nil
-}
-
-func isParameterChar(b byte) bool {
- return ('0' <= b && b <= '9') || b == separatorChar
-}
-
-func (cw *ansiColorWriter) Write(p []byte) (int, error) {
- r, nw, first, last := 0, 0, 0, 0
- if cw.mode != DiscardNonColorEscSeq {
- cw.state = outsideCsiCode
- cw.resetBuffer()
- }
-
- var err error
- for i, ch := range p {
- switch cw.state {
- case outsideCsiCode:
- if ch == firstCsiChar {
- cw.paramStartBuf.WriteByte(ch)
- cw.state = firstCsiCode
- }
- case firstCsiCode:
- switch ch {
- case firstCsiChar:
- cw.paramStartBuf.WriteByte(ch)
- break
- case secondeCsiChar:
- cw.paramStartBuf.WriteByte(ch)
- cw.state = secondCsiCode
- last = i - 1
- default:
- cw.resetBuffer()
- cw.state = outsideCsiCode
- }
- case secondCsiCode:
- if isParameterChar(ch) {
- cw.paramBuf.WriteByte(ch)
- } else {
- nw, err = cw.w.Write(p[first:last])
- r += nw
- if err != nil {
- return r, err
- }
- first = i + 1
- result := parseEscapeSequence(ch, cw.paramBuf.Bytes())
- if result == noConsole || (cw.mode == OutputNonColorEscSeq && result == unknown) {
- cw.paramBuf.WriteByte(ch)
- nw, err := cw.flushBuffer()
- if err != nil {
- return r, err
- }
- r += nw
- } else {
- n, _ := cw.resetBuffer()
- // Add one more to the size of the buffer for the last ch
- r += n + 1
- }
-
- cw.state = outsideCsiCode
- }
- default:
- cw.state = outsideCsiCode
- }
- }
-
- if cw.mode != DiscardNonColorEscSeq || cw.state == outsideCsiCode {
- nw, err = cw.w.Write(p[first:len(p)])
- r += nw
- }
-
- return r, err
-}
diff --git a/vendor/github.com/shiena/ansicolor/ansicolor_windows_test.go b/vendor/github.com/shiena/ansicolor/ansicolor_windows_test.go
deleted file mode 100644
index 3d8c53b9..00000000
--- a/vendor/github.com/shiena/ansicolor/ansicolor_windows_test.go
+++ /dev/null
@@ -1,277 +0,0 @@
-// Copyright 2014 shiena Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-// +build windows
-
-package ansicolor_test
-
-import (
- "bytes"
- "fmt"
- "syscall"
- "testing"
-
- "github.com/shiena/ansicolor"
- . "github.com/shiena/ansicolor"
-)
-
-func TestWritePlanText(t *testing.T) {
- inner := bytes.NewBufferString("")
- w := ansicolor.NewAnsiColorWriter(inner)
- expected := "plain text"
- fmt.Fprintf(w, expected)
- actual := inner.String()
- if actual != expected {
- t.Errorf("Get %q, want %q", actual, expected)
- }
-}
-
-func TestWriteParseText(t *testing.T) {
- inner := bytes.NewBufferString("")
- w := ansicolor.NewAnsiColorWriter(inner)
-
- inputTail := "\x1b[0mtail text"
- expectedTail := "tail text"
- fmt.Fprintf(w, inputTail)
- actualTail := inner.String()
- inner.Reset()
- if actualTail != expectedTail {
- t.Errorf("Get %q, want %q", actualTail, expectedTail)
- }
-
- inputHead := "head text\x1b[0m"
- expectedHead := "head text"
- fmt.Fprintf(w, inputHead)
- actualHead := inner.String()
- inner.Reset()
- if actualHead != expectedHead {
- t.Errorf("Get %q, want %q", actualHead, expectedHead)
- }
-
- inputBothEnds := "both ends \x1b[0m text"
- expectedBothEnds := "both ends text"
- fmt.Fprintf(w, inputBothEnds)
- actualBothEnds := inner.String()
- inner.Reset()
- if actualBothEnds != expectedBothEnds {
- t.Errorf("Get %q, want %q", actualBothEnds, expectedBothEnds)
- }
-
- inputManyEsc := "\x1b\x1b\x1b\x1b[0m many esc"
- expectedManyEsc := "\x1b\x1b\x1b many esc"
- fmt.Fprintf(w, inputManyEsc)
- actualManyEsc := inner.String()
- inner.Reset()
- if actualManyEsc != expectedManyEsc {
- t.Errorf("Get %q, want %q", actualManyEsc, expectedManyEsc)
- }
-
- expectedSplit := "split text"
- for _, ch := range "split \x1b[0m text" {
- fmt.Fprintf(w, string(ch))
- }
- actualSplit := inner.String()
- inner.Reset()
- if actualSplit != expectedSplit {
- t.Errorf("Get %q, want %q", actualSplit, expectedSplit)
- }
-}
-
-type screenNotFoundError struct {
- error
-}
-
-func writeAnsiColor(expectedText, colorCode string) (actualText string, actualAttributes uint16, err error) {
- inner := bytes.NewBufferString("")
- w := ansicolor.NewAnsiColorWriter(inner)
- fmt.Fprintf(w, "\x1b[%sm%s", colorCode, expectedText)
-
- actualText = inner.String()
- screenInfo := GetConsoleScreenBufferInfo(uintptr(syscall.Stdout))
- if screenInfo != nil {
- actualAttributes = screenInfo.WAttributes
- } else {
- err = &screenNotFoundError{}
- }
- return
-}
-
-type testParam struct {
- text string
- attributes uint16
- ansiColor string
-}
-
-func TestWriteAnsiColorText(t *testing.T) {
- screenInfo := GetConsoleScreenBufferInfo(uintptr(syscall.Stdout))
- if screenInfo == nil {
- t.Fatal("Could not get ConsoleScreenBufferInfo")
- }
- defer ChangeColor(screenInfo.WAttributes)
- defaultFgColor := screenInfo.WAttributes & uint16(0x0007)
- defaultBgColor := screenInfo.WAttributes & uint16(0x0070)
- defaultFgIntensity := screenInfo.WAttributes & uint16(0x0008)
- defaultBgIntensity := screenInfo.WAttributes & uint16(0x0080)
-
- fgParam := []testParam{
- {"foreground black ", uint16(0x0000 | 0x0000), "30"},
- {"foreground red ", uint16(0x0004 | 0x0000), "31"},
- {"foreground green ", uint16(0x0002 | 0x0000), "32"},
- {"foreground yellow ", uint16(0x0006 | 0x0000), "33"},
- {"foreground blue ", uint16(0x0001 | 0x0000), "34"},
- {"foreground magenta", uint16(0x0005 | 0x0000), "35"},
- {"foreground cyan ", uint16(0x0003 | 0x0000), "36"},
- {"foreground white ", uint16(0x0007 | 0x0000), "37"},
- {"foreground default", defaultFgColor | 0x0000, "39"},
- {"foreground light gray ", uint16(0x0000 | 0x0008 | 0x0000), "90"},
- {"foreground light red ", uint16(0x0004 | 0x0008 | 0x0000), "91"},
- {"foreground light green ", uint16(0x0002 | 0x0008 | 0x0000), "92"},
- {"foreground light yellow ", uint16(0x0006 | 0x0008 | 0x0000), "93"},
- {"foreground light blue ", uint16(0x0001 | 0x0008 | 0x0000), "94"},
- {"foreground light magenta", uint16(0x0005 | 0x0008 | 0x0000), "95"},
- {"foreground light cyan ", uint16(0x0003 | 0x0008 | 0x0000), "96"},
- {"foreground light white ", uint16(0x0007 | 0x0008 | 0x0000), "97"},
- }
-
- bgParam := []testParam{
- {"background black ", uint16(0x0007 | 0x0000), "40"},
- {"background red ", uint16(0x0007 | 0x0040), "41"},
- {"background green ", uint16(0x0007 | 0x0020), "42"},
- {"background yellow ", uint16(0x0007 | 0x0060), "43"},
- {"background blue ", uint16(0x0007 | 0x0010), "44"},
- {"background magenta", uint16(0x0007 | 0x0050), "45"},
- {"background cyan ", uint16(0x0007 | 0x0030), "46"},
- {"background white ", uint16(0x0007 | 0x0070), "47"},
- {"background default", uint16(0x0007) | defaultBgColor, "49"},
- {"background light gray ", uint16(0x0007 | 0x0000 | 0x0080), "100"},
- {"background light red ", uint16(0x0007 | 0x0040 | 0x0080), "101"},
- {"background light green ", uint16(0x0007 | 0x0020 | 0x0080), "102"},
- {"background light yellow ", uint16(0x0007 | 0x0060 | 0x0080), "103"},
- {"background light blue ", uint16(0x0007 | 0x0010 | 0x0080), "104"},
- {"background light magenta", uint16(0x0007 | 0x0050 | 0x0080), "105"},
- {"background light cyan ", uint16(0x0007 | 0x0030 | 0x0080), "106"},
- {"background light white ", uint16(0x0007 | 0x0070 | 0x0080), "107"},
- }
-
- resetParam := []testParam{
- {"all reset", defaultFgColor | defaultBgColor | defaultFgIntensity | defaultBgIntensity, "0"},
- {"all reset", defaultFgColor | defaultBgColor | defaultFgIntensity | defaultBgIntensity, ""},
- }
-
- boldParam := []testParam{
- {"bold on", uint16(0x0007 | 0x0008), "1"},
- {"bold off", uint16(0x0007), "21"},
- }
-
- underscoreParam := []testParam{
- {"underscore on", uint16(0x0007 | 0x8000), "4"},
- {"underscore off", uint16(0x0007), "24"},
- }
-
- blinkParam := []testParam{
- {"blink on", uint16(0x0007 | 0x0080), "5"},
- {"blink off", uint16(0x0007), "25"},
- }
-
- mixedParam := []testParam{
- {"both black, bold, underline, blink", uint16(0x0000 | 0x0000 | 0x0008 | 0x8000 | 0x0080), "30;40;1;4;5"},
- {"both red, bold, underline, blink", uint16(0x0004 | 0x0040 | 0x0008 | 0x8000 | 0x0080), "31;41;1;4;5"},
- {"both green, bold, underline, blink", uint16(0x0002 | 0x0020 | 0x0008 | 0x8000 | 0x0080), "32;42;1;4;5"},
- {"both yellow, bold, underline, blink", uint16(0x0006 | 0x0060 | 0x0008 | 0x8000 | 0x0080), "33;43;1;4;5"},
- {"both blue, bold, underline, blink", uint16(0x0001 | 0x0010 | 0x0008 | 0x8000 | 0x0080), "34;44;1;4;5"},
- {"both magenta, bold, underline, blink", uint16(0x0005 | 0x0050 | 0x0008 | 0x8000 | 0x0080), "35;45;1;4;5"},
- {"both cyan, bold, underline, blink", uint16(0x0003 | 0x0030 | 0x0008 | 0x8000 | 0x0080), "36;46;1;4;5"},
- {"both white, bold, underline, blink", uint16(0x0007 | 0x0070 | 0x0008 | 0x8000 | 0x0080), "37;47;1;4;5"},
- {"both default, bold, underline, blink", uint16(defaultFgColor | defaultBgColor | 0x0008 | 0x8000 | 0x0080), "39;49;1;4;5"},
- }
-
- assertTextAttribute := func(expectedText string, expectedAttributes uint16, ansiColor string) {
- actualText, actualAttributes, err := writeAnsiColor(expectedText, ansiColor)
- if actualText != expectedText {
- t.Errorf("Get %q, want %q", actualText, expectedText)
- }
- if err != nil {
- t.Fatal("Could not get ConsoleScreenBufferInfo")
- }
- if actualAttributes != expectedAttributes {
- t.Errorf("Text: %q, Get 0x%04x, want 0x%04x", expectedText, actualAttributes, expectedAttributes)
- }
- }
-
- for _, v := range fgParam {
- ResetColor()
- assertTextAttribute(v.text, v.attributes, v.ansiColor)
- }
-
- for _, v := range bgParam {
- ChangeColor(uint16(0x0070 | 0x0007))
- assertTextAttribute(v.text, v.attributes, v.ansiColor)
- }
-
- for _, v := range resetParam {
- ChangeColor(uint16(0x0000 | 0x0070 | 0x0008))
- assertTextAttribute(v.text, v.attributes, v.ansiColor)
- }
-
- ResetColor()
- for _, v := range boldParam {
- assertTextAttribute(v.text, v.attributes, v.ansiColor)
- }
-
- ResetColor()
- for _, v := range underscoreParam {
- assertTextAttribute(v.text, v.attributes, v.ansiColor)
- }
-
- ResetColor()
- for _, v := range blinkParam {
- assertTextAttribute(v.text, v.attributes, v.ansiColor)
- }
-
- for _, v := range mixedParam {
- ResetColor()
- assertTextAttribute(v.text, v.attributes, v.ansiColor)
- }
-}
-
-func TestIgnoreUnknownSequences(t *testing.T) {
- inner := bytes.NewBufferString("")
- w := ansicolor.NewModeAnsiColorWriter(inner, ansicolor.OutputNonColorEscSeq)
-
- inputText := "\x1b[=decpath mode"
- expectedTail := inputText
- fmt.Fprintf(w, inputText)
- actualTail := inner.String()
- inner.Reset()
- if actualTail != expectedTail {
- t.Errorf("Get %q, want %q", actualTail, expectedTail)
- }
-
- inputText = "\x1b[=tailing esc and bracket\x1b["
- expectedTail = inputText
- fmt.Fprintf(w, inputText)
- actualTail = inner.String()
- inner.Reset()
- if actualTail != expectedTail {
- t.Errorf("Get %q, want %q", actualTail, expectedTail)
- }
-
- inputText = "\x1b[?tailing esc\x1b"
- expectedTail = inputText
- fmt.Fprintf(w, inputText)
- actualTail = inner.String()
- inner.Reset()
- if actualTail != expectedTail {
- t.Errorf("Get %q, want %q", actualTail, expectedTail)
- }
-
- inputText = "\x1b[1h;3punended color code invalid\x1b3"
- expectedTail = inputText
- fmt.Fprintf(w, inputText)
- actualTail = inner.String()
- inner.Reset()
- if actualTail != expectedTail {
- t.Errorf("Get %q, want %q", actualTail, expectedTail)
- }
-}
diff --git a/vendor/github.com/shiena/ansicolor/example_test.go b/vendor/github.com/shiena/ansicolor/example_test.go
deleted file mode 100644
index f2ac67c1..00000000
--- a/vendor/github.com/shiena/ansicolor/example_test.go
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2014 shiena Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package ansicolor_test
-
-import (
- "fmt"
- "os"
-
- "github.com/shiena/ansicolor"
-)
-
-func ExampleNewAnsiColorWriter() {
- w := ansicolor.NewAnsiColorWriter(os.Stdout)
- text := "%sforeground %sbold%s %sbackground%s\n"
- fmt.Fprintf(w, text, "\x1b[31m", "\x1b[1m", "\x1b[21m", "\x1b[41;32m", "\x1b[0m")
- fmt.Fprintf(w, text, "\x1b[32m", "\x1b[1m", "\x1b[21m", "\x1b[42;31m", "\x1b[0m")
- fmt.Fprintf(w, text, "\x1b[33m", "\x1b[1m", "\x1b[21m", "\x1b[43;34m", "\x1b[0m")
- fmt.Fprintf(w, text, "\x1b[34m", "\x1b[1m", "\x1b[21m", "\x1b[44;33m", "\x1b[0m")
- fmt.Fprintf(w, text, "\x1b[35m", "\x1b[1m", "\x1b[21m", "\x1b[45;36m", "\x1b[0m")
- fmt.Fprintf(w, text, "\x1b[36m", "\x1b[1m", "\x1b[21m", "\x1b[46;35m", "\x1b[0m")
- fmt.Fprintf(w, text, "\x1b[37m", "\x1b[1m", "\x1b[21m", "\x1b[47;30m", "\x1b[0m")
-}
diff --git a/vendor/github.com/shiena/ansicolor/export_test.go b/vendor/github.com/shiena/ansicolor/export_test.go
deleted file mode 100644
index 6d2f7c07..00000000
--- a/vendor/github.com/shiena/ansicolor/export_test.go
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2014 shiena Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-// +build windows
-
-package ansicolor
-
-import "syscall"
-
-var GetConsoleScreenBufferInfo = getConsoleScreenBufferInfo
-
-func ChangeColor(color uint16) {
- setConsoleTextAttribute(uintptr(syscall.Stdout), color)
-}
-
-func ResetColor() {
- ChangeColor(uint16(0x0007))
-}
diff --git a/vendor/github.com/sirupsen/logrus/.gitignore b/vendor/github.com/sirupsen/logrus/.gitignore
new file mode 100644
index 00000000..66be63a0
--- /dev/null
+++ b/vendor/github.com/sirupsen/logrus/.gitignore
@@ -0,0 +1 @@
+logrus
diff --git a/vendor/github.com/sirupsen/logrus/.travis.yml b/vendor/github.com/sirupsen/logrus/.travis.yml
new file mode 100644
index 00000000..804c5694
--- /dev/null
+++ b/vendor/github.com/sirupsen/logrus/.travis.yml
@@ -0,0 +1,8 @@
+language: go
+go:
+ - 1.6
+ - 1.7
+ - tip
+install:
+ - go get -t ./...
+script: GOMAXPROCS=4 GORACE="halt_on_error=1" go test -race -v ./...
diff --git a/vendor/github.com/sirupsen/logrus/CHANGELOG.md b/vendor/github.com/sirupsen/logrus/CHANGELOG.md
new file mode 100644
index 00000000..747e4d89
--- /dev/null
+++ b/vendor/github.com/sirupsen/logrus/CHANGELOG.md
@@ -0,0 +1,94 @@
+# 0.11.5
+
+* feature: add writer and writerlevel to entry (#372)
+
+# 0.11.4
+
+* bug: fix undefined variable on solaris (#493)
+
+# 0.11.3
+
+* formatter: configure quoting of empty values (#484)
+* formatter: configure quoting character (default is `"`) (#484)
+* bug: fix not importing io correctly in non-linux environments (#481)
+
+# 0.11.2
+
+* bug: fix windows terminal detection (#476)
+
+# 0.11.1
+
+* bug: fix tty detection with custom out (#471)
+
+# 0.11.0
+
+* performance: Use bufferpool to allocate (#370)
+* terminal: terminal detection for app-engine (#343)
+* feature: exit handler (#375)
+
+# 0.10.0
+
+* feature: Add a test hook (#180)
+* feature: `ParseLevel` is now case-insensitive (#326)
+* feature: `FieldLogger` interface that generalizes `Logger` and `Entry` (#308)
+* performance: avoid re-allocations on `WithFields` (#335)
+
+# 0.9.0
+
+* logrus/text_formatter: don't emit empty msg
+* logrus/hooks/airbrake: move out of main repository
+* logrus/hooks/sentry: move out of main repository
+* logrus/hooks/papertrail: move out of main repository
+* logrus/hooks/bugsnag: move out of main repository
+* logrus/core: run tests with `-race`
+* logrus/core: detect TTY based on `stderr`
+* logrus/core: support `WithError` on logger
+* logrus/core: Solaris support
+
+# 0.8.7
+
+* logrus/core: fix possible race (#216)
+* logrus/doc: small typo fixes and doc improvements
+
+
+# 0.8.6
+
+* hooks/raven: allow passing an initialized client
+
+# 0.8.5
+
+* logrus/core: revert #208
+
+# 0.8.4
+
+* formatter/text: fix data race (#218)
+
+# 0.8.3
+
+* logrus/core: fix entry log level (#208)
+* logrus/core: improve performance of text formatter by 40%
+* logrus/core: expose `LevelHooks` type
+* logrus/core: add support for DragonflyBSD and NetBSD
+* formatter/text: print structs more verbosely
+
+# 0.8.2
+
+* logrus: fix more Fatal family functions
+
+# 0.8.1
+
+* logrus: fix not exiting on `Fatalf` and `Fatalln`
+
+# 0.8.0
+
+* logrus: defaults to stderr instead of stdout
+* hooks/sentry: add special field for `*http.Request`
+* formatter/text: ignore Windows for colors
+
+# 0.7.3
+
+* formatter/\*: allow configuration of timestamp layout
+
+# 0.7.2
+
+* formatter/text: Add configuration option for time format (#158)
diff --git a/vendor/github.com/shiena/ansicolor/LICENSE b/vendor/github.com/sirupsen/logrus/LICENSE
similarity index 88%
rename from vendor/github.com/shiena/ansicolor/LICENSE
rename to vendor/github.com/sirupsen/logrus/LICENSE
index e58473ed..f090cb42 100644
--- a/vendor/github.com/shiena/ansicolor/LICENSE
+++ b/vendor/github.com/sirupsen/logrus/LICENSE
@@ -1,6 +1,6 @@
The MIT License (MIT)
-Copyright (c) [2014] [shiena]
+Copyright (c) 2014 Simon Eskildsen
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -9,13 +9,13 @@ 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 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.
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/vendor/github.com/sirupsen/logrus/README.md b/vendor/github.com/sirupsen/logrus/README.md
new file mode 100644
index 00000000..640cf61f
--- /dev/null
+++ b/vendor/github.com/sirupsen/logrus/README.md
@@ -0,0 +1,476 @@
+# Logrus
[](https://travis-ci.org/Sirupsen/logrus) [](https://godoc.org/github.com/Sirupsen/logrus)
+
+**Seeing weird case-sensitive problems?** See [this
+issue](https://github.com/sirupsen/logrus/issues/451#issuecomment-264332021).
+This change has been reverted. I apologize for causing this. I greatly
+underestimated the impact this would have. Logrus strives for stability and
+backwards compatibility and failed to provide that.
+
+Logrus is a structured logger for Go (golang), completely API compatible with
+the standard library logger. [Godoc][godoc]. **Please note the Logrus API is not
+yet stable (pre 1.0). Logrus itself is completely stable and has been used in
+many large deployments. The core API is unlikely to change much but please
+version control your Logrus to make sure you aren't fetching latest `master` on
+every build.**
+
+Nicely color-coded in development (when a TTY is attached, otherwise just
+plain text):
+
+
+
+With `log.SetFormatter(&log.JSONFormatter{})`, for easy parsing by logstash
+or Splunk:
+
+```json
+{"animal":"walrus","level":"info","msg":"A group of walrus emerges from the
+ocean","size":10,"time":"2014-03-10 19:57:38.562264131 -0400 EDT"}
+
+{"level":"warning","msg":"The group's number increased tremendously!",
+"number":122,"omg":true,"time":"2014-03-10 19:57:38.562471297 -0400 EDT"}
+
+{"animal":"walrus","level":"info","msg":"A giant walrus appears!",
+"size":10,"time":"2014-03-10 19:57:38.562500591 -0400 EDT"}
+
+{"animal":"walrus","level":"info","msg":"Tremendously sized cow enters the ocean.",
+"size":9,"time":"2014-03-10 19:57:38.562527896 -0400 EDT"}
+
+{"level":"fatal","msg":"The ice breaks!","number":100,"omg":true,
+"time":"2014-03-10 19:57:38.562543128 -0400 EDT"}
+```
+
+With the default `log.SetFormatter(&log.TextFormatter{})` when a TTY is not
+attached, the output is compatible with the
+[logfmt](http://godoc.org/github.com/kr/logfmt) format:
+
+```text
+time="2015-03-26T01:27:38-04:00" level=debug msg="Started observing beach" animal=walrus number=8
+time="2015-03-26T01:27:38-04:00" level=info msg="A group of walrus emerges from the ocean" animal=walrus size=10
+time="2015-03-26T01:27:38-04:00" level=warning msg="The group's number increased tremendously!" number=122 omg=true
+time="2015-03-26T01:27:38-04:00" level=debug msg="Temperature changes" temperature=-4
+time="2015-03-26T01:27:38-04:00" level=panic msg="It's over 9000!" animal=orca size=9009
+time="2015-03-26T01:27:38-04:00" level=fatal msg="The ice breaks!" err=&{0x2082280c0 map[animal:orca size:9009] 2015-03-26 01:27:38.441574009 -0400 EDT panic It's over 9000!} number=100 omg=true
+exit status 1
+```
+
+#### Example
+
+The simplest way to use Logrus is simply the package-level exported logger:
+
+```go
+package main
+
+import (
+ log "github.com/Sirupsen/logrus"
+)
+
+func main() {
+ log.WithFields(log.Fields{
+ "animal": "walrus",
+ }).Info("A walrus appears")
+}
+```
+
+Note that it's completely api-compatible with the stdlib logger, so you can
+replace your `log` imports everywhere with `log "github.com/Sirupsen/logrus"`
+and you'll now have the flexibility of Logrus. You can customize it all you
+want:
+
+```go
+package main
+
+import (
+ "os"
+ log "github.com/Sirupsen/logrus"
+)
+
+func init() {
+ // Log as JSON instead of the default ASCII formatter.
+ log.SetFormatter(&log.JSONFormatter{})
+
+ // Output to stdout instead of the default stderr
+ // Can be any io.Writer, see below for File example
+ log.SetOutput(os.Stdout)
+
+ // Only log the warning severity or above.
+ log.SetLevel(log.WarnLevel)
+}
+
+func main() {
+ log.WithFields(log.Fields{
+ "animal": "walrus",
+ "size": 10,
+ }).Info("A group of walrus emerges from the ocean")
+
+ log.WithFields(log.Fields{
+ "omg": true,
+ "number": 122,
+ }).Warn("The group's number increased tremendously!")
+
+ log.WithFields(log.Fields{
+ "omg": true,
+ "number": 100,
+ }).Fatal("The ice breaks!")
+
+ // A common pattern is to re-use fields between logging statements by re-using
+ // the logrus.Entry returned from WithFields()
+ contextLogger := log.WithFields(log.Fields{
+ "common": "this is a common field",
+ "other": "I also should be logged always",
+ })
+
+ contextLogger.Info("I'll be logged with common and other field")
+ contextLogger.Info("Me too")
+}
+```
+
+For more advanced usage such as logging to multiple locations from the same
+application, you can also create an instance of the `logrus` Logger:
+
+```go
+package main
+
+import (
+ "github.com/Sirupsen/logrus"
+)
+
+// Create a new instance of the logger. You can have any number of instances.
+var log = logrus.New()
+
+func main() {
+ // The API for setting attributes is a little different than the package level
+ // exported logger. See Godoc.
+ log.Out = os.Stdout
+
+ // You could set this to any `io.Writer` such as a file
+ // file, err := os.OpenFile("logrus.log", os.O_CREATE|os.O_WRONLY, 0666)
+ // if err == nil {
+ // log.Out = file
+ // } else {
+ // log.Info("Failed to log to file, using default stderr")
+ // }
+
+ log.WithFields(logrus.Fields{
+ "animal": "walrus",
+ "size": 10,
+ }).Info("A group of walrus emerges from the ocean")
+}
+```
+
+#### Fields
+
+Logrus encourages careful, structured logging though logging fields instead of
+long, unparseable error messages. For example, instead of: `log.Fatalf("Failed
+to send event %s to topic %s with key %d")`, you should log the much more
+discoverable:
+
+```go
+log.WithFields(log.Fields{
+ "event": event,
+ "topic": topic,
+ "key": key,
+}).Fatal("Failed to send event")
+```
+
+We've found this API forces you to think about logging in a way that produces
+much more useful logging messages. We've been in countless situations where just
+a single added field to a log statement that was already there would've saved us
+hours. The `WithFields` call is optional.
+
+In general, with Logrus using any of the `printf`-family functions should be
+seen as a hint you should add a field, however, you can still use the
+`printf`-family functions with Logrus.
+
+#### Default Fields
+
+Often it's helpful to have fields _always_ attached to log statements in an
+application or parts of one. For example, you may want to always log the
+`request_id` and `user_ip` in the context of a request. Instead of writing
+`log.WithFields(log.Fields{"request_id": request_id, "user_ip": user_ip})` on
+every line, you can create a `logrus.Entry` to pass around instead:
+
+```go
+requestLogger := log.WithFields(log.Fields{"request_id": request_id, user_ip: user_ip})
+requestLogger.Info("something happened on that request") # will log request_id and user_ip
+requestLogger.Warn("something not great happened")
+```
+
+#### Hooks
+
+You can add hooks for logging levels. For example to send errors to an exception
+tracking service on `Error`, `Fatal` and `Panic`, info to StatsD or log to
+multiple places simultaneously, e.g. syslog.
+
+Logrus comes with [built-in hooks](hooks/). Add those, or your custom hook, in
+`init`:
+
+```go
+import (
+ log "github.com/Sirupsen/logrus"
+ "gopkg.in/gemnasium/logrus-airbrake-hook.v2" // the package is named "aibrake"
+ logrus_syslog "github.com/Sirupsen/logrus/hooks/syslog"
+ "log/syslog"
+)
+
+func init() {
+
+ // Use the Airbrake hook to report errors that have Error severity or above to
+ // an exception tracker. You can create custom hooks, see the Hooks section.
+ log.AddHook(airbrake.NewHook(123, "xyz", "production"))
+
+ hook, err := logrus_syslog.NewSyslogHook("udp", "localhost:514", syslog.LOG_INFO, "")
+ if err != nil {
+ log.Error("Unable to connect to local syslog daemon")
+ } else {
+ log.AddHook(hook)
+ }
+}
+```
+Note: Syslog hook also support connecting to local syslog (Ex. "/dev/log" or "/var/run/syslog" or "/var/run/log"). For the detail, please check the [syslog hook README](hooks/syslog/README.md).
+
+| Hook | Description |
+| ----- | ----------- |
+| [Airbrake "legacy"](https://github.com/gemnasium/logrus-airbrake-legacy-hook) | Send errors to an exception tracking service compatible with the Airbrake API V2. Uses [`airbrake-go`](https://github.com/tobi/airbrake-go) behind the scenes. |
+| [Airbrake](https://github.com/gemnasium/logrus-airbrake-hook) | Send errors to the Airbrake API V3. Uses the official [`gobrake`](https://github.com/airbrake/gobrake) behind the scenes. |
+| [Amazon Kinesis](https://github.com/evalphobia/logrus_kinesis) | Hook for logging to [Amazon Kinesis](https://aws.amazon.com/kinesis/) |
+| [Amqp-Hook](https://github.com/vladoatanasov/logrus_amqp) | Hook for logging to Amqp broker (Like RabbitMQ) |
+| [Bugsnag](https://github.com/Shopify/logrus-bugsnag/blob/master/bugsnag.go) | Send errors to the Bugsnag exception tracking service. |
+| [DeferPanic](https://github.com/deferpanic/dp-logrus) | Hook for logging to DeferPanic |
+| [ElasticSearch](https://github.com/sohlich/elogrus) | Hook for logging to ElasticSearch|
+| [Fluentd](https://github.com/evalphobia/logrus_fluent) | Hook for logging to fluentd |
+| [Go-Slack](https://github.com/multiplay/go-slack) | Hook for logging to [Slack](https://slack.com) |
+| [Graylog](https://github.com/gemnasium/logrus-graylog-hook) | Hook for logging to [Graylog](http://graylog2.org/) |
+| [Hiprus](https://github.com/nubo/hiprus) | Send errors to a channel in hipchat. |
+| [Honeybadger](https://github.com/agonzalezro/logrus_honeybadger) | Hook for sending exceptions to Honeybadger |
+| [InfluxDB](https://github.com/Abramovic/logrus_influxdb) | Hook for logging to influxdb |
+| [Influxus] (http://github.com/vlad-doru/influxus) | Hook for concurrently logging to [InfluxDB] (http://influxdata.com/) |
+| [Journalhook](https://github.com/wercker/journalhook) | Hook for logging to `systemd-journald` |
+| [KafkaLogrus](https://github.com/goibibo/KafkaLogrus) | Hook for logging to kafka |
+| [LFShook](https://github.com/rifflock/lfshook) | Hook for logging to the local filesystem |
+| [Logentries](https://github.com/jcftang/logentriesrus) | Hook for logging to [Logentries](https://logentries.com/) |
+| [Logentrus](https://github.com/puddingfactory/logentrus) | Hook for logging to [Logentries](https://logentries.com/) |
+| [Logmatic.io](https://github.com/logmatic/logmatic-go) | Hook for logging to [Logmatic.io](http://logmatic.io/) |
+| [Logrusly](https://github.com/sebest/logrusly) | Send logs to [Loggly](https://www.loggly.com/) |
+| [Logstash](https://github.com/bshuster-repo/logrus-logstash-hook) | Hook for logging to [Logstash](https://www.elastic.co/products/logstash) |
+| [Mail](https://github.com/zbindenren/logrus_mail) | Hook for sending exceptions via mail |
+| [Mongodb](https://github.com/weekface/mgorus) | Hook for logging to mongodb |
+| [NATS-Hook](https://github.com/rybit/nats_logrus_hook) | Hook for logging to [NATS](https://nats.io) |
+| [Octokit](https://github.com/dorajistyle/logrus-octokit-hook) | Hook for logging to github via octokit |
+| [Papertrail](https://github.com/polds/logrus-papertrail-hook) | Send errors to the [Papertrail](https://papertrailapp.com) hosted logging service via UDP. |
+| [PostgreSQL](https://github.com/gemnasium/logrus-postgresql-hook) | Send logs to [PostgreSQL](http://postgresql.org) |
+| [Pushover](https://github.com/toorop/logrus_pushover) | Send error via [Pushover](https://pushover.net) |
+| [Raygun](https://github.com/squirkle/logrus-raygun-hook) | Hook for logging to [Raygun.io](http://raygun.io/) |
+| [Redis-Hook](https://github.com/rogierlommers/logrus-redis-hook) | Hook for logging to a ELK stack (through Redis) |
+| [Rollrus](https://github.com/heroku/rollrus) | Hook for sending errors to rollbar |
+| [Scribe](https://github.com/sagar8192/logrus-scribe-hook) | Hook for logging to [Scribe](https://github.com/facebookarchive/scribe)|
+| [Sentry](https://github.com/evalphobia/logrus_sentry) | Send errors to the Sentry error logging and aggregation service. |
+| [Slackrus](https://github.com/johntdyer/slackrus) | Hook for Slack chat. |
+| [Stackdriver](https://github.com/knq/sdhook) | Hook for logging to [Google Stackdriver](https://cloud.google.com/logging/) |
+| [Sumorus](https://github.com/doublefree/sumorus) | Hook for logging to [SumoLogic](https://www.sumologic.com/)|
+| [Syslog](https://github.com/Sirupsen/logrus/blob/master/hooks/syslog/syslog.go) | Send errors to remote syslog server. Uses standard library `log/syslog` behind the scenes. |
+| [TraceView](https://github.com/evalphobia/logrus_appneta) | Hook for logging to [AppNeta TraceView](https://www.appneta.com/products/traceview/) |
+| [Typetalk](https://github.com/dragon3/logrus-typetalk-hook) | Hook for logging to [Typetalk](https://www.typetalk.in/) |
+| [logz.io](https://github.com/ripcurld00d/logrus-logzio-hook) | Hook for logging to [logz.io](https://logz.io), a Log as a Service using Logstash |
+
+#### Level logging
+
+Logrus has six logging levels: Debug, Info, Warning, Error, Fatal and Panic.
+
+```go
+log.Debug("Useful debugging information.")
+log.Info("Something noteworthy happened!")
+log.Warn("You should probably take a look at this.")
+log.Error("Something failed but I'm not quitting.")
+// Calls os.Exit(1) after logging
+log.Fatal("Bye.")
+// Calls panic() after logging
+log.Panic("I'm bailing.")
+```
+
+You can set the logging level on a `Logger`, then it will only log entries with
+that severity or anything above it:
+
+```go
+// Will log anything that is info or above (warn, error, fatal, panic). Default.
+log.SetLevel(log.InfoLevel)
+```
+
+It may be useful to set `log.Level = logrus.DebugLevel` in a debug or verbose
+environment if your application has that.
+
+#### Entries
+
+Besides the fields added with `WithField` or `WithFields` some fields are
+automatically added to all logging events:
+
+1. `time`. The timestamp when the entry was created.
+2. `msg`. The logging message passed to `{Info,Warn,Error,Fatal,Panic}` after
+ the `AddFields` call. E.g. `Failed to send event.`
+3. `level`. The logging level. E.g. `info`.
+
+#### Environments
+
+Logrus has no notion of environment.
+
+If you wish for hooks and formatters to only be used in specific environments,
+you should handle that yourself. For example, if your application has a global
+variable `Environment`, which is a string representation of the environment you
+could do:
+
+```go
+import (
+ log "github.com/Sirupsen/logrus"
+)
+
+init() {
+ // do something here to set environment depending on an environment variable
+ // or command-line flag
+ if Environment == "production" {
+ log.SetFormatter(&log.JSONFormatter{})
+ } else {
+ // The TextFormatter is default, you don't actually have to do this.
+ log.SetFormatter(&log.TextFormatter{})
+ }
+}
+```
+
+This configuration is how `logrus` was intended to be used, but JSON in
+production is mostly only useful if you do log aggregation with tools like
+Splunk or Logstash.
+
+#### Formatters
+
+The built-in logging formatters are:
+
+* `logrus.TextFormatter`. Logs the event in colors if stdout is a tty, otherwise
+ without colors.
+ * *Note:* to force colored output when there is no TTY, set the `ForceColors`
+ field to `true`. To force no colored output even if there is a TTY set the
+ `DisableColors` field to `true`. For Windows, see
+ [github.com/mattn/go-colorable](https://github.com/mattn/go-colorable).
+ * All options are listed in the [generated docs](https://godoc.org/github.com/sirupsen/logrus#TextFormatter).
+* `logrus.JSONFormatter`. Logs fields as JSON.
+ * All options are listed in the [generated docs](https://godoc.org/github.com/sirupsen/logrus#JSONFormatter).
+
+Third party logging formatters:
+
+* [`logstash`](https://github.com/bshuster-repo/logrus-logstash-hook). Logs fields as [Logstash](http://logstash.net) Events.
+* [`prefixed`](https://github.com/x-cray/logrus-prefixed-formatter). Displays log entry source along with alternative layout.
+* [`zalgo`](https://github.com/aybabtme/logzalgo). Invoking the P͉̫o̳̼̊w̖͈̰͎e̬͔̭͂r͚̼̹̲ ̫͓͉̳͈ō̠͕͖̚f̝͍̠ ͕̲̞͖͑Z̖̫̤̫ͪa͉̬͈̗l͖͎g̳̥o̰̥̅!̣͔̲̻͊̄ ̙̘̦̹̦.
+
+You can define your formatter by implementing the `Formatter` interface,
+requiring a `Format` method. `Format` takes an `*Entry`. `entry.Data` is a
+`Fields` type (`map[string]interface{}`) with all your fields as well as the
+default ones (see Entries section above):
+
+```go
+type MyJSONFormatter struct {
+}
+
+log.SetFormatter(new(MyJSONFormatter))
+
+func (f *MyJSONFormatter) Format(entry *Entry) ([]byte, error) {
+ // Note this doesn't include Time, Level and Message which are available on
+ // the Entry. Consult `godoc` on information about those fields or read the
+ // source of the official loggers.
+ serialized, err := json.Marshal(entry.Data)
+ if err != nil {
+ return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err)
+ }
+ return append(serialized, '\n'), nil
+}
+```
+
+#### Logger as an `io.Writer`
+
+Logrus can be transformed into an `io.Writer`. That writer is the end of an `io.Pipe` and it is your responsibility to close it.
+
+```go
+w := logger.Writer()
+defer w.Close()
+
+srv := http.Server{
+ // create a stdlib log.Logger that writes to
+ // logrus.Logger.
+ ErrorLog: log.New(w, "", 0),
+}
+```
+
+Each line written to that writer will be printed the usual way, using formatters
+and hooks. The level for those entries is `info`.
+
+This means that we can override the standard library logger easily:
+
+```go
+logger := logrus.New()
+logger.Formatter = &logrus.JSONFormatter{}
+
+// Use logrus for standard log output
+// Note that `log` here references stdlib's log
+// Not logrus imported under the name `log`.
+log.SetOutput(logger.Writer())
+```
+
+#### Rotation
+
+Log rotation is not provided with Logrus. Log rotation should be done by an
+external program (like `logrotate(8)`) that can compress and delete old log
+entries. It should not be a feature of the application-level logger.
+
+#### Tools
+
+| Tool | Description |
+| ---- | ----------- |
+|[Logrus Mate](https://github.com/gogap/logrus_mate)|Logrus mate is a tool for Logrus to manage loggers, you can initial logger's level, hook and formatter by config file, the logger will generated with different config at different environment.|
+|[Logrus Viper Helper](https://github.com/heirko/go-contrib/tree/master/logrusHelper)|An Helper arround Logrus to wrap with spf13/Viper to load configuration with fangs! And to simplify Logrus configuration use some behavior of [Logrus Mate](https://github.com/gogap/logrus_mate). [sample](https://github.com/heirko/iris-contrib/blob/master/middleware/logrus-logger/example) |
+
+#### Testing
+
+Logrus has a built in facility for asserting the presence of log messages. This is implemented through the `test` hook and provides:
+
+* decorators for existing logger (`test.NewLocal` and `test.NewGlobal`) which basically just add the `test` hook
+* a test logger (`test.NewNullLogger`) that just records log messages (and does not output any):
+
+```go
+logger, hook := NewNullLogger()
+logger.Error("Hello error")
+
+assert.Equal(1, len(hook.Entries))
+assert.Equal(logrus.ErrorLevel, hook.LastEntry().Level)
+assert.Equal("Hello error", hook.LastEntry().Message)
+
+hook.Reset()
+assert.Nil(hook.LastEntry())
+```
+
+#### Fatal handlers
+
+Logrus can register one or more functions that will be called when any `fatal`
+level message is logged. The registered handlers will be executed before
+logrus performs a `os.Exit(1)`. This behavior may be helpful if callers need
+to gracefully shutdown. Unlike a `panic("Something went wrong...")` call which can be intercepted with a deferred `recover` a call to `os.Exit(1)` can not be intercepted.
+
+```
+...
+handler := func() {
+ // gracefully shutdown something...
+}
+logrus.RegisterExitHandler(handler)
+...
+```
+
+#### Thread safety
+
+By default Logger is protected by mutex for concurrent writes, this mutex is invoked when calling hooks and writing logs.
+If you are sure such locking is not needed, you can call logger.SetNoLock() to disable the locking.
+
+Situation when locking is not needed includes:
+
+* You have no hooks registered, or hooks calling is already thread-safe.
+
+* Writing to logger.Out is already thread-safe, for example:
+
+ 1) logger.Out is protected by locks.
+
+ 2) logger.Out is a os.File handler opened with `O_APPEND` flag, and every write is smaller than 4k. (This allow multi-thread/multi-process writing)
+
+ (Refer to http://www.notthewizard.com/2014/06/17/are-files-appends-really-atomic/)
diff --git a/vendor/github.com/sirupsen/logrus/alt_exit.go b/vendor/github.com/sirupsen/logrus/alt_exit.go
new file mode 100644
index 00000000..b4c9e847
--- /dev/null
+++ b/vendor/github.com/sirupsen/logrus/alt_exit.go
@@ -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 .
+//
+// 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)
+}
diff --git a/vendor/github.com/sirupsen/logrus/alt_exit_test.go b/vendor/github.com/sirupsen/logrus/alt_exit_test.go
new file mode 100644
index 00000000..022b7783
--- /dev/null
+++ b/vendor/github.com/sirupsen/logrus/alt_exit_test.go
@@ -0,0 +1,74 @@
+package logrus
+
+import (
+ "io/ioutil"
+ "os/exec"
+ "testing"
+ "time"
+)
+
+func TestRegister(t *testing.T) {
+ current := len(handlers)
+ RegisterExitHandler(func() {})
+ if len(handlers) != current+1 {
+ t.Fatalf("can't add handler")
+ }
+}
+
+func TestHandler(t *testing.T) {
+ gofile := "/tmp/testprog.go"
+ if err := ioutil.WriteFile(gofile, testprog, 0666); err != nil {
+ t.Fatalf("can't create go file")
+ }
+
+ outfile := "/tmp/testprog.out"
+ arg := time.Now().UTC().String()
+ err := exec.Command("go", "run", gofile, outfile, arg).Run()
+ if err == nil {
+ t.Fatalf("completed normally, should have failed")
+ }
+
+ data, err := ioutil.ReadFile(outfile)
+ if err != nil {
+ t.Fatalf("can't read output file %s", outfile)
+ }
+
+ if string(data) != arg {
+ t.Fatalf("bad data")
+ }
+}
+
+var testprog = []byte(`
+// Test program for atexit, gets output file and data as arguments and writes
+// data to output file in atexit handler.
+package main
+
+import (
+ "github.com/Sirupsen/logrus"
+ "flag"
+ "fmt"
+ "io/ioutil"
+)
+
+var outfile = ""
+var data = ""
+
+func handler() {
+ ioutil.WriteFile(outfile, []byte(data), 0666)
+}
+
+func badHandler() {
+ n := 0
+ fmt.Println(1/n)
+}
+
+func main() {
+ flag.Parse()
+ outfile = flag.Arg(0)
+ data = flag.Arg(1)
+
+ logrus.RegisterExitHandler(handler)
+ logrus.RegisterExitHandler(badHandler)
+ logrus.Fatal("Bye bye")
+}
+`)
diff --git a/vendor/github.com/sirupsen/logrus/doc.go b/vendor/github.com/sirupsen/logrus/doc.go
new file mode 100644
index 00000000..dddd5f87
--- /dev/null
+++ b/vendor/github.com/sirupsen/logrus/doc.go
@@ -0,0 +1,26 @@
+/*
+Package logrus is a structured logger for Go, completely API compatible with the standard library logger.
+
+
+The simplest way to use Logrus is simply the package-level exported logger:
+
+ package main
+
+ import (
+ log "github.com/Sirupsen/logrus"
+ )
+
+ func main() {
+ log.WithFields(log.Fields{
+ "animal": "walrus",
+ "number": 1,
+ "size": 10,
+ }).Info("A walrus appears")
+ }
+
+Output:
+ time="2015-09-07T08:48:33Z" level=info msg="A walrus appears" animal=walrus number=1 size=10
+
+For a full guide visit https://github.com/Sirupsen/logrus
+*/
+package logrus
diff --git a/vendor/github.com/sirupsen/logrus/entry.go b/vendor/github.com/sirupsen/logrus/entry.go
new file mode 100644
index 00000000..4edbe7a2
--- /dev/null
+++ b/vendor/github.com/sirupsen/logrus/entry.go
@@ -0,0 +1,275 @@
+package logrus
+
+import (
+ "bytes"
+ "fmt"
+ "os"
+ "sync"
+ "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.
+var ErrorKey = "error"
+
+// An entry is the final or intermediate Logrus logging entry. It contains all
+// the fields passed with WithField{,s}. It's finally logged when Debug, Info,
+// Warn, Error, Fatal or Panic is called on it. These objects can be reused and
+// passed around as much as you wish to avoid field duplication.
+type Entry struct {
+ Logger *Logger
+
+ // Contains all the fields set by the user.
+ Data Fields
+
+ // Time at which the log entry was created
+ Time time.Time
+
+ // Level the log entry was logged at: Debug, Info, Warn, Error, Fatal or Panic
+ Level Level
+
+ // Message passed to Debug, Info, Warn, Error, Fatal or Panic
+ Message string
+
+ // When formatter is called in entry.log(), an Buffer may be set to entry
+ Buffer *bytes.Buffer
+}
+
+func NewEntry(logger *Logger) *Entry {
+ return &Entry{
+ Logger: logger,
+ // Default is three fields, give a little extra room
+ Data: make(Fields, 5),
+ }
+}
+
+// Returns the string representation from the reader and ultimately the
+// formatter.
+func (entry *Entry) String() (string, error) {
+ serialized, err := entry.Logger.Formatter.Format(entry)
+ if err != nil {
+ return "", err
+ }
+ str := string(serialized)
+ return str, nil
+}
+
+// Add an error as single field (using the key defined in ErrorKey) to the Entry.
+func (entry *Entry) WithError(err error) *Entry {
+ return entry.WithField(ErrorKey, err)
+}
+
+// Add a single field to the Entry.
+func (entry *Entry) WithField(key string, value interface{}) *Entry {
+ return entry.WithFields(Fields{key: value})
+}
+
+// Add a map of fields to the Entry.
+func (entry *Entry) WithFields(fields Fields) *Entry {
+ data := make(Fields, len(entry.Data)+len(fields))
+ for k, v := range entry.Data {
+ data[k] = v
+ }
+ for k, v := range fields {
+ data[k] = v
+ }
+ return &Entry{Logger: entry.Logger, Data: data}
+}
+
+// This function is not declared with a pointer value because otherwise
+// race conditions will occur when using multiple goroutines
+func (entry Entry) log(level Level, msg string) {
+ var buffer *bytes.Buffer
+ entry.Time = time.Now()
+ entry.Level = level
+ entry.Message = msg
+
+ if err := entry.Logger.Hooks.Fire(level, &entry); err != nil {
+ entry.Logger.mu.Lock()
+ fmt.Fprintf(os.Stderr, "Failed to fire hook: %v\n", err)
+ entry.Logger.mu.Unlock()
+ }
+ buffer = bufferPool.Get().(*bytes.Buffer)
+ buffer.Reset()
+ defer bufferPool.Put(buffer)
+ entry.Buffer = buffer
+ serialized, err := entry.Logger.Formatter.Format(&entry)
+ entry.Buffer = nil
+ if err != nil {
+ entry.Logger.mu.Lock()
+ fmt.Fprintf(os.Stderr, "Failed to obtain reader, %v\n", err)
+ entry.Logger.mu.Unlock()
+ } else {
+ entry.Logger.mu.Lock()
+ _, err = entry.Logger.Out.Write(serialized)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "Failed to write to log, %v\n", err)
+ }
+ entry.Logger.mu.Unlock()
+ }
+
+ // To avoid Entry#log() returning a value that only would make sense for
+ // panic() to use in Entry#Panic(), we avoid the allocation by checking
+ // directly here.
+ if level <= PanicLevel {
+ panic(&entry)
+ }
+}
+
+func (entry *Entry) Debug(args ...interface{}) {
+ if entry.Logger.Level >= DebugLevel {
+ entry.log(DebugLevel, fmt.Sprint(args...))
+ }
+}
+
+func (entry *Entry) Print(args ...interface{}) {
+ entry.Info(args...)
+}
+
+func (entry *Entry) Info(args ...interface{}) {
+ if entry.Logger.Level >= InfoLevel {
+ entry.log(InfoLevel, fmt.Sprint(args...))
+ }
+}
+
+func (entry *Entry) Warn(args ...interface{}) {
+ if entry.Logger.Level >= WarnLevel {
+ entry.log(WarnLevel, fmt.Sprint(args...))
+ }
+}
+
+func (entry *Entry) Warning(args ...interface{}) {
+ entry.Warn(args...)
+}
+
+func (entry *Entry) Error(args ...interface{}) {
+ if entry.Logger.Level >= ErrorLevel {
+ entry.log(ErrorLevel, fmt.Sprint(args...))
+ }
+}
+
+func (entry *Entry) Fatal(args ...interface{}) {
+ if entry.Logger.Level >= FatalLevel {
+ entry.log(FatalLevel, fmt.Sprint(args...))
+ }
+ Exit(1)
+}
+
+func (entry *Entry) Panic(args ...interface{}) {
+ if entry.Logger.Level >= PanicLevel {
+ entry.log(PanicLevel, fmt.Sprint(args...))
+ }
+ panic(fmt.Sprint(args...))
+}
+
+// Entry Printf family functions
+
+func (entry *Entry) Debugf(format string, args ...interface{}) {
+ if entry.Logger.Level >= DebugLevel {
+ entry.Debug(fmt.Sprintf(format, args...))
+ }
+}
+
+func (entry *Entry) Infof(format string, args ...interface{}) {
+ if entry.Logger.Level >= InfoLevel {
+ entry.Info(fmt.Sprintf(format, args...))
+ }
+}
+
+func (entry *Entry) Printf(format string, args ...interface{}) {
+ entry.Infof(format, args...)
+}
+
+func (entry *Entry) Warnf(format string, args ...interface{}) {
+ if entry.Logger.Level >= WarnLevel {
+ entry.Warn(fmt.Sprintf(format, args...))
+ }
+}
+
+func (entry *Entry) Warningf(format string, args ...interface{}) {
+ entry.Warnf(format, args...)
+}
+
+func (entry *Entry) Errorf(format string, args ...interface{}) {
+ if entry.Logger.Level >= ErrorLevel {
+ entry.Error(fmt.Sprintf(format, args...))
+ }
+}
+
+func (entry *Entry) Fatalf(format string, args ...interface{}) {
+ if entry.Logger.Level >= FatalLevel {
+ entry.Fatal(fmt.Sprintf(format, args...))
+ }
+ Exit(1)
+}
+
+func (entry *Entry) Panicf(format string, args ...interface{}) {
+ if entry.Logger.Level >= PanicLevel {
+ entry.Panic(fmt.Sprintf(format, args...))
+ }
+}
+
+// Entry Println family functions
+
+func (entry *Entry) Debugln(args ...interface{}) {
+ if entry.Logger.Level >= DebugLevel {
+ entry.Debug(entry.sprintlnn(args...))
+ }
+}
+
+func (entry *Entry) Infoln(args ...interface{}) {
+ if entry.Logger.Level >= InfoLevel {
+ entry.Info(entry.sprintlnn(args...))
+ }
+}
+
+func (entry *Entry) Println(args ...interface{}) {
+ entry.Infoln(args...)
+}
+
+func (entry *Entry) Warnln(args ...interface{}) {
+ if entry.Logger.Level >= WarnLevel {
+ entry.Warn(entry.sprintlnn(args...))
+ }
+}
+
+func (entry *Entry) Warningln(args ...interface{}) {
+ entry.Warnln(args...)
+}
+
+func (entry *Entry) Errorln(args ...interface{}) {
+ if entry.Logger.Level >= ErrorLevel {
+ entry.Error(entry.sprintlnn(args...))
+ }
+}
+
+func (entry *Entry) Fatalln(args ...interface{}) {
+ if entry.Logger.Level >= FatalLevel {
+ entry.Fatal(entry.sprintlnn(args...))
+ }
+ Exit(1)
+}
+
+func (entry *Entry) Panicln(args ...interface{}) {
+ if entry.Logger.Level >= PanicLevel {
+ entry.Panic(entry.sprintlnn(args...))
+ }
+}
+
+// Sprintlnn => Sprint no newline. This is to get the behavior of how
+// fmt.Sprintln where spaces are always added between operands, regardless of
+// their type. Instead of vendoring the Sprintln implementation to spare a
+// string allocation, we do the simplest thing.
+func (entry *Entry) sprintlnn(args ...interface{}) string {
+ msg := fmt.Sprintln(args...)
+ return msg[:len(msg)-1]
+}
diff --git a/vendor/github.com/sirupsen/logrus/entry_test.go b/vendor/github.com/sirupsen/logrus/entry_test.go
new file mode 100644
index 00000000..99c3b41d
--- /dev/null
+++ b/vendor/github.com/sirupsen/logrus/entry_test.go
@@ -0,0 +1,77 @@
+package logrus
+
+import (
+ "bytes"
+ "fmt"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestEntryWithError(t *testing.T) {
+
+ assert := assert.New(t)
+
+ defer func() {
+ ErrorKey = "error"
+ }()
+
+ err := fmt.Errorf("kaboom at layer %d", 4711)
+
+ assert.Equal(err, WithError(err).Data["error"])
+
+ logger := New()
+ logger.Out = &bytes.Buffer{}
+ entry := NewEntry(logger)
+
+ assert.Equal(err, entry.WithError(err).Data["error"])
+
+ ErrorKey = "err"
+
+ assert.Equal(err, entry.WithError(err).Data["err"])
+
+}
+
+func TestEntryPanicln(t *testing.T) {
+ errBoom := fmt.Errorf("boom time")
+
+ defer func() {
+ p := recover()
+ assert.NotNil(t, p)
+
+ switch pVal := p.(type) {
+ case *Entry:
+ assert.Equal(t, "kaboom", pVal.Message)
+ assert.Equal(t, errBoom, pVal.Data["err"])
+ default:
+ t.Fatalf("want type *Entry, got %T: %#v", pVal, pVal)
+ }
+ }()
+
+ logger := New()
+ logger.Out = &bytes.Buffer{}
+ entry := NewEntry(logger)
+ entry.WithField("err", errBoom).Panicln("kaboom")
+}
+
+func TestEntryPanicf(t *testing.T) {
+ errBoom := fmt.Errorf("boom again")
+
+ defer func() {
+ p := recover()
+ assert.NotNil(t, p)
+
+ switch pVal := p.(type) {
+ case *Entry:
+ assert.Equal(t, "kaboom true", pVal.Message)
+ assert.Equal(t, errBoom, pVal.Data["err"])
+ default:
+ t.Fatalf("want type *Entry, got %T: %#v", pVal, pVal)
+ }
+ }()
+
+ logger := New()
+ logger.Out = &bytes.Buffer{}
+ entry := NewEntry(logger)
+ entry.WithField("err", errBoom).Panicf("kaboom %v", true)
+}
diff --git a/vendor/github.com/sirupsen/logrus/examples/basic/basic.go b/vendor/github.com/sirupsen/logrus/examples/basic/basic.go
new file mode 100644
index 00000000..ad703fcb
--- /dev/null
+++ b/vendor/github.com/sirupsen/logrus/examples/basic/basic.go
@@ -0,0 +1,59 @@
+package main
+
+import (
+ "github.com/Sirupsen/logrus"
+ // "os"
+)
+
+var log = logrus.New()
+
+func init() {
+ log.Formatter = new(logrus.JSONFormatter)
+ log.Formatter = new(logrus.TextFormatter) // default
+
+ // file, err := os.OpenFile("logrus.log", os.O_CREATE|os.O_WRONLY, 0666)
+ // if err == nil {
+ // log.Out = file
+ // } else {
+ // log.Info("Failed to log to file, using default stderr")
+ // }
+
+ log.Level = logrus.DebugLevel
+}
+
+func main() {
+ defer func() {
+ err := recover()
+ if err != nil {
+ log.WithFields(logrus.Fields{
+ "omg": true,
+ "err": err,
+ "number": 100,
+ }).Fatal("The ice breaks!")
+ }
+ }()
+
+ log.WithFields(logrus.Fields{
+ "animal": "walrus",
+ "number": 8,
+ }).Debug("Started observing beach")
+
+ log.WithFields(logrus.Fields{
+ "animal": "walrus",
+ "size": 10,
+ }).Info("A group of walrus emerges from the ocean")
+
+ log.WithFields(logrus.Fields{
+ "omg": true,
+ "number": 122,
+ }).Warn("The group's number increased tremendously!")
+
+ log.WithFields(logrus.Fields{
+ "temperature": -4,
+ }).Debug("Temperature changes")
+
+ log.WithFields(logrus.Fields{
+ "animal": "orca",
+ "size": 9009,
+ }).Panic("It's over 9000!")
+}
diff --git a/vendor/github.com/sirupsen/logrus/examples/hook/hook.go b/vendor/github.com/sirupsen/logrus/examples/hook/hook.go
new file mode 100644
index 00000000..3187f6d3
--- /dev/null
+++ b/vendor/github.com/sirupsen/logrus/examples/hook/hook.go
@@ -0,0 +1,30 @@
+package main
+
+import (
+ "github.com/Sirupsen/logrus"
+ "gopkg.in/gemnasium/logrus-airbrake-hook.v2"
+)
+
+var log = logrus.New()
+
+func init() {
+ log.Formatter = new(logrus.TextFormatter) // default
+ log.Hooks.Add(airbrake.NewHook(123, "xyz", "development"))
+}
+
+func main() {
+ log.WithFields(logrus.Fields{
+ "animal": "walrus",
+ "size": 10,
+ }).Info("A group of walrus emerges from the ocean")
+
+ log.WithFields(logrus.Fields{
+ "omg": true,
+ "number": 122,
+ }).Warn("The group's number increased tremendously!")
+
+ log.WithFields(logrus.Fields{
+ "omg": true,
+ "number": 100,
+ }).Fatal("The ice breaks!")
+}
diff --git a/vendor/github.com/sirupsen/logrus/exported.go b/vendor/github.com/sirupsen/logrus/exported.go
new file mode 100644
index 00000000..9a0120ac
--- /dev/null
+++ b/vendor/github.com/sirupsen/logrus/exported.go
@@ -0,0 +1,193 @@
+package logrus
+
+import (
+ "io"
+)
+
+var (
+ // std is the name of the standard logger in stdlib `log`
+ std = New()
+)
+
+func StandardLogger() *Logger {
+ return std
+}
+
+// SetOutput sets the standard logger output.
+func SetOutput(out io.Writer) {
+ std.mu.Lock()
+ defer std.mu.Unlock()
+ std.Out = out
+}
+
+// SetFormatter sets the standard logger formatter.
+func SetFormatter(formatter Formatter) {
+ std.mu.Lock()
+ defer std.mu.Unlock()
+ std.Formatter = formatter
+}
+
+// SetLevel sets the standard logger level.
+func SetLevel(level Level) {
+ std.mu.Lock()
+ defer std.mu.Unlock()
+ std.Level = level
+}
+
+// GetLevel returns the standard logger level.
+func GetLevel() Level {
+ std.mu.Lock()
+ defer std.mu.Unlock()
+ return std.Level
+}
+
+// AddHook adds a hook to the standard logger hooks.
+func AddHook(hook Hook) {
+ std.mu.Lock()
+ defer std.mu.Unlock()
+ std.Hooks.Add(hook)
+}
+
+// WithError creates an entry from the standard logger and adds an error to it, using the value defined in ErrorKey as key.
+func WithError(err error) *Entry {
+ return std.WithField(ErrorKey, err)
+}
+
+// WithField creates an entry from the standard logger and adds a field to
+// it. If you want multiple fields, use `WithFields`.
+//
+// Note that it doesn't log until you call Debug, Print, Info, Warn, Fatal
+// or Panic on the Entry it returns.
+func WithField(key string, value interface{}) *Entry {
+ return std.WithField(key, value)
+}
+
+// WithFields creates an entry from the standard logger and adds multiple
+// fields to it. This is simply a helper for `WithField`, invoking it
+// once for each field.
+//
+// Note that it doesn't log until you call Debug, Print, Info, Warn, Fatal
+// or Panic on the Entry it returns.
+func WithFields(fields Fields) *Entry {
+ return std.WithFields(fields)
+}
+
+// Debug logs a message at level Debug on the standard logger.
+func Debug(args ...interface{}) {
+ std.Debug(args...)
+}
+
+// Print logs a message at level Info on the standard logger.
+func Print(args ...interface{}) {
+ std.Print(args...)
+}
+
+// Info logs a message at level Info on the standard logger.
+func Info(args ...interface{}) {
+ std.Info(args...)
+}
+
+// Warn logs a message at level Warn on the standard logger.
+func Warn(args ...interface{}) {
+ std.Warn(args...)
+}
+
+// Warning logs a message at level Warn on the standard logger.
+func Warning(args ...interface{}) {
+ std.Warning(args...)
+}
+
+// Error logs a message at level Error on the standard logger.
+func Error(args ...interface{}) {
+ std.Error(args...)
+}
+
+// Panic logs a message at level Panic on the standard logger.
+func Panic(args ...interface{}) {
+ std.Panic(args...)
+}
+
+// Fatal logs a message at level Fatal on the standard logger.
+func Fatal(args ...interface{}) {
+ std.Fatal(args...)
+}
+
+// Debugf logs a message at level Debug on the standard logger.
+func Debugf(format string, args ...interface{}) {
+ std.Debugf(format, args...)
+}
+
+// Printf logs a message at level Info on the standard logger.
+func Printf(format string, args ...interface{}) {
+ std.Printf(format, args...)
+}
+
+// Infof logs a message at level Info on the standard logger.
+func Infof(format string, args ...interface{}) {
+ std.Infof(format, args...)
+}
+
+// Warnf logs a message at level Warn on the standard logger.
+func Warnf(format string, args ...interface{}) {
+ std.Warnf(format, args...)
+}
+
+// Warningf logs a message at level Warn on the standard logger.
+func Warningf(format string, args ...interface{}) {
+ std.Warningf(format, args...)
+}
+
+// Errorf logs a message at level Error on the standard logger.
+func Errorf(format string, args ...interface{}) {
+ std.Errorf(format, args...)
+}
+
+// Panicf logs a message at level Panic on the standard logger.
+func Panicf(format string, args ...interface{}) {
+ std.Panicf(format, args...)
+}
+
+// Fatalf logs a message at level Fatal on the standard logger.
+func Fatalf(format string, args ...interface{}) {
+ std.Fatalf(format, args...)
+}
+
+// Debugln logs a message at level Debug on the standard logger.
+func Debugln(args ...interface{}) {
+ std.Debugln(args...)
+}
+
+// Println logs a message at level Info on the standard logger.
+func Println(args ...interface{}) {
+ std.Println(args...)
+}
+
+// Infoln logs a message at level Info on the standard logger.
+func Infoln(args ...interface{}) {
+ std.Infoln(args...)
+}
+
+// Warnln logs a message at level Warn on the standard logger.
+func Warnln(args ...interface{}) {
+ std.Warnln(args...)
+}
+
+// Warningln logs a message at level Warn on the standard logger.
+func Warningln(args ...interface{}) {
+ std.Warningln(args...)
+}
+
+// Errorln logs a message at level Error on the standard logger.
+func Errorln(args ...interface{}) {
+ std.Errorln(args...)
+}
+
+// Panicln logs a message at level Panic on the standard logger.
+func Panicln(args ...interface{}) {
+ std.Panicln(args...)
+}
+
+// Fatalln logs a message at level Fatal on the standard logger.
+func Fatalln(args ...interface{}) {
+ std.Fatalln(args...)
+}
diff --git a/vendor/github.com/sirupsen/logrus/formatter.go b/vendor/github.com/sirupsen/logrus/formatter.go
new file mode 100644
index 00000000..b5fbe934
--- /dev/null
+++ b/vendor/github.com/sirupsen/logrus/formatter.go
@@ -0,0 +1,45 @@
+package logrus
+
+import "time"
+
+const DefaultTimestampFormat = time.RFC3339
+
+// The Formatter interface is used to implement a custom Formatter. It takes an
+// `Entry`. It exposes all the fields, including the default ones:
+//
+// * `entry.Data["msg"]`. The message passed from Info, Warn, Error ..
+// * `entry.Data["time"]`. The timestamp.
+// * `entry.Data["level"]. The level the entry was logged at.
+//
+// Any additional fields added with `WithField` or `WithFields` are also in
+// `entry.Data`. Format is expected to return an array of bytes which are then
+// logged to `logger.Out`.
+type Formatter interface {
+ Format(*Entry) ([]byte, error)
+}
+
+// This is to not silently overwrite `time`, `msg` and `level` fields when
+// dumping it. If this code wasn't there doing:
+//
+// logrus.WithField("level", 1).Info("hello")
+//
+// Would just silently drop the user provided level. Instead with this code
+// it'll logged as:
+//
+// {"level": "info", "fields.level": 1, "msg": "hello", "time": "..."}
+//
+// 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.
+func prefixFieldClashes(data Fields) {
+ if t, ok := data["time"]; ok {
+ data["fields.time"] = t
+ }
+
+ if m, ok := data["msg"]; ok {
+ data["fields.msg"] = m
+ }
+
+ if l, ok := data["level"]; ok {
+ data["fields.level"] = l
+ }
+}
diff --git a/vendor/github.com/sirupsen/logrus/formatter_bench_test.go b/vendor/github.com/sirupsen/logrus/formatter_bench_test.go
new file mode 100644
index 00000000..d9481589
--- /dev/null
+++ b/vendor/github.com/sirupsen/logrus/formatter_bench_test.go
@@ -0,0 +1,101 @@
+package logrus
+
+import (
+ "fmt"
+ "testing"
+ "time"
+)
+
+// smallFields is a small size data set for benchmarking
+var smallFields = Fields{
+ "foo": "bar",
+ "baz": "qux",
+ "one": "two",
+ "three": "four",
+}
+
+// largeFields is a large size data set for benchmarking
+var largeFields = Fields{
+ "foo": "bar",
+ "baz": "qux",
+ "one": "two",
+ "three": "four",
+ "five": "six",
+ "seven": "eight",
+ "nine": "ten",
+ "eleven": "twelve",
+ "thirteen": "fourteen",
+ "fifteen": "sixteen",
+ "seventeen": "eighteen",
+ "nineteen": "twenty",
+ "a": "b",
+ "c": "d",
+ "e": "f",
+ "g": "h",
+ "i": "j",
+ "k": "l",
+ "m": "n",
+ "o": "p",
+ "q": "r",
+ "s": "t",
+ "u": "v",
+ "w": "x",
+ "y": "z",
+ "this": "will",
+ "make": "thirty",
+ "entries": "yeah",
+}
+
+var errorFields = Fields{
+ "foo": fmt.Errorf("bar"),
+ "baz": fmt.Errorf("qux"),
+}
+
+func BenchmarkErrorTextFormatter(b *testing.B) {
+ doBenchmark(b, &TextFormatter{DisableColors: true}, errorFields)
+}
+
+func BenchmarkSmallTextFormatter(b *testing.B) {
+ doBenchmark(b, &TextFormatter{DisableColors: true}, smallFields)
+}
+
+func BenchmarkLargeTextFormatter(b *testing.B) {
+ doBenchmark(b, &TextFormatter{DisableColors: true}, largeFields)
+}
+
+func BenchmarkSmallColoredTextFormatter(b *testing.B) {
+ doBenchmark(b, &TextFormatter{ForceColors: true}, smallFields)
+}
+
+func BenchmarkLargeColoredTextFormatter(b *testing.B) {
+ doBenchmark(b, &TextFormatter{ForceColors: true}, largeFields)
+}
+
+func BenchmarkSmallJSONFormatter(b *testing.B) {
+ doBenchmark(b, &JSONFormatter{}, smallFields)
+}
+
+func BenchmarkLargeJSONFormatter(b *testing.B) {
+ doBenchmark(b, &JSONFormatter{}, largeFields)
+}
+
+func doBenchmark(b *testing.B, formatter Formatter, fields Fields) {
+ logger := New()
+
+ entry := &Entry{
+ Time: time.Time{},
+ Level: InfoLevel,
+ Message: "message",
+ Data: fields,
+ Logger: logger,
+ }
+ var d []byte
+ var err error
+ for i := 0; i < b.N; i++ {
+ d, err = formatter.Format(entry)
+ if err != nil {
+ b.Fatal(err)
+ }
+ b.SetBytes(int64(len(d)))
+ }
+}
diff --git a/vendor/github.com/sirupsen/logrus/hook_test.go b/vendor/github.com/sirupsen/logrus/hook_test.go
new file mode 100644
index 00000000..13f34cb6
--- /dev/null
+++ b/vendor/github.com/sirupsen/logrus/hook_test.go
@@ -0,0 +1,122 @@
+package logrus
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+type TestHook struct {
+ Fired bool
+}
+
+func (hook *TestHook) Fire(entry *Entry) error {
+ hook.Fired = true
+ return nil
+}
+
+func (hook *TestHook) Levels() []Level {
+ return []Level{
+ DebugLevel,
+ InfoLevel,
+ WarnLevel,
+ ErrorLevel,
+ FatalLevel,
+ PanicLevel,
+ }
+}
+
+func TestHookFires(t *testing.T) {
+ hook := new(TestHook)
+
+ LogAndAssertJSON(t, func(log *Logger) {
+ log.Hooks.Add(hook)
+ assert.Equal(t, hook.Fired, false)
+
+ log.Print("test")
+ }, func(fields Fields) {
+ assert.Equal(t, hook.Fired, true)
+ })
+}
+
+type ModifyHook struct {
+}
+
+func (hook *ModifyHook) Fire(entry *Entry) error {
+ entry.Data["wow"] = "whale"
+ return nil
+}
+
+func (hook *ModifyHook) Levels() []Level {
+ return []Level{
+ DebugLevel,
+ InfoLevel,
+ WarnLevel,
+ ErrorLevel,
+ FatalLevel,
+ PanicLevel,
+ }
+}
+
+func TestHookCanModifyEntry(t *testing.T) {
+ hook := new(ModifyHook)
+
+ LogAndAssertJSON(t, func(log *Logger) {
+ log.Hooks.Add(hook)
+ log.WithField("wow", "elephant").Print("test")
+ }, func(fields Fields) {
+ assert.Equal(t, fields["wow"], "whale")
+ })
+}
+
+func TestCanFireMultipleHooks(t *testing.T) {
+ hook1 := new(ModifyHook)
+ hook2 := new(TestHook)
+
+ LogAndAssertJSON(t, func(log *Logger) {
+ log.Hooks.Add(hook1)
+ log.Hooks.Add(hook2)
+
+ log.WithField("wow", "elephant").Print("test")
+ }, func(fields Fields) {
+ assert.Equal(t, fields["wow"], "whale")
+ assert.Equal(t, hook2.Fired, true)
+ })
+}
+
+type ErrorHook struct {
+ Fired bool
+}
+
+func (hook *ErrorHook) Fire(entry *Entry) error {
+ hook.Fired = true
+ return nil
+}
+
+func (hook *ErrorHook) Levels() []Level {
+ return []Level{
+ ErrorLevel,
+ }
+}
+
+func TestErrorHookShouldntFireOnInfo(t *testing.T) {
+ hook := new(ErrorHook)
+
+ LogAndAssertJSON(t, func(log *Logger) {
+ log.Hooks.Add(hook)
+ log.Info("test")
+ }, func(fields Fields) {
+ assert.Equal(t, hook.Fired, false)
+ })
+}
+
+func TestErrorHookShouldFireOnError(t *testing.T) {
+ hook := new(ErrorHook)
+
+ LogAndAssertJSON(t, func(log *Logger) {
+ log.Hooks.Add(hook)
+ log.Error("test")
+ }, func(fields Fields) {
+ assert.Equal(t, hook.Fired, true)
+ })
+}
diff --git a/vendor/github.com/sirupsen/logrus/hooks.go b/vendor/github.com/sirupsen/logrus/hooks.go
new file mode 100644
index 00000000..3f151cdc
--- /dev/null
+++ b/vendor/github.com/sirupsen/logrus/hooks.go
@@ -0,0 +1,34 @@
+package logrus
+
+// A hook to be fired when logging on the logging levels returned from
+// `Levels()` on your implementation of the interface. Note that this is not
+// fired in a goroutine or a channel with workers, you should handle such
+// functionality yourself if your call is non-blocking and you don't wish for
+// the logging calls for levels returned from `Levels()` to block.
+type Hook interface {
+ Levels() []Level
+ Fire(*Entry) error
+}
+
+// Internal type for storing the hooks on a logger instance.
+type LevelHooks map[Level][]Hook
+
+// Add a hook to an instance of logger. This is called with
+// `log.Hooks.Add(new(MyHook))` where `MyHook` implements the `Hook` interface.
+func (hooks LevelHooks) Add(hook Hook) {
+ for _, level := range hook.Levels() {
+ hooks[level] = append(hooks[level], hook)
+ }
+}
+
+// Fire all the hooks for the passed level. Used by `entry.log` to fire
+// appropriate hooks for a log entry.
+func (hooks LevelHooks) Fire(level Level, entry *Entry) error {
+ for _, hook := range hooks[level] {
+ if err := hook.Fire(entry); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
diff --git a/vendor/github.com/sirupsen/logrus/hooks/syslog/README.md b/vendor/github.com/sirupsen/logrus/hooks/syslog/README.md
new file mode 100644
index 00000000..066704b3
--- /dev/null
+++ b/vendor/github.com/sirupsen/logrus/hooks/syslog/README.md
@@ -0,0 +1,39 @@
+# Syslog Hooks for Logrus
+
+## Usage
+
+```go
+import (
+ "log/syslog"
+ "github.com/Sirupsen/logrus"
+ logrus_syslog "github.com/Sirupsen/logrus/hooks/syslog"
+)
+
+func main() {
+ log := logrus.New()
+ hook, err := logrus_syslog.NewSyslogHook("udp", "localhost:514", syslog.LOG_INFO, "")
+
+ if err == nil {
+ log.Hooks.Add(hook)
+ }
+}
+```
+
+If you want to connect to local syslog (Ex. "/dev/log" or "/var/run/syslog" or "/var/run/log"). Just assign empty string to the first two parameters of `NewSyslogHook`. It should look like the following.
+
+```go
+import (
+ "log/syslog"
+ "github.com/Sirupsen/logrus"
+ logrus_syslog "github.com/Sirupsen/logrus/hooks/syslog"
+)
+
+func main() {
+ log := logrus.New()
+ hook, err := logrus_syslog.NewSyslogHook("", "", syslog.LOG_INFO, "")
+
+ if err == nil {
+ log.Hooks.Add(hook)
+ }
+}
+```
\ No newline at end of file
diff --git a/vendor/github.com/sirupsen/logrus/hooks/syslog/syslog.go b/vendor/github.com/sirupsen/logrus/hooks/syslog/syslog.go
new file mode 100644
index 00000000..a36e2003
--- /dev/null
+++ b/vendor/github.com/sirupsen/logrus/hooks/syslog/syslog.go
@@ -0,0 +1,54 @@
+// +build !windows,!nacl,!plan9
+
+package logrus_syslog
+
+import (
+ "fmt"
+ "github.com/Sirupsen/logrus"
+ "log/syslog"
+ "os"
+)
+
+// SyslogHook to send logs via syslog.
+type SyslogHook struct {
+ Writer *syslog.Writer
+ SyslogNetwork string
+ SyslogRaddr string
+}
+
+// Creates a hook to be added to an instance of logger. This is called with
+// `hook, err := NewSyslogHook("udp", "localhost:514", syslog.LOG_DEBUG, "")`
+// `if err == nil { log.Hooks.Add(hook) }`
+func NewSyslogHook(network, raddr string, priority syslog.Priority, tag string) (*SyslogHook, error) {
+ w, err := syslog.Dial(network, raddr, priority, tag)
+ return &SyslogHook{w, network, raddr}, err
+}
+
+func (hook *SyslogHook) Fire(entry *logrus.Entry) error {
+ line, err := entry.String()
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "Unable to read entry, %v", err)
+ return err
+ }
+
+ switch entry.Level {
+ case logrus.PanicLevel:
+ return hook.Writer.Crit(line)
+ case logrus.FatalLevel:
+ return hook.Writer.Crit(line)
+ case logrus.ErrorLevel:
+ return hook.Writer.Err(line)
+ case logrus.WarnLevel:
+ return hook.Writer.Warning(line)
+ case logrus.InfoLevel:
+ return hook.Writer.Info(line)
+ case logrus.DebugLevel:
+ return hook.Writer.Debug(line)
+ default:
+ return nil
+ }
+}
+
+func (hook *SyslogHook) Levels() []logrus.Level {
+ return logrus.AllLevels
+}
diff --git a/vendor/github.com/sirupsen/logrus/hooks/syslog/syslog_test.go b/vendor/github.com/sirupsen/logrus/hooks/syslog/syslog_test.go
new file mode 100644
index 00000000..42762dc1
--- /dev/null
+++ b/vendor/github.com/sirupsen/logrus/hooks/syslog/syslog_test.go
@@ -0,0 +1,26 @@
+package logrus_syslog
+
+import (
+ "github.com/Sirupsen/logrus"
+ "log/syslog"
+ "testing"
+)
+
+func TestLocalhostAddAndPrint(t *testing.T) {
+ log := logrus.New()
+ hook, err := NewSyslogHook("udp", "localhost:514", syslog.LOG_INFO, "")
+
+ if err != nil {
+ t.Errorf("Unable to connect to local syslog.")
+ }
+
+ log.Hooks.Add(hook)
+
+ for _, level := range hook.Levels() {
+ if len(log.Hooks[level]) != 1 {
+ t.Errorf("SyslogHook was not added. The length of log.Hooks[%v]: %v", level, len(log.Hooks[level]))
+ }
+ }
+
+ log.Info("Congratulations!")
+}
diff --git a/vendor/github.com/sirupsen/logrus/hooks/test/test.go b/vendor/github.com/sirupsen/logrus/hooks/test/test.go
new file mode 100644
index 00000000..06881253
--- /dev/null
+++ b/vendor/github.com/sirupsen/logrus/hooks/test/test.go
@@ -0,0 +1,67 @@
+package test
+
+import (
+ "io/ioutil"
+
+ "github.com/Sirupsen/logrus"
+)
+
+// test.Hook is a hook designed for dealing with logs in test scenarios.
+type Hook struct {
+ Entries []*logrus.Entry
+}
+
+// Installs a test hook for the global logger.
+func NewGlobal() *Hook {
+
+ hook := new(Hook)
+ logrus.AddHook(hook)
+
+ return hook
+
+}
+
+// Installs a test hook for a given local logger.
+func NewLocal(logger *logrus.Logger) *Hook {
+
+ hook := new(Hook)
+ logger.Hooks.Add(hook)
+
+ return hook
+
+}
+
+// Creates a discarding logger and installs the test hook.
+func NewNullLogger() (*logrus.Logger, *Hook) {
+
+ logger := logrus.New()
+ logger.Out = ioutil.Discard
+
+ return logger, NewLocal(logger)
+
+}
+
+func (t *Hook) Fire(e *logrus.Entry) error {
+ t.Entries = append(t.Entries, e)
+ return nil
+}
+
+func (t *Hook) Levels() []logrus.Level {
+ return logrus.AllLevels
+}
+
+// LastEntry returns the last entry that was logged or nil.
+func (t *Hook) LastEntry() (l *logrus.Entry) {
+
+ if i := len(t.Entries) - 1; i < 0 {
+ return nil
+ } else {
+ return t.Entries[i]
+ }
+
+}
+
+// Reset removes all Entries from this test hook.
+func (t *Hook) Reset() {
+ t.Entries = make([]*logrus.Entry, 0)
+}
diff --git a/vendor/github.com/sirupsen/logrus/hooks/test/test_test.go b/vendor/github.com/sirupsen/logrus/hooks/test/test_test.go
new file mode 100644
index 00000000..d69455ba
--- /dev/null
+++ b/vendor/github.com/sirupsen/logrus/hooks/test/test_test.go
@@ -0,0 +1,39 @@
+package test
+
+import (
+ "testing"
+
+ "github.com/Sirupsen/logrus"
+ "github.com/stretchr/testify/assert"
+)
+
+func TestAllHooks(t *testing.T) {
+
+ assert := assert.New(t)
+
+ logger, hook := NewNullLogger()
+ assert.Nil(hook.LastEntry())
+ assert.Equal(0, len(hook.Entries))
+
+ logger.Error("Hello error")
+ assert.Equal(logrus.ErrorLevel, hook.LastEntry().Level)
+ assert.Equal("Hello error", hook.LastEntry().Message)
+ assert.Equal(1, len(hook.Entries))
+
+ logger.Warn("Hello warning")
+ assert.Equal(logrus.WarnLevel, hook.LastEntry().Level)
+ assert.Equal("Hello warning", hook.LastEntry().Message)
+ assert.Equal(2, len(hook.Entries))
+
+ hook.Reset()
+ assert.Nil(hook.LastEntry())
+ assert.Equal(0, len(hook.Entries))
+
+ hook = NewGlobal()
+
+ logrus.Error("Hello error")
+ assert.Equal(logrus.ErrorLevel, hook.LastEntry().Level)
+ assert.Equal("Hello error", hook.LastEntry().Message)
+ assert.Equal(1, len(hook.Entries))
+
+}
diff --git a/vendor/github.com/sirupsen/logrus/json_formatter.go b/vendor/github.com/sirupsen/logrus/json_formatter.go
new file mode 100644
index 00000000..266554e9
--- /dev/null
+++ b/vendor/github.com/sirupsen/logrus/json_formatter.go
@@ -0,0 +1,74 @@
+package logrus
+
+import (
+ "encoding/json"
+ "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 {
+ // TimestampFormat sets the format used for marshaling timestamps.
+ 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) {
+ data := make(Fields, len(entry.Data)+3)
+ for k, v := range entry.Data {
+ switch v := v.(type) {
+ case error:
+ // Otherwise errors are ignored by `encoding/json`
+ // https://github.com/Sirupsen/logrus/issues/137
+ data[k] = v.Error()
+ default:
+ data[k] = v
+ }
+ }
+ prefixFieldClashes(data)
+
+ timestampFormat := f.TimestampFormat
+ if timestampFormat == "" {
+ timestampFormat = DefaultTimestampFormat
+ }
+
+ if !f.DisableTimestamp {
+ data[f.FieldMap.resolve(FieldKeyTime)] = entry.Time.Format(timestampFormat)
+ }
+ data[f.FieldMap.resolve(FieldKeyMsg)] = entry.Message
+ data[f.FieldMap.resolve(FieldKeyLevel)] = entry.Level.String()
+
+ serialized, err := json.Marshal(data)
+ if err != nil {
+ return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err)
+ }
+ return append(serialized, '\n'), nil
+}
diff --git a/vendor/github.com/sirupsen/logrus/json_formatter_test.go b/vendor/github.com/sirupsen/logrus/json_formatter_test.go
new file mode 100644
index 00000000..51093a79
--- /dev/null
+++ b/vendor/github.com/sirupsen/logrus/json_formatter_test.go
@@ -0,0 +1,199 @@
+package logrus
+
+import (
+ "encoding/json"
+ "errors"
+ "strings"
+ "testing"
+)
+
+func TestErrorNotLost(t *testing.T) {
+ formatter := &JSONFormatter{}
+
+ b, err := formatter.Format(WithField("error", errors.New("wild walrus")))
+ if err != nil {
+ t.Fatal("Unable to format entry: ", err)
+ }
+
+ entry := make(map[string]interface{})
+ err = json.Unmarshal(b, &entry)
+ if err != nil {
+ t.Fatal("Unable to unmarshal formatted entry: ", err)
+ }
+
+ if entry["error"] != "wild walrus" {
+ t.Fatal("Error field not set")
+ }
+}
+
+func TestErrorNotLostOnFieldNotNamedError(t *testing.T) {
+ formatter := &JSONFormatter{}
+
+ b, err := formatter.Format(WithField("omg", errors.New("wild walrus")))
+ if err != nil {
+ t.Fatal("Unable to format entry: ", err)
+ }
+
+ entry := make(map[string]interface{})
+ err = json.Unmarshal(b, &entry)
+ if err != nil {
+ t.Fatal("Unable to unmarshal formatted entry: ", err)
+ }
+
+ if entry["omg"] != "wild walrus" {
+ t.Fatal("Error field not set")
+ }
+}
+
+func TestFieldClashWithTime(t *testing.T) {
+ formatter := &JSONFormatter{}
+
+ b, err := formatter.Format(WithField("time", "right now!"))
+ if err != nil {
+ t.Fatal("Unable to format entry: ", err)
+ }
+
+ entry := make(map[string]interface{})
+ err = json.Unmarshal(b, &entry)
+ if err != nil {
+ t.Fatal("Unable to unmarshal formatted entry: ", err)
+ }
+
+ if entry["fields.time"] != "right now!" {
+ t.Fatal("fields.time not set to original time field")
+ }
+
+ if entry["time"] != "0001-01-01T00:00:00Z" {
+ t.Fatal("time field not set to current time, was: ", entry["time"])
+ }
+}
+
+func TestFieldClashWithMsg(t *testing.T) {
+ formatter := &JSONFormatter{}
+
+ b, err := formatter.Format(WithField("msg", "something"))
+ if err != nil {
+ t.Fatal("Unable to format entry: ", err)
+ }
+
+ entry := make(map[string]interface{})
+ err = json.Unmarshal(b, &entry)
+ if err != nil {
+ t.Fatal("Unable to unmarshal formatted entry: ", err)
+ }
+
+ if entry["fields.msg"] != "something" {
+ t.Fatal("fields.msg not set to original msg field")
+ }
+}
+
+func TestFieldClashWithLevel(t *testing.T) {
+ formatter := &JSONFormatter{}
+
+ b, err := formatter.Format(WithField("level", "something"))
+ if err != nil {
+ t.Fatal("Unable to format entry: ", err)
+ }
+
+ entry := make(map[string]interface{})
+ err = json.Unmarshal(b, &entry)
+ if err != nil {
+ t.Fatal("Unable to unmarshal formatted entry: ", err)
+ }
+
+ if entry["fields.level"] != "something" {
+ t.Fatal("fields.level not set to original level field")
+ }
+}
+
+func TestJSONEntryEndsWithNewline(t *testing.T) {
+ formatter := &JSONFormatter{}
+
+ b, err := formatter.Format(WithField("level", "something"))
+ if err != nil {
+ t.Fatal("Unable to format entry: ", err)
+ }
+
+ if b[len(b)-1] != '\n' {
+ t.Fatal("Expected JSON log entry to end with a newline")
+ }
+}
+
+func TestJSONMessageKey(t *testing.T) {
+ formatter := &JSONFormatter{
+ FieldMap: FieldMap{
+ FieldKeyMsg: "message",
+ },
+ }
+
+ b, err := formatter.Format(&Entry{Message: "oh hai"})
+ if err != nil {
+ t.Fatal("Unable to format entry: ", err)
+ }
+ s := string(b)
+ if !(strings.Contains(s, "message") && strings.Contains(s, "oh hai")) {
+ t.Fatal("Expected JSON to format message key")
+ }
+}
+
+func TestJSONLevelKey(t *testing.T) {
+ formatter := &JSONFormatter{
+ FieldMap: FieldMap{
+ FieldKeyLevel: "somelevel",
+ },
+ }
+
+ b, err := formatter.Format(WithField("level", "something"))
+ if err != nil {
+ t.Fatal("Unable to format entry: ", err)
+ }
+ s := string(b)
+ if !strings.Contains(s, "somelevel") {
+ t.Fatal("Expected JSON to format level key")
+ }
+}
+
+func TestJSONTimeKey(t *testing.T) {
+ formatter := &JSONFormatter{
+ FieldMap: FieldMap{
+ FieldKeyTime: "timeywimey",
+ },
+ }
+
+ b, err := formatter.Format(WithField("level", "something"))
+ if err != nil {
+ t.Fatal("Unable to format entry: ", err)
+ }
+ s := string(b)
+ if !strings.Contains(s, "timeywimey") {
+ t.Fatal("Expected JSON to format time key")
+ }
+}
+
+func TestJSONDisableTimestamp(t *testing.T) {
+ formatter := &JSONFormatter{
+ DisableTimestamp: true,
+ }
+
+ b, err := formatter.Format(WithField("level", "something"))
+ if err != nil {
+ t.Fatal("Unable to format entry: ", err)
+ }
+ s := string(b)
+ if strings.Contains(s, FieldKeyTime) {
+ t.Error("Did not prevent timestamp", s)
+ }
+}
+
+func TestJSONEnableTimestamp(t *testing.T) {
+ formatter := &JSONFormatter{}
+
+ b, err := formatter.Format(WithField("level", "something"))
+ if err != nil {
+ t.Fatal("Unable to format entry: ", err)
+ }
+ s := string(b)
+ if !strings.Contains(s, FieldKeyTime) {
+ t.Error("Timestamp not present", s)
+ }
+}
diff --git a/vendor/github.com/sirupsen/logrus/logger.go b/vendor/github.com/sirupsen/logrus/logger.go
new file mode 100644
index 00000000..b769f3d3
--- /dev/null
+++ b/vendor/github.com/sirupsen/logrus/logger.go
@@ -0,0 +1,308 @@
+package logrus
+
+import (
+ "io"
+ "os"
+ "sync"
+)
+
+type Logger struct {
+ // The logs are `io.Copy`'d to this in a mutex. It's common to set this to a
+ // file, or leave it default which is `os.Stderr`. You can also set this to
+ // something more adventorous, such as logging to Kafka.
+ Out io.Writer
+ // Hooks for the logger instance. These allow firing events based on logging
+ // levels and log entries. For example, to send errors to an error tracking
+ // service, log to StatsD or dump the core on fatal errors.
+ Hooks LevelHooks
+ // All log entries pass through the formatter before logged to Out. The
+ // included formatters are `TextFormatter` and `JSONFormatter` for which
+ // TextFormatter is the default. In development (when a TTY is attached) it
+ // logs with colors, but to a file it wouldn't. You can easily implement your
+ // own that implements the `Formatter` interface, see the `README` or included
+ // formatters for examples.
+ Formatter Formatter
+ // The logging level the logger should log at. This is typically (and defaults
+ // to) `logrus.Info`, which allows Info(), Warn(), Error() and Fatal() to be
+ // logged. `logrus.Debug` is useful in
+ Level Level
+ // Used to sync writing to the log. Locking is enabled by Default
+ 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`,
+// `Out` and `Hooks` directly on the default logger instance. You can also just
+// instantiate your own:
+//
+// var log = &Logger{
+// Out: os.Stderr,
+// Formatter: new(JSONFormatter),
+// Hooks: make(LevelHooks),
+// Level: logrus.DebugLevel,
+// }
+//
+// It's recommended to make this a global instance called `log`.
+func New() *Logger {
+ return &Logger{
+ Out: os.Stderr,
+ Formatter: new(TextFormatter),
+ Hooks: make(LevelHooks),
+ Level: InfoLevel,
+ }
+}
+
+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.
+// If you want multiple fields, use `WithFields`.
+func (logger *Logger) WithField(key string, value interface{}) *Entry {
+ 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
+// each `Field`.
+func (logger *Logger) WithFields(fields Fields) *Entry {
+ 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
+// `WithError` for the given `error`.
+func (logger *Logger) WithError(err error) *Entry {
+ entry := logger.newEntry()
+ defer logger.releaseEntry(entry)
+ return entry.WithError(err)
+}
+
+func (logger *Logger) Debugf(format string, args ...interface{}) {
+ if logger.Level >= DebugLevel {
+ entry := logger.newEntry()
+ entry.Debugf(format, args...)
+ logger.releaseEntry(entry)
+ }
+}
+
+func (logger *Logger) Infof(format string, args ...interface{}) {
+ if logger.Level >= InfoLevel {
+ entry := logger.newEntry()
+ entry.Infof(format, args...)
+ logger.releaseEntry(entry)
+ }
+}
+
+func (logger *Logger) Printf(format string, args ...interface{}) {
+ entry := logger.newEntry()
+ entry.Printf(format, args...)
+ logger.releaseEntry(entry)
+}
+
+func (logger *Logger) Warnf(format string, args ...interface{}) {
+ if logger.Level >= WarnLevel {
+ entry := logger.newEntry()
+ entry.Warnf(format, args...)
+ logger.releaseEntry(entry)
+ }
+}
+
+func (logger *Logger) Warningf(format string, args ...interface{}) {
+ if logger.Level >= WarnLevel {
+ entry := logger.newEntry()
+ entry.Warnf(format, args...)
+ logger.releaseEntry(entry)
+ }
+}
+
+func (logger *Logger) Errorf(format string, args ...interface{}) {
+ if logger.Level >= ErrorLevel {
+ entry := logger.newEntry()
+ entry.Errorf(format, args...)
+ logger.releaseEntry(entry)
+ }
+}
+
+func (logger *Logger) Fatalf(format string, args ...interface{}) {
+ if logger.Level >= FatalLevel {
+ entry := logger.newEntry()
+ entry.Fatalf(format, args...)
+ logger.releaseEntry(entry)
+ }
+ Exit(1)
+}
+
+func (logger *Logger) Panicf(format string, args ...interface{}) {
+ if logger.Level >= PanicLevel {
+ entry := logger.newEntry()
+ entry.Panicf(format, args...)
+ logger.releaseEntry(entry)
+ }
+}
+
+func (logger *Logger) Debug(args ...interface{}) {
+ if logger.Level >= DebugLevel {
+ entry := logger.newEntry()
+ entry.Debug(args...)
+ logger.releaseEntry(entry)
+ }
+}
+
+func (logger *Logger) Info(args ...interface{}) {
+ if logger.Level >= InfoLevel {
+ entry := logger.newEntry()
+ entry.Info(args...)
+ logger.releaseEntry(entry)
+ }
+}
+
+func (logger *Logger) Print(args ...interface{}) {
+ entry := logger.newEntry()
+ entry.Info(args...)
+ logger.releaseEntry(entry)
+}
+
+func (logger *Logger) Warn(args ...interface{}) {
+ if logger.Level >= WarnLevel {
+ entry := logger.newEntry()
+ entry.Warn(args...)
+ logger.releaseEntry(entry)
+ }
+}
+
+func (logger *Logger) Warning(args ...interface{}) {
+ if logger.Level >= WarnLevel {
+ entry := logger.newEntry()
+ entry.Warn(args...)
+ logger.releaseEntry(entry)
+ }
+}
+
+func (logger *Logger) Error(args ...interface{}) {
+ if logger.Level >= ErrorLevel {
+ entry := logger.newEntry()
+ entry.Error(args...)
+ logger.releaseEntry(entry)
+ }
+}
+
+func (logger *Logger) Fatal(args ...interface{}) {
+ if logger.Level >= FatalLevel {
+ entry := logger.newEntry()
+ entry.Fatal(args...)
+ logger.releaseEntry(entry)
+ }
+ Exit(1)
+}
+
+func (logger *Logger) Panic(args ...interface{}) {
+ if logger.Level >= PanicLevel {
+ entry := logger.newEntry()
+ entry.Panic(args...)
+ logger.releaseEntry(entry)
+ }
+}
+
+func (logger *Logger) Debugln(args ...interface{}) {
+ if logger.Level >= DebugLevel {
+ entry := logger.newEntry()
+ entry.Debugln(args...)
+ logger.releaseEntry(entry)
+ }
+}
+
+func (logger *Logger) Infoln(args ...interface{}) {
+ if logger.Level >= InfoLevel {
+ entry := logger.newEntry()
+ entry.Infoln(args...)
+ logger.releaseEntry(entry)
+ }
+}
+
+func (logger *Logger) Println(args ...interface{}) {
+ entry := logger.newEntry()
+ entry.Println(args...)
+ logger.releaseEntry(entry)
+}
+
+func (logger *Logger) Warnln(args ...interface{}) {
+ if logger.Level >= WarnLevel {
+ entry := logger.newEntry()
+ entry.Warnln(args...)
+ logger.releaseEntry(entry)
+ }
+}
+
+func (logger *Logger) Warningln(args ...interface{}) {
+ if logger.Level >= WarnLevel {
+ entry := logger.newEntry()
+ entry.Warnln(args...)
+ logger.releaseEntry(entry)
+ }
+}
+
+func (logger *Logger) Errorln(args ...interface{}) {
+ if logger.Level >= ErrorLevel {
+ entry := logger.newEntry()
+ entry.Errorln(args...)
+ logger.releaseEntry(entry)
+ }
+}
+
+func (logger *Logger) Fatalln(args ...interface{}) {
+ if logger.Level >= FatalLevel {
+ entry := logger.newEntry()
+ entry.Fatalln(args...)
+ logger.releaseEntry(entry)
+ }
+ Exit(1)
+}
+
+func (logger *Logger) Panicln(args ...interface{}) {
+ if logger.Level >= PanicLevel {
+ 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()
+}
diff --git a/vendor/github.com/sirupsen/logrus/logger_bench_test.go b/vendor/github.com/sirupsen/logrus/logger_bench_test.go
new file mode 100644
index 00000000..dd23a353
--- /dev/null
+++ b/vendor/github.com/sirupsen/logrus/logger_bench_test.go
@@ -0,0 +1,61 @@
+package logrus
+
+import (
+ "os"
+ "testing"
+)
+
+// smallFields is a small size data set for benchmarking
+var loggerFields = Fields{
+ "foo": "bar",
+ "baz": "qux",
+ "one": "two",
+ "three": "four",
+}
+
+func BenchmarkDummyLogger(b *testing.B) {
+ nullf, err := os.OpenFile("/dev/null", os.O_WRONLY, 0666)
+ if err != nil {
+ b.Fatalf("%v", err)
+ }
+ defer nullf.Close()
+ doLoggerBenchmark(b, nullf, &TextFormatter{DisableColors: true}, smallFields)
+}
+
+func BenchmarkDummyLoggerNoLock(b *testing.B) {
+ nullf, err := os.OpenFile("/dev/null", os.O_WRONLY|os.O_APPEND, 0666)
+ if err != nil {
+ b.Fatalf("%v", err)
+ }
+ defer nullf.Close()
+ doLoggerBenchmarkNoLock(b, nullf, &TextFormatter{DisableColors: true}, smallFields)
+}
+
+func doLoggerBenchmark(b *testing.B, out *os.File, formatter Formatter, fields Fields) {
+ logger := Logger{
+ Out: out,
+ Level: InfoLevel,
+ Formatter: formatter,
+ }
+ entry := logger.WithFields(fields)
+ b.RunParallel(func(pb *testing.PB) {
+ for pb.Next() {
+ entry.Info("aaa")
+ }
+ })
+}
+
+func doLoggerBenchmarkNoLock(b *testing.B, out *os.File, formatter Formatter, fields Fields) {
+ logger := Logger{
+ Out: out,
+ Level: InfoLevel,
+ Formatter: formatter,
+ }
+ logger.SetNoLock()
+ entry := logger.WithFields(fields)
+ b.RunParallel(func(pb *testing.PB) {
+ for pb.Next() {
+ entry.Info("aaa")
+ }
+ })
+}
diff --git a/vendor/github.com/sirupsen/logrus/logrus.go b/vendor/github.com/sirupsen/logrus/logrus.go
new file mode 100644
index 00000000..e5966911
--- /dev/null
+++ b/vendor/github.com/sirupsen/logrus/logrus.go
@@ -0,0 +1,143 @@
+package logrus
+
+import (
+ "fmt"
+ "log"
+ "strings"
+)
+
+// Fields type, used to pass to `WithFields`.
+type Fields map[string]interface{}
+
+// Level type
+type Level uint8
+
+// Convert the Level to a string. E.g. PanicLevel becomes "panic".
+func (level Level) String() string {
+ switch level {
+ case DebugLevel:
+ return "debug"
+ case InfoLevel:
+ return "info"
+ case WarnLevel:
+ return "warning"
+ case ErrorLevel:
+ return "error"
+ case FatalLevel:
+ return "fatal"
+ case PanicLevel:
+ return "panic"
+ }
+
+ return "unknown"
+}
+
+// ParseLevel takes a string level and returns the Logrus log level constant.
+func ParseLevel(lvl string) (Level, error) {
+ switch strings.ToLower(lvl) {
+ case "panic":
+ return PanicLevel, nil
+ case "fatal":
+ return FatalLevel, nil
+ case "error":
+ return ErrorLevel, nil
+ case "warn", "warning":
+ return WarnLevel, nil
+ case "info":
+ return InfoLevel, nil
+ case "debug":
+ return DebugLevel, nil
+ }
+
+ var l Level
+ return l, fmt.Errorf("not a valid logrus Level: %q", lvl)
+}
+
+// A constant exposing all logging levels
+var AllLevels = []Level{
+ PanicLevel,
+ FatalLevel,
+ ErrorLevel,
+ WarnLevel,
+ InfoLevel,
+ DebugLevel,
+}
+
+// These are the different logging levels. You can set the logging level to log
+// on your instance of logger, obtained with `logrus.New()`.
+const (
+ // PanicLevel level, highest level of severity. Logs and then calls panic with the
+ // message passed to Debug, Info, ...
+ PanicLevel Level = iota
+ // FatalLevel level. Logs and then calls `os.Exit(1)`. It will exit even if the
+ // logging level is set to Panic.
+ FatalLevel
+ // ErrorLevel level. Logs. Used for errors that should definitely be noted.
+ // Commonly used for hooks to send errors to an error tracking service.
+ ErrorLevel
+ // WarnLevel level. Non-critical entries that deserve eyes.
+ WarnLevel
+ // InfoLevel level. General operational entries about what's going on inside the
+ // application.
+ InfoLevel
+ // DebugLevel level. Usually only enabled when debugging. Very verbose logging.
+ DebugLevel
+)
+
+// Won't compile if StdLogger can't be realized by a log.Logger
+var (
+ _ StdLogger = &log.Logger{}
+ _ StdLogger = &Entry{}
+ _ StdLogger = &Logger{}
+)
+
+// StdLogger is what your logrus-enabled library should take, that way
+// it'll accept a stdlib logger and a logrus logger. There's no standard
+// interface, this is the closest we get, unfortunately.
+type StdLogger interface {
+ Print(...interface{})
+ Printf(string, ...interface{})
+ Println(...interface{})
+
+ Fatal(...interface{})
+ Fatalf(string, ...interface{})
+ Fatalln(...interface{})
+
+ Panic(...interface{})
+ Panicf(string, ...interface{})
+ Panicln(...interface{})
+}
+
+// The FieldLogger interface generalizes the Entry and Logger types
+type FieldLogger interface {
+ WithField(key string, value interface{}) *Entry
+ WithFields(fields Fields) *Entry
+ WithError(err error) *Entry
+
+ Debugf(format string, args ...interface{})
+ Infof(format string, args ...interface{})
+ Printf(format string, args ...interface{})
+ Warnf(format string, args ...interface{})
+ Warningf(format string, args ...interface{})
+ Errorf(format string, args ...interface{})
+ Fatalf(format string, args ...interface{})
+ Panicf(format string, args ...interface{})
+
+ Debug(args ...interface{})
+ Info(args ...interface{})
+ Print(args ...interface{})
+ Warn(args ...interface{})
+ Warning(args ...interface{})
+ Error(args ...interface{})
+ Fatal(args ...interface{})
+ Panic(args ...interface{})
+
+ Debugln(args ...interface{})
+ Infoln(args ...interface{})
+ Println(args ...interface{})
+ Warnln(args ...interface{})
+ Warningln(args ...interface{})
+ Errorln(args ...interface{})
+ Fatalln(args ...interface{})
+ Panicln(args ...interface{})
+}
diff --git a/vendor/github.com/sirupsen/logrus/logrus_test.go b/vendor/github.com/sirupsen/logrus/logrus_test.go
new file mode 100644
index 00000000..78cbc282
--- /dev/null
+++ b/vendor/github.com/sirupsen/logrus/logrus_test.go
@@ -0,0 +1,386 @@
+package logrus
+
+import (
+ "bytes"
+ "encoding/json"
+ "strconv"
+ "strings"
+ "sync"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func LogAndAssertJSON(t *testing.T, log func(*Logger), assertions func(fields Fields)) {
+ var buffer bytes.Buffer
+ var fields Fields
+
+ logger := New()
+ logger.Out = &buffer
+ logger.Formatter = new(JSONFormatter)
+
+ log(logger)
+
+ err := json.Unmarshal(buffer.Bytes(), &fields)
+ assert.Nil(t, err)
+
+ assertions(fields)
+}
+
+func LogAndAssertText(t *testing.T, log func(*Logger), assertions func(fields map[string]string)) {
+ var buffer bytes.Buffer
+
+ logger := New()
+ logger.Out = &buffer
+ logger.Formatter = &TextFormatter{
+ DisableColors: true,
+ }
+
+ log(logger)
+
+ fields := make(map[string]string)
+ for _, kv := range strings.Split(buffer.String(), " ") {
+ if !strings.Contains(kv, "=") {
+ continue
+ }
+ kvArr := strings.Split(kv, "=")
+ key := strings.TrimSpace(kvArr[0])
+ val := kvArr[1]
+ if kvArr[1][0] == '"' {
+ var err error
+ val, err = strconv.Unquote(val)
+ assert.NoError(t, err)
+ }
+ fields[key] = val
+ }
+ assertions(fields)
+}
+
+func TestPrint(t *testing.T) {
+ LogAndAssertJSON(t, func(log *Logger) {
+ log.Print("test")
+ }, func(fields Fields) {
+ assert.Equal(t, fields["msg"], "test")
+ assert.Equal(t, fields["level"], "info")
+ })
+}
+
+func TestInfo(t *testing.T) {
+ LogAndAssertJSON(t, func(log *Logger) {
+ log.Info("test")
+ }, func(fields Fields) {
+ assert.Equal(t, fields["msg"], "test")
+ assert.Equal(t, fields["level"], "info")
+ })
+}
+
+func TestWarn(t *testing.T) {
+ LogAndAssertJSON(t, func(log *Logger) {
+ log.Warn("test")
+ }, func(fields Fields) {
+ assert.Equal(t, fields["msg"], "test")
+ assert.Equal(t, fields["level"], "warning")
+ })
+}
+
+func TestInfolnShouldAddSpacesBetweenStrings(t *testing.T) {
+ LogAndAssertJSON(t, func(log *Logger) {
+ log.Infoln("test", "test")
+ }, func(fields Fields) {
+ assert.Equal(t, fields["msg"], "test test")
+ })
+}
+
+func TestInfolnShouldAddSpacesBetweenStringAndNonstring(t *testing.T) {
+ LogAndAssertJSON(t, func(log *Logger) {
+ log.Infoln("test", 10)
+ }, func(fields Fields) {
+ assert.Equal(t, fields["msg"], "test 10")
+ })
+}
+
+func TestInfolnShouldAddSpacesBetweenTwoNonStrings(t *testing.T) {
+ LogAndAssertJSON(t, func(log *Logger) {
+ log.Infoln(10, 10)
+ }, func(fields Fields) {
+ assert.Equal(t, fields["msg"], "10 10")
+ })
+}
+
+func TestInfoShouldAddSpacesBetweenTwoNonStrings(t *testing.T) {
+ LogAndAssertJSON(t, func(log *Logger) {
+ log.Infoln(10, 10)
+ }, func(fields Fields) {
+ assert.Equal(t, fields["msg"], "10 10")
+ })
+}
+
+func TestInfoShouldNotAddSpacesBetweenStringAndNonstring(t *testing.T) {
+ LogAndAssertJSON(t, func(log *Logger) {
+ log.Info("test", 10)
+ }, func(fields Fields) {
+ assert.Equal(t, fields["msg"], "test10")
+ })
+}
+
+func TestInfoShouldNotAddSpacesBetweenStrings(t *testing.T) {
+ LogAndAssertJSON(t, func(log *Logger) {
+ log.Info("test", "test")
+ }, func(fields Fields) {
+ assert.Equal(t, fields["msg"], "testtest")
+ })
+}
+
+func TestWithFieldsShouldAllowAssignments(t *testing.T) {
+ var buffer bytes.Buffer
+ var fields Fields
+
+ logger := New()
+ logger.Out = &buffer
+ logger.Formatter = new(JSONFormatter)
+
+ localLog := logger.WithFields(Fields{
+ "key1": "value1",
+ })
+
+ localLog.WithField("key2", "value2").Info("test")
+ err := json.Unmarshal(buffer.Bytes(), &fields)
+ assert.Nil(t, err)
+
+ assert.Equal(t, "value2", fields["key2"])
+ assert.Equal(t, "value1", fields["key1"])
+
+ buffer = bytes.Buffer{}
+ fields = Fields{}
+ localLog.Info("test")
+ err = json.Unmarshal(buffer.Bytes(), &fields)
+ assert.Nil(t, err)
+
+ _, ok := fields["key2"]
+ assert.Equal(t, false, ok)
+ assert.Equal(t, "value1", fields["key1"])
+}
+
+func TestUserSuppliedFieldDoesNotOverwriteDefaults(t *testing.T) {
+ LogAndAssertJSON(t, func(log *Logger) {
+ log.WithField("msg", "hello").Info("test")
+ }, func(fields Fields) {
+ assert.Equal(t, fields["msg"], "test")
+ })
+}
+
+func TestUserSuppliedMsgFieldHasPrefix(t *testing.T) {
+ LogAndAssertJSON(t, func(log *Logger) {
+ log.WithField("msg", "hello").Info("test")
+ }, func(fields Fields) {
+ assert.Equal(t, fields["msg"], "test")
+ assert.Equal(t, fields["fields.msg"], "hello")
+ })
+}
+
+func TestUserSuppliedTimeFieldHasPrefix(t *testing.T) {
+ LogAndAssertJSON(t, func(log *Logger) {
+ log.WithField("time", "hello").Info("test")
+ }, func(fields Fields) {
+ assert.Equal(t, fields["fields.time"], "hello")
+ })
+}
+
+func TestUserSuppliedLevelFieldHasPrefix(t *testing.T) {
+ LogAndAssertJSON(t, func(log *Logger) {
+ log.WithField("level", 1).Info("test")
+ }, func(fields Fields) {
+ assert.Equal(t, fields["level"], "info")
+ assert.Equal(t, fields["fields.level"], 1.0) // JSON has floats only
+ })
+}
+
+func TestDefaultFieldsAreNotPrefixed(t *testing.T) {
+ LogAndAssertText(t, func(log *Logger) {
+ ll := log.WithField("herp", "derp")
+ ll.Info("hello")
+ ll.Info("bye")
+ }, func(fields map[string]string) {
+ for _, fieldName := range []string{"fields.level", "fields.time", "fields.msg"} {
+ if _, ok := fields[fieldName]; ok {
+ t.Fatalf("should not have prefixed %q: %v", fieldName, fields)
+ }
+ }
+ })
+}
+
+func TestDoubleLoggingDoesntPrefixPreviousFields(t *testing.T) {
+
+ var buffer bytes.Buffer
+ var fields Fields
+
+ logger := New()
+ logger.Out = &buffer
+ logger.Formatter = new(JSONFormatter)
+
+ llog := logger.WithField("context", "eating raw fish")
+
+ llog.Info("looks delicious")
+
+ err := json.Unmarshal(buffer.Bytes(), &fields)
+ assert.NoError(t, err, "should have decoded first message")
+ assert.Equal(t, len(fields), 4, "should only have msg/time/level/context fields")
+ assert.Equal(t, fields["msg"], "looks delicious")
+ assert.Equal(t, fields["context"], "eating raw fish")
+
+ buffer.Reset()
+
+ llog.Warn("omg it is!")
+
+ err = json.Unmarshal(buffer.Bytes(), &fields)
+ assert.NoError(t, err, "should have decoded second message")
+ assert.Equal(t, len(fields), 4, "should only have msg/time/level/context fields")
+ assert.Equal(t, fields["msg"], "omg it is!")
+ assert.Equal(t, fields["context"], "eating raw fish")
+ assert.Nil(t, fields["fields.msg"], "should not have prefixed previous `msg` entry")
+
+}
+
+func TestConvertLevelToString(t *testing.T) {
+ assert.Equal(t, "debug", DebugLevel.String())
+ assert.Equal(t, "info", InfoLevel.String())
+ assert.Equal(t, "warning", WarnLevel.String())
+ assert.Equal(t, "error", ErrorLevel.String())
+ assert.Equal(t, "fatal", FatalLevel.String())
+ assert.Equal(t, "panic", PanicLevel.String())
+}
+
+func TestParseLevel(t *testing.T) {
+ l, err := ParseLevel("panic")
+ assert.Nil(t, err)
+ assert.Equal(t, PanicLevel, l)
+
+ l, err = ParseLevel("PANIC")
+ assert.Nil(t, err)
+ assert.Equal(t, PanicLevel, l)
+
+ l, err = ParseLevel("fatal")
+ assert.Nil(t, err)
+ assert.Equal(t, FatalLevel, l)
+
+ l, err = ParseLevel("FATAL")
+ assert.Nil(t, err)
+ assert.Equal(t, FatalLevel, l)
+
+ l, err = ParseLevel("error")
+ assert.Nil(t, err)
+ assert.Equal(t, ErrorLevel, l)
+
+ l, err = ParseLevel("ERROR")
+ assert.Nil(t, err)
+ assert.Equal(t, ErrorLevel, l)
+
+ l, err = ParseLevel("warn")
+ assert.Nil(t, err)
+ assert.Equal(t, WarnLevel, l)
+
+ l, err = ParseLevel("WARN")
+ assert.Nil(t, err)
+ assert.Equal(t, WarnLevel, l)
+
+ l, err = ParseLevel("warning")
+ assert.Nil(t, err)
+ assert.Equal(t, WarnLevel, l)
+
+ l, err = ParseLevel("WARNING")
+ assert.Nil(t, err)
+ assert.Equal(t, WarnLevel, l)
+
+ l, err = ParseLevel("info")
+ assert.Nil(t, err)
+ assert.Equal(t, InfoLevel, l)
+
+ l, err = ParseLevel("INFO")
+ assert.Nil(t, err)
+ assert.Equal(t, InfoLevel, l)
+
+ l, err = ParseLevel("debug")
+ assert.Nil(t, err)
+ assert.Equal(t, DebugLevel, l)
+
+ l, err = ParseLevel("DEBUG")
+ assert.Nil(t, err)
+ assert.Equal(t, DebugLevel, l)
+
+ l, err = ParseLevel("invalid")
+ assert.Equal(t, "not a valid logrus Level: \"invalid\"", err.Error())
+}
+
+func TestGetSetLevelRace(t *testing.T) {
+ wg := sync.WaitGroup{}
+ for i := 0; i < 100; i++ {
+ wg.Add(1)
+ go func(i int) {
+ defer wg.Done()
+ if i%2 == 0 {
+ SetLevel(InfoLevel)
+ } else {
+ GetLevel()
+ }
+ }(i)
+
+ }
+ wg.Wait()
+}
+
+func TestLoggingRace(t *testing.T) {
+ logger := New()
+
+ var wg sync.WaitGroup
+ wg.Add(100)
+
+ for i := 0; i < 100; i++ {
+ go func() {
+ logger.Info("info")
+ wg.Done()
+ }()
+ }
+ wg.Wait()
+}
+
+// Compile test
+func TestLogrusInterface(t *testing.T) {
+ var buffer bytes.Buffer
+ fn := func(l FieldLogger) {
+ b := l.WithField("key", "value")
+ b.Debug("Test")
+ }
+ // test logger
+ logger := New()
+ logger.Out = &buffer
+ fn(logger)
+
+ // test Entry
+ e := logger.WithField("another", "value")
+ fn(e)
+}
+
+// Implements io.Writer using channels for synchronization, so we can wait on
+// the Entry.Writer goroutine to write in a non-racey way. This does assume that
+// there is a single call to Logger.Out for each message.
+type channelWriter chan []byte
+
+func (cw channelWriter) Write(p []byte) (int, error) {
+ cw <- p
+ return len(p), nil
+}
+
+func TestEntryWriter(t *testing.T) {
+ cw := channelWriter(make(chan []byte, 1))
+ log := New()
+ log.Out = cw
+ log.Formatter = new(JSONFormatter)
+ log.WithField("foo", "bar").WriterLevel(WarnLevel).Write([]byte("hello\n"))
+
+ bs := <-cw
+ var fields Fields
+ err := json.Unmarshal(bs, &fields)
+ assert.Nil(t, err)
+ assert.Equal(t, fields["foo"], "bar")
+ assert.Equal(t, fields["level"], "warning")
+}
diff --git a/vendor/github.com/sirupsen/logrus/terminal_appengine.go b/vendor/github.com/sirupsen/logrus/terminal_appengine.go
new file mode 100644
index 00000000..e011a869
--- /dev/null
+++ b/vendor/github.com/sirupsen/logrus/terminal_appengine.go
@@ -0,0 +1,10 @@
+// +build appengine
+
+package logrus
+
+import "io"
+
+// IsTerminal returns true if stderr's file descriptor is a terminal.
+func IsTerminal(f io.Writer) bool {
+ return true
+}
diff --git a/vendor/github.com/sirupsen/logrus/terminal_bsd.go b/vendor/github.com/sirupsen/logrus/terminal_bsd.go
new file mode 100644
index 00000000..5f6be4d3
--- /dev/null
+++ b/vendor/github.com/sirupsen/logrus/terminal_bsd.go
@@ -0,0 +1,10 @@
+// +build darwin freebsd openbsd netbsd dragonfly
+// +build !appengine
+
+package logrus
+
+import "syscall"
+
+const ioctlReadTermios = syscall.TIOCGETA
+
+type Termios syscall.Termios
diff --git a/vendor/github.com/sirupsen/logrus/terminal_linux.go b/vendor/github.com/sirupsen/logrus/terminal_linux.go
new file mode 100644
index 00000000..308160ca
--- /dev/null
+++ b/vendor/github.com/sirupsen/logrus/terminal_linux.go
@@ -0,0 +1,14 @@
+// Based on ssh/terminal:
+// Copyright 2013 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 !appengine
+
+package logrus
+
+import "syscall"
+
+const ioctlReadTermios = syscall.TCGETS
+
+type Termios syscall.Termios
diff --git a/vendor/github.com/sirupsen/logrus/terminal_notwindows.go b/vendor/github.com/sirupsen/logrus/terminal_notwindows.go
new file mode 100644
index 00000000..190297ab
--- /dev/null
+++ b/vendor/github.com/sirupsen/logrus/terminal_notwindows.go
@@ -0,0 +1,28 @@
+// Based on ssh/terminal:
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build linux darwin freebsd openbsd netbsd dragonfly
+// +build !appengine
+
+package logrus
+
+import (
+ "io"
+ "os"
+ "syscall"
+ "unsafe"
+)
+
+// IsTerminal returns true if stderr's file descriptor is a terminal.
+func IsTerminal(f io.Writer) bool {
+ var termios Termios
+ switch v := f.(type) {
+ case *os.File:
+ _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(v.Fd()), ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0)
+ return err == 0
+ default:
+ return false
+ }
+}
diff --git a/vendor/github.com/sirupsen/logrus/terminal_solaris.go b/vendor/github.com/sirupsen/logrus/terminal_solaris.go
new file mode 100644
index 00000000..3c86b1ab
--- /dev/null
+++ b/vendor/github.com/sirupsen/logrus/terminal_solaris.go
@@ -0,0 +1,21 @@
+// +build solaris,!appengine
+
+package logrus
+
+import (
+ "io"
+ "os"
+
+ "golang.org/x/sys/unix"
+)
+
+// IsTerminal returns true if the given file descriptor is a terminal.
+func IsTerminal(f io.Writer) bool {
+ switch v := f.(type) {
+ case *os.File:
+ _, err := unix.IoctlGetTermios(int(v.Fd()), unix.TCGETA)
+ return err == nil
+ default:
+ return false
+ }
+}
diff --git a/vendor/github.com/sirupsen/logrus/terminal_windows.go b/vendor/github.com/sirupsen/logrus/terminal_windows.go
new file mode 100644
index 00000000..05d2f91f
--- /dev/null
+++ b/vendor/github.com/sirupsen/logrus/terminal_windows.go
@@ -0,0 +1,33 @@
+// Based on ssh/terminal:
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build windows,!appengine
+
+package logrus
+
+import (
+ "io"
+ "os"
+ "syscall"
+ "unsafe"
+)
+
+var kernel32 = syscall.NewLazyDLL("kernel32.dll")
+
+var (
+ procGetConsoleMode = kernel32.NewProc("GetConsoleMode")
+)
+
+// IsTerminal returns true if stderr's file descriptor is a terminal.
+func IsTerminal(f io.Writer) bool {
+ switch v := f.(type) {
+ case *os.File:
+ var st uint32
+ r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(v.Fd()), uintptr(unsafe.Pointer(&st)), 0)
+ return r != 0 && e == 0
+ default:
+ return false
+ }
+}
diff --git a/vendor/github.com/sirupsen/logrus/text_formatter.go b/vendor/github.com/sirupsen/logrus/text_formatter.go
new file mode 100644
index 00000000..ba888540
--- /dev/null
+++ b/vendor/github.com/sirupsen/logrus/text_formatter.go
@@ -0,0 +1,189 @@
+package logrus
+
+import (
+ "bytes"
+ "fmt"
+ "sort"
+ "strings"
+ "sync"
+ "time"
+)
+
+const (
+ nocolor = 0
+ red = 31
+ green = 32
+ yellow = 33
+ blue = 34
+ gray = 37
+)
+
+var (
+ baseTimestamp time.Time
+)
+
+func init() {
+ baseTimestamp = time.Now()
+}
+
+type TextFormatter struct {
+ // Set to true to bypass checking for a TTY before outputting colors.
+ ForceColors bool
+
+ // Force disabling colors.
+ DisableColors bool
+
+ // Disable timestamp logging. useful when output is redirected to logging
+ // system that already adds timestamps.
+ DisableTimestamp bool
+
+ // Enable logging the full timestamp when a TTY is attached instead of just
+ // the time passed since beginning of execution.
+ FullTimestamp bool
+
+ // TimestampFormat to use for display when a full timestamp is printed
+ TimestampFormat string
+
+ // The fields are sorted by default for a consistent output. For applications
+ // that log extremely frequently and don't use the JSON formatter this may not
+ // be desired.
+ DisableSorting bool
+
+ // QuoteEmptyFields will wrap empty fields in quotes if true
+ QuoteEmptyFields bool
+
+ // QuoteCharacter can be set to the override the default quoting character "
+ // with something else. For example: ', or `.
+ QuoteCharacter string
+
+ // Whether the logger's out is to a terminal
+ isTerminal bool
+
+ sync.Once
+}
+
+func (f *TextFormatter) init(entry *Entry) {
+ if len(f.QuoteCharacter) == 0 {
+ f.QuoteCharacter = "\""
+ }
+ if entry.Logger != nil {
+ f.isTerminal = IsTerminal(entry.Logger.Out)
+ }
+}
+
+func (f *TextFormatter) Format(entry *Entry) ([]byte, error) {
+ var b *bytes.Buffer
+ keys := make([]string, 0, len(entry.Data))
+ for k := range entry.Data {
+ keys = append(keys, k)
+ }
+
+ if !f.DisableSorting {
+ sort.Strings(keys)
+ }
+ if entry.Buffer != nil {
+ b = entry.Buffer
+ } else {
+ b = &bytes.Buffer{}
+ }
+
+ prefixFieldClashes(entry.Data)
+
+ f.Do(func() { f.init(entry) })
+
+ isColored := (f.ForceColors || f.isTerminal) && !f.DisableColors
+
+ timestampFormat := f.TimestampFormat
+ if timestampFormat == "" {
+ timestampFormat = DefaultTimestampFormat
+ }
+ if isColored {
+ f.printColored(b, entry, keys, timestampFormat)
+ } else {
+ if !f.DisableTimestamp {
+ f.appendKeyValue(b, "time", entry.Time.Format(timestampFormat))
+ }
+ f.appendKeyValue(b, "level", entry.Level.String())
+ if entry.Message != "" {
+ f.appendKeyValue(b, "msg", entry.Message)
+ }
+ for _, key := range keys {
+ f.appendKeyValue(b, key, entry.Data[key])
+ }
+ }
+
+ b.WriteByte('\n')
+ return b.Bytes(), nil
+}
+
+func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys []string, timestampFormat string) {
+ var levelColor int
+ switch entry.Level {
+ case DebugLevel:
+ levelColor = gray
+ case WarnLevel:
+ levelColor = yellow
+ case ErrorLevel, FatalLevel, PanicLevel:
+ levelColor = red
+ default:
+ levelColor = blue
+ }
+
+ levelText := strings.ToUpper(entry.Level.String())[0:4]
+
+ if f.DisableTimestamp {
+ 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 {
+ fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%s] %-44s ", levelColor, levelText, entry.Time.Format(timestampFormat), entry.Message)
+ }
+ for _, k := range keys {
+ v := entry.Data[k]
+ fmt.Fprintf(b, " \x1b[%dm%s\x1b[0m=", levelColor, k)
+ f.appendValue(b, v)
+ }
+}
+
+func (f *TextFormatter) needsQuoting(text string) bool {
+ if f.QuoteEmptyFields && len(text) == 0 {
+ return true
+ }
+ for _, ch := range text {
+ if !((ch >= 'a' && ch <= 'z') ||
+ (ch >= 'A' && ch <= 'Z') ||
+ (ch >= '0' && ch <= '9') ||
+ ch == '-' || ch == '.') {
+ return true
+ }
+ }
+ return false
+}
+
+func (f *TextFormatter) appendKeyValue(b *bytes.Buffer, key string, value interface{}) {
+
+ b.WriteString(key)
+ b.WriteByte('=')
+ f.appendValue(b, value)
+ b.WriteByte(' ')
+}
+
+func (f *TextFormatter) appendValue(b *bytes.Buffer, value interface{}) {
+ switch value := value.(type) {
+ case string:
+ if !f.needsQuoting(value) {
+ b.WriteString(value)
+ } else {
+ fmt.Fprintf(b, "%s%v%s", f.QuoteCharacter, value, f.QuoteCharacter)
+ }
+ case error:
+ errmsg := value.Error()
+ if !f.needsQuoting(errmsg) {
+ b.WriteString(errmsg)
+ } else {
+ fmt.Fprintf(b, "%s%v%s", f.QuoteCharacter, errmsg, f.QuoteCharacter)
+ }
+ default:
+ fmt.Fprint(b, value)
+ }
+}
diff --git a/vendor/github.com/sirupsen/logrus/text_formatter_test.go b/vendor/github.com/sirupsen/logrus/text_formatter_test.go
new file mode 100644
index 00000000..9793b5f3
--- /dev/null
+++ b/vendor/github.com/sirupsen/logrus/text_formatter_test.go
@@ -0,0 +1,87 @@
+package logrus
+
+import (
+ "bytes"
+ "errors"
+ "strings"
+ "testing"
+ "time"
+)
+
+func TestQuoting(t *testing.T) {
+ tf := &TextFormatter{DisableColors: true}
+
+ checkQuoting := func(q bool, value interface{}) {
+ b, _ := tf.Format(WithField("test", value))
+ idx := bytes.Index(b, ([]byte)("test="))
+ cont := bytes.Contains(b[idx+5:], []byte(tf.QuoteCharacter))
+ if cont != q {
+ if q {
+ t.Errorf("quoting expected for: %#v", value)
+ } else {
+ t.Errorf("quoting not expected for: %#v", value)
+ }
+ }
+ }
+
+ checkQuoting(false, "")
+ checkQuoting(false, "abcd")
+ checkQuoting(false, "v1.0")
+ checkQuoting(false, "1234567890")
+ checkQuoting(true, "/foobar")
+ checkQuoting(true, "x y")
+ checkQuoting(true, "x,y")
+ checkQuoting(false, errors.New("invalid"))
+ checkQuoting(true, errors.New("invalid argument"))
+
+ // Test for custom quote character.
+ tf.QuoteCharacter = "`"
+ checkQuoting(false, "")
+ checkQuoting(false, "abcd")
+ checkQuoting(true, "/foobar")
+ checkQuoting(true, errors.New("invalid argument"))
+
+ // Test for multi-character quotes.
+ tf.QuoteCharacter = "§~±"
+ checkQuoting(false, "abcd")
+ checkQuoting(true, errors.New("invalid argument"))
+
+ // Test for quoting empty fields.
+ tf.QuoteEmptyFields = true
+ checkQuoting(true, "")
+ checkQuoting(false, "abcd")
+ checkQuoting(true, errors.New("invalid argument"))
+}
+
+func TestTimestampFormat(t *testing.T) {
+ checkTimeStr := func(format string) {
+ customFormatter := &TextFormatter{DisableColors: true, TimestampFormat: format}
+ customStr, _ := customFormatter.Format(WithField("test", "test"))
+ timeStart := bytes.Index(customStr, ([]byte)("time="))
+ timeEnd := bytes.Index(customStr, ([]byte)("level="))
+ timeStr := customStr[timeStart+5+len(customFormatter.QuoteCharacter) : timeEnd-1-len(customFormatter.QuoteCharacter)]
+ if format == "" {
+ format = time.RFC3339
+ }
+ _, e := time.Parse(format, (string)(timeStr))
+ if e != nil {
+ t.Errorf("time string \"%s\" did not match provided time format \"%s\": %s", timeStr, format, e)
+ }
+ }
+
+ checkTimeStr("2006-01-02T15:04:05.000000000Z07:00")
+ checkTimeStr("Mon Jan _2 15:04:05 2006")
+ checkTimeStr("")
+}
+
+func TestDisableTimestampWithColoredOutput(t *testing.T) {
+ tf := &TextFormatter{DisableTimestamp: true, ForceColors: true}
+
+ b, _ := tf.Format(WithField("test", "test"))
+ if strings.Contains(string(b), "[0000]") {
+ t.Error("timestamp not expected when DisableTimestamp is true")
+ }
+}
+
+// TODO add tests for sorting etc., this requires a parser for the text
+// formatter output.
diff --git a/vendor/github.com/sirupsen/logrus/writer.go b/vendor/github.com/sirupsen/logrus/writer.go
new file mode 100644
index 00000000..7bdebedc
--- /dev/null
+++ b/vendor/github.com/sirupsen/logrus/writer.go
@@ -0,0 +1,62 @@
+package logrus
+
+import (
+ "bufio"
+ "io"
+ "runtime"
+)
+
+func (logger *Logger) Writer() *io.PipeWriter {
+ return logger.WriterLevel(InfoLevel)
+}
+
+func (logger *Logger) WriterLevel(level Level) *io.PipeWriter {
+ return NewEntry(logger).WriterLevel(level)
+}
+
+func (entry *Entry) Writer() *io.PipeWriter {
+ return entry.WriterLevel(InfoLevel)
+}
+
+func (entry *Entry) WriterLevel(level Level) *io.PipeWriter {
+ reader, writer := io.Pipe()
+
+ var printFunc func(args ...interface{})
+
+ switch level {
+ case DebugLevel:
+ printFunc = entry.Debug
+ case InfoLevel:
+ printFunc = entry.Info
+ case WarnLevel:
+ printFunc = entry.Warn
+ case ErrorLevel:
+ printFunc = entry.Error
+ case FatalLevel:
+ printFunc = entry.Fatal
+ case PanicLevel:
+ printFunc = entry.Panic
+ default:
+ printFunc = entry.Print
+ }
+
+ go entry.writerScanner(reader, printFunc)
+ runtime.SetFinalizer(writer, writerFinalizer)
+
+ return writer
+}
+
+func (entry *Entry) writerScanner(reader *io.PipeReader, printFunc func(args ...interface{})) {
+ scanner := bufio.NewScanner(reader)
+ for scanner.Scan() {
+ printFunc(scanner.Text())
+ }
+ if err := scanner.Err(); err != nil {
+ entry.Errorf("Error while reading from Writer: %s", err)
+ }
+ reader.Close()
+}
+
+func writerFinalizer(writer *io.PipeWriter) {
+ writer.Close()
+}
diff --git a/vendor/github.com/syndtr/goleveldb/leveldb/cache/cache.go b/vendor/github.com/syndtr/goleveldb/leveldb/cache/cache.go
deleted file mode 100644
index c9670de5..00000000
--- a/vendor/github.com/syndtr/goleveldb/leveldb/cache/cache.go
+++ /dev/null
@@ -1,676 +0,0 @@
-// Copyright (c) 2012, Suryandaru Triandana
-// All rights reserved.
-//
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Package cache provides interface and implementation of a cache algorithms.
-package cache
-
-import (
- "sync"
- "sync/atomic"
- "unsafe"
-
- "github.com/syndtr/goleveldb/leveldb/util"
-)
-
-// Cacher provides interface to implements a caching functionality.
-// An implementation must be goroutine-safe.
-type Cacher interface {
- // Capacity returns cache capacity.
- Capacity() int
-
- // SetCapacity sets cache capacity.
- SetCapacity(capacity int)
-
- // Promote promotes the 'cache node'.
- Promote(n *Node)
-
- // Ban evicts the 'cache node' and prevent subsequent 'promote'.
- Ban(n *Node)
-
- // Evict evicts the 'cache node'.
- Evict(n *Node)
-
- // EvictNS evicts 'cache node' with the given namespace.
- EvictNS(ns uint64)
-
- // EvictAll evicts all 'cache node'.
- EvictAll()
-
- // Close closes the 'cache tree'
- Close() error
-}
-
-// Value is a 'cacheable object'. It may implements util.Releaser, if
-// so the the Release method will be called once object is released.
-type Value interface{}
-
-type CacheGetter struct {
- Cache *Cache
- NS uint64
-}
-
-func (g *CacheGetter) Get(key uint64, setFunc func() (size int, value Value)) *Handle {
- return g.Cache.Get(g.NS, key, setFunc)
-}
-
-// The hash tables implementation is based on:
-// "Dynamic-Sized Nonblocking Hash Tables", by Yujie Liu, Kunlong Zhang, and Michael Spear. ACM Symposium on Principles of Distributed Computing, Jul 2014.
-
-const (
- mInitialSize = 1 << 4
- mOverflowThreshold = 1 << 5
- mOverflowGrowThreshold = 1 << 7
-)
-
-type mBucket struct {
- mu sync.Mutex
- node []*Node
- frozen bool
-}
-
-func (b *mBucket) freeze() []*Node {
- b.mu.Lock()
- defer b.mu.Unlock()
- if !b.frozen {
- b.frozen = true
- }
- return b.node
-}
-
-func (b *mBucket) get(r *Cache, h *mNode, hash uint32, ns, key uint64, noset bool) (done, added bool, n *Node) {
- b.mu.Lock()
-
- if b.frozen {
- b.mu.Unlock()
- return
- }
-
- // Scan the node.
- for _, n := range b.node {
- if n.hash == hash && n.ns == ns && n.key == key {
- atomic.AddInt32(&n.ref, 1)
- b.mu.Unlock()
- return true, false, n
- }
- }
-
- // Get only.
- if noset {
- b.mu.Unlock()
- return true, false, nil
- }
-
- // Create node.
- n = &Node{
- r: r,
- hash: hash,
- ns: ns,
- key: key,
- ref: 1,
- }
- // Add node to bucket.
- b.node = append(b.node, n)
- bLen := len(b.node)
- b.mu.Unlock()
-
- // Update counter.
- grow := atomic.AddInt32(&r.nodes, 1) >= h.growThreshold
- if bLen > mOverflowThreshold {
- grow = grow || atomic.AddInt32(&h.overflow, 1) >= mOverflowGrowThreshold
- }
-
- // Grow.
- if grow && atomic.CompareAndSwapInt32(&h.resizeInProgess, 0, 1) {
- nhLen := len(h.buckets) << 1
- nh := &mNode{
- buckets: make([]unsafe.Pointer, nhLen),
- mask: uint32(nhLen) - 1,
- pred: unsafe.Pointer(h),
- growThreshold: int32(nhLen * mOverflowThreshold),
- shrinkThreshold: int32(nhLen >> 1),
- }
- ok := atomic.CompareAndSwapPointer(&r.mHead, unsafe.Pointer(h), unsafe.Pointer(nh))
- if !ok {
- panic("BUG: failed swapping head")
- }
- go nh.initBuckets()
- }
-
- return true, true, n
-}
-
-func (b *mBucket) delete(r *Cache, h *mNode, hash uint32, ns, key uint64) (done, deleted bool) {
- b.mu.Lock()
-
- if b.frozen {
- b.mu.Unlock()
- return
- }
-
- // Scan the node.
- var (
- n *Node
- bLen int
- )
- for i := range b.node {
- n = b.node[i]
- if n.ns == ns && n.key == key {
- if atomic.LoadInt32(&n.ref) == 0 {
- deleted = true
-
- // Call releaser.
- if n.value != nil {
- if r, ok := n.value.(util.Releaser); ok {
- r.Release()
- }
- n.value = nil
- }
-
- // Remove node from bucket.
- b.node = append(b.node[:i], b.node[i+1:]...)
- bLen = len(b.node)
- }
- break
- }
- }
- b.mu.Unlock()
-
- if deleted {
- // Call OnDel.
- for _, f := range n.onDel {
- f()
- }
-
- // Update counter.
- atomic.AddInt32(&r.size, int32(n.size)*-1)
- shrink := atomic.AddInt32(&r.nodes, -1) < h.shrinkThreshold
- if bLen >= mOverflowThreshold {
- atomic.AddInt32(&h.overflow, -1)
- }
-
- // Shrink.
- if shrink && len(h.buckets) > mInitialSize && atomic.CompareAndSwapInt32(&h.resizeInProgess, 0, 1) {
- nhLen := len(h.buckets) >> 1
- nh := &mNode{
- buckets: make([]unsafe.Pointer, nhLen),
- mask: uint32(nhLen) - 1,
- pred: unsafe.Pointer(h),
- growThreshold: int32(nhLen * mOverflowThreshold),
- shrinkThreshold: int32(nhLen >> 1),
- }
- ok := atomic.CompareAndSwapPointer(&r.mHead, unsafe.Pointer(h), unsafe.Pointer(nh))
- if !ok {
- panic("BUG: failed swapping head")
- }
- go nh.initBuckets()
- }
- }
-
- return true, deleted
-}
-
-type mNode struct {
- buckets []unsafe.Pointer // []*mBucket
- mask uint32
- pred unsafe.Pointer // *mNode
- resizeInProgess int32
-
- overflow int32
- growThreshold int32
- shrinkThreshold int32
-}
-
-func (n *mNode) initBucket(i uint32) *mBucket {
- if b := (*mBucket)(atomic.LoadPointer(&n.buckets[i])); b != nil {
- return b
- }
-
- p := (*mNode)(atomic.LoadPointer(&n.pred))
- if p != nil {
- var node []*Node
- if n.mask > p.mask {
- // Grow.
- pb := (*mBucket)(atomic.LoadPointer(&p.buckets[i&p.mask]))
- if pb == nil {
- pb = p.initBucket(i & p.mask)
- }
- m := pb.freeze()
- // Split nodes.
- for _, x := range m {
- if x.hash&n.mask == i {
- node = append(node, x)
- }
- }
- } else {
- // Shrink.
- pb0 := (*mBucket)(atomic.LoadPointer(&p.buckets[i]))
- if pb0 == nil {
- pb0 = p.initBucket(i)
- }
- pb1 := (*mBucket)(atomic.LoadPointer(&p.buckets[i+uint32(len(n.buckets))]))
- if pb1 == nil {
- pb1 = p.initBucket(i + uint32(len(n.buckets)))
- }
- m0 := pb0.freeze()
- m1 := pb1.freeze()
- // Merge nodes.
- node = make([]*Node, 0, len(m0)+len(m1))
- node = append(node, m0...)
- node = append(node, m1...)
- }
- b := &mBucket{node: node}
- if atomic.CompareAndSwapPointer(&n.buckets[i], nil, unsafe.Pointer(b)) {
- if len(node) > mOverflowThreshold {
- atomic.AddInt32(&n.overflow, int32(len(node)-mOverflowThreshold))
- }
- return b
- }
- }
-
- return (*mBucket)(atomic.LoadPointer(&n.buckets[i]))
-}
-
-func (n *mNode) initBuckets() {
- for i := range n.buckets {
- n.initBucket(uint32(i))
- }
- atomic.StorePointer(&n.pred, nil)
-}
-
-// Cache is a 'cache map'.
-type Cache struct {
- mu sync.RWMutex
- mHead unsafe.Pointer // *mNode
- nodes int32
- size int32
- cacher Cacher
- closed bool
-}
-
-// NewCache creates a new 'cache map'. The cacher is optional and
-// may be nil.
-func NewCache(cacher Cacher) *Cache {
- h := &mNode{
- buckets: make([]unsafe.Pointer, mInitialSize),
- mask: mInitialSize - 1,
- growThreshold: int32(mInitialSize * mOverflowThreshold),
- shrinkThreshold: 0,
- }
- for i := range h.buckets {
- h.buckets[i] = unsafe.Pointer(&mBucket{})
- }
- r := &Cache{
- mHead: unsafe.Pointer(h),
- cacher: cacher,
- }
- return r
-}
-
-func (r *Cache) getBucket(hash uint32) (*mNode, *mBucket) {
- h := (*mNode)(atomic.LoadPointer(&r.mHead))
- i := hash & h.mask
- b := (*mBucket)(atomic.LoadPointer(&h.buckets[i]))
- if b == nil {
- b = h.initBucket(i)
- }
- return h, b
-}
-
-func (r *Cache) delete(n *Node) bool {
- for {
- h, b := r.getBucket(n.hash)
- done, deleted := b.delete(r, h, n.hash, n.ns, n.key)
- if done {
- return deleted
- }
- }
- return false
-}
-
-// Nodes returns number of 'cache node' in the map.
-func (r *Cache) Nodes() int {
- return int(atomic.LoadInt32(&r.nodes))
-}
-
-// Size returns sums of 'cache node' size in the map.
-func (r *Cache) Size() int {
- return int(atomic.LoadInt32(&r.size))
-}
-
-// Capacity returns cache capacity.
-func (r *Cache) Capacity() int {
- if r.cacher == nil {
- return 0
- }
- return r.cacher.Capacity()
-}
-
-// SetCapacity sets cache capacity.
-func (r *Cache) SetCapacity(capacity int) {
- if r.cacher != nil {
- r.cacher.SetCapacity(capacity)
- }
-}
-
-// Get gets 'cache node' with the given namespace and key.
-// If cache node is not found and setFunc is not nil, Get will atomically creates
-// the 'cache node' by calling setFunc. Otherwise Get will returns nil.
-//
-// The returned 'cache handle' should be released after use by calling Release
-// method.
-func (r *Cache) Get(ns, key uint64, setFunc func() (size int, value Value)) *Handle {
- r.mu.RLock()
- defer r.mu.RUnlock()
- if r.closed {
- return nil
- }
-
- hash := murmur32(ns, key, 0xf00)
- for {
- h, b := r.getBucket(hash)
- done, _, n := b.get(r, h, hash, ns, key, setFunc == nil)
- if done {
- if n != nil {
- n.mu.Lock()
- if n.value == nil {
- if setFunc == nil {
- n.mu.Unlock()
- n.unref()
- return nil
- }
-
- n.size, n.value = setFunc()
- if n.value == nil {
- n.size = 0
- n.mu.Unlock()
- n.unref()
- return nil
- }
- atomic.AddInt32(&r.size, int32(n.size))
- }
- n.mu.Unlock()
- if r.cacher != nil {
- r.cacher.Promote(n)
- }
- return &Handle{unsafe.Pointer(n)}
- }
-
- break
- }
- }
- return nil
-}
-
-// Delete removes and ban 'cache node' with the given namespace and key.
-// A banned 'cache node' will never inserted into the 'cache tree'. Ban
-// only attributed to the particular 'cache node', so when a 'cache node'
-// is recreated it will not be banned.
-//
-// If onDel is not nil, then it will be executed if such 'cache node'
-// doesn't exist or once the 'cache node' is released.
-//
-// Delete return true is such 'cache node' exist.
-func (r *Cache) Delete(ns, key uint64, onDel func()) bool {
- r.mu.RLock()
- defer r.mu.RUnlock()
- if r.closed {
- return false
- }
-
- hash := murmur32(ns, key, 0xf00)
- for {
- h, b := r.getBucket(hash)
- done, _, n := b.get(r, h, hash, ns, key, true)
- if done {
- if n != nil {
- if onDel != nil {
- n.mu.Lock()
- n.onDel = append(n.onDel, onDel)
- n.mu.Unlock()
- }
- if r.cacher != nil {
- r.cacher.Ban(n)
- }
- n.unref()
- return true
- }
-
- break
- }
- }
-
- if onDel != nil {
- onDel()
- }
-
- return false
-}
-
-// Evict evicts 'cache node' with the given namespace and key. This will
-// simply call Cacher.Evict.
-//
-// Evict return true is such 'cache node' exist.
-func (r *Cache) Evict(ns, key uint64) bool {
- r.mu.RLock()
- defer r.mu.RUnlock()
- if r.closed {
- return false
- }
-
- hash := murmur32(ns, key, 0xf00)
- for {
- h, b := r.getBucket(hash)
- done, _, n := b.get(r, h, hash, ns, key, true)
- if done {
- if n != nil {
- if r.cacher != nil {
- r.cacher.Evict(n)
- }
- n.unref()
- return true
- }
-
- break
- }
- }
-
- return false
-}
-
-// EvictNS evicts 'cache node' with the given namespace. This will
-// simply call Cacher.EvictNS.
-func (r *Cache) EvictNS(ns uint64) {
- r.mu.RLock()
- defer r.mu.RUnlock()
- if r.closed {
- return
- }
-
- if r.cacher != nil {
- r.cacher.EvictNS(ns)
- }
-}
-
-// EvictAll evicts all 'cache node'. This will simply call Cacher.EvictAll.
-func (r *Cache) EvictAll() {
- r.mu.RLock()
- defer r.mu.RUnlock()
- if r.closed {
- return
- }
-
- if r.cacher != nil {
- r.cacher.EvictAll()
- }
-}
-
-// Close closes the 'cache map' and releases all 'cache node'.
-func (r *Cache) Close() error {
- r.mu.Lock()
- if !r.closed {
- r.closed = true
-
- if r.cacher != nil {
- if err := r.cacher.Close(); err != nil {
- return err
- }
- }
-
- h := (*mNode)(r.mHead)
- h.initBuckets()
-
- for i := range h.buckets {
- b := (*mBucket)(h.buckets[i])
- for _, n := range b.node {
- // Call releaser.
- if n.value != nil {
- if r, ok := n.value.(util.Releaser); ok {
- r.Release()
- }
- n.value = nil
- }
-
- // Call OnDel.
- for _, f := range n.onDel {
- f()
- }
- }
- }
- }
- r.mu.Unlock()
- return nil
-}
-
-// Node is a 'cache node'.
-type Node struct {
- r *Cache
-
- hash uint32
- ns, key uint64
-
- mu sync.Mutex
- size int
- value Value
-
- ref int32
- onDel []func()
-
- CacheData unsafe.Pointer
-}
-
-// NS returns this 'cache node' namespace.
-func (n *Node) NS() uint64 {
- return n.ns
-}
-
-// Key returns this 'cache node' key.
-func (n *Node) Key() uint64 {
- return n.key
-}
-
-// Size returns this 'cache node' size.
-func (n *Node) Size() int {
- return n.size
-}
-
-// Value returns this 'cache node' value.
-func (n *Node) Value() Value {
- return n.value
-}
-
-// Ref returns this 'cache node' ref counter.
-func (n *Node) Ref() int32 {
- return atomic.LoadInt32(&n.ref)
-}
-
-// GetHandle returns an handle for this 'cache node'.
-func (n *Node) GetHandle() *Handle {
- if atomic.AddInt32(&n.ref, 1) <= 1 {
- panic("BUG: Node.GetHandle on zero ref")
- }
- return &Handle{unsafe.Pointer(n)}
-}
-
-func (n *Node) unref() {
- if atomic.AddInt32(&n.ref, -1) == 0 {
- n.r.delete(n)
- }
-}
-
-func (n *Node) unrefLocked() {
- if atomic.AddInt32(&n.ref, -1) == 0 {
- n.r.mu.RLock()
- if !n.r.closed {
- n.r.delete(n)
- }
- n.r.mu.RUnlock()
- }
-}
-
-type Handle struct {
- n unsafe.Pointer // *Node
-}
-
-func (h *Handle) Value() Value {
- n := (*Node)(atomic.LoadPointer(&h.n))
- if n != nil {
- return n.value
- }
- return nil
-}
-
-func (h *Handle) Release() {
- nPtr := atomic.LoadPointer(&h.n)
- if nPtr != nil && atomic.CompareAndSwapPointer(&h.n, nPtr, nil) {
- n := (*Node)(nPtr)
- n.unrefLocked()
- }
-}
-
-func murmur32(ns, key uint64, seed uint32) uint32 {
- const (
- m = uint32(0x5bd1e995)
- r = 24
- )
-
- k1 := uint32(ns >> 32)
- k2 := uint32(ns)
- k3 := uint32(key >> 32)
- k4 := uint32(key)
-
- k1 *= m
- k1 ^= k1 >> r
- k1 *= m
-
- k2 *= m
- k2 ^= k2 >> r
- k2 *= m
-
- k3 *= m
- k3 ^= k3 >> r
- k3 *= m
-
- k4 *= m
- k4 ^= k4 >> r
- k4 *= m
-
- h := seed
-
- h *= m
- h ^= k1
- h *= m
- h ^= k2
- h *= m
- h ^= k3
- h *= m
- h ^= k4
-
- h ^= h >> 13
- h *= m
- h ^= h >> 15
-
- return h
-}
diff --git a/vendor/github.com/syndtr/goleveldb/leveldb/cache/lru.go b/vendor/github.com/syndtr/goleveldb/leveldb/cache/lru.go
deleted file mode 100644
index d9a84cde..00000000
--- a/vendor/github.com/syndtr/goleveldb/leveldb/cache/lru.go
+++ /dev/null
@@ -1,195 +0,0 @@
-// Copyright (c) 2012, Suryandaru Triandana
-// All rights reserved.
-//
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package cache
-
-import (
- "sync"
- "unsafe"
-)
-
-type lruNode struct {
- n *Node
- h *Handle
- ban bool
-
- next, prev *lruNode
-}
-
-func (n *lruNode) insert(at *lruNode) {
- x := at.next
- at.next = n
- n.prev = at
- n.next = x
- x.prev = n
-}
-
-func (n *lruNode) remove() {
- if n.prev != nil {
- n.prev.next = n.next
- n.next.prev = n.prev
- n.prev = nil
- n.next = nil
- } else {
- panic("BUG: removing removed node")
- }
-}
-
-type lru struct {
- mu sync.Mutex
- capacity int
- used int
- recent lruNode
-}
-
-func (r *lru) reset() {
- r.recent.next = &r.recent
- r.recent.prev = &r.recent
- r.used = 0
-}
-
-func (r *lru) Capacity() int {
- r.mu.Lock()
- defer r.mu.Unlock()
- return r.capacity
-}
-
-func (r *lru) SetCapacity(capacity int) {
- var evicted []*lruNode
-
- r.mu.Lock()
- r.capacity = capacity
- for r.used > r.capacity {
- rn := r.recent.prev
- if rn == nil {
- panic("BUG: invalid LRU used or capacity counter")
- }
- rn.remove()
- rn.n.CacheData = nil
- r.used -= rn.n.Size()
- evicted = append(evicted, rn)
- }
- r.mu.Unlock()
-
- for _, rn := range evicted {
- rn.h.Release()
- }
-}
-
-func (r *lru) Promote(n *Node) {
- var evicted []*lruNode
-
- r.mu.Lock()
- if n.CacheData == nil {
- if n.Size() <= r.capacity {
- rn := &lruNode{n: n, h: n.GetHandle()}
- rn.insert(&r.recent)
- n.CacheData = unsafe.Pointer(rn)
- r.used += n.Size()
-
- for r.used > r.capacity {
- rn := r.recent.prev
- if rn == nil {
- panic("BUG: invalid LRU used or capacity counter")
- }
- rn.remove()
- rn.n.CacheData = nil
- r.used -= rn.n.Size()
- evicted = append(evicted, rn)
- }
- }
- } else {
- rn := (*lruNode)(n.CacheData)
- if !rn.ban {
- rn.remove()
- rn.insert(&r.recent)
- }
- }
- r.mu.Unlock()
-
- for _, rn := range evicted {
- rn.h.Release()
- }
-}
-
-func (r *lru) Ban(n *Node) {
- r.mu.Lock()
- if n.CacheData == nil {
- n.CacheData = unsafe.Pointer(&lruNode{n: n, ban: true})
- } else {
- rn := (*lruNode)(n.CacheData)
- if !rn.ban {
- rn.remove()
- rn.ban = true
- r.used -= rn.n.Size()
- r.mu.Unlock()
-
- rn.h.Release()
- rn.h = nil
- return
- }
- }
- r.mu.Unlock()
-}
-
-func (r *lru) Evict(n *Node) {
- r.mu.Lock()
- rn := (*lruNode)(n.CacheData)
- if rn == nil || rn.ban {
- r.mu.Unlock()
- return
- }
- n.CacheData = nil
- r.mu.Unlock()
-
- rn.h.Release()
-}
-
-func (r *lru) EvictNS(ns uint64) {
- var evicted []*lruNode
-
- r.mu.Lock()
- for e := r.recent.prev; e != &r.recent; {
- rn := e
- e = e.prev
- if rn.n.NS() == ns {
- rn.remove()
- rn.n.CacheData = nil
- r.used -= rn.n.Size()
- evicted = append(evicted, rn)
- }
- }
- r.mu.Unlock()
-
- for _, rn := range evicted {
- rn.h.Release()
- }
-}
-
-func (r *lru) EvictAll() {
- r.mu.Lock()
- back := r.recent.prev
- for rn := back; rn != &r.recent; rn = rn.prev {
- rn.n.CacheData = nil
- }
- r.reset()
- r.mu.Unlock()
-
- for rn := back; rn != &r.recent; rn = rn.prev {
- rn.h.Release()
- }
-}
-
-func (r *lru) Close() error {
- return nil
-}
-
-// NewLRU create a new LRU-cache.
-func NewLRU(capacity int) Cacher {
- r := &lru{capacity: capacity}
- r.reset()
- return r
-}
diff --git a/vendor/github.com/tylerb/graceful/.travis.yml b/vendor/github.com/tylerb/graceful/.travis.yml
index a58cfc70..66fdff76 100644
--- a/vendor/github.com/tylerb/graceful/.travis.yml
+++ b/vendor/github.com/tylerb/graceful/.travis.yml
@@ -1,6 +1,7 @@
language: go
sudo: false
go:
+ - 1.7
- 1.6.2
- 1.5.4
- 1.4.3
diff --git a/vendor/github.com/tylerb/graceful/graceful.go b/vendor/github.com/tylerb/graceful/graceful.go
index 41fb393b..ebf0aeb7 100644
--- a/vendor/github.com/tylerb/graceful/graceful.go
+++ b/vendor/github.com/tylerb/graceful/graceful.go
@@ -6,12 +6,8 @@ import (
"net"
"net/http"
"os"
- "os/signal"
"sync"
- "syscall"
"time"
-
- "golang.org/x/net/netutil"
)
// Server wraps an http.Server with graceful connection handling.
@@ -46,8 +42,8 @@ type Server struct {
ConnState func(net.Conn, http.ConnState)
// BeforeShutdown is an optional callback function that is called
- // before the listener is closed.
- BeforeShutdown func()
+ // before the listener is closed. Returns true if shutdown is allowed
+ BeforeShutdown func() bool
// ShutdownInitiated is an optional callback function that is called
// when shutdown is initiated. It can be used to notify the client
@@ -62,6 +58,10 @@ type Server struct {
// Logger used to notify of errors on startup and on stop.
Logger *log.Logger
+ // LogFunc can be assigned with a logging function of your choice, allowing
+ // you to use whatever logging approach you would like
+ LogFunc func(format string, args ...interface{})
+
// Interrupted is true if the server is handling a SIGINT or SIGTERM
// signal and is thus shutting down.
Interrupted bool
@@ -96,12 +96,13 @@ func Run(addr string, timeout time.Duration, n http.Handler) {
Timeout: timeout,
TCPKeepAlive: 3 * time.Minute,
Server: &http.Server{Addr: addr, Handler: n},
- Logger: DefaultLogger(),
+ // Logger: DefaultLogger(),
}
if err := srv.ListenAndServe(); err != nil {
if opErr, ok := err.(*net.OpError); !ok || (ok && opErr.Op != "accept") {
- srv.Logger.Fatal(err)
+ srv.logf("%s", err)
+ os.Exit(1)
}
}
@@ -138,12 +139,12 @@ func (srv *Server) ListenAndServe() error {
if addr == "" {
addr = ":http"
}
- l, err := net.Listen("tcp", addr)
+ conn, err := srv.newTCPListener(addr)
if err != nil {
return err
}
- return srv.Serve(l)
+ return srv.Serve(conn)
}
// ListenAndServeTLS is equivalent to http.Server.ListenAndServeTLS with graceful shutdown enabled.
@@ -171,13 +172,18 @@ func (srv *Server) ListenTLS(certFile, keyFile string) (net.Listener, error) {
}
var err error
- config.Certificates = make([]tls.Certificate, 1)
- config.Certificates[0], err = tls.LoadX509KeyPair(certFile, keyFile)
- if err != nil {
- return nil, err
+ if certFile != "" && keyFile != "" {
+ config.Certificates = make([]tls.Certificate, 1)
+ config.Certificates[0], err = tls.LoadX509KeyPair(certFile, keyFile)
+ if err != nil {
+ return nil, err
+ }
}
- conn, err := net.Listen("tcp", addr)
+ // Enable http2
+ enableHTTP2ForTLSConfig(config)
+
+ conn, err := srv.newTCPListener(addr)
if err != nil {
return nil, err
}
@@ -188,6 +194,28 @@ func (srv *Server) ListenTLS(certFile, keyFile string) (net.Listener, error) {
return tlsListener, nil
}
+// Enable HTTP2ForTLSConfig explicitly enables http/2 for a TLS Config. This is due to changes in Go 1.7 where
+// http servers are no longer automatically configured to enable http/2 if the server's TLSConfig is set.
+// See https://github.com/golang/go/issues/15908
+func enableHTTP2ForTLSConfig(t *tls.Config) {
+
+ if TLSConfigHasHTTP2Enabled(t) {
+ return
+ }
+
+ t.NextProtos = append(t.NextProtos, "h2")
+}
+
+// TLSConfigHasHTTP2Enabled checks to see if a given TLS Config has http2 enabled.
+func TLSConfigHasHTTP2Enabled(t *tls.Config) bool {
+ for _, value := range t.NextProtos {
+ if value == "h2" {
+ return true
+ }
+ }
+ return false
+}
+
// ListenAndServeTLS is equivalent to http.Server.ListenAndServeTLS with graceful shutdown enabled.
func (srv *Server) ListenAndServeTLS(certFile, keyFile string) error {
l, err := srv.ListenTLS(certFile, keyFile)
@@ -206,7 +234,7 @@ func (srv *Server) ListenAndServeTLSConfig(config *tls.Config) error {
addr = ":https"
}
- conn, err := net.Listen("tcp", addr)
+ conn, err := srv.newTCPListener(addr)
if err != nil {
return err
}
@@ -223,6 +251,7 @@ func (srv *Server) ListenAndServeTLSConfig(config *tls.Config) error {
// If timeout is 0, the server never times out. It waits for all active requests to finish.
func Serve(server *http.Server, l net.Listener, timeout time.Duration) error {
srv := &Server{Timeout: timeout, Server: server, Logger: DefaultLogger()}
+
return srv.Serve(l)
}
@@ -230,11 +259,7 @@ func Serve(server *http.Server, l net.Listener, timeout time.Duration) error {
func (srv *Server) Serve(listener net.Listener) error {
if srv.ListenLimit != 0 {
- listener = netutil.LimitListener(listener, srv.ListenLimit)
- }
-
- if srv.TCPKeepAlive != 0 {
- listener = tcpKeepAliveListener{listener.(*net.TCPListener), srv.TCPKeepAlive}
+ listener = LimitListener(listener, srv.ListenLimit)
}
// Make our stopchan
@@ -243,17 +268,24 @@ func (srv *Server) Serve(listener net.Listener) error {
// Track connection state
add := make(chan net.Conn)
idle := make(chan net.Conn)
+ active := make(chan net.Conn)
remove := make(chan net.Conn)
srv.Server.ConnState = func(conn net.Conn, state http.ConnState) {
switch state {
case http.StateNew:
add <- conn
+ case http.StateActive:
+ active <- conn
case http.StateIdle:
idle <- conn
case http.StateClosed, http.StateHijacked:
remove <- conn
}
+
+ srv.stopLock.Lock()
+ defer srv.stopLock.Unlock()
+
if srv.ConnState != nil {
srv.ConnState(conn, state)
}
@@ -262,12 +294,12 @@ func (srv *Server) Serve(listener net.Listener) error {
// Manage open connections
shutdown := make(chan chan struct{})
kill := make(chan struct{})
- go srv.manageConnections(add, idle, remove, shutdown, kill)
+ go srv.manageConnections(add, idle, active, remove, shutdown, kill)
interrupt := srv.interruptChan()
// Set up the interrupt handler
if !srv.NoSignalHandling {
- signal.Notify(interrupt, syscall.SIGINT, syscall.SIGTERM)
+ signalNotify(interrupt)
}
quitting := make(chan struct{})
go srv.handleInterrupt(interrupt, quitting, listener)
@@ -304,8 +336,7 @@ func (srv *Server) Stop(timeout time.Duration) {
defer srv.stopLock.Unlock()
srv.Timeout = timeout
- interrupt := srv.interruptChan()
- interrupt <- syscall.SIGINT
+ sendSignalInt(srv.interruptChan())
}
// StopChan gets the stop channel which will block until
@@ -327,7 +358,7 @@ func DefaultLogger() *log.Logger {
return log.New(os.Stderr, "[graceful] ", 0)
}
-func (srv *Server) manageConnections(add, idle, remove chan net.Conn, shutdown chan chan struct{}, kill chan struct{}) {
+func (srv *Server) manageConnections(add, idle, active, remove chan net.Conn, shutdown chan chan struct{}, kill chan struct{}) {
var done chan struct{}
srv.connections = map[net.Conn]struct{}{}
srv.idleConnections = map[net.Conn]struct{}{}
@@ -335,8 +366,11 @@ func (srv *Server) manageConnections(add, idle, remove chan net.Conn, shutdown c
select {
case conn := <-add:
srv.connections[conn] = struct{}{}
+ srv.idleConnections[conn] = struct{}{} // Newly-added connections are considered idle until they become active.
case conn := <-idle:
srv.idleConnections[conn] = struct{}{}
+ case conn := <-active:
+ delete(srv.idleConnections, conn)
case conn := <-remove:
delete(srv.connections, conn)
delete(srv.idleConnections, conn)
@@ -355,14 +389,17 @@ func (srv *Server) manageConnections(add, idle, remove chan net.Conn, shutdown c
// hit their idle timeout.
for k := range srv.idleConnections {
if err := k.Close(); err != nil {
- srv.log("[ERROR] %s", err)
+ srv.logf("[ERROR] %s", err)
}
}
case <-kill:
+ srv.stopLock.Lock()
+ defer srv.stopLock.Unlock()
+
srv.Server.ConnState = nil
for k := range srv.connections {
if err := k.Close(); err != nil {
- srv.log("[ERROR] %s", err)
+ srv.logf("[ERROR] %s", err)
}
}
return
@@ -384,19 +421,22 @@ func (srv *Server) interruptChan() chan os.Signal {
func (srv *Server) handleInterrupt(interrupt chan os.Signal, quitting chan struct{}, listener net.Listener) {
for _ = range interrupt {
if srv.Interrupted {
- srv.log("already shutting down")
+ srv.logf("already shutting down")
continue
}
- srv.log("shutdown initiated")
+ srv.logf("shutdown initiated")
srv.Interrupted = true
if srv.BeforeShutdown != nil {
- srv.BeforeShutdown()
+ if !srv.BeforeShutdown() {
+ srv.Interrupted = false
+ continue
+ }
}
close(quitting)
srv.SetKeepAlivesEnabled(false)
if err := listener.Close(); err != nil {
- srv.log("[ERROR] %s", err)
+ srv.logf("[ERROR] %s", err)
}
if srv.ShutdownInitiated != nil {
@@ -405,9 +445,11 @@ func (srv *Server) handleInterrupt(interrupt chan os.Signal, quitting chan struc
}
}
-func (srv *Server) log(fmt string, v ...interface{}) {
- if srv.Logger != nil {
- srv.Logger.Printf(fmt, v...)
+func (srv *Server) logf(format string, args ...interface{}) {
+ if srv.LogFunc != nil {
+ srv.LogFunc(format, args...)
+ } else if srv.Logger != nil {
+ srv.Logger.Printf(format, args...)
}
}
@@ -416,6 +458,8 @@ func (srv *Server) shutdown(shutdown chan chan struct{}, kill chan struct{}) {
done := make(chan struct{})
shutdown <- done
+ srv.stopLock.Lock()
+ defer srv.stopLock.Unlock()
if srv.Timeout > 0 {
select {
case <-done:
@@ -433,21 +477,13 @@ func (srv *Server) shutdown(shutdown chan chan struct{}, kill chan struct{}) {
srv.chanLock.Unlock()
}
-// tcpKeepAliveListener sets TCP keep-alive timeouts on accepted
-// connections. It's used by ListenAndServe and ListenAndServeTLS so
-// dead TCP connections (e.g. closing laptop mid-download) eventually
-// go away.
-type tcpKeepAliveListener struct {
- *net.TCPListener
- keepAlivePeriod time.Duration
-}
-
-func (ln tcpKeepAliveListener) Accept() (c net.Conn, err error) {
- tc, err := ln.AcceptTCP()
+func (srv *Server) newTCPListener(addr string) (net.Listener, error) {
+ conn, err := net.Listen("tcp", addr)
if err != nil {
- return
+ return conn, err
}
- tc.SetKeepAlive(true)
- tc.SetKeepAlivePeriod(ln.keepAlivePeriod)
- return tc, nil
+ if srv.TCPKeepAlive != 0 {
+ conn = keepAliveListener{conn, srv.TCPKeepAlive}
+ }
+ return conn, nil
}
diff --git a/vendor/github.com/tylerb/graceful/graceful_test.go b/vendor/github.com/tylerb/graceful/graceful_test.go
index 0fdec0df..b9c49336 100644
--- a/vendor/github.com/tylerb/graceful/graceful_test.go
+++ b/vendor/github.com/tylerb/graceful/graceful_test.go
@@ -17,20 +17,22 @@ import (
"time"
)
-var (
- killTime = 500 * time.Millisecond
- timeoutTime = 1000 * time.Millisecond
- waitTime = 100 * time.Millisecond
+const (
+ // The tests will run a test server on this port.
+ port = 9654
+ concurrentRequestN = 8
+ killTime = 500 * time.Millisecond
+ timeoutTime = 1000 * time.Millisecond
+ waitTime = 100 * time.Millisecond
)
func runQuery(t *testing.T, expected int, shouldErr bool, wg *sync.WaitGroup, once *sync.Once) {
- wg.Add(1)
defer wg.Done()
client := http.Client{}
- r, err := client.Get("http://localhost:9654")
+ r, err := client.Get(fmt.Sprintf("http://localhost:%d", port))
if shouldErr && err == nil {
once.Do(func() {
- t.Fatal("Expected an error but none was encountered.")
+ t.Error("Expected an error but none was encountered.")
})
} else if shouldErr && err != nil {
if checkErr(t, err, once) {
@@ -39,11 +41,11 @@ func runQuery(t *testing.T, expected int, shouldErr bool, wg *sync.WaitGroup, on
}
if r != nil && r.StatusCode != expected {
once.Do(func() {
- t.Fatalf("Incorrect status code on response. Expected %d. Got %d", expected, r.StatusCode)
+ t.Errorf("Incorrect status code on response. Expected %d. Got %d", expected, r.StatusCode)
})
} else if r == nil {
once.Do(func() {
- t.Fatal("No response when a response was expected.")
+ t.Error("No response when a response was expected.")
})
}
}
@@ -65,13 +67,16 @@ func checkErr(t *testing.T, err error, once *sync.Once) bool {
return true
} else if err != nil {
once.Do(func() {
- t.Fatal("Error on Get:", err)
+ t.Error("Error on Get:", err)
})
}
default:
if strings.Contains(err.Error(), "transport closed before response was received") {
return true
}
+ if strings.Contains(err.Error(), "server closed connection") {
+ return true
+ }
fmt.Printf("unknown err: %s, %#v\n", err, err)
}
return false
@@ -84,16 +89,17 @@ func createListener(sleep time.Duration) (*http.Server, net.Listener, error) {
rw.WriteHeader(http.StatusOK)
})
- server := &http.Server{Addr: ":9654", Handler: mux}
- l, err := net.Listen("tcp", ":9654")
- if err != nil {
- }
+ server := &http.Server{Addr: fmt.Sprintf(":%d", port), Handler: mux}
+ l, err := net.Listen("tcp", fmt.Sprintf(":%d", port))
return server, l, err
}
func launchTestQueries(t *testing.T, wg *sync.WaitGroup, c chan os.Signal) {
+ defer wg.Done()
var once sync.Once
- for i := 0; i < 8; i++ {
+
+ for i := 0; i < concurrentRequestN; i++ {
+ wg.Add(1)
go runQuery(t, http.StatusOK, false, wg, &once)
}
@@ -101,121 +107,185 @@ func launchTestQueries(t *testing.T, wg *sync.WaitGroup, c chan os.Signal) {
c <- os.Interrupt
time.Sleep(waitTime)
- for i := 0; i < 8; i++ {
+ for i := 0; i < concurrentRequestN; i++ {
+ wg.Add(1)
go runQuery(t, 0, true, wg, &once)
}
-
- wg.Done()
}
func TestGracefulRun(t *testing.T) {
- c := make(chan os.Signal, 1)
-
var wg sync.WaitGroup
- wg.Add(1)
+ defer wg.Wait()
+ c := make(chan os.Signal, 1)
server, l, err := createListener(killTime / 2)
if err != nil {
t.Fatal(err)
}
+ wg.Add(1)
go func() {
+ defer wg.Done()
srv := &Server{Timeout: killTime, Server: server, interrupt: c}
srv.Serve(l)
- wg.Done()
}()
wg.Add(1)
go launchTestQueries(t, &wg, c)
- wg.Wait()
+}
+
+func TestGracefulRunLimitKeepAliveListener(t *testing.T) {
+ var wg sync.WaitGroup
+ defer wg.Wait()
+
+ c := make(chan os.Signal, 1)
+ server, l, err := createListener(killTime / 2)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+ srv := &Server{
+ Timeout: killTime,
+ ListenLimit: concurrentRequestN,
+ TCPKeepAlive: 1 * time.Second,
+ Server: server,
+ interrupt: c,
+ }
+ srv.Serve(l)
+ }()
+
+ wg.Add(1)
+ go launchTestQueries(t, &wg, c)
}
func TestGracefulRunTimesOut(t *testing.T) {
- c := make(chan os.Signal, 1)
-
var wg sync.WaitGroup
- wg.Add(1)
+ defer wg.Wait()
+ c := make(chan os.Signal, 1)
server, l, err := createListener(killTime * 10)
if err != nil {
t.Fatal(err)
}
- go func() {
- srv := &Server{Timeout: killTime, Server: server, interrupt: c}
- srv.Serve(l)
- wg.Done()
- }()
-
- var once sync.Once
wg.Add(1)
go func() {
- for i := 0; i < 8; i++ {
+ defer wg.Done()
+ srv := &Server{Timeout: killTime, Server: server, interrupt: c}
+ srv.Serve(l)
+ }()
+
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+ var once sync.Once
+
+ for i := 0; i < concurrentRequestN; i++ {
+ wg.Add(1)
go runQuery(t, 0, true, &wg, &once)
}
+
time.Sleep(waitTime)
c <- os.Interrupt
time.Sleep(waitTime)
- for i := 0; i < 8; i++ {
+
+ for i := 0; i < concurrentRequestN; i++ {
+ wg.Add(1)
go runQuery(t, 0, true, &wg, &once)
}
- wg.Done()
}()
-
- wg.Wait()
-
}
func TestGracefulRunDoesntTimeOut(t *testing.T) {
- c := make(chan os.Signal, 1)
-
var wg sync.WaitGroup
- wg.Add(1)
+ defer wg.Wait()
+ c := make(chan os.Signal, 1)
server, l, err := createListener(killTime * 2)
if err != nil {
t.Fatal(err)
}
+ wg.Add(1)
go func() {
+ defer wg.Done()
srv := &Server{Timeout: 0, Server: server, interrupt: c}
srv.Serve(l)
- wg.Done()
}()
wg.Add(1)
go launchTestQueries(t, &wg, c)
+}
+
+func TestGracefulRunDoesntTimeOutAfterConnectionCreated(t *testing.T) {
+ var wg sync.WaitGroup
+ defer wg.Wait()
+
+ c := make(chan os.Signal, 1)
+ server, l, err := createListener(killTime)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+ srv := &Server{Timeout: 0, Server: server, interrupt: c}
+ srv.Serve(l)
+ }()
+ time.Sleep(waitTime)
+
+ // Make a sample first request. The connection will be left idle.
+ resp, err := http.Get(fmt.Sprintf("http://localhost:%d", port))
+ if err != nil {
+ panic(fmt.Sprintf("first request failed: %v", err))
+ }
+ resp.Body.Close()
+
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+
+ // With idle connections improperly handled, the server doesn't wait for this
+ // to complete and the request fails. It should be allowed to complete successfully.
+ _, err := http.Get(fmt.Sprintf("http://localhost:%d", port))
+ if err != nil {
+ t.Errorf("Get failed: %v", err)
+ }
+ }()
+
+ // Ensure the request goes out
+ time.Sleep(waitTime)
+ c <- os.Interrupt
wg.Wait()
}
func TestGracefulRunNoRequests(t *testing.T) {
- c := make(chan os.Signal, 1)
-
var wg sync.WaitGroup
- wg.Add(1)
+ defer wg.Wait()
+ c := make(chan os.Signal, 1)
server, l, err := createListener(killTime * 2)
if err != nil {
t.Fatal(err)
}
+ wg.Add(1)
go func() {
+ defer wg.Done()
srv := &Server{Timeout: 0, Server: server, interrupt: c}
srv.Serve(l)
- wg.Done()
}()
c <- os.Interrupt
-
- wg.Wait()
-
}
func TestGracefulForwardsConnState(t *testing.T) {
- c := make(chan os.Signal, 1)
- states := make(map[http.ConnState]int)
var stateLock sync.Mutex
-
+ states := make(map[http.ConnState]int)
connState := func(conn net.Conn, state http.ConnState) {
stateLock.Lock()
states[state]++
@@ -223,20 +293,23 @@ func TestGracefulForwardsConnState(t *testing.T) {
}
var wg sync.WaitGroup
- wg.Add(1)
+ defer wg.Wait()
expected := map[http.ConnState]int{
- http.StateNew: 8,
- http.StateActive: 8,
- http.StateClosed: 8,
+ http.StateNew: concurrentRequestN,
+ http.StateActive: concurrentRequestN,
+ http.StateClosed: concurrentRequestN,
}
+ c := make(chan os.Signal, 1)
server, l, err := createListener(killTime / 2)
if err != nil {
t.Fatal(err)
}
+ wg.Add(1)
go func() {
+ defer wg.Done()
srv := &Server{
ConnState: connState,
Timeout: killTime,
@@ -244,8 +317,6 @@ func TestGracefulForwardsConnState(t *testing.T) {
interrupt: c,
}
srv.Serve(l)
-
- wg.Done()
}()
wg.Add(1)
@@ -305,7 +376,7 @@ func TestGracefulExplicitStopOverride(t *testing.T) {
func TestBeforeShutdownAndShutdownInitiatedCallbacks(t *testing.T) {
var wg sync.WaitGroup
- wg.Add(1)
+ defer wg.Wait()
server, l, err := createListener(1 * time.Millisecond)
if err != nil {
@@ -313,16 +384,18 @@ func TestBeforeShutdownAndShutdownInitiatedCallbacks(t *testing.T) {
}
beforeShutdownCalled := make(chan struct{})
- cb1 := func() { close(beforeShutdownCalled) }
+ cb1 := func() bool { close(beforeShutdownCalled); return true }
shutdownInitiatedCalled := make(chan struct{})
cb2 := func() { close(shutdownInitiatedCalled) }
+ wg.Add(2)
srv := &Server{Server: server, BeforeShutdown: cb1, ShutdownInitiated: cb2}
go func() {
+ defer wg.Done()
srv.Serve(l)
- wg.Done()
}()
go func() {
+ defer wg.Done()
time.Sleep(waitTime)
srv.Stop(killTime)
}()
@@ -348,6 +421,61 @@ func TestBeforeShutdownAndShutdownInitiatedCallbacks(t *testing.T) {
if !shutdownInitiated {
t.Fatal("shutdownInitiated should be true")
}
+}
+
+func TestBeforeShutdownCanceled(t *testing.T) {
+ var wg sync.WaitGroup
+ wg.Add(1)
+
+ server, l, err := createListener(1 * time.Millisecond)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ beforeShutdownCalled := make(chan struct{})
+ cb1 := func() bool { close(beforeShutdownCalled); return false }
+ shutdownInitiatedCalled := make(chan struct{})
+ cb2 := func() { close(shutdownInitiatedCalled) }
+
+ srv := &Server{Server: server, BeforeShutdown: cb1, ShutdownInitiated: cb2}
+ go func() {
+ srv.Serve(l)
+ wg.Done()
+ }()
+ go func() {
+ time.Sleep(waitTime)
+ srv.Stop(killTime)
+ }()
+
+ beforeShutdown := false
+ shutdownInitiated := false
+ timeouted := false
+
+ for i := 0; i < 2; i++ {
+ select {
+ case <-beforeShutdownCalled:
+ beforeShutdownCalled = nil
+ beforeShutdown = true
+ case <-shutdownInitiatedCalled:
+ shutdownInitiatedCalled = nil
+ shutdownInitiated = true
+ case <-time.After(killTime):
+ timeouted = true
+ }
+ }
+
+ if !beforeShutdown {
+ t.Fatal("beforeShutdown should be true")
+ }
+ if !timeouted {
+ t.Fatal("timeouted should be true")
+ }
+ if shutdownInitiated {
+ t.Fatal("shutdownInitiated shouldn't be true")
+ }
+
+ srv.BeforeShutdown = func() bool { return true }
+ srv.Stop(killTime)
wg.Wait()
}
@@ -367,17 +495,16 @@ func hijackingListener(srv *Server) (*http.Server, net.Listener, error) {
bufrw.Flush()
})
- server := &http.Server{Addr: ":9654", Handler: mux}
- l, err := net.Listen("tcp", ":9654")
+ server := &http.Server{Addr: fmt.Sprintf(":%d", port), Handler: mux}
+ l, err := net.Listen("tcp", fmt.Sprintf(":%d", port))
return server, l, err
}
func TestNotifyClosed(t *testing.T) {
- c := make(chan os.Signal, 1)
-
var wg sync.WaitGroup
- wg.Add(1)
+ defer wg.Wait()
+ c := make(chan os.Signal, 1)
srv := &Server{Timeout: killTime, interrupt: c}
server, l, err := hijackingListener(srv)
if err != nil {
@@ -386,13 +513,15 @@ func TestNotifyClosed(t *testing.T) {
srv.Server = server
+ wg.Add(1)
go func() {
+ defer wg.Done()
srv.Serve(l)
- wg.Done()
}()
var once sync.Once
- for i := 0; i < 8; i++ {
+ for i := 0; i < concurrentRequestN; i++ {
+ wg.Add(1)
runQuery(t, http.StatusOK, false, &wg, &once)
}
@@ -412,8 +541,10 @@ func TestNotifyClosed(t *testing.T) {
}
func TestStopDeadlock(t *testing.T) {
- c := make(chan struct{})
+ var wg sync.WaitGroup
+ defer wg.Wait()
+ c := make(chan struct{})
server, l, err := createListener(1 * time.Millisecond)
if err != nil {
t.Fatal(err)
@@ -421,12 +552,14 @@ func TestStopDeadlock(t *testing.T) {
srv := &Server{Server: server, NoSignalHandling: true}
+ wg.Add(2)
go func() {
+ defer wg.Done()
time.Sleep(waitTime)
srv.Serve(l)
}()
-
go func() {
+ defer wg.Done()
srv.Stop(0)
close(c)
}()
@@ -525,6 +658,28 @@ func TestMultiInterrupts(t *testing.T) {
}
}
+func TestLogFunc(t *testing.T) {
+ c := make(chan os.Signal, 1)
+
+ server, l, err := createListener(killTime * 10)
+ if err != nil {
+ t.Fatal(err)
+ }
+ var called bool
+ srv := &Server{Timeout: killTime, Server: server,
+ LogFunc: func(format string, args ...interface{}) {
+ called = true
+ }, interrupt: c}
+ stop := srv.StopChan()
+ go func() { srv.Serve(l) }()
+ c <- os.Interrupt
+ <-stop
+
+ if called != true {
+ t.Fatal("Expected LogFunc to be called.")
+ }
+}
+
// SyncBuffer calls Done on the embedded wait group after each call to Write.
type SyncBuffer struct {
*sync.WaitGroup
diff --git a/vendor/github.com/tylerb/graceful/http2_test.go b/vendor/github.com/tylerb/graceful/http2_test.go
index 8ee00289..5b2ebbb8 100644
--- a/vendor/github.com/tylerb/graceful/http2_test.go
+++ b/vendor/github.com/tylerb/graceful/http2_test.go
@@ -4,6 +4,7 @@ package graceful
import (
"crypto/tls"
+ "fmt"
"net/http"
"os"
"sync"
@@ -19,7 +20,7 @@ func createServer() *http.Server {
rw.WriteHeader(http.StatusOK)
})
- server := &http.Server{Addr: ":9654", Handler: mux}
+ server := &http.Server{Addr: fmt.Sprintf(":%d", port), Handler: mux}
return server
}
@@ -39,7 +40,7 @@ func checkIfConnectionToServerIsHTTP2(t *testing.T, wg *sync.WaitGroup, c chan o
}
client := http.Client{Transport: tr}
- r, err := client.Get("https://localhost:9654")
+ r, err := client.Get(fmt.Sprintf("https://localhost:%d", port))
c <- os.Interrupt
@@ -47,7 +48,7 @@ func checkIfConnectionToServerIsHTTP2(t *testing.T, wg *sync.WaitGroup, c chan o
t.Fatalf("Error encountered while connecting to test server: %s", err)
}
- if r.Proto != "HTTP/2.0" {
+ if !r.ProtoAtLeast(2, 0) {
t.Fatalf("Expected HTTP/2 connection to server, but connection was using %s", r.Proto)
}
}
@@ -64,7 +65,7 @@ func TestHTTP2ListenAndServeTLS(t *testing.T) {
var srv *Server
go func() {
// set timeout of 0 to test idle connection closing
- srv = &Server{Timeout: 0, Server: server, interrupt: c}
+ srv = &Server{Timeout: 0, TCPKeepAlive: 1 * time.Minute, Server: server, interrupt: c}
srv.ListenAndServeTLS("test-fixtures/cert.crt", "test-fixtures/key.pem")
wg.Done()
}()
@@ -97,7 +98,7 @@ func TestHTTP2ListenAndServeTLSConfig(t *testing.T) {
server2 := createServer()
go func() {
- srv := &Server{Timeout: killTime, Server: server2, interrupt: c}
+ srv := &Server{Timeout: killTime, TCPKeepAlive: 1 * time.Minute, Server: server2, interrupt: c}
cert, err := tls.LoadX509KeyPair("test-fixtures/cert.crt", "test-fixtures/key.pem")
@@ -107,6 +108,7 @@ func TestHTTP2ListenAndServeTLSConfig(t *testing.T) {
tlsConf := &tls.Config{
Certificates: []tls.Certificate{cert},
+ NextProtos: []string{"h2"}, // We need to explicitly enable http/2 in Go 1.7+
}
tlsConf.BuildNameToCertificate()
diff --git a/vendor/github.com/tylerb/graceful/keepalive_listener.go b/vendor/github.com/tylerb/graceful/keepalive_listener.go
new file mode 100644
index 00000000..1484bc21
--- /dev/null
+++ b/vendor/github.com/tylerb/graceful/keepalive_listener.go
@@ -0,0 +1,32 @@
+package graceful
+
+import (
+ "net"
+ "time"
+)
+
+type keepAliveConn interface {
+ SetKeepAlive(bool) error
+ SetKeepAlivePeriod(d time.Duration) error
+}
+
+// keepAliveListener sets TCP keep-alive timeouts on accepted
+// connections. It's used by ListenAndServe and ListenAndServeTLS so
+// dead TCP connections (e.g. closing laptop mid-download) eventually
+// go away.
+type keepAliveListener struct {
+ net.Listener
+ keepAlivePeriod time.Duration
+}
+
+func (ln keepAliveListener) Accept() (net.Conn, error) {
+ c, err := ln.Listener.Accept()
+ if err != nil {
+ return nil, err
+ }
+
+ kac := c.(keepAliveConn)
+ kac.SetKeepAlive(true)
+ kac.SetKeepAlivePeriod(ln.keepAlivePeriod)
+ return c, nil
+}
diff --git a/vendor/github.com/tylerb/graceful/limit_listen.go b/vendor/github.com/tylerb/graceful/limit_listen.go
new file mode 100644
index 00000000..ce32ce99
--- /dev/null
+++ b/vendor/github.com/tylerb/graceful/limit_listen.go
@@ -0,0 +1,77 @@
+// Copyright 2013 The etcd Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package graceful
+
+import (
+ "errors"
+ "net"
+ "sync"
+ "time"
+)
+
+// ErrNotTCP indicates that network connection is not a TCP connection.
+var ErrNotTCP = errors.New("only tcp connections have keepalive")
+
+// LimitListener returns a Listener that accepts at most n simultaneous
+// connections from the provided Listener.
+func LimitListener(l net.Listener, n int) net.Listener {
+ return &limitListener{l, make(chan struct{}, n)}
+}
+
+type limitListener struct {
+ net.Listener
+ sem chan struct{}
+}
+
+func (l *limitListener) acquire() { l.sem <- struct{}{} }
+func (l *limitListener) release() { <-l.sem }
+
+func (l *limitListener) Accept() (net.Conn, error) {
+ l.acquire()
+ c, err := l.Listener.Accept()
+ if err != nil {
+ l.release()
+ return nil, err
+ }
+ return &limitListenerConn{Conn: c, release: l.release}, nil
+}
+
+type limitListenerConn struct {
+ net.Conn
+ releaseOnce sync.Once
+ release func()
+}
+
+func (l *limitListenerConn) Close() error {
+ err := l.Conn.Close()
+ l.releaseOnce.Do(l.release)
+ return err
+}
+
+func (l *limitListenerConn) SetKeepAlive(doKeepAlive bool) error {
+ tcpc, ok := l.Conn.(*net.TCPConn)
+ if !ok {
+ return ErrNotTCP
+ }
+ return tcpc.SetKeepAlive(doKeepAlive)
+}
+
+func (l *limitListenerConn) SetKeepAlivePeriod(d time.Duration) error {
+ tcpc, ok := l.Conn.(*net.TCPConn)
+ if !ok {
+ return ErrNotTCP
+ }
+ return tcpc.SetKeepAlivePeriod(d)
+}
diff --git a/vendor/github.com/tylerb/graceful/signal.go b/vendor/github.com/tylerb/graceful/signal.go
new file mode 100644
index 00000000..9550978f
--- /dev/null
+++ b/vendor/github.com/tylerb/graceful/signal.go
@@ -0,0 +1,17 @@
+//+build !appengine
+
+package graceful
+
+import (
+ "os"
+ "os/signal"
+ "syscall"
+)
+
+func signalNotify(interrupt chan<- os.Signal) {
+ signal.Notify(interrupt, syscall.SIGINT, syscall.SIGTERM)
+}
+
+func sendSignalInt(interrupt chan<- os.Signal) {
+ interrupt <- syscall.SIGINT
+}
diff --git a/vendor/github.com/tylerb/graceful/signal_appengine.go b/vendor/github.com/tylerb/graceful/signal_appengine.go
new file mode 100644
index 00000000..6b776f08
--- /dev/null
+++ b/vendor/github.com/tylerb/graceful/signal_appengine.go
@@ -0,0 +1,13 @@
+//+build appengine
+
+package graceful
+
+import "os"
+
+func signalNotify(interrupt chan<- os.Signal) {
+ // Does not notify in the case of AppEngine.
+}
+
+func sendSignalInt(interrupt chan<- os.Signal) {
+ // Does not send in the case of AppEngine.
+}
diff --git a/vendor/github.com/tylerb/graceful/tests/main.go b/vendor/github.com/tylerb/graceful/tests/main.go
index 8c8fa204..9380ae69 100644
--- a/vendor/github.com/tylerb/graceful/tests/main.go
+++ b/vendor/github.com/tylerb/graceful/tests/main.go
@@ -4,8 +4,8 @@ import (
"fmt"
"sync"
- "github.com/codegangsta/negroni"
- "github.com/tylerb/graceful"
+ "github.com/urfave/negroni"
+ "gopkg.in/tylerb/graceful.v1"
)
func main() {
diff --git a/vendor/golang.org/x/sys/.gitattributes b/vendor/golang.org/x/sys/.gitattributes
new file mode 100644
index 00000000..d2f212e5
--- /dev/null
+++ b/vendor/golang.org/x/sys/.gitattributes
@@ -0,0 +1,10 @@
+# Treat all files in this repo as binary, with no git magic updating
+# line endings. Windows users contributing to Go will need to use a
+# modern version of git and editors capable of LF line endings.
+#
+# We'll prevent accidental CRLF line endings from entering the repo
+# via the git-review gofmt checks.
+#
+# See golang.org/issue/9281
+
+* -text
diff --git a/vendor/golang.org/x/sys/.gitignore b/vendor/golang.org/x/sys/.gitignore
new file mode 100644
index 00000000..8339fd61
--- /dev/null
+++ b/vendor/golang.org/x/sys/.gitignore
@@ -0,0 +1,2 @@
+# Add no patterns to .hgignore except for files generated by the build.
+last-change
diff --git a/vendor/golang.org/x/sys/AUTHORS b/vendor/golang.org/x/sys/AUTHORS
new file mode 100644
index 00000000..15167cd7
--- /dev/null
+++ b/vendor/golang.org/x/sys/AUTHORS
@@ -0,0 +1,3 @@
+# This source code refers to The Go Authors for copyright purposes.
+# The master list of authors is in the main Go distribution,
+# visible at http://tip.golang.org/AUTHORS.
diff --git a/vendor/golang.org/x/sys/CONTRIBUTING.md b/vendor/golang.org/x/sys/CONTRIBUTING.md
new file mode 100644
index 00000000..88dff59b
--- /dev/null
+++ b/vendor/golang.org/x/sys/CONTRIBUTING.md
@@ -0,0 +1,31 @@
+# Contributing to Go
+
+Go is an open source project.
+
+It is the work of hundreds of contributors. We appreciate your help!
+
+
+## Filing issues
+
+When [filing an issue](https://golang.org/issue/new), make sure to answer these five questions:
+
+1. What version of Go are you using (`go version`)?
+2. What operating system and processor architecture are you using?
+3. What did you do?
+4. What did you expect to see?
+5. What did you see instead?
+
+General questions should go to the [golang-nuts mailing list](https://groups.google.com/group/golang-nuts) instead of the issue tracker.
+The gophers there will answer or ask you to file an issue if you've tripped over a bug.
+
+## Contributing code
+
+Please read the [Contribution Guidelines](https://golang.org/doc/contribute.html)
+before sending patches.
+
+**We do not accept GitHub pull requests**
+(we use [Gerrit](https://code.google.com/p/gerrit/) instead for code review).
+
+Unless otherwise noted, the Go source files are distributed under
+the BSD-style license found in the LICENSE file.
+
diff --git a/vendor/golang.org/x/sys/CONTRIBUTORS b/vendor/golang.org/x/sys/CONTRIBUTORS
new file mode 100644
index 00000000..1c4577e9
--- /dev/null
+++ b/vendor/golang.org/x/sys/CONTRIBUTORS
@@ -0,0 +1,3 @@
+# This source code was written by the Go contributors.
+# The master list of contributors is in the main Go distribution,
+# visible at http://tip.golang.org/CONTRIBUTORS.
diff --git a/vendor/golang.org/x/sys/LICENSE b/vendor/golang.org/x/sys/LICENSE
new file mode 100644
index 00000000..6a66aea5
--- /dev/null
+++ b/vendor/golang.org/x/sys/LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) 2009 The Go Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+ * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/golang.org/x/sys/PATENTS b/vendor/golang.org/x/sys/PATENTS
new file mode 100644
index 00000000..73309904
--- /dev/null
+++ b/vendor/golang.org/x/sys/PATENTS
@@ -0,0 +1,22 @@
+Additional IP Rights Grant (Patents)
+
+"This implementation" means the copyrightable works distributed by
+Google as part of the Go project.
+
+Google hereby grants to You a perpetual, worldwide, non-exclusive,
+no-charge, royalty-free, irrevocable (except as stated in this section)
+patent license to make, have made, use, offer to sell, sell, import,
+transfer and otherwise run, modify and propagate the contents of this
+implementation of Go, where such license applies only to those patent
+claims, both currently owned or controlled by Google and acquired in
+the future, licensable by Google that are necessarily infringed by this
+implementation of Go. This grant does not include claims that would be
+infringed only as a consequence of further modification of this
+implementation. If you or your agent or exclusive licensee institute or
+order or agree to the institution of patent litigation against any
+entity (including a cross-claim or counterclaim in a lawsuit) alleging
+that this implementation of Go or any code incorporated within this
+implementation of Go constitutes direct or contributory patent
+infringement, or inducement of patent infringement, then any patent
+rights granted to you under this License for this implementation of Go
+shall terminate as of the date such litigation is filed.
diff --git a/vendor/golang.org/x/sys/README b/vendor/golang.org/x/sys/README
new file mode 100644
index 00000000..bd422b40
--- /dev/null
+++ b/vendor/golang.org/x/sys/README
@@ -0,0 +1,3 @@
+This repository holds supplemental Go packages for low-level interactions with the operating system.
+
+To submit changes to this repository, see http://golang.org/doc/contribute.html.
diff --git a/vendor/golang.org/x/sys/codereview.cfg b/vendor/golang.org/x/sys/codereview.cfg
new file mode 100644
index 00000000..3f8b14b6
--- /dev/null
+++ b/vendor/golang.org/x/sys/codereview.cfg
@@ -0,0 +1 @@
+issuerepo: golang/go
diff --git a/vendor/golang.org/x/sys/plan9/asm.s b/vendor/golang.org/x/sys/plan9/asm.s
new file mode 100644
index 00000000..d4ca868f
--- /dev/null
+++ b/vendor/golang.org/x/sys/plan9/asm.s
@@ -0,0 +1,8 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT ·use(SB),NOSPLIT,$0
+ RET
diff --git a/vendor/golang.org/x/sys/plan9/asm_plan9_386.s b/vendor/golang.org/x/sys/plan9/asm_plan9_386.s
new file mode 100644
index 00000000..bc5cab1f
--- /dev/null
+++ b/vendor/golang.org/x/sys/plan9/asm_plan9_386.s
@@ -0,0 +1,30 @@
+// 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.
+
+#include "textflag.h"
+
+//
+// System call support for 386, Plan 9
+//
+
+// Just jump to package syscall's implementation for all these functions.
+// The runtime may know about them.
+
+TEXT ·Syscall(SB),NOSPLIT,$0-32
+ JMP syscall·Syscall(SB)
+
+TEXT ·Syscall6(SB),NOSPLIT,$0-44
+ JMP syscall·Syscall6(SB)
+
+TEXT ·RawSyscall(SB),NOSPLIT,$0-28
+ JMP syscall·RawSyscall(SB)
+
+TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
+ JMP syscall·RawSyscall6(SB)
+
+TEXT ·seek(SB),NOSPLIT,$0-36
+ JMP syscall·seek(SB)
+
+TEXT ·exit(SB),NOSPLIT,$4-4
+ JMP syscall·exit(SB)
diff --git a/vendor/golang.org/x/sys/plan9/asm_plan9_amd64.s b/vendor/golang.org/x/sys/plan9/asm_plan9_amd64.s
new file mode 100644
index 00000000..d3448e67
--- /dev/null
+++ b/vendor/golang.org/x/sys/plan9/asm_plan9_amd64.s
@@ -0,0 +1,30 @@
+// 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.
+
+#include "textflag.h"
+
+//
+// System call support for amd64, Plan 9
+//
+
+// Just jump to package syscall's implementation for all these functions.
+// The runtime may know about them.
+
+TEXT ·Syscall(SB),NOSPLIT,$0-64
+ JMP syscall·Syscall(SB)
+
+TEXT ·Syscall6(SB),NOSPLIT,$0-88
+ JMP syscall·Syscall6(SB)
+
+TEXT ·RawSyscall(SB),NOSPLIT,$0-56
+ JMP syscall·RawSyscall(SB)
+
+TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
+ JMP syscall·RawSyscall6(SB)
+
+TEXT ·seek(SB),NOSPLIT,$0-56
+ JMP syscall·seek(SB)
+
+TEXT ·exit(SB),NOSPLIT,$8-8
+ JMP syscall·exit(SB)
diff --git a/vendor/golang.org/x/sys/plan9/const_plan9.go b/vendor/golang.org/x/sys/plan9/const_plan9.go
new file mode 100644
index 00000000..b4e85a3a
--- /dev/null
+++ b/vendor/golang.org/x/sys/plan9/const_plan9.go
@@ -0,0 +1,70 @@
+package plan9
+
+// Plan 9 Constants
+
+// Open modes
+const (
+ O_RDONLY = 0
+ O_WRONLY = 1
+ O_RDWR = 2
+ O_TRUNC = 16
+ O_CLOEXEC = 32
+ O_EXCL = 0x1000
+)
+
+// Rfork flags
+const (
+ RFNAMEG = 1 << 0
+ RFENVG = 1 << 1
+ RFFDG = 1 << 2
+ RFNOTEG = 1 << 3
+ RFPROC = 1 << 4
+ RFMEM = 1 << 5
+ RFNOWAIT = 1 << 6
+ RFCNAMEG = 1 << 10
+ RFCENVG = 1 << 11
+ RFCFDG = 1 << 12
+ RFREND = 1 << 13
+ RFNOMNT = 1 << 14
+)
+
+// Qid.Type bits
+const (
+ QTDIR = 0x80
+ QTAPPEND = 0x40
+ QTEXCL = 0x20
+ QTMOUNT = 0x10
+ QTAUTH = 0x08
+ QTTMP = 0x04
+ QTFILE = 0x00
+)
+
+// Dir.Mode bits
+const (
+ DMDIR = 0x80000000
+ DMAPPEND = 0x40000000
+ DMEXCL = 0x20000000
+ DMMOUNT = 0x10000000
+ DMAUTH = 0x08000000
+ DMTMP = 0x04000000
+ DMREAD = 0x4
+ DMWRITE = 0x2
+ DMEXEC = 0x1
+)
+
+const (
+ STATMAX = 65535
+ ERRMAX = 128
+ STATFIXLEN = 49
+)
+
+// Mount and bind flags
+const (
+ MREPL = 0x0000
+ MBEFORE = 0x0001
+ MAFTER = 0x0002
+ MORDER = 0x0003
+ MCREATE = 0x0004
+ MCACHE = 0x0010
+ MMASK = 0x0017
+)
diff --git a/vendor/golang.org/x/sys/plan9/dir_plan9.go b/vendor/golang.org/x/sys/plan9/dir_plan9.go
new file mode 100644
index 00000000..0955e0c5
--- /dev/null
+++ b/vendor/golang.org/x/sys/plan9/dir_plan9.go
@@ -0,0 +1,212 @@
+// Copyright 2012 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.
+
+// Plan 9 directory marshalling. See intro(5).
+
+package plan9
+
+import "errors"
+
+var (
+ ErrShortStat = errors.New("stat buffer too short")
+ ErrBadStat = errors.New("malformed stat buffer")
+ ErrBadName = errors.New("bad character in file name")
+)
+
+// A Qid represents a 9P server's unique identification for a file.
+type Qid struct {
+ Path uint64 // the file server's unique identification for the file
+ Vers uint32 // version number for given Path
+ Type uint8 // the type of the file (plan9.QTDIR for example)
+}
+
+// A Dir contains the metadata for a file.
+type Dir struct {
+ // system-modified data
+ Type uint16 // server type
+ Dev uint32 // server subtype
+
+ // file data
+ Qid Qid // unique id from server
+ Mode uint32 // permissions
+ Atime uint32 // last read time
+ Mtime uint32 // last write time
+ Length int64 // file length
+ Name string // last element of path
+ Uid string // owner name
+ Gid string // group name
+ Muid string // last modifier name
+}
+
+var nullDir = Dir{
+ Type: ^uint16(0),
+ Dev: ^uint32(0),
+ Qid: Qid{
+ Path: ^uint64(0),
+ Vers: ^uint32(0),
+ Type: ^uint8(0),
+ },
+ Mode: ^uint32(0),
+ Atime: ^uint32(0),
+ Mtime: ^uint32(0),
+ Length: ^int64(0),
+}
+
+// Null assigns special "don't touch" values to members of d to
+// avoid modifying them during plan9.Wstat.
+func (d *Dir) Null() { *d = nullDir }
+
+// Marshal encodes a 9P stat message corresponding to d into b
+//
+// If there isn't enough space in b for a stat message, ErrShortStat is returned.
+func (d *Dir) Marshal(b []byte) (n int, err error) {
+ n = STATFIXLEN + len(d.Name) + len(d.Uid) + len(d.Gid) + len(d.Muid)
+ if n > len(b) {
+ return n, ErrShortStat
+ }
+
+ for _, c := range d.Name {
+ if c == '/' {
+ return n, ErrBadName
+ }
+ }
+
+ b = pbit16(b, uint16(n)-2)
+ b = pbit16(b, d.Type)
+ b = pbit32(b, d.Dev)
+ b = pbit8(b, d.Qid.Type)
+ b = pbit32(b, d.Qid.Vers)
+ b = pbit64(b, d.Qid.Path)
+ b = pbit32(b, d.Mode)
+ b = pbit32(b, d.Atime)
+ b = pbit32(b, d.Mtime)
+ b = pbit64(b, uint64(d.Length))
+ b = pstring(b, d.Name)
+ b = pstring(b, d.Uid)
+ b = pstring(b, d.Gid)
+ b = pstring(b, d.Muid)
+
+ return n, nil
+}
+
+// UnmarshalDir decodes a single 9P stat message from b and returns the resulting Dir.
+//
+// If b is too small to hold a valid stat message, ErrShortStat is returned.
+//
+// If the stat message itself is invalid, ErrBadStat is returned.
+func UnmarshalDir(b []byte) (*Dir, error) {
+ if len(b) < STATFIXLEN {
+ return nil, ErrShortStat
+ }
+ size, buf := gbit16(b)
+ if len(b) != int(size)+2 {
+ return nil, ErrBadStat
+ }
+ b = buf
+
+ var d Dir
+ d.Type, b = gbit16(b)
+ d.Dev, b = gbit32(b)
+ d.Qid.Type, b = gbit8(b)
+ d.Qid.Vers, b = gbit32(b)
+ d.Qid.Path, b = gbit64(b)
+ d.Mode, b = gbit32(b)
+ d.Atime, b = gbit32(b)
+ d.Mtime, b = gbit32(b)
+
+ n, b := gbit64(b)
+ d.Length = int64(n)
+
+ var ok bool
+ if d.Name, b, ok = gstring(b); !ok {
+ return nil, ErrBadStat
+ }
+ if d.Uid, b, ok = gstring(b); !ok {
+ return nil, ErrBadStat
+ }
+ if d.Gid, b, ok = gstring(b); !ok {
+ return nil, ErrBadStat
+ }
+ if d.Muid, b, ok = gstring(b); !ok {
+ return nil, ErrBadStat
+ }
+
+ return &d, nil
+}
+
+// pbit8 copies the 8-bit number v to b and returns the remaining slice of b.
+func pbit8(b []byte, v uint8) []byte {
+ b[0] = byte(v)
+ return b[1:]
+}
+
+// pbit16 copies the 16-bit number v to b in little-endian order and returns the remaining slice of b.
+func pbit16(b []byte, v uint16) []byte {
+ b[0] = byte(v)
+ b[1] = byte(v >> 8)
+ return b[2:]
+}
+
+// pbit32 copies the 32-bit number v to b in little-endian order and returns the remaining slice of b.
+func pbit32(b []byte, v uint32) []byte {
+ b[0] = byte(v)
+ b[1] = byte(v >> 8)
+ b[2] = byte(v >> 16)
+ b[3] = byte(v >> 24)
+ return b[4:]
+}
+
+// pbit64 copies the 64-bit number v to b in little-endian order and returns the remaining slice of b.
+func pbit64(b []byte, v uint64) []byte {
+ b[0] = byte(v)
+ b[1] = byte(v >> 8)
+ b[2] = byte(v >> 16)
+ b[3] = byte(v >> 24)
+ b[4] = byte(v >> 32)
+ b[5] = byte(v >> 40)
+ b[6] = byte(v >> 48)
+ b[7] = byte(v >> 56)
+ return b[8:]
+}
+
+// pstring copies the string s to b, prepending it with a 16-bit length in little-endian order, and
+// returning the remaining slice of b..
+func pstring(b []byte, s string) []byte {
+ b = pbit16(b, uint16(len(s)))
+ n := copy(b, s)
+ return b[n:]
+}
+
+// gbit8 reads an 8-bit number from b and returns it with the remaining slice of b.
+func gbit8(b []byte) (uint8, []byte) {
+ return uint8(b[0]), b[1:]
+}
+
+// gbit16 reads a 16-bit number in little-endian order from b and returns it with the remaining slice of b.
+func gbit16(b []byte) (uint16, []byte) {
+ return uint16(b[0]) | uint16(b[1])<<8, b[2:]
+}
+
+// gbit32 reads a 32-bit number in little-endian order from b and returns it with the remaining slice of b.
+func gbit32(b []byte) (uint32, []byte) {
+ return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24, b[4:]
+}
+
+// gbit64 reads a 64-bit number in little-endian order from b and returns it with the remaining slice of b.
+func gbit64(b []byte) (uint64, []byte) {
+ lo := uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
+ hi := uint32(b[4]) | uint32(b[5])<<8 | uint32(b[6])<<16 | uint32(b[7])<<24
+ return uint64(lo) | uint64(hi)<<32, b[8:]
+}
+
+// gstring reads a string from b, prefixed with a 16-bit length in little-endian order.
+// It returns the string with the remaining slice of b and a boolean. If the length is
+// greater than the number of bytes in b, the boolean will be false.
+func gstring(b []byte) (string, []byte, bool) {
+ n, b := gbit16(b)
+ if int(n) > len(b) {
+ return "", b, false
+ }
+ return string(b[:n]), b[n:], true
+}
diff --git a/vendor/golang.org/x/sys/plan9/env_plan9.go b/vendor/golang.org/x/sys/plan9/env_plan9.go
new file mode 100644
index 00000000..25a96e7e
--- /dev/null
+++ b/vendor/golang.org/x/sys/plan9/env_plan9.go
@@ -0,0 +1,27 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Plan 9 environment variables.
+
+package plan9
+
+import (
+ "syscall"
+)
+
+func Getenv(key string) (value string, found bool) {
+ return syscall.Getenv(key)
+}
+
+func Setenv(key, value string) error {
+ return syscall.Setenv(key, value)
+}
+
+func Clearenv() {
+ syscall.Clearenv()
+}
+
+func Environ() []string {
+ return syscall.Environ()
+}
diff --git a/vendor/golang.org/x/sys/plan9/env_unset.go b/vendor/golang.org/x/sys/plan9/env_unset.go
new file mode 100644
index 00000000..c37fc26e
--- /dev/null
+++ b/vendor/golang.org/x/sys/plan9/env_unset.go
@@ -0,0 +1,14 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build go1.4
+
+package plan9
+
+import "syscall"
+
+func Unsetenv(key string) error {
+ // This was added in Go 1.4.
+ return syscall.Unsetenv(key)
+}
diff --git a/vendor/golang.org/x/sys/plan9/errors_plan9.go b/vendor/golang.org/x/sys/plan9/errors_plan9.go
new file mode 100644
index 00000000..110cf6a3
--- /dev/null
+++ b/vendor/golang.org/x/sys/plan9/errors_plan9.go
@@ -0,0 +1,50 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package plan9
+
+import "syscall"
+
+// Constants
+const (
+ // Invented values to support what package os expects.
+ O_CREAT = 0x02000
+ O_APPEND = 0x00400
+ O_NOCTTY = 0x00000
+ O_NONBLOCK = 0x00000
+ O_SYNC = 0x00000
+ O_ASYNC = 0x00000
+
+ S_IFMT = 0x1f000
+ S_IFIFO = 0x1000
+ S_IFCHR = 0x2000
+ S_IFDIR = 0x4000
+ S_IFBLK = 0x6000
+ S_IFREG = 0x8000
+ S_IFLNK = 0xa000
+ S_IFSOCK = 0xc000
+)
+
+// Errors
+var (
+ EINVAL = syscall.NewError("bad arg in system call")
+ ENOTDIR = syscall.NewError("not a directory")
+ EISDIR = syscall.NewError("file is a directory")
+ ENOENT = syscall.NewError("file does not exist")
+ EEXIST = syscall.NewError("file already exists")
+ EMFILE = syscall.NewError("no free file descriptors")
+ EIO = syscall.NewError("i/o error")
+ ENAMETOOLONG = syscall.NewError("file name too long")
+ EINTR = syscall.NewError("interrupted")
+ EPERM = syscall.NewError("permission denied")
+ EBUSY = syscall.NewError("no free devices")
+ ETIMEDOUT = syscall.NewError("connection timed out")
+ EPLAN9 = syscall.NewError("not supported by plan 9")
+
+ // The following errors do not correspond to any
+ // Plan 9 system messages. Invented to support
+ // what package os and others expect.
+ EACCES = syscall.NewError("access permission denied")
+ EAFNOSUPPORT = syscall.NewError("address family not supported by protocol")
+)
diff --git a/vendor/golang.org/x/sys/plan9/mkall.sh b/vendor/golang.org/x/sys/plan9/mkall.sh
new file mode 100755
index 00000000..9f73c606
--- /dev/null
+++ b/vendor/golang.org/x/sys/plan9/mkall.sh
@@ -0,0 +1,138 @@
+#!/usr/bin/env bash
+# Copyright 2009 The Go Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
+
+# The plan9 package provides access to the raw system call
+# interface of the underlying operating system. Porting Go to
+# a new architecture/operating system combination requires
+# some manual effort, though there are tools that automate
+# much of the process. The auto-generated files have names
+# beginning with z.
+#
+# This script runs or (given -n) prints suggested commands to generate z files
+# for the current system. Running those commands is not automatic.
+# This script is documentation more than anything else.
+#
+# * asm_${GOOS}_${GOARCH}.s
+#
+# This hand-written assembly file implements system call dispatch.
+# There are three entry points:
+#
+# func Syscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr);
+# func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr);
+# func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr);
+#
+# The first and second are the standard ones; they differ only in
+# how many arguments can be passed to the kernel.
+# The third is for low-level use by the ForkExec wrapper;
+# unlike the first two, it does not call into the scheduler to
+# let it know that a system call is running.
+#
+# * syscall_${GOOS}.go
+#
+# This hand-written Go file implements system calls that need
+# special handling and lists "//sys" comments giving prototypes
+# for ones that can be auto-generated. Mksyscall reads those
+# comments to generate the stubs.
+#
+# * syscall_${GOOS}_${GOARCH}.go
+#
+# Same as syscall_${GOOS}.go except that it contains code specific
+# to ${GOOS} on one particular architecture.
+#
+# * types_${GOOS}.c
+#
+# This hand-written C file includes standard C headers and then
+# creates typedef or enum names beginning with a dollar sign
+# (use of $ in variable names is a gcc extension). The hardest
+# part about preparing this file is figuring out which headers to
+# include and which symbols need to be #defined to get the
+# actual data structures that pass through to the kernel system calls.
+# Some C libraries present alternate versions for binary compatibility
+# and translate them on the way in and out of system calls, but
+# there is almost always a #define that can get the real ones.
+# See types_darwin.c and types_linux.c for examples.
+#
+# * zerror_${GOOS}_${GOARCH}.go
+#
+# This machine-generated file defines the system's error numbers,
+# error strings, and signal numbers. The generator is "mkerrors.sh".
+# Usually no arguments are needed, but mkerrors.sh will pass its
+# arguments on to godefs.
+#
+# * zsyscall_${GOOS}_${GOARCH}.go
+#
+# Generated by mksyscall.pl; see syscall_${GOOS}.go above.
+#
+# * zsysnum_${GOOS}_${GOARCH}.go
+#
+# Generated by mksysnum_${GOOS}.
+#
+# * ztypes_${GOOS}_${GOARCH}.go
+#
+# Generated by godefs; see types_${GOOS}.c above.
+
+GOOSARCH="${GOOS}_${GOARCH}"
+
+# defaults
+mksyscall="./mksyscall.pl"
+mkerrors="./mkerrors.sh"
+zerrors="zerrors_$GOOSARCH.go"
+mksysctl=""
+zsysctl="zsysctl_$GOOSARCH.go"
+mksysnum=
+mktypes=
+run="sh"
+
+case "$1" in
+-syscalls)
+ for i in zsyscall*go
+ do
+ sed 1q $i | sed 's;^// ;;' | sh > _$i && gofmt < _$i > $i
+ rm _$i
+ done
+ exit 0
+ ;;
+-n)
+ run="cat"
+ shift
+esac
+
+case "$#" in
+0)
+ ;;
+*)
+ echo 'usage: mkall.sh [-n]' 1>&2
+ exit 2
+esac
+
+case "$GOOSARCH" in
+_* | *_ | _)
+ echo 'undefined $GOOS_$GOARCH:' "$GOOSARCH" 1>&2
+ exit 1
+ ;;
+plan9_386)
+ mkerrors=
+ mksyscall="./mksyscall.pl -l32 -plan9"
+ mksysnum="./mksysnum_plan9.sh /n/sources/plan9/sys/src/libc/9syscall/sys.h"
+ mktypes="XXX"
+ ;;
+*)
+ echo 'unrecognized $GOOS_$GOARCH: ' "$GOOSARCH" 1>&2
+ exit 1
+ ;;
+esac
+
+(
+ if [ -n "$mkerrors" ]; then echo "$mkerrors |gofmt >$zerrors"; fi
+ case "$GOOS" in
+ plan9)
+ syscall_goos="syscall_$GOOS.go"
+ if [ -n "$mksyscall" ]; then echo "$mksyscall $syscall_goos syscall_$GOOSARCH.go |gofmt >zsyscall_$GOOSARCH.go"; fi
+ ;;
+ esac
+ if [ -n "$mksysctl" ]; then echo "$mksysctl |gofmt >$zsysctl"; fi
+ if [ -n "$mksysnum" ]; then echo "$mksysnum |gofmt >zsysnum_$GOOSARCH.go"; fi
+ if [ -n "$mktypes" ]; then echo "$mktypes types_$GOOS.go |gofmt >ztypes_$GOOSARCH.go"; fi
+) | $run
diff --git a/vendor/golang.org/x/sys/plan9/mkerrors.sh b/vendor/golang.org/x/sys/plan9/mkerrors.sh
new file mode 100755
index 00000000..052c86d9
--- /dev/null
+++ b/vendor/golang.org/x/sys/plan9/mkerrors.sh
@@ -0,0 +1,246 @@
+#!/usr/bin/env bash
+# Copyright 2009 The Go Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
+
+# Generate Go code listing errors and other #defined constant
+# values (ENAMETOOLONG etc.), by asking the preprocessor
+# about the definitions.
+
+unset LANG
+export LC_ALL=C
+export LC_CTYPE=C
+
+CC=${CC:-gcc}
+
+uname=$(uname)
+
+includes='
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+'
+
+ccflags="$@"
+
+# Write go tool cgo -godefs input.
+(
+ echo package plan9
+ echo
+ echo '/*'
+ indirect="includes_$(uname)"
+ echo "${!indirect} $includes"
+ echo '*/'
+ echo 'import "C"'
+ echo
+ echo 'const ('
+
+ # The gcc command line prints all the #defines
+ # it encounters while processing the input
+ echo "${!indirect} $includes" | $CC -x c - -E -dM $ccflags |
+ awk '
+ $1 != "#define" || $2 ~ /\(/ || $3 == "" {next}
+
+ $2 ~ /^E([ABCD]X|[BIS]P|[SD]I|S|FL)$/ {next} # 386 registers
+ $2 ~ /^(SIGEV_|SIGSTKSZ|SIGRT(MIN|MAX))/ {next}
+ $2 ~ /^(SCM_SRCRT)$/ {next}
+ $2 ~ /^(MAP_FAILED)$/ {next}
+
+ $2 !~ /^ETH_/ &&
+ $2 !~ /^EPROC_/ &&
+ $2 !~ /^EQUIV_/ &&
+ $2 !~ /^EXPR_/ &&
+ $2 ~ /^E[A-Z0-9_]+$/ ||
+ $2 ~ /^B[0-9_]+$/ ||
+ $2 ~ /^V[A-Z0-9]+$/ ||
+ $2 ~ /^CS[A-Z0-9]/ ||
+ $2 ~ /^I(SIG|CANON|CRNL|EXTEN|MAXBEL|STRIP|UTF8)$/ ||
+ $2 ~ /^IGN/ ||
+ $2 ~ /^IX(ON|ANY|OFF)$/ ||
+ $2 ~ /^IN(LCR|PCK)$/ ||
+ $2 ~ /(^FLU?SH)|(FLU?SH$)/ ||
+ $2 ~ /^C(LOCAL|READ)$/ ||
+ $2 == "BRKINT" ||
+ $2 == "HUPCL" ||
+ $2 == "PENDIN" ||
+ $2 == "TOSTOP" ||
+ $2 ~ /^PAR/ ||
+ $2 ~ /^SIG[^_]/ ||
+ $2 ~ /^O[CNPFP][A-Z]+[^_][A-Z]+$/ ||
+ $2 ~ /^IN_/ ||
+ $2 ~ /^LOCK_(SH|EX|NB|UN)$/ ||
+ $2 ~ /^(AF|SOCK|SO|SOL|IPPROTO|IP|IPV6|ICMP6|TCP|EVFILT|NOTE|EV|SHUT|PROT|MAP|PACKET|MSG|SCM|MCL|DT|MADV|PR)_/ ||
+ $2 == "ICMPV6_FILTER" ||
+ $2 == "SOMAXCONN" ||
+ $2 == "NAME_MAX" ||
+ $2 == "IFNAMSIZ" ||
+ $2 ~ /^CTL_(MAXNAME|NET|QUERY)$/ ||
+ $2 ~ /^SYSCTL_VERS/ ||
+ $2 ~ /^(MS|MNT)_/ ||
+ $2 ~ /^TUN(SET|GET|ATTACH|DETACH)/ ||
+ $2 ~ /^(O|F|FD|NAME|S|PTRACE|PT)_/ ||
+ $2 ~ /^LINUX_REBOOT_CMD_/ ||
+ $2 ~ /^LINUX_REBOOT_MAGIC[12]$/ ||
+ $2 !~ "NLA_TYPE_MASK" &&
+ $2 ~ /^(NETLINK|NLM|NLMSG|NLA|IFA|IFAN|RT|RTCF|RTN|RTPROT|RTNH|ARPHRD|ETH_P)_/ ||
+ $2 ~ /^SIOC/ ||
+ $2 ~ /^TIOC/ ||
+ $2 !~ "RTF_BITS" &&
+ $2 ~ /^(IFF|IFT|NET_RT|RTM|RTF|RTV|RTA|RTAX)_/ ||
+ $2 ~ /^BIOC/ ||
+ $2 ~ /^RUSAGE_(SELF|CHILDREN|THREAD)/ ||
+ $2 ~ /^RLIMIT_(AS|CORE|CPU|DATA|FSIZE|NOFILE|STACK)|RLIM_INFINITY/ ||
+ $2 ~ /^PRIO_(PROCESS|PGRP|USER)/ ||
+ $2 ~ /^CLONE_[A-Z_]+/ ||
+ $2 !~ /^(BPF_TIMEVAL)$/ &&
+ $2 ~ /^(BPF|DLT)_/ ||
+ $2 !~ "WMESGLEN" &&
+ $2 ~ /^W[A-Z0-9]+$/ {printf("\t%s = C.%s\n", $2, $2)}
+ $2 ~ /^__WCOREFLAG$/ {next}
+ $2 ~ /^__W[A-Z0-9]+$/ {printf("\t%s = C.%s\n", substr($2,3), $2)}
+
+ {next}
+ ' | sort
+
+ echo ')'
+) >_const.go
+
+# Pull out the error names for later.
+errors=$(
+ echo '#include ' | $CC -x c - -E -dM $ccflags |
+ awk '$1=="#define" && $2 ~ /^E[A-Z0-9_]+$/ { print $2 }' |
+ sort
+)
+
+# Pull out the signal names for later.
+signals=$(
+ echo '#include ' | $CC -x c - -E -dM $ccflags |
+ awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print $2 }' |
+ egrep -v '(SIGSTKSIZE|SIGSTKSZ|SIGRT)' |
+ sort
+)
+
+# Again, writing regexps to a file.
+echo '#include ' | $CC -x c - -E -dM $ccflags |
+ awk '$1=="#define" && $2 ~ /^E[A-Z0-9_]+$/ { print "^\t" $2 "[ \t]*=" }' |
+ sort >_error.grep
+echo '#include ' | $CC -x c - -E -dM $ccflags |
+ awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print "^\t" $2 "[ \t]*=" }' |
+ egrep -v '(SIGSTKSIZE|SIGSTKSZ|SIGRT)' |
+ sort >_signal.grep
+
+echo '// mkerrors.sh' "$@"
+echo '// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT'
+echo
+go tool cgo -godefs -- "$@" _const.go >_error.out
+cat _error.out | grep -vf _error.grep | grep -vf _signal.grep
+echo
+echo '// Errors'
+echo 'const ('
+cat _error.out | grep -f _error.grep | sed 's/=\(.*\)/= Errno(\1)/'
+echo ')'
+
+echo
+echo '// Signals'
+echo 'const ('
+cat _error.out | grep -f _signal.grep | sed 's/=\(.*\)/= Signal(\1)/'
+echo ')'
+
+# Run C program to print error and syscall strings.
+(
+ echo -E "
+#include
+#include
+#include
+#include
+#include
+#include
+
+#define nelem(x) (sizeof(x)/sizeof((x)[0]))
+
+enum { A = 'A', Z = 'Z', a = 'a', z = 'z' }; // avoid need for single quotes below
+
+int errors[] = {
+"
+ for i in $errors
+ do
+ echo -E ' '$i,
+ done
+
+ echo -E "
+};
+
+int signals[] = {
+"
+ for i in $signals
+ do
+ echo -E ' '$i,
+ done
+
+ # Use -E because on some systems bash builtin interprets \n itself.
+ echo -E '
+};
+
+static int
+intcmp(const void *a, const void *b)
+{
+ return *(int*)a - *(int*)b;
+}
+
+int
+main(void)
+{
+ int i, j, e;
+ char buf[1024], *p;
+
+ printf("\n\n// Error table\n");
+ printf("var errors = [...]string {\n");
+ qsort(errors, nelem(errors), sizeof errors[0], intcmp);
+ for(i=0; i 0 && errors[i-1] == e)
+ continue;
+ strcpy(buf, strerror(e));
+ // lowercase first letter: Bad -> bad, but STREAM -> STREAM.
+ if(A <= buf[0] && buf[0] <= Z && a <= buf[1] && buf[1] <= z)
+ buf[0] += a - A;
+ printf("\t%d: \"%s\",\n", e, buf);
+ }
+ printf("}\n\n");
+
+ printf("\n\n// Signal table\n");
+ printf("var signals = [...]string {\n");
+ qsort(signals, nelem(signals), sizeof signals[0], intcmp);
+ for(i=0; i 0 && signals[i-1] == e)
+ continue;
+ strcpy(buf, strsignal(e));
+ // lowercase first letter: Bad -> bad, but STREAM -> STREAM.
+ if(A <= buf[0] && buf[0] <= Z && a <= buf[1] && buf[1] <= z)
+ buf[0] += a - A;
+ // cut trailing : number.
+ p = strrchr(buf, ":"[0]);
+ if(p)
+ *p = '\0';
+ printf("\t%d: \"%s\",\n", e, buf);
+ }
+ printf("}\n\n");
+
+ return 0;
+}
+
+'
+) >_errors.c
+
+$CC $ccflags -o _errors _errors.c && $GORUN ./_errors && rm -f _errors.c _errors _const.go _error.grep _signal.grep _error.out
diff --git a/vendor/golang.org/x/sys/plan9/mksyscall.pl b/vendor/golang.org/x/sys/plan9/mksyscall.pl
new file mode 100755
index 00000000..ce8e1e4f
--- /dev/null
+++ b/vendor/golang.org/x/sys/plan9/mksyscall.pl
@@ -0,0 +1,319 @@
+#!/usr/bin/env perl
+# Copyright 2009 The Go Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
+
+# This program reads a file containing function prototypes
+# (like syscall_plan9.go) and generates system call bodies.
+# The prototypes are marked by lines beginning with "//sys"
+# and read like func declarations if //sys is replaced by func, but:
+# * The parameter lists must give a name for each argument.
+# This includes return parameters.
+# * The parameter lists must give a type for each argument:
+# the (x, y, z int) shorthand is not allowed.
+# * If the return parameter is an error number, it must be named errno.
+
+# A line beginning with //sysnb is like //sys, except that the
+# goroutine will not be suspended during the execution of the system
+# call. This must only be used for system calls which can never
+# block, as otherwise the system call could cause all goroutines to
+# hang.
+
+use strict;
+
+my $cmdline = "mksyscall.pl " . join(' ', @ARGV);
+my $errors = 0;
+my $_32bit = "";
+my $plan9 = 0;
+my $openbsd = 0;
+my $netbsd = 0;
+my $dragonfly = 0;
+my $nacl = 0;
+my $arm = 0; # 64-bit value should use (even, odd)-pair
+
+if($ARGV[0] eq "-b32") {
+ $_32bit = "big-endian";
+ shift;
+} elsif($ARGV[0] eq "-l32") {
+ $_32bit = "little-endian";
+ shift;
+}
+if($ARGV[0] eq "-plan9") {
+ $plan9 = 1;
+ shift;
+}
+if($ARGV[0] eq "-openbsd") {
+ $openbsd = 1;
+ shift;
+}
+if($ARGV[0] eq "-netbsd") {
+ $netbsd = 1;
+ shift;
+}
+if($ARGV[0] eq "-dragonfly") {
+ $dragonfly = 1;
+ shift;
+}
+if($ARGV[0] eq "-nacl") {
+ $nacl = 1;
+ shift;
+}
+if($ARGV[0] eq "-arm") {
+ $arm = 1;
+ shift;
+}
+
+if($ARGV[0] =~ /^-/) {
+ print STDERR "usage: mksyscall.pl [-b32 | -l32] [file ...]\n";
+ exit 1;
+}
+
+sub parseparamlist($) {
+ my ($list) = @_;
+ $list =~ s/^\s*//;
+ $list =~ s/\s*$//;
+ if($list eq "") {
+ return ();
+ }
+ return split(/\s*,\s*/, $list);
+}
+
+sub parseparam($) {
+ my ($p) = @_;
+ if($p !~ /^(\S*) (\S*)$/) {
+ print STDERR "$ARGV:$.: malformed parameter: $p\n";
+ $errors = 1;
+ return ("xx", "int");
+ }
+ return ($1, $2);
+}
+
+my $text = "";
+while(<>) {
+ chomp;
+ s/\s+/ /g;
+ s/^\s+//;
+ s/\s+$//;
+ my $nonblock = /^\/\/sysnb /;
+ next if !/^\/\/sys / && !$nonblock;
+
+ # Line must be of the form
+ # func Open(path string, mode int, perm int) (fd int, errno error)
+ # Split into name, in params, out params.
+ if(!/^\/\/sys(nb)? (\w+)\(([^()]*)\)\s*(?:\(([^()]+)\))?\s*(?:=\s*((?i)SYS_[A-Z0-9_]+))?$/) {
+ print STDERR "$ARGV:$.: malformed //sys declaration\n";
+ $errors = 1;
+ next;
+ }
+ my ($func, $in, $out, $sysname) = ($2, $3, $4, $5);
+
+ # Split argument lists on comma.
+ my @in = parseparamlist($in);
+ my @out = parseparamlist($out);
+
+ # Try in vain to keep people from editing this file.
+ # The theory is that they jump into the middle of the file
+ # without reading the header.
+ $text .= "// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\n";
+
+ # Go function header.
+ my $out_decl = @out ? sprintf(" (%s)", join(', ', @out)) : "";
+ $text .= sprintf "func %s(%s)%s {\n", $func, join(', ', @in), $out_decl;
+
+ # Check if err return available
+ my $errvar = "";
+ foreach my $p (@out) {
+ my ($name, $type) = parseparam($p);
+ if($type eq "error") {
+ $errvar = $name;
+ last;
+ }
+ }
+
+ # Prepare arguments to Syscall.
+ my @args = ();
+ my @uses = ();
+ my $n = 0;
+ foreach my $p (@in) {
+ my ($name, $type) = parseparam($p);
+ if($type =~ /^\*/) {
+ push @args, "uintptr(unsafe.Pointer($name))";
+ } elsif($type eq "string" && $errvar ne "") {
+ $text .= "\tvar _p$n *byte\n";
+ $text .= "\t_p$n, $errvar = BytePtrFromString($name)\n";
+ $text .= "\tif $errvar != nil {\n\t\treturn\n\t}\n";
+ push @args, "uintptr(unsafe.Pointer(_p$n))";
+ push @uses, "use(unsafe.Pointer(_p$n))";
+ $n++;
+ } elsif($type eq "string") {
+ print STDERR "$ARGV:$.: $func uses string arguments, but has no error return\n";
+ $text .= "\tvar _p$n *byte\n";
+ $text .= "\t_p$n, _ = BytePtrFromString($name)\n";
+ push @args, "uintptr(unsafe.Pointer(_p$n))";
+ push @uses, "use(unsafe.Pointer(_p$n))";
+ $n++;
+ } elsif($type =~ /^\[\](.*)/) {
+ # Convert slice into pointer, length.
+ # Have to be careful not to take address of &a[0] if len == 0:
+ # pass dummy pointer in that case.
+ # Used to pass nil, but some OSes or simulators reject write(fd, nil, 0).
+ $text .= "\tvar _p$n unsafe.Pointer\n";
+ $text .= "\tif len($name) > 0 {\n\t\t_p$n = unsafe.Pointer(\&${name}[0])\n\t}";
+ $text .= " else {\n\t\t_p$n = unsafe.Pointer(&_zero)\n\t}";
+ $text .= "\n";
+ push @args, "uintptr(_p$n)", "uintptr(len($name))";
+ $n++;
+ } elsif($type eq "int64" && ($openbsd || $netbsd)) {
+ push @args, "0";
+ if($_32bit eq "big-endian") {
+ push @args, "uintptr($name>>32)", "uintptr($name)";
+ } elsif($_32bit eq "little-endian") {
+ push @args, "uintptr($name)", "uintptr($name>>32)";
+ } else {
+ push @args, "uintptr($name)";
+ }
+ } elsif($type eq "int64" && $dragonfly) {
+ if ($func !~ /^extp(read|write)/i) {
+ push @args, "0";
+ }
+ if($_32bit eq "big-endian") {
+ push @args, "uintptr($name>>32)", "uintptr($name)";
+ } elsif($_32bit eq "little-endian") {
+ push @args, "uintptr($name)", "uintptr($name>>32)";
+ } else {
+ push @args, "uintptr($name)";
+ }
+ } elsif($type eq "int64" && $_32bit ne "") {
+ if(@args % 2 && $arm) {
+ # arm abi specifies 64-bit argument uses
+ # (even, odd) pair
+ push @args, "0"
+ }
+ if($_32bit eq "big-endian") {
+ push @args, "uintptr($name>>32)", "uintptr($name)";
+ } else {
+ push @args, "uintptr($name)", "uintptr($name>>32)";
+ }
+ } else {
+ push @args, "uintptr($name)";
+ }
+ }
+
+ # Determine which form to use; pad args with zeros.
+ my $asm = "Syscall";
+ if ($nonblock) {
+ $asm = "RawSyscall";
+ }
+ if(@args <= 3) {
+ while(@args < 3) {
+ push @args, "0";
+ }
+ } elsif(@args <= 6) {
+ $asm .= "6";
+ while(@args < 6) {
+ push @args, "0";
+ }
+ } elsif(@args <= 9) {
+ $asm .= "9";
+ while(@args < 9) {
+ push @args, "0";
+ }
+ } else {
+ print STDERR "$ARGV:$.: too many arguments to system call\n";
+ }
+
+ # System call number.
+ if($sysname eq "") {
+ $sysname = "SYS_$func";
+ $sysname =~ s/([a-z])([A-Z])/${1}_$2/g; # turn FooBar into Foo_Bar
+ $sysname =~ y/a-z/A-Z/;
+ if($nacl) {
+ $sysname =~ y/A-Z/a-z/;
+ }
+ }
+
+ # Actual call.
+ my $args = join(', ', @args);
+ my $call = "$asm($sysname, $args)";
+
+ # Assign return values.
+ my $body = "";
+ my @ret = ("_", "_", "_");
+ my $do_errno = 0;
+ for(my $i=0; $i<@out; $i++) {
+ my $p = $out[$i];
+ my ($name, $type) = parseparam($p);
+ my $reg = "";
+ if($name eq "err" && !$plan9) {
+ $reg = "e1";
+ $ret[2] = $reg;
+ $do_errno = 1;
+ } elsif($name eq "err" && $plan9) {
+ $ret[0] = "r0";
+ $ret[2] = "e1";
+ next;
+ } else {
+ $reg = sprintf("r%d", $i);
+ $ret[$i] = $reg;
+ }
+ if($type eq "bool") {
+ $reg = "$reg != 0";
+ }
+ if($type eq "int64" && $_32bit ne "") {
+ # 64-bit number in r1:r0 or r0:r1.
+ if($i+2 > @out) {
+ print STDERR "$ARGV:$.: not enough registers for int64 return\n";
+ }
+ if($_32bit eq "big-endian") {
+ $reg = sprintf("int64(r%d)<<32 | int64(r%d)", $i, $i+1);
+ } else {
+ $reg = sprintf("int64(r%d)<<32 | int64(r%d)", $i+1, $i);
+ }
+ $ret[$i] = sprintf("r%d", $i);
+ $ret[$i+1] = sprintf("r%d", $i+1);
+ }
+ if($reg ne "e1" || $plan9) {
+ $body .= "\t$name = $type($reg)\n";
+ }
+ }
+ if ($ret[0] eq "_" && $ret[1] eq "_" && $ret[2] eq "_") {
+ $text .= "\t$call\n";
+ } else {
+ $text .= "\t$ret[0], $ret[1], $ret[2] := $call\n";
+ }
+ foreach my $use (@uses) {
+ $text .= "\t$use\n";
+ }
+ $text .= $body;
+
+ if ($plan9 && $ret[2] eq "e1") {
+ $text .= "\tif int32(r0) == -1 {\n";
+ $text .= "\t\terr = e1\n";
+ $text .= "\t}\n";
+ } elsif ($do_errno) {
+ $text .= "\tif e1 != 0 {\n";
+ $text .= "\t\terr = e1\n";
+ $text .= "\t}\n";
+ }
+ $text .= "\treturn\n";
+ $text .= "}\n\n";
+}
+
+chomp $text;
+chomp $text;
+
+if($errors) {
+ exit 1;
+}
+
+print <= 10 {
+ buf[i] = byte(val%10 + '0')
+ i--
+ val /= 10
+ }
+ buf[i] = byte(val + '0')
+ return string(buf[i:])
+}
diff --git a/vendor/golang.org/x/sys/plan9/syscall.go b/vendor/golang.org/x/sys/plan9/syscall.go
new file mode 100644
index 00000000..df6f8c5b
--- /dev/null
+++ b/vendor/golang.org/x/sys/plan9/syscall.go
@@ -0,0 +1,74 @@
+// 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 plan9
+
+// Package plan9 contains an interface to the low-level operating system
+// primitives. OS details vary depending on the underlying system, and
+// by default, godoc will display the OS-specific documentation for the current
+// system. If you want godoc to display documentation for another
+// system, set $GOOS and $GOARCH to the desired system. For example, if
+// you want to view documentation for freebsd/arm on linux/amd64, set $GOOS
+// to freebsd and $GOARCH to arm.
+// The primary use of this package is inside other packages that provide a more
+// portable interface to the system, such as "os", "time" and "net". Use
+// those packages rather than this one if you can.
+// For details of the functions and data types in this package consult
+// the manuals for the appropriate operating system.
+// These calls return err == nil to indicate success; otherwise
+// err represents an operating system error describing the failure and
+// holds a value of type syscall.ErrorString.
+package plan9 // import "golang.org/x/sys/plan9"
+
+import "unsafe"
+
+// ByteSliceFromString returns a NUL-terminated slice of bytes
+// containing the text of s. If s contains a NUL byte at any
+// location, it returns (nil, EINVAL).
+func ByteSliceFromString(s string) ([]byte, error) {
+ for i := 0; i < len(s); i++ {
+ if s[i] == 0 {
+ return nil, EINVAL
+ }
+ }
+ a := make([]byte, len(s)+1)
+ copy(a, s)
+ return a, nil
+}
+
+// BytePtrFromString returns a pointer to a NUL-terminated array of
+// bytes containing the text of s. If s contains a NUL byte at any
+// location, it returns (nil, EINVAL).
+func BytePtrFromString(s string) (*byte, error) {
+ a, err := ByteSliceFromString(s)
+ if err != nil {
+ return nil, err
+ }
+ return &a[0], nil
+}
+
+// Single-word zero for use when we need a valid pointer to 0 bytes.
+// See mksyscall.pl.
+var _zero uintptr
+
+func (ts *Timespec) Unix() (sec int64, nsec int64) {
+ return int64(ts.Sec), int64(ts.Nsec)
+}
+
+func (tv *Timeval) Unix() (sec int64, nsec int64) {
+ return int64(tv.Sec), int64(tv.Usec) * 1000
+}
+
+func (ts *Timespec) Nano() int64 {
+ return int64(ts.Sec)*1e9 + int64(ts.Nsec)
+}
+
+func (tv *Timeval) Nano() int64 {
+ return int64(tv.Sec)*1e9 + int64(tv.Usec)*1000
+}
+
+// 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.
+//go:noescape
+func use(p unsafe.Pointer)
diff --git a/vendor/golang.org/x/sys/plan9/syscall_plan9.go b/vendor/golang.org/x/sys/plan9/syscall_plan9.go
new file mode 100644
index 00000000..d39d07de
--- /dev/null
+++ b/vendor/golang.org/x/sys/plan9/syscall_plan9.go
@@ -0,0 +1,349 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Plan 9 system calls.
+// This file is compiled as ordinary Go code,
+// but it is also input to mksyscall,
+// which parses the //sys lines and generates system call stubs.
+// Note that sometimes we use a lowercase //sys name and
+// wrap it in our own nicer implementation.
+
+package plan9
+
+import (
+ "syscall"
+ "unsafe"
+)
+
+// A Note is a string describing a process note.
+// It implements the os.Signal interface.
+type Note string
+
+func (n Note) Signal() {}
+
+func (n Note) String() string {
+ return string(n)
+}
+
+var (
+ Stdin = 0
+ Stdout = 1
+ Stderr = 2
+)
+
+// For testing: clients can set this flag to force
+// creation of IPv6 sockets to return EAFNOSUPPORT.
+var SocketDisableIPv6 bool
+
+func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.ErrorString)
+func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.ErrorString)
+func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr)
+func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr)
+
+func atoi(b []byte) (n uint) {
+ n = 0
+ for i := 0; i < len(b); i++ {
+ n = n*10 + uint(b[i]-'0')
+ }
+ return
+}
+
+func cstring(s []byte) string {
+ for i := range s {
+ if s[i] == 0 {
+ return string(s[0:i])
+ }
+ }
+ return string(s)
+}
+
+func errstr() string {
+ var buf [ERRMAX]byte
+
+ RawSyscall(SYS_ERRSTR, uintptr(unsafe.Pointer(&buf[0])), uintptr(len(buf)), 0)
+
+ buf[len(buf)-1] = 0
+ return cstring(buf[:])
+}
+
+// Implemented in assembly to import from runtime.
+func exit(code int)
+
+func Exit(code int) { exit(code) }
+
+func readnum(path string) (uint, error) {
+ var b [12]byte
+
+ fd, e := Open(path, O_RDONLY)
+ if e != nil {
+ return 0, e
+ }
+ defer Close(fd)
+
+ n, e := Pread(fd, b[:], 0)
+
+ if e != nil {
+ return 0, e
+ }
+
+ m := 0
+ for ; m < n && b[m] == ' '; m++ {
+ }
+
+ return atoi(b[m : n-1]), nil
+}
+
+func Getpid() (pid int) {
+ n, _ := readnum("#c/pid")
+ return int(n)
+}
+
+func Getppid() (ppid int) {
+ n, _ := readnum("#c/ppid")
+ return int(n)
+}
+
+func Read(fd int, p []byte) (n int, err error) {
+ return Pread(fd, p, -1)
+}
+
+func Write(fd int, p []byte) (n int, err error) {
+ return Pwrite(fd, p, -1)
+}
+
+var ioSync int64
+
+//sys fd2path(fd int, buf []byte) (err error)
+func Fd2path(fd int) (path string, err error) {
+ var buf [512]byte
+
+ e := fd2path(fd, buf[:])
+ if e != nil {
+ return "", e
+ }
+ return cstring(buf[:]), nil
+}
+
+//sys pipe(p *[2]int32) (err error)
+func Pipe(p []int) (err error) {
+ if len(p) != 2 {
+ return syscall.ErrorString("bad arg in system call")
+ }
+ var pp [2]int32
+ err = pipe(&pp)
+ p[0] = int(pp[0])
+ p[1] = int(pp[1])
+ return
+}
+
+// Underlying system call writes to newoffset via pointer.
+// Implemented in assembly to avoid allocation.
+func seek(placeholder uintptr, fd int, offset int64, whence int) (newoffset int64, err string)
+
+func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
+ newoffset, e := seek(0, fd, offset, whence)
+
+ if newoffset == -1 {
+ err = syscall.ErrorString(e)
+ }
+ return
+}
+
+func Mkdir(path string, mode uint32) (err error) {
+ fd, err := Create(path, O_RDONLY, DMDIR|mode)
+
+ if fd != -1 {
+ Close(fd)
+ }
+
+ return
+}
+
+type Waitmsg struct {
+ Pid int
+ Time [3]uint32
+ Msg string
+}
+
+func (w Waitmsg) Exited() bool { return true }
+func (w Waitmsg) Signaled() bool { return false }
+
+func (w Waitmsg) ExitStatus() int {
+ if len(w.Msg) == 0 {
+ // a normal exit returns no message
+ return 0
+ }
+ return 1
+}
+
+//sys await(s []byte) (n int, err error)
+func Await(w *Waitmsg) (err error) {
+ var buf [512]byte
+ var f [5][]byte
+
+ n, err := await(buf[:])
+
+ if err != nil || w == nil {
+ return
+ }
+
+ nf := 0
+ p := 0
+ for i := 0; i < n && nf < len(f)-1; i++ {
+ if buf[i] == ' ' {
+ f[nf] = buf[p:i]
+ p = i + 1
+ nf++
+ }
+ }
+ f[nf] = buf[p:]
+ nf++
+
+ if nf != len(f) {
+ return syscall.ErrorString("invalid wait message")
+ }
+ w.Pid = int(atoi(f[0]))
+ w.Time[0] = uint32(atoi(f[1]))
+ w.Time[1] = uint32(atoi(f[2]))
+ w.Time[2] = uint32(atoi(f[3]))
+ w.Msg = cstring(f[4])
+ if w.Msg == "''" {
+ // await() returns '' for no error
+ w.Msg = ""
+ }
+ return
+}
+
+func Unmount(name, old string) (err error) {
+ fixwd()
+ oldp, err := BytePtrFromString(old)
+ if err != nil {
+ return err
+ }
+ oldptr := uintptr(unsafe.Pointer(oldp))
+
+ var r0 uintptr
+ var e syscall.ErrorString
+
+ // bind(2) man page: If name is zero, everything bound or mounted upon old is unbound or unmounted.
+ if name == "" {
+ r0, _, e = Syscall(SYS_UNMOUNT, _zero, oldptr, 0)
+ } else {
+ namep, err := BytePtrFromString(name)
+ if err != nil {
+ return err
+ }
+ r0, _, e = Syscall(SYS_UNMOUNT, uintptr(unsafe.Pointer(namep)), oldptr, 0)
+ }
+
+ if int32(r0) == -1 {
+ err = e
+ }
+ return
+}
+
+func Fchdir(fd int) (err error) {
+ path, err := Fd2path(fd)
+
+ if err != nil {
+ return
+ }
+
+ return Chdir(path)
+}
+
+type Timespec struct {
+ Sec int32
+ Nsec int32
+}
+
+type Timeval struct {
+ Sec int32
+ Usec int32
+}
+
+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 nsec() int64 {
+ var scratch int64
+
+ r0, _, _ := Syscall(SYS_NSEC, uintptr(unsafe.Pointer(&scratch)), 0, 0)
+ // TODO(aram): remove hack after I fix _nsec in the pc64 kernel.
+ if r0 == 0 {
+ return scratch
+ }
+ return int64(r0)
+}
+
+func Gettimeofday(tv *Timeval) error {
+ nsec := nsec()
+ *tv = NsecToTimeval(nsec)
+ return nil
+}
+
+func Getpagesize() int { return 0x1000 }
+
+func Getegid() (egid int) { return -1 }
+func Geteuid() (euid int) { return -1 }
+func Getgid() (gid int) { return -1 }
+func Getuid() (uid int) { return -1 }
+
+func Getgroups() (gids []int, err error) {
+ return make([]int, 0), nil
+}
+
+//sys open(path string, mode int) (fd int, err error)
+func Open(path string, mode int) (fd int, err error) {
+ fixwd()
+ return open(path, mode)
+}
+
+//sys create(path string, mode int, perm uint32) (fd int, err error)
+func Create(path string, mode int, perm uint32) (fd int, err error) {
+ fixwd()
+ return create(path, mode, perm)
+}
+
+//sys remove(path string) (err error)
+func Remove(path string) error {
+ fixwd()
+ return remove(path)
+}
+
+//sys stat(path string, edir []byte) (n int, err error)
+func Stat(path string, edir []byte) (n int, err error) {
+ fixwd()
+ return stat(path, edir)
+}
+
+//sys bind(name string, old string, flag int) (err error)
+func Bind(name string, old string, flag int) (err error) {
+ fixwd()
+ return bind(name, old, flag)
+}
+
+//sys mount(fd int, afd int, old string, flag int, aname string) (err error)
+func Mount(fd int, afd int, old string, flag int, aname string) (err error) {
+ fixwd()
+ return mount(fd, afd, old, flag, aname)
+}
+
+//sys wstat(path string, edir []byte) (err error)
+func Wstat(path string, edir []byte) (err error) {
+ fixwd()
+ return wstat(path, edir)
+}
+
+//sys chdir(path string) (err error)
+//sys Dup(oldfd int, newfd int) (fd int, err error)
+//sys Pread(fd int, p []byte, offset int64) (n int, err error)
+//sys Pwrite(fd int, p []byte, offset int64) (n int, err error)
+//sys Close(fd int) (err error)
+//sys Fstat(fd int, edir []byte) (n int, err error)
+//sys Fwstat(fd int, edir []byte) (err error)
diff --git a/vendor/golang.org/x/sys/plan9/syscall_test.go b/vendor/golang.org/x/sys/plan9/syscall_test.go
new file mode 100644
index 00000000..8f829bad
--- /dev/null
+++ b/vendor/golang.org/x/sys/plan9/syscall_test.go
@@ -0,0 +1,33 @@
+// Copyright 2013 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 plan9
+
+package plan9_test
+
+import (
+ "testing"
+
+ "golang.org/x/sys/plan9"
+)
+
+func testSetGetenv(t *testing.T, key, value string) {
+ err := plan9.Setenv(key, value)
+ if err != nil {
+ t.Fatalf("Setenv failed to set %q: %v", value, err)
+ }
+ newvalue, found := plan9.Getenv(key)
+ if !found {
+ t.Fatalf("Getenv failed to find %v variable (want value %q)", key, value)
+ }
+ if newvalue != value {
+ t.Fatalf("Getenv(%v) = %q; want %q", key, newvalue, value)
+ }
+}
+
+func TestEnv(t *testing.T) {
+ testSetGetenv(t, "TESTENV", "AVALUE")
+ // make sure TESTENV gets set to "", not deleted
+ testSetGetenv(t, "TESTENV", "")
+}
diff --git a/vendor/golang.org/x/sys/plan9/zsyscall_plan9_386.go b/vendor/golang.org/x/sys/plan9/zsyscall_plan9_386.go
new file mode 100644
index 00000000..b35598ad
--- /dev/null
+++ b/vendor/golang.org/x/sys/plan9/zsyscall_plan9_386.go
@@ -0,0 +1,292 @@
+// mksyscall.pl -l32 -plan9 syscall_plan9.go
+// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
+
+package plan9
+
+import "unsafe"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func fd2path(fd int, buf []byte) (err error) {
+ var _p0 unsafe.Pointer
+ if len(buf) > 0 {
+ _p0 = unsafe.Pointer(&buf[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := Syscall(SYS_FD2PATH, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func pipe(p *[2]int32) (err error) {
+ r0, _, e1 := Syscall(SYS_PIPE, uintptr(unsafe.Pointer(p)), 0, 0)
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func await(s []byte) (n int, err error) {
+ var _p0 unsafe.Pointer
+ if len(s) > 0 {
+ _p0 = unsafe.Pointer(&s[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := Syscall(SYS_AWAIT, uintptr(_p0), uintptr(len(s)), 0)
+ n = int(r0)
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func open(path string, mode int) (fd int, err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+ use(unsafe.Pointer(_p0))
+ fd = int(r0)
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func create(path string, mode int, perm uint32) (fd int, err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ r0, _, e1 := Syscall(SYS_CREATE, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
+ use(unsafe.Pointer(_p0))
+ fd = int(r0)
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func remove(path string) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ r0, _, e1 := Syscall(SYS_REMOVE, uintptr(unsafe.Pointer(_p0)), 0, 0)
+ use(unsafe.Pointer(_p0))
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func stat(path string, edir []byte) (n int, err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ var _p1 unsafe.Pointer
+ if len(edir) > 0 {
+ _p1 = unsafe.Pointer(&edir[0])
+ } else {
+ _p1 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(edir)))
+ use(unsafe.Pointer(_p0))
+ n = int(r0)
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func bind(name string, old string, flag int) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(name)
+ if err != nil {
+ return
+ }
+ var _p1 *byte
+ _p1, err = BytePtrFromString(old)
+ if err != nil {
+ return
+ }
+ r0, _, e1 := Syscall(SYS_BIND, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(flag))
+ use(unsafe.Pointer(_p0))
+ use(unsafe.Pointer(_p1))
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func mount(fd int, afd int, old string, flag int, aname string) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(old)
+ if err != nil {
+ return
+ }
+ var _p1 *byte
+ _p1, err = BytePtrFromString(aname)
+ if err != nil {
+ return
+ }
+ r0, _, e1 := Syscall6(SYS_MOUNT, uintptr(fd), uintptr(afd), uintptr(unsafe.Pointer(_p0)), uintptr(flag), uintptr(unsafe.Pointer(_p1)), 0)
+ use(unsafe.Pointer(_p0))
+ use(unsafe.Pointer(_p1))
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func wstat(path string, edir []byte) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ var _p1 unsafe.Pointer
+ if len(edir) > 0 {
+ _p1 = unsafe.Pointer(&edir[0])
+ } else {
+ _p1 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := Syscall(SYS_WSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(edir)))
+ use(unsafe.Pointer(_p0))
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func chdir(path string) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ r0, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
+ use(unsafe.Pointer(_p0))
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup(oldfd int, newfd int) (fd int, err error) {
+ r0, _, e1 := Syscall(SYS_DUP, uintptr(oldfd), uintptr(newfd), 0)
+ fd = int(r0)
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pread(fd int, p []byte, offset int64) (n int, err error) {
+ var _p0 unsafe.Pointer
+ if len(p) > 0 {
+ _p0 = unsafe.Pointer(&p[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := Syscall6(SYS_PREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0)
+ n = int(r0)
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
+ var _p0 unsafe.Pointer
+ if len(p) > 0 {
+ _p0 = unsafe.Pointer(&p[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := Syscall6(SYS_PWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0)
+ n = int(r0)
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Close(fd int) (err error) {
+ r0, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fstat(fd int, edir []byte) (n int, err error) {
+ var _p0 unsafe.Pointer
+ if len(edir) > 0 {
+ _p0 = unsafe.Pointer(&edir[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(_p0), uintptr(len(edir)))
+ n = int(r0)
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fwstat(fd int, edir []byte) (err error) {
+ var _p0 unsafe.Pointer
+ if len(edir) > 0 {
+ _p0 = unsafe.Pointer(&edir[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := Syscall(SYS_FWSTAT, uintptr(fd), uintptr(_p0), uintptr(len(edir)))
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
diff --git a/vendor/golang.org/x/sys/plan9/zsyscall_plan9_amd64.go b/vendor/golang.org/x/sys/plan9/zsyscall_plan9_amd64.go
new file mode 100644
index 00000000..b35598ad
--- /dev/null
+++ b/vendor/golang.org/x/sys/plan9/zsyscall_plan9_amd64.go
@@ -0,0 +1,292 @@
+// mksyscall.pl -l32 -plan9 syscall_plan9.go
+// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
+
+package plan9
+
+import "unsafe"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func fd2path(fd int, buf []byte) (err error) {
+ var _p0 unsafe.Pointer
+ if len(buf) > 0 {
+ _p0 = unsafe.Pointer(&buf[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := Syscall(SYS_FD2PATH, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func pipe(p *[2]int32) (err error) {
+ r0, _, e1 := Syscall(SYS_PIPE, uintptr(unsafe.Pointer(p)), 0, 0)
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func await(s []byte) (n int, err error) {
+ var _p0 unsafe.Pointer
+ if len(s) > 0 {
+ _p0 = unsafe.Pointer(&s[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := Syscall(SYS_AWAIT, uintptr(_p0), uintptr(len(s)), 0)
+ n = int(r0)
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func open(path string, mode int) (fd int, err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+ use(unsafe.Pointer(_p0))
+ fd = int(r0)
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func create(path string, mode int, perm uint32) (fd int, err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ r0, _, e1 := Syscall(SYS_CREATE, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
+ use(unsafe.Pointer(_p0))
+ fd = int(r0)
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func remove(path string) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ r0, _, e1 := Syscall(SYS_REMOVE, uintptr(unsafe.Pointer(_p0)), 0, 0)
+ use(unsafe.Pointer(_p0))
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func stat(path string, edir []byte) (n int, err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ var _p1 unsafe.Pointer
+ if len(edir) > 0 {
+ _p1 = unsafe.Pointer(&edir[0])
+ } else {
+ _p1 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(edir)))
+ use(unsafe.Pointer(_p0))
+ n = int(r0)
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func bind(name string, old string, flag int) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(name)
+ if err != nil {
+ return
+ }
+ var _p1 *byte
+ _p1, err = BytePtrFromString(old)
+ if err != nil {
+ return
+ }
+ r0, _, e1 := Syscall(SYS_BIND, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(flag))
+ use(unsafe.Pointer(_p0))
+ use(unsafe.Pointer(_p1))
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func mount(fd int, afd int, old string, flag int, aname string) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(old)
+ if err != nil {
+ return
+ }
+ var _p1 *byte
+ _p1, err = BytePtrFromString(aname)
+ if err != nil {
+ return
+ }
+ r0, _, e1 := Syscall6(SYS_MOUNT, uintptr(fd), uintptr(afd), uintptr(unsafe.Pointer(_p0)), uintptr(flag), uintptr(unsafe.Pointer(_p1)), 0)
+ use(unsafe.Pointer(_p0))
+ use(unsafe.Pointer(_p1))
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func wstat(path string, edir []byte) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ var _p1 unsafe.Pointer
+ if len(edir) > 0 {
+ _p1 = unsafe.Pointer(&edir[0])
+ } else {
+ _p1 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := Syscall(SYS_WSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(edir)))
+ use(unsafe.Pointer(_p0))
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func chdir(path string) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ r0, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
+ use(unsafe.Pointer(_p0))
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup(oldfd int, newfd int) (fd int, err error) {
+ r0, _, e1 := Syscall(SYS_DUP, uintptr(oldfd), uintptr(newfd), 0)
+ fd = int(r0)
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pread(fd int, p []byte, offset int64) (n int, err error) {
+ var _p0 unsafe.Pointer
+ if len(p) > 0 {
+ _p0 = unsafe.Pointer(&p[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := Syscall6(SYS_PREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0)
+ n = int(r0)
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
+ var _p0 unsafe.Pointer
+ if len(p) > 0 {
+ _p0 = unsafe.Pointer(&p[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := Syscall6(SYS_PWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0)
+ n = int(r0)
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Close(fd int) (err error) {
+ r0, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fstat(fd int, edir []byte) (n int, err error) {
+ var _p0 unsafe.Pointer
+ if len(edir) > 0 {
+ _p0 = unsafe.Pointer(&edir[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(_p0), uintptr(len(edir)))
+ n = int(r0)
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fwstat(fd int, edir []byte) (err error) {
+ var _p0 unsafe.Pointer
+ if len(edir) > 0 {
+ _p0 = unsafe.Pointer(&edir[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := Syscall(SYS_FWSTAT, uintptr(fd), uintptr(_p0), uintptr(len(edir)))
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
diff --git a/vendor/golang.org/x/sys/plan9/zsysnum_plan9.go b/vendor/golang.org/x/sys/plan9/zsysnum_plan9.go
new file mode 100644
index 00000000..22e8abd4
--- /dev/null
+++ b/vendor/golang.org/x/sys/plan9/zsysnum_plan9.go
@@ -0,0 +1,49 @@
+// mksysnum_plan9.sh /opt/plan9/sys/src/libc/9syscall/sys.h
+// MACHINE GENERATED BY THE ABOVE COMMAND; DO NOT EDIT
+
+package plan9
+
+const (
+ SYS_SYSR1 = 0
+ SYS_BIND = 2
+ SYS_CHDIR = 3
+ SYS_CLOSE = 4
+ SYS_DUP = 5
+ SYS_ALARM = 6
+ SYS_EXEC = 7
+ SYS_EXITS = 8
+ SYS_FAUTH = 10
+ SYS_SEGBRK = 12
+ SYS_OPEN = 14
+ SYS_OSEEK = 16
+ SYS_SLEEP = 17
+ SYS_RFORK = 19
+ SYS_PIPE = 21
+ SYS_CREATE = 22
+ SYS_FD2PATH = 23
+ SYS_BRK_ = 24
+ SYS_REMOVE = 25
+ SYS_NOTIFY = 28
+ SYS_NOTED = 29
+ SYS_SEGATTACH = 30
+ SYS_SEGDETACH = 31
+ SYS_SEGFREE = 32
+ SYS_SEGFLUSH = 33
+ SYS_RENDEZVOUS = 34
+ SYS_UNMOUNT = 35
+ SYS_SEMACQUIRE = 37
+ SYS_SEMRELEASE = 38
+ SYS_SEEK = 39
+ SYS_FVERSION = 40
+ SYS_ERRSTR = 41
+ SYS_STAT = 42
+ SYS_FSTAT = 43
+ SYS_WSTAT = 44
+ SYS_FWSTAT = 45
+ SYS_MOUNT = 46
+ SYS_AWAIT = 47
+ SYS_PREAD = 50
+ SYS_PWRITE = 51
+ SYS_TSEMACQUIRE = 52
+ SYS_NSEC = 53
+)
diff --git a/vendor/golang.org/x/sys/unix/.gitignore b/vendor/golang.org/x/sys/unix/.gitignore
new file mode 100644
index 00000000..e4827159
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/.gitignore
@@ -0,0 +1 @@
+_obj/
diff --git a/vendor/golang.org/x/sys/unix/README.md b/vendor/golang.org/x/sys/unix/README.md
new file mode 100644
index 00000000..bc6f6031
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/README.md
@@ -0,0 +1,173 @@
+# Building `sys/unix`
+
+The sys/unix package provides access to the raw system call interface of the
+underlying operating system. See: https://godoc.org/golang.org/x/sys/unix
+
+Porting Go to a new architecture/OS combination or adding syscalls, types, or
+constants to an existing architecture/OS pair requires some manual effort;
+however, there are tools that automate much of the process.
+
+## Build Systems
+
+There are currently two ways we generate the necessary files. We are currently
+migrating the build system to use containers so the builds are reproducible.
+This is being done on an OS-by-OS basis. Please update this documentation as
+components of the build system change.
+
+### Old Build System (currently for `GOOS != "Linux" || GOARCH == "sparc64"`)
+
+The old build system generates the Go files based on the C header files
+present on your system. This means that files
+for a given GOOS/GOARCH pair must be generated on a system with that OS and
+architecture. This also means that the generated code can differ from system
+to system, based on differences in the header files.
+
+To avoid this, if you are using the old build system, only generate the Go
+files on an installation with unmodified header files. It is also important to
+keep track of which version of the OS the files were generated from (ex.
+Darwin 14 vs Darwin 15). This makes it easier to track the progress of changes
+and have each OS upgrade correspond to a single change.
+
+To build the files for your current OS and architecture, make sure GOOS and
+GOARCH are set correctly and run `mkall.sh`. This will generate the files for
+your specific system. Running `mkall.sh -n` shows the commands that will be run.
+
+Requirements: bash, perl, go
+
+### New Build System (currently for `GOOS == "Linux" && GOARCH != "sparc64"`)
+
+The new build system uses a Docker container to generate the go files directly
+from source checkouts of the kernel and various system libraries. This means
+that on any platform that supports Docker, all the files using the new build
+system can be generated at once, and generated files will not change based on
+what the person running the scripts has installed on their computer.
+
+The OS specific files for the new build system are located in the `${GOOS}`
+directory, and the build is coordinated by the `${GOOS}/mkall.go` program. When
+the kernel or system library updates, modify the Dockerfile at
+`${GOOS}/Dockerfile` to checkout the new release of the source.
+
+To build all the files under the new build system, you must be on an amd64/Linux
+system and have your GOOS and GOARCH set accordingly. Running `mkall.sh` will
+then generate all of the files for all of the GOOS/GOARCH pairs in the new build
+system. Running `mkall.sh -n` shows the commands that will be run.
+
+Requirements: bash, perl, go, docker
+
+## Component files
+
+This section describes the various files used in the code generation process.
+It also contains instructions on how to modify these files to add a new
+architecture/OS or to add additional syscalls, types, or constants. Note that
+if you are using the new build system, the scripts cannot be called normally.
+They must be called from within the docker container.
+
+### asm files
+
+The hand-written assembly file at `asm_${GOOS}_${GOARCH}.s` implements system
+call dispatch. There are three entry points:
+```
+ func Syscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr)
+ func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr)
+ func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr)
+```
+The first and second are the standard ones; they differ only in how many
+arguments can be passed to the kernel. The third is for low-level use by the
+ForkExec wrapper. Unlike the first two, it does not call into the scheduler to
+let it know that a system call is running.
+
+When porting Go to an new architecture/OS, this file must be implemented for
+each GOOS/GOARCH pair.
+
+### mksysnum
+
+Mksysnum is a script located at `${GOOS}/mksysnum.pl` (or `mksysnum_${GOOS}.pl`
+for the old system). This script takes in a list of header files containing the
+syscall number declarations and parses them to produce the corresponding list of
+Go numeric constants. See `zsysnum_${GOOS}_${GOARCH}.go` for the generated
+constants.
+
+Adding new syscall numbers is mostly done by running the build on a sufficiently
+new installation of the target OS (or updating the source checkouts for the
+new build system). However, depending on the OS, you make need to update the
+parsing in mksysnum.
+
+### mksyscall.pl
+
+The `syscall.go`, `syscall_${GOOS}.go`, `syscall_${GOOS}_${GOARCH}.go` are
+hand-written Go files which implement system calls (for unix, the specific OS,
+or the specific OS/Architecture pair respectively) that need special handling
+and list `//sys` comments giving prototypes for ones that can be generated.
+
+The mksyscall.pl script takes the `//sys` and `//sysnb` comments and converts
+them into syscalls. This requires the name of the prototype in the comment to
+match a syscall number in the `zsysnum_${GOOS}_${GOARCH}.go` file. The function
+prototype can be exported (capitalized) or not.
+
+Adding a new syscall often just requires adding a new `//sys` function prototype
+with the desired arguments and a capitalized name so it is exported. However, if
+you want the interface to the syscall to be different, often one will make an
+unexported `//sys` prototype, an then write a custom wrapper in
+`syscall_${GOOS}.go`.
+
+### types files
+
+For each OS, there is a hand-written Go file at `${GOOS}/types.go` (or
+`types_${GOOS}.go` on the old system). This file includes standard C headers and
+creates Go type aliases to the corresponding C types. The file is then fed
+through godef to get the Go compatible definitions. Finally, the generated code
+is fed though mkpost.go to format the code correctly and remove any hidden or
+private identifiers. This cleaned-up code is written to
+`ztypes_${GOOS}_${GOARCH}.go`.
+
+The hardest part about preparing this file is figuring out which headers to
+include and which symbols need to be `#define`d to get the actual data
+structures that pass through to the kernel system calls. Some C libraries
+preset alternate versions for binary compatibility and translate them on the
+way in and out of system calls, but there is almost always a `#define` that can
+get the real ones.
+See `types_darwin.go` and `linux/types.go` for examples.
+
+To add a new type, add in the necessary include statement at the top of the
+file (if it is not already there) and add in a type alias line. Note that if
+your type is significantly different on different architectures, you may need
+some `#if/#elif` macros in your include statements.
+
+### mkerrors.sh
+
+This script is used to generate the system's various constants. This doesn't
+just include the error numbers and error strings, but also the signal numbers
+an a wide variety of miscellaneous constants. The constants come from the list
+of include files in the `includes_${uname}` variable. A regex then picks out
+the desired `#define` statements, and generates the corresponding Go constants.
+The error numbers and strings are generated from `#include `, and the
+signal numbers and strings are generated from `#include `. All of
+these constants are written to `zerrors_${GOOS}_${GOARCH}.go` via a C program,
+`_errors.c`, which prints out all the constants.
+
+To add a constant, add the header that includes it to the appropriate variable.
+Then, edit the regex (if necessary) to match the desired constant. Avoid making
+the regex too broad to avoid matching unintended constants.
+
+
+## Generated files
+
+### `zerror_${GOOS}_${GOARCH}.go`
+
+A file containing all of the system's generated error numbers, error strings,
+signal numbers, and constants. Generated by `mkerrors.sh` (see above).
+
+### `zsyscall_${GOOS}_${GOARCH}.go`
+
+A file containing all the generated syscalls for a specific GOOS and GOARCH.
+Generated by `mksyscall.pl` (see above).
+
+### `zsysnum_${GOOS}_${GOARCH}.go`
+
+A list of numeric constants for all the syscall number of the specific GOOS
+and GOARCH. Generated by mksysnum (see above).
+
+### `ztypes_${GOOS}_${GOARCH}.go`
+
+A file containing Go types for passing into (or returning from) syscalls.
+Generated by godefs and the types file (see above).
diff --git a/vendor/golang.org/x/sys/unix/asm_darwin_386.s b/vendor/golang.org/x/sys/unix/asm_darwin_386.s
new file mode 100644
index 00000000..8a727831
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/asm_darwin_386.s
@@ -0,0 +1,29 @@
+// 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 !gccgo
+
+#include "textflag.h"
+
+//
+// System call support for 386, Darwin
+//
+
+// 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)
diff --git a/vendor/golang.org/x/sys/unix/asm_darwin_amd64.s b/vendor/golang.org/x/sys/unix/asm_darwin_amd64.s
new file mode 100644
index 00000000..6321421f
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/asm_darwin_amd64.s
@@ -0,0 +1,29 @@
+// 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 !gccgo
+
+#include "textflag.h"
+
+//
+// System call support for AMD64, Darwin
+//
+
+// Just jump to package syscall's implementation for all these functions.
+// The runtime may know about them.
+
+TEXT ·Syscall(SB),NOSPLIT,$0-56
+ JMP syscall·Syscall(SB)
+
+TEXT ·Syscall6(SB),NOSPLIT,$0-80
+ JMP syscall·Syscall6(SB)
+
+TEXT ·Syscall9(SB),NOSPLIT,$0-104
+ JMP syscall·Syscall9(SB)
+
+TEXT ·RawSyscall(SB),NOSPLIT,$0-56
+ JMP syscall·RawSyscall(SB)
+
+TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
+ JMP syscall·RawSyscall6(SB)
diff --git a/vendor/golang.org/x/sys/unix/asm_darwin_arm.s b/vendor/golang.org/x/sys/unix/asm_darwin_arm.s
new file mode 100644
index 00000000..333242d5
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/asm_darwin_arm.s
@@ -0,0 +1,30 @@
+// 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 !gccgo
+// +build arm,darwin
+
+#include "textflag.h"
+
+//
+// System call support for ARM, Darwin
+//
+
+// Just jump to package syscall's implementation for all these functions.
+// The runtime may know about them.
+
+TEXT ·Syscall(SB),NOSPLIT,$0-28
+ B syscall·Syscall(SB)
+
+TEXT ·Syscall6(SB),NOSPLIT,$0-40
+ B syscall·Syscall6(SB)
+
+TEXT ·Syscall9(SB),NOSPLIT,$0-52
+ B syscall·Syscall9(SB)
+
+TEXT ·RawSyscall(SB),NOSPLIT,$0-28
+ B syscall·RawSyscall(SB)
+
+TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
+ B syscall·RawSyscall6(SB)
diff --git a/vendor/golang.org/x/sys/unix/asm_darwin_arm64.s b/vendor/golang.org/x/sys/unix/asm_darwin_arm64.s
new file mode 100644
index 00000000..97e01743
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/asm_darwin_arm64.s
@@ -0,0 +1,30 @@
+// 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 !gccgo
+// +build arm64,darwin
+
+#include "textflag.h"
+
+//
+// System call support for AMD64, Darwin
+//
+
+// Just jump to package syscall's implementation for all these functions.
+// The runtime may know about them.
+
+TEXT ·Syscall(SB),NOSPLIT,$0-56
+ B syscall·Syscall(SB)
+
+TEXT ·Syscall6(SB),NOSPLIT,$0-80
+ B syscall·Syscall6(SB)
+
+TEXT ·Syscall9(SB),NOSPLIT,$0-104
+ B syscall·Syscall9(SB)
+
+TEXT ·RawSyscall(SB),NOSPLIT,$0-56
+ B syscall·RawSyscall(SB)
+
+TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
+ B syscall·RawSyscall6(SB)
diff --git a/vendor/golang.org/x/sys/unix/asm_dragonfly_amd64.s b/vendor/golang.org/x/sys/unix/asm_dragonfly_amd64.s
new file mode 100644
index 00000000..d5ed6726
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/asm_dragonfly_amd64.s
@@ -0,0 +1,29 @@
+// 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 !gccgo
+
+#include "textflag.h"
+
+//
+// System call support for AMD64, DragonFly
+//
+
+// Just jump to package syscall's implementation for all these functions.
+// The runtime may know about them.
+
+TEXT ·Syscall(SB),NOSPLIT,$0-64
+ JMP syscall·Syscall(SB)
+
+TEXT ·Syscall6(SB),NOSPLIT,$0-88
+ JMP syscall·Syscall6(SB)
+
+TEXT ·Syscall9(SB),NOSPLIT,$0-112
+ JMP syscall·Syscall9(SB)
+
+TEXT ·RawSyscall(SB),NOSPLIT,$0-64
+ JMP syscall·RawSyscall(SB)
+
+TEXT ·RawSyscall6(SB),NOSPLIT,$0-88
+ JMP syscall·RawSyscall6(SB)
diff --git a/vendor/golang.org/x/sys/unix/asm_freebsd_386.s b/vendor/golang.org/x/sys/unix/asm_freebsd_386.s
new file mode 100644
index 00000000..c9a0a260
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/asm_freebsd_386.s
@@ -0,0 +1,29 @@
+// 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 !gccgo
+
+#include "textflag.h"
+
+//
+// System call support for 386, FreeBSD
+//
+
+// 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)
diff --git a/vendor/golang.org/x/sys/unix/asm_freebsd_amd64.s b/vendor/golang.org/x/sys/unix/asm_freebsd_amd64.s
new file mode 100644
index 00000000..35172477
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/asm_freebsd_amd64.s
@@ -0,0 +1,29 @@
+// 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 !gccgo
+
+#include "textflag.h"
+
+//
+// System call support for AMD64, FreeBSD
+//
+
+// Just jump to package syscall's implementation for all these functions.
+// The runtime may know about them.
+
+TEXT ·Syscall(SB),NOSPLIT,$0-56
+ JMP syscall·Syscall(SB)
+
+TEXT ·Syscall6(SB),NOSPLIT,$0-80
+ JMP syscall·Syscall6(SB)
+
+TEXT ·Syscall9(SB),NOSPLIT,$0-104
+ JMP syscall·Syscall9(SB)
+
+TEXT ·RawSyscall(SB),NOSPLIT,$0-56
+ JMP syscall·RawSyscall(SB)
+
+TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
+ JMP syscall·RawSyscall6(SB)
diff --git a/vendor/golang.org/x/sys/unix/asm_freebsd_arm.s b/vendor/golang.org/x/sys/unix/asm_freebsd_arm.s
new file mode 100644
index 00000000..9227c875
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/asm_freebsd_arm.s
@@ -0,0 +1,29 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !gccgo
+
+#include "textflag.h"
+
+//
+// System call support for ARM, FreeBSD
+//
+
+// Just jump to package syscall's implementation for all these functions.
+// The runtime may know about them.
+
+TEXT ·Syscall(SB),NOSPLIT,$0-28
+ B syscall·Syscall(SB)
+
+TEXT ·Syscall6(SB),NOSPLIT,$0-40
+ B syscall·Syscall6(SB)
+
+TEXT ·Syscall9(SB),NOSPLIT,$0-52
+ B syscall·Syscall9(SB)
+
+TEXT ·RawSyscall(SB),NOSPLIT,$0-28
+ B syscall·RawSyscall(SB)
+
+TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
+ B syscall·RawSyscall6(SB)
diff --git a/vendor/golang.org/x/sys/unix/asm_linux_386.s b/vendor/golang.org/x/sys/unix/asm_linux_386.s
new file mode 100644
index 00000000..4db29093
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/asm_linux_386.s
@@ -0,0 +1,35 @@
+// 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 !gccgo
+
+#include "textflag.h"
+
+//
+// System calls for 386, 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 ·RawSyscall(SB),NOSPLIT,$0-28
+ JMP syscall·RawSyscall(SB)
+
+TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
+ JMP syscall·RawSyscall6(SB)
+
+TEXT ·socketcall(SB),NOSPLIT,$0-36
+ JMP syscall·socketcall(SB)
+
+TEXT ·rawsocketcall(SB),NOSPLIT,$0-36
+ JMP syscall·rawsocketcall(SB)
+
+TEXT ·seek(SB),NOSPLIT,$0-28
+ JMP syscall·seek(SB)
diff --git a/vendor/golang.org/x/sys/unix/asm_linux_amd64.s b/vendor/golang.org/x/sys/unix/asm_linux_amd64.s
new file mode 100644
index 00000000..44e25c62
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/asm_linux_amd64.s
@@ -0,0 +1,29 @@
+// 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 !gccgo
+
+#include "textflag.h"
+
+//
+// System calls for AMD64, Linux
+//
+
+// Just jump to package syscall's implementation for all these functions.
+// The runtime may know about them.
+
+TEXT ·Syscall(SB),NOSPLIT,$0-56
+ JMP syscall·Syscall(SB)
+
+TEXT ·Syscall6(SB),NOSPLIT,$0-80
+ JMP syscall·Syscall6(SB)
+
+TEXT ·RawSyscall(SB),NOSPLIT,$0-56
+ JMP syscall·RawSyscall(SB)
+
+TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
+ JMP syscall·RawSyscall6(SB)
+
+TEXT ·gettimeofday(SB),NOSPLIT,$0-16
+ JMP syscall·gettimeofday(SB)
diff --git a/vendor/golang.org/x/sys/unix/asm_linux_arm.s b/vendor/golang.org/x/sys/unix/asm_linux_arm.s
new file mode 100644
index 00000000..cf0b5746
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/asm_linux_arm.s
@@ -0,0 +1,29 @@
+// 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 !gccgo
+
+#include "textflag.h"
+
+//
+// System calls for arm, Linux
+//
+
+// Just jump to package syscall's implementation for all these functions.
+// The runtime may know about them.
+
+TEXT ·Syscall(SB),NOSPLIT,$0-28
+ B syscall·Syscall(SB)
+
+TEXT ·Syscall6(SB),NOSPLIT,$0-40
+ B syscall·Syscall6(SB)
+
+TEXT ·RawSyscall(SB),NOSPLIT,$0-28
+ B syscall·RawSyscall(SB)
+
+TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
+ B syscall·RawSyscall6(SB)
+
+TEXT ·seek(SB),NOSPLIT,$0-32
+ B syscall·seek(SB)
diff --git a/vendor/golang.org/x/sys/unix/asm_linux_arm64.s b/vendor/golang.org/x/sys/unix/asm_linux_arm64.s
new file mode 100644
index 00000000..4be9bfed
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/asm_linux_arm64.s
@@ -0,0 +1,24 @@
+// 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 arm64
+// +build !gccgo
+
+#include "textflag.h"
+
+// Just jump to package syscall's implementation for all these functions.
+// The runtime may know about them.
+
+TEXT ·Syscall(SB),NOSPLIT,$0-56
+ B syscall·Syscall(SB)
+
+TEXT ·Syscall6(SB),NOSPLIT,$0-80
+ B syscall·Syscall6(SB)
+
+TEXT ·RawSyscall(SB),NOSPLIT,$0-56
+ B syscall·RawSyscall(SB)
+
+TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
+ B syscall·RawSyscall6(SB)
diff --git a/vendor/golang.org/x/sys/unix/asm_linux_mips64x.s b/vendor/golang.org/x/sys/unix/asm_linux_mips64x.s
new file mode 100644
index 00000000..724e580c
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/asm_linux_mips64x.s
@@ -0,0 +1,28 @@
+// 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
+// +build !gccgo
+
+#include "textflag.h"
+
+//
+// System calls for mips64, Linux
+//
+
+// Just jump to package syscall's implementation for all these functions.
+// The runtime may know about them.
+
+TEXT ·Syscall(SB),NOSPLIT,$0-56
+ JMP syscall·Syscall(SB)
+
+TEXT ·Syscall6(SB),NOSPLIT,$0-80
+ JMP syscall·Syscall6(SB)
+
+TEXT ·RawSyscall(SB),NOSPLIT,$0-56
+ JMP syscall·RawSyscall(SB)
+
+TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
+ JMP syscall·RawSyscall6(SB)
diff --git a/vendor/golang.org/x/sys/unix/asm_linux_mipsx.s b/vendor/golang.org/x/sys/unix/asm_linux_mipsx.s
new file mode 100644
index 00000000..2ea42575
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/asm_linux_mipsx.s
@@ -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)
diff --git a/vendor/golang.org/x/sys/unix/asm_linux_ppc64x.s b/vendor/golang.org/x/sys/unix/asm_linux_ppc64x.s
new file mode 100644
index 00000000..8d231feb
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/asm_linux_ppc64x.s
@@ -0,0 +1,28 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build linux
+// +build ppc64 ppc64le
+// +build !gccgo
+
+#include "textflag.h"
+
+//
+// System calls for ppc64, 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)
diff --git a/vendor/golang.org/x/sys/unix/asm_linux_s390x.s b/vendor/golang.org/x/sys/unix/asm_linux_s390x.s
new file mode 100644
index 00000000..11889859
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/asm_linux_s390x.s
@@ -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)
diff --git a/vendor/golang.org/x/sys/unix/asm_netbsd_386.s b/vendor/golang.org/x/sys/unix/asm_netbsd_386.s
new file mode 100644
index 00000000..48bdcd76
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/asm_netbsd_386.s
@@ -0,0 +1,29 @@
+// 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 !gccgo
+
+#include "textflag.h"
+
+//
+// System call support for 386, NetBSD
+//
+
+// 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)
diff --git a/vendor/golang.org/x/sys/unix/asm_netbsd_amd64.s b/vendor/golang.org/x/sys/unix/asm_netbsd_amd64.s
new file mode 100644
index 00000000..2ede05c7
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/asm_netbsd_amd64.s
@@ -0,0 +1,29 @@
+// 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 !gccgo
+
+#include "textflag.h"
+
+//
+// System call support for AMD64, NetBSD
+//
+
+// Just jump to package syscall's implementation for all these functions.
+// The runtime may know about them.
+
+TEXT ·Syscall(SB),NOSPLIT,$0-56
+ JMP syscall·Syscall(SB)
+
+TEXT ·Syscall6(SB),NOSPLIT,$0-80
+ JMP syscall·Syscall6(SB)
+
+TEXT ·Syscall9(SB),NOSPLIT,$0-104
+ JMP syscall·Syscall9(SB)
+
+TEXT ·RawSyscall(SB),NOSPLIT,$0-56
+ JMP syscall·RawSyscall(SB)
+
+TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
+ JMP syscall·RawSyscall6(SB)
diff --git a/vendor/golang.org/x/sys/unix/asm_netbsd_arm.s b/vendor/golang.org/x/sys/unix/asm_netbsd_arm.s
new file mode 100644
index 00000000..e8928571
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/asm_netbsd_arm.s
@@ -0,0 +1,29 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !gccgo
+
+#include "textflag.h"
+
+//
+// System call support for ARM, NetBSD
+//
+
+// Just jump to package syscall's implementation for all these functions.
+// The runtime may know about them.
+
+TEXT ·Syscall(SB),NOSPLIT,$0-28
+ B syscall·Syscall(SB)
+
+TEXT ·Syscall6(SB),NOSPLIT,$0-40
+ B syscall·Syscall6(SB)
+
+TEXT ·Syscall9(SB),NOSPLIT,$0-52
+ B syscall·Syscall9(SB)
+
+TEXT ·RawSyscall(SB),NOSPLIT,$0-28
+ B syscall·RawSyscall(SB)
+
+TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
+ B syscall·RawSyscall6(SB)
diff --git a/vendor/golang.org/x/sys/unix/asm_openbsd_386.s b/vendor/golang.org/x/sys/unix/asm_openbsd_386.s
new file mode 100644
index 00000000..00576f3c
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/asm_openbsd_386.s
@@ -0,0 +1,29 @@
+// 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 !gccgo
+
+#include "textflag.h"
+
+//
+// System call support for 386, OpenBSD
+//
+
+// 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)
diff --git a/vendor/golang.org/x/sys/unix/asm_openbsd_amd64.s b/vendor/golang.org/x/sys/unix/asm_openbsd_amd64.s
new file mode 100644
index 00000000..790ef77f
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/asm_openbsd_amd64.s
@@ -0,0 +1,29 @@
+// 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 !gccgo
+
+#include "textflag.h"
+
+//
+// System call support for AMD64, OpenBSD
+//
+
+// Just jump to package syscall's implementation for all these functions.
+// The runtime may know about them.
+
+TEXT ·Syscall(SB),NOSPLIT,$0-56
+ JMP syscall·Syscall(SB)
+
+TEXT ·Syscall6(SB),NOSPLIT,$0-80
+ JMP syscall·Syscall6(SB)
+
+TEXT ·Syscall9(SB),NOSPLIT,$0-104
+ JMP syscall·Syscall9(SB)
+
+TEXT ·RawSyscall(SB),NOSPLIT,$0-56
+ JMP syscall·RawSyscall(SB)
+
+TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
+ JMP syscall·RawSyscall6(SB)
diff --git a/vendor/golang.org/x/sys/unix/asm_solaris_amd64.s b/vendor/golang.org/x/sys/unix/asm_solaris_amd64.s
new file mode 100644
index 00000000..43ed17a0
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/asm_solaris_amd64.s
@@ -0,0 +1,17 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !gccgo
+
+#include "textflag.h"
+
+//
+// System calls for amd64, Solaris are implemented in runtime/syscall_solaris.go
+//
+
+TEXT ·sysvicall6(SB),NOSPLIT,$0-64
+ JMP syscall·sysvicall6(SB)
+
+TEXT ·rawSysvicall6(SB),NOSPLIT,$0-64
+ JMP syscall·rawSysvicall6(SB)
diff --git a/vendor/golang.org/x/sys/unix/bluetooth_linux.go b/vendor/golang.org/x/sys/unix/bluetooth_linux.go
new file mode 100644
index 00000000..6e322969
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/bluetooth_linux.go
@@ -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
+)
diff --git a/vendor/golang.org/x/sys/unix/constants.go b/vendor/golang.org/x/sys/unix/constants.go
new file mode 100644
index 00000000..a96f0ebc
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/constants.go
@@ -0,0 +1,13 @@
+// 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 darwin dragonfly freebsd linux netbsd openbsd solaris
+
+package unix
+
+const (
+ R_OK = 0x4
+ W_OK = 0x2
+ X_OK = 0x1
+)
diff --git a/vendor/golang.org/x/sys/unix/creds_test.go b/vendor/golang.org/x/sys/unix/creds_test.go
new file mode 100644
index 00000000..eaae7c36
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/creds_test.go
@@ -0,0 +1,121 @@
+// Copyright 2012 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
+
+package unix_test
+
+import (
+ "bytes"
+ "net"
+ "os"
+ "syscall"
+ "testing"
+
+ "golang.org/x/sys/unix"
+)
+
+// TestSCMCredentials tests the sending and receiving of credentials
+// (PID, UID, GID) in an ancillary message between two UNIX
+// sockets. The SO_PASSCRED socket option is enabled on the sending
+// socket for this to work.
+func TestSCMCredentials(t *testing.T) {
+ fds, err := unix.Socketpair(unix.AF_LOCAL, unix.SOCK_STREAM, 0)
+ if err != nil {
+ t.Fatalf("Socketpair: %v", err)
+ }
+ defer unix.Close(fds[0])
+ defer unix.Close(fds[1])
+
+ err = unix.SetsockoptInt(fds[0], unix.SOL_SOCKET, unix.SO_PASSCRED, 1)
+ if err != nil {
+ t.Fatalf("SetsockoptInt: %v", err)
+ }
+
+ srvFile := os.NewFile(uintptr(fds[0]), "server")
+ defer srvFile.Close()
+ srv, err := net.FileConn(srvFile)
+ if err != nil {
+ t.Errorf("FileConn: %v", err)
+ return
+ }
+ defer srv.Close()
+
+ cliFile := os.NewFile(uintptr(fds[1]), "client")
+ defer cliFile.Close()
+ cli, err := net.FileConn(cliFile)
+ if err != nil {
+ t.Errorf("FileConn: %v", err)
+ return
+ }
+ defer cli.Close()
+
+ var ucred unix.Ucred
+ if os.Getuid() != 0 {
+ ucred.Pid = int32(os.Getpid())
+ ucred.Uid = 0
+ ucred.Gid = 0
+ oob := unix.UnixCredentials(&ucred)
+ _, _, err := cli.(*net.UnixConn).WriteMsgUnix(nil, oob, nil)
+ if op, ok := err.(*net.OpError); ok {
+ err = op.Err
+ }
+ if sys, ok := err.(*os.SyscallError); ok {
+ err = sys.Err
+ }
+ if err != syscall.EPERM {
+ t.Fatalf("WriteMsgUnix failed with %v, want EPERM", err)
+ }
+ }
+
+ ucred.Pid = int32(os.Getpid())
+ ucred.Uid = uint32(os.Getuid())
+ ucred.Gid = uint32(os.Getgid())
+ oob := unix.UnixCredentials(&ucred)
+
+ // this is going to send a dummy byte
+ n, oobn, err := cli.(*net.UnixConn).WriteMsgUnix(nil, oob, nil)
+ if err != nil {
+ t.Fatalf("WriteMsgUnix: %v", err)
+ }
+ if n != 0 {
+ t.Fatalf("WriteMsgUnix n = %d, want 0", n)
+ }
+ if oobn != len(oob) {
+ t.Fatalf("WriteMsgUnix oobn = %d, want %d", oobn, len(oob))
+ }
+
+ oob2 := make([]byte, 10*len(oob))
+ n, oobn2, flags, _, err := srv.(*net.UnixConn).ReadMsgUnix(nil, oob2)
+ if err != nil {
+ t.Fatalf("ReadMsgUnix: %v", err)
+ }
+ if flags != 0 {
+ t.Fatalf("ReadMsgUnix flags = 0x%x, want 0", flags)
+ }
+ if n != 1 {
+ t.Fatalf("ReadMsgUnix n = %d, want 1 (dummy byte)", n)
+ }
+ if oobn2 != oobn {
+ // without SO_PASSCRED set on the socket, ReadMsgUnix will
+ // return zero oob bytes
+ t.Fatalf("ReadMsgUnix oobn = %d, want %d", oobn2, oobn)
+ }
+ oob2 = oob2[:oobn2]
+ if !bytes.Equal(oob, oob2) {
+ t.Fatal("ReadMsgUnix oob bytes don't match")
+ }
+
+ scm, err := unix.ParseSocketControlMessage(oob2)
+ if err != nil {
+ t.Fatalf("ParseSocketControlMessage: %v", err)
+ }
+ newUcred, err := unix.ParseUnixCredentials(&scm[0])
+ if err != nil {
+ t.Fatalf("ParseUnixCredentials: %v", err)
+ }
+ if *newUcred != ucred {
+ t.Fatalf("ParseUnixCredentials = %+v, want %+v", newUcred, ucred)
+ }
+}
diff --git a/vendor/golang.org/x/sys/unix/dirent.go b/vendor/golang.org/x/sys/unix/dirent.go
new file mode 100644
index 00000000..bd475812
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/dirent.go
@@ -0,0 +1,102 @@
+// 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 darwin dragonfly freebsd linux nacl netbsd openbsd solaris
+
+package unix
+
+import "unsafe"
+
+// readInt returns the size-bytes unsigned integer in native byte order at offset off.
+func readInt(b []byte, off, size uintptr) (u uint64, ok bool) {
+ if len(b) < int(off+size) {
+ return 0, false
+ }
+ if isBigEndian {
+ return readIntBE(b[off:], size), true
+ }
+ return readIntLE(b[off:], size), true
+}
+
+func readIntBE(b []byte, size uintptr) uint64 {
+ switch size {
+ case 1:
+ return uint64(b[0])
+ case 2:
+ _ = b[1] // bounds check hint to compiler; see golang.org/issue/14808
+ return uint64(b[1]) | uint64(b[0])<<8
+ case 4:
+ _ = b[3] // bounds check hint to compiler; see golang.org/issue/14808
+ return uint64(b[3]) | uint64(b[2])<<8 | uint64(b[1])<<16 | uint64(b[0])<<24
+ case 8:
+ _ = b[7] // bounds check hint to compiler; see golang.org/issue/14808
+ return uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 |
+ uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56
+ default:
+ panic("syscall: readInt with unsupported size")
+ }
+}
+
+func readIntLE(b []byte, size uintptr) uint64 {
+ switch size {
+ case 1:
+ return uint64(b[0])
+ case 2:
+ _ = b[1] // bounds check hint to compiler; see golang.org/issue/14808
+ return uint64(b[0]) | uint64(b[1])<<8
+ case 4:
+ _ = b[3] // bounds check hint to compiler; see golang.org/issue/14808
+ return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24
+ case 8:
+ _ = b[7] // bounds check hint to compiler; see golang.org/issue/14808
+ return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 |
+ uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56
+ default:
+ panic("syscall: readInt with unsupported size")
+ }
+}
+
+// ParseDirent parses up to max directory entries in buf,
+// appending the names to names. It returns the number of
+// bytes consumed from buf, the number of entries added
+// to names, and the new names slice.
+func ParseDirent(buf []byte, max int, names []string) (consumed int, count int, newnames []string) {
+ origlen := len(buf)
+ count = 0
+ for max != 0 && len(buf) > 0 {
+ reclen, ok := direntReclen(buf)
+ if !ok || reclen > uint64(len(buf)) {
+ return origlen, count, names
+ }
+ rec := buf[:reclen]
+ buf = buf[reclen:]
+ ino, ok := direntIno(rec)
+ if !ok {
+ break
+ }
+ if ino == 0 { // File absent in directory.
+ continue
+ }
+ const namoff = uint64(unsafe.Offsetof(Dirent{}.Name))
+ namlen, ok := direntNamlen(rec)
+ if !ok || namoff+namlen > uint64(len(rec)) {
+ break
+ }
+ name := rec[namoff : namoff+namlen]
+ for i, c := range name {
+ if c == 0 {
+ name = name[:i]
+ break
+ }
+ }
+ // Check for useless names before allocating a string.
+ if string(name) == "." || string(name) == ".." {
+ continue
+ }
+ max--
+ count++
+ names = append(names, string(name))
+ }
+ return origlen - len(buf), count, names
+}
diff --git a/vendor/golang.org/x/sys/unix/endian_big.go b/vendor/golang.org/x/sys/unix/endian_big.go
new file mode 100644
index 00000000..5e926906
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/endian_big.go
@@ -0,0 +1,9 @@
+// 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 ppc64 s390x mips mips64
+
+package unix
+
+const isBigEndian = true
diff --git a/vendor/golang.org/x/sys/unix/endian_little.go b/vendor/golang.org/x/sys/unix/endian_little.go
new file mode 100644
index 00000000..085df2d8
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/endian_little.go
@@ -0,0 +1,9 @@
+// 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 386 amd64 amd64p32 arm arm64 ppc64le mipsle mips64le
+
+package unix
+
+const isBigEndian = false
diff --git a/vendor/golang.org/x/sys/unix/env_unix.go b/vendor/golang.org/x/sys/unix/env_unix.go
new file mode 100644
index 00000000..45e281a0
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/env_unix.go
@@ -0,0 +1,27 @@
+// Copyright 2010 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
+
+// Unix environment variables.
+
+package unix
+
+import "syscall"
+
+func Getenv(key string) (value string, found bool) {
+ return syscall.Getenv(key)
+}
+
+func Setenv(key, value string) error {
+ return syscall.Setenv(key, value)
+}
+
+func Clearenv() {
+ syscall.Clearenv()
+}
+
+func Environ() []string {
+ return syscall.Environ()
+}
diff --git a/vendor/golang.org/x/sys/unix/env_unset.go b/vendor/golang.org/x/sys/unix/env_unset.go
new file mode 100644
index 00000000..92222625
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/env_unset.go
@@ -0,0 +1,14 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build go1.4
+
+package unix
+
+import "syscall"
+
+func Unsetenv(key string) error {
+ // This was added in Go 1.4.
+ return syscall.Unsetenv(key)
+}
diff --git a/vendor/golang.org/x/sys/unix/export_test.go b/vendor/golang.org/x/sys/unix/export_test.go
new file mode 100644
index 00000000..b4fdd970
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/export_test.go
@@ -0,0 +1,9 @@
+// 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 darwin dragonfly freebsd linux netbsd openbsd solaris
+
+package unix
+
+var Itoa = itoa
diff --git a/vendor/golang.org/x/sys/unix/flock.go b/vendor/golang.org/x/sys/unix/flock.go
new file mode 100644
index 00000000..ce67a595
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/flock.go
@@ -0,0 +1,24 @@
+// +build linux darwin freebsd openbsd netbsd dragonfly
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin dragonfly freebsd linux netbsd openbsd
+
+package unix
+
+import "unsafe"
+
+// fcntl64Syscall is usually SYS_FCNTL, but is overridden on 32-bit Linux
+// systems by flock_linux_32bit.go to be SYS_FCNTL64.
+var fcntl64Syscall uintptr = SYS_FCNTL
+
+// FcntlFlock performs a fcntl syscall for the F_GETLK, F_SETLK or F_SETLKW command.
+func FcntlFlock(fd uintptr, cmd int, lk *Flock_t) error {
+ _, _, errno := Syscall(fcntl64Syscall, fd, uintptr(cmd), uintptr(unsafe.Pointer(lk)))
+ if errno == 0 {
+ return nil
+ }
+ return errno
+}
diff --git a/vendor/golang.org/x/sys/unix/flock_linux_32bit.go b/vendor/golang.org/x/sys/unix/flock_linux_32bit.go
new file mode 100644
index 00000000..fc0e50e0
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/flock_linux_32bit.go
@@ -0,0 +1,13 @@
+// +build linux,386 linux,arm linux,mips linux,mipsle
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package unix
+
+func init() {
+ // On 32-bit Linux systems, the fcntl syscall that matches Go's
+ // Flock_t type is SYS_FCNTL64, not SYS_FCNTL.
+ fcntl64Syscall = SYS_FCNTL64
+}
diff --git a/vendor/golang.org/x/sys/unix/gccgo.go b/vendor/golang.org/x/sys/unix/gccgo.go
new file mode 100644
index 00000000..94c82321
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/gccgo.go
@@ -0,0 +1,46 @@
+// 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 gccgo
+
+package unix
+
+import "syscall"
+
+// We can't use the gc-syntax .s files for gccgo. On the plus side
+// much of the functionality can be written directly in Go.
+
+//extern gccgoRealSyscall
+func realSyscall(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r, errno uintptr)
+
+func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno) {
+ syscall.Entersyscall()
+ r, errno := realSyscall(trap, a1, a2, a3, 0, 0, 0, 0, 0, 0)
+ syscall.Exitsyscall()
+ return r, 0, syscall.Errno(errno)
+}
+
+func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno) {
+ syscall.Entersyscall()
+ r, errno := realSyscall(trap, a1, a2, a3, a4, a5, a6, 0, 0, 0)
+ syscall.Exitsyscall()
+ return r, 0, syscall.Errno(errno)
+}
+
+func Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno) {
+ syscall.Entersyscall()
+ r, errno := realSyscall(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9)
+ syscall.Exitsyscall()
+ return r, 0, syscall.Errno(errno)
+}
+
+func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno) {
+ r, errno := realSyscall(trap, a1, a2, a3, 0, 0, 0, 0, 0, 0)
+ return r, 0, syscall.Errno(errno)
+}
+
+func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno) {
+ r, errno := realSyscall(trap, a1, a2, a3, a4, a5, a6, 0, 0, 0)
+ return r, 0, syscall.Errno(errno)
+}
diff --git a/vendor/golang.org/x/sys/unix/gccgo_c.c b/vendor/golang.org/x/sys/unix/gccgo_c.c
new file mode 100644
index 00000000..07f6be03
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/gccgo_c.c
@@ -0,0 +1,41 @@
+// 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 gccgo
+
+#include
+#include
+#include
+
+#define _STRINGIFY2_(x) #x
+#define _STRINGIFY_(x) _STRINGIFY2_(x)
+#define GOSYM_PREFIX _STRINGIFY_(__USER_LABEL_PREFIX__)
+
+// Call syscall from C code because the gccgo support for calling from
+// Go to C does not support varargs functions.
+
+struct ret {
+ uintptr_t r;
+ uintptr_t err;
+};
+
+struct ret
+gccgoRealSyscall(uintptr_t trap, uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, uintptr_t a5, uintptr_t a6, uintptr_t a7, uintptr_t a8, uintptr_t a9)
+{
+ struct ret r;
+
+ errno = 0;
+ r.r = syscall(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+ r.err = errno;
+ return r;
+}
+
+// Define the use function in C so that it is not inlined.
+
+extern void use(void *) __asm__ (GOSYM_PREFIX GOPKGPATH ".use") __attribute__((noinline));
+
+void
+use(void *p __attribute__ ((unused)))
+{
+}
diff --git a/vendor/golang.org/x/sys/unix/gccgo_linux_amd64.go b/vendor/golang.org/x/sys/unix/gccgo_linux_amd64.go
new file mode 100644
index 00000000..bffe1a77
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/gccgo_linux_amd64.go
@@ -0,0 +1,20 @@
+// 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 gccgo,linux,amd64
+
+package unix
+
+import "syscall"
+
+//extern gettimeofday
+func realGettimeofday(*Timeval, *byte) int32
+
+func gettimeofday(tv *Timeval) (err syscall.Errno) {
+ r := realGettimeofday(tv, nil)
+ if r < 0 {
+ return syscall.GetErrno()
+ }
+ return 0
+}
diff --git a/vendor/golang.org/x/sys/unix/gccgo_linux_sparc64.go b/vendor/golang.org/x/sys/unix/gccgo_linux_sparc64.go
new file mode 100644
index 00000000..56332692
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/gccgo_linux_sparc64.go
@@ -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
+}
diff --git a/vendor/golang.org/x/sys/unix/linux/Dockerfile b/vendor/golang.org/x/sys/unix/linux/Dockerfile
new file mode 100644
index 00000000..4397143c
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/linux/Dockerfile
@@ -0,0 +1,48 @@
+FROM ubuntu:16.04
+
+# Dependencies to get the git sources and go binaries
+RUN apt-get update && apt-get install -y \
+ curl \
+ git \
+ && rm -rf /var/lib/apt/lists/*
+
+# Get the git sources. If not cached, this takes O(5 minutes).
+WORKDIR /git
+RUN git config --global advice.detachedHead false
+# Linux Kernel: Released 19 Feb 2017
+RUN git clone --branch v4.10 --depth 1 https://kernel.googlesource.com/pub/scm/linux/kernel/git/torvalds/linux
+# GNU C library: Released 05 Feb 2017 (we should try to get a secure way to clone this)
+RUN git clone --branch glibc-2.25 --depth 1 git://sourceware.org/git/glibc.git
+
+# Get Go 1.8 (https://github.com/docker-library/golang/blob/master/1.8/Dockerfile)
+ENV GOLANG_VERSION 1.8
+ENV GOLANG_DOWNLOAD_URL https://golang.org/dl/go$GOLANG_VERSION.linux-amd64.tar.gz
+ENV GOLANG_DOWNLOAD_SHA256 53ab94104ee3923e228a2cb2116e5e462ad3ebaeea06ff04463479d7f12d27ca
+
+RUN curl -fsSL "$GOLANG_DOWNLOAD_URL" -o golang.tar.gz \
+ && echo "$GOLANG_DOWNLOAD_SHA256 golang.tar.gz" | sha256sum -c - \
+ && tar -C /usr/local -xzf golang.tar.gz \
+ && rm golang.tar.gz
+
+ENV PATH /usr/local/go/bin:$PATH
+
+# Linux and Glibc build dependencies
+RUN apt-get update && apt-get install -y \
+ gawk make python \
+ gcc gcc-multilib \
+ gettext texinfo \
+ && rm -rf /var/lib/apt/lists/*
+# Emulator and cross compilers
+RUN apt-get update && apt-get install -y \
+ qemu \
+ gcc-aarch64-linux-gnu gcc-arm-linux-gnueabi \
+ gcc-mips-linux-gnu gcc-mips64-linux-gnuabi64 \
+ gcc-mips64el-linux-gnuabi64 gcc-mipsel-linux-gnu \
+ gcc-powerpc64-linux-gnu gcc-powerpc64le-linux-gnu \
+ gcc-s390x-linux-gnu gcc-sparc64-linux-gnu \
+ && rm -rf /var/lib/apt/lists/*
+
+# Let the scripts know they are in the docker environment
+ENV GOLANG_SYS_BUILD docker
+WORKDIR /build
+ENTRYPOINT ["go", "run", "linux/mkall.go", "/git/linux", "/git/glibc"]
diff --git a/vendor/golang.org/x/sys/unix/linux/mkall.go b/vendor/golang.org/x/sys/unix/linux/mkall.go
new file mode 100644
index 00000000..429754f1
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/linux/mkall.go
@@ -0,0 +1,379 @@
+// Copyright 2017 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.
+
+// linux/mkall.go - Generates all Linux zsysnum, zsyscall, zerror, and ztype
+// files for all 11 linux architectures supported by the go compiler. See
+// README.md for more information about the build system.
+
+// To run it you must have a git checkout of the Linux kernel and glibc. Once
+// the appropriate sources are ready, the program is run as:
+// go run linux/mkall.go
+
+// +build ignore
+
+package main
+
+import (
+ "fmt"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "runtime"
+ "strings"
+)
+
+// These will be paths to the appropriate source directories.
+var LinuxDir string
+var GlibcDir string
+
+const TempDir = "/tmp"
+const IncludeDir = TempDir + "/include" // To hold our C headers
+const BuildDir = TempDir + "/build" // To hold intermediate build files
+
+const GOOS = "linux" // Only for Linux targets
+const BuildArch = "amd64" // Must be built on this architecture
+const MinKernel = "2.6.23" // https://golang.org/doc/install#requirements
+
+type target struct {
+ GoArch string // Architecture name according to Go
+ LinuxArch string // Architecture name according to the Linux Kernel
+ GNUArch string // Architecture name according to GNU tools (https://wiki.debian.org/Multiarch/Tuples)
+ BigEndian bool // Default Little Endian
+ SignedChar bool // Is -fsigned-char needed (default no)
+ Bits int
+}
+
+// List of the 11 Linux targets supported by the go compiler. sparc64 is not
+// currently supported, though a port is in progress.
+var targets = []target{
+ {
+ GoArch: "386",
+ LinuxArch: "x86",
+ GNUArch: "i686-linux-gnu", // Note "i686" not "i386"
+ Bits: 32,
+ },
+ {
+ GoArch: "amd64",
+ LinuxArch: "x86",
+ GNUArch: "x86_64-linux-gnu",
+ Bits: 64,
+ },
+ {
+ GoArch: "arm64",
+ LinuxArch: "arm64",
+ GNUArch: "aarch64-linux-gnu",
+ SignedChar: true,
+ Bits: 64,
+ },
+ {
+ GoArch: "arm",
+ LinuxArch: "arm",
+ GNUArch: "arm-linux-gnueabi",
+ Bits: 32,
+ },
+ {
+ GoArch: "mips",
+ LinuxArch: "mips",
+ GNUArch: "mips-linux-gnu",
+ BigEndian: true,
+ Bits: 32,
+ },
+ {
+ GoArch: "mipsle",
+ LinuxArch: "mips",
+ GNUArch: "mipsel-linux-gnu",
+ Bits: 32,
+ },
+ {
+ GoArch: "mips64",
+ LinuxArch: "mips",
+ GNUArch: "mips64-linux-gnuabi64",
+ BigEndian: true,
+ Bits: 64,
+ },
+ {
+ GoArch: "mips64le",
+ LinuxArch: "mips",
+ GNUArch: "mips64el-linux-gnuabi64",
+ Bits: 64,
+ },
+ {
+ GoArch: "ppc64",
+ LinuxArch: "powerpc",
+ GNUArch: "powerpc64-linux-gnu",
+ BigEndian: true,
+ Bits: 64,
+ },
+ {
+ GoArch: "ppc64le",
+ LinuxArch: "powerpc",
+ GNUArch: "powerpc64le-linux-gnu",
+ Bits: 64,
+ },
+ {
+ GoArch: "s390x",
+ LinuxArch: "s390",
+ GNUArch: "s390x-linux-gnu",
+ BigEndian: true,
+ SignedChar: true,
+ Bits: 64,
+ },
+ // {
+ // GoArch: "sparc64",
+ // LinuxArch: "sparc",
+ // GNUArch: "sparc64-linux-gnu",
+ // BigEndian: true,
+ // Bits: 64,
+ // },
+}
+
+func main() {
+ if runtime.GOOS != GOOS || runtime.GOARCH != BuildArch {
+ fmt.Printf("Build system has GOOS_GOARCH = %s_%s, need %s_%s\n",
+ runtime.GOOS, runtime.GOARCH, GOOS, BuildArch)
+ return
+ }
+
+ // Check that we are using the new build system if we should
+ if os.Getenv("GOLANG_SYS_BUILD") != "docker" {
+ fmt.Println("In the new build system, mkall.go should not be called directly.")
+ fmt.Println("See README.md")
+ return
+ }
+
+ // Parse the command line options
+ if len(os.Args) != 3 {
+ fmt.Println("USAGE: go run linux/mkall.go ")
+ return
+ }
+ LinuxDir = os.Args[1]
+ GlibcDir = os.Args[2]
+
+ for _, t := range targets {
+ fmt.Printf("----- GENERATING: %s -----\n", t.GoArch)
+ if err := t.generateFiles(); err != nil {
+ fmt.Printf("%v\n***** FAILURE: %s *****\n\n", err, t.GoArch)
+ } else {
+ fmt.Printf("----- SUCCESS: %s -----\n\n", t.GoArch)
+ }
+ }
+}
+
+// Makes an exec.Cmd with Stderr attached to os.Stderr
+func makeCommand(name string, args ...string) *exec.Cmd {
+ cmd := exec.Command(name, args...)
+ cmd.Stderr = os.Stderr
+ return cmd
+}
+
+// Runs the command, pipes output to a formatter, pipes that to an output file.
+func (t *target) commandFormatOutput(formatter string, outputFile string,
+ name string, args ...string) (err error) {
+ mainCmd := makeCommand(name, args...)
+
+ fmtCmd := makeCommand(formatter)
+ if formatter == "mkpost" {
+ fmtCmd = makeCommand("go", "run", "mkpost.go")
+ // Set GOARCH_TARGET so mkpost knows what GOARCH is..
+ fmtCmd.Env = append(os.Environ(), "GOARCH_TARGET="+t.GoArch)
+ // Set GOARCH to host arch for mkpost, so it can run natively.
+ for i, s := range fmtCmd.Env {
+ if strings.HasPrefix(s, "GOARCH=") {
+ fmtCmd.Env[i] = "GOARCH=" + BuildArch
+ }
+ }
+ }
+
+ // mainCmd | fmtCmd > outputFile
+ if fmtCmd.Stdin, err = mainCmd.StdoutPipe(); err != nil {
+ return
+ }
+ if fmtCmd.Stdout, err = os.Create(outputFile); err != nil {
+ return
+ }
+
+ // Make sure the formatter eventually closes
+ if err = fmtCmd.Start(); err != nil {
+ return
+ }
+ defer func() {
+ fmtErr := fmtCmd.Wait()
+ if err == nil {
+ err = fmtErr
+ }
+ }()
+
+ return mainCmd.Run()
+}
+
+// Generates all the files for a Linux target
+func (t *target) generateFiles() error {
+ // Setup environment variables
+ os.Setenv("GOOS", GOOS)
+ os.Setenv("GOARCH", t.GoArch)
+
+ // Get appropriate compiler and emulator (unless on x86)
+ if t.LinuxArch != "x86" {
+ // Check/Setup cross compiler
+ compiler := t.GNUArch + "-gcc"
+ if _, err := exec.LookPath(compiler); err != nil {
+ return err
+ }
+ os.Setenv("CC", compiler)
+
+ // Check/Setup emulator (usually first component of GNUArch)
+ qemuArchName := t.GNUArch[:strings.Index(t.GNUArch, "-")]
+ if t.LinuxArch == "powerpc" {
+ qemuArchName = t.GoArch
+ }
+ os.Setenv("GORUN", "qemu-"+qemuArchName)
+ } else {
+ os.Setenv("CC", "gcc")
+ }
+
+ // Make the include directory and fill it with headers
+ if err := os.MkdirAll(IncludeDir, os.ModePerm); err != nil {
+ return err
+ }
+ defer os.RemoveAll(IncludeDir)
+ if err := t.makeHeaders(); err != nil {
+ return fmt.Errorf("could not make header files: %v", err)
+ }
+ fmt.Println("header files generated")
+
+ // Make each of the four files
+ if err := t.makeZSysnumFile(); err != nil {
+ return fmt.Errorf("could not make zsysnum file: %v", err)
+ }
+ fmt.Println("zsysnum file generated")
+
+ if err := t.makeZSyscallFile(); err != nil {
+ return fmt.Errorf("could not make zsyscall file: %v", err)
+ }
+ fmt.Println("zsyscall file generated")
+
+ if err := t.makeZTypesFile(); err != nil {
+ return fmt.Errorf("could not make ztypes file: %v", err)
+ }
+ fmt.Println("ztypes file generated")
+
+ if err := t.makeZErrorsFile(); err != nil {
+ return fmt.Errorf("could not make zerrors file: %v", err)
+ }
+ fmt.Println("zerrors file generated")
+
+ return nil
+}
+
+// Create the Linux and glibc headers in the include directory.
+func (t *target) makeHeaders() error {
+ // Make the Linux headers we need for this architecture
+ linuxMake := makeCommand("make", "headers_install", "ARCH="+t.LinuxArch, "INSTALL_HDR_PATH="+TempDir)
+ linuxMake.Dir = LinuxDir
+ if err := linuxMake.Run(); err != nil {
+ return err
+ }
+
+ // A Temporary build directory for glibc
+ if err := os.MkdirAll(BuildDir, os.ModePerm); err != nil {
+ return err
+ }
+ defer os.RemoveAll(BuildDir)
+
+ // Make the glibc headers we need for this architecture
+ confScript := filepath.Join(GlibcDir, "configure")
+ glibcConf := makeCommand(confScript, "--prefix="+TempDir, "--host="+t.GNUArch, "--enable-kernel="+MinKernel)
+ glibcConf.Dir = BuildDir
+ if err := glibcConf.Run(); err != nil {
+ return err
+ }
+ glibcMake := makeCommand("make", "install-headers")
+ glibcMake.Dir = BuildDir
+ if err := glibcMake.Run(); err != nil {
+ return err
+ }
+ // We only need an empty stubs file
+ stubsFile := filepath.Join(IncludeDir, "gnu/stubs.h")
+ if file, err := os.Create(stubsFile); err != nil {
+ return err
+ } else {
+ file.Close()
+ }
+
+ return nil
+}
+
+// makes the zsysnum_linux_$GOARCH.go file
+func (t *target) makeZSysnumFile() error {
+ zsysnumFile := fmt.Sprintf("zsysnum_linux_%s.go", t.GoArch)
+ unistdFile := filepath.Join(IncludeDir, "asm/unistd.h")
+
+ args := append(t.cFlags(), unistdFile)
+ return t.commandFormatOutput("gofmt", zsysnumFile, "linux/mksysnum.pl", args...)
+}
+
+// makes the zsyscall_linux_$GOARCH.go file
+func (t *target) makeZSyscallFile() error {
+ zsyscallFile := fmt.Sprintf("zsyscall_linux_%s.go", t.GoArch)
+ // Find the correct architecture syscall file (might end with x.go)
+ archSyscallFile := fmt.Sprintf("syscall_linux_%s.go", t.GoArch)
+ if _, err := os.Stat(archSyscallFile); os.IsNotExist(err) {
+ shortArch := strings.TrimSuffix(t.GoArch, "le")
+ archSyscallFile = fmt.Sprintf("syscall_linux_%sx.go", shortArch)
+ }
+
+ args := append(t.mksyscallFlags(), "-tags", "linux,"+t.GoArch,
+ "syscall_linux.go", archSyscallFile)
+ return t.commandFormatOutput("gofmt", zsyscallFile, "./mksyscall.pl", args...)
+}
+
+// makes the zerrors_linux_$GOARCH.go file
+func (t *target) makeZErrorsFile() error {
+ zerrorsFile := fmt.Sprintf("zerrors_linux_%s.go", t.GoArch)
+
+ return t.commandFormatOutput("gofmt", zerrorsFile, "./mkerrors.sh", t.cFlags()...)
+}
+
+// makes the ztypes_linux_$GOARCH.go file
+func (t *target) makeZTypesFile() error {
+ ztypesFile := fmt.Sprintf("ztypes_linux_%s.go", t.GoArch)
+
+ args := []string{"tool", "cgo", "-godefs", "--"}
+ args = append(args, t.cFlags()...)
+ args = append(args, "linux/types.go")
+ return t.commandFormatOutput("mkpost", ztypesFile, "go", args...)
+}
+
+// Flags that should be given to gcc and cgo for this target
+func (t *target) cFlags() []string {
+ // Compile statically to avoid cross-architecture dynamic linking.
+ flags := []string{"-Wall", "-Werror", "-static", "-I" + IncludeDir}
+
+ // Architecture-specific flags
+ if t.SignedChar {
+ flags = append(flags, "-fsigned-char")
+ }
+ if t.LinuxArch == "x86" {
+ flags = append(flags, fmt.Sprintf("-m%d", t.Bits))
+ }
+
+ return flags
+}
+
+// Flags that should be given to mksyscall for this target
+func (t *target) mksyscallFlags() (flags []string) {
+ if t.Bits == 32 {
+ if t.BigEndian {
+ flags = append(flags, "-b32")
+ } else {
+ flags = append(flags, "-l32")
+ }
+ }
+
+ // This flag menas a 64-bit value should use (even, odd)-pair.
+ if t.GoArch == "arm" || (t.LinuxArch == "mips" && t.Bits == 32) {
+ flags = append(flags, "-arm")
+ }
+ return
+}
diff --git a/vendor/golang.org/x/sys/unix/linux/mksysnum.pl b/vendor/golang.org/x/sys/unix/linux/mksysnum.pl
new file mode 100755
index 00000000..63fd800b
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/linux/mksysnum.pl
@@ -0,0 +1,85 @@
+#!/usr/bin/env perl
+# 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.
+
+use strict;
+
+if($ENV{'GOARCH'} eq "" || $ENV{'GOOS'} eq "") {
+ print STDERR "GOARCH or GOOS not defined in environment\n";
+ exit 1;
+}
+
+# Check that we are using the new build system if we should
+if($ENV{'GOLANG_SYS_BUILD'} ne "docker") {
+ print STDERR "In the new build system, mksysnum should not be called directly.\n";
+ print STDERR "See README.md\n";
+ exit 1;
+}
+
+my $command = "$0 ". join(' ', @ARGV);
+
+print < 999){
+ # ignore deprecated syscalls that are no longer implemented
+ # https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/include/uapi/asm-generic/unistd.h?id=refs/heads/master#n716
+ return;
+ }
+ $name =~ y/a-z/A-Z/;
+ $num = $num + $offset;
+ print " SYS_$name = $num;\n";
+}
+
+my $prev;
+open(CC, "$ENV{'CC'} -E -dD @ARGV |") || die "can't run $ENV{'CC'}";
+while(){
+ if(/^#define __NR_Linux\s+([0-9]+)/){
+ # mips/mips64: extract offset
+ $offset = $1;
+ }
+ elsif(/^#define __NR(\w*)_SYSCALL_BASE\s+([0-9]+)/){
+ # arm: extract offset
+ $offset = $1;
+ }
+ elsif(/^#define __NR_syscalls\s+/) {
+ # ignore redefinitions of __NR_syscalls
+ }
+ elsif(/^#define __NR_(\w*)Linux_syscalls\s+/) {
+ # mips/mips64: ignore definitions about the number of syscalls
+ }
+ elsif(/^#define __NR_(\w+)\s+([0-9]+)/){
+ $prev = $2;
+ fmt($1, $2);
+ }
+ elsif(/^#define __NR3264_(\w+)\s+([0-9]+)/){
+ $prev = $2;
+ fmt($1, $2);
+ }
+ elsif(/^#define __NR_(\w+)\s+\(\w+\+\s*([0-9]+)\)/){
+ fmt($1, $prev+$2)
+ }
+ elsif(/^#define __NR_(\w+)\s+\(__NR_Linux \+ ([0-9]+)/){
+ fmt($1, $2);
+ }
+ elsif(/^#define __NR_(\w+)\s+\(__NR_SYSCALL_BASE \+ ([0-9]+)/){
+ fmt($1, $2);
+ }
+}
+
+print <
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+// On mips64, the glibc stat and kernel stat do not agree
+#if (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI64)
+
+// Use the stat defined by the kernel with a few modifications. These are:
+// * The time fields (like st_atime and st_atimensec) use the timespec
+// struct (like st_atim) for consitancy with the glibc fields.
+// * The padding fields get different names to not break compatibility.
+// * st_blocks is signed, again for compatibility.
+struct stat {
+ unsigned int st_dev;
+ unsigned int st_pad1[3]; // Reserved for st_dev expansion
+
+ unsigned long st_ino;
+
+ mode_t st_mode;
+ __u32 st_nlink;
+
+ uid_t st_uid;
+ gid_t st_gid;
+
+ unsigned int st_rdev;
+ unsigned int st_pad2[3]; // Reserved for st_rdev expansion
+
+ off_t st_size;
+
+ // These are declared as speperate fields in the kernel. Here we use
+ // the timespec struct for consistancy with the other stat structs.
+ struct timespec st_atim;
+ struct timespec st_mtim;
+ struct timespec st_ctim;
+
+ unsigned int st_blksize;
+ unsigned int st_pad4;
+
+ long st_blocks;
+};
+
+// These are needed because we do not include fcntl.h or sys/types.h
+#include
+#include
+
+#else
+
+// Use the stat defined by glibc
+#include
+#include
+
+#endif
+
+// Certain constants and structs are missing from the fs/crypto UAPI
+#define FS_MAX_KEY_SIZE 64
+struct fscrypt_key {
+ __u32 mode;
+ __u8 raw[FS_MAX_KEY_SIZE];
+ __u32 size;
+};
+
+#ifdef TCSETS2
+// On systems that have "struct termios2" use this as type Termios.
+typedef struct termios2 termios_t;
+#else
+typedef struct termios termios_t;
+#endif
+
+enum {
+ sizeofPtr = sizeof(void*),
+};
+
+union sockaddr_all {
+ struct sockaddr s1; // this one gets used for fields
+ struct sockaddr_in s2; // these pad it out
+ struct sockaddr_in6 s3;
+ struct sockaddr_un s4;
+ struct sockaddr_ll s5;
+ struct sockaddr_nl s6;
+};
+
+struct sockaddr_any {
+ struct sockaddr addr;
+ char pad[sizeof(union sockaddr_all) - sizeof(struct sockaddr)];
+};
+
+// copied from /usr/include/bluetooth/hci.h
+struct sockaddr_hci {
+ sa_family_t hci_family;
+ unsigned short hci_dev;
+ unsigned short hci_channel;
+};;
+
+// copied from /usr/include/linux/un.h
+struct my_sockaddr_un {
+ sa_family_t sun_family;
+#if defined(__ARM_EABI__) || defined(__powerpc64__)
+ // on ARM char is by default unsigned
+ signed char sun_path[108];
+#else
+ char sun_path[108];
+#endif
+};
+
+#ifdef __ARM_EABI__
+typedef struct user_regs PtraceRegs;
+#elif defined(__aarch64__)
+typedef struct user_pt_regs PtraceRegs;
+#elif defined(__powerpc64__)
+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
+typedef struct pt_regs PtraceRegs;
+#else
+typedef struct user_regs_struct PtraceRegs;
+#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.
+struct my_epoll_event {
+ uint32_t events;
+#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
+ // alignment requirements of EABI
+ int32_t padFd;
+#elif defined(__powerpc64__) || defined(__s390x__) || defined(__sparc__)
+ int32_t _padFd;
+#endif
+ int32_t fd;
+ int32_t pad;
+};
+
+*/
+import "C"
+
+// Machine characteristics; for internal use.
+
+const (
+ sizeofPtr = C.sizeofPtr
+ sizeofShort = C.sizeof_short
+ sizeofInt = C.sizeof_int
+ sizeofLong = C.sizeof_long
+ sizeofLongLong = C.sizeof_longlong
+ PathMax = C.PATH_MAX
+)
+
+// Basic types
+
+type (
+ _C_short C.short
+ _C_int C.int
+ _C_long C.long
+ _C_long_long C.longlong
+)
+
+// Time
+
+type Timespec C.struct_timespec
+
+type Timeval C.struct_timeval
+
+type Timex C.struct_timex
+
+type Time_t C.time_t
+
+type Tms C.struct_tms
+
+type Utimbuf C.struct_utimbuf
+
+// Processes
+
+type Rusage C.struct_rusage
+
+type Rlimit C.struct_rlimit
+
+type _Gid_t C.gid_t
+
+// Files
+
+type Stat_t C.struct_stat
+
+type Statfs_t C.struct_statfs
+
+type Dirent C.struct_dirent
+
+type Fsid C.fsid_t
+
+type Flock_t C.struct_flock
+
+// Filesystem Encryption
+
+type FscryptPolicy C.struct_fscrypt_policy
+
+type FscryptKey C.struct_fscrypt_key
+
+// Advice to Fadvise
+
+const (
+ FADV_NORMAL = C.POSIX_FADV_NORMAL
+ FADV_RANDOM = C.POSIX_FADV_RANDOM
+ FADV_SEQUENTIAL = C.POSIX_FADV_SEQUENTIAL
+ FADV_WILLNEED = C.POSIX_FADV_WILLNEED
+ FADV_DONTNEED = C.POSIX_FADV_DONTNEED
+ FADV_NOREUSE = C.POSIX_FADV_NOREUSE
+)
+
+// Sockets
+
+type RawSockaddrInet4 C.struct_sockaddr_in
+
+type RawSockaddrInet6 C.struct_sockaddr_in6
+
+type RawSockaddrUnix C.struct_my_sockaddr_un
+
+type RawSockaddrLinklayer C.struct_sockaddr_ll
+
+type RawSockaddrNetlink C.struct_sockaddr_nl
+
+type RawSockaddrHCI C.struct_sockaddr_hci
+
+type RawSockaddrCAN C.struct_sockaddr_can
+
+type RawSockaddrALG C.struct_sockaddr_alg
+
+type RawSockaddrVM C.struct_sockaddr_vm
+
+type RawSockaddr C.struct_sockaddr
+
+type RawSockaddrAny C.struct_sockaddr_any
+
+type _Socklen C.socklen_t
+
+type Linger C.struct_linger
+
+type Iovec C.struct_iovec
+
+type IPMreq C.struct_ip_mreq
+
+type IPMreqn C.struct_ip_mreqn
+
+type IPv6Mreq C.struct_ipv6_mreq
+
+type Msghdr C.struct_msghdr
+
+type Cmsghdr C.struct_cmsghdr
+
+type Inet4Pktinfo C.struct_in_pktinfo
+
+type Inet6Pktinfo C.struct_in6_pktinfo
+
+type IPv6MTUInfo C.struct_ip6_mtuinfo
+
+type ICMPv6Filter C.struct_icmp6_filter
+
+type Ucred C.struct_ucred
+
+type TCPInfo C.struct_tcp_info
+
+const (
+ SizeofSockaddrInet4 = C.sizeof_struct_sockaddr_in
+ SizeofSockaddrInet6 = C.sizeof_struct_sockaddr_in6
+ SizeofSockaddrAny = C.sizeof_struct_sockaddr_any
+ SizeofSockaddrUnix = C.sizeof_struct_sockaddr_un
+ SizeofSockaddrLinklayer = C.sizeof_struct_sockaddr_ll
+ SizeofSockaddrNetlink = C.sizeof_struct_sockaddr_nl
+ SizeofSockaddrHCI = C.sizeof_struct_sockaddr_hci
+ SizeofSockaddrCAN = C.sizeof_struct_sockaddr_can
+ SizeofSockaddrALG = C.sizeof_struct_sockaddr_alg
+ SizeofSockaddrVM = C.sizeof_struct_sockaddr_vm
+ SizeofLinger = C.sizeof_struct_linger
+ SizeofIPMreq = C.sizeof_struct_ip_mreq
+ SizeofIPMreqn = C.sizeof_struct_ip_mreqn
+ SizeofIPv6Mreq = C.sizeof_struct_ipv6_mreq
+ SizeofMsghdr = C.sizeof_struct_msghdr
+ SizeofCmsghdr = C.sizeof_struct_cmsghdr
+ SizeofInet4Pktinfo = C.sizeof_struct_in_pktinfo
+ SizeofInet6Pktinfo = C.sizeof_struct_in6_pktinfo
+ SizeofIPv6MTUInfo = C.sizeof_struct_ip6_mtuinfo
+ SizeofICMPv6Filter = C.sizeof_struct_icmp6_filter
+ SizeofUcred = C.sizeof_struct_ucred
+ SizeofTCPInfo = C.sizeof_struct_tcp_info
+)
+
+// Netlink routing and interface messages
+
+const (
+ IFA_UNSPEC = C.IFA_UNSPEC
+ IFA_ADDRESS = C.IFA_ADDRESS
+ IFA_LOCAL = C.IFA_LOCAL
+ IFA_LABEL = C.IFA_LABEL
+ IFA_BROADCAST = C.IFA_BROADCAST
+ IFA_ANYCAST = C.IFA_ANYCAST
+ IFA_CACHEINFO = C.IFA_CACHEINFO
+ IFA_MULTICAST = C.IFA_MULTICAST
+ IFLA_UNSPEC = C.IFLA_UNSPEC
+ IFLA_ADDRESS = C.IFLA_ADDRESS
+ IFLA_BROADCAST = C.IFLA_BROADCAST
+ IFLA_IFNAME = C.IFLA_IFNAME
+ IFLA_MTU = C.IFLA_MTU
+ IFLA_LINK = C.IFLA_LINK
+ IFLA_QDISC = C.IFLA_QDISC
+ IFLA_STATS = C.IFLA_STATS
+ IFLA_COST = C.IFLA_COST
+ IFLA_PRIORITY = C.IFLA_PRIORITY
+ IFLA_MASTER = C.IFLA_MASTER
+ IFLA_WIRELESS = C.IFLA_WIRELESS
+ IFLA_PROTINFO = C.IFLA_PROTINFO
+ IFLA_TXQLEN = C.IFLA_TXQLEN
+ IFLA_MAP = C.IFLA_MAP
+ IFLA_WEIGHT = C.IFLA_WEIGHT
+ IFLA_OPERSTATE = C.IFLA_OPERSTATE
+ IFLA_LINKMODE = C.IFLA_LINKMODE
+ IFLA_LINKINFO = C.IFLA_LINKINFO
+ IFLA_NET_NS_PID = C.IFLA_NET_NS_PID
+ IFLA_IFALIAS = C.IFLA_IFALIAS
+ IFLA_MAX = C.IFLA_MAX
+ RT_SCOPE_UNIVERSE = C.RT_SCOPE_UNIVERSE
+ RT_SCOPE_SITE = C.RT_SCOPE_SITE
+ RT_SCOPE_LINK = C.RT_SCOPE_LINK
+ RT_SCOPE_HOST = C.RT_SCOPE_HOST
+ RT_SCOPE_NOWHERE = C.RT_SCOPE_NOWHERE
+ RT_TABLE_UNSPEC = C.RT_TABLE_UNSPEC
+ RT_TABLE_COMPAT = C.RT_TABLE_COMPAT
+ RT_TABLE_DEFAULT = C.RT_TABLE_DEFAULT
+ RT_TABLE_MAIN = C.RT_TABLE_MAIN
+ RT_TABLE_LOCAL = C.RT_TABLE_LOCAL
+ RT_TABLE_MAX = C.RT_TABLE_MAX
+ RTA_UNSPEC = C.RTA_UNSPEC
+ RTA_DST = C.RTA_DST
+ RTA_SRC = C.RTA_SRC
+ RTA_IIF = C.RTA_IIF
+ RTA_OIF = C.RTA_OIF
+ RTA_GATEWAY = C.RTA_GATEWAY
+ RTA_PRIORITY = C.RTA_PRIORITY
+ RTA_PREFSRC = C.RTA_PREFSRC
+ RTA_METRICS = C.RTA_METRICS
+ RTA_MULTIPATH = C.RTA_MULTIPATH
+ RTA_FLOW = C.RTA_FLOW
+ RTA_CACHEINFO = C.RTA_CACHEINFO
+ RTA_TABLE = C.RTA_TABLE
+ RTN_UNSPEC = C.RTN_UNSPEC
+ RTN_UNICAST = C.RTN_UNICAST
+ RTN_LOCAL = C.RTN_LOCAL
+ RTN_BROADCAST = C.RTN_BROADCAST
+ RTN_ANYCAST = C.RTN_ANYCAST
+ RTN_MULTICAST = C.RTN_MULTICAST
+ RTN_BLACKHOLE = C.RTN_BLACKHOLE
+ RTN_UNREACHABLE = C.RTN_UNREACHABLE
+ RTN_PROHIBIT = C.RTN_PROHIBIT
+ RTN_THROW = C.RTN_THROW
+ RTN_NAT = C.RTN_NAT
+ RTN_XRESOLVE = C.RTN_XRESOLVE
+ RTNLGRP_NONE = C.RTNLGRP_NONE
+ RTNLGRP_LINK = C.RTNLGRP_LINK
+ RTNLGRP_NOTIFY = C.RTNLGRP_NOTIFY
+ RTNLGRP_NEIGH = C.RTNLGRP_NEIGH
+ RTNLGRP_TC = C.RTNLGRP_TC
+ RTNLGRP_IPV4_IFADDR = C.RTNLGRP_IPV4_IFADDR
+ RTNLGRP_IPV4_MROUTE = C.RTNLGRP_IPV4_MROUTE
+ RTNLGRP_IPV4_ROUTE = C.RTNLGRP_IPV4_ROUTE
+ RTNLGRP_IPV4_RULE = C.RTNLGRP_IPV4_RULE
+ RTNLGRP_IPV6_IFADDR = C.RTNLGRP_IPV6_IFADDR
+ RTNLGRP_IPV6_MROUTE = C.RTNLGRP_IPV6_MROUTE
+ RTNLGRP_IPV6_ROUTE = C.RTNLGRP_IPV6_ROUTE
+ RTNLGRP_IPV6_IFINFO = C.RTNLGRP_IPV6_IFINFO
+ RTNLGRP_IPV6_PREFIX = C.RTNLGRP_IPV6_PREFIX
+ RTNLGRP_IPV6_RULE = C.RTNLGRP_IPV6_RULE
+ RTNLGRP_ND_USEROPT = C.RTNLGRP_ND_USEROPT
+ SizeofNlMsghdr = C.sizeof_struct_nlmsghdr
+ SizeofNlMsgerr = C.sizeof_struct_nlmsgerr
+ SizeofRtGenmsg = C.sizeof_struct_rtgenmsg
+ SizeofNlAttr = C.sizeof_struct_nlattr
+ SizeofRtAttr = C.sizeof_struct_rtattr
+ SizeofIfInfomsg = C.sizeof_struct_ifinfomsg
+ SizeofIfAddrmsg = C.sizeof_struct_ifaddrmsg
+ SizeofRtMsg = C.sizeof_struct_rtmsg
+ SizeofRtNexthop = C.sizeof_struct_rtnexthop
+)
+
+type NlMsghdr C.struct_nlmsghdr
+
+type NlMsgerr C.struct_nlmsgerr
+
+type RtGenmsg C.struct_rtgenmsg
+
+type NlAttr C.struct_nlattr
+
+type RtAttr C.struct_rtattr
+
+type IfInfomsg C.struct_ifinfomsg
+
+type IfAddrmsg C.struct_ifaddrmsg
+
+type RtMsg C.struct_rtmsg
+
+type RtNexthop C.struct_rtnexthop
+
+// Linux socket filter
+
+const (
+ SizeofSockFilter = C.sizeof_struct_sock_filter
+ SizeofSockFprog = C.sizeof_struct_sock_fprog
+)
+
+type SockFilter C.struct_sock_filter
+
+type SockFprog C.struct_sock_fprog
+
+// Inotify
+
+type InotifyEvent C.struct_inotify_event
+
+const SizeofInotifyEvent = C.sizeof_struct_inotify_event
+
+// Ptrace
+
+// Register structures
+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
+
+type FdSet C.fd_set
+
+type Sysinfo_t C.struct_sysinfo
+
+type Utsname C.struct_utsname
+
+type Ustat_t C.struct_ustat
+
+type EpollEvent C.struct_my_epoll_event
+
+const (
+ AT_FDCWD = C.AT_FDCWD
+ AT_REMOVEDIR = C.AT_REMOVEDIR
+ AT_SYMLINK_FOLLOW = C.AT_SYMLINK_FOLLOW
+ 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
+
+type Termios C.termios_t
diff --git a/vendor/golang.org/x/sys/unix/mkall.sh b/vendor/golang.org/x/sys/unix/mkall.sh
new file mode 100755
index 00000000..f0d6566f
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/mkall.sh
@@ -0,0 +1,179 @@
+#!/usr/bin/env bash
+# Copyright 2009 The Go Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
+
+# This script runs or (given -n) prints suggested commands to generate files for
+# the Architecture/OS specified by the GOARCH and GOOS environment variables.
+# See README.md for more information about how the build system works.
+
+GOOSARCH="${GOOS}_${GOARCH}"
+
+# defaults
+mksyscall="./mksyscall.pl"
+mkerrors="./mkerrors.sh"
+zerrors="zerrors_$GOOSARCH.go"
+mksysctl=""
+zsysctl="zsysctl_$GOOSARCH.go"
+mksysnum=
+mktypes=
+run="sh"
+cmd=""
+
+case "$1" in
+-syscalls)
+ for i in zsyscall*go
+ do
+ # Run the command line that appears in the first line
+ # of the generated file to regenerate it.
+ sed 1q $i | sed 's;^// ;;' | sh > _$i && gofmt < _$i > $i
+ rm _$i
+ done
+ exit 0
+ ;;
+-n)
+ run="cat"
+ cmd="echo"
+ shift
+esac
+
+case "$#" in
+0)
+ ;;
+*)
+ echo 'usage: mkall.sh [-n]' 1>&2
+ exit 2
+esac
+
+if [[ "$GOOS" = "linux" ]] && [[ "$GOARCH" != "sparc64" ]]; then
+ # Use then new build system
+ # Files generated through docker (use $cmd so you can Ctl-C the build or run)
+ $cmd docker build --tag generate:$GOOS $GOOS
+ $cmd docker run --interactive --tty --volume $(dirname "$(readlink -f "$0")"):/build generate:$GOOS
+ exit
+fi
+
+GOOSARCH_in=syscall_$GOOSARCH.go
+case "$GOOSARCH" in
+_* | *_ | _)
+ echo 'undefined $GOOS_$GOARCH:' "$GOOSARCH" 1>&2
+ exit 1
+ ;;
+darwin_386)
+ mkerrors="$mkerrors -m32"
+ mksyscall="./mksyscall.pl -l32"
+ mksysnum="./mksysnum_darwin.pl $(xcrun --show-sdk-path --sdk macosx)/usr/include/sys/syscall.h"
+ mktypes="GOARCH=$GOARCH go tool cgo -godefs"
+ ;;
+darwin_amd64)
+ mkerrors="$mkerrors -m64"
+ mksysnum="./mksysnum_darwin.pl $(xcrun --show-sdk-path --sdk macosx)/usr/include/sys/syscall.h"
+ mktypes="GOARCH=$GOARCH go tool cgo -godefs"
+ ;;
+darwin_arm)
+ mkerrors="$mkerrors"
+ mksysnum="./mksysnum_darwin.pl /usr/include/sys/syscall.h"
+ mktypes="GOARCH=$GOARCH go tool cgo -godefs"
+ ;;
+darwin_arm64)
+ mkerrors="$mkerrors -m64"
+ mksysnum="./mksysnum_darwin.pl $(xcrun --show-sdk-path --sdk iphoneos)/usr/include/sys/syscall.h"
+ mktypes="GOARCH=$GOARCH go tool cgo -godefs"
+ ;;
+dragonfly_386)
+ mkerrors="$mkerrors -m32"
+ mksyscall="./mksyscall.pl -l32 -dragonfly"
+ mksysnum="curl -s 'http://gitweb.dragonflybsd.org/dragonfly.git/blob_plain/HEAD:/sys/kern/syscalls.master' | ./mksysnum_dragonfly.pl"
+ mktypes="GOARCH=$GOARCH go tool cgo -godefs"
+ ;;
+dragonfly_amd64)
+ mkerrors="$mkerrors -m64"
+ mksyscall="./mksyscall.pl -dragonfly"
+ mksysnum="curl -s 'http://gitweb.dragonflybsd.org/dragonfly.git/blob_plain/HEAD:/sys/kern/syscalls.master' | ./mksysnum_dragonfly.pl"
+ mktypes="GOARCH=$GOARCH go tool cgo -godefs"
+ ;;
+freebsd_386)
+ mkerrors="$mkerrors -m32"
+ mksyscall="./mksyscall.pl -l32"
+ mksysnum="curl -s 'http://svn.freebsd.org/base/stable/10/sys/kern/syscalls.master' | ./mksysnum_freebsd.pl"
+ mktypes="GOARCH=$GOARCH go tool cgo -godefs"
+ ;;
+freebsd_amd64)
+ mkerrors="$mkerrors -m64"
+ mksysnum="curl -s 'http://svn.freebsd.org/base/stable/10/sys/kern/syscalls.master' | ./mksysnum_freebsd.pl"
+ mktypes="GOARCH=$GOARCH go tool cgo -godefs"
+ ;;
+freebsd_arm)
+ mkerrors="$mkerrors"
+ mksyscall="./mksyscall.pl -l32 -arm"
+ mksysnum="curl -s 'http://svn.freebsd.org/base/stable/10/sys/kern/syscalls.master' | ./mksysnum_freebsd.pl"
+ # Let the type of C char be signed for making the bare syscall
+ # API consistent across over platforms.
+ mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
+ ;;
+linux_sparc64)
+ GOOSARCH_in=syscall_linux_sparc64.go
+ unistd_h=/usr/include/sparc64-linux-gnu/asm/unistd.h
+ mkerrors="$mkerrors -m64"
+ mksysnum="./mksysnum_linux.pl $unistd_h"
+ mktypes="GOARCH=$GOARCH go tool cgo -godefs"
+ ;;
+netbsd_386)
+ mkerrors="$mkerrors -m32"
+ mksyscall="./mksyscall.pl -l32 -netbsd"
+ mksysnum="curl -s 'http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_netbsd.pl"
+ mktypes="GOARCH=$GOARCH go tool cgo -godefs"
+ ;;
+netbsd_amd64)
+ mkerrors="$mkerrors -m64"
+ mksyscall="./mksyscall.pl -netbsd"
+ mksysnum="curl -s 'http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_netbsd.pl"
+ mktypes="GOARCH=$GOARCH go tool cgo -godefs"
+ ;;
+openbsd_386)
+ mkerrors="$mkerrors -m32"
+ mksyscall="./mksyscall.pl -l32 -openbsd"
+ mksysctl="./mksysctl_openbsd.pl"
+ zsysctl="zsysctl_openbsd.go"
+ mksysnum="curl -s 'http://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_openbsd.pl"
+ mktypes="GOARCH=$GOARCH go tool cgo -godefs"
+ ;;
+openbsd_amd64)
+ mkerrors="$mkerrors -m64"
+ mksyscall="./mksyscall.pl -openbsd"
+ mksysctl="./mksysctl_openbsd.pl"
+ zsysctl="zsysctl_openbsd.go"
+ mksysnum="curl -s 'http://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_openbsd.pl"
+ mktypes="GOARCH=$GOARCH go tool cgo -godefs"
+ ;;
+solaris_amd64)
+ mksyscall="./mksyscall_solaris.pl"
+ mkerrors="$mkerrors -m64"
+ mksysnum=
+ mktypes="GOARCH=$GOARCH go tool cgo -godefs"
+ ;;
+*)
+ echo 'unrecognized $GOOS_$GOARCH: ' "$GOOSARCH" 1>&2
+ exit 1
+ ;;
+esac
+
+(
+ if [ -n "$mkerrors" ]; then echo "$mkerrors |gofmt >$zerrors"; fi
+ case "$GOOS" in
+ *)
+ syscall_goos="syscall_$GOOS.go"
+ case "$GOOS" in
+ darwin | dragonfly | freebsd | netbsd | openbsd)
+ syscall_goos="syscall_bsd.go $syscall_goos"
+ ;;
+ esac
+ if [ -n "$mksyscall" ]; then echo "$mksyscall -tags $GOOS,$GOARCH $syscall_goos $GOOSARCH_in |gofmt >zsyscall_$GOOSARCH.go"; fi
+ ;;
+ esac
+ if [ -n "$mksysctl" ]; then echo "$mksysctl |gofmt >$zsysctl"; fi
+ if [ -n "$mksysnum" ]; then echo "$mksysnum |gofmt >zsysnum_$GOOSARCH.go"; fi
+ if [ -n "$mktypes" ]; then
+ echo "$mktypes types_$GOOS.go | go run mkpost.go > ztypes_$GOOSARCH.go";
+ fi
+) | $run
diff --git a/vendor/golang.org/x/sys/unix/mkerrors.sh b/vendor/golang.org/x/sys/unix/mkerrors.sh
new file mode 100755
index 00000000..1bd1c9e6
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/mkerrors.sh
@@ -0,0 +1,545 @@
+#!/usr/bin/env bash
+# Copyright 2009 The Go Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
+
+# Generate Go code listing errors and other #defined constant
+# values (ENAMETOOLONG etc.), by asking the preprocessor
+# about the definitions.
+
+unset LANG
+export LC_ALL=C
+export LC_CTYPE=C
+
+if test -z "$GOARCH" -o -z "$GOOS"; then
+ echo 1>&2 "GOARCH or GOOS not defined in environment"
+ exit 1
+fi
+
+# Check that we are using the new build system if we should
+if [[ "$GOOS" -eq "linux" ]] && [[ "$GOARCH" != "sparc64" ]]; then
+ if [[ "$GOLANG_SYS_BUILD" -ne "docker" ]]; then
+ echo 1>&2 "In the new build system, mkerrors should not be called directly."
+ echo 1>&2 "See README.md"
+ exit 1
+ fi
+fi
+
+CC=${CC:-cc}
+
+if [[ "$GOOS" -eq "solaris" ]]; then
+ # Assumes GNU versions of utilities in PATH.
+ export PATH=/usr/gnu/bin:$PATH
+fi
+
+uname=$(uname)
+
+includes_Darwin='
+#define _DARWIN_C_SOURCE
+#define KERNEL
+#define _DARWIN_USE_64_BIT_INODE
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+'
+
+includes_DragonFly='
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+'
+
+includes_FreeBSD='
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#if __FreeBSD__ >= 10
+#define IFT_CARP 0xf8 // IFT_CARP is deprecated in FreeBSD 10
+#undef SIOCAIFADDR
+#define SIOCAIFADDR _IOW(105, 26, struct oifaliasreq) // ifaliasreq contains if_data
+#undef SIOCSIFPHYADDR
+#define SIOCSIFPHYADDR _IOW(105, 70, struct oifaliasreq) // ifaliasreq contains if_data
+#endif
+'
+
+includes_Linux='
+#define _LARGEFILE_SOURCE
+#define _LARGEFILE64_SOURCE
+#ifndef __LP64__
+#define _FILE_OFFSET_BITS 64
+#endif
+#define _GNU_SOURCE
+
+// is broken on powerpc64, as it fails to include definitions of
+// these structures. We just include them copied from .
+#if defined(__powerpc__)
+struct sgttyb {
+ char sg_ispeed;
+ char sg_ospeed;
+ char sg_erase;
+ char sg_kill;
+ short sg_flags;
+};
+
+struct tchars {
+ char t_intrc;
+ char t_quitc;
+ char t_startc;
+ char t_stopc;
+ char t_eofc;
+ char t_brkc;
+};
+
+struct ltchars {
+ char t_suspc;
+ char t_dsuspc;
+ char t_rprntc;
+ char t_flushc;
+ char t_werasc;
+ char t_lnextc;
+};
+#endif
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#ifndef MSG_FASTOPEN
+#define MSG_FASTOPEN 0x20000000
+#endif
+
+#ifndef PTRACE_GETREGS
+#define PTRACE_GETREGS 0xc
+#endif
+
+#ifndef PTRACE_SETREGS
+#define PTRACE_SETREGS 0xd
+#endif
+
+#ifndef SOL_NETLINK
+#define SOL_NETLINK 270
+#endif
+
+#ifdef SOL_BLUETOOTH
+// SPARC includes this in /usr/include/sparc64-linux-gnu/bits/socket.h
+// but it is already in bluetooth_linux.go
+#undef SOL_BLUETOOTH
+#endif
+
+// Certain constants are missing from the fs/crypto UAPI
+#define FS_KEY_DESC_PREFIX "fscrypt:"
+#define FS_KEY_DESC_PREFIX_SIZE 8
+#define FS_MAX_KEY_SIZE 64
+'
+
+includes_NetBSD='
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+// Needed since refers to it...
+#define schedppq 1
+'
+
+includes_OpenBSD='
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+// We keep some constants not supported in OpenBSD 5.5 and beyond for
+// the promise of compatibility.
+#define EMUL_ENABLED 0x1
+#define EMUL_NATIVE 0x2
+#define IPV6_FAITH 0x1d
+#define IPV6_OPTIONS 0x1
+#define IPV6_RTHDR_STRICT 0x1
+#define IPV6_SOCKOPT_RESERVED1 0x3
+#define SIOCGIFGENERIC 0xc020693a
+#define SIOCSIFGENERIC 0x80206939
+#define WALTSIG 0x4
+'
+
+includes_SunOS='
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+'
+
+
+includes='
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+'
+ccflags="$@"
+
+# Write go tool cgo -godefs input.
+(
+ echo package unix
+ echo
+ echo '/*'
+ indirect="includes_$(uname)"
+ echo "${!indirect} $includes"
+ echo '*/'
+ echo 'import "C"'
+ echo 'import "syscall"'
+ echo
+ echo 'const ('
+
+ # The gcc command line prints all the #defines
+ # it encounters while processing the input
+ echo "${!indirect} $includes" | $CC -x c - -E -dM $ccflags |
+ awk '
+ $1 != "#define" || $2 ~ /\(/ || $3 == "" {next}
+
+ $2 ~ /^E([ABCD]X|[BIS]P|[SD]I|S|FL)$/ {next} # 386 registers
+ $2 ~ /^(SIGEV_|SIGSTKSZ|SIGRT(MIN|MAX))/ {next}
+ $2 ~ /^(SCM_SRCRT)$/ {next}
+ $2 ~ /^(MAP_FAILED)$/ {next}
+ $2 ~ /^ELF_.*$/ {next}# contains ELF_ARCH, etc.
+
+ $2 ~ /^EXTATTR_NAMESPACE_NAMES/ ||
+ $2 ~ /^EXTATTR_NAMESPACE_[A-Z]+_STRING/ {next}
+
+ $2 !~ /^ETH_/ &&
+ $2 !~ /^EPROC_/ &&
+ $2 !~ /^EQUIV_/ &&
+ $2 !~ /^EXPR_/ &&
+ $2 ~ /^E[A-Z0-9_]+$/ ||
+ $2 ~ /^B[0-9_]+$/ ||
+ $2 == "BOTHER" ||
+ $2 ~ /^CI?BAUD(EX)?$/ ||
+ $2 == "IBSHIFT" ||
+ $2 ~ /^V[A-Z0-9]+$/ ||
+ $2 ~ /^CS[A-Z0-9]/ ||
+ $2 ~ /^I(SIG|CANON|CRNL|UCLC|EXTEN|MAXBEL|STRIP|UTF8)$/ ||
+ $2 ~ /^IGN/ ||
+ $2 ~ /^IX(ON|ANY|OFF)$/ ||
+ $2 ~ /^IN(LCR|PCK)$/ ||
+ $2 ~ /(^FLU?SH)|(FLU?SH$)/ ||
+ $2 ~ /^C(LOCAL|READ|MSPAR|RTSCTS)$/ ||
+ $2 == "BRKINT" ||
+ $2 == "HUPCL" ||
+ $2 == "PENDIN" ||
+ $2 == "TOSTOP" ||
+ $2 == "XCASE" ||
+ $2 == "ALTWERASE" ||
+ $2 == "NOKERNINFO" ||
+ $2 ~ /^PAR/ ||
+ $2 ~ /^SIG[^_]/ ||
+ $2 ~ /^O[CNPFPL][A-Z]+[^_][A-Z]+$/ ||
+ $2 ~ /^(NL|CR|TAB|BS|VT|FF)DLY$/ ||
+ $2 ~ /^(NL|CR|TAB|BS|VT|FF)[0-9]$/ ||
+ $2 ~ /^O?XTABS$/ ||
+ $2 ~ /^TC[IO](ON|OFF)$/ ||
+ $2 ~ /^IN_/ ||
+ $2 ~ /^LOCK_(SH|EX|NB|UN)$/ ||
+ $2 ~ /^(AF|SOCK|SO|SOL|IPPROTO|IP|IPV6|ICMP6|TCP|EVFILT|NOTE|EV|SHUT|PROT|MAP|PACKET|MSG|SCM|MCL|DT|MADV|PR)_/ ||
+ $2 ~ /^FALLOC_/ ||
+ $2 == "ICMPV6_FILTER" ||
+ $2 == "SOMAXCONN" ||
+ $2 == "NAME_MAX" ||
+ $2 == "IFNAMSIZ" ||
+ $2 ~ /^CTL_(MAXNAME|NET|QUERY)$/ ||
+ $2 ~ /^SYSCTL_VERS/ ||
+ $2 ~ /^(MS|MNT)_/ ||
+ $2 ~ /^TUN(SET|GET|ATTACH|DETACH)/ ||
+ $2 ~ /^(O|F|FD|NAME|S|PTRACE|PT)_/ ||
+ $2 ~ /^LINUX_REBOOT_CMD_/ ||
+ $2 ~ /^LINUX_REBOOT_MAGIC[12]$/ ||
+ $2 !~ "NLA_TYPE_MASK" &&
+ $2 ~ /^(NETLINK|NLM|NLMSG|NLA|IFA|IFAN|RT|RTCF|RTN|RTPROT|RTNH|ARPHRD|ETH_P)_/ ||
+ $2 ~ /^SIOC/ ||
+ $2 ~ /^TIOC/ ||
+ $2 ~ /^TCGET/ ||
+ $2 ~ /^TCSET/ ||
+ $2 ~ /^TC(FLSH|SBRKP?|XONC)$/ ||
+ $2 !~ "RTF_BITS" &&
+ $2 ~ /^(IFF|IFT|NET_RT|RTM|RTF|RTV|RTA|RTAX)_/ ||
+ $2 ~ /^BIOC/ ||
+ $2 ~ /^RUSAGE_(SELF|CHILDREN|THREAD)/ ||
+ $2 ~ /^RLIMIT_(AS|CORE|CPU|DATA|FSIZE|NOFILE|STACK)|RLIM_INFINITY/ ||
+ $2 ~ /^PRIO_(PROCESS|PGRP|USER)/ ||
+ $2 ~ /^CLONE_[A-Z_]+/ ||
+ $2 !~ /^(BPF_TIMEVAL)$/ &&
+ $2 ~ /^(BPF|DLT)_/ ||
+ $2 ~ /^CLOCK_/ ||
+ $2 ~ /^CAN_/ ||
+ $2 ~ /^ALG_/ ||
+ $2 ~ /^FS_(POLICY_FLAGS|KEY_DESC|ENCRYPTION_MODE|[A-Z0-9_]+_KEY_SIZE|IOC_(GET|SET)_ENCRYPTION)/ ||
+ $2 ~ /^GRND_/ ||
+ $2 ~ /^SPLICE_/ ||
+ $2 ~ /^(VM|VMADDR)_/ ||
+ $2 !~ "WMESGLEN" &&
+ $2 ~ /^W[A-Z0-9]+$/ ||
+ $2 ~ /^BLK[A-Z]*(GET$|SET$|BUF$|PART$|SIZE)/ {printf("\t%s = C.%s\n", $2, $2)}
+ $2 ~ /^__WCOREFLAG$/ {next}
+ $2 ~ /^__W[A-Z0-9]+$/ {printf("\t%s = C.%s\n", substr($2,3), $2)}
+
+ {next}
+ ' | sort
+
+ echo ')'
+) >_const.go
+
+# Pull out the error names for later.
+errors=$(
+ echo '#include ' | $CC -x c - -E -dM $ccflags |
+ awk '$1=="#define" && $2 ~ /^E[A-Z0-9_]+$/ { print $2 }' |
+ sort
+)
+
+# Pull out the signal names for later.
+signals=$(
+ echo '#include ' | $CC -x c - -E -dM $ccflags |
+ awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print $2 }' |
+ egrep -v '(SIGSTKSIZE|SIGSTKSZ|SIGRT)' |
+ sort
+)
+
+# Again, writing regexps to a file.
+echo '#include ' | $CC -x c - -E -dM $ccflags |
+ awk '$1=="#define" && $2 ~ /^E[A-Z0-9_]+$/ { print "^\t" $2 "[ \t]*=" }' |
+ sort >_error.grep
+echo '#include ' | $CC -x c - -E -dM $ccflags |
+ awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print "^\t" $2 "[ \t]*=" }' |
+ egrep -v '(SIGSTKSIZE|SIGSTKSZ|SIGRT)' |
+ sort >_signal.grep
+
+echo '// mkerrors.sh' "$@"
+echo '// Code generated by the command above; see README.md. DO NOT EDIT.'
+echo
+echo "// +build ${GOARCH},${GOOS}"
+echo
+go tool cgo -godefs -- "$@" _const.go >_error.out
+cat _error.out | grep -vf _error.grep | grep -vf _signal.grep
+echo
+echo '// Errors'
+echo 'const ('
+cat _error.out | grep -f _error.grep | sed 's/=\(.*\)/= syscall.Errno(\1)/'
+echo ')'
+
+echo
+echo '// Signals'
+echo 'const ('
+cat _error.out | grep -f _signal.grep | sed 's/=\(.*\)/= syscall.Signal(\1)/'
+echo ')'
+
+# Run C program to print error and syscall strings.
+(
+ echo -E "
+#include
+#include
+#include
+#include
+#include
+#include
+
+#define nelem(x) (sizeof(x)/sizeof((x)[0]))
+
+enum { A = 'A', Z = 'Z', a = 'a', z = 'z' }; // avoid need for single quotes below
+
+int errors[] = {
+"
+ for i in $errors
+ do
+ echo -E ' '$i,
+ done
+
+ echo -E "
+};
+
+int signals[] = {
+"
+ for i in $signals
+ do
+ echo -E ' '$i,
+ done
+
+ # Use -E because on some systems bash builtin interprets \n itself.
+ echo -E '
+};
+
+static int
+intcmp(const void *a, const void *b)
+{
+ return *(int*)a - *(int*)b;
+}
+
+int
+main(void)
+{
+ int i, e;
+ char buf[1024], *p;
+
+ printf("\n\n// Error table\n");
+ printf("var errors = [...]string {\n");
+ qsort(errors, nelem(errors), sizeof errors[0], intcmp);
+ for(i=0; i 0 && errors[i-1] == e)
+ continue;
+ strcpy(buf, strerror(e));
+ // lowercase first letter: Bad -> bad, but STREAM -> STREAM.
+ if(A <= buf[0] && buf[0] <= Z && a <= buf[1] && buf[1] <= z)
+ buf[0] += a - A;
+ printf("\t%d: \"%s\",\n", e, buf);
+ }
+ printf("}\n\n");
+
+ printf("\n\n// Signal table\n");
+ printf("var signals = [...]string {\n");
+ qsort(signals, nelem(signals), sizeof signals[0], intcmp);
+ for(i=0; i 0 && signals[i-1] == e)
+ continue;
+ strcpy(buf, strsignal(e));
+ // lowercase first letter: Bad -> bad, but STREAM -> STREAM.
+ if(A <= buf[0] && buf[0] <= Z && a <= buf[1] && buf[1] <= z)
+ buf[0] += a - A;
+ // cut trailing : number.
+ p = strrchr(buf, ":"[0]);
+ if(p)
+ *p = '\0';
+ printf("\t%d: \"%s\",\n", e, buf);
+ }
+ printf("}\n\n");
+
+ return 0;
+}
+
+'
+) >_errors.c
+
+$CC $ccflags -o _errors _errors.c && $GORUN ./_errors && rm -f _errors.c _errors _const.go _error.grep _signal.grep _error.out
diff --git a/vendor/golang.org/x/sys/unix/mkpost.go b/vendor/golang.org/x/sys/unix/mkpost.go
new file mode 100644
index 00000000..d3ff659b
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/mkpost.go
@@ -0,0 +1,88 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build ignore
+
+// mkpost processes the output of cgo -godefs to
+// modify the generated types. It is used to clean up
+// the sys API in an architecture specific manner.
+//
+// mkpost is run after cgo -godefs; see README.md.
+package main
+
+import (
+ "bytes"
+ "fmt"
+ "go/format"
+ "io/ioutil"
+ "log"
+ "os"
+ "regexp"
+)
+
+func main() {
+ // Get the OS and architecture (using GOARCH_TARGET if it exists)
+ goos := os.Getenv("GOOS")
+ goarch := os.Getenv("GOARCH_TARGET")
+ if goarch == "" {
+ goarch = os.Getenv("GOARCH")
+ }
+ // Check that we are using the new build system if we should be.
+ if goos == "linux" && goarch != "sparc64" {
+ if os.Getenv("GOLANG_SYS_BUILD") != "docker" {
+ os.Stderr.WriteString("In the new build system, mkpost should not be called directly.\n")
+ os.Stderr.WriteString("See README.md\n")
+ os.Exit(1)
+ }
+ }
+
+ b, err := ioutil.ReadAll(os.Stdin)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ // If we have empty Ptrace structs, we should delete them. Only s390x emits
+ // nonempty Ptrace structs.
+ ptraceRexexp := regexp.MustCompile(`type Ptrace((Psw|Fpregs|Per) struct {\s*})`)
+ b = ptraceRexexp.ReplaceAll(b, nil)
+
+ // Replace the control_regs union with a blank identifier for now.
+ controlRegsRegex := regexp.MustCompile(`(Control_regs)\s+\[0\]uint64`)
+ b = controlRegsRegex.ReplaceAll(b, []byte("_ [0]uint64"))
+
+ // Remove fields that are added by glibc
+ // Note that this is unstable as the identifers are private.
+ removeFieldsRegex := regexp.MustCompile(`X__glibc\S*`)
+ b = removeFieldsRegex.ReplaceAll(b, []byte("_"))
+
+ // We refuse to export private fields on s390x
+ if goarch == "s390x" && goos == "linux" {
+ // Remove cgo padding fields
+ removeFieldsRegex := regexp.MustCompile(`Pad_cgo_\d+`)
+ b = removeFieldsRegex.ReplaceAll(b, []byte("_"))
+
+ // Remove padding, hidden, or unused fields
+ removeFieldsRegex = regexp.MustCompile(`X_\S+`)
+ b = removeFieldsRegex.ReplaceAll(b, []byte("_"))
+ }
+
+ // Remove the first line of warning from cgo
+ b = b[bytes.IndexByte(b, '\n')+1:]
+ // Modify the command in the header to include:
+ // mkpost, our own warning, and a build tag.
+ replacement := fmt.Sprintf(`$1 | go run mkpost.go
+// Code generated by the command above; see README.md. DO NOT EDIT.
+
+// +build %s,%s`, goarch, goos)
+ cgoCommandRegex := regexp.MustCompile(`(cgo -godefs .*)`)
+ b = cgoCommandRegex.ReplaceAll(b, []byte(replacement))
+
+ // gofmt
+ b, err = format.Source(b)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ os.Stdout.Write(b)
+}
diff --git a/vendor/golang.org/x/sys/unix/mksyscall.pl b/vendor/golang.org/x/sys/unix/mksyscall.pl
new file mode 100755
index 00000000..fb929b4c
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/mksyscall.pl
@@ -0,0 +1,328 @@
+#!/usr/bin/env perl
+# Copyright 2009 The Go Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
+
+# This program reads a file containing function prototypes
+# (like syscall_darwin.go) and generates system call bodies.
+# The prototypes are marked by lines beginning with "//sys"
+# and read like func declarations if //sys is replaced by func, but:
+# * The parameter lists must give a name for each argument.
+# This includes return parameters.
+# * The parameter lists must give a type for each argument:
+# the (x, y, z int) shorthand is not allowed.
+# * If the return parameter is an error number, it must be named errno.
+
+# A line beginning with //sysnb is like //sys, except that the
+# goroutine will not be suspended during the execution of the system
+# call. This must only be used for system calls which can never
+# block, as otherwise the system call could cause all goroutines to
+# hang.
+
+use strict;
+
+my $cmdline = "mksyscall.pl " . join(' ', @ARGV);
+my $errors = 0;
+my $_32bit = "";
+my $plan9 = 0;
+my $openbsd = 0;
+my $netbsd = 0;
+my $dragonfly = 0;
+my $arm = 0; # 64-bit value should use (even, odd)-pair
+my $tags = ""; # build tags
+
+if($ARGV[0] eq "-b32") {
+ $_32bit = "big-endian";
+ shift;
+} elsif($ARGV[0] eq "-l32") {
+ $_32bit = "little-endian";
+ shift;
+}
+if($ARGV[0] eq "-plan9") {
+ $plan9 = 1;
+ shift;
+}
+if($ARGV[0] eq "-openbsd") {
+ $openbsd = 1;
+ shift;
+}
+if($ARGV[0] eq "-netbsd") {
+ $netbsd = 1;
+ shift;
+}
+if($ARGV[0] eq "-dragonfly") {
+ $dragonfly = 1;
+ shift;
+}
+if($ARGV[0] eq "-arm") {
+ $arm = 1;
+ shift;
+}
+if($ARGV[0] eq "-tags") {
+ shift;
+ $tags = $ARGV[0];
+ shift;
+}
+
+if($ARGV[0] =~ /^-/) {
+ print STDERR "usage: mksyscall.pl [-b32 | -l32] [-tags x,y] [file ...]\n";
+ exit 1;
+}
+
+# Check that we are using the new build system if we should
+if($ENV{'GOOS'} eq "linux" && $ENV{'GOARCH'} ne "sparc64") {
+ if($ENV{'GOLANG_SYS_BUILD'} ne "docker") {
+ print STDERR "In the new build system, mksyscall should not be called directly.\n";
+ print STDERR "See README.md\n";
+ exit 1;
+ }
+}
+
+
+sub parseparamlist($) {
+ my ($list) = @_;
+ $list =~ s/^\s*//;
+ $list =~ s/\s*$//;
+ if($list eq "") {
+ return ();
+ }
+ return split(/\s*,\s*/, $list);
+}
+
+sub parseparam($) {
+ my ($p) = @_;
+ if($p !~ /^(\S*) (\S*)$/) {
+ print STDERR "$ARGV:$.: malformed parameter: $p\n";
+ $errors = 1;
+ return ("xx", "int");
+ }
+ return ($1, $2);
+}
+
+my $text = "";
+while(<>) {
+ chomp;
+ s/\s+/ /g;
+ s/^\s+//;
+ s/\s+$//;
+ my $nonblock = /^\/\/sysnb /;
+ next if !/^\/\/sys / && !$nonblock;
+
+ # Line must be of the form
+ # func Open(path string, mode int, perm int) (fd int, errno error)
+ # Split into name, in params, out params.
+ if(!/^\/\/sys(nb)? (\w+)\(([^()]*)\)\s*(?:\(([^()]+)\))?\s*(?:=\s*((?i)SYS_[A-Z0-9_]+))?$/) {
+ print STDERR "$ARGV:$.: malformed //sys declaration\n";
+ $errors = 1;
+ next;
+ }
+ my ($func, $in, $out, $sysname) = ($2, $3, $4, $5);
+
+ # Split argument lists on comma.
+ my @in = parseparamlist($in);
+ my @out = parseparamlist($out);
+
+ # Try in vain to keep people from editing this file.
+ # The theory is that they jump into the middle of the file
+ # without reading the header.
+ $text .= "// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\n";
+
+ # Go function header.
+ my $out_decl = @out ? sprintf(" (%s)", join(', ', @out)) : "";
+ $text .= sprintf "func %s(%s)%s {\n", $func, join(', ', @in), $out_decl;
+
+ # Check if err return available
+ my $errvar = "";
+ foreach my $p (@out) {
+ my ($name, $type) = parseparam($p);
+ if($type eq "error") {
+ $errvar = $name;
+ last;
+ }
+ }
+
+ # Prepare arguments to Syscall.
+ my @args = ();
+ my $n = 0;
+ foreach my $p (@in) {
+ my ($name, $type) = parseparam($p);
+ if($type =~ /^\*/) {
+ push @args, "uintptr(unsafe.Pointer($name))";
+ } elsif($type eq "string" && $errvar ne "") {
+ $text .= "\tvar _p$n *byte\n";
+ $text .= "\t_p$n, $errvar = BytePtrFromString($name)\n";
+ $text .= "\tif $errvar != nil {\n\t\treturn\n\t}\n";
+ push @args, "uintptr(unsafe.Pointer(_p$n))";
+ $n++;
+ } elsif($type eq "string") {
+ print STDERR "$ARGV:$.: $func uses string arguments, but has no error return\n";
+ $text .= "\tvar _p$n *byte\n";
+ $text .= "\t_p$n, _ = BytePtrFromString($name)\n";
+ push @args, "uintptr(unsafe.Pointer(_p$n))";
+ $n++;
+ } elsif($type =~ /^\[\](.*)/) {
+ # Convert slice into pointer, length.
+ # Have to be careful not to take address of &a[0] if len == 0:
+ # pass dummy pointer in that case.
+ # Used to pass nil, but some OSes or simulators reject write(fd, nil, 0).
+ $text .= "\tvar _p$n unsafe.Pointer\n";
+ $text .= "\tif len($name) > 0 {\n\t\t_p$n = unsafe.Pointer(\&${name}[0])\n\t}";
+ $text .= " else {\n\t\t_p$n = unsafe.Pointer(&_zero)\n\t}";
+ $text .= "\n";
+ push @args, "uintptr(_p$n)", "uintptr(len($name))";
+ $n++;
+ } elsif($type eq "int64" && ($openbsd || $netbsd)) {
+ push @args, "0";
+ if($_32bit eq "big-endian") {
+ push @args, "uintptr($name>>32)", "uintptr($name)";
+ } elsif($_32bit eq "little-endian") {
+ push @args, "uintptr($name)", "uintptr($name>>32)";
+ } else {
+ push @args, "uintptr($name)";
+ }
+ } elsif($type eq "int64" && $dragonfly) {
+ if ($func !~ /^extp(read|write)/i) {
+ push @args, "0";
+ }
+ if($_32bit eq "big-endian") {
+ push @args, "uintptr($name>>32)", "uintptr($name)";
+ } elsif($_32bit eq "little-endian") {
+ push @args, "uintptr($name)", "uintptr($name>>32)";
+ } else {
+ push @args, "uintptr($name)";
+ }
+ } elsif($type eq "int64" && $_32bit ne "") {
+ if(@args % 2 && $arm) {
+ # arm abi specifies 64-bit argument uses
+ # (even, odd) pair
+ push @args, "0"
+ }
+ if($_32bit eq "big-endian") {
+ push @args, "uintptr($name>>32)", "uintptr($name)";
+ } else {
+ push @args, "uintptr($name)", "uintptr($name>>32)";
+ }
+ } else {
+ push @args, "uintptr($name)";
+ }
+ }
+
+ # Determine which form to use; pad args with zeros.
+ my $asm = "Syscall";
+ if ($nonblock) {
+ $asm = "RawSyscall";
+ }
+ if(@args <= 3) {
+ while(@args < 3) {
+ push @args, "0";
+ }
+ } elsif(@args <= 6) {
+ $asm .= "6";
+ while(@args < 6) {
+ push @args, "0";
+ }
+ } elsif(@args <= 9) {
+ $asm .= "9";
+ while(@args < 9) {
+ push @args, "0";
+ }
+ } else {
+ print STDERR "$ARGV:$.: too many arguments to system call\n";
+ }
+
+ # System call number.
+ if($sysname eq "") {
+ $sysname = "SYS_$func";
+ $sysname =~ s/([a-z])([A-Z])/${1}_$2/g; # turn FooBar into Foo_Bar
+ $sysname =~ y/a-z/A-Z/;
+ }
+
+ # Actual call.
+ my $args = join(', ', @args);
+ my $call = "$asm($sysname, $args)";
+
+ # Assign return values.
+ my $body = "";
+ my @ret = ("_", "_", "_");
+ my $do_errno = 0;
+ for(my $i=0; $i<@out; $i++) {
+ my $p = $out[$i];
+ my ($name, $type) = parseparam($p);
+ my $reg = "";
+ if($name eq "err" && !$plan9) {
+ $reg = "e1";
+ $ret[2] = $reg;
+ $do_errno = 1;
+ } elsif($name eq "err" && $plan9) {
+ $ret[0] = "r0";
+ $ret[2] = "e1";
+ next;
+ } else {
+ $reg = sprintf("r%d", $i);
+ $ret[$i] = $reg;
+ }
+ if($type eq "bool") {
+ $reg = "$reg != 0";
+ }
+ if($type eq "int64" && $_32bit ne "") {
+ # 64-bit number in r1:r0 or r0:r1.
+ if($i+2 > @out) {
+ print STDERR "$ARGV:$.: not enough registers for int64 return\n";
+ }
+ if($_32bit eq "big-endian") {
+ $reg = sprintf("int64(r%d)<<32 | int64(r%d)", $i, $i+1);
+ } else {
+ $reg = sprintf("int64(r%d)<<32 | int64(r%d)", $i+1, $i);
+ }
+ $ret[$i] = sprintf("r%d", $i);
+ $ret[$i+1] = sprintf("r%d", $i+1);
+ }
+ if($reg ne "e1" || $plan9) {
+ $body .= "\t$name = $type($reg)\n";
+ }
+ }
+ if ($ret[0] eq "_" && $ret[1] eq "_" && $ret[2] eq "_") {
+ $text .= "\t$call\n";
+ } else {
+ $text .= "\t$ret[0], $ret[1], $ret[2] := $call\n";
+ }
+ $text .= $body;
+
+ if ($plan9 && $ret[2] eq "e1") {
+ $text .= "\tif int32(r0) == -1 {\n";
+ $text .= "\t\terr = e1\n";
+ $text .= "\t}\n";
+ } elsif ($do_errno) {
+ $text .= "\tif e1 != 0 {\n";
+ $text .= "\t\terr = errnoErr(e1)\n";
+ $text .= "\t}\n";
+ }
+ $text .= "\treturn\n";
+ $text .= "}\n\n";
+}
+
+chomp $text;
+chomp $text;
+
+if($errors) {
+ exit 1;
+}
+
+print <) {
+ chomp;
+ s/\s+/ /g;
+ s/^\s+//;
+ s/\s+$//;
+ $package = $1 if !$package && /^package (\S+)$/;
+ my $nonblock = /^\/\/sysnb /;
+ next if !/^\/\/sys / && !$nonblock;
+
+ # Line must be of the form
+ # func Open(path string, mode int, perm int) (fd int, err error)
+ # Split into name, in params, out params.
+ if(!/^\/\/sys(nb)? (\w+)\(([^()]*)\)\s*(?:\(([^()]+)\))?\s*(?:=\s*(?:(\w*)\.)?(\w*))?$/) {
+ print STDERR "$ARGV:$.: malformed //sys declaration\n";
+ $errors = 1;
+ next;
+ }
+ my ($nb, $func, $in, $out, $modname, $sysname) = ($1, $2, $3, $4, $5, $6);
+
+ # Split argument lists on comma.
+ my @in = parseparamlist($in);
+ my @out = parseparamlist($out);
+
+ # So file name.
+ if($modname eq "") {
+ $modname = "libc";
+ }
+
+ # System call name.
+ if($sysname eq "") {
+ $sysname = "$func";
+ }
+
+ # System call pointer variable name.
+ my $sysvarname = "proc$sysname";
+
+ my $strconvfunc = "BytePtrFromString";
+ my $strconvtype = "*byte";
+
+ $sysname =~ y/A-Z/a-z/; # All libc functions are lowercase.
+
+ # Runtime import of function to allow cross-platform builds.
+ $dynimports .= "//go:cgo_import_dynamic libc_${sysname} ${sysname} \"$modname.so\"\n";
+ # Link symbol to proc address variable.
+ $linknames .= "//go:linkname ${sysvarname} libc_${sysname}\n";
+ # Library proc address variable.
+ push @vars, $sysvarname;
+
+ # Go function header.
+ $out = join(', ', @out);
+ if($out ne "") {
+ $out = " ($out)";
+ }
+ if($text ne "") {
+ $text .= "\n"
+ }
+ $text .= sprintf "func %s(%s)%s {\n", $func, join(', ', @in), $out;
+
+ # Check if err return available
+ my $errvar = "";
+ foreach my $p (@out) {
+ my ($name, $type) = parseparam($p);
+ if($type eq "error") {
+ $errvar = $name;
+ last;
+ }
+ }
+
+ # Prepare arguments to Syscall.
+ my @args = ();
+ my $n = 0;
+ foreach my $p (@in) {
+ my ($name, $type) = parseparam($p);
+ if($type =~ /^\*/) {
+ push @args, "uintptr(unsafe.Pointer($name))";
+ } elsif($type eq "string" && $errvar ne "") {
+ $text .= "\tvar _p$n $strconvtype\n";
+ $text .= "\t_p$n, $errvar = $strconvfunc($name)\n";
+ $text .= "\tif $errvar != nil {\n\t\treturn\n\t}\n";
+ push @args, "uintptr(unsafe.Pointer(_p$n))";
+ $n++;
+ } elsif($type eq "string") {
+ print STDERR "$ARGV:$.: $func uses string arguments, but has no error return\n";
+ $text .= "\tvar _p$n $strconvtype\n";
+ $text .= "\t_p$n, _ = $strconvfunc($name)\n";
+ push @args, "uintptr(unsafe.Pointer(_p$n))";
+ $n++;
+ } elsif($type =~ /^\[\](.*)/) {
+ # Convert slice into pointer, length.
+ # Have to be careful not to take address of &a[0] if len == 0:
+ # pass nil in that case.
+ $text .= "\tvar _p$n *$1\n";
+ $text .= "\tif len($name) > 0 {\n\t\t_p$n = \&$name\[0]\n\t}\n";
+ push @args, "uintptr(unsafe.Pointer(_p$n))", "uintptr(len($name))";
+ $n++;
+ } elsif($type eq "int64" && $_32bit ne "") {
+ if($_32bit eq "big-endian") {
+ push @args, "uintptr($name >> 32)", "uintptr($name)";
+ } else {
+ push @args, "uintptr($name)", "uintptr($name >> 32)";
+ }
+ } elsif($type eq "bool") {
+ $text .= "\tvar _p$n uint32\n";
+ $text .= "\tif $name {\n\t\t_p$n = 1\n\t} else {\n\t\t_p$n = 0\n\t}\n";
+ push @args, "uintptr(_p$n)";
+ $n++;
+ } else {
+ push @args, "uintptr($name)";
+ }
+ }
+ my $nargs = @args;
+
+ # Determine which form to use; pad args with zeros.
+ my $asm = "sysvicall6";
+ if ($nonblock) {
+ $asm = "rawSysvicall6";
+ }
+ if(@args <= 6) {
+ while(@args < 6) {
+ push @args, "0";
+ }
+ } else {
+ print STDERR "$ARGV:$.: too many arguments to system call\n";
+ }
+
+ # Actual call.
+ my $args = join(', ', @args);
+ my $call = "$asm(uintptr(unsafe.Pointer(&$sysvarname)), $nargs, $args)";
+
+ # Assign return values.
+ my $body = "";
+ my $failexpr = "";
+ my @ret = ("_", "_", "_");
+ my @pout= ();
+ my $do_errno = 0;
+ for(my $i=0; $i<@out; $i++) {
+ my $p = $out[$i];
+ my ($name, $type) = parseparam($p);
+ my $reg = "";
+ if($name eq "err") {
+ $reg = "e1";
+ $ret[2] = $reg;
+ $do_errno = 1;
+ } else {
+ $reg = sprintf("r%d", $i);
+ $ret[$i] = $reg;
+ }
+ if($type eq "bool") {
+ $reg = "$reg != 0";
+ }
+ if($type eq "int64" && $_32bit ne "") {
+ # 64-bit number in r1:r0 or r0:r1.
+ if($i+2 > @out) {
+ print STDERR "$ARGV:$.: not enough registers for int64 return\n";
+ }
+ if($_32bit eq "big-endian") {
+ $reg = sprintf("int64(r%d)<<32 | int64(r%d)", $i, $i+1);
+ } else {
+ $reg = sprintf("int64(r%d)<<32 | int64(r%d)", $i+1, $i);
+ }
+ $ret[$i] = sprintf("r%d", $i);
+ $ret[$i+1] = sprintf("r%d", $i+1);
+ }
+ if($reg ne "e1") {
+ $body .= "\t$name = $type($reg)\n";
+ }
+ }
+ if ($ret[0] eq "_" && $ret[1] eq "_" && $ret[2] eq "_") {
+ $text .= "\t$call\n";
+ } else {
+ $text .= "\t$ret[0], $ret[1], $ret[2] := $call\n";
+ }
+ $text .= $body;
+
+ if ($do_errno) {
+ $text .= "\tif e1 != 0 {\n";
+ $text .= "\t\terr = e1\n";
+ $text .= "\t}\n";
+ }
+ $text .= "\treturn\n";
+ $text .= "}\n";
+}
+
+if($errors) {
+ exit 1;
+}
+
+print <