Update Vendor

(*) github.com/Microsoft/hcsshim
    (*) golang.org/x/sys
    (*) github.com/x/cyrpto
    (*) github.com/sirupsen/logrus
    (*) github.com/Microsoft/go-winio
    (*) github.com/juju/errors
    (*) github.com/buger/jsonparser
This commit is contained in:
MaiWJ
2018-08-23 11:46:58 +08:00
parent 35b87a34db
commit e1d29e9fe4
400 changed files with 84213 additions and 27920 deletions

3
vendor/golang.org/x/crypto/AUTHORS generated vendored Normal file
View File

@ -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 https://tip.golang.org/AUTHORS.

3
vendor/golang.org/x/crypto/CONTRIBUTORS generated vendored Normal file
View File

@ -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 https://tip.golang.org/CONTRIBUTORS.

27
vendor/golang.org/x/crypto/LICENSE generated vendored Normal file
View File

@ -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.

22
vendor/golang.org/x/crypto/PATENTS generated vendored Normal file
View File

@ -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.

951
vendor/golang.org/x/crypto/ssh/terminal/terminal.go generated vendored Normal file
View File

@ -0,0 +1,951 @@
// 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 terminal
import (
"bytes"
"io"
"sync"
"unicode/utf8"
)
// EscapeCodes contains escape sequences that can be written to the terminal in
// order to achieve different styles of text.
type EscapeCodes struct {
// Foreground colors
Black, Red, Green, Yellow, Blue, Magenta, Cyan, White []byte
// Reset all attributes
Reset []byte
}
var vt100EscapeCodes = EscapeCodes{
Black: []byte{keyEscape, '[', '3', '0', 'm'},
Red: []byte{keyEscape, '[', '3', '1', 'm'},
Green: []byte{keyEscape, '[', '3', '2', 'm'},
Yellow: []byte{keyEscape, '[', '3', '3', 'm'},
Blue: []byte{keyEscape, '[', '3', '4', 'm'},
Magenta: []byte{keyEscape, '[', '3', '5', 'm'},
Cyan: []byte{keyEscape, '[', '3', '6', 'm'},
White: []byte{keyEscape, '[', '3', '7', 'm'},
Reset: []byte{keyEscape, '[', '0', 'm'},
}
// Terminal contains the state for running a VT100 terminal that is capable of
// reading lines of input.
type Terminal struct {
// AutoCompleteCallback, if non-null, is called for each keypress with
// the full input line and the current position of the cursor (in
// bytes, as an index into |line|). If it returns ok=false, the key
// press is processed normally. Otherwise it returns a replacement line
// and the new cursor position.
AutoCompleteCallback func(line string, pos int, key rune) (newLine string, newPos int, ok bool)
// Escape contains a pointer to the escape codes for this terminal.
// It's always a valid pointer, although the escape codes themselves
// may be empty if the terminal doesn't support them.
Escape *EscapeCodes
// lock protects the terminal and the state in this object from
// concurrent processing of a key press and a Write() call.
lock sync.Mutex
c io.ReadWriter
prompt []rune
// line is the current line being entered.
line []rune
// pos is the logical position of the cursor in line
pos int
// echo is true if local echo is enabled
echo bool
// pasteActive is true iff there is a bracketed paste operation in
// progress.
pasteActive bool
// cursorX contains the current X value of the cursor where the left
// edge is 0. cursorY contains the row number where the first row of
// the current line is 0.
cursorX, cursorY int
// maxLine is the greatest value of cursorY so far.
maxLine int
termWidth, termHeight int
// outBuf contains the terminal data to be sent.
outBuf []byte
// remainder contains the remainder of any partial key sequences after
// a read. It aliases into inBuf.
remainder []byte
inBuf [256]byte
// history contains previously entered commands so that they can be
// accessed with the up and down keys.
history stRingBuffer
// historyIndex stores the currently accessed history entry, where zero
// means the immediately previous entry.
historyIndex int
// When navigating up and down the history it's possible to return to
// the incomplete, initial line. That value is stored in
// historyPending.
historyPending string
}
// NewTerminal runs a VT100 terminal on the given ReadWriter. If the ReadWriter is
// a local terminal, that terminal must first have been put into raw mode.
// prompt is a string that is written at the start of each input line (i.e.
// "> ").
func NewTerminal(c io.ReadWriter, prompt string) *Terminal {
return &Terminal{
Escape: &vt100EscapeCodes,
c: c,
prompt: []rune(prompt),
termWidth: 80,
termHeight: 24,
echo: true,
historyIndex: -1,
}
}
const (
keyCtrlD = 4
keyCtrlU = 21
keyEnter = '\r'
keyEscape = 27
keyBackspace = 127
keyUnknown = 0xd800 /* UTF-16 surrogate area */ + iota
keyUp
keyDown
keyLeft
keyRight
keyAltLeft
keyAltRight
keyHome
keyEnd
keyDeleteWord
keyDeleteLine
keyClearScreen
keyPasteStart
keyPasteEnd
)
var (
crlf = []byte{'\r', '\n'}
pasteStart = []byte{keyEscape, '[', '2', '0', '0', '~'}
pasteEnd = []byte{keyEscape, '[', '2', '0', '1', '~'}
)
// bytesToKey tries to parse a key sequence from b. If successful, it returns
// the key and the remainder of the input. Otherwise it returns utf8.RuneError.
func bytesToKey(b []byte, pasteActive bool) (rune, []byte) {
if len(b) == 0 {
return utf8.RuneError, nil
}
if !pasteActive {
switch b[0] {
case 1: // ^A
return keyHome, b[1:]
case 5: // ^E
return keyEnd, b[1:]
case 8: // ^H
return keyBackspace, b[1:]
case 11: // ^K
return keyDeleteLine, b[1:]
case 12: // ^L
return keyClearScreen, b[1:]
case 23: // ^W
return keyDeleteWord, b[1:]
}
}
if b[0] != keyEscape {
if !utf8.FullRune(b) {
return utf8.RuneError, b
}
r, l := utf8.DecodeRune(b)
return r, b[l:]
}
if !pasteActive && len(b) >= 3 && b[0] == keyEscape && b[1] == '[' {
switch b[2] {
case 'A':
return keyUp, b[3:]
case 'B':
return keyDown, b[3:]
case 'C':
return keyRight, b[3:]
case 'D':
return keyLeft, b[3:]
case 'H':
return keyHome, b[3:]
case 'F':
return keyEnd, b[3:]
}
}
if !pasteActive && len(b) >= 6 && b[0] == keyEscape && b[1] == '[' && b[2] == '1' && b[3] == ';' && b[4] == '3' {
switch b[5] {
case 'C':
return keyAltRight, b[6:]
case 'D':
return keyAltLeft, b[6:]
}
}
if !pasteActive && len(b) >= 6 && bytes.Equal(b[:6], pasteStart) {
return keyPasteStart, b[6:]
}
if pasteActive && len(b) >= 6 && bytes.Equal(b[:6], pasteEnd) {
return keyPasteEnd, b[6:]
}
// If we get here then we have a key that we don't recognise, or a
// partial sequence. It's not clear how one should find the end of a
// sequence without knowing them all, but it seems that [a-zA-Z~] only
// appears at the end of a sequence.
for i, c := range b[0:] {
if c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c == '~' {
return keyUnknown, b[i+1:]
}
}
return utf8.RuneError, b
}
// queue appends data to the end of t.outBuf
func (t *Terminal) queue(data []rune) {
t.outBuf = append(t.outBuf, []byte(string(data))...)
}
var eraseUnderCursor = []rune{' ', keyEscape, '[', 'D'}
var space = []rune{' '}
func isPrintable(key rune) bool {
isInSurrogateArea := key >= 0xd800 && key <= 0xdbff
return key >= 32 && !isInSurrogateArea
}
// moveCursorToPos appends data to t.outBuf which will move the cursor to the
// given, logical position in the text.
func (t *Terminal) moveCursorToPos(pos int) {
if !t.echo {
return
}
x := visualLength(t.prompt) + pos
y := x / t.termWidth
x = x % t.termWidth
up := 0
if y < t.cursorY {
up = t.cursorY - y
}
down := 0
if y > t.cursorY {
down = y - t.cursorY
}
left := 0
if x < t.cursorX {
left = t.cursorX - x
}
right := 0
if x > t.cursorX {
right = x - t.cursorX
}
t.cursorX = x
t.cursorY = y
t.move(up, down, left, right)
}
func (t *Terminal) move(up, down, left, right int) {
movement := make([]rune, 3*(up+down+left+right))
m := movement
for i := 0; i < up; i++ {
m[0] = keyEscape
m[1] = '['
m[2] = 'A'
m = m[3:]
}
for i := 0; i < down; i++ {
m[0] = keyEscape
m[1] = '['
m[2] = 'B'
m = m[3:]
}
for i := 0; i < left; i++ {
m[0] = keyEscape
m[1] = '['
m[2] = 'D'
m = m[3:]
}
for i := 0; i < right; i++ {
m[0] = keyEscape
m[1] = '['
m[2] = 'C'
m = m[3:]
}
t.queue(movement)
}
func (t *Terminal) clearLineToRight() {
op := []rune{keyEscape, '[', 'K'}
t.queue(op)
}
const maxLineLength = 4096
func (t *Terminal) setLine(newLine []rune, newPos int) {
if t.echo {
t.moveCursorToPos(0)
t.writeLine(newLine)
for i := len(newLine); i < len(t.line); i++ {
t.writeLine(space)
}
t.moveCursorToPos(newPos)
}
t.line = newLine
t.pos = newPos
}
func (t *Terminal) advanceCursor(places int) {
t.cursorX += places
t.cursorY += t.cursorX / t.termWidth
if t.cursorY > t.maxLine {
t.maxLine = t.cursorY
}
t.cursorX = t.cursorX % t.termWidth
if places > 0 && t.cursorX == 0 {
// Normally terminals will advance the current position
// when writing a character. But that doesn't happen
// for the last character in a line. However, when
// writing a character (except a new line) that causes
// a line wrap, the position will be advanced two
// places.
//
// So, if we are stopping at the end of a line, we
// need to write a newline so that our cursor can be
// advanced to the next line.
t.outBuf = append(t.outBuf, '\r', '\n')
}
}
func (t *Terminal) eraseNPreviousChars(n int) {
if n == 0 {
return
}
if t.pos < n {
n = t.pos
}
t.pos -= n
t.moveCursorToPos(t.pos)
copy(t.line[t.pos:], t.line[n+t.pos:])
t.line = t.line[:len(t.line)-n]
if t.echo {
t.writeLine(t.line[t.pos:])
for i := 0; i < n; i++ {
t.queue(space)
}
t.advanceCursor(n)
t.moveCursorToPos(t.pos)
}
}
// countToLeftWord returns then number of characters from the cursor to the
// start of the previous word.
func (t *Terminal) countToLeftWord() int {
if t.pos == 0 {
return 0
}
pos := t.pos - 1
for pos > 0 {
if t.line[pos] != ' ' {
break
}
pos--
}
for pos > 0 {
if t.line[pos] == ' ' {
pos++
break
}
pos--
}
return t.pos - pos
}
// countToRightWord returns then number of characters from the cursor to the
// start of the next word.
func (t *Terminal) countToRightWord() int {
pos := t.pos
for pos < len(t.line) {
if t.line[pos] == ' ' {
break
}
pos++
}
for pos < len(t.line) {
if t.line[pos] != ' ' {
break
}
pos++
}
return pos - t.pos
}
// visualLength returns the number of visible glyphs in s.
func visualLength(runes []rune) int {
inEscapeSeq := false
length := 0
for _, r := range runes {
switch {
case inEscapeSeq:
if (r >= 'a' && r <= 'z') || (r >= 'A' && r <= 'Z') {
inEscapeSeq = false
}
case r == '\x1b':
inEscapeSeq = true
default:
length++
}
}
return length
}
// handleKey processes the given key and, optionally, returns a line of text
// that the user has entered.
func (t *Terminal) handleKey(key rune) (line string, ok bool) {
if t.pasteActive && key != keyEnter {
t.addKeyToLine(key)
return
}
switch key {
case keyBackspace:
if t.pos == 0 {
return
}
t.eraseNPreviousChars(1)
case keyAltLeft:
// move left by a word.
t.pos -= t.countToLeftWord()
t.moveCursorToPos(t.pos)
case keyAltRight:
// move right by a word.
t.pos += t.countToRightWord()
t.moveCursorToPos(t.pos)
case keyLeft:
if t.pos == 0 {
return
}
t.pos--
t.moveCursorToPos(t.pos)
case keyRight:
if t.pos == len(t.line) {
return
}
t.pos++
t.moveCursorToPos(t.pos)
case keyHome:
if t.pos == 0 {
return
}
t.pos = 0
t.moveCursorToPos(t.pos)
case keyEnd:
if t.pos == len(t.line) {
return
}
t.pos = len(t.line)
t.moveCursorToPos(t.pos)
case keyUp:
entry, ok := t.history.NthPreviousEntry(t.historyIndex + 1)
if !ok {
return "", false
}
if t.historyIndex == -1 {
t.historyPending = string(t.line)
}
t.historyIndex++
runes := []rune(entry)
t.setLine(runes, len(runes))
case keyDown:
switch t.historyIndex {
case -1:
return
case 0:
runes := []rune(t.historyPending)
t.setLine(runes, len(runes))
t.historyIndex--
default:
entry, ok := t.history.NthPreviousEntry(t.historyIndex - 1)
if ok {
t.historyIndex--
runes := []rune(entry)
t.setLine(runes, len(runes))
}
}
case keyEnter:
t.moveCursorToPos(len(t.line))
t.queue([]rune("\r\n"))
line = string(t.line)
ok = true
t.line = t.line[:0]
t.pos = 0
t.cursorX = 0
t.cursorY = 0
t.maxLine = 0
case keyDeleteWord:
// Delete zero or more spaces and then one or more characters.
t.eraseNPreviousChars(t.countToLeftWord())
case keyDeleteLine:
// Delete everything from the current cursor position to the
// end of line.
for i := t.pos; i < len(t.line); i++ {
t.queue(space)
t.advanceCursor(1)
}
t.line = t.line[:t.pos]
t.moveCursorToPos(t.pos)
case keyCtrlD:
// Erase the character under the current position.
// The EOF case when the line is empty is handled in
// readLine().
if t.pos < len(t.line) {
t.pos++
t.eraseNPreviousChars(1)
}
case keyCtrlU:
t.eraseNPreviousChars(t.pos)
case keyClearScreen:
// Erases the screen and moves the cursor to the home position.
t.queue([]rune("\x1b[2J\x1b[H"))
t.queue(t.prompt)
t.cursorX, t.cursorY = 0, 0
t.advanceCursor(visualLength(t.prompt))
t.setLine(t.line, t.pos)
default:
if t.AutoCompleteCallback != nil {
prefix := string(t.line[:t.pos])
suffix := string(t.line[t.pos:])
t.lock.Unlock()
newLine, newPos, completeOk := t.AutoCompleteCallback(prefix+suffix, len(prefix), key)
t.lock.Lock()
if completeOk {
t.setLine([]rune(newLine), utf8.RuneCount([]byte(newLine)[:newPos]))
return
}
}
if !isPrintable(key) {
return
}
if len(t.line) == maxLineLength {
return
}
t.addKeyToLine(key)
}
return
}
// addKeyToLine inserts the given key at the current position in the current
// line.
func (t *Terminal) addKeyToLine(key rune) {
if len(t.line) == cap(t.line) {
newLine := make([]rune, len(t.line), 2*(1+len(t.line)))
copy(newLine, t.line)
t.line = newLine
}
t.line = t.line[:len(t.line)+1]
copy(t.line[t.pos+1:], t.line[t.pos:])
t.line[t.pos] = key
if t.echo {
t.writeLine(t.line[t.pos:])
}
t.pos++
t.moveCursorToPos(t.pos)
}
func (t *Terminal) writeLine(line []rune) {
for len(line) != 0 {
remainingOnLine := t.termWidth - t.cursorX
todo := len(line)
if todo > remainingOnLine {
todo = remainingOnLine
}
t.queue(line[:todo])
t.advanceCursor(visualLength(line[:todo]))
line = line[todo:]
}
}
// writeWithCRLF writes buf to w but replaces all occurrences of \n with \r\n.
func writeWithCRLF(w io.Writer, buf []byte) (n int, err error) {
for len(buf) > 0 {
i := bytes.IndexByte(buf, '\n')
todo := len(buf)
if i >= 0 {
todo = i
}
var nn int
nn, err = w.Write(buf[:todo])
n += nn
if err != nil {
return n, err
}
buf = buf[todo:]
if i >= 0 {
if _, err = w.Write(crlf); err != nil {
return n, err
}
n++
buf = buf[1:]
}
}
return n, nil
}
func (t *Terminal) Write(buf []byte) (n int, err error) {
t.lock.Lock()
defer t.lock.Unlock()
if t.cursorX == 0 && t.cursorY == 0 {
// This is the easy case: there's nothing on the screen that we
// have to move out of the way.
return writeWithCRLF(t.c, buf)
}
// We have a prompt and possibly user input on the screen. We
// have to clear it first.
t.move(0 /* up */, 0 /* down */, t.cursorX /* left */, 0 /* right */)
t.cursorX = 0
t.clearLineToRight()
for t.cursorY > 0 {
t.move(1 /* up */, 0, 0, 0)
t.cursorY--
t.clearLineToRight()
}
if _, err = t.c.Write(t.outBuf); err != nil {
return
}
t.outBuf = t.outBuf[:0]
if n, err = writeWithCRLF(t.c, buf); err != nil {
return
}
t.writeLine(t.prompt)
if t.echo {
t.writeLine(t.line)
}
t.moveCursorToPos(t.pos)
if _, err = t.c.Write(t.outBuf); err != nil {
return
}
t.outBuf = t.outBuf[:0]
return
}
// ReadPassword temporarily changes the prompt and reads a password, without
// echo, from the terminal.
func (t *Terminal) ReadPassword(prompt string) (line string, err error) {
t.lock.Lock()
defer t.lock.Unlock()
oldPrompt := t.prompt
t.prompt = []rune(prompt)
t.echo = false
line, err = t.readLine()
t.prompt = oldPrompt
t.echo = true
return
}
// ReadLine returns a line of input from the terminal.
func (t *Terminal) ReadLine() (line string, err error) {
t.lock.Lock()
defer t.lock.Unlock()
return t.readLine()
}
func (t *Terminal) readLine() (line string, err error) {
// t.lock must be held at this point
if t.cursorX == 0 && t.cursorY == 0 {
t.writeLine(t.prompt)
t.c.Write(t.outBuf)
t.outBuf = t.outBuf[:0]
}
lineIsPasted := t.pasteActive
for {
rest := t.remainder
lineOk := false
for !lineOk {
var key rune
key, rest = bytesToKey(rest, t.pasteActive)
if key == utf8.RuneError {
break
}
if !t.pasteActive {
if key == keyCtrlD {
if len(t.line) == 0 {
return "", io.EOF
}
}
if key == keyPasteStart {
t.pasteActive = true
if len(t.line) == 0 {
lineIsPasted = true
}
continue
}
} else if key == keyPasteEnd {
t.pasteActive = false
continue
}
if !t.pasteActive {
lineIsPasted = false
}
line, lineOk = t.handleKey(key)
}
if len(rest) > 0 {
n := copy(t.inBuf[:], rest)
t.remainder = t.inBuf[:n]
} else {
t.remainder = nil
}
t.c.Write(t.outBuf)
t.outBuf = t.outBuf[:0]
if lineOk {
if t.echo {
t.historyIndex = -1
t.history.Add(line)
}
if lineIsPasted {
err = ErrPasteIndicator
}
return
}
// t.remainder is a slice at the beginning of t.inBuf
// containing a partial key sequence
readBuf := t.inBuf[len(t.remainder):]
var n int
t.lock.Unlock()
n, err = t.c.Read(readBuf)
t.lock.Lock()
if err != nil {
return
}
t.remainder = t.inBuf[:n+len(t.remainder)]
}
}
// SetPrompt sets the prompt to be used when reading subsequent lines.
func (t *Terminal) SetPrompt(prompt string) {
t.lock.Lock()
defer t.lock.Unlock()
t.prompt = []rune(prompt)
}
func (t *Terminal) clearAndRepaintLinePlusNPrevious(numPrevLines int) {
// Move cursor to column zero at the start of the line.
t.move(t.cursorY, 0, t.cursorX, 0)
t.cursorX, t.cursorY = 0, 0
t.clearLineToRight()
for t.cursorY < numPrevLines {
// Move down a line
t.move(0, 1, 0, 0)
t.cursorY++
t.clearLineToRight()
}
// Move back to beginning.
t.move(t.cursorY, 0, 0, 0)
t.cursorX, t.cursorY = 0, 0
t.queue(t.prompt)
t.advanceCursor(visualLength(t.prompt))
t.writeLine(t.line)
t.moveCursorToPos(t.pos)
}
func (t *Terminal) SetSize(width, height int) error {
t.lock.Lock()
defer t.lock.Unlock()
if width == 0 {
width = 1
}
oldWidth := t.termWidth
t.termWidth, t.termHeight = width, height
switch {
case width == oldWidth:
// If the width didn't change then nothing else needs to be
// done.
return nil
case len(t.line) == 0 && t.cursorX == 0 && t.cursorY == 0:
// If there is nothing on current line and no prompt printed,
// just do nothing
return nil
case width < oldWidth:
// Some terminals (e.g. xterm) will truncate lines that were
// too long when shinking. Others, (e.g. gnome-terminal) will
// attempt to wrap them. For the former, repainting t.maxLine
// works great, but that behaviour goes badly wrong in the case
// of the latter because they have doubled every full line.
// We assume that we are working on a terminal that wraps lines
// and adjust the cursor position based on every previous line
// wrapping and turning into two. This causes the prompt on
// xterms to move upwards, which isn't great, but it avoids a
// huge mess with gnome-terminal.
if t.cursorX >= t.termWidth {
t.cursorX = t.termWidth - 1
}
t.cursorY *= 2
t.clearAndRepaintLinePlusNPrevious(t.maxLine * 2)
case width > oldWidth:
// If the terminal expands then our position calculations will
// be wrong in the future because we think the cursor is
// |t.pos| chars into the string, but there will be a gap at
// the end of any wrapped line.
//
// But the position will actually be correct until we move, so
// we can move back to the beginning and repaint everything.
t.clearAndRepaintLinePlusNPrevious(t.maxLine)
}
_, err := t.c.Write(t.outBuf)
t.outBuf = t.outBuf[:0]
return err
}
type pasteIndicatorError struct{}
func (pasteIndicatorError) Error() string {
return "terminal: ErrPasteIndicator not correctly handled"
}
// ErrPasteIndicator may be returned from ReadLine as the error, in addition
// to valid line data. It indicates that bracketed paste mode is enabled and
// that the returned line consists only of pasted data. Programs may wish to
// interpret pasted data more literally than typed data.
var ErrPasteIndicator = pasteIndicatorError{}
// SetBracketedPasteMode requests that the terminal bracket paste operations
// with markers. Not all terminals support this but, if it is supported, then
// enabling this mode will stop any autocomplete callback from running due to
// pastes. Additionally, any lines that are completely pasted will be returned
// from ReadLine with the error set to ErrPasteIndicator.
func (t *Terminal) SetBracketedPasteMode(on bool) {
if on {
io.WriteString(t.c, "\x1b[?2004h")
} else {
io.WriteString(t.c, "\x1b[?2004l")
}
}
// stRingBuffer is a ring buffer of strings.
type stRingBuffer struct {
// entries contains max elements.
entries []string
max int
// head contains the index of the element most recently added to the ring.
head int
// size contains the number of elements in the ring.
size int
}
func (s *stRingBuffer) Add(a string) {
if s.entries == nil {
const defaultNumEntries = 100
s.entries = make([]string, defaultNumEntries)
s.max = defaultNumEntries
}
s.head = (s.head + 1) % s.max
s.entries[s.head] = a
if s.size < s.max {
s.size++
}
}
// NthPreviousEntry returns the value passed to the nth previous call to Add.
// If n is zero then the immediately prior value is returned, if one, then the
// next most recent, and so on. If such an element doesn't exist then ok is
// false.
func (s *stRingBuffer) NthPreviousEntry(n int) (value string, ok bool) {
if n >= s.size {
return "", false
}
index := s.head - n
if index < 0 {
index += s.max
}
return s.entries[index], true
}
// readPasswordLine reads from reader until it finds \n or io.EOF.
// The slice returned does not include the \n.
// readPasswordLine also ignores any \r it finds.
func readPasswordLine(reader io.Reader) ([]byte, error) {
var buf [1]byte
var ret []byte
for {
n, err := reader.Read(buf[:])
if n > 0 {
switch buf[0] {
case '\n':
return ret, nil
case '\r':
// remove \r from passwords on Windows
default:
ret = append(ret, buf[0])
}
continue
}
if err != nil {
if err == io.EOF && len(ret) > 0 {
return ret, nil
}
return ret, err
}
}
}

116
vendor/golang.org/x/crypto/ssh/terminal/util.go generated vendored Normal file
View File

@ -0,0 +1,116 @@
// 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 darwin dragonfly freebsd linux,!appengine netbsd openbsd
// Package terminal provides support functions for dealing with terminals, as
// commonly found on UNIX systems.
//
// Putting a terminal into raw mode is the most common requirement:
//
// oldState, err := terminal.MakeRaw(0)
// if err != nil {
// panic(err)
// }
// defer terminal.Restore(0, oldState)
package terminal
import (
"golang.org/x/sys/unix"
)
// State contains the state of a terminal.
type State struct {
termios unix.Termios
}
// IsTerminal returns true if the given file descriptor is a terminal.
func IsTerminal(fd int) bool {
_, err := unix.IoctlGetTermios(fd, ioctlReadTermios)
return err == nil
}
// MakeRaw put the terminal connected to the given file descriptor into raw
// mode and returns the previous state of the terminal so that it can be
// restored.
func MakeRaw(fd int) (*State, error) {
termios, err := unix.IoctlGetTermios(fd, ioctlReadTermios)
if err != nil {
return nil, err
}
oldState := State{termios: *termios}
// This attempts to replicate the behaviour documented for cfmakeraw in
// the termios(3) manpage.
termios.Iflag &^= unix.IGNBRK | unix.BRKINT | unix.PARMRK | unix.ISTRIP | unix.INLCR | unix.IGNCR | unix.ICRNL | unix.IXON
termios.Oflag &^= unix.OPOST
termios.Lflag &^= unix.ECHO | unix.ECHONL | unix.ICANON | unix.ISIG | unix.IEXTEN
termios.Cflag &^= unix.CSIZE | unix.PARENB
termios.Cflag |= unix.CS8
termios.Cc[unix.VMIN] = 1
termios.Cc[unix.VTIME] = 0
if err := unix.IoctlSetTermios(fd, ioctlWriteTermios, termios); err != nil {
return nil, err
}
return &oldState, nil
}
// GetState returns the current state of a terminal which may be useful to
// restore the terminal after a signal.
func GetState(fd int) (*State, error) {
termios, err := unix.IoctlGetTermios(fd, ioctlReadTermios)
if err != nil {
return nil, err
}
return &State{termios: *termios}, nil
}
// Restore restores the terminal connected to the given file descriptor to a
// previous state.
func Restore(fd int, state *State) error {
return unix.IoctlSetTermios(fd, ioctlWriteTermios, &state.termios)
}
// GetSize returns the dimensions of the given terminal.
func GetSize(fd int) (width, height int, err error) {
ws, err := unix.IoctlGetWinsize(fd, unix.TIOCGWINSZ)
if err != nil {
return -1, -1, err
}
return int(ws.Col), int(ws.Row), nil
}
// passwordReader is an io.Reader that reads from a specific file descriptor.
type passwordReader int
func (r passwordReader) Read(buf []byte) (int, error) {
return unix.Read(int(r), buf)
}
// ReadPassword reads a line of input from a terminal without local echo. This
// is commonly used for inputting passwords and other sensitive data. The slice
// returned does not include the \n.
func ReadPassword(fd int) ([]byte, error) {
termios, err := unix.IoctlGetTermios(fd, ioctlReadTermios)
if err != nil {
return nil, err
}
newState := *termios
newState.Lflag &^= unix.ECHO
newState.Lflag |= unix.ICANON | unix.ISIG
newState.Iflag |= unix.ICRNL
if err := unix.IoctlSetTermios(fd, ioctlWriteTermios, &newState); err != nil {
return nil, err
}
defer func() {
unix.IoctlSetTermios(fd, ioctlWriteTermios, termios)
}()
return readPasswordLine(passwordReader(fd))
}

12
vendor/golang.org/x/crypto/ssh/terminal/util_bsd.go generated vendored Normal file
View File

@ -0,0 +1,12 @@
// 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 darwin dragonfly freebsd netbsd openbsd
package terminal
import "golang.org/x/sys/unix"
const ioctlReadTermios = unix.TIOCGETA
const ioctlWriteTermios = unix.TIOCSETA

View File

@ -2,10 +2,9 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build dragonfly freebsd netbsd openbsd
package terminal
package unix
import "golang.org/x/sys/unix"
const ImplementsGetwd = false
func Getwd() (string, error) { return "", ENOTSUP }
const ioctlReadTermios = unix.TCGETS
const ioctlWriteTermios = unix.TCSETS

58
vendor/golang.org/x/crypto/ssh/terminal/util_plan9.go generated vendored Normal file
View File

@ -0,0 +1,58 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package terminal provides support functions for dealing with terminals, as
// commonly found on UNIX systems.
//
// Putting a terminal into raw mode is the most common requirement:
//
// oldState, err := terminal.MakeRaw(0)
// if err != nil {
// panic(err)
// }
// defer terminal.Restore(0, oldState)
package terminal
import (
"fmt"
"runtime"
)
type State struct{}
// IsTerminal returns true if the given file descriptor is a terminal.
func IsTerminal(fd int) bool {
return false
}
// MakeRaw put the terminal connected to the given file descriptor into raw
// mode and returns the previous state of the terminal so that it can be
// restored.
func MakeRaw(fd int) (*State, error) {
return nil, fmt.Errorf("terminal: MakeRaw not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
}
// GetState returns the current state of a terminal which may be useful to
// restore the terminal after a signal.
func GetState(fd int) (*State, error) {
return nil, fmt.Errorf("terminal: GetState not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
}
// Restore restores the terminal connected to the given file descriptor to a
// previous state.
func Restore(fd int, state *State) error {
return fmt.Errorf("terminal: Restore not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
}
// GetSize returns the dimensions of the given terminal.
func GetSize(fd int) (width, height int, err error) {
return 0, 0, fmt.Errorf("terminal: GetSize not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
}
// ReadPassword reads a line of input from a terminal without local echo. This
// is commonly used for inputting passwords and other sensitive data. The slice
// returned does not include the \n.
func ReadPassword(fd int) ([]byte, error) {
return nil, fmt.Errorf("terminal: ReadPassword not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
}

128
vendor/golang.org/x/crypto/ssh/terminal/util_solaris.go generated vendored Normal file
View File

@ -0,0 +1,128 @@
// 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 solaris
package terminal
import (
"golang.org/x/sys/unix"
"io"
"syscall"
)
// State contains the state of a terminal.
type State struct {
state *unix.Termios
}
// IsTerminal returns true if the given file descriptor is a terminal.
func IsTerminal(fd int) bool {
_, err := unix.IoctlGetTermio(fd, unix.TCGETA)
return err == nil
}
// ReadPassword reads a line of input from a terminal without local echo. This
// is commonly used for inputting passwords and other sensitive data. The slice
// returned does not include the \n.
func ReadPassword(fd int) ([]byte, error) {
// see also: http://src.illumos.org/source/xref/illumos-gate/usr/src/lib/libast/common/uwin/getpass.c
val, err := unix.IoctlGetTermios(fd, unix.TCGETS)
if err != nil {
return nil, err
}
oldState := *val
newState := oldState
newState.Lflag &^= syscall.ECHO
newState.Lflag |= syscall.ICANON | syscall.ISIG
newState.Iflag |= syscall.ICRNL
err = unix.IoctlSetTermios(fd, unix.TCSETS, &newState)
if err != nil {
return nil, err
}
defer unix.IoctlSetTermios(fd, unix.TCSETS, &oldState)
var buf [16]byte
var ret []byte
for {
n, err := syscall.Read(fd, buf[:])
if err != nil {
return nil, err
}
if n == 0 {
if len(ret) == 0 {
return nil, io.EOF
}
break
}
if buf[n-1] == '\n' {
n--
}
ret = append(ret, buf[:n]...)
if n < len(buf) {
break
}
}
return ret, nil
}
// MakeRaw puts the terminal connected to the given file descriptor into raw
// mode and returns the previous state of the terminal so that it can be
// restored.
// see http://cr.illumos.org/~webrev/andy_js/1060/
func MakeRaw(fd int) (*State, error) {
oldTermiosPtr, err := unix.IoctlGetTermios(fd, unix.TCGETS)
if err != nil {
return nil, err
}
oldTermios := *oldTermiosPtr
newTermios := oldTermios
newTermios.Iflag &^= syscall.IGNBRK | syscall.BRKINT | syscall.PARMRK | syscall.ISTRIP | syscall.INLCR | syscall.IGNCR | syscall.ICRNL | syscall.IXON
newTermios.Oflag &^= syscall.OPOST
newTermios.Lflag &^= syscall.ECHO | syscall.ECHONL | syscall.ICANON | syscall.ISIG | syscall.IEXTEN
newTermios.Cflag &^= syscall.CSIZE | syscall.PARENB
newTermios.Cflag |= syscall.CS8
newTermios.Cc[unix.VMIN] = 1
newTermios.Cc[unix.VTIME] = 0
if err := unix.IoctlSetTermios(fd, unix.TCSETS, &newTermios); err != nil {
return nil, err
}
return &State{
state: oldTermiosPtr,
}, nil
}
// Restore restores the terminal connected to the given file descriptor to a
// previous state.
func Restore(fd int, oldState *State) error {
return unix.IoctlSetTermios(fd, unix.TCSETS, oldState.state)
}
// GetState returns the current state of a terminal which may be useful to
// restore the terminal after a signal.
func GetState(fd int) (*State, error) {
oldTermiosPtr, err := unix.IoctlGetTermios(fd, unix.TCGETS)
if err != nil {
return nil, err
}
return &State{
state: oldTermiosPtr,
}, nil
}
// GetSize returns the dimensions of the given terminal.
func GetSize(fd int) (width, height int, err error) {
ws, err := unix.IoctlGetWinsize(fd, unix.TIOCGWINSZ)
if err != nil {
return 0, 0, err
}
return int(ws.Col), int(ws.Row), nil
}

View File

@ -0,0 +1,97 @@
// 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
// Package terminal provides support functions for dealing with terminals, as
// commonly found on UNIX systems.
//
// Putting a terminal into raw mode is the most common requirement:
//
// oldState, err := terminal.MakeRaw(0)
// if err != nil {
// panic(err)
// }
// defer terminal.Restore(0, oldState)
package terminal
import (
"os"
"golang.org/x/sys/windows"
)
type State struct {
mode uint32
}
// IsTerminal returns true if the given file descriptor is a terminal.
func IsTerminal(fd int) bool {
var st uint32
err := windows.GetConsoleMode(windows.Handle(fd), &st)
return err == nil
}
// MakeRaw put the terminal connected to the given file descriptor into raw
// mode and returns the previous state of the terminal so that it can be
// restored.
func MakeRaw(fd int) (*State, error) {
var st uint32
if err := windows.GetConsoleMode(windows.Handle(fd), &st); err != nil {
return nil, err
}
raw := st &^ (windows.ENABLE_ECHO_INPUT | windows.ENABLE_PROCESSED_INPUT | windows.ENABLE_LINE_INPUT | windows.ENABLE_PROCESSED_OUTPUT)
if err := windows.SetConsoleMode(windows.Handle(fd), raw); err != nil {
return nil, err
}
return &State{st}, nil
}
// GetState returns the current state of a terminal which may be useful to
// restore the terminal after a signal.
func GetState(fd int) (*State, error) {
var st uint32
if err := windows.GetConsoleMode(windows.Handle(fd), &st); err != nil {
return nil, err
}
return &State{st}, nil
}
// Restore restores the terminal connected to the given file descriptor to a
// previous state.
func Restore(fd int, state *State) error {
return windows.SetConsoleMode(windows.Handle(fd), state.mode)
}
// GetSize returns the dimensions of the given terminal.
func GetSize(fd int) (width, height int, err error) {
var info windows.ConsoleScreenBufferInfo
if err := windows.GetConsoleScreenBufferInfo(windows.Handle(fd), &info); err != nil {
return 0, 0, err
}
return int(info.Size.X), int(info.Size.Y), nil
}
// ReadPassword reads a line of input from a terminal without local echo. This
// is commonly used for inputting passwords and other sensitive data. The slice
// returned does not include the \n.
func ReadPassword(fd int) ([]byte, error) {
var st uint32
if err := windows.GetConsoleMode(windows.Handle(fd), &st); err != nil {
return nil, err
}
old := st
st &^= (windows.ENABLE_ECHO_INPUT)
st |= (windows.ENABLE_PROCESSED_INPUT | windows.ENABLE_LINE_INPUT | windows.ENABLE_PROCESSED_OUTPUT)
if err := windows.SetConsoleMode(windows.Handle(fd), st); err != nil {
return nil, err
}
defer func() {
windows.SetConsoleMode(windows.Handle(fd), old)
}()
return readPasswordLine(os.NewFile(uintptr(fd), "stdin"))
}

3
vendor/golang.org/x/net/AUTHORS generated vendored Normal file
View File

@ -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.

3
vendor/golang.org/x/net/CONTRIBUTORS generated vendored Normal file
View File

@ -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.

27
vendor/golang.org/x/net/LICENSE generated vendored Normal file
View File

@ -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.

22
vendor/golang.org/x/net/PATENTS generated vendored Normal file
View File

@ -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.

2
vendor/golang.org/x/net/bpf/doc.go generated vendored
View File

@ -79,4 +79,4 @@ This packet filter captures a random 1% sample of traffic.
})
*/
package bpf // import "golang.org/x/net/bpf"
package bpf

View File

@ -1,184 +0,0 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package bpf
import (
"io/ioutil"
"reflect"
"strconv"
"strings"
"testing"
)
// This is a direct translation of the program in
// testdata/all_instructions.txt.
var allInstructions = []Instruction{
LoadConstant{Dst: RegA, Val: 42},
LoadConstant{Dst: RegX, Val: 42},
LoadScratch{Dst: RegA, N: 3},
LoadScratch{Dst: RegX, N: 3},
LoadAbsolute{Off: 42, Size: 1},
LoadAbsolute{Off: 42, Size: 2},
LoadAbsolute{Off: 42, Size: 4},
LoadIndirect{Off: 42, Size: 1},
LoadIndirect{Off: 42, Size: 2},
LoadIndirect{Off: 42, Size: 4},
LoadMemShift{Off: 42},
LoadExtension{Num: ExtLen},
LoadExtension{Num: ExtProto},
LoadExtension{Num: ExtType},
LoadExtension{Num: ExtRand},
StoreScratch{Src: RegA, N: 3},
StoreScratch{Src: RegX, N: 3},
ALUOpConstant{Op: ALUOpAdd, Val: 42},
ALUOpConstant{Op: ALUOpSub, Val: 42},
ALUOpConstant{Op: ALUOpMul, Val: 42},
ALUOpConstant{Op: ALUOpDiv, Val: 42},
ALUOpConstant{Op: ALUOpOr, Val: 42},
ALUOpConstant{Op: ALUOpAnd, Val: 42},
ALUOpConstant{Op: ALUOpShiftLeft, Val: 42},
ALUOpConstant{Op: ALUOpShiftRight, Val: 42},
ALUOpConstant{Op: ALUOpMod, Val: 42},
ALUOpConstant{Op: ALUOpXor, Val: 42},
ALUOpX{Op: ALUOpAdd},
ALUOpX{Op: ALUOpSub},
ALUOpX{Op: ALUOpMul},
ALUOpX{Op: ALUOpDiv},
ALUOpX{Op: ALUOpOr},
ALUOpX{Op: ALUOpAnd},
ALUOpX{Op: ALUOpShiftLeft},
ALUOpX{Op: ALUOpShiftRight},
ALUOpX{Op: ALUOpMod},
ALUOpX{Op: ALUOpXor},
NegateA{},
Jump{Skip: 10},
JumpIf{Cond: JumpEqual, Val: 42, SkipTrue: 8, SkipFalse: 9},
JumpIf{Cond: JumpNotEqual, Val: 42, SkipTrue: 8},
JumpIf{Cond: JumpLessThan, Val: 42, SkipTrue: 7},
JumpIf{Cond: JumpLessOrEqual, Val: 42, SkipTrue: 6},
JumpIf{Cond: JumpGreaterThan, Val: 42, SkipTrue: 4, SkipFalse: 5},
JumpIf{Cond: JumpGreaterOrEqual, Val: 42, SkipTrue: 3, SkipFalse: 4},
JumpIf{Cond: JumpBitsSet, Val: 42, SkipTrue: 2, SkipFalse: 3},
TAX{},
TXA{},
RetA{},
RetConstant{Val: 42},
}
var allInstructionsExpected = "testdata/all_instructions.bpf"
// Check that we produce the same output as the canonical bpf_asm
// linux kernel tool.
func TestInterop(t *testing.T) {
out, err := Assemble(allInstructions)
if err != nil {
t.Fatalf("assembly of allInstructions program failed: %s", err)
}
t.Logf("Assembled program is %d instructions long", len(out))
bs, err := ioutil.ReadFile(allInstructionsExpected)
if err != nil {
t.Fatalf("reading %s: %s", allInstructionsExpected, err)
}
// First statement is the number of statements, last statement is
// empty. We just ignore both and rely on slice length.
stmts := strings.Split(string(bs), ",")
if len(stmts)-2 != len(out) {
t.Fatalf("test program lengths don't match: %s has %d, Go implementation has %d", allInstructionsExpected, len(stmts)-2, len(allInstructions))
}
for i, stmt := range stmts[1 : len(stmts)-2] {
nums := strings.Split(stmt, " ")
if len(nums) != 4 {
t.Fatalf("malformed instruction %d in %s: %s", i+1, allInstructionsExpected, stmt)
}
actual := out[i]
op, err := strconv.ParseUint(nums[0], 10, 16)
if err != nil {
t.Fatalf("malformed opcode %s in instruction %d of %s", nums[0], i+1, allInstructionsExpected)
}
if actual.Op != uint16(op) {
t.Errorf("opcode mismatch on instruction %d (%#v): got 0x%02x, want 0x%02x", i+1, allInstructions[i], actual.Op, op)
}
jt, err := strconv.ParseUint(nums[1], 10, 8)
if err != nil {
t.Fatalf("malformed jt offset %s in instruction %d of %s", nums[1], i+1, allInstructionsExpected)
}
if actual.Jt != uint8(jt) {
t.Errorf("jt mismatch on instruction %d (%#v): got %d, want %d", i+1, allInstructions[i], actual.Jt, jt)
}
jf, err := strconv.ParseUint(nums[2], 10, 8)
if err != nil {
t.Fatalf("malformed jf offset %s in instruction %d of %s", nums[2], i+1, allInstructionsExpected)
}
if actual.Jf != uint8(jf) {
t.Errorf("jf mismatch on instruction %d (%#v): got %d, want %d", i+1, allInstructions[i], actual.Jf, jf)
}
k, err := strconv.ParseUint(nums[3], 10, 32)
if err != nil {
t.Fatalf("malformed constant %s in instruction %d of %s", nums[3], i+1, allInstructionsExpected)
}
if actual.K != uint32(k) {
t.Errorf("constant mismatch on instruction %d (%#v): got %d, want %d", i+1, allInstructions[i], actual.K, k)
}
}
}
// Check that assembly and disassembly match each other.
//
// Because we offer "fake" jump conditions that don't appear in the
// machine code, disassembly won't be a 1:1 match with the original
// source, although the behavior will be identical. However,
// reassembling the disassembly should produce an identical program.
func TestAsmDisasm(t *testing.T) {
prog1, err := Assemble(allInstructions)
if err != nil {
t.Fatalf("assembly of allInstructions program failed: %s", err)
}
t.Logf("Assembled program is %d instructions long", len(prog1))
src, allDecoded := Disassemble(prog1)
if !allDecoded {
t.Errorf("Disassemble(Assemble(allInstructions)) produced unrecognized instructions:")
for i, inst := range src {
if r, ok := inst.(RawInstruction); ok {
t.Logf(" insn %d, %#v --> %#v", i+1, allInstructions[i], r)
}
}
}
prog2, err := Assemble(src)
if err != nil {
t.Fatalf("assembly of Disassemble(Assemble(allInstructions)) failed: %s", err)
}
if len(prog2) != len(prog1) {
t.Fatalf("disassembly changed program size: %d insns before, %d insns after", len(prog1), len(prog2))
}
if !reflect.DeepEqual(prog1, prog2) {
t.Errorf("program mutated by disassembly:")
for i := range prog2 {
if !reflect.DeepEqual(prog1[i], prog2[i]) {
t.Logf(" insn %d, s: %#v, p1: %#v, p2: %#v", i+1, allInstructions[i], prog1[i], prog2[i])
}
}
}
}

View File

@ -1 +0,0 @@
50,0 0 0 42,1 0 0 42,96 0 0 3,97 0 0 3,48 0 0 42,40 0 0 42,32 0 0 42,80 0 0 42,72 0 0 42,64 0 0 42,177 0 0 42,128 0 0 0,32 0 0 4294963200,32 0 0 4294963204,32 0 0 4294963256,2 0 0 3,3 0 0 3,4 0 0 42,20 0 0 42,36 0 0 42,52 0 0 42,68 0 0 42,84 0 0 42,100 0 0 42,116 0 0 42,148 0 0 42,164 0 0 42,12 0 0 0,28 0 0 0,44 0 0 0,60 0 0 0,76 0 0 0,92 0 0 0,108 0 0 0,124 0 0 0,156 0 0 0,172 0 0 0,132 0 0 0,5 0 0 10,21 8 9 42,21 0 8 42,53 0 7 42,37 0 6 42,37 4 5 42,53 3 4 42,69 2 3 42,7 0 0 0,135 0 0 0,22 0 0 0,6 0 0 0,

View File

@ -1,79 +0,0 @@
# This filter is compiled to all_instructions.bpf by the `bpf_asm`
# tool, which can be found in the linux kernel source tree under
# tools/net.
# Load immediate
ld #42
ldx #42
# Load scratch
ld M[3]
ldx M[3]
# Load absolute
ldb [42]
ldh [42]
ld [42]
# Load indirect
ldb [x + 42]
ldh [x + 42]
ld [x + 42]
# Load IPv4 header length
ldx 4*([42]&0xf)
# Run extension function
ld #len
ld #proto
ld #type
ld #rand
# Store scratch
st M[3]
stx M[3]
# A <op> constant
add #42
sub #42
mul #42
div #42
or #42
and #42
lsh #42
rsh #42
mod #42
xor #42
# A <op> X
add x
sub x
mul x
div x
or x
and x
lsh x
rsh x
mod x
xor x
# !A
neg
# Jumps
ja end
jeq #42,prev,end
jne #42,end
jlt #42,end
jle #42,end
jgt #42,prev,end
jge #42,prev,end
jset #42,prev,end
# Register transfers
tax
txa
# Returns
prev: ret a
end: ret #42

View File

@ -1,512 +0,0 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package bpf_test
import (
"testing"
"golang.org/x/net/bpf"
)
func TestVMALUOpAdd(t *testing.T) {
vm, done, err := testVM(t, []bpf.Instruction{
bpf.LoadAbsolute{
Off: 8,
Size: 1,
},
bpf.ALUOpConstant{
Op: bpf.ALUOpAdd,
Val: 3,
},
bpf.RetA{},
})
if err != nil {
t.Fatalf("failed to load BPF program: %v", err)
}
defer done()
out, err := vm.Run([]byte{
0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff,
8, 2, 3,
})
if err != nil {
t.Fatalf("unexpected error while running program: %v", err)
}
if want, got := 3, out; want != got {
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
want, got)
}
}
func TestVMALUOpSub(t *testing.T) {
vm, done, err := testVM(t, []bpf.Instruction{
bpf.LoadAbsolute{
Off: 8,
Size: 1,
},
bpf.TAX{},
bpf.ALUOpX{
Op: bpf.ALUOpSub,
},
bpf.RetA{},
})
if err != nil {
t.Fatalf("failed to load BPF program: %v", err)
}
defer done()
out, err := vm.Run([]byte{
0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff,
1, 2, 3,
})
if err != nil {
t.Fatalf("unexpected error while running program: %v", err)
}
if want, got := 0, out; want != got {
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
want, got)
}
}
func TestVMALUOpMul(t *testing.T) {
vm, done, err := testVM(t, []bpf.Instruction{
bpf.LoadAbsolute{
Off: 8,
Size: 1,
},
bpf.ALUOpConstant{
Op: bpf.ALUOpMul,
Val: 2,
},
bpf.RetA{},
})
if err != nil {
t.Fatalf("failed to load BPF program: %v", err)
}
defer done()
out, err := vm.Run([]byte{
0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff,
6, 2, 3, 4,
})
if err != nil {
t.Fatalf("unexpected error while running program: %v", err)
}
if want, got := 4, out; want != got {
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
want, got)
}
}
func TestVMALUOpDiv(t *testing.T) {
vm, done, err := testVM(t, []bpf.Instruction{
bpf.LoadAbsolute{
Off: 8,
Size: 1,
},
bpf.ALUOpConstant{
Op: bpf.ALUOpDiv,
Val: 2,
},
bpf.RetA{},
})
if err != nil {
t.Fatalf("failed to load BPF program: %v", err)
}
defer done()
out, err := vm.Run([]byte{
0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff,
20, 2, 3, 4,
})
if err != nil {
t.Fatalf("unexpected error while running program: %v", err)
}
if want, got := 2, out; want != got {
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
want, got)
}
}
func TestVMALUOpDivByZeroALUOpConstant(t *testing.T) {
_, _, err := testVM(t, []bpf.Instruction{
bpf.ALUOpConstant{
Op: bpf.ALUOpDiv,
Val: 0,
},
bpf.RetA{},
})
if errStr(err) != "cannot divide by zero using ALUOpConstant" {
t.Fatalf("unexpected error: %v", err)
}
}
func TestVMALUOpDivByZeroALUOpX(t *testing.T) {
vm, done, err := testVM(t, []bpf.Instruction{
// Load byte 0 into X
bpf.LoadAbsolute{
Off: 8,
Size: 1,
},
bpf.TAX{},
// Load byte 1 into A
bpf.LoadAbsolute{
Off: 9,
Size: 1,
},
// Attempt to perform 1/0
bpf.ALUOpX{
Op: bpf.ALUOpDiv,
},
// Return 4 bytes if program does not terminate
bpf.LoadConstant{
Val: 12,
},
bpf.RetA{},
})
if err != nil {
t.Fatalf("failed to load BPF program: %v", err)
}
defer done()
out, err := vm.Run([]byte{
0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff,
0, 1, 3, 4,
})
if err != nil {
t.Fatalf("unexpected error while running program: %v", err)
}
if want, got := 0, out; want != got {
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
want, got)
}
}
func TestVMALUOpOr(t *testing.T) {
vm, done, err := testVM(t, []bpf.Instruction{
bpf.LoadAbsolute{
Off: 8,
Size: 2,
},
bpf.ALUOpConstant{
Op: bpf.ALUOpOr,
Val: 0x01,
},
bpf.RetA{},
})
if err != nil {
t.Fatalf("failed to load BPF program: %v", err)
}
defer done()
out, err := vm.Run([]byte{
0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff,
0x00, 0x10, 0x03, 0x04,
0x05, 0x06, 0x07, 0x08,
0x09, 0xff,
})
if err != nil {
t.Fatalf("unexpected error while running program: %v", err)
}
if want, got := 9, out; want != got {
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
want, got)
}
}
func TestVMALUOpAnd(t *testing.T) {
vm, done, err := testVM(t, []bpf.Instruction{
bpf.LoadAbsolute{
Off: 8,
Size: 2,
},
bpf.ALUOpConstant{
Op: bpf.ALUOpAnd,
Val: 0x0019,
},
bpf.RetA{},
})
if err != nil {
t.Fatalf("failed to load BPF program: %v", err)
}
defer done()
out, err := vm.Run([]byte{
0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff,
0xaa, 0x09,
})
if err != nil {
t.Fatalf("unexpected error while running program: %v", err)
}
if want, got := 1, out; want != got {
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
want, got)
}
}
func TestVMALUOpShiftLeft(t *testing.T) {
vm, done, err := testVM(t, []bpf.Instruction{
bpf.LoadAbsolute{
Off: 8,
Size: 1,
},
bpf.ALUOpConstant{
Op: bpf.ALUOpShiftLeft,
Val: 0x01,
},
bpf.JumpIf{
Cond: bpf.JumpEqual,
Val: 0x02,
SkipTrue: 1,
},
bpf.RetConstant{
Val: 0,
},
bpf.RetConstant{
Val: 9,
},
})
if err != nil {
t.Fatalf("failed to load BPF program: %v", err)
}
defer done()
out, err := vm.Run([]byte{
0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff,
0x01, 0xaa,
})
if err != nil {
t.Fatalf("unexpected error while running program: %v", err)
}
if want, got := 1, out; want != got {
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
want, got)
}
}
func TestVMALUOpShiftRight(t *testing.T) {
vm, done, err := testVM(t, []bpf.Instruction{
bpf.LoadAbsolute{
Off: 8,
Size: 1,
},
bpf.ALUOpConstant{
Op: bpf.ALUOpShiftRight,
Val: 0x01,
},
bpf.JumpIf{
Cond: bpf.JumpEqual,
Val: 0x04,
SkipTrue: 1,
},
bpf.RetConstant{
Val: 0,
},
bpf.RetConstant{
Val: 9,
},
})
if err != nil {
t.Fatalf("failed to load BPF program: %v", err)
}
defer done()
out, err := vm.Run([]byte{
0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff,
0x08, 0xff, 0xff,
})
if err != nil {
t.Fatalf("unexpected error while running program: %v", err)
}
if want, got := 1, out; want != got {
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
want, got)
}
}
func TestVMALUOpMod(t *testing.T) {
vm, done, err := testVM(t, []bpf.Instruction{
bpf.LoadAbsolute{
Off: 8,
Size: 1,
},
bpf.ALUOpConstant{
Op: bpf.ALUOpMod,
Val: 20,
},
bpf.RetA{},
})
if err != nil {
t.Fatalf("failed to load BPF program: %v", err)
}
defer done()
out, err := vm.Run([]byte{
0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff,
30, 0, 0,
})
if err != nil {
t.Fatalf("unexpected error while running program: %v", err)
}
if want, got := 2, out; want != got {
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
want, got)
}
}
func TestVMALUOpModByZeroALUOpConstant(t *testing.T) {
_, _, err := testVM(t, []bpf.Instruction{
bpf.LoadAbsolute{
Off: 8,
Size: 1,
},
bpf.ALUOpConstant{
Op: bpf.ALUOpMod,
Val: 0,
},
bpf.RetA{},
})
if errStr(err) != "cannot divide by zero using ALUOpConstant" {
t.Fatalf("unexpected error: %v", err)
}
}
func TestVMALUOpModByZeroALUOpX(t *testing.T) {
vm, done, err := testVM(t, []bpf.Instruction{
// Load byte 0 into X
bpf.LoadAbsolute{
Off: 8,
Size: 1,
},
bpf.TAX{},
// Load byte 1 into A
bpf.LoadAbsolute{
Off: 9,
Size: 1,
},
// Attempt to perform 1%0
bpf.ALUOpX{
Op: bpf.ALUOpMod,
},
// Return 4 bytes if program does not terminate
bpf.LoadConstant{
Val: 12,
},
bpf.RetA{},
})
if err != nil {
t.Fatalf("failed to load BPF program: %v", err)
}
defer done()
out, err := vm.Run([]byte{
0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff,
0, 1, 3, 4,
})
if err != nil {
t.Fatalf("unexpected error while running program: %v", err)
}
if want, got := 0, out; want != got {
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
want, got)
}
}
func TestVMALUOpXor(t *testing.T) {
vm, done, err := testVM(t, []bpf.Instruction{
bpf.LoadAbsolute{
Off: 8,
Size: 1,
},
bpf.ALUOpConstant{
Op: bpf.ALUOpXor,
Val: 0x0a,
},
bpf.JumpIf{
Cond: bpf.JumpEqual,
Val: 0x01,
SkipTrue: 1,
},
bpf.RetConstant{
Val: 0,
},
bpf.RetConstant{
Val: 9,
},
})
if err != nil {
t.Fatalf("failed to load BPF program: %v", err)
}
defer done()
out, err := vm.Run([]byte{
0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff,
0x0b, 0x00, 0x00, 0x00,
})
if err != nil {
t.Fatalf("unexpected error while running program: %v", err)
}
if want, got := 1, out; want != got {
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
want, got)
}
}
func TestVMALUOpUnknown(t *testing.T) {
vm, done, err := testVM(t, []bpf.Instruction{
bpf.LoadAbsolute{
Off: 8,
Size: 1,
},
bpf.ALUOpConstant{
Op: bpf.ALUOpAdd,
Val: 1,
},
// Verify that an unknown operation is a no-op
bpf.ALUOpConstant{
Op: 100,
},
bpf.JumpIf{
Cond: bpf.JumpEqual,
Val: 0x02,
SkipTrue: 1,
},
bpf.RetConstant{
Val: 0,
},
bpf.RetConstant{
Val: 9,
},
})
if err != nil {
t.Fatalf("failed to load BPF program: %v", err)
}
defer done()
out, err := vm.Run([]byte{
0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff,
1,
})
if err != nil {
t.Fatalf("unexpected error while running program: %v", err)
}
if want, got := 1, out; want != got {
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
want, got)
}
}

View File

@ -1,192 +0,0 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package bpf_test
import (
"net"
"runtime"
"testing"
"time"
"golang.org/x/net/bpf"
"golang.org/x/net/ipv4"
)
// A virtualMachine is a BPF virtual machine which can process an
// input packet against a BPF program and render a verdict.
type virtualMachine interface {
Run(in []byte) (int, error)
}
// canUseOSVM indicates if the OS BPF VM is available on this platform.
func canUseOSVM() bool {
// OS BPF VM can only be used on platforms where x/net/ipv4 supports
// attaching a BPF program to a socket.
switch runtime.GOOS {
case "linux":
return true
}
return false
}
// All BPF tests against both the Go VM and OS VM are assumed to
// be used with a UDP socket. As a result, the entire contents
// of a UDP datagram is sent through the BPF program, but only
// the body after the UDP header will ever be returned in output.
// testVM sets up a Go BPF VM, and if available, a native OS BPF VM
// for integration testing.
func testVM(t *testing.T, filter []bpf.Instruction) (virtualMachine, func(), error) {
goVM, err := bpf.NewVM(filter)
if err != nil {
// Some tests expect an error, so this error must be returned
// instead of fatally exiting the test
return nil, nil, err
}
mvm := &multiVirtualMachine{
goVM: goVM,
t: t,
}
// If available, add the OS VM for tests which verify that both the Go
// VM and OS VM have exactly the same output for the same input program
// and packet.
done := func() {}
if canUseOSVM() {
osVM, osVMDone := testOSVM(t, filter)
done = func() { osVMDone() }
mvm.osVM = osVM
}
return mvm, done, nil
}
// udpHeaderLen is the length of a UDP header.
const udpHeaderLen = 8
// A multiVirtualMachine is a virtualMachine which can call out to both the Go VM
// and the native OS VM, if the OS VM is available.
type multiVirtualMachine struct {
goVM virtualMachine
osVM virtualMachine
t *testing.T
}
func (mvm *multiVirtualMachine) Run(in []byte) (int, error) {
if len(in) < udpHeaderLen {
mvm.t.Fatalf("input must be at least length of UDP header (%d), got: %d",
udpHeaderLen, len(in))
}
// All tests have a UDP header as part of input, because the OS VM
// packets always will. For the Go VM, this output is trimmed before
// being sent back to tests.
goOut, goErr := mvm.goVM.Run(in)
if goOut >= udpHeaderLen {
goOut -= udpHeaderLen
}
// If Go output is larger than the size of the packet, packet filtering
// interop tests must trim the output bytes to the length of the packet.
// The BPF VM should not do this on its own, as other uses of it do
// not trim the output byte count.
trim := len(in) - udpHeaderLen
if goOut > trim {
goOut = trim
}
// When the OS VM is not available, process using the Go VM alone
if mvm.osVM == nil {
return goOut, goErr
}
// The OS VM will apply its own UDP header, so remove the pseudo header
// that the Go VM needs.
osOut, err := mvm.osVM.Run(in[udpHeaderLen:])
if err != nil {
mvm.t.Fatalf("error while running OS VM: %v", err)
}
// Verify both VMs return same number of bytes
var mismatch bool
if goOut != osOut {
mismatch = true
mvm.t.Logf("output byte count does not match:\n- go: %v\n- os: %v", goOut, osOut)
}
if mismatch {
mvm.t.Fatal("Go BPF and OS BPF packet outputs do not match")
}
return goOut, goErr
}
// An osVirtualMachine is a virtualMachine which uses the OS's BPF VM for
// processing BPF programs.
type osVirtualMachine struct {
l net.PacketConn
s net.Conn
}
// testOSVM creates a virtualMachine which uses the OS's BPF VM by injecting
// packets into a UDP listener with a BPF program attached to it.
func testOSVM(t *testing.T, filter []bpf.Instruction) (virtualMachine, func()) {
l, err := net.ListenPacket("udp4", "127.0.0.1:0")
if err != nil {
t.Fatalf("failed to open OS VM UDP listener: %v", err)
}
prog, err := bpf.Assemble(filter)
if err != nil {
t.Fatalf("failed to compile BPF program: %v", err)
}
p := ipv4.NewPacketConn(l)
if err = p.SetBPF(prog); err != nil {
t.Fatalf("failed to attach BPF program to listener: %v", err)
}
s, err := net.Dial("udp4", l.LocalAddr().String())
if err != nil {
t.Fatalf("failed to dial connection to listener: %v", err)
}
done := func() {
_ = s.Close()
_ = l.Close()
}
return &osVirtualMachine{
l: l,
s: s,
}, done
}
// Run sends the input bytes into the OS's BPF VM and returns its verdict.
func (vm *osVirtualMachine) Run(in []byte) (int, error) {
go func() {
_, _ = vm.s.Write(in)
}()
vm.l.SetDeadline(time.Now().Add(50 * time.Millisecond))
var b [512]byte
n, _, err := vm.l.ReadFrom(b[:])
if err != nil {
// A timeout indicates that BPF filtered out the packet, and thus,
// no input should be returned.
if nerr, ok := err.(net.Error); ok && nerr.Timeout() {
return n, nil
}
return n, err
}
return n, nil
}

View File

@ -1,49 +0,0 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package bpf_test
import (
"testing"
"golang.org/x/net/bpf"
)
func TestVMLoadExtensionNotImplemented(t *testing.T) {
_, _, err := testVM(t, []bpf.Instruction{
bpf.LoadExtension{
Num: 100,
},
bpf.RetA{},
})
if errStr(err) != "extension 100 not implemented" {
t.Fatalf("unexpected error: %v", err)
}
}
func TestVMLoadExtensionExtLen(t *testing.T) {
vm, done, err := testVM(t, []bpf.Instruction{
bpf.LoadExtension{
Num: bpf.ExtLen,
},
bpf.RetA{},
})
if err != nil {
t.Fatalf("failed to load BPF program: %v", err)
}
defer done()
out, err := vm.Run([]byte{
0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff,
0, 1, 2, 3,
})
if err != nil {
t.Fatalf("unexpected error while running program: %v", err)
}
if want, got := 4, out; want != got {
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
want, got)
}
}

View File

@ -1,380 +0,0 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package bpf_test
import (
"testing"
"golang.org/x/net/bpf"
)
func TestVMJumpOne(t *testing.T) {
vm, done, err := testVM(t, []bpf.Instruction{
bpf.LoadAbsolute{
Off: 8,
Size: 1,
},
bpf.Jump{
Skip: 1,
},
bpf.RetConstant{
Val: 0,
},
bpf.RetConstant{
Val: 9,
},
})
if err != nil {
t.Fatalf("failed to load BPF program: %v", err)
}
defer done()
out, err := vm.Run([]byte{
0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff,
1,
})
if err != nil {
t.Fatalf("unexpected error while running program: %v", err)
}
if want, got := 1, out; want != got {
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
want, got)
}
}
func TestVMJumpOutOfProgram(t *testing.T) {
_, _, err := testVM(t, []bpf.Instruction{
bpf.Jump{
Skip: 1,
},
bpf.RetA{},
})
if errStr(err) != "cannot jump 1 instructions; jumping past program bounds" {
t.Fatalf("unexpected error: %v", err)
}
}
func TestVMJumpIfTrueOutOfProgram(t *testing.T) {
_, _, err := testVM(t, []bpf.Instruction{
bpf.JumpIf{
Cond: bpf.JumpEqual,
SkipTrue: 2,
},
bpf.RetA{},
})
if errStr(err) != "cannot jump 2 instructions in true case; jumping past program bounds" {
t.Fatalf("unexpected error: %v", err)
}
}
func TestVMJumpIfFalseOutOfProgram(t *testing.T) {
_, _, err := testVM(t, []bpf.Instruction{
bpf.JumpIf{
Cond: bpf.JumpEqual,
SkipFalse: 3,
},
bpf.RetA{},
})
if errStr(err) != "cannot jump 3 instructions in false case; jumping past program bounds" {
t.Fatalf("unexpected error: %v", err)
}
}
func TestVMJumpIfEqual(t *testing.T) {
vm, done, err := testVM(t, []bpf.Instruction{
bpf.LoadAbsolute{
Off: 8,
Size: 1,
},
bpf.JumpIf{
Cond: bpf.JumpEqual,
Val: 1,
SkipTrue: 1,
},
bpf.RetConstant{
Val: 0,
},
bpf.RetConstant{
Val: 9,
},
})
if err != nil {
t.Fatalf("failed to load BPF program: %v", err)
}
defer done()
out, err := vm.Run([]byte{
0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff,
1,
})
if err != nil {
t.Fatalf("unexpected error while running program: %v", err)
}
if want, got := 1, out; want != got {
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
want, got)
}
}
func TestVMJumpIfNotEqual(t *testing.T) {
vm, done, err := testVM(t, []bpf.Instruction{
bpf.LoadAbsolute{
Off: 8,
Size: 1,
},
bpf.JumpIf{
Cond: bpf.JumpNotEqual,
Val: 1,
SkipFalse: 1,
},
bpf.RetConstant{
Val: 0,
},
bpf.RetConstant{
Val: 9,
},
})
if err != nil {
t.Fatalf("failed to load BPF program: %v", err)
}
defer done()
out, err := vm.Run([]byte{
0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff,
1,
})
if err != nil {
t.Fatalf("unexpected error while running program: %v", err)
}
if want, got := 1, out; want != got {
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
want, got)
}
}
func TestVMJumpIfGreaterThan(t *testing.T) {
vm, done, err := testVM(t, []bpf.Instruction{
bpf.LoadAbsolute{
Off: 8,
Size: 4,
},
bpf.JumpIf{
Cond: bpf.JumpGreaterThan,
Val: 0x00010202,
SkipTrue: 1,
},
bpf.RetConstant{
Val: 0,
},
bpf.RetConstant{
Val: 12,
},
})
if err != nil {
t.Fatalf("failed to load BPF program: %v", err)
}
defer done()
out, err := vm.Run([]byte{
0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff,
0, 1, 2, 3,
})
if err != nil {
t.Fatalf("unexpected error while running program: %v", err)
}
if want, got := 4, out; want != got {
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
want, got)
}
}
func TestVMJumpIfLessThan(t *testing.T) {
vm, done, err := testVM(t, []bpf.Instruction{
bpf.LoadAbsolute{
Off: 8,
Size: 4,
},
bpf.JumpIf{
Cond: bpf.JumpLessThan,
Val: 0xff010203,
SkipTrue: 1,
},
bpf.RetConstant{
Val: 0,
},
bpf.RetConstant{
Val: 12,
},
})
if err != nil {
t.Fatalf("failed to load BPF program: %v", err)
}
defer done()
out, err := vm.Run([]byte{
0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff,
0, 1, 2, 3,
})
if err != nil {
t.Fatalf("unexpected error while running program: %v", err)
}
if want, got := 4, out; want != got {
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
want, got)
}
}
func TestVMJumpIfGreaterOrEqual(t *testing.T) {
vm, done, err := testVM(t, []bpf.Instruction{
bpf.LoadAbsolute{
Off: 8,
Size: 4,
},
bpf.JumpIf{
Cond: bpf.JumpGreaterOrEqual,
Val: 0x00010203,
SkipTrue: 1,
},
bpf.RetConstant{
Val: 0,
},
bpf.RetConstant{
Val: 12,
},
})
if err != nil {
t.Fatalf("failed to load BPF program: %v", err)
}
defer done()
out, err := vm.Run([]byte{
0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff,
0, 1, 2, 3,
})
if err != nil {
t.Fatalf("unexpected error while running program: %v", err)
}
if want, got := 4, out; want != got {
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
want, got)
}
}
func TestVMJumpIfLessOrEqual(t *testing.T) {
vm, done, err := testVM(t, []bpf.Instruction{
bpf.LoadAbsolute{
Off: 8,
Size: 4,
},
bpf.JumpIf{
Cond: bpf.JumpLessOrEqual,
Val: 0xff010203,
SkipTrue: 1,
},
bpf.RetConstant{
Val: 0,
},
bpf.RetConstant{
Val: 12,
},
})
if err != nil {
t.Fatalf("failed to load BPF program: %v", err)
}
defer done()
out, err := vm.Run([]byte{
0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff,
0, 1, 2, 3,
})
if err != nil {
t.Fatalf("unexpected error while running program: %v", err)
}
if want, got := 4, out; want != got {
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
want, got)
}
}
func TestVMJumpIfBitsSet(t *testing.T) {
vm, done, err := testVM(t, []bpf.Instruction{
bpf.LoadAbsolute{
Off: 8,
Size: 2,
},
bpf.JumpIf{
Cond: bpf.JumpBitsSet,
Val: 0x1122,
SkipTrue: 1,
},
bpf.RetConstant{
Val: 0,
},
bpf.RetConstant{
Val: 10,
},
})
if err != nil {
t.Fatalf("failed to load BPF program: %v", err)
}
defer done()
out, err := vm.Run([]byte{
0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff,
0x01, 0x02,
})
if err != nil {
t.Fatalf("unexpected error while running program: %v", err)
}
if want, got := 2, out; want != got {
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
want, got)
}
}
func TestVMJumpIfBitsNotSet(t *testing.T) {
vm, done, err := testVM(t, []bpf.Instruction{
bpf.LoadAbsolute{
Off: 8,
Size: 2,
},
bpf.JumpIf{
Cond: bpf.JumpBitsNotSet,
Val: 0x1221,
SkipTrue: 1,
},
bpf.RetConstant{
Val: 0,
},
bpf.RetConstant{
Val: 10,
},
})
if err != nil {
t.Fatalf("failed to load BPF program: %v", err)
}
defer done()
out, err := vm.Run([]byte{
0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff,
0x01, 0x02,
})
if err != nil {
t.Fatalf("unexpected error while running program: %v", err)
}
if want, got := 2, out; want != got {
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
want, got)
}
}

View File

@ -1,246 +0,0 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package bpf_test
import (
"net"
"testing"
"golang.org/x/net/bpf"
"golang.org/x/net/ipv4"
)
func TestVMLoadAbsoluteOffsetOutOfBounds(t *testing.T) {
vm, done, err := testVM(t, []bpf.Instruction{
bpf.LoadAbsolute{
Off: 100,
Size: 2,
},
bpf.RetA{},
})
if err != nil {
t.Fatalf("failed to load BPF program: %v", err)
}
defer done()
out, err := vm.Run([]byte{
0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff,
0, 1, 2, 3,
})
if err != nil {
t.Fatalf("unexpected error while running program: %v", err)
}
if want, got := 0, out; want != got {
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
want, got)
}
}
func TestVMLoadAbsoluteOffsetPlusSizeOutOfBounds(t *testing.T) {
vm, done, err := testVM(t, []bpf.Instruction{
bpf.LoadAbsolute{
Off: 8,
Size: 2,
},
bpf.RetA{},
})
if err != nil {
t.Fatalf("failed to load BPF program: %v", err)
}
defer done()
out, err := vm.Run([]byte{
0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff,
0,
})
if err != nil {
t.Fatalf("unexpected error while running program: %v", err)
}
if want, got := 0, out; want != got {
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
want, got)
}
}
func TestVMLoadAbsoluteBadInstructionSize(t *testing.T) {
_, _, err := testVM(t, []bpf.Instruction{
bpf.LoadAbsolute{
Size: 5,
},
bpf.RetA{},
})
if errStr(err) != "assembling instruction 1: invalid load byte length 0" {
t.Fatalf("unexpected error: %v", err)
}
}
func TestVMLoadConstantOK(t *testing.T) {
vm, done, err := testVM(t, []bpf.Instruction{
bpf.LoadConstant{
Dst: bpf.RegX,
Val: 9,
},
bpf.TXA{},
bpf.RetA{},
})
if err != nil {
t.Fatalf("failed to load BPF program: %v", err)
}
defer done()
out, err := vm.Run([]byte{
0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff,
0,
})
if err != nil {
t.Fatalf("unexpected error while running program: %v", err)
}
if want, got := 1, out; want != got {
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
want, got)
}
}
func TestVMLoadIndirectOutOfBounds(t *testing.T) {
vm, done, err := testVM(t, []bpf.Instruction{
bpf.LoadIndirect{
Off: 100,
Size: 1,
},
bpf.RetA{},
})
if err != nil {
t.Fatalf("failed to load BPF program: %v", err)
}
defer done()
out, err := vm.Run([]byte{
0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff,
0,
})
if err != nil {
t.Fatalf("unexpected error while running program: %v", err)
}
if want, got := 0, out; want != got {
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
want, got)
}
}
func TestVMLoadMemShiftOutOfBounds(t *testing.T) {
vm, done, err := testVM(t, []bpf.Instruction{
bpf.LoadMemShift{
Off: 100,
},
bpf.RetA{},
})
if err != nil {
t.Fatalf("failed to load BPF program: %v", err)
}
defer done()
out, err := vm.Run([]byte{
0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff,
0,
})
if err != nil {
t.Fatalf("unexpected error while running program: %v", err)
}
if want, got := 0, out; want != got {
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
want, got)
}
}
const (
dhcp4Port = 53
)
func TestVMLoadMemShiftLoadIndirectNoResult(t *testing.T) {
vm, in, done := testDHCPv4(t)
defer done()
// Append mostly empty UDP header with incorrect DHCPv4 port
in = append(in, []byte{
0, 0,
0, dhcp4Port + 1,
0, 0,
0, 0,
}...)
out, err := vm.Run(in)
if err != nil {
t.Fatalf("unexpected error while running program: %v", err)
}
if want, got := 0, out; want != got {
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
want, got)
}
}
func TestVMLoadMemShiftLoadIndirectOK(t *testing.T) {
vm, in, done := testDHCPv4(t)
defer done()
// Append mostly empty UDP header with correct DHCPv4 port
in = append(in, []byte{
0, 0,
0, dhcp4Port,
0, 0,
0, 0,
}...)
out, err := vm.Run(in)
if err != nil {
t.Fatalf("unexpected error while running program: %v", err)
}
if want, got := len(in)-8, out; want != got {
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
want, got)
}
}
func testDHCPv4(t *testing.T) (virtualMachine, []byte, func()) {
// DHCPv4 test data courtesy of David Anderson:
// https://github.com/google/netboot/blob/master/dhcp4/conn_linux.go#L59-L70
vm, done, err := testVM(t, []bpf.Instruction{
// Load IPv4 packet length
bpf.LoadMemShift{Off: 8},
// Get UDP dport
bpf.LoadIndirect{Off: 8 + 2, Size: 2},
// Correct dport?
bpf.JumpIf{Cond: bpf.JumpEqual, Val: dhcp4Port, SkipFalse: 1},
// Accept
bpf.RetConstant{Val: 1500},
// Ignore
bpf.RetConstant{Val: 0},
})
if err != nil {
t.Fatalf("failed to load BPF program: %v", err)
}
// Minimal requirements to make a valid IPv4 header
h := &ipv4.Header{
Len: ipv4.HeaderLen,
Src: net.IPv4(192, 168, 1, 1),
Dst: net.IPv4(192, 168, 1, 2),
}
hb, err := h.Marshal()
if err != nil {
t.Fatalf("failed to marshal IPv4 header: %v", err)
}
hb = append([]byte{
0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff,
}, hb...)
return vm, hb, done
}

View File

@ -1,115 +0,0 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package bpf_test
import (
"testing"
"golang.org/x/net/bpf"
)
func TestVMRetA(t *testing.T) {
vm, done, err := testVM(t, []bpf.Instruction{
bpf.LoadAbsolute{
Off: 8,
Size: 1,
},
bpf.RetA{},
})
if err != nil {
t.Fatalf("failed to load BPF program: %v", err)
}
defer done()
out, err := vm.Run([]byte{
0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff,
9,
})
if err != nil {
t.Fatalf("unexpected error while running program: %v", err)
}
if want, got := 1, out; want != got {
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
want, got)
}
}
func TestVMRetALargerThanInput(t *testing.T) {
vm, done, err := testVM(t, []bpf.Instruction{
bpf.LoadAbsolute{
Off: 8,
Size: 2,
},
bpf.RetA{},
})
if err != nil {
t.Fatalf("failed to load BPF program: %v", err)
}
defer done()
out, err := vm.Run([]byte{
0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff,
0, 255,
})
if err != nil {
t.Fatalf("unexpected error while running program: %v", err)
}
if want, got := 2, out; want != got {
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
want, got)
}
}
func TestVMRetConstant(t *testing.T) {
vm, done, err := testVM(t, []bpf.Instruction{
bpf.RetConstant{
Val: 9,
},
})
if err != nil {
t.Fatalf("failed to load BPF program: %v", err)
}
defer done()
out, err := vm.Run([]byte{
0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff,
0, 1,
})
if err != nil {
t.Fatalf("unexpected error while running program: %v", err)
}
if want, got := 1, out; want != got {
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
want, got)
}
}
func TestVMRetConstantLargerThanInput(t *testing.T) {
vm, done, err := testVM(t, []bpf.Instruction{
bpf.RetConstant{
Val: 16,
},
})
if err != nil {
t.Fatalf("failed to load BPF program: %v", err)
}
defer done()
out, err := vm.Run([]byte{
0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff,
0, 1,
})
if err != nil {
t.Fatalf("unexpected error while running program: %v", err)
}
if want, got := 2, out; want != got {
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
want, got)
}
}

View File

@ -1,247 +0,0 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package bpf_test
import (
"testing"
"golang.org/x/net/bpf"
)
func TestVMStoreScratchInvalidScratchRegisterTooSmall(t *testing.T) {
_, _, err := testVM(t, []bpf.Instruction{
bpf.StoreScratch{
Src: bpf.RegA,
N: -1,
},
bpf.RetA{},
})
if errStr(err) != "assembling instruction 1: invalid scratch slot -1" {
t.Fatalf("unexpected error: %v", err)
}
}
func TestVMStoreScratchInvalidScratchRegisterTooLarge(t *testing.T) {
_, _, err := testVM(t, []bpf.Instruction{
bpf.StoreScratch{
Src: bpf.RegA,
N: 16,
},
bpf.RetA{},
})
if errStr(err) != "assembling instruction 1: invalid scratch slot 16" {
t.Fatalf("unexpected error: %v", err)
}
}
func TestVMStoreScratchUnknownSourceRegister(t *testing.T) {
_, _, err := testVM(t, []bpf.Instruction{
bpf.StoreScratch{
Src: 100,
N: 0,
},
bpf.RetA{},
})
if errStr(err) != "assembling instruction 1: invalid source register 100" {
t.Fatalf("unexpected error: %v", err)
}
}
func TestVMLoadScratchInvalidScratchRegisterTooSmall(t *testing.T) {
_, _, err := testVM(t, []bpf.Instruction{
bpf.LoadScratch{
Dst: bpf.RegX,
N: -1,
},
bpf.RetA{},
})
if errStr(err) != "assembling instruction 1: invalid scratch slot -1" {
t.Fatalf("unexpected error: %v", err)
}
}
func TestVMLoadScratchInvalidScratchRegisterTooLarge(t *testing.T) {
_, _, err := testVM(t, []bpf.Instruction{
bpf.LoadScratch{
Dst: bpf.RegX,
N: 16,
},
bpf.RetA{},
})
if errStr(err) != "assembling instruction 1: invalid scratch slot 16" {
t.Fatalf("unexpected error: %v", err)
}
}
func TestVMLoadScratchUnknownDestinationRegister(t *testing.T) {
_, _, err := testVM(t, []bpf.Instruction{
bpf.LoadScratch{
Dst: 100,
N: 0,
},
bpf.RetA{},
})
if errStr(err) != "assembling instruction 1: invalid target register 100" {
t.Fatalf("unexpected error: %v", err)
}
}
func TestVMStoreScratchLoadScratchOneValue(t *testing.T) {
vm, done, err := testVM(t, []bpf.Instruction{
// Load byte 255
bpf.LoadAbsolute{
Off: 8,
Size: 1,
},
// Copy to X and store in scratch[0]
bpf.TAX{},
bpf.StoreScratch{
Src: bpf.RegX,
N: 0,
},
// Load byte 1
bpf.LoadAbsolute{
Off: 9,
Size: 1,
},
// Overwrite 1 with 255 from scratch[0]
bpf.LoadScratch{
Dst: bpf.RegA,
N: 0,
},
// Return 255
bpf.RetA{},
})
if err != nil {
t.Fatalf("failed to load BPF program: %v", err)
}
defer done()
out, err := vm.Run([]byte{
0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff,
255, 1, 2,
})
if err != nil {
t.Fatalf("unexpected error while running program: %v", err)
}
if want, got := 3, out; want != got {
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
want, got)
}
}
func TestVMStoreScratchLoadScratchMultipleValues(t *testing.T) {
vm, done, err := testVM(t, []bpf.Instruction{
// Load byte 10
bpf.LoadAbsolute{
Off: 8,
Size: 1,
},
// Store in scratch[0]
bpf.StoreScratch{
Src: bpf.RegA,
N: 0,
},
// Load byte 20
bpf.LoadAbsolute{
Off: 9,
Size: 1,
},
// Store in scratch[1]
bpf.StoreScratch{
Src: bpf.RegA,
N: 1,
},
// Load byte 30
bpf.LoadAbsolute{
Off: 10,
Size: 1,
},
// Store in scratch[2]
bpf.StoreScratch{
Src: bpf.RegA,
N: 2,
},
// Load byte 1
bpf.LoadAbsolute{
Off: 11,
Size: 1,
},
// Store in scratch[3]
bpf.StoreScratch{
Src: bpf.RegA,
N: 3,
},
// Load in byte 10 to X
bpf.LoadScratch{
Dst: bpf.RegX,
N: 0,
},
// Copy X -> A
bpf.TXA{},
// Verify value is 10
bpf.JumpIf{
Cond: bpf.JumpEqual,
Val: 10,
SkipTrue: 1,
},
// Fail test if incorrect
bpf.RetConstant{
Val: 0,
},
// Load in byte 20 to A
bpf.LoadScratch{
Dst: bpf.RegA,
N: 1,
},
// Verify value is 20
bpf.JumpIf{
Cond: bpf.JumpEqual,
Val: 20,
SkipTrue: 1,
},
// Fail test if incorrect
bpf.RetConstant{
Val: 0,
},
// Load in byte 30 to A
bpf.LoadScratch{
Dst: bpf.RegA,
N: 2,
},
// Verify value is 30
bpf.JumpIf{
Cond: bpf.JumpEqual,
Val: 30,
SkipTrue: 1,
},
// Fail test if incorrect
bpf.RetConstant{
Val: 0,
},
// Return first two bytes on success
bpf.RetConstant{
Val: 10,
},
})
if err != nil {
t.Fatalf("failed to load BPF program: %v", err)
}
defer done()
out, err := vm.Run([]byte{
0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff,
10, 20, 30, 1,
})
if err != nil {
t.Fatalf("unexpected error while running program: %v", err)
}
if want, got := 2, out; want != got {
t.Fatalf("unexpected number of output bytes:\n- want: %d\n- got: %d",
want, got)
}
}

View File

@ -1,144 +0,0 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package bpf_test
import (
"fmt"
"testing"
"golang.org/x/net/bpf"
)
var _ bpf.Instruction = unknown{}
type unknown struct{}
func (unknown) Assemble() (bpf.RawInstruction, error) {
return bpf.RawInstruction{}, nil
}
func TestVMUnknownInstruction(t *testing.T) {
vm, done, err := testVM(t, []bpf.Instruction{
bpf.LoadConstant{
Dst: bpf.RegA,
Val: 100,
},
// Should terminate the program with an error immediately
unknown{},
bpf.RetA{},
})
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
defer done()
_, err = vm.Run([]byte{
0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff,
0x00, 0x00,
})
if errStr(err) != "unknown Instruction at index 1: bpf_test.unknown" {
t.Fatalf("unexpected error while running program: %v", err)
}
}
func TestVMNoReturnInstruction(t *testing.T) {
_, _, err := testVM(t, []bpf.Instruction{
bpf.LoadConstant{
Dst: bpf.RegA,
Val: 1,
},
})
if errStr(err) != "BPF program must end with RetA or RetConstant" {
t.Fatalf("unexpected error: %v", err)
}
}
func TestVMNoInputInstructions(t *testing.T) {
_, _, err := testVM(t, []bpf.Instruction{})
if errStr(err) != "one or more Instructions must be specified" {
t.Fatalf("unexpected error: %v", err)
}
}
// ExampleNewVM demonstrates usage of a VM, using an Ethernet frame
// as input and checking its EtherType to determine if it should be accepted.
func ExampleNewVM() {
// Offset | Length | Comment
// -------------------------
// 00 | 06 | Ethernet destination MAC address
// 06 | 06 | Ethernet source MAC address
// 12 | 02 | Ethernet EtherType
const (
etOff = 12
etLen = 2
etARP = 0x0806
)
// Set up a VM to filter traffic based on if its EtherType
// matches the ARP EtherType.
vm, err := bpf.NewVM([]bpf.Instruction{
// Load EtherType value from Ethernet header
bpf.LoadAbsolute{
Off: etOff,
Size: etLen,
},
// If EtherType is equal to the ARP EtherType, jump to allow
// packet to be accepted
bpf.JumpIf{
Cond: bpf.JumpEqual,
Val: etARP,
SkipTrue: 1,
},
// EtherType does not match the ARP EtherType
bpf.RetConstant{
Val: 0,
},
// EtherType matches the ARP EtherType, accept up to 1500
// bytes of packet
bpf.RetConstant{
Val: 1500,
},
})
if err != nil {
panic(fmt.Sprintf("failed to load BPF program: %v", err))
}
// Create an Ethernet frame with the ARP EtherType for testing
frame := []byte{
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55,
0x08, 0x06,
// Payload omitted for brevity
}
// Run our VM's BPF program using the Ethernet frame as input
out, err := vm.Run(frame)
if err != nil {
panic(fmt.Sprintf("failed to accept Ethernet frame: %v", err))
}
// BPF VM can return a byte count greater than the number of input
// bytes, so trim the output to match the input byte length
if out > len(frame) {
out = len(frame)
}
fmt.Printf("out: %d bytes", out)
// Output:
// out: 14 bytes
}
// errStr returns the string representation of an error, or
// "<nil>" if it is nil.
func errStr(err error) string {
if err == nil {
return "<nil>"
}
return err.Error()
}

View File

@ -2,7 +2,7 @@
// GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
// Package iana provides protocol number resources managed by the Internet Assigned Numbers Authority (IANA).
package iana // import "golang.org/x/net/internal/iana"
package iana
// Differentiated Services Field Codepoints (DSCP), Updated: 2013-06-25
const (

View File

@ -1,93 +0,0 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package ipv4_test
import (
"net"
"runtime"
"testing"
"time"
"golang.org/x/net/bpf"
"golang.org/x/net/ipv4"
)
func TestBPF(t *testing.T) {
if runtime.GOOS != "linux" {
t.Skipf("not supported on %s", runtime.GOOS)
}
l, err := net.ListenPacket("udp4", "127.0.0.1:0")
if err != nil {
t.Fatal(err)
}
defer l.Close()
p := ipv4.NewPacketConn(l)
// This filter accepts UDP packets whose first payload byte is
// even.
prog, err := bpf.Assemble([]bpf.Instruction{
// Load the first byte of the payload (skipping UDP header).
bpf.LoadAbsolute{Off: 8, Size: 1},
// Select LSB of the byte.
bpf.ALUOpConstant{Op: bpf.ALUOpAnd, Val: 1},
// Byte is even?
bpf.JumpIf{Cond: bpf.JumpEqual, Val: 0, SkipFalse: 1},
// Accept.
bpf.RetConstant{Val: 4096},
// Ignore.
bpf.RetConstant{Val: 0},
})
if err != nil {
t.Fatalf("compiling BPF: %s", err)
}
if err = p.SetBPF(prog); err != nil {
t.Fatalf("attaching filter to Conn: %s", err)
}
s, err := net.Dial("udp4", l.LocalAddr().String())
if err != nil {
t.Fatal(err)
}
defer s.Close()
go func() {
for i := byte(0); i < 10; i++ {
s.Write([]byte{i})
}
}()
l.SetDeadline(time.Now().Add(2 * time.Second))
seen := make([]bool, 5)
for {
var b [512]byte
n, _, err := l.ReadFrom(b[:])
if err != nil {
t.Fatalf("reading from listener: %s", err)
}
if n != 1 {
t.Fatalf("unexpected packet length, want 1, got %d", n)
}
if b[0] >= 10 {
t.Fatalf("unexpected byte, want 0-9, got %d", b[0])
}
if b[0]%2 != 0 {
t.Fatalf("got odd byte %d, wanted only even bytes", b[0])
}
seen[b[0]/2] = true
seenAll := true
for _, v := range seen {
if !v {
seenAll = false
break
}
}
if seenAll {
break
}
}
}

View File

@ -239,4 +239,4 @@
// IGMPv1 or IGMPv2 and starts to listen to multicast traffic.
// In the fallback case, ExcludeSourceSpecificGroup and
// IncludeSourceSpecificGroup may return an error.
package ipv4 // import "golang.org/x/net/ipv4"
package ipv4

View File

@ -1,224 +0,0 @@
// 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.
package ipv4_test
import (
"fmt"
"log"
"net"
"os"
"runtime"
"time"
"golang.org/x/net/icmp"
"golang.org/x/net/ipv4"
)
func ExampleConn_markingTCP() {
ln, err := net.Listen("tcp", "0.0.0.0:1024")
if err != nil {
log.Fatal(err)
}
defer ln.Close()
for {
c, err := ln.Accept()
if err != nil {
log.Fatal(err)
}
go func(c net.Conn) {
defer c.Close()
if c.RemoteAddr().(*net.TCPAddr).IP.To4() != nil {
p := ipv4.NewConn(c)
if err := p.SetTOS(0x28); err != nil { // DSCP AF11
log.Fatal(err)
}
if err := p.SetTTL(128); err != nil {
log.Fatal(err)
}
}
if _, err := c.Write([]byte("HELLO-R-U-THERE-ACK")); err != nil {
log.Fatal(err)
}
}(c)
}
}
func ExamplePacketConn_servingOneShotMulticastDNS() {
c, err := net.ListenPacket("udp4", "0.0.0.0:5353") // mDNS over UDP
if err != nil {
log.Fatal(err)
}
defer c.Close()
p := ipv4.NewPacketConn(c)
en0, err := net.InterfaceByName("en0")
if err != nil {
log.Fatal(err)
}
mDNSLinkLocal := net.UDPAddr{IP: net.IPv4(224, 0, 0, 251)}
if err := p.JoinGroup(en0, &mDNSLinkLocal); err != nil {
log.Fatal(err)
}
defer p.LeaveGroup(en0, &mDNSLinkLocal)
if err := p.SetControlMessage(ipv4.FlagDst, true); err != nil {
log.Fatal(err)
}
b := make([]byte, 1500)
for {
_, cm, peer, err := p.ReadFrom(b)
if err != nil {
log.Fatal(err)
}
if !cm.Dst.IsMulticast() || !cm.Dst.Equal(mDNSLinkLocal.IP) {
continue
}
answers := []byte("FAKE-MDNS-ANSWERS") // fake mDNS answers, you need to implement this
if _, err := p.WriteTo(answers, nil, peer); err != nil {
log.Fatal(err)
}
}
}
func ExamplePacketConn_tracingIPPacketRoute() {
// Tracing an IP packet route to www.google.com.
const host = "www.google.com"
ips, err := net.LookupIP(host)
if err != nil {
log.Fatal(err)
}
var dst net.IPAddr
for _, ip := range ips {
if ip.To4() != nil {
dst.IP = ip
fmt.Printf("using %v for tracing an IP packet route to %s\n", dst.IP, host)
break
}
}
if dst.IP == nil {
log.Fatal("no A record found")
}
c, err := net.ListenPacket("ip4:1", "0.0.0.0") // ICMP for IPv4
if err != nil {
log.Fatal(err)
}
defer c.Close()
p := ipv4.NewPacketConn(c)
if err := p.SetControlMessage(ipv4.FlagTTL|ipv4.FlagSrc|ipv4.FlagDst|ipv4.FlagInterface, true); err != nil {
log.Fatal(err)
}
wm := icmp.Message{
Type: ipv4.ICMPTypeEcho, Code: 0,
Body: &icmp.Echo{
ID: os.Getpid() & 0xffff,
Data: []byte("HELLO-R-U-THERE"),
},
}
rb := make([]byte, 1500)
for i := 1; i <= 64; i++ { // up to 64 hops
wm.Body.(*icmp.Echo).Seq = i
wb, err := wm.Marshal(nil)
if err != nil {
log.Fatal(err)
}
if err := p.SetTTL(i); err != nil {
log.Fatal(err)
}
// In the real world usually there are several
// multiple traffic-engineered paths for each hop.
// You may need to probe a few times to each hop.
begin := time.Now()
if _, err := p.WriteTo(wb, nil, &dst); err != nil {
log.Fatal(err)
}
if err := p.SetReadDeadline(time.Now().Add(3 * time.Second)); err != nil {
log.Fatal(err)
}
n, cm, peer, err := p.ReadFrom(rb)
if err != nil {
if err, ok := err.(net.Error); ok && err.Timeout() {
fmt.Printf("%v\t*\n", i)
continue
}
log.Fatal(err)
}
rm, err := icmp.ParseMessage(1, rb[:n])
if err != nil {
log.Fatal(err)
}
rtt := time.Since(begin)
// In the real world you need to determine whether the
// received message is yours using ControlMessage.Src,
// ControlMessage.Dst, icmp.Echo.ID and icmp.Echo.Seq.
switch rm.Type {
case ipv4.ICMPTypeTimeExceeded:
names, _ := net.LookupAddr(peer.String())
fmt.Printf("%d\t%v %+v %v\n\t%+v\n", i, peer, names, rtt, cm)
case ipv4.ICMPTypeEchoReply:
names, _ := net.LookupAddr(peer.String())
fmt.Printf("%d\t%v %+v %v\n\t%+v\n", i, peer, names, rtt, cm)
return
default:
log.Printf("unknown ICMP message: %+v\n", rm)
}
}
}
func ExampleRawConn_advertisingOSPFHello() {
c, err := net.ListenPacket("ip4:89", "0.0.0.0") // OSPF for IPv4
if err != nil {
log.Fatal(err)
}
defer c.Close()
r, err := ipv4.NewRawConn(c)
if err != nil {
log.Fatal(err)
}
en0, err := net.InterfaceByName("en0")
if err != nil {
log.Fatal(err)
}
allSPFRouters := net.IPAddr{IP: net.IPv4(224, 0, 0, 5)}
if err := r.JoinGroup(en0, &allSPFRouters); err != nil {
log.Fatal(err)
}
defer r.LeaveGroup(en0, &allSPFRouters)
hello := make([]byte, 24) // fake hello data, you need to implement this
ospf := make([]byte, 24) // fake ospf header, you need to implement this
ospf[0] = 2 // version 2
ospf[1] = 1 // hello packet
ospf = append(ospf, hello...)
iph := &ipv4.Header{
Version: ipv4.Version,
Len: ipv4.HeaderLen,
TOS: 0xc0, // DSCP CS6
TotalLen: ipv4.HeaderLen + len(ospf),
TTL: 1,
Protocol: 89,
Dst: allSPFRouters.IP.To4(),
}
var cm *ipv4.ControlMessage
switch runtime.GOOS {
case "darwin", "linux":
cm = &ipv4.ControlMessage{IfIndex: en0.Index}
default:
if err := r.SetMulticastInterface(en0); err != nil {
log.Fatal(err)
}
}
if err := r.WriteTo(iph, ospf, cm); err != nil {
log.Fatal(err)
}
}

View File

@ -1,138 +0,0 @@
// 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.
package ipv4
import (
"bytes"
"encoding/binary"
"net"
"reflect"
"runtime"
"strings"
"testing"
)
type headerTest struct {
wireHeaderFromKernel [HeaderLen]byte
wireHeaderToKernel [HeaderLen]byte
wireHeaderFromTradBSDKernel [HeaderLen]byte
wireHeaderFromFreeBSD10Kernel [HeaderLen]byte
wireHeaderToTradBSDKernel [HeaderLen]byte
*Header
}
var headerLittleEndianTest = headerTest{
// TODO(mikio): Add platform dependent wire header formats when
// we support new platforms.
wireHeaderFromKernel: [HeaderLen]byte{
0x45, 0x01, 0xbe, 0xef,
0xca, 0xfe, 0x45, 0xdc,
0xff, 0x01, 0xde, 0xad,
172, 16, 254, 254,
192, 168, 0, 1,
},
wireHeaderToKernel: [HeaderLen]byte{
0x45, 0x01, 0xbe, 0xef,
0xca, 0xfe, 0x45, 0xdc,
0xff, 0x01, 0xde, 0xad,
172, 16, 254, 254,
192, 168, 0, 1,
},
wireHeaderFromTradBSDKernel: [HeaderLen]byte{
0x45, 0x01, 0xdb, 0xbe,
0xca, 0xfe, 0xdc, 0x45,
0xff, 0x01, 0xde, 0xad,
172, 16, 254, 254,
192, 168, 0, 1,
},
wireHeaderFromFreeBSD10Kernel: [HeaderLen]byte{
0x45, 0x01, 0xef, 0xbe,
0xca, 0xfe, 0xdc, 0x45,
0xff, 0x01, 0xde, 0xad,
172, 16, 254, 254,
192, 168, 0, 1,
},
wireHeaderToTradBSDKernel: [HeaderLen]byte{
0x45, 0x01, 0xef, 0xbe,
0xca, 0xfe, 0xdc, 0x45,
0xff, 0x01, 0xde, 0xad,
172, 16, 254, 254,
192, 168, 0, 1,
},
Header: &Header{
Version: Version,
Len: HeaderLen,
TOS: 1,
TotalLen: 0xbeef,
ID: 0xcafe,
Flags: DontFragment,
FragOff: 1500,
TTL: 255,
Protocol: 1,
Checksum: 0xdead,
Src: net.IPv4(172, 16, 254, 254),
Dst: net.IPv4(192, 168, 0, 1),
},
}
func TestMarshalHeader(t *testing.T) {
tt := &headerLittleEndianTest
if nativeEndian != binary.LittleEndian {
t.Skip("no test for non-little endian machine yet")
}
b, err := tt.Header.Marshal()
if err != nil {
t.Fatal(err)
}
var wh []byte
switch runtime.GOOS {
case "darwin", "dragonfly", "netbsd":
wh = tt.wireHeaderToTradBSDKernel[:]
case "freebsd":
if freebsdVersion < 1000000 {
wh = tt.wireHeaderToTradBSDKernel[:]
} else {
wh = tt.wireHeaderFromFreeBSD10Kernel[:]
}
default:
wh = tt.wireHeaderToKernel[:]
}
if !bytes.Equal(b, wh) {
t.Fatalf("got %#v; want %#v", b, wh)
}
}
func TestParseHeader(t *testing.T) {
tt := &headerLittleEndianTest
if nativeEndian != binary.LittleEndian {
t.Skip("no test for big endian machine yet")
}
var wh []byte
switch runtime.GOOS {
case "darwin", "dragonfly", "netbsd":
wh = tt.wireHeaderFromTradBSDKernel[:]
case "freebsd":
if freebsdVersion < 1000000 {
wh = tt.wireHeaderFromTradBSDKernel[:]
} else {
wh = tt.wireHeaderFromFreeBSD10Kernel[:]
}
default:
wh = tt.wireHeaderFromKernel[:]
}
h, err := ParseHeader(wh)
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(h, tt.Header) {
t.Fatalf("got %#v; want %#v", h, tt.Header)
}
s := h.String()
if strings.Contains(s, ",") {
t.Fatalf("should be space-separated values: %s", s)
}
}

View File

@ -1,95 +0,0 @@
// 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 ipv4_test
import (
"net"
"reflect"
"runtime"
"testing"
"golang.org/x/net/internal/nettest"
"golang.org/x/net/ipv4"
)
var icmpStringTests = []struct {
in ipv4.ICMPType
out string
}{
{ipv4.ICMPTypeDestinationUnreachable, "destination unreachable"},
{256, "<nil>"},
}
func TestICMPString(t *testing.T) {
for _, tt := range icmpStringTests {
s := tt.in.String()
if s != tt.out {
t.Errorf("got %s; want %s", s, tt.out)
}
}
}
func TestICMPFilter(t *testing.T) {
switch runtime.GOOS {
case "linux":
default:
t.Skipf("not supported on %s", runtime.GOOS)
}
var f ipv4.ICMPFilter
for _, toggle := range []bool{false, true} {
f.SetAll(toggle)
for _, typ := range []ipv4.ICMPType{
ipv4.ICMPTypeDestinationUnreachable,
ipv4.ICMPTypeEchoReply,
ipv4.ICMPTypeTimeExceeded,
ipv4.ICMPTypeParameterProblem,
} {
f.Accept(typ)
if f.WillBlock(typ) {
t.Errorf("ipv4.ICMPFilter.Set(%v, false) failed", typ)
}
f.Block(typ)
if !f.WillBlock(typ) {
t.Errorf("ipv4.ICMPFilter.Set(%v, true) failed", typ)
}
}
}
}
func TestSetICMPFilter(t *testing.T) {
switch runtime.GOOS {
case "linux":
default:
t.Skipf("not supported on %s", runtime.GOOS)
}
if m, ok := nettest.SupportsRawIPSocket(); !ok {
t.Skip(m)
}
c, err := net.ListenPacket("ip4:icmp", "127.0.0.1")
if err != nil {
t.Fatal(err)
}
defer c.Close()
p := ipv4.NewPacketConn(c)
var f ipv4.ICMPFilter
f.SetAll(true)
f.Accept(ipv4.ICMPTypeEcho)
f.Accept(ipv4.ICMPTypeEchoReply)
if err := p.SetICMPFilter(&f); err != nil {
t.Fatal(err)
}
kf, err := p.ICMPFilter()
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(kf, &f) {
t.Fatalf("got %#v; want %#v", kf, f)
}
}

View File

@ -1,21 +0,0 @@
// 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.
package ipv4_test
import (
"net"
"testing"
)
func acceptor(t *testing.T, ln net.Listener, done chan<- bool) {
defer func() { done <- true }()
c, err := ln.Accept()
if err != nil {
t.Error(err)
return
}
c.Close()
}

View File

@ -1,330 +0,0 @@
// 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.
package ipv4_test
import (
"bytes"
"net"
"os"
"runtime"
"testing"
"time"
"golang.org/x/net/icmp"
"golang.org/x/net/internal/iana"
"golang.org/x/net/internal/nettest"
"golang.org/x/net/ipv4"
)
var packetConnReadWriteMulticastUDPTests = []struct {
addr string
grp, src *net.UDPAddr
}{
{"224.0.0.0:0", &net.UDPAddr{IP: net.IPv4(224, 0, 0, 254)}, nil}, // see RFC 4727
{"232.0.1.0:0", &net.UDPAddr{IP: net.IPv4(232, 0, 1, 254)}, &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1)}}, // see RFC 5771
}
func TestPacketConnReadWriteMulticastUDP(t *testing.T) {
switch runtime.GOOS {
case "nacl", "plan9", "solaris", "windows":
t.Skipf("not supported on %s", runtime.GOOS)
}
ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagMulticast|net.FlagLoopback)
if ifi == nil {
t.Skipf("not available on %s", runtime.GOOS)
}
for _, tt := range packetConnReadWriteMulticastUDPTests {
c, err := net.ListenPacket("udp4", tt.addr)
if err != nil {
t.Fatal(err)
}
defer c.Close()
grp := *tt.grp
grp.Port = c.LocalAddr().(*net.UDPAddr).Port
p := ipv4.NewPacketConn(c)
defer p.Close()
if tt.src == nil {
if err := p.JoinGroup(ifi, &grp); err != nil {
t.Fatal(err)
}
defer p.LeaveGroup(ifi, &grp)
} else {
if err := p.JoinSourceSpecificGroup(ifi, &grp, tt.src); err != nil {
switch runtime.GOOS {
case "freebsd", "linux":
default: // platforms that don't support IGMPv2/3 fail here
t.Logf("not supported on %s", runtime.GOOS)
continue
}
t.Fatal(err)
}
defer p.LeaveSourceSpecificGroup(ifi, &grp, tt.src)
}
if err := p.SetMulticastInterface(ifi); err != nil {
t.Fatal(err)
}
if _, err := p.MulticastInterface(); err != nil {
t.Fatal(err)
}
if err := p.SetMulticastLoopback(true); err != nil {
t.Fatal(err)
}
if _, err := p.MulticastLoopback(); err != nil {
t.Fatal(err)
}
cf := ipv4.FlagTTL | ipv4.FlagDst | ipv4.FlagInterface
wb := []byte("HELLO-R-U-THERE")
for i, toggle := range []bool{true, false, true} {
if err := p.SetControlMessage(cf, toggle); err != nil {
if nettest.ProtocolNotSupported(err) {
t.Logf("not supported on %s", runtime.GOOS)
continue
}
t.Fatal(err)
}
if err := p.SetDeadline(time.Now().Add(200 * time.Millisecond)); err != nil {
t.Fatal(err)
}
p.SetMulticastTTL(i + 1)
if n, err := p.WriteTo(wb, nil, &grp); err != nil {
t.Fatal(err)
} else if n != len(wb) {
t.Fatalf("got %v; want %v", n, len(wb))
}
rb := make([]byte, 128)
if n, _, _, err := p.ReadFrom(rb); err != nil {
t.Fatal(err)
} else if !bytes.Equal(rb[:n], wb) {
t.Fatalf("got %v; want %v", rb[:n], wb)
}
}
}
}
var packetConnReadWriteMulticastICMPTests = []struct {
grp, src *net.IPAddr
}{
{&net.IPAddr{IP: net.IPv4(224, 0, 0, 254)}, nil}, // see RFC 4727
{&net.IPAddr{IP: net.IPv4(232, 0, 1, 254)}, &net.IPAddr{IP: net.IPv4(127, 0, 0, 1)}}, // see RFC 5771
}
func TestPacketConnReadWriteMulticastICMP(t *testing.T) {
switch runtime.GOOS {
case "nacl", "plan9", "solaris", "windows":
t.Skipf("not supported on %s", runtime.GOOS)
}
if m, ok := nettest.SupportsRawIPSocket(); !ok {
t.Skip(m)
}
ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagMulticast|net.FlagLoopback)
if ifi == nil {
t.Skipf("not available on %s", runtime.GOOS)
}
for _, tt := range packetConnReadWriteMulticastICMPTests {
c, err := net.ListenPacket("ip4:icmp", "0.0.0.0")
if err != nil {
t.Fatal(err)
}
defer c.Close()
p := ipv4.NewPacketConn(c)
defer p.Close()
if tt.src == nil {
if err := p.JoinGroup(ifi, tt.grp); err != nil {
t.Fatal(err)
}
defer p.LeaveGroup(ifi, tt.grp)
} else {
if err := p.JoinSourceSpecificGroup(ifi, tt.grp, tt.src); err != nil {
switch runtime.GOOS {
case "freebsd", "linux":
default: // platforms that don't support IGMPv2/3 fail here
t.Logf("not supported on %s", runtime.GOOS)
continue
}
t.Fatal(err)
}
defer p.LeaveSourceSpecificGroup(ifi, tt.grp, tt.src)
}
if err := p.SetMulticastInterface(ifi); err != nil {
t.Fatal(err)
}
if _, err := p.MulticastInterface(); err != nil {
t.Fatal(err)
}
if err := p.SetMulticastLoopback(true); err != nil {
t.Fatal(err)
}
if _, err := p.MulticastLoopback(); err != nil {
t.Fatal(err)
}
cf := ipv4.FlagTTL | ipv4.FlagDst | ipv4.FlagInterface
for i, toggle := range []bool{true, false, true} {
wb, err := (&icmp.Message{
Type: ipv4.ICMPTypeEcho, Code: 0,
Body: &icmp.Echo{
ID: os.Getpid() & 0xffff, Seq: i + 1,
Data: []byte("HELLO-R-U-THERE"),
},
}).Marshal(nil)
if err != nil {
t.Fatal(err)
}
if err := p.SetControlMessage(cf, toggle); err != nil {
if nettest.ProtocolNotSupported(err) {
t.Logf("not supported on %s", runtime.GOOS)
continue
}
t.Fatal(err)
}
if err := p.SetDeadline(time.Now().Add(200 * time.Millisecond)); err != nil {
t.Fatal(err)
}
p.SetMulticastTTL(i + 1)
if n, err := p.WriteTo(wb, nil, tt.grp); err != nil {
t.Fatal(err)
} else if n != len(wb) {
t.Fatalf("got %v; want %v", n, len(wb))
}
rb := make([]byte, 128)
if n, _, _, err := p.ReadFrom(rb); err != nil {
t.Fatal(err)
} else {
m, err := icmp.ParseMessage(iana.ProtocolICMP, rb[:n])
if err != nil {
t.Fatal(err)
}
switch {
case m.Type == ipv4.ICMPTypeEchoReply && m.Code == 0: // net.inet.icmp.bmcastecho=1
case m.Type == ipv4.ICMPTypeEcho && m.Code == 0: // net.inet.icmp.bmcastecho=0
default:
t.Fatalf("got type=%v, code=%v; want type=%v, code=%v", m.Type, m.Code, ipv4.ICMPTypeEchoReply, 0)
}
}
}
}
}
var rawConnReadWriteMulticastICMPTests = []struct {
grp, src *net.IPAddr
}{
{&net.IPAddr{IP: net.IPv4(224, 0, 0, 254)}, nil}, // see RFC 4727
{&net.IPAddr{IP: net.IPv4(232, 0, 1, 254)}, &net.IPAddr{IP: net.IPv4(127, 0, 0, 1)}}, // see RFC 5771
}
func TestRawConnReadWriteMulticastICMP(t *testing.T) {
if testing.Short() {
t.Skip("to avoid external network")
}
if m, ok := nettest.SupportsRawIPSocket(); !ok {
t.Skip(m)
}
ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagMulticast|net.FlagLoopback)
if ifi == nil {
t.Skipf("not available on %s", runtime.GOOS)
}
for _, tt := range rawConnReadWriteMulticastICMPTests {
c, err := net.ListenPacket("ip4:icmp", "0.0.0.0")
if err != nil {
t.Fatal(err)
}
defer c.Close()
r, err := ipv4.NewRawConn(c)
if err != nil {
t.Fatal(err)
}
defer r.Close()
if tt.src == nil {
if err := r.JoinGroup(ifi, tt.grp); err != nil {
t.Fatal(err)
}
defer r.LeaveGroup(ifi, tt.grp)
} else {
if err := r.JoinSourceSpecificGroup(ifi, tt.grp, tt.src); err != nil {
switch runtime.GOOS {
case "freebsd", "linux":
default: // platforms that don't support IGMPv2/3 fail here
t.Logf("not supported on %s", runtime.GOOS)
continue
}
t.Fatal(err)
}
defer r.LeaveSourceSpecificGroup(ifi, tt.grp, tt.src)
}
if err := r.SetMulticastInterface(ifi); err != nil {
t.Fatal(err)
}
if _, err := r.MulticastInterface(); err != nil {
t.Fatal(err)
}
if err := r.SetMulticastLoopback(true); err != nil {
t.Fatal(err)
}
if _, err := r.MulticastLoopback(); err != nil {
t.Fatal(err)
}
cf := ipv4.FlagTTL | ipv4.FlagDst | ipv4.FlagInterface
for i, toggle := range []bool{true, false, true} {
wb, err := (&icmp.Message{
Type: ipv4.ICMPTypeEcho, Code: 0,
Body: &icmp.Echo{
ID: os.Getpid() & 0xffff, Seq: i + 1,
Data: []byte("HELLO-R-U-THERE"),
},
}).Marshal(nil)
if err != nil {
t.Fatal(err)
}
wh := &ipv4.Header{
Version: ipv4.Version,
Len: ipv4.HeaderLen,
TOS: i + 1,
TotalLen: ipv4.HeaderLen + len(wb),
Protocol: 1,
Dst: tt.grp.IP,
}
if err := r.SetControlMessage(cf, toggle); err != nil {
if nettest.ProtocolNotSupported(err) {
t.Logf("not supported on %s", runtime.GOOS)
continue
}
t.Fatal(err)
}
if err := r.SetDeadline(time.Now().Add(200 * time.Millisecond)); err != nil {
t.Fatal(err)
}
r.SetMulticastTTL(i + 1)
if err := r.WriteTo(wh, wb, nil); err != nil {
t.Fatal(err)
}
rb := make([]byte, ipv4.HeaderLen+128)
if rh, b, _, err := r.ReadFrom(rb); err != nil {
t.Fatal(err)
} else {
m, err := icmp.ParseMessage(iana.ProtocolICMP, b)
if err != nil {
t.Fatal(err)
}
switch {
case (rh.Dst.IsLoopback() || rh.Dst.IsLinkLocalUnicast() || rh.Dst.IsGlobalUnicast()) && m.Type == ipv4.ICMPTypeEchoReply && m.Code == 0: // net.inet.icmp.bmcastecho=1
case rh.Dst.IsMulticast() && m.Type == ipv4.ICMPTypeEcho && m.Code == 0: // net.inet.icmp.bmcastecho=0
default:
t.Fatalf("got type=%v, code=%v; want type=%v, code=%v", m.Type, m.Code, ipv4.ICMPTypeEchoReply, 0)
}
}
}
}
}

View File

@ -1,249 +0,0 @@
// 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.
package ipv4_test
import (
"net"
"runtime"
"testing"
"golang.org/x/net/internal/nettest"
"golang.org/x/net/ipv4"
)
var udpMultipleGroupListenerTests = []net.Addr{
&net.UDPAddr{IP: net.IPv4(224, 0, 0, 249)}, // see RFC 4727
&net.UDPAddr{IP: net.IPv4(224, 0, 0, 250)},
&net.UDPAddr{IP: net.IPv4(224, 0, 0, 254)},
}
func TestUDPSinglePacketConnWithMultipleGroupListeners(t *testing.T) {
switch runtime.GOOS {
case "nacl", "plan9", "solaris", "windows":
t.Skipf("not supported on %s", runtime.GOOS)
}
if testing.Short() {
t.Skip("to avoid external network")
}
for _, gaddr := range udpMultipleGroupListenerTests {
c, err := net.ListenPacket("udp4", "0.0.0.0:0") // wildcard address with no reusable port
if err != nil {
t.Fatal(err)
}
defer c.Close()
p := ipv4.NewPacketConn(c)
var mift []*net.Interface
ift, err := net.Interfaces()
if err != nil {
t.Fatal(err)
}
for i, ifi := range ift {
if _, ok := nettest.IsMulticastCapable("ip4", &ifi); !ok {
continue
}
if err := p.JoinGroup(&ifi, gaddr); err != nil {
t.Fatal(err)
}
mift = append(mift, &ift[i])
}
for _, ifi := range mift {
if err := p.LeaveGroup(ifi, gaddr); err != nil {
t.Fatal(err)
}
}
}
}
func TestUDPMultiplePacketConnWithMultipleGroupListeners(t *testing.T) {
switch runtime.GOOS {
case "nacl", "plan9", "solaris", "windows":
t.Skipf("not supported on %s", runtime.GOOS)
}
if testing.Short() {
t.Skip("to avoid external network")
}
for _, gaddr := range udpMultipleGroupListenerTests {
c1, err := net.ListenPacket("udp4", "224.0.0.0:1024") // wildcard address with reusable port
if err != nil {
t.Fatal(err)
}
defer c1.Close()
c2, err := net.ListenPacket("udp4", "224.0.0.0:1024") // wildcard address with reusable port
if err != nil {
t.Fatal(err)
}
defer c2.Close()
var ps [2]*ipv4.PacketConn
ps[0] = ipv4.NewPacketConn(c1)
ps[1] = ipv4.NewPacketConn(c2)
var mift []*net.Interface
ift, err := net.Interfaces()
if err != nil {
t.Fatal(err)
}
for i, ifi := range ift {
if _, ok := nettest.IsMulticastCapable("ip4", &ifi); !ok {
continue
}
for _, p := range ps {
if err := p.JoinGroup(&ifi, gaddr); err != nil {
t.Fatal(err)
}
}
mift = append(mift, &ift[i])
}
for _, ifi := range mift {
for _, p := range ps {
if err := p.LeaveGroup(ifi, gaddr); err != nil {
t.Fatal(err)
}
}
}
}
}
func TestUDPPerInterfaceSinglePacketConnWithSingleGroupListener(t *testing.T) {
switch runtime.GOOS {
case "nacl", "plan9", "solaris", "windows":
t.Skipf("not supported on %s", runtime.GOOS)
}
if testing.Short() {
t.Skip("to avoid external network")
}
gaddr := net.IPAddr{IP: net.IPv4(224, 0, 0, 254)} // see RFC 4727
type ml struct {
c *ipv4.PacketConn
ifi *net.Interface
}
var mlt []*ml
ift, err := net.Interfaces()
if err != nil {
t.Fatal(err)
}
for i, ifi := range ift {
ip, ok := nettest.IsMulticastCapable("ip4", &ifi)
if !ok {
continue
}
c, err := net.ListenPacket("udp4", ip.String()+":"+"1024") // unicast address with non-reusable port
if err != nil {
t.Fatal(err)
}
defer c.Close()
p := ipv4.NewPacketConn(c)
if err := p.JoinGroup(&ifi, &gaddr); err != nil {
t.Fatal(err)
}
mlt = append(mlt, &ml{p, &ift[i]})
}
for _, m := range mlt {
if err := m.c.LeaveGroup(m.ifi, &gaddr); err != nil {
t.Fatal(err)
}
}
}
func TestIPSingleRawConnWithSingleGroupListener(t *testing.T) {
switch runtime.GOOS {
case "nacl", "plan9", "solaris", "windows":
t.Skipf("not supported on %s", runtime.GOOS)
}
if testing.Short() {
t.Skip("to avoid external network")
}
if m, ok := nettest.SupportsRawIPSocket(); !ok {
t.Skip(m)
}
c, err := net.ListenPacket("ip4:icmp", "0.0.0.0") // wildcard address
if err != nil {
t.Fatal(err)
}
defer c.Close()
r, err := ipv4.NewRawConn(c)
if err != nil {
t.Fatal(err)
}
gaddr := net.IPAddr{IP: net.IPv4(224, 0, 0, 254)} // see RFC 4727
var mift []*net.Interface
ift, err := net.Interfaces()
if err != nil {
t.Fatal(err)
}
for i, ifi := range ift {
if _, ok := nettest.IsMulticastCapable("ip4", &ifi); !ok {
continue
}
if err := r.JoinGroup(&ifi, &gaddr); err != nil {
t.Fatal(err)
}
mift = append(mift, &ift[i])
}
for _, ifi := range mift {
if err := r.LeaveGroup(ifi, &gaddr); err != nil {
t.Fatal(err)
}
}
}
func TestIPPerInterfaceSingleRawConnWithSingleGroupListener(t *testing.T) {
switch runtime.GOOS {
case "nacl", "plan9", "solaris", "windows":
t.Skipf("not supported on %s", runtime.GOOS)
}
if testing.Short() {
t.Skip("to avoid external network")
}
if m, ok := nettest.SupportsRawIPSocket(); !ok {
t.Skip(m)
}
gaddr := net.IPAddr{IP: net.IPv4(224, 0, 0, 254)} // see RFC 4727
type ml struct {
c *ipv4.RawConn
ifi *net.Interface
}
var mlt []*ml
ift, err := net.Interfaces()
if err != nil {
t.Fatal(err)
}
for i, ifi := range ift {
ip, ok := nettest.IsMulticastCapable("ip4", &ifi)
if !ok {
continue
}
c, err := net.ListenPacket("ip4:253", ip.String()) // unicast address
if err != nil {
t.Fatal(err)
}
defer c.Close()
r, err := ipv4.NewRawConn(c)
if err != nil {
t.Fatal(err)
}
if err := r.JoinGroup(&ifi, &gaddr); err != nil {
t.Fatal(err)
}
mlt = append(mlt, &ml{r, &ift[i]})
}
for _, m := range mlt {
if err := m.c.LeaveGroup(m.ifi, &gaddr); err != nil {
t.Fatal(err)
}
}
}

View File

@ -1,195 +0,0 @@
// 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.
package ipv4_test
import (
"net"
"runtime"
"testing"
"golang.org/x/net/internal/nettest"
"golang.org/x/net/ipv4"
)
var packetConnMulticastSocketOptionTests = []struct {
net, proto, addr string
grp, src net.Addr
}{
{"udp4", "", "224.0.0.0:0", &net.UDPAddr{IP: net.IPv4(224, 0, 0, 249)}, nil}, // see RFC 4727
{"ip4", ":icmp", "0.0.0.0", &net.IPAddr{IP: net.IPv4(224, 0, 0, 250)}, nil}, // see RFC 4727
{"udp4", "", "232.0.0.0:0", &net.UDPAddr{IP: net.IPv4(232, 0, 1, 249)}, &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1)}}, // see RFC 5771
{"ip4", ":icmp", "0.0.0.0", &net.IPAddr{IP: net.IPv4(232, 0, 1, 250)}, &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1)}}, // see RFC 5771
}
func TestPacketConnMulticastSocketOptions(t *testing.T) {
switch runtime.GOOS {
case "nacl", "plan9", "solaris":
t.Skipf("not supported on %s", runtime.GOOS)
}
ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagMulticast|net.FlagLoopback)
if ifi == nil {
t.Skipf("not available on %s", runtime.GOOS)
}
m, ok := nettest.SupportsRawIPSocket()
for _, tt := range packetConnMulticastSocketOptionTests {
if tt.net == "ip4" && !ok {
t.Log(m)
continue
}
c, err := net.ListenPacket(tt.net+tt.proto, tt.addr)
if err != nil {
t.Fatal(err)
}
defer c.Close()
p := ipv4.NewPacketConn(c)
defer p.Close()
if tt.src == nil {
testMulticastSocketOptions(t, p, ifi, tt.grp)
} else {
testSourceSpecificMulticastSocketOptions(t, p, ifi, tt.grp, tt.src)
}
}
}
var rawConnMulticastSocketOptionTests = []struct {
grp, src net.Addr
}{
{&net.IPAddr{IP: net.IPv4(224, 0, 0, 250)}, nil}, // see RFC 4727
{&net.IPAddr{IP: net.IPv4(232, 0, 1, 250)}, &net.IPAddr{IP: net.IPv4(127, 0, 0, 1)}}, // see RFC 5771
}
func TestRawConnMulticastSocketOptions(t *testing.T) {
switch runtime.GOOS {
case "nacl", "plan9", "solaris":
t.Skipf("not supported on %s", runtime.GOOS)
}
if m, ok := nettest.SupportsRawIPSocket(); !ok {
t.Skip(m)
}
ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagMulticast|net.FlagLoopback)
if ifi == nil {
t.Skipf("not available on %s", runtime.GOOS)
}
for _, tt := range rawConnMulticastSocketOptionTests {
c, err := net.ListenPacket("ip4:icmp", "0.0.0.0")
if err != nil {
t.Fatal(err)
}
defer c.Close()
r, err := ipv4.NewRawConn(c)
if err != nil {
t.Fatal(err)
}
defer r.Close()
if tt.src == nil {
testMulticastSocketOptions(t, r, ifi, tt.grp)
} else {
testSourceSpecificMulticastSocketOptions(t, r, ifi, tt.grp, tt.src)
}
}
}
type testIPv4MulticastConn interface {
MulticastTTL() (int, error)
SetMulticastTTL(ttl int) error
MulticastLoopback() (bool, error)
SetMulticastLoopback(bool) error
JoinGroup(*net.Interface, net.Addr) error
LeaveGroup(*net.Interface, net.Addr) error
JoinSourceSpecificGroup(*net.Interface, net.Addr, net.Addr) error
LeaveSourceSpecificGroup(*net.Interface, net.Addr, net.Addr) error
ExcludeSourceSpecificGroup(*net.Interface, net.Addr, net.Addr) error
IncludeSourceSpecificGroup(*net.Interface, net.Addr, net.Addr) error
}
func testMulticastSocketOptions(t *testing.T, c testIPv4MulticastConn, ifi *net.Interface, grp net.Addr) {
const ttl = 255
if err := c.SetMulticastTTL(ttl); err != nil {
t.Error(err)
return
}
if v, err := c.MulticastTTL(); err != nil {
t.Error(err)
return
} else if v != ttl {
t.Errorf("got %v; want %v", v, ttl)
return
}
for _, toggle := range []bool{true, false} {
if err := c.SetMulticastLoopback(toggle); err != nil {
t.Error(err)
return
}
if v, err := c.MulticastLoopback(); err != nil {
t.Error(err)
return
} else if v != toggle {
t.Errorf("got %v; want %v", v, toggle)
return
}
}
if err := c.JoinGroup(ifi, grp); err != nil {
t.Error(err)
return
}
if err := c.LeaveGroup(ifi, grp); err != nil {
t.Error(err)
return
}
}
func testSourceSpecificMulticastSocketOptions(t *testing.T, c testIPv4MulticastConn, ifi *net.Interface, grp, src net.Addr) {
// MCAST_JOIN_GROUP -> MCAST_BLOCK_SOURCE -> MCAST_UNBLOCK_SOURCE -> MCAST_LEAVE_GROUP
if err := c.JoinGroup(ifi, grp); err != nil {
t.Error(err)
return
}
if err := c.ExcludeSourceSpecificGroup(ifi, grp, src); err != nil {
switch runtime.GOOS {
case "freebsd", "linux":
default: // platforms that don't support IGMPv2/3 fail here
t.Logf("not supported on %s", runtime.GOOS)
return
}
t.Error(err)
return
}
if err := c.IncludeSourceSpecificGroup(ifi, grp, src); err != nil {
t.Error(err)
return
}
if err := c.LeaveGroup(ifi, grp); err != nil {
t.Error(err)
return
}
// MCAST_JOIN_SOURCE_GROUP -> MCAST_LEAVE_SOURCE_GROUP
if err := c.JoinSourceSpecificGroup(ifi, grp, src); err != nil {
t.Error(err)
return
}
if err := c.LeaveSourceSpecificGroup(ifi, grp, src); err != nil {
t.Error(err)
return
}
// MCAST_JOIN_SOURCE_GROUP -> MCAST_LEAVE_GROUP
if err := c.JoinSourceSpecificGroup(ifi, grp, src); err != nil {
t.Error(err)
return
}
if err := c.LeaveGroup(ifi, grp); err != nil {
t.Error(err)
return
}
}

View File

@ -1,174 +0,0 @@
// 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.
package ipv4_test
import (
"bytes"
"net"
"runtime"
"strings"
"sync"
"testing"
"golang.org/x/net/internal/nettest"
"golang.org/x/net/ipv4"
)
func benchmarkUDPListener() (net.PacketConn, net.Addr, error) {
c, err := net.ListenPacket("udp4", "127.0.0.1:0")
if err != nil {
return nil, nil, err
}
dst, err := net.ResolveUDPAddr("udp4", c.LocalAddr().String())
if err != nil {
c.Close()
return nil, nil, err
}
return c, dst, nil
}
func BenchmarkReadWriteNetUDP(b *testing.B) {
c, dst, err := benchmarkUDPListener()
if err != nil {
b.Fatal(err)
}
defer c.Close()
wb, rb := []byte("HELLO-R-U-THERE"), make([]byte, 128)
b.ResetTimer()
for i := 0; i < b.N; i++ {
benchmarkReadWriteNetUDP(b, c, wb, rb, dst)
}
}
func benchmarkReadWriteNetUDP(b *testing.B, c net.PacketConn, wb, rb []byte, dst net.Addr) {
if _, err := c.WriteTo(wb, dst); err != nil {
b.Fatal(err)
}
if _, _, err := c.ReadFrom(rb); err != nil {
b.Fatal(err)
}
}
func BenchmarkReadWriteIPv4UDP(b *testing.B) {
c, dst, err := benchmarkUDPListener()
if err != nil {
b.Fatal(err)
}
defer c.Close()
p := ipv4.NewPacketConn(c)
defer p.Close()
cf := ipv4.FlagTTL | ipv4.FlagInterface
if err := p.SetControlMessage(cf, true); err != nil {
b.Fatal(err)
}
ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback)
wb, rb := []byte("HELLO-R-U-THERE"), make([]byte, 128)
b.ResetTimer()
for i := 0; i < b.N; i++ {
benchmarkReadWriteIPv4UDP(b, p, wb, rb, dst, ifi)
}
}
func benchmarkReadWriteIPv4UDP(b *testing.B, p *ipv4.PacketConn, wb, rb []byte, dst net.Addr, ifi *net.Interface) {
cm := ipv4.ControlMessage{TTL: 1}
if ifi != nil {
cm.IfIndex = ifi.Index
}
if n, err := p.WriteTo(wb, &cm, dst); err != nil {
b.Fatal(err)
} else if n != len(wb) {
b.Fatalf("got %v; want %v", n, len(wb))
}
if _, _, _, err := p.ReadFrom(rb); err != nil {
b.Fatal(err)
}
}
func TestPacketConnConcurrentReadWriteUnicastUDP(t *testing.T) {
switch runtime.GOOS {
case "nacl", "plan9", "solaris", "windows":
t.Skipf("not supported on %s", runtime.GOOS)
}
c, err := net.ListenPacket("udp4", "127.0.0.1:0")
if err != nil {
t.Fatal(err)
}
defer c.Close()
p := ipv4.NewPacketConn(c)
defer p.Close()
dst, err := net.ResolveUDPAddr("udp4", c.LocalAddr().String())
if err != nil {
t.Fatal(err)
}
ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback)
cf := ipv4.FlagTTL | ipv4.FlagSrc | ipv4.FlagDst | ipv4.FlagInterface
wb := []byte("HELLO-R-U-THERE")
if err := p.SetControlMessage(cf, true); err != nil { // probe before test
if nettest.ProtocolNotSupported(err) {
t.Skipf("not supported on %s", runtime.GOOS)
}
t.Fatal(err)
}
var wg sync.WaitGroup
reader := func() {
defer wg.Done()
rb := make([]byte, 128)
if n, cm, _, err := p.ReadFrom(rb); err != nil {
t.Error(err)
return
} else if !bytes.Equal(rb[:n], wb) {
t.Errorf("got %v; want %v", rb[:n], wb)
return
} else {
s := cm.String()
if strings.Contains(s, ",") {
t.Errorf("should be space-separated values: %s", s)
}
}
}
writer := func(toggle bool) {
defer wg.Done()
cm := ipv4.ControlMessage{
Src: net.IPv4(127, 0, 0, 1),
}
if ifi != nil {
cm.IfIndex = ifi.Index
}
if err := p.SetControlMessage(cf, toggle); err != nil {
t.Error(err)
return
}
if n, err := p.WriteTo(wb, &cm, dst); err != nil {
t.Error(err)
return
} else if n != len(wb) {
t.Errorf("short write: %v", n)
return
}
}
const N = 10
wg.Add(N)
for i := 0; i < N; i++ {
go reader()
}
wg.Add(2 * N)
for i := 0; i < 2*N; i++ {
go writer(i%2 != 0)
}
wg.Add(N)
for i := 0; i < N; i++ {
go reader()
}
wg.Wait()
}

View File

@ -1,246 +0,0 @@
// 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.
package ipv4_test
import (
"bytes"
"net"
"os"
"runtime"
"testing"
"time"
"golang.org/x/net/icmp"
"golang.org/x/net/internal/iana"
"golang.org/x/net/internal/nettest"
"golang.org/x/net/ipv4"
)
func TestPacketConnReadWriteUnicastUDP(t *testing.T) {
switch runtime.GOOS {
case "nacl", "plan9", "solaris", "windows":
t.Skipf("not supported on %s", runtime.GOOS)
}
ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback)
if ifi == nil {
t.Skipf("not available on %s", runtime.GOOS)
}
c, err := net.ListenPacket("udp4", "127.0.0.1:0")
if err != nil {
t.Fatal(err)
}
defer c.Close()
dst, err := net.ResolveUDPAddr("udp4", c.LocalAddr().String())
if err != nil {
t.Fatal(err)
}
p := ipv4.NewPacketConn(c)
defer p.Close()
cf := ipv4.FlagTTL | ipv4.FlagDst | ipv4.FlagInterface
wb := []byte("HELLO-R-U-THERE")
for i, toggle := range []bool{true, false, true} {
if err := p.SetControlMessage(cf, toggle); err != nil {
if nettest.ProtocolNotSupported(err) {
t.Logf("not supported on %s", runtime.GOOS)
continue
}
t.Fatal(err)
}
p.SetTTL(i + 1)
if err := p.SetWriteDeadline(time.Now().Add(100 * time.Millisecond)); err != nil {
t.Fatal(err)
}
if n, err := p.WriteTo(wb, nil, dst); err != nil {
t.Fatal(err)
} else if n != len(wb) {
t.Fatalf("got %v; want %v", n, len(wb))
}
rb := make([]byte, 128)
if err := p.SetReadDeadline(time.Now().Add(100 * time.Millisecond)); err != nil {
t.Fatal(err)
}
if n, _, _, err := p.ReadFrom(rb); err != nil {
t.Fatal(err)
} else if !bytes.Equal(rb[:n], wb) {
t.Fatalf("got %v; want %v", rb[:n], wb)
}
}
}
func TestPacketConnReadWriteUnicastICMP(t *testing.T) {
switch runtime.GOOS {
case "nacl", "plan9", "solaris", "windows":
t.Skipf("not supported on %s", runtime.GOOS)
}
if m, ok := nettest.SupportsRawIPSocket(); !ok {
t.Skip(m)
}
ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback)
if ifi == nil {
t.Skipf("not available on %s", runtime.GOOS)
}
c, err := net.ListenPacket("ip4:icmp", "0.0.0.0")
if err != nil {
t.Fatal(err)
}
defer c.Close()
dst, err := net.ResolveIPAddr("ip4", "127.0.0.1")
if err != nil {
t.Fatal(err)
}
p := ipv4.NewPacketConn(c)
defer p.Close()
cf := ipv4.FlagTTL | ipv4.FlagDst | ipv4.FlagInterface
for i, toggle := range []bool{true, false, true} {
wb, err := (&icmp.Message{
Type: ipv4.ICMPTypeEcho, Code: 0,
Body: &icmp.Echo{
ID: os.Getpid() & 0xffff, Seq: i + 1,
Data: []byte("HELLO-R-U-THERE"),
},
}).Marshal(nil)
if err != nil {
t.Fatal(err)
}
if err := p.SetControlMessage(cf, toggle); err != nil {
if nettest.ProtocolNotSupported(err) {
t.Logf("not supported on %s", runtime.GOOS)
continue
}
t.Fatal(err)
}
p.SetTTL(i + 1)
if err := p.SetWriteDeadline(time.Now().Add(100 * time.Millisecond)); err != nil {
t.Fatal(err)
}
if n, err := p.WriteTo(wb, nil, dst); err != nil {
t.Fatal(err)
} else if n != len(wb) {
t.Fatalf("got %v; want %v", n, len(wb))
}
rb := make([]byte, 128)
loop:
if err := p.SetReadDeadline(time.Now().Add(100 * time.Millisecond)); err != nil {
t.Fatal(err)
}
if n, _, _, err := p.ReadFrom(rb); err != nil {
switch runtime.GOOS {
case "darwin": // older darwin kernels have some limitation on receiving icmp packet through raw socket
t.Logf("not supported on %s", runtime.GOOS)
continue
}
t.Fatal(err)
} else {
m, err := icmp.ParseMessage(iana.ProtocolICMP, rb[:n])
if err != nil {
t.Fatal(err)
}
if runtime.GOOS == "linux" && m.Type == ipv4.ICMPTypeEcho {
// On Linux we must handle own sent packets.
goto loop
}
if m.Type != ipv4.ICMPTypeEchoReply || m.Code != 0 {
t.Fatalf("got type=%v, code=%v; want type=%v, code=%v", m.Type, m.Code, ipv4.ICMPTypeEchoReply, 0)
}
}
}
}
func TestRawConnReadWriteUnicastICMP(t *testing.T) {
switch runtime.GOOS {
case "nacl", "plan9", "solaris", "windows":
t.Skipf("not supported on %s", runtime.GOOS)
}
if m, ok := nettest.SupportsRawIPSocket(); !ok {
t.Skip(m)
}
ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback)
if ifi == nil {
t.Skipf("not available on %s", runtime.GOOS)
}
c, err := net.ListenPacket("ip4:icmp", "0.0.0.0")
if err != nil {
t.Fatal(err)
}
defer c.Close()
dst, err := net.ResolveIPAddr("ip4", "127.0.0.1")
if err != nil {
t.Fatal(err)
}
r, err := ipv4.NewRawConn(c)
if err != nil {
t.Fatal(err)
}
defer r.Close()
cf := ipv4.FlagTTL | ipv4.FlagDst | ipv4.FlagInterface
for i, toggle := range []bool{true, false, true} {
wb, err := (&icmp.Message{
Type: ipv4.ICMPTypeEcho, Code: 0,
Body: &icmp.Echo{
ID: os.Getpid() & 0xffff, Seq: i + 1,
Data: []byte("HELLO-R-U-THERE"),
},
}).Marshal(nil)
if err != nil {
t.Fatal(err)
}
wh := &ipv4.Header{
Version: ipv4.Version,
Len: ipv4.HeaderLen,
TOS: i + 1,
TotalLen: ipv4.HeaderLen + len(wb),
TTL: i + 1,
Protocol: 1,
Dst: dst.IP,
}
if err := r.SetControlMessage(cf, toggle); err != nil {
if nettest.ProtocolNotSupported(err) {
t.Logf("not supported on %s", runtime.GOOS)
continue
}
t.Fatal(err)
}
if err := r.SetWriteDeadline(time.Now().Add(100 * time.Millisecond)); err != nil {
t.Fatal(err)
}
if err := r.WriteTo(wh, wb, nil); err != nil {
t.Fatal(err)
}
rb := make([]byte, ipv4.HeaderLen+128)
loop:
if err := r.SetReadDeadline(time.Now().Add(100 * time.Millisecond)); err != nil {
t.Fatal(err)
}
if _, b, _, err := r.ReadFrom(rb); err != nil {
switch runtime.GOOS {
case "darwin": // older darwin kernels have some limitation on receiving icmp packet through raw socket
t.Logf("not supported on %s", runtime.GOOS)
continue
}
t.Fatal(err)
} else {
m, err := icmp.ParseMessage(iana.ProtocolICMP, b)
if err != nil {
t.Fatal(err)
}
if runtime.GOOS == "linux" && m.Type == ipv4.ICMPTypeEcho {
// On Linux we must handle own sent packets.
goto loop
}
if m.Type != ipv4.ICMPTypeEchoReply || m.Code != 0 {
t.Fatalf("got type=%v, code=%v; want type=%v, code=%v", m.Type, m.Code, ipv4.ICMPTypeEchoReply, 0)
}
}
}
}

View File

@ -1,139 +0,0 @@
// 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.
package ipv4_test
import (
"net"
"runtime"
"testing"
"golang.org/x/net/internal/iana"
"golang.org/x/net/internal/nettest"
"golang.org/x/net/ipv4"
)
func TestConnUnicastSocketOptions(t *testing.T) {
switch runtime.GOOS {
case "nacl", "plan9", "solaris":
t.Skipf("not supported on %s", runtime.GOOS)
}
ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback)
if ifi == nil {
t.Skipf("not available on %s", runtime.GOOS)
}
ln, err := net.Listen("tcp4", "127.0.0.1:0")
if err != nil {
t.Fatal(err)
}
defer ln.Close()
done := make(chan bool)
go acceptor(t, ln, done)
c, err := net.Dial("tcp4", ln.Addr().String())
if err != nil {
t.Fatal(err)
}
defer c.Close()
testUnicastSocketOptions(t, ipv4.NewConn(c))
<-done
}
var packetConnUnicastSocketOptionTests = []struct {
net, proto, addr string
}{
{"udp4", "", "127.0.0.1:0"},
{"ip4", ":icmp", "127.0.0.1"},
}
func TestPacketConnUnicastSocketOptions(t *testing.T) {
switch runtime.GOOS {
case "nacl", "plan9", "solaris":
t.Skipf("not supported on %s", runtime.GOOS)
}
ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback)
if ifi == nil {
t.Skipf("not available on %s", runtime.GOOS)
}
m, ok := nettest.SupportsRawIPSocket()
for _, tt := range packetConnUnicastSocketOptionTests {
if tt.net == "ip4" && !ok {
t.Log(m)
continue
}
c, err := net.ListenPacket(tt.net+tt.proto, tt.addr)
if err != nil {
t.Fatal(err)
}
defer c.Close()
testUnicastSocketOptions(t, ipv4.NewPacketConn(c))
}
}
func TestRawConnUnicastSocketOptions(t *testing.T) {
switch runtime.GOOS {
case "nacl", "plan9", "solaris":
t.Skipf("not supported on %s", runtime.GOOS)
}
if m, ok := nettest.SupportsRawIPSocket(); !ok {
t.Skip(m)
}
ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback)
if ifi == nil {
t.Skipf("not available on %s", runtime.GOOS)
}
c, err := net.ListenPacket("ip4:icmp", "127.0.0.1")
if err != nil {
t.Fatal(err)
}
defer c.Close()
r, err := ipv4.NewRawConn(c)
if err != nil {
t.Fatal(err)
}
testUnicastSocketOptions(t, r)
}
type testIPv4UnicastConn interface {
TOS() (int, error)
SetTOS(int) error
TTL() (int, error)
SetTTL(int) error
}
func testUnicastSocketOptions(t *testing.T, c testIPv4UnicastConn) {
tos := iana.DiffServCS0 | iana.NotECNTransport
switch runtime.GOOS {
case "windows":
// IP_TOS option is supported on Windows 8 and beyond.
t.Skipf("not supported on %s", runtime.GOOS)
}
if err := c.SetTOS(tos); err != nil {
t.Fatal(err)
}
if v, err := c.TOS(); err != nil {
t.Fatal(err)
} else if v != tos {
t.Fatalf("got %v; want %v", v, tos)
}
const ttl = 255
if err := c.SetTTL(ttl); err != nil {
t.Fatal(err)
}
if v, err := c.TTL(); err != nil {
t.Fatal(err)
} else if v != ttl {
t.Fatalf("got %v; want %v", v, ttl)
}
}

View File

@ -1 +1,2 @@
_obj/
unix.test

173
vendor/golang.org/x/sys/unix/README.md generated vendored Normal file
View File

@ -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 <errno.h>`, and the
signal numbers and strings are generated from `#include <signal.h>`. 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).

10
vendor/golang.org/x/sys/unix/asm.s generated vendored
View File

@ -1,10 +0,0 @@
// 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"
TEXT ·use(SB),NOSPLIT,$0
RET

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

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

29
vendor/golang.org/x/sys/unix/asm_openbsd_arm.s generated vendored Normal file
View File

@ -0,0 +1,29 @@
// 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.
// +build !gccgo
#include "textflag.h"
//
// System call support for ARM, OpenBSD
//
// 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)

View File

@ -10,8 +10,8 @@
// System calls for amd64, Solaris are implemented in runtime/syscall_solaris.go
//
TEXT ·sysvicall6(SB),NOSPLIT,$0-64
TEXT ·sysvicall6(SB),NOSPLIT,$0-88
JMP syscall·sysvicall6(SB)
TEXT ·rawSysvicall6(SB),NOSPLIT,$0-64
TEXT ·rawSysvicall6(SB),NOSPLIT,$0-88
JMP syscall·rawSysvicall6(SB)

195
vendor/golang.org/x/sys/unix/cap_freebsd.go generated vendored Normal file
View File

@ -0,0 +1,195 @@
// 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.
// +build freebsd
package unix
import (
errorspkg "errors"
"fmt"
)
// Go implementation of C mostly found in /usr/src/sys/kern/subr_capability.c
const (
// This is the version of CapRights this package understands. See C implementation for parallels.
capRightsGoVersion = CAP_RIGHTS_VERSION_00
capArSizeMin = CAP_RIGHTS_VERSION_00 + 2
capArSizeMax = capRightsGoVersion + 2
)
var (
bit2idx = []int{
-1, 0, 1, -1, 2, -1, -1, -1, 3, -1, -1, -1, -1, -1, -1, -1,
4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
}
)
func capidxbit(right uint64) int {
return int((right >> 57) & 0x1f)
}
func rightToIndex(right uint64) (int, error) {
idx := capidxbit(right)
if idx < 0 || idx >= len(bit2idx) {
return -2, fmt.Errorf("index for right 0x%x out of range", right)
}
return bit2idx[idx], nil
}
func caprver(right uint64) int {
return int(right >> 62)
}
func capver(rights *CapRights) int {
return caprver(rights.Rights[0])
}
func caparsize(rights *CapRights) int {
return capver(rights) + 2
}
// CapRightsSet sets the permissions in setrights in rights.
func CapRightsSet(rights *CapRights, setrights []uint64) error {
// This is essentially a copy of cap_rights_vset()
if capver(rights) != CAP_RIGHTS_VERSION_00 {
return fmt.Errorf("bad rights version %d", capver(rights))
}
n := caparsize(rights)
if n < capArSizeMin || n > capArSizeMax {
return errorspkg.New("bad rights size")
}
for _, right := range setrights {
if caprver(right) != CAP_RIGHTS_VERSION_00 {
return errorspkg.New("bad right version")
}
i, err := rightToIndex(right)
if err != nil {
return err
}
if i >= n {
return errorspkg.New("index overflow")
}
if capidxbit(rights.Rights[i]) != capidxbit(right) {
return errorspkg.New("index mismatch")
}
rights.Rights[i] |= right
if capidxbit(rights.Rights[i]) != capidxbit(right) {
return errorspkg.New("index mismatch (after assign)")
}
}
return nil
}
// CapRightsClear clears the permissions in clearrights from rights.
func CapRightsClear(rights *CapRights, clearrights []uint64) error {
// This is essentially a copy of cap_rights_vclear()
if capver(rights) != CAP_RIGHTS_VERSION_00 {
return fmt.Errorf("bad rights version %d", capver(rights))
}
n := caparsize(rights)
if n < capArSizeMin || n > capArSizeMax {
return errorspkg.New("bad rights size")
}
for _, right := range clearrights {
if caprver(right) != CAP_RIGHTS_VERSION_00 {
return errorspkg.New("bad right version")
}
i, err := rightToIndex(right)
if err != nil {
return err
}
if i >= n {
return errorspkg.New("index overflow")
}
if capidxbit(rights.Rights[i]) != capidxbit(right) {
return errorspkg.New("index mismatch")
}
rights.Rights[i] &= ^(right & 0x01FFFFFFFFFFFFFF)
if capidxbit(rights.Rights[i]) != capidxbit(right) {
return errorspkg.New("index mismatch (after assign)")
}
}
return nil
}
// CapRightsIsSet checks whether all the permissions in setrights are present in rights.
func CapRightsIsSet(rights *CapRights, setrights []uint64) (bool, error) {
// This is essentially a copy of cap_rights_is_vset()
if capver(rights) != CAP_RIGHTS_VERSION_00 {
return false, fmt.Errorf("bad rights version %d", capver(rights))
}
n := caparsize(rights)
if n < capArSizeMin || n > capArSizeMax {
return false, errorspkg.New("bad rights size")
}
for _, right := range setrights {
if caprver(right) != CAP_RIGHTS_VERSION_00 {
return false, errorspkg.New("bad right version")
}
i, err := rightToIndex(right)
if err != nil {
return false, err
}
if i >= n {
return false, errorspkg.New("index overflow")
}
if capidxbit(rights.Rights[i]) != capidxbit(right) {
return false, errorspkg.New("index mismatch")
}
if (rights.Rights[i] & right) != right {
return false, nil
}
}
return true, nil
}
func capright(idx uint64, bit uint64) uint64 {
return ((1 << (57 + idx)) | bit)
}
// CapRightsInit returns a pointer to an initialised CapRights structure filled with rights.
// See man cap_rights_init(3) and rights(4).
func CapRightsInit(rights []uint64) (*CapRights, error) {
var r CapRights
r.Rights[0] = (capRightsGoVersion << 62) | capright(0, 0)
r.Rights[1] = capright(1, 0)
err := CapRightsSet(&r, rights)
if err != nil {
return nil, err
}
return &r, nil
}
// CapRightsLimit reduces the operations permitted on fd to at most those contained in rights.
// The capability rights on fd can never be increased by CapRightsLimit.
// See man cap_rights_limit(2) and rights(4).
func CapRightsLimit(fd uintptr, rights *CapRights) error {
return capRightsLimit(int(fd), rights)
}
// CapRightsGet returns a CapRights structure containing the operations permitted on fd.
// See man cap_rights_get(3) and rights(4).
func CapRightsGet(fd uintptr) (*CapRights, error) {
r, err := CapRightsInit(nil)
if err != nil {
return nil, err
}
err = capRightsGet(capRightsGoVersion, int(fd), r)
if err != nil {
return nil, err
}
return r, nil
}

24
vendor/golang.org/x/sys/unix/dev_darwin.go generated vendored Normal file
View File

@ -0,0 +1,24 @@
// 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.
// Functions to access/create device major and minor numbers matching the
// encoding used in Darwin's sys/types.h header.
package unix
// Major returns the major component of a Darwin device number.
func Major(dev uint64) uint32 {
return uint32((dev >> 24) & 0xff)
}
// Minor returns the minor component of a Darwin device number.
func Minor(dev uint64) uint32 {
return uint32(dev & 0xffffff)
}
// Mkdev returns a Darwin device number generated from the given major and minor
// components.
func Mkdev(major, minor uint32) uint64 {
return (uint64(major) << 24) | uint64(minor)
}

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

@ -0,0 +1,30 @@
// 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.
// Functions to access/create device major and minor numbers matching the
// encoding used in Dragonfly's sys/types.h header.
//
// The information below is extracted and adapted from sys/types.h:
//
// Minor gives a cookie instead of an index since in order to avoid changing the
// meanings of bits 0-15 or wasting time and space shifting bits 16-31 for
// devices that don't use them.
package unix
// Major returns the major component of a DragonFlyBSD device number.
func Major(dev uint64) uint32 {
return uint32((dev >> 8) & 0xff)
}
// Minor returns the minor component of a DragonFlyBSD device number.
func Minor(dev uint64) uint32 {
return uint32(dev & 0xffff00ff)
}
// Mkdev returns a DragonFlyBSD device number generated from the given major and
// minor components.
func Mkdev(major, minor uint32) uint64 {
return (uint64(major) << 8) | uint64(minor)
}

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

@ -0,0 +1,30 @@
// 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.
// Functions to access/create device major and minor numbers matching the
// encoding used in FreeBSD's sys/types.h header.
//
// The information below is extracted and adapted from sys/types.h:
//
// Minor gives a cookie instead of an index since in order to avoid changing the
// meanings of bits 0-15 or wasting time and space shifting bits 16-31 for
// devices that don't use them.
package unix
// Major returns the major component of a FreeBSD device number.
func Major(dev uint64) uint32 {
return uint32((dev >> 8) & 0xff)
}
// Minor returns the minor component of a FreeBSD device number.
func Minor(dev uint64) uint32 {
return uint32(dev & 0xffff00ff)
}
// Mkdev returns a FreeBSD device number generated from the given major and
// minor components.
func Mkdev(major, minor uint32) uint64 {
return (uint64(major) << 8) | uint64(minor)
}

42
vendor/golang.org/x/sys/unix/dev_linux.go generated vendored Normal file
View File

@ -0,0 +1,42 @@
// 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.
// Functions to access/create device major and minor numbers matching the
// encoding used by the Linux kernel and glibc.
//
// The information below is extracted and adapted from bits/sysmacros.h in the
// glibc sources:
//
// dev_t in glibc is 64-bit, with 32-bit major and minor numbers. glibc's
// default encoding is MMMM Mmmm mmmM MMmm, where M is a hex digit of the major
// number and m is a hex digit of the minor number. This is backward compatible
// with legacy systems where dev_t is 16 bits wide, encoded as MMmm. It is also
// backward compatible with the Linux kernel, which for some architectures uses
// 32-bit dev_t, encoded as mmmM MMmm.
package unix
// Major returns the major component of a Linux device number.
func Major(dev uint64) uint32 {
major := uint32((dev & 0x00000000000fff00) >> 8)
major |= uint32((dev & 0xfffff00000000000) >> 32)
return major
}
// Minor returns the minor component of a Linux device number.
func Minor(dev uint64) uint32 {
minor := uint32((dev & 0x00000000000000ff) >> 0)
minor |= uint32((dev & 0x00000ffffff00000) >> 12)
return minor
}
// Mkdev returns a Linux device number generated from the given major and minor
// components.
func Mkdev(major, minor uint32) uint64 {
dev := (uint64(major) & 0x00000fff) << 8
dev |= (uint64(major) & 0xfffff000) << 32
dev |= (uint64(minor) & 0x000000ff) << 0
dev |= (uint64(minor) & 0xffffff00) << 12
return dev
}

29
vendor/golang.org/x/sys/unix/dev_netbsd.go generated vendored Normal file
View File

@ -0,0 +1,29 @@
// 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.
// Functions to access/create device major and minor numbers matching the
// encoding used in NetBSD's sys/types.h header.
package unix
// Major returns the major component of a NetBSD device number.
func Major(dev uint64) uint32 {
return uint32((dev & 0x000fff00) >> 8)
}
// Minor returns the minor component of a NetBSD device number.
func Minor(dev uint64) uint32 {
minor := uint32((dev & 0x000000ff) >> 0)
minor |= uint32((dev & 0xfff00000) >> 12)
return minor
}
// Mkdev returns a NetBSD device number generated from the given major and minor
// components.
func Mkdev(major, minor uint32) uint64 {
dev := (uint64(major) << 8) & 0x000fff00
dev |= (uint64(minor) << 12) & 0xfff00000
dev |= (uint64(minor) << 0) & 0x000000ff
return dev
}

29
vendor/golang.org/x/sys/unix/dev_openbsd.go generated vendored Normal file
View File

@ -0,0 +1,29 @@
// 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.
// Functions to access/create device major and minor numbers matching the
// encoding used in OpenBSD's sys/types.h header.
package unix
// Major returns the major component of an OpenBSD device number.
func Major(dev uint64) uint32 {
return uint32((dev & 0x0000ff00) >> 8)
}
// Minor returns the minor component of an OpenBSD device number.
func Minor(dev uint64) uint32 {
minor := uint32((dev & 0x000000ff) >> 0)
minor |= uint32((dev & 0xffff0000) >> 8)
return minor
}
// Mkdev returns an OpenBSD device number generated from the given major and minor
// components.
func Mkdev(major, minor uint32) uint64 {
dev := (uint64(major) << 8) & 0x0000ff00
dev |= (uint64(minor) << 8) & 0xffff0000
dev |= (uint64(minor) << 0) & 0x000000ff
return dev
}

102
vendor/golang.org/x/sys/unix/dirent.go generated vendored Normal file
View File

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

9
vendor/golang.org/x/sys/unix/endian_big.go generated vendored Normal file
View File

@ -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

9
vendor/golang.org/x/sys/unix/endian_little.go generated vendored Normal file
View File

@ -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

View File

@ -1,4 +1,4 @@
// Copyright 2010 The Go Authors. All rights reserved.
// 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.

View File

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

227
vendor/golang.org/x/sys/unix/errors_freebsd_386.go generated vendored Normal file
View File

@ -0,0 +1,227 @@
// 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.
// Constants that were deprecated or moved to enums in the FreeBSD headers. Keep
// them here for backwards compatibility.
package unix
const (
IFF_SMART = 0x20
IFT_1822 = 0x2
IFT_A12MPPSWITCH = 0x82
IFT_AAL2 = 0xbb
IFT_AAL5 = 0x31
IFT_ADSL = 0x5e
IFT_AFLANE8023 = 0x3b
IFT_AFLANE8025 = 0x3c
IFT_ARAP = 0x58
IFT_ARCNET = 0x23
IFT_ARCNETPLUS = 0x24
IFT_ASYNC = 0x54
IFT_ATM = 0x25
IFT_ATMDXI = 0x69
IFT_ATMFUNI = 0x6a
IFT_ATMIMA = 0x6b
IFT_ATMLOGICAL = 0x50
IFT_ATMRADIO = 0xbd
IFT_ATMSUBINTERFACE = 0x86
IFT_ATMVCIENDPT = 0xc2
IFT_ATMVIRTUAL = 0x95
IFT_BGPPOLICYACCOUNTING = 0xa2
IFT_BSC = 0x53
IFT_CCTEMUL = 0x3d
IFT_CEPT = 0x13
IFT_CES = 0x85
IFT_CHANNEL = 0x46
IFT_CNR = 0x55
IFT_COFFEE = 0x84
IFT_COMPOSITELINK = 0x9b
IFT_DCN = 0x8d
IFT_DIGITALPOWERLINE = 0x8a
IFT_DIGITALWRAPPEROVERHEADCHANNEL = 0xba
IFT_DLSW = 0x4a
IFT_DOCSCABLEDOWNSTREAM = 0x80
IFT_DOCSCABLEMACLAYER = 0x7f
IFT_DOCSCABLEUPSTREAM = 0x81
IFT_DS0 = 0x51
IFT_DS0BUNDLE = 0x52
IFT_DS1FDL = 0xaa
IFT_DS3 = 0x1e
IFT_DTM = 0x8c
IFT_DVBASILN = 0xac
IFT_DVBASIOUT = 0xad
IFT_DVBRCCDOWNSTREAM = 0x93
IFT_DVBRCCMACLAYER = 0x92
IFT_DVBRCCUPSTREAM = 0x94
IFT_ENC = 0xf4
IFT_EON = 0x19
IFT_EPLRS = 0x57
IFT_ESCON = 0x49
IFT_ETHER = 0x6
IFT_FAITH = 0xf2
IFT_FAST = 0x7d
IFT_FASTETHER = 0x3e
IFT_FASTETHERFX = 0x45
IFT_FDDI = 0xf
IFT_FIBRECHANNEL = 0x38
IFT_FRAMERELAYINTERCONNECT = 0x3a
IFT_FRAMERELAYMPI = 0x5c
IFT_FRDLCIENDPT = 0xc1
IFT_FRELAY = 0x20
IFT_FRELAYDCE = 0x2c
IFT_FRF16MFRBUNDLE = 0xa3
IFT_FRFORWARD = 0x9e
IFT_G703AT2MB = 0x43
IFT_G703AT64K = 0x42
IFT_GIF = 0xf0
IFT_GIGABITETHERNET = 0x75
IFT_GR303IDT = 0xb2
IFT_GR303RDT = 0xb1
IFT_H323GATEKEEPER = 0xa4
IFT_H323PROXY = 0xa5
IFT_HDH1822 = 0x3
IFT_HDLC = 0x76
IFT_HDSL2 = 0xa8
IFT_HIPERLAN2 = 0xb7
IFT_HIPPI = 0x2f
IFT_HIPPIINTERFACE = 0x39
IFT_HOSTPAD = 0x5a
IFT_HSSI = 0x2e
IFT_HY = 0xe
IFT_IBM370PARCHAN = 0x48
IFT_IDSL = 0x9a
IFT_IEEE80211 = 0x47
IFT_IEEE80212 = 0x37
IFT_IEEE8023ADLAG = 0xa1
IFT_IFGSN = 0x91
IFT_IMT = 0xbe
IFT_INTERLEAVE = 0x7c
IFT_IP = 0x7e
IFT_IPFORWARD = 0x8e
IFT_IPOVERATM = 0x72
IFT_IPOVERCDLC = 0x6d
IFT_IPOVERCLAW = 0x6e
IFT_IPSWITCH = 0x4e
IFT_IPXIP = 0xf9
IFT_ISDN = 0x3f
IFT_ISDNBASIC = 0x14
IFT_ISDNPRIMARY = 0x15
IFT_ISDNS = 0x4b
IFT_ISDNU = 0x4c
IFT_ISO88022LLC = 0x29
IFT_ISO88023 = 0x7
IFT_ISO88024 = 0x8
IFT_ISO88025 = 0x9
IFT_ISO88025CRFPINT = 0x62
IFT_ISO88025DTR = 0x56
IFT_ISO88025FIBER = 0x73
IFT_ISO88026 = 0xa
IFT_ISUP = 0xb3
IFT_L3IPXVLAN = 0x89
IFT_LAPB = 0x10
IFT_LAPD = 0x4d
IFT_LAPF = 0x77
IFT_LOCALTALK = 0x2a
IFT_LOOP = 0x18
IFT_MEDIAMAILOVERIP = 0x8b
IFT_MFSIGLINK = 0xa7
IFT_MIOX25 = 0x26
IFT_MODEM = 0x30
IFT_MPC = 0x71
IFT_MPLS = 0xa6
IFT_MPLSTUNNEL = 0x96
IFT_MSDSL = 0x8f
IFT_MVL = 0xbf
IFT_MYRINET = 0x63
IFT_NFAS = 0xaf
IFT_NSIP = 0x1b
IFT_OPTICALCHANNEL = 0xc3
IFT_OPTICALTRANSPORT = 0xc4
IFT_OTHER = 0x1
IFT_P10 = 0xc
IFT_P80 = 0xd
IFT_PARA = 0x22
IFT_PFLOG = 0xf6
IFT_PFSYNC = 0xf7
IFT_PLC = 0xae
IFT_POS = 0xab
IFT_PPPMULTILINKBUNDLE = 0x6c
IFT_PROPBWAP2MP = 0xb8
IFT_PROPCNLS = 0x59
IFT_PROPDOCSWIRELESSDOWNSTREAM = 0xb5
IFT_PROPDOCSWIRELESSMACLAYER = 0xb4
IFT_PROPDOCSWIRELESSUPSTREAM = 0xb6
IFT_PROPMUX = 0x36
IFT_PROPWIRELESSP2P = 0x9d
IFT_PTPSERIAL = 0x16
IFT_PVC = 0xf1
IFT_QLLC = 0x44
IFT_RADIOMAC = 0xbc
IFT_RADSL = 0x5f
IFT_REACHDSL = 0xc0
IFT_RFC1483 = 0x9f
IFT_RS232 = 0x21
IFT_RSRB = 0x4f
IFT_SDLC = 0x11
IFT_SDSL = 0x60
IFT_SHDSL = 0xa9
IFT_SIP = 0x1f
IFT_SLIP = 0x1c
IFT_SMDSDXI = 0x2b
IFT_SMDSICIP = 0x34
IFT_SONET = 0x27
IFT_SONETOVERHEADCHANNEL = 0xb9
IFT_SONETPATH = 0x32
IFT_SONETVT = 0x33
IFT_SRP = 0x97
IFT_SS7SIGLINK = 0x9c
IFT_STACKTOSTACK = 0x6f
IFT_STARLAN = 0xb
IFT_STF = 0xd7
IFT_T1 = 0x12
IFT_TDLC = 0x74
IFT_TERMPAD = 0x5b
IFT_TR008 = 0xb0
IFT_TRANSPHDLC = 0x7b
IFT_TUNNEL = 0x83
IFT_ULTRA = 0x1d
IFT_USB = 0xa0
IFT_V11 = 0x40
IFT_V35 = 0x2d
IFT_V36 = 0x41
IFT_V37 = 0x78
IFT_VDSL = 0x61
IFT_VIRTUALIPADDRESS = 0x70
IFT_VOICEEM = 0x64
IFT_VOICEENCAP = 0x67
IFT_VOICEFXO = 0x65
IFT_VOICEFXS = 0x66
IFT_VOICEOVERATM = 0x98
IFT_VOICEOVERFRAMERELAY = 0x99
IFT_VOICEOVERIP = 0x68
IFT_X213 = 0x5d
IFT_X25 = 0x5
IFT_X25DDN = 0x4
IFT_X25HUNTGROUP = 0x7a
IFT_X25MLP = 0x79
IFT_X25PLE = 0x28
IFT_XETHER = 0x1a
IPPROTO_MAXID = 0x34
IPV6_FAITH = 0x1d
IP_FAITH = 0x16
MAP_NORESERVE = 0x40
MAP_RENAME = 0x20
NET_RT_MAXID = 0x6
RTF_PRCLONING = 0x10000
RTM_OLDADD = 0x9
RTM_OLDDEL = 0xa
SIOCADDRT = 0x8030720a
SIOCALIFADDR = 0x8118691b
SIOCDELRT = 0x8030720b
SIOCDLIFADDR = 0x8118691d
SIOCGLIFADDR = 0xc118691c
SIOCGLIFPHYADDR = 0xc118694b
SIOCSLIFPHYADDR = 0x8118694a
)

227
vendor/golang.org/x/sys/unix/errors_freebsd_amd64.go generated vendored Normal file
View File

@ -0,0 +1,227 @@
// 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.
// Constants that were deprecated or moved to enums in the FreeBSD headers. Keep
// them here for backwards compatibility.
package unix
const (
IFF_SMART = 0x20
IFT_1822 = 0x2
IFT_A12MPPSWITCH = 0x82
IFT_AAL2 = 0xbb
IFT_AAL5 = 0x31
IFT_ADSL = 0x5e
IFT_AFLANE8023 = 0x3b
IFT_AFLANE8025 = 0x3c
IFT_ARAP = 0x58
IFT_ARCNET = 0x23
IFT_ARCNETPLUS = 0x24
IFT_ASYNC = 0x54
IFT_ATM = 0x25
IFT_ATMDXI = 0x69
IFT_ATMFUNI = 0x6a
IFT_ATMIMA = 0x6b
IFT_ATMLOGICAL = 0x50
IFT_ATMRADIO = 0xbd
IFT_ATMSUBINTERFACE = 0x86
IFT_ATMVCIENDPT = 0xc2
IFT_ATMVIRTUAL = 0x95
IFT_BGPPOLICYACCOUNTING = 0xa2
IFT_BSC = 0x53
IFT_CCTEMUL = 0x3d
IFT_CEPT = 0x13
IFT_CES = 0x85
IFT_CHANNEL = 0x46
IFT_CNR = 0x55
IFT_COFFEE = 0x84
IFT_COMPOSITELINK = 0x9b
IFT_DCN = 0x8d
IFT_DIGITALPOWERLINE = 0x8a
IFT_DIGITALWRAPPEROVERHEADCHANNEL = 0xba
IFT_DLSW = 0x4a
IFT_DOCSCABLEDOWNSTREAM = 0x80
IFT_DOCSCABLEMACLAYER = 0x7f
IFT_DOCSCABLEUPSTREAM = 0x81
IFT_DS0 = 0x51
IFT_DS0BUNDLE = 0x52
IFT_DS1FDL = 0xaa
IFT_DS3 = 0x1e
IFT_DTM = 0x8c
IFT_DVBASILN = 0xac
IFT_DVBASIOUT = 0xad
IFT_DVBRCCDOWNSTREAM = 0x93
IFT_DVBRCCMACLAYER = 0x92
IFT_DVBRCCUPSTREAM = 0x94
IFT_ENC = 0xf4
IFT_EON = 0x19
IFT_EPLRS = 0x57
IFT_ESCON = 0x49
IFT_ETHER = 0x6
IFT_FAITH = 0xf2
IFT_FAST = 0x7d
IFT_FASTETHER = 0x3e
IFT_FASTETHERFX = 0x45
IFT_FDDI = 0xf
IFT_FIBRECHANNEL = 0x38
IFT_FRAMERELAYINTERCONNECT = 0x3a
IFT_FRAMERELAYMPI = 0x5c
IFT_FRDLCIENDPT = 0xc1
IFT_FRELAY = 0x20
IFT_FRELAYDCE = 0x2c
IFT_FRF16MFRBUNDLE = 0xa3
IFT_FRFORWARD = 0x9e
IFT_G703AT2MB = 0x43
IFT_G703AT64K = 0x42
IFT_GIF = 0xf0
IFT_GIGABITETHERNET = 0x75
IFT_GR303IDT = 0xb2
IFT_GR303RDT = 0xb1
IFT_H323GATEKEEPER = 0xa4
IFT_H323PROXY = 0xa5
IFT_HDH1822 = 0x3
IFT_HDLC = 0x76
IFT_HDSL2 = 0xa8
IFT_HIPERLAN2 = 0xb7
IFT_HIPPI = 0x2f
IFT_HIPPIINTERFACE = 0x39
IFT_HOSTPAD = 0x5a
IFT_HSSI = 0x2e
IFT_HY = 0xe
IFT_IBM370PARCHAN = 0x48
IFT_IDSL = 0x9a
IFT_IEEE80211 = 0x47
IFT_IEEE80212 = 0x37
IFT_IEEE8023ADLAG = 0xa1
IFT_IFGSN = 0x91
IFT_IMT = 0xbe
IFT_INTERLEAVE = 0x7c
IFT_IP = 0x7e
IFT_IPFORWARD = 0x8e
IFT_IPOVERATM = 0x72
IFT_IPOVERCDLC = 0x6d
IFT_IPOVERCLAW = 0x6e
IFT_IPSWITCH = 0x4e
IFT_IPXIP = 0xf9
IFT_ISDN = 0x3f
IFT_ISDNBASIC = 0x14
IFT_ISDNPRIMARY = 0x15
IFT_ISDNS = 0x4b
IFT_ISDNU = 0x4c
IFT_ISO88022LLC = 0x29
IFT_ISO88023 = 0x7
IFT_ISO88024 = 0x8
IFT_ISO88025 = 0x9
IFT_ISO88025CRFPINT = 0x62
IFT_ISO88025DTR = 0x56
IFT_ISO88025FIBER = 0x73
IFT_ISO88026 = 0xa
IFT_ISUP = 0xb3
IFT_L3IPXVLAN = 0x89
IFT_LAPB = 0x10
IFT_LAPD = 0x4d
IFT_LAPF = 0x77
IFT_LOCALTALK = 0x2a
IFT_LOOP = 0x18
IFT_MEDIAMAILOVERIP = 0x8b
IFT_MFSIGLINK = 0xa7
IFT_MIOX25 = 0x26
IFT_MODEM = 0x30
IFT_MPC = 0x71
IFT_MPLS = 0xa6
IFT_MPLSTUNNEL = 0x96
IFT_MSDSL = 0x8f
IFT_MVL = 0xbf
IFT_MYRINET = 0x63
IFT_NFAS = 0xaf
IFT_NSIP = 0x1b
IFT_OPTICALCHANNEL = 0xc3
IFT_OPTICALTRANSPORT = 0xc4
IFT_OTHER = 0x1
IFT_P10 = 0xc
IFT_P80 = 0xd
IFT_PARA = 0x22
IFT_PFLOG = 0xf6
IFT_PFSYNC = 0xf7
IFT_PLC = 0xae
IFT_POS = 0xab
IFT_PPPMULTILINKBUNDLE = 0x6c
IFT_PROPBWAP2MP = 0xb8
IFT_PROPCNLS = 0x59
IFT_PROPDOCSWIRELESSDOWNSTREAM = 0xb5
IFT_PROPDOCSWIRELESSMACLAYER = 0xb4
IFT_PROPDOCSWIRELESSUPSTREAM = 0xb6
IFT_PROPMUX = 0x36
IFT_PROPWIRELESSP2P = 0x9d
IFT_PTPSERIAL = 0x16
IFT_PVC = 0xf1
IFT_QLLC = 0x44
IFT_RADIOMAC = 0xbc
IFT_RADSL = 0x5f
IFT_REACHDSL = 0xc0
IFT_RFC1483 = 0x9f
IFT_RS232 = 0x21
IFT_RSRB = 0x4f
IFT_SDLC = 0x11
IFT_SDSL = 0x60
IFT_SHDSL = 0xa9
IFT_SIP = 0x1f
IFT_SLIP = 0x1c
IFT_SMDSDXI = 0x2b
IFT_SMDSICIP = 0x34
IFT_SONET = 0x27
IFT_SONETOVERHEADCHANNEL = 0xb9
IFT_SONETPATH = 0x32
IFT_SONETVT = 0x33
IFT_SRP = 0x97
IFT_SS7SIGLINK = 0x9c
IFT_STACKTOSTACK = 0x6f
IFT_STARLAN = 0xb
IFT_STF = 0xd7
IFT_T1 = 0x12
IFT_TDLC = 0x74
IFT_TERMPAD = 0x5b
IFT_TR008 = 0xb0
IFT_TRANSPHDLC = 0x7b
IFT_TUNNEL = 0x83
IFT_ULTRA = 0x1d
IFT_USB = 0xa0
IFT_V11 = 0x40
IFT_V35 = 0x2d
IFT_V36 = 0x41
IFT_V37 = 0x78
IFT_VDSL = 0x61
IFT_VIRTUALIPADDRESS = 0x70
IFT_VOICEEM = 0x64
IFT_VOICEENCAP = 0x67
IFT_VOICEFXO = 0x65
IFT_VOICEFXS = 0x66
IFT_VOICEOVERATM = 0x98
IFT_VOICEOVERFRAMERELAY = 0x99
IFT_VOICEOVERIP = 0x68
IFT_X213 = 0x5d
IFT_X25 = 0x5
IFT_X25DDN = 0x4
IFT_X25HUNTGROUP = 0x7a
IFT_X25MLP = 0x79
IFT_X25PLE = 0x28
IFT_XETHER = 0x1a
IPPROTO_MAXID = 0x34
IPV6_FAITH = 0x1d
IP_FAITH = 0x16
MAP_NORESERVE = 0x40
MAP_RENAME = 0x20
NET_RT_MAXID = 0x6
RTF_PRCLONING = 0x10000
RTM_OLDADD = 0x9
RTM_OLDDEL = 0xa
SIOCADDRT = 0x8040720a
SIOCALIFADDR = 0x8118691b
SIOCDELRT = 0x8040720b
SIOCDLIFADDR = 0x8118691d
SIOCGLIFADDR = 0xc118691c
SIOCGLIFPHYADDR = 0xc118694b
SIOCSLIFPHYADDR = 0x8118694a
)

226
vendor/golang.org/x/sys/unix/errors_freebsd_arm.go generated vendored Normal file
View File

@ -0,0 +1,226 @@
// 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.
package unix
const (
IFT_1822 = 0x2
IFT_A12MPPSWITCH = 0x82
IFT_AAL2 = 0xbb
IFT_AAL5 = 0x31
IFT_ADSL = 0x5e
IFT_AFLANE8023 = 0x3b
IFT_AFLANE8025 = 0x3c
IFT_ARAP = 0x58
IFT_ARCNET = 0x23
IFT_ARCNETPLUS = 0x24
IFT_ASYNC = 0x54
IFT_ATM = 0x25
IFT_ATMDXI = 0x69
IFT_ATMFUNI = 0x6a
IFT_ATMIMA = 0x6b
IFT_ATMLOGICAL = 0x50
IFT_ATMRADIO = 0xbd
IFT_ATMSUBINTERFACE = 0x86
IFT_ATMVCIENDPT = 0xc2
IFT_ATMVIRTUAL = 0x95
IFT_BGPPOLICYACCOUNTING = 0xa2
IFT_BSC = 0x53
IFT_CCTEMUL = 0x3d
IFT_CEPT = 0x13
IFT_CES = 0x85
IFT_CHANNEL = 0x46
IFT_CNR = 0x55
IFT_COFFEE = 0x84
IFT_COMPOSITELINK = 0x9b
IFT_DCN = 0x8d
IFT_DIGITALPOWERLINE = 0x8a
IFT_DIGITALWRAPPEROVERHEADCHANNEL = 0xba
IFT_DLSW = 0x4a
IFT_DOCSCABLEDOWNSTREAM = 0x80
IFT_DOCSCABLEMACLAYER = 0x7f
IFT_DOCSCABLEUPSTREAM = 0x81
IFT_DS0 = 0x51
IFT_DS0BUNDLE = 0x52
IFT_DS1FDL = 0xaa
IFT_DS3 = 0x1e
IFT_DTM = 0x8c
IFT_DVBASILN = 0xac
IFT_DVBASIOUT = 0xad
IFT_DVBRCCDOWNSTREAM = 0x93
IFT_DVBRCCMACLAYER = 0x92
IFT_DVBRCCUPSTREAM = 0x94
IFT_ENC = 0xf4
IFT_EON = 0x19
IFT_EPLRS = 0x57
IFT_ESCON = 0x49
IFT_ETHER = 0x6
IFT_FAST = 0x7d
IFT_FASTETHER = 0x3e
IFT_FASTETHERFX = 0x45
IFT_FDDI = 0xf
IFT_FIBRECHANNEL = 0x38
IFT_FRAMERELAYINTERCONNECT = 0x3a
IFT_FRAMERELAYMPI = 0x5c
IFT_FRDLCIENDPT = 0xc1
IFT_FRELAY = 0x20
IFT_FRELAYDCE = 0x2c
IFT_FRF16MFRBUNDLE = 0xa3
IFT_FRFORWARD = 0x9e
IFT_G703AT2MB = 0x43
IFT_G703AT64K = 0x42
IFT_GIF = 0xf0
IFT_GIGABITETHERNET = 0x75
IFT_GR303IDT = 0xb2
IFT_GR303RDT = 0xb1
IFT_H323GATEKEEPER = 0xa4
IFT_H323PROXY = 0xa5
IFT_HDH1822 = 0x3
IFT_HDLC = 0x76
IFT_HDSL2 = 0xa8
IFT_HIPERLAN2 = 0xb7
IFT_HIPPI = 0x2f
IFT_HIPPIINTERFACE = 0x39
IFT_HOSTPAD = 0x5a
IFT_HSSI = 0x2e
IFT_HY = 0xe
IFT_IBM370PARCHAN = 0x48
IFT_IDSL = 0x9a
IFT_IEEE80211 = 0x47
IFT_IEEE80212 = 0x37
IFT_IEEE8023ADLAG = 0xa1
IFT_IFGSN = 0x91
IFT_IMT = 0xbe
IFT_INTERLEAVE = 0x7c
IFT_IP = 0x7e
IFT_IPFORWARD = 0x8e
IFT_IPOVERATM = 0x72
IFT_IPOVERCDLC = 0x6d
IFT_IPOVERCLAW = 0x6e
IFT_IPSWITCH = 0x4e
IFT_ISDN = 0x3f
IFT_ISDNBASIC = 0x14
IFT_ISDNPRIMARY = 0x15
IFT_ISDNS = 0x4b
IFT_ISDNU = 0x4c
IFT_ISO88022LLC = 0x29
IFT_ISO88023 = 0x7
IFT_ISO88024 = 0x8
IFT_ISO88025 = 0x9
IFT_ISO88025CRFPINT = 0x62
IFT_ISO88025DTR = 0x56
IFT_ISO88025FIBER = 0x73
IFT_ISO88026 = 0xa
IFT_ISUP = 0xb3
IFT_L3IPXVLAN = 0x89
IFT_LAPB = 0x10
IFT_LAPD = 0x4d
IFT_LAPF = 0x77
IFT_LOCALTALK = 0x2a
IFT_LOOP = 0x18
IFT_MEDIAMAILOVERIP = 0x8b
IFT_MFSIGLINK = 0xa7
IFT_MIOX25 = 0x26
IFT_MODEM = 0x30
IFT_MPC = 0x71
IFT_MPLS = 0xa6
IFT_MPLSTUNNEL = 0x96
IFT_MSDSL = 0x8f
IFT_MVL = 0xbf
IFT_MYRINET = 0x63
IFT_NFAS = 0xaf
IFT_NSIP = 0x1b
IFT_OPTICALCHANNEL = 0xc3
IFT_OPTICALTRANSPORT = 0xc4
IFT_OTHER = 0x1
IFT_P10 = 0xc
IFT_P80 = 0xd
IFT_PARA = 0x22
IFT_PFLOG = 0xf6
IFT_PFSYNC = 0xf7
IFT_PLC = 0xae
IFT_POS = 0xab
IFT_PPPMULTILINKBUNDLE = 0x6c
IFT_PROPBWAP2MP = 0xb8
IFT_PROPCNLS = 0x59
IFT_PROPDOCSWIRELESSDOWNSTREAM = 0xb5
IFT_PROPDOCSWIRELESSMACLAYER = 0xb4
IFT_PROPDOCSWIRELESSUPSTREAM = 0xb6
IFT_PROPMUX = 0x36
IFT_PROPWIRELESSP2P = 0x9d
IFT_PTPSERIAL = 0x16
IFT_PVC = 0xf1
IFT_QLLC = 0x44
IFT_RADIOMAC = 0xbc
IFT_RADSL = 0x5f
IFT_REACHDSL = 0xc0
IFT_RFC1483 = 0x9f
IFT_RS232 = 0x21
IFT_RSRB = 0x4f
IFT_SDLC = 0x11
IFT_SDSL = 0x60
IFT_SHDSL = 0xa9
IFT_SIP = 0x1f
IFT_SLIP = 0x1c
IFT_SMDSDXI = 0x2b
IFT_SMDSICIP = 0x34
IFT_SONET = 0x27
IFT_SONETOVERHEADCHANNEL = 0xb9
IFT_SONETPATH = 0x32
IFT_SONETVT = 0x33
IFT_SRP = 0x97
IFT_SS7SIGLINK = 0x9c
IFT_STACKTOSTACK = 0x6f
IFT_STARLAN = 0xb
IFT_STF = 0xd7
IFT_T1 = 0x12
IFT_TDLC = 0x74
IFT_TERMPAD = 0x5b
IFT_TR008 = 0xb0
IFT_TRANSPHDLC = 0x7b
IFT_TUNNEL = 0x83
IFT_ULTRA = 0x1d
IFT_USB = 0xa0
IFT_V11 = 0x40
IFT_V35 = 0x2d
IFT_V36 = 0x41
IFT_V37 = 0x78
IFT_VDSL = 0x61
IFT_VIRTUALIPADDRESS = 0x70
IFT_VOICEEM = 0x64
IFT_VOICEENCAP = 0x67
IFT_VOICEFXO = 0x65
IFT_VOICEFXS = 0x66
IFT_VOICEOVERATM = 0x98
IFT_VOICEOVERFRAMERELAY = 0x99
IFT_VOICEOVERIP = 0x68
IFT_X213 = 0x5d
IFT_X25 = 0x5
IFT_X25DDN = 0x4
IFT_X25HUNTGROUP = 0x7a
IFT_X25MLP = 0x79
IFT_X25PLE = 0x28
IFT_XETHER = 0x1a
// missing constants on FreeBSD-11.1-RELEASE, copied from old values in ztypes_freebsd_arm.go
IFF_SMART = 0x20
IFT_FAITH = 0xf2
IFT_IPXIP = 0xf9
IPPROTO_MAXID = 0x34
IPV6_FAITH = 0x1d
IP_FAITH = 0x16
MAP_NORESERVE = 0x40
MAP_RENAME = 0x20
NET_RT_MAXID = 0x6
RTF_PRCLONING = 0x10000
RTM_OLDADD = 0x9
RTM_OLDDEL = 0xa
SIOCADDRT = 0x8030720a
SIOCALIFADDR = 0x8118691b
SIOCDELRT = 0x8030720b
SIOCDLIFADDR = 0x8118691d
SIOCGLIFADDR = 0xc118691c
SIOCGLIFPHYADDR = 0xc118694b
SIOCSLIFPHYADDR = 0x8118694a
)

View File

@ -1,5 +1,3 @@
// +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.

View File

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

View File

@ -1,4 +1,4 @@
// Copyright 2015 The Go Authors. All rights reserved.
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
@ -8,7 +8,7 @@ package unix
import "syscall"
// We can't use the gc-syntax .s files for gccgo. On the plus side
// 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

View File

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

View File

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

175
vendor/golang.org/x/sys/unix/mkall.sh generated vendored
View File

@ -3,75 +3,9 @@
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.
# The unix 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.
# 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}"
@ -84,11 +18,14 @@ 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
@ -96,6 +33,7 @@ case "$1" in
;;
-n)
run="cat"
cmd="echo"
shift
esac
@ -107,6 +45,14 @@ case "$#" in
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
_* | *_ | _)
@ -126,7 +72,7 @@ darwin_amd64)
;;
darwin_arm)
mkerrors="$mkerrors"
mksysnum="./mksysnum_darwin.pl /usr/include/sys/syscall.h"
mksysnum="./mksysnum_darwin.pl $(xcrun --show-sdk-path --sdk iphoneos)/usr/include/sys/syscall.h"
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
;;
darwin_arm64)
@ -134,12 +80,6 @@ darwin_arm64)
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"
@ -162,67 +102,16 @@ freebsd_arm)
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.
# API consistent across platforms.
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
;;
linux_386)
mkerrors="$mkerrors -m32"
mksyscall="./mksyscall.pl -l32"
mksysnum="./mksysnum_linux.pl /usr/include/asm/unistd_32.h"
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
;;
linux_amd64)
unistd_h=$(ls -1 /usr/include/asm/unistd_64.h /usr/include/x86_64-linux-gnu/asm/unistd_64.h 2>/dev/null | head -1)
if [ "$unistd_h" = "" ]; then
echo >&2 cannot find unistd_64.h
exit 1
fi
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"
;;
linux_arm)
mkerrors="$mkerrors"
mksyscall="./mksyscall.pl -l32 -arm"
mksysnum="curl -s 'http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/plain/arch/arm/include/uapi/asm/unistd.h' | ./mksysnum_linux.pl -"
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
;;
linux_arm64)
unistd_h=$(ls -1 /usr/include/asm/unistd.h /usr/include/asm-generic/unistd.h 2>/dev/null | head -1)
if [ "$unistd_h" = "" ]; then
echo >&2 cannot find unistd_64.h
exit 1
fi
mksysnum="./mksysnum_linux.pl $unistd_h"
# 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_ppc64)
GOOSARCH_in=syscall_linux_ppc64x.go
unistd_h=/usr/include/asm/unistd.h
mkerrors="$mkerrors -m64"
mksysnum="./mksysnum_linux.pl $unistd_h"
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
;;
linux_ppc64le)
GOOSARCH_in=syscall_linux_ppc64x.go
unistd_h=/usr/include/powerpc64le-linux-gnu/asm/unistd.h
mkerrors="$mkerrors -m64"
mksysnum="./mksysnum_linux.pl $unistd_h"
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
;;
linux_s390x)
GOOSARCH_in=syscall_linux_s390x.go
unistd_h=/usr/include/asm/unistd.h
mkerrors="$mkerrors -m64"
mksysnum="./mksysnum_linux.pl $unistd_h"
# Let the type of C char be signed to make the bare sys
# API more consistent between platforms.
# This is a deliberate departure from the way the syscall
# package generates its version of the types file.
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
;;
netbsd_386)
mkerrors="$mkerrors -m32"
mksyscall="./mksyscall.pl -l32 -netbsd"
@ -235,11 +124,18 @@ netbsd_amd64)
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_arm)
mkerrors="$mkerrors"
mksyscall="./mksyscall.pl -l32 -netbsd -arm"
mksysnum="curl -s 'http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_netbsd.pl"
# Let the type of C char be signed for making the bare syscall
# API consistent across platforms.
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
;;
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"
;;
@ -247,10 +143,18 @@ 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"
;;
openbsd_arm)
mkerrors="$mkerrors"
mksyscall="./mksyscall.pl -l32 -openbsd -arm"
mksysctl="./mksysctl_openbsd.pl"
mksysnum="curl -s 'http://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_openbsd.pl"
# Let the type of C char be signed for making the bare syscall
# API consistent across platforms.
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
;;
solaris_amd64)
mksyscall="./mksyscall_solaris.pl"
mkerrors="$mkerrors -m64"
@ -273,13 +177,12 @@ esac
syscall_goos="syscall_bsd.go $syscall_goos"
;;
esac
if [ -n "$mksyscall" ]; then echo "$mksyscall $syscall_goos $GOOSARCH_in |gofmt >zsyscall_$GOOSARCH.go"; fi
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 "echo // +build $GOARCH,$GOOS > ztypes_$GOOSARCH.go";
echo "$mktypes types_$GOOS.go | go run mkpost.go >>ztypes_$GOOSARCH.go";
echo "$mktypes types_$GOOS.go | go run mkpost.go > ztypes_$GOOSARCH.go";
fi
) | $run

View File

@ -16,9 +16,18 @@ if test -z "$GOARCH" -o -z "$GOOS"; then
exit 1
fi
# Check that we are using the new build system if we should
if [[ "$GOOS" = "linux" ]] && [[ "$GOARCH" != "sparc64" ]]; then
if [[ "$GOLANG_SYS_BUILD" != "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
if [[ "$GOOS" = "solaris" ]]; then
# Assumes GNU versions of utilities in PATH.
export PATH=/usr/gnu/bin:$PATH
fi
@ -29,6 +38,8 @@ includes_Darwin='
#define _DARWIN_C_SOURCE
#define KERNEL
#define _DARWIN_USE_64_BIT_INODE
#include <stdint.h>
#include <sys/attr.h>
#include <sys/types.h>
#include <sys/event.h>
#include <sys/ptrace.h>
@ -36,6 +47,8 @@ includes_Darwin='
#include <sys/sockio.h>
#include <sys/sysctl.h>
#include <sys/mman.h>
#include <sys/mount.h>
#include <sys/utsname.h>
#include <sys/wait.h>
#include <net/bpf.h>
#include <net/if.h>
@ -66,6 +79,7 @@ includes_DragonFly='
'
includes_FreeBSD='
#include <sys/capability.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/event.h>
@ -73,6 +87,7 @@ includes_FreeBSD='
#include <sys/sockio.h>
#include <sys/sysctl.h>
#include <sys/mman.h>
#include <sys/mount.h>
#include <sys/wait.h>
#include <sys/ioctl.h>
#include <net/bpf.h>
@ -102,8 +117,39 @@ includes_Linux='
#endif
#define _GNU_SOURCE
// <sys/ioctl.h> is broken on powerpc64, as it fails to include definitions of
// these structures. We just include them copied from <bits/termios.h>.
#if defined(__powerpc__)
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 <bits/sockaddr.h>
#include <sys/epoll.h>
#include <sys/eventfd.h>
#include <sys/inotify.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
@ -113,20 +159,35 @@ includes_Linux='
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <sys/xattr.h>
#include <linux/if.h>
#include <linux/if_alg.h>
#include <linux/if_arp.h>
#include <linux/if_ether.h>
#include <linux/if_tun.h>
#include <linux/if_packet.h>
#include <linux/if_addr.h>
#include <linux/falloc.h>
#include <linux/filter.h>
#include <linux/fs.h>
#include <linux/keyctl.h>
#include <linux/netlink.h>
#include <linux/perf_event.h>
#include <linux/random.h>
#include <linux/reboot.h>
#include <linux/rtnetlink.h>
#include <linux/ptrace.h>
#include <linux/sched.h>
#include <linux/seccomp.h>
#include <linux/sockios.h>
#include <linux/wait.h>
#include <linux/icmpv6.h>
#include <linux/serial.h>
#include <linux/can.h>
#include <linux/vm_sockets.h>
#include <linux/taskstats.h>
#include <linux/genetlink.h>
#include <linux/watchdog.h>
#include <net/route.h>
#include <asm/termbits.h>
@ -141,6 +202,21 @@ includes_Linux='
#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='
@ -212,6 +288,7 @@ includes_SunOS='
#include <sys/mman.h>
#include <sys/wait.h>
#include <sys/ioctl.h>
#include <sys/mkdev.h>
#include <net/bpf.h>
#include <net/if.h>
#include <net/if_arp.h>
@ -276,6 +353,7 @@ ccflags="$@"
$2 !~ /^EXPR_/ &&
$2 ~ /^E[A-Z0-9_]+$/ ||
$2 ~ /^B[0-9_]+$/ ||
$2 ~ /^(OLD|NEW)DEV$/ ||
$2 == "BOTHER" ||
$2 ~ /^CI?BAUD(EX)?$/ ||
$2 == "IBSHIFT" ||
@ -304,15 +382,18 @@ ccflags="$@"
$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 ~ /^CTL_(HW|KERN|MAXNAME|NET|QUERY)$/ ||
$2 ~ /^KERN_(HOSTNAME|OS(RELEASE|TYPE)|VERSION)$/ ||
$2 ~ /^HW_MACHINE$/ ||
$2 ~ /^SYSCTL_VERS/ ||
$2 ~ /^(MS|MNT)_/ ||
$2 ~ /^(MS|MNT|UMOUNT)_/ ||
$2 ~ /^TUN(SET|GET|ATTACH|DETACH)/ ||
$2 ~ /^(O|F|FD|NAME|S|PTRACE|PT)_/ ||
$2 ~ /^(O|F|E?FD|NAME|S|PTRACE|PT)_/ ||
$2 ~ /^LINUX_REBOOT_CMD_/ ||
$2 ~ /^LINUX_REBOOT_MAGIC[12]$/ ||
$2 !~ "NLA_TYPE_MASK" &&
@ -326,14 +407,34 @@ ccflags="$@"
$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 ~ /^RLIMIT_(AS|CORE|CPU|DATA|FSIZE|LOCKS|MEMLOCK|MSGQUEUE|NICE|NOFILE|NPROC|RSS|RTPRIO|RTTIME|SIGPENDING|STACK)|RLIM_INFINITY/ ||
$2 ~ /^PRIO_(PROCESS|PGRP|USER)/ ||
$2 ~ /^CLONE_[A-Z_]+/ ||
$2 !~ /^(BPF_TIMEVAL)$/ &&
$2 ~ /^(BPF|DLT)_/ ||
$2 ~ /^CLOCK_/ ||
$2 ~ /^CAN_/ ||
$2 ~ /^CAP_/ ||
$2 ~ /^ALG_/ ||
$2 ~ /^FS_(POLICY_FLAGS|KEY_DESC|ENCRYPTION_MODE|[A-Z0-9_]+_KEY_SIZE|IOC_(GET|SET)_ENCRYPTION)/ ||
$2 ~ /^GRND_/ ||
$2 ~ /^KEY_(SPEC|REQKEY_DEFL)_/ ||
$2 ~ /^KEYCTL_/ ||
$2 ~ /^PERF_EVENT_IOC_/ ||
$2 ~ /^SECCOMP_MODE_/ ||
$2 ~ /^SPLICE_/ ||
$2 ~ /^(VM|VMADDR)_/ ||
$2 ~ /^IOCTL_VM_SOCKETS_/ ||
$2 ~ /^(TASKSTATS|TS)_/ ||
$2 ~ /^GENL_/ ||
$2 ~ /^UTIME_/ ||
$2 ~ /^XATTR_(CREATE|REPLACE)/ ||
$2 ~ /^ATTR_(BIT_MAP_COUNT|(CMN|VOL|FILE)_)/ ||
$2 ~ /^FSOPT_/ ||
$2 ~ /^WDIOC_/ ||
$2 !~ "WMESGLEN" &&
$2 ~ /^W[A-Z0-9]+$/ {printf("\t%s = C.%s\n", $2, $2)}
$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)}
@ -368,7 +469,7 @@ echo '#include <signal.h>' | $CC -x c - -E -dM $ccflags |
sort >_signal.grep
echo '// mkerrors.sh' "$@"
echo '// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT'
echo '// Code generated by the command above; see README.md. DO NOT EDIT.'
echo
echo "// +build ${GOARCH},${GOOS}"
echo
@ -430,7 +531,7 @@ intcmp(const void *a, const void *b)
int
main(void)
{
int i, j, e;
int i, e;
char buf[1024], *p;
printf("\n\n// Error table\n");
@ -447,7 +548,7 @@ main(void)
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);

View File

@ -8,10 +8,11 @@
// modify the generated types. It is used to clean up
// the sys API in an architecture specific manner.
//
// mkpost is run after cgo -godefs by mkall.sh.
// mkpost is run after cgo -godefs; see README.md.
package main
import (
"bytes"
"fmt"
"go/format"
"io/ioutil"
@ -21,42 +22,72 @@ import (
)
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)
}
s := string(b)
goarch := os.Getenv("GOARCH")
goos := os.Getenv("GOOS")
// 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("_"))
// Convert [65]int8 to [65]byte in Utsname members to simplify
// conversion to string; see golang.org/issue/20753
convertUtsnameRegex := regexp.MustCompile(`((Sys|Node|Domain)name|Release|Version|Machine)(\s+)\[(\d+)\]u?int8`)
b = convertUtsnameRegex.ReplaceAll(b, []byte("$1$3[$4]byte"))
// We refuse to export private fields on s390x
if goarch == "s390x" && goos == "linux" {
// Export the types of PtraceRegs fields.
re := regexp.MustCompile("ptrace(Psw|Fpregs|Per)")
s = re.ReplaceAllString(s, "Ptrace$1")
// Remove cgo padding fields
removeFieldsRegex := regexp.MustCompile(`Pad_cgo_\d+`)
b = removeFieldsRegex.ReplaceAll(b, []byte("_"))
// Replace padding fields inserted by cgo with blank identifiers.
re = regexp.MustCompile("Pad_cgo[A-Za-z0-9_]*")
s = re.ReplaceAllString(s, "_")
// Replace other unwanted fields with blank identifiers.
re = regexp.MustCompile("X_[A-Za-z0-9_]*")
s = re.ReplaceAllString(s, "_")
// Replace the control_regs union with a blank identifier for now.
re = regexp.MustCompile("(Control_regs)\\s+\\[0\\]uint64")
s = re.ReplaceAllString(s, "_ [0]uint64")
// 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([]byte(s))
b, err = format.Source(b)
if err != nil {
log.Fatal(err)
}
// Append this command to the header to show where the new file
// came from.
re := regexp.MustCompile("(cgo -godefs [a-zA-Z0-9_]+\\.go.*)")
b = re.ReplaceAll(b, []byte("$1 | go run mkpost.go"))
fmt.Printf("%s", b)
os.Stdout.Write(b)
}

View File

@ -29,6 +29,7 @@ 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";
@ -57,17 +58,27 @@ 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] [file ...]\n";
print STDERR "usage: mksyscall.pl [-b32 | -l32] [-tags x,y] [file ...]\n";
exit 1;
}
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{'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*//;
@ -132,7 +143,6 @@ while(<>) {
# Prepare arguments to Syscall.
my @args = ();
my @uses = ();
my $n = 0;
foreach my $p (@in) {
my ($name, $type) = parseparam($p);
@ -143,14 +153,12 @@ while(<>) {
$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.
@ -185,7 +193,7 @@ while(<>) {
}
} elsif($type eq "int64" && $_32bit ne "") {
if(@args % 2 && $arm) {
# arm abi specifies 64-bit argument uses
# arm abi specifies 64-bit argument uses
# (even, odd) pair
push @args, "0"
}
@ -278,11 +286,8 @@ while(<>) {
} 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";
@ -305,9 +310,9 @@ if($errors) {
print <<EOF;
// $cmdline
// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
// Code generated by the command above; see README.md. DO NOT EDIT.
// +build $ENV{'GOARCH'},$ENV{'GOOS'}
// +build $tags
package unix

View File

@ -12,7 +12,7 @@
# * 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 err.
# * If go func name needs to be different than its libc name,
# * If go func name needs to be different than its libc name,
# * or the function is not in libc, name could be specified
# * at the end, after "=" sign, like
# //sys getsockopt(s int, level int, name int, val uintptr, vallen *_Socklen) (err error) = libsocket.getsockopt
@ -22,6 +22,7 @@ use strict;
my $cmdline = "mksyscall_solaris.pl " . join(' ', @ARGV);
my $errors = 0;
my $_32bit = "";
my $tags = ""; # build tags
binmode STDOUT;
@ -32,14 +33,14 @@ if($ARGV[0] eq "-b32") {
$_32bit = "little-endian";
shift;
}
if($ARGV[0] =~ /^-/) {
print STDERR "usage: mksyscall_solaris.pl [-b32 | -l32] [file ...]\n";
exit 1;
if($ARGV[0] eq "-tags") {
shift;
$tags = $ARGV[0];
shift;
}
if($ENV{'GOARCH'} eq "" || $ENV{'GOOS'} eq "") {
print STDERR "GOARCH or GOOS not defined in environment\n";
if($ARGV[0] =~ /^-/) {
print STDERR "usage: mksyscall_solaris.pl [-b32 | -l32] [-tags x,y] [file ...]\n";
exit 1;
}
@ -138,7 +139,6 @@ while(<>) {
# Prepare arguments to Syscall.
my @args = ();
my @uses = ();
my $n = 0;
foreach my $p (@in) {
my ($name, $type) = parseparam($p);
@ -149,14 +149,12 @@ while(<>) {
$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))";
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 $strconvtype\n";
$text .= "\t_p$n, _ = $strconvfunc($name)\n";
push @args, "uintptr(unsafe.Pointer(_p$n))";
push @uses, "use(unsafe.Pointer(_p$n))";
$n++;
} elsif($type =~ /^\[\](.*)/) {
# Convert slice into pointer, length.
@ -243,9 +241,6 @@ while(<>) {
} else {
$text .= "\t$ret[0], $ret[1], $ret[2] := $call\n";
}
foreach my $use (@uses) {
$text .= "\t$use\n";
}
$text .= $body;
if ($do_errno) {
@ -263,9 +258,9 @@ if($errors) {
print <<EOF;
// $cmdline
// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
// Code generated by the command above; see README.md. DO NOT EDIT.
// +build $ENV{'GOARCH'},$ENV{'GOOS'}
// +build $tags
package $package

View File

@ -16,7 +16,7 @@ my $command = "mksysnum_darwin.pl " . join(' ', @ARGV);
print <<EOF;
// $command
// MACHINE GENERATED BY THE ABOVE COMMAND; DO NOT EDIT
// Code generated by the command above; see README.md. DO NOT EDIT.
// +build $ENV{'GOARCH'},$ENV{'GOOS'}

View File

@ -17,7 +17,7 @@ my $command = "mksysnum_dragonfly.pl " . join(' ', @ARGV);
print <<EOF;
// $command
// MACHINE GENERATED BY THE ABOVE COMMAND; DO NOT EDIT
// Code generated by the command above; see README.md. DO NOT EDIT.
// +build $ENV{'GOARCH'},$ENV{'GOOS'}

View File

@ -17,7 +17,7 @@ my $command = "mksysnum_freebsd.pl " . join(' ', @ARGV);
print <<EOF;
// $command
// MACHINE GENERATED BY THE ABOVE COMMAND; DO NOT EDIT
// Code generated by the command above; see README.md. DO NOT EDIT.
// +build $ENV{'GOARCH'},$ENV{'GOOS'}
@ -40,21 +40,8 @@ while(<>){
if($name eq 'SYS_SYS_EXIT'){
$name = 'SYS_EXIT';
}
if($name =~ /^SYS_CAP_+/ || $name =~ /^SYS___CAP_+/){
next
}
print " $name = $num; // $proto\n";
# We keep Capsicum syscall numbers for FreeBSD
# 9-STABLE here because we are not sure whether they
# are mature and stable.
if($num == 513){
print " SYS_CAP_NEW = 514 // { int cap_new(int fd, uint64_t rights); }\n";
print " SYS_CAP_GETRIGHTS = 515 // { int cap_getrights(int fd, \\\n";
print " SYS_CAP_ENTER = 516 // { int cap_enter(void); }\n";
print " SYS_CAP_GETMODE = 517 // { int cap_getmode(u_int *modep); }\n";
}
}
}

View File

@ -1,58 +0,0 @@
#!/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;
}
my $command = "mksysnum_linux.pl ". join(' ', @ARGV);
print <<EOF;
// $command
// MACHINE GENERATED BY THE ABOVE COMMAND; DO NOT EDIT
// +build $ENV{'GOARCH'},$ENV{'GOOS'}
package unix
const(
EOF
sub fmt {
my ($name, $num) = @_;
if($num > 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/;
print " SYS_$name = $num;\n";
}
my $prev;
open(GCC, "gcc -E -dD $ARGV[0] |") || die "can't run gcc";
while(<GCC>){
if(/^#define __NR_syscalls\s+/) {
# ignore redefinitions of __NR_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)
}
}
print <<EOF;
)
EOF

View File

@ -17,7 +17,7 @@ my $command = "mksysnum_netbsd.pl " . join(' ', @ARGV);
print <<EOF;
// $command
// MACHINE GENERATED BY THE ABOVE COMMAND; DO NOT EDIT
// Code generated by the command above; see README.md. DO NOT EDIT.
// +build $ENV{'GOARCH'},$ENV{'GOOS'}
@ -47,7 +47,7 @@ while(<>){
$name = "$7_$11" if $11 ne '';
$name =~ y/a-z/A-Z/;
if($compat eq '' || $compat eq '30' || $compat eq '50') {
if($compat eq '' || $compat eq '13' || $compat eq '30' || $compat eq '50') {
print " $name = $num; // $proto\n";
}
}

View File

@ -17,7 +17,7 @@ my $command = "mksysnum_openbsd.pl " . join(' ', @ARGV);
print <<EOF;
// $command
// MACHINE GENERATED BY THE ABOVE COMMAND; DO NOT EDIT
// Code generated by the command above; see README.md. DO NOT EDIT.
// +build $ENV{'GOARCH'},$ENV{'GOOS'}

38
vendor/golang.org/x/sys/unix/openbsd_pledge.go generated vendored Normal file
View File

@ -0,0 +1,38 @@
// 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 openbsd
// +build 386 amd64 arm
package unix
import (
"syscall"
"unsafe"
)
const (
SYS_PLEDGE = 108
)
// Pledge implements the pledge syscall. For more information see pledge(2).
func Pledge(promises string, paths []string) error {
promisesPtr, err := syscall.BytePtrFromString(promises)
if err != nil {
return err
}
promisesUnsafe, pathsUnsafe := unsafe.Pointer(promisesPtr), unsafe.Pointer(nil)
if paths != nil {
var pathsPtr []*byte
if pathsPtr, err = syscall.SlicePtrFromStrings(paths); err != nil {
return err
}
pathsUnsafe = unsafe.Pointer(&pathsPtr[0])
}
_, _, e := syscall.Syscall(SYS_PLEDGE, uintptr(promisesUnsafe), uintptr(pathsUnsafe), 0)
if e != 0 {
return e
}
return nil
}

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

@ -0,0 +1,15 @@
// 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.
// +build darwin dragonfly freebsd linux netbsd openbsd solaris
// For Unix, get the pagesize from the runtime.
package unix
import "syscall"
func Getpagesize() int {
return syscall.Getpagesize()
}

View File

@ -1,4 +1,4 @@
// Copyright 2012 The Go Authors. All rights reserved.
// 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.

View File

@ -1,4 +1,4 @@
// Copyright 2012 The Go Authors. All rights reserved.
// 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.

View File

@ -1,4 +1,4 @@
// Copyright 2011 The Go Authors. All rights reserved.
// 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.

View File

@ -1,4 +1,4 @@
// Copyright 2011 The Go Authors. All rights reserved.
// 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.
@ -13,9 +13,10 @@ import "unsafe"
// Round the length of a raw sockaddr up to align it properly.
func cmsgAlignOf(salen int) int {
salign := sizeofPtr
// NOTE: It seems like 64-bit Darwin and DragonFly BSD kernels
// still require 32-bit aligned access to network subsystem.
if darwin64Bit || dragonfly64Bit {
// NOTE: It seems like 64-bit Darwin, DragonFly BSD and
// Solaris kernels still require 32-bit aligned access to
// network subsystem.
if darwin64Bit || dragonfly64Bit || solaris64Bit {
salign = 4
}
return (salen + salign - 1) & ^(salign - 1)

View File

@ -5,10 +5,10 @@
// +build darwin dragonfly freebsd linux netbsd openbsd solaris
// Package unix contains an interface to the low-level operating system
// primitives. OS details vary depending on the underlying system, and
// primitives. OS details vary depending on the underlying system, and
// by default, godoc will display OS-specific documentation for the current
// system. If you want godoc to display OS documentation for another
// system, set $GOOS and $GOARCH to the desired system. For example, if
// system. If you want godoc to display OS 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
@ -21,8 +21,6 @@
// holds a value of type syscall.Errno.
package unix
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).
@ -51,26 +49,3 @@ func BytePtrFromString(s string) (*byte, error) {
// Single-word zero for use when we need a valid pointer to 0 bytes.
// See mkunix.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
}
func TimevalToNsec(tv Timeval) int64 { return int64(tv.Sec)*1e9 + int64(tv.Usec)*1e3 }
// use is a no-op, but the compiler cannot see that it is.
// Calling use(p) ensures that p is kept live until that point.
//go:noescape
func use(p unsafe.Pointer)

View File

@ -34,7 +34,7 @@ func Getgroups() (gids []int, err error) {
return nil, nil
}
// Sanity check group count. Max is 16 on BSD.
// Sanity check group count. Max is 16 on BSD.
if n < 0 || n > 1000 {
return nil, EINVAL
}
@ -352,6 +352,18 @@ func GetsockoptICMPv6Filter(fd, level, opt int) (*ICMPv6Filter, error) {
return &value, err
}
// GetsockoptString returns the string value of the socket option opt for the
// socket associated with fd at the given socket level.
func GetsockoptString(fd, level, opt int) (string, error) {
buf := make([]byte, 256)
vallen := _Socklen(len(buf))
err := getsockopt(fd, level, opt, unsafe.Pointer(&buf[0]), &vallen)
if err != nil {
return "", err
}
return string(buf[:vallen-1]), nil
}
//sys recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error)
//sys sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error)
//sys recvmsg(s int, msg *Msghdr, flags int) (n int, err error)
@ -470,25 +482,11 @@ func Sysctl(name string) (string, error) {
}
func SysctlArgs(name string, args ...int) (string, error) {
mib, err := sysctlmib(name, args...)
buf, err := SysctlRaw(name, args...)
if err != nil {
return "", err
}
// Find size.
n := uintptr(0)
if err := sysctl(mib, nil, &n, nil, 0); err != nil {
return "", err
}
if n == 0 {
return "", nil
}
// Read into buffer of that size.
buf := make([]byte, n)
if err := sysctl(mib, &buf[0], &n, nil, 0); err != nil {
return "", err
}
n := len(buf)
// Throw away terminating NUL.
if n > 0 && buf[n-1] == '\x00' {
@ -575,13 +573,24 @@ func Utimes(path string, tv []Timeval) error {
func UtimesNano(path string, ts []Timespec) error {
if ts == nil {
err := utimensat(AT_FDCWD, path, nil, 0)
if err != ENOSYS {
return err
}
return utimes(path, nil)
}
// TODO: The BSDs can do utimensat with SYS_UTIMENSAT but it
// isn't supported by darwin so this uses utimes instead
if len(ts) != 2 {
return EINVAL
}
// Darwin setattrlist can set nanosecond timestamps
err := setattrlistTimes(path, ts, 0)
if err != ENOSYS {
return err
}
err = utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
if err != ENOSYS {
return err
}
// Not as efficient as it could be because Timespec and
// Timeval have different types in the different OSes
tv := [2]Timeval{
@ -591,6 +600,20 @@ func UtimesNano(path string, ts []Timespec) error {
return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
}
func UtimesNanoAt(dirfd int, path string, ts []Timespec, flags int) error {
if ts == nil {
return utimensat(dirfd, path, nil, flags)
}
if len(ts) != 2 {
return EINVAL
}
err := setattrlistTimes(path, ts, flags)
if err != ENOSYS {
return err
}
return utimensat(dirfd, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), flags)
}
//sys futimes(fd int, timeval *[2]Timeval) (err error)
func Futimes(fd int, tv []Timeval) error {
@ -605,12 +628,18 @@ func Futimes(fd int, tv []Timeval) error {
//sys fcntl(fd int, cmd int, arg int) (val int, err error)
//sys poll(fds *PollFd, nfds int, timeout int) (n int, err error)
func Poll(fds []PollFd, timeout int) (n int, err error) {
if len(fds) == 0 {
return poll(nil, 0, timeout)
}
return poll(&fds[0], len(fds), timeout)
}
// TODO: wrap
// Acct(name nil-string) (err error)
// Gethostuuid(uuid *byte, timeout *Timespec) (err error)
// Madvise(addr *byte, len int, behav int) (err error)
// Mprotect(addr *byte, len int, prot int) (err error)
// Msync(addr *byte, len int, flags int) (err error)
// Ptrace(req int, pid int, addr uintptr, data int) (ret uintptr, err error)
var mapper = &mmapper{
@ -626,3 +655,11 @@ func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, e
func Munmap(b []byte) (err error) {
return mapper.Munmap(b)
}
//sys Madvise(b []byte, behav int) (err error)
//sys Mlock(b []byte) (err error)
//sys Mlockall(flags int) (err error)
//sys Mprotect(b []byte, prot int) (err error)
//sys Msync(b []byte, flags int) (err error)
//sys Munlock(b []byte) (err error)
//sys Munlockall() (err error)

View File

@ -54,7 +54,7 @@ func nametomib(name string) (mib []_C_int, err error) {
// NOTE(rsc): It seems strange to set the buffer to have
// size CTL_MAXNAME+2 but use only CTL_MAXNAME
// as the size. I don't know why the +2 is here, but the
// as the size. I don't know why the +2 is here, but the
// kernel uses +2 for its own implementation of this function.
// I am scared that if we don't include the +2 here, the kernel
// will silently write 2 words farther than we specify
@ -76,32 +76,16 @@ func nametomib(name string) (mib []_C_int, err error) {
return buf[0 : n/siz], nil
}
// ParseDirent parses up to max directory entries in buf,
// appending the names to names. It returns the number
// 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)
for max != 0 && len(buf) > 0 {
dirent := (*Dirent)(unsafe.Pointer(&buf[0]))
if dirent.Reclen == 0 {
buf = nil
break
}
buf = buf[dirent.Reclen:]
if dirent.Ino == 0 { // File absent in directory.
continue
}
bytes := (*[10000]byte)(unsafe.Pointer(&dirent.Name[0]))
var name = string(bytes[0:dirent.Namlen])
if name == "." || name == ".." { // Useless names
continue
}
max--
count++
names = append(names, name)
}
return origlen - len(buf), count, names
func direntIno(buf []byte) (uint64, bool) {
return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino))
}
func direntReclen(buf []byte) (uint64, bool) {
return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
}
func direntNamlen(buf []byte) (uint64, bool) {
return readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen))
}
//sys ptrace(request int, pid int, addr uintptr, data uintptr) (err error)
@ -203,6 +187,42 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
return
}
func setattrlistTimes(path string, times []Timespec, flags int) error {
_p0, err := BytePtrFromString(path)
if err != nil {
return err
}
var attrList attrList
attrList.bitmapCount = ATTR_BIT_MAP_COUNT
attrList.CommonAttr = ATTR_CMN_MODTIME | ATTR_CMN_ACCTIME
// order is mtime, atime: the opposite of Chtimes
attributes := [2]Timespec{times[1], times[0]}
options := 0
if flags&AT_SYMLINK_NOFOLLOW != 0 {
options |= FSOPT_NOFOLLOW
}
_, _, e1 := Syscall6(
SYS_SETATTRLIST,
uintptr(unsafe.Pointer(_p0)),
uintptr(unsafe.Pointer(&attrList)),
uintptr(unsafe.Pointer(&attributes)),
uintptr(unsafe.Sizeof(attributes)),
uintptr(options),
0,
)
if e1 != 0 {
return e1
}
return nil
}
func utimensat(dirfd int, path string, times *[2]Timespec, flags int) error {
// Darwin doesn't support SYS_UTIMENSAT
return ENOSYS
}
/*
* Wrapped
*/
@ -211,6 +231,91 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
func Kill(pid int, signum syscall.Signal) (err error) { return kill(pid, int(signum), 1) }
//sys ioctl(fd int, req uint, arg uintptr) (err error)
// ioctl itself should not be exposed directly, but additional get/set
// functions for specific types are permissible.
// IoctlSetInt performs an ioctl operation which sets an integer value
// on fd, using the specified request number.
func IoctlSetInt(fd int, req uint, value int) error {
return ioctl(fd, req, uintptr(value))
}
func IoctlSetWinsize(fd int, req uint, value *Winsize) error {
return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
}
func IoctlSetTermios(fd int, req uint, value *Termios) error {
return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
}
// IoctlGetInt performs an ioctl operation which gets an integer value
// from fd, using the specified request number.
func IoctlGetInt(fd int, req uint) (int, error) {
var value int
err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
return value, err
}
func IoctlGetWinsize(fd int, req uint) (*Winsize, error) {
var value Winsize
err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
return &value, err
}
func IoctlGetTermios(fd int, req uint) (*Termios, error) {
var value Termios
err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
return &value, err
}
func Uname(uname *Utsname) error {
mib := []_C_int{CTL_KERN, KERN_OSTYPE}
n := unsafe.Sizeof(uname.Sysname)
if err := sysctl(mib, &uname.Sysname[0], &n, nil, 0); err != nil {
return err
}
mib = []_C_int{CTL_KERN, KERN_HOSTNAME}
n = unsafe.Sizeof(uname.Nodename)
if err := sysctl(mib, &uname.Nodename[0], &n, nil, 0); err != nil {
return err
}
mib = []_C_int{CTL_KERN, KERN_OSRELEASE}
n = unsafe.Sizeof(uname.Release)
if err := sysctl(mib, &uname.Release[0], &n, nil, 0); err != nil {
return err
}
mib = []_C_int{CTL_KERN, KERN_VERSION}
n = unsafe.Sizeof(uname.Version)
if err := sysctl(mib, &uname.Version[0], &n, nil, 0); err != nil {
return err
}
// The version might have newlines or tabs in it, convert them to
// spaces.
for i, b := range uname.Version {
if b == '\n' || b == '\t' {
if i == len(uname.Version)-1 {
uname.Version[i] = 0
} else {
uname.Version[i] = ' '
}
}
}
mib = []_C_int{CTL_HW, HW_MACHINE}
n = unsafe.Sizeof(uname.Machine)
if err := sysctl(mib, &uname.Machine[0], &n, nil, 0); err != nil {
return err
}
return nil
}
/*
* Exposed directly
*/
@ -226,10 +331,13 @@ func Kill(pid int, signum syscall.Signal) (err error) { return kill(pid, int(sig
//sys Dup2(from int, to int) (err error)
//sys Exchangedata(path1 string, path2 string, options int) (err error)
//sys Exit(code int)
//sys Faccessat(dirfd int, path string, mode uint32, flags int) (err error)
//sys Fchdir(fd int) (err error)
//sys Fchflags(fd int, flags int) (err error)
//sys Fchmod(fd int, mode uint32) (err error)
//sys Fchmodat(dirfd int, path string, mode uint32, flags int) (err error)
//sys Fchown(fd int, uid int, gid int) (err error)
//sys Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error)
//sys Flock(fd int, how int) (err error)
//sys Fpathconf(fd int, name int) (val int, err error)
//sys Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64
@ -254,23 +362,23 @@ func Kill(pid int, signum syscall.Signal) (err error) { return kill(pid, int(sig
//sys Kqueue() (fd int, err error)
//sys Lchown(path string, uid int, gid int) (err error)
//sys Link(path string, link string) (err error)
//sys Linkat(pathfd int, path string, linkfd int, link string, flags int) (err error)
//sys Listen(s int, backlog int) (err error)
//sys Lstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64
//sys Mkdir(path string, mode uint32) (err error)
//sys Mkdirat(dirfd int, path string, mode uint32) (err error)
//sys Mkfifo(path string, mode uint32) (err error)
//sys Mknod(path string, mode uint32, dev int) (err error)
//sys Mlock(b []byte) (err error)
//sys Mlockall(flags int) (err error)
//sys Mprotect(b []byte, prot int) (err error)
//sys Munlock(b []byte) (err error)
//sys Munlockall() (err error)
//sys Open(path string, mode int, perm uint32) (fd int, err error)
//sys Openat(dirfd int, path string, mode int, perm uint32) (fd int, err error)
//sys Pathconf(path string, name int) (val 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 read(fd int, p []byte) (n int, err error)
//sys Readlink(path string, buf []byte) (n int, err error)
//sys Readlinkat(dirfd int, path string, buf []byte) (n int, err error)
//sys Rename(from string, to string) (err error)
//sys Renameat(fromfd int, from string, tofd int, to string) (err error)
//sys Revoke(path string) (err error)
//sys Rmdir(path string) (err error)
//sys Seek(fd int, offset int64, whence int) (newoffset int64, err error) = SYS_LSEEK
@ -291,11 +399,13 @@ func Kill(pid int, signum syscall.Signal) (err error) { return kill(pid, int(sig
//sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64
//sys Statfs(path string, stat *Statfs_t) (err error) = SYS_STATFS64
//sys Symlink(path string, link string) (err error)
//sys Symlinkat(oldpath string, newdirfd int, newpath string) (err error)
//sys Sync() (err error)
//sys Truncate(path string, length int64) (err error)
//sys Umask(newmask int) (oldmask int)
//sys Undelete(path string) (err error)
//sys Unlink(path string) (err error)
//sys Unlinkat(dirfd int, path string, flags int) (err error)
//sys Unmount(path string, flags int) (err error)
//sys write(fd int, p []byte) (n int, err error)
//sys mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error)
@ -335,9 +445,6 @@ func Kill(pid int, signum syscall.Signal) (err error) { return kill(pid, int(sig
// Add_profil
// Kdebug_trace
// Sigreturn
// Mmap
// Mlock
// Munlock
// Atsocket
// Kqueue_from_portset_np
// Kqueue_portset
@ -347,7 +454,6 @@ func Kill(pid int, signum syscall.Signal) (err error) { return kill(pid, int(sig
// Searchfs
// Delete
// Copyfile
// Poll
// Watchevent
// Waitevent
// Modwatch
@ -430,8 +536,6 @@ func Kill(pid int, signum syscall.Signal) (err error) { return kill(pid, int(sig
// Lio_listio
// __pthread_cond_wait
// Iopolicysys
// Mlockall
// Munlockall
// __pthread_kill
// __pthread_sigmask
// __sigwait
@ -485,7 +589,6 @@ func Kill(pid int, signum syscall.Signal) (err error) { return kill(pid, int(sig
// Sendmsg_nocancel
// Recvfrom_nocancel
// Accept_nocancel
// Msync_nocancel
// Fcntl_nocancel
// Select_nocancel
// Fsync_nocancel

View File

@ -11,27 +11,18 @@ import (
"unsafe"
)
func Getpagesize() int { return 4096 }
func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
func NsecToTimespec(nsec int64) (ts Timespec) {
ts.Sec = int32(nsec / 1e9)
ts.Nsec = int32(nsec % 1e9)
return
func setTimespec(sec, nsec int64) Timespec {
return Timespec{Sec: int32(sec), Nsec: int32(nsec)}
}
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 setTimeval(sec, usec int64) Timeval {
return Timeval{Sec: int32(sec), Usec: int32(usec)}
}
//sysnb gettimeofday(tp *Timeval) (sec int32, usec int32, err error)
func Gettimeofday(tv *Timeval) (err error) {
// The tv passed to gettimeofday must be non-nil
// but is otherwise unused. The answers come back
// but is otherwise unused. The answers come back
// in the two registers.
sec, usec, err := gettimeofday(tv)
tv.Sec = int32(sec)

View File

@ -11,29 +11,18 @@ import (
"unsafe"
)
//sys Fchmodat(dirfd int, path string, mode uint32, flags int) (err error)
func Getpagesize() int { return 4096 }
func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
func NsecToTimespec(nsec int64) (ts Timespec) {
ts.Sec = nsec / 1e9
ts.Nsec = nsec % 1e9
return
func setTimespec(sec, nsec int64) Timespec {
return Timespec{Sec: sec, Nsec: nsec}
}
func NsecToTimeval(nsec int64) (tv Timeval) {
nsec += 999 // round up to microsecond
tv.Usec = int32(nsec % 1e9 / 1e3)
tv.Sec = int64(nsec / 1e9)
return
func setTimeval(sec, usec int64) Timeval {
return Timeval{Sec: sec, Usec: int32(usec)}
}
//sysnb gettimeofday(tp *Timeval) (sec int64, usec int32, err error)
func Gettimeofday(tv *Timeval) (err error) {
// The tv passed to gettimeofday must be non-nil
// but is otherwise unused. The answers come back
// but is otherwise unused. The answers come back
// in the two registers.
sec, usec, err := gettimeofday(tv)
tv.Sec = sec

View File

@ -9,27 +9,18 @@ import (
"unsafe"
)
func Getpagesize() int { return 4096 }
func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
func NsecToTimespec(nsec int64) (ts Timespec) {
ts.Sec = int32(nsec / 1e9)
ts.Nsec = int32(nsec % 1e9)
return
func setTimespec(sec, nsec int64) Timespec {
return Timespec{Sec: int32(sec), Nsec: int32(nsec)}
}
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 setTimeval(sec, usec int64) Timeval {
return Timeval{Sec: int32(sec), Usec: int32(usec)}
}
//sysnb gettimeofday(tp *Timeval) (sec int32, usec int32, err error)
func Gettimeofday(tv *Timeval) (err error) {
// The tv passed to gettimeofday must be non-nil
// but is otherwise unused. The answers come back
// but is otherwise unused. The answers come back
// in the two registers.
sec, usec, err := gettimeofday(tv)
tv.Sec = int32(sec)
@ -69,3 +60,7 @@ func sendfile(outfd int, infd int, offset *int64, count int) (written int, err e
}
func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno) // sic
// SYS___SYSCTL is used by syscall_bsd.go for all BSDs, but in modern versions
// of darwin/arm the syscall is called sysctl instead of __sysctl.
const SYS___SYSCTL = SYS_SYSCTL

View File

@ -11,27 +11,18 @@ import (
"unsafe"
)
func Getpagesize() int { return 16384 }
func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
func NsecToTimespec(nsec int64) (ts Timespec) {
ts.Sec = nsec / 1e9
ts.Nsec = nsec % 1e9
return
func setTimespec(sec, nsec int64) Timespec {
return Timespec{Sec: sec, Nsec: nsec}
}
func NsecToTimeval(nsec int64) (tv Timeval) {
nsec += 999 // round up to microsecond
tv.Usec = int32(nsec % 1e9 / 1e3)
tv.Sec = int64(nsec / 1e9)
return
func setTimeval(sec, usec int64) Timeval {
return Timeval{Sec: sec, Usec: int32(usec)}
}
//sysnb gettimeofday(tp *Timeval) (sec int64, usec int32, err error)
func Gettimeofday(tv *Timeval) (err error) {
// The tv passed to gettimeofday must be non-nil
// but is otherwise unused. The answers come back
// but is otherwise unused. The answers come back
// in the two registers.
sec, usec, err := gettimeofday(tv)
tv.Sec = sec

View File

@ -1,8 +1,8 @@
// Copyright 2009,2010 The Go Authors. All rights reserved.
// 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.
// FreeBSD system calls.
// DragonFly BSD 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.
@ -34,7 +34,7 @@ func nametomib(name string) (mib []_C_int, err error) {
// NOTE(rsc): It seems strange to set the buffer to have
// size CTL_MAXNAME+2 but use only CTL_MAXNAME
// as the size. I don't know why the +2 is here, but the
// as the size. I don't know why the +2 is here, but the
// kernel uses +2 for its own implementation of this function.
// I am scared that if we don't include the +2 here, the kernel
// will silently write 2 words farther than we specify
@ -56,29 +56,20 @@ func nametomib(name string) (mib []_C_int, err error) {
return buf[0 : n/siz], nil
}
// ParseDirent parses up to max directory entries in buf,
// appending the names to names. It returns the number
// 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)
for max != 0 && len(buf) > 0 {
dirent := (*Dirent)(unsafe.Pointer(&buf[0]))
reclen := int(16+dirent.Namlen+1+7) & ^7
buf = buf[reclen:]
if dirent.Fileno == 0 { // File absent in directory.
continue
}
bytes := (*[10000]byte)(unsafe.Pointer(&dirent.Name[0]))
var name = string(bytes[0:dirent.Namlen])
if name == "." || name == ".." { // Useless names
continue
}
max--
count++
names = append(names, name)
func direntIno(buf []byte) (uint64, bool) {
return readInt(buf, unsafe.Offsetof(Dirent{}.Fileno), unsafe.Sizeof(Dirent{}.Fileno))
}
func direntReclen(buf []byte) (uint64, bool) {
namlen, ok := direntNamlen(buf)
if !ok {
return 0, false
}
return origlen - len(buf), count, names
return (16 + namlen + 1 + 7) &^ 7, true
}
func direntNamlen(buf []byte) (uint64, bool) {
return readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen))
}
//sysnb pipe() (r int, w int, err error)
@ -101,6 +92,41 @@ func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
return extpwrite(fd, p, 0, offset)
}
func Accept4(fd, flags int) (nfd int, sa Sockaddr, err error) {
var rsa RawSockaddrAny
var len _Socklen = SizeofSockaddrAny
nfd, err = accept4(fd, &rsa, &len, flags)
if err != nil {
return
}
if len > SizeofSockaddrAny {
panic("RawSockaddrAny too small")
}
sa, err = anyToSockaddr(&rsa)
if err != nil {
Close(nfd)
nfd = 0
}
return
}
const ImplementsGetwd = true
//sys Getcwd(buf []byte) (n int, err error) = SYS___GETCWD
func Getwd() (string, error) {
var buf [PathMax]byte
_, err := Getcwd(buf[0:])
if err != nil {
return "", err
}
n := clen(buf[:])
if n < 1 {
return "", EINVAL
}
return string(buf[:n]), nil
}
func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
var _p0 unsafe.Pointer
var bufsize uintptr
@ -116,6 +142,113 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
return
}
func setattrlistTimes(path string, times []Timespec, flags int) error {
// used on Darwin for UtimesNano
return ENOSYS
}
//sys ioctl(fd int, req uint, arg uintptr) (err error)
// ioctl itself should not be exposed directly, but additional get/set
// functions for specific types are permissible.
// IoctlSetInt performs an ioctl operation which sets an integer value
// on fd, using the specified request number.
func IoctlSetInt(fd int, req uint, value int) error {
return ioctl(fd, req, uintptr(value))
}
func IoctlSetWinsize(fd int, req uint, value *Winsize) error {
return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
}
func IoctlSetTermios(fd int, req uint, value *Termios) error {
return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
}
// IoctlGetInt performs an ioctl operation which gets an integer value
// from fd, using the specified request number.
func IoctlGetInt(fd int, req uint) (int, error) {
var value int
err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
return value, err
}
func IoctlGetWinsize(fd int, req uint) (*Winsize, error) {
var value Winsize
err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
return &value, err
}
func IoctlGetTermios(fd int, req uint) (*Termios, error) {
var value Termios
err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
return &value, err
}
func sysctlUname(mib []_C_int, old *byte, oldlen *uintptr) error {
err := sysctl(mib, old, oldlen, nil, 0)
if err != nil {
// Utsname members on Dragonfly are only 32 bytes and
// the syscall returns ENOMEM in case the actual value
// is longer.
if err == ENOMEM {
err = nil
}
}
return err
}
func Uname(uname *Utsname) error {
mib := []_C_int{CTL_KERN, KERN_OSTYPE}
n := unsafe.Sizeof(uname.Sysname)
if err := sysctlUname(mib, &uname.Sysname[0], &n); err != nil {
return err
}
uname.Sysname[unsafe.Sizeof(uname.Sysname)-1] = 0
mib = []_C_int{CTL_KERN, KERN_HOSTNAME}
n = unsafe.Sizeof(uname.Nodename)
if err := sysctlUname(mib, &uname.Nodename[0], &n); err != nil {
return err
}
uname.Nodename[unsafe.Sizeof(uname.Nodename)-1] = 0
mib = []_C_int{CTL_KERN, KERN_OSRELEASE}
n = unsafe.Sizeof(uname.Release)
if err := sysctlUname(mib, &uname.Release[0], &n); err != nil {
return err
}
uname.Release[unsafe.Sizeof(uname.Release)-1] = 0
mib = []_C_int{CTL_KERN, KERN_VERSION}
n = unsafe.Sizeof(uname.Version)
if err := sysctlUname(mib, &uname.Version[0], &n); err != nil {
return err
}
// The version might have newlines or tabs in it, convert them to
// spaces.
for i, b := range uname.Version {
if b == '\n' || b == '\t' {
if i == len(uname.Version)-1 {
uname.Version[i] = 0
} else {
uname.Version[i] = ' '
}
}
}
mib = []_C_int{CTL_HW, HW_MACHINE}
n = unsafe.Sizeof(uname.Machine)
if err := sysctlUname(mib, &uname.Machine[0], &n); err != nil {
return err
}
uname.Machine[unsafe.Sizeof(uname.Machine)-1] = 0
return nil
}
/*
* Exposed directly
*/
@ -165,11 +298,6 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
//sys Mkdir(path string, mode uint32) (err error)
//sys Mkfifo(path string, mode uint32) (err error)
//sys Mknod(path string, mode uint32, dev int) (err error)
//sys Mlock(b []byte) (err error)
//sys Mlockall(flags int) (err error)
//sys Mprotect(b []byte, prot int) (err error)
//sys Munlock(b []byte) (err error)
//sys Munlockall() (err error)
//sys Nanosleep(time *Timespec, leftover *Timespec) (err error)
//sys Open(path string, mode int, perm uint32) (fd int, err error)
//sys Pathconf(path string, name int) (val int, err error)
@ -208,6 +336,8 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
//sys munmap(addr uintptr, length uintptr) (err error)
//sys readlen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_READ
//sys writelen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_WRITE
//sys accept4(fd int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (nfd int, err error)
//sys utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error)
/*
* Unimplemented
@ -219,7 +349,6 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
// Getlogin
// Sigpending
// Sigaltstack
// Ioctl
// Reboot
// Execve
// Vfork
@ -242,7 +371,6 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
// Add_profil
// Kdebug_trace
// Sigreturn
// Mmap
// Atsocket
// Kqueue_from_portset_np
// Kqueue_portset
@ -252,7 +380,6 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
// Searchfs
// Delete
// Copyfile
// Poll
// Watchevent
// Waitevent
// Modwatch
@ -387,7 +514,6 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
// Sendmsg_nocancel
// Recvfrom_nocancel
// Accept_nocancel
// Msync_nocancel
// Fcntl_nocancel
// Select_nocancel
// Fsync_nocancel
@ -399,7 +525,6 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
// Pread_nocancel
// Pwrite_nocancel
// Waitid_nocancel
// Poll_nocancel
// Msgsnd_nocancel
// Msgrcv_nocancel
// Sem_wait_nocancel

View File

@ -11,21 +11,12 @@ import (
"unsafe"
)
func Getpagesize() int { return 4096 }
func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
func NsecToTimespec(nsec int64) (ts Timespec) {
ts.Sec = nsec / 1e9
ts.Nsec = nsec % 1e9
return
func setTimespec(sec, nsec int64) Timespec {
return Timespec{Sec: sec, Nsec: nsec}
}
func NsecToTimeval(nsec int64) (tv Timeval) {
nsec += 999 // round up to microsecond
tv.Usec = nsec % 1e9 / 1e3
tv.Sec = int64(nsec / 1e9)
return
func setTimeval(sec, usec int64) Timeval {
return Timeval{Sec: sec, Usec: usec}
}
func SetKevent(k *Kevent_t, fd, mode, flags int) {

View File

@ -32,7 +32,7 @@ func nametomib(name string) (mib []_C_int, err error) {
// NOTE(rsc): It seems strange to set the buffer to have
// size CTL_MAXNAME+2 but use only CTL_MAXNAME
// as the size. I don't know why the +2 is here, but the
// as the size. I don't know why the +2 is here, but the
// kernel uses +2 for its own implementation of this function.
// I am scared that if we don't include the +2 here, the kernel
// will silently write 2 words farther than we specify
@ -54,32 +54,16 @@ func nametomib(name string) (mib []_C_int, err error) {
return buf[0 : n/siz], nil
}
// ParseDirent parses up to max directory entries in buf,
// appending the names to names. It returns the number
// 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)
for max != 0 && len(buf) > 0 {
dirent := (*Dirent)(unsafe.Pointer(&buf[0]))
if dirent.Reclen == 0 {
buf = nil
break
}
buf = buf[dirent.Reclen:]
if dirent.Fileno == 0 { // File absent in directory.
continue
}
bytes := (*[10000]byte)(unsafe.Pointer(&dirent.Name[0]))
var name = string(bytes[0:dirent.Namlen])
if name == "." || name == ".." { // Useless names
continue
}
max--
count++
names = append(names, name)
}
return origlen - len(buf), count, names
func direntIno(buf []byte) (uint64, bool) {
return readInt(buf, unsafe.Offsetof(Dirent{}.Fileno), unsafe.Sizeof(Dirent{}.Fileno))
}
func direntReclen(buf []byte) (uint64, bool) {
return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
}
func direntNamlen(buf []byte) (uint64, bool) {
return readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen))
}
//sysnb pipe() (r int, w int, err error)
@ -121,6 +105,23 @@ func Accept4(fd, flags int) (nfd int, sa Sockaddr, err error) {
return
}
const ImplementsGetwd = true
//sys Getcwd(buf []byte) (n int, err error) = SYS___GETCWD
func Getwd() (string, error) {
var buf [PathMax]byte
_, err := Getcwd(buf[0:])
if err != nil {
return "", err
}
n := clen(buf[:])
if n < 1 {
return "", EINVAL
}
return string(buf[:n]), nil
}
func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
var _p0 unsafe.Pointer
var bufsize uintptr
@ -136,6 +137,11 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
return
}
func setattrlistTimes(path string, times []Timespec, flags int) error {
// used on Darwin for UtimesNano
return ENOSYS
}
// Derive extattr namespace and attribute name
func xattrnamespace(fullattr string) (ns int, attr string, err error) {
@ -368,11 +374,99 @@ func Llistxattr(link string, dest []byte) (sz int, err error) {
return s, e
}
//sys ioctl(fd int, req uint, arg uintptr) (err error)
// ioctl itself should not be exposed directly, but additional get/set
// functions for specific types are permissible.
// IoctlSetInt performs an ioctl operation which sets an integer value
// on fd, using the specified request number.
func IoctlSetInt(fd int, req uint, value int) error {
return ioctl(fd, req, uintptr(value))
}
func IoctlSetWinsize(fd int, req uint, value *Winsize) error {
return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
}
func IoctlSetTermios(fd int, req uint, value *Termios) error {
return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
}
// IoctlGetInt performs an ioctl operation which gets an integer value
// from fd, using the specified request number.
func IoctlGetInt(fd int, req uint) (int, error) {
var value int
err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
return value, err
}
func IoctlGetWinsize(fd int, req uint) (*Winsize, error) {
var value Winsize
err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
return &value, err
}
func IoctlGetTermios(fd int, req uint) (*Termios, error) {
var value Termios
err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
return &value, err
}
func Uname(uname *Utsname) error {
mib := []_C_int{CTL_KERN, KERN_OSTYPE}
n := unsafe.Sizeof(uname.Sysname)
if err := sysctl(mib, &uname.Sysname[0], &n, nil, 0); err != nil {
return err
}
mib = []_C_int{CTL_KERN, KERN_HOSTNAME}
n = unsafe.Sizeof(uname.Nodename)
if err := sysctl(mib, &uname.Nodename[0], &n, nil, 0); err != nil {
return err
}
mib = []_C_int{CTL_KERN, KERN_OSRELEASE}
n = unsafe.Sizeof(uname.Release)
if err := sysctl(mib, &uname.Release[0], &n, nil, 0); err != nil {
return err
}
mib = []_C_int{CTL_KERN, KERN_VERSION}
n = unsafe.Sizeof(uname.Version)
if err := sysctl(mib, &uname.Version[0], &n, nil, 0); err != nil {
return err
}
// The version might have newlines or tabs in it, convert them to
// spaces.
for i, b := range uname.Version {
if b == '\n' || b == '\t' {
if i == len(uname.Version)-1 {
uname.Version[i] = 0
} else {
uname.Version[i] = ' '
}
}
}
mib = []_C_int{CTL_HW, HW_MACHINE}
n = unsafe.Sizeof(uname.Machine)
if err := sysctl(mib, &uname.Machine[0], &n, nil, 0); err != nil {
return err
}
return nil
}
/*
* Exposed directly
*/
//sys Access(path string, mode uint32) (err error)
//sys Adjtime(delta *Timeval, olddelta *Timeval) (err error)
//sys CapEnter() (err error)
//sys capRightsGet(version int, fd int, rightsp *CapRights) (err error) = SYS___CAP_RIGHTS_GET
//sys capRightsLimit(fd int, rightsp *CapRights) (err error)
//sys Chdir(path string) (err error)
//sys Chflags(path string, flags int) (err error)
//sys Chmod(path string, mode uint32) (err error)
@ -395,16 +489,20 @@ func Llistxattr(link string, dest []byte) (sz int, err error) {
//sys ExtattrDeleteLink(link string, attrnamespace int, attrname string) (err error)
//sys ExtattrListLink(link string, attrnamespace int, data uintptr, nbytes int) (ret int, err error)
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_POSIX_FADVISE
//sys Faccessat(dirfd int, path string, mode uint32, flags int) (err error)
//sys Fchdir(fd int) (err error)
//sys Fchflags(fd int, flags int) (err error)
//sys Fchmod(fd int, mode uint32) (err error)
//sys Fchmodat(dirfd int, path string, mode uint32, flags int) (err error)
//sys Fchown(fd int, uid int, gid int) (err error)
//sys Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error)
//sys Flock(fd int, how int) (err error)
//sys Fpathconf(fd int, name int) (val int, err error)
//sys Fstat(fd int, stat *Stat_t) (err error)
//sys Fstatfs(fd int, stat *Statfs_t) (err error)
//sys Fsync(fd int) (err error)
//sys Ftruncate(fd int, length int64) (err error)
//sys Getdents(fd int, buf []byte) (n int, err error)
//sys Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error)
//sys Getdtablesize() (size int)
//sysnb Getegid() (egid int)
@ -425,24 +523,24 @@ func Llistxattr(link string, dest []byte) (sz int, err error) {
//sys Kqueue() (fd int, err error)
//sys Lchown(path string, uid int, gid int) (err error)
//sys Link(path string, link string) (err error)
//sys Linkat(pathfd int, path string, linkfd int, link string, flags int) (err error)
//sys Listen(s int, backlog int) (err error)
//sys Lstat(path string, stat *Stat_t) (err error)
//sys Mkdir(path string, mode uint32) (err error)
//sys Mkdirat(dirfd int, path string, mode uint32) (err error)
//sys Mkfifo(path string, mode uint32) (err error)
//sys Mknod(path string, mode uint32, dev int) (err error)
//sys Mlock(b []byte) (err error)
//sys Mlockall(flags int) (err error)
//sys Mprotect(b []byte, prot int) (err error)
//sys Munlock(b []byte) (err error)
//sys Munlockall() (err error)
//sys Nanosleep(time *Timespec, leftover *Timespec) (err error)
//sys Open(path string, mode int, perm uint32) (fd int, err error)
//sys Openat(fdat int, path string, mode int, perm uint32) (fd int, err error)
//sys Pathconf(path string, name int) (val 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 read(fd int, p []byte) (n int, err error)
//sys Readlink(path string, buf []byte) (n int, err error)
//sys Readlinkat(dirfd int, path string, buf []byte) (n int, err error)
//sys Rename(from string, to string) (err error)
//sys Renameat(fromfd int, from string, tofd int, to string) (err error)
//sys Revoke(path string) (err error)
//sys Rmdir(path string) (err error)
//sys Seek(fd int, offset int64, whence int) (newoffset int64, err error) = SYS_LSEEK
@ -464,11 +562,13 @@ func Llistxattr(link string, dest []byte) (sz int, err error) {
//sys Stat(path string, stat *Stat_t) (err error)
//sys Statfs(path string, stat *Statfs_t) (err error)
//sys Symlink(path string, link string) (err error)
//sys Symlinkat(oldpath string, newdirfd int, newpath string) (err error)
//sys Sync() (err error)
//sys Truncate(path string, length int64) (err error)
//sys Umask(newmask int) (oldmask int)
//sys Undelete(path string) (err error)
//sys Unlink(path string) (err error)
//sys Unlinkat(dirfd int, path string, flags int) (err error)
//sys Unmount(path string, flags int) (err error)
//sys write(fd int, p []byte) (n int, err error)
//sys mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error)
@ -476,6 +576,7 @@ func Llistxattr(link string, dest []byte) (sz int, err error) {
//sys readlen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_READ
//sys writelen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_WRITE
//sys accept4(fd int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (nfd int, err error)
//sys utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error)
/*
* Unimplemented
@ -509,9 +610,6 @@ func Llistxattr(link string, dest []byte) (sz int, err error) {
// Add_profil
// Kdebug_trace
// Sigreturn
// Mmap
// Mlock
// Munlock
// Atsocket
// Kqueue_from_portset_np
// Kqueue_portset
@ -521,7 +619,6 @@ func Llistxattr(link string, dest []byte) (sz int, err error) {
// Searchfs
// Delete
// Copyfile
// Poll
// Watchevent
// Waitevent
// Modwatch
@ -604,8 +701,6 @@ func Llistxattr(link string, dest []byte) (sz int, err error) {
// Lio_listio
// __pthread_cond_wait
// Iopolicysys
// Mlockall
// Munlockall
// __pthread_kill
// __pthread_sigmask
// __sigwait
@ -658,7 +753,6 @@ func Llistxattr(link string, dest []byte) (sz int, err error) {
// Sendmsg_nocancel
// Recvfrom_nocancel
// Accept_nocancel
// Msync_nocancel
// Fcntl_nocancel
// Select_nocancel
// Fsync_nocancel

View File

@ -11,21 +11,12 @@ import (
"unsafe"
)
func Getpagesize() int { return 4096 }
func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
func NsecToTimespec(nsec int64) (ts Timespec) {
ts.Sec = int32(nsec / 1e9)
ts.Nsec = int32(nsec % 1e9)
return
func setTimespec(sec, nsec int64) Timespec {
return Timespec{Sec: int32(sec), Nsec: int32(nsec)}
}
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 setTimeval(sec, usec int64) Timeval {
return Timeval{Sec: int32(sec), Usec: int32(usec)}
}
func SetKevent(k *Kevent_t, fd, mode, flags int) {

View File

@ -11,21 +11,12 @@ import (
"unsafe"
)
func Getpagesize() int { return 4096 }
func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
func NsecToTimespec(nsec int64) (ts Timespec) {
ts.Sec = nsec / 1e9
ts.Nsec = nsec % 1e9
return
func setTimespec(sec, nsec int64) Timespec {
return Timespec{Sec: sec, Nsec: nsec}
}
func NsecToTimeval(nsec int64) (tv Timeval) {
nsec += 999 // round up to microsecond
tv.Usec = nsec % 1e9 / 1e3
tv.Sec = int64(nsec / 1e9)
return
func setTimeval(sec, usec int64) Timeval {
return Timeval{Sec: sec, Usec: usec}
}
func SetKevent(k *Kevent_t, fd, mode, flags int) {

View File

@ -11,21 +11,12 @@ import (
"unsafe"
)
func Getpagesize() int { return 4096 }
func TimespecToNsec(ts Timespec) int64 { return ts.Sec*1e9 + int64(ts.Nsec) }
func NsecToTimespec(nsec int64) (ts Timespec) {
ts.Sec = nsec / 1e9
ts.Nsec = int32(nsec % 1e9)
return
func setTimespec(sec, nsec int64) Timespec {
return Timespec{Sec: sec, Nsec: int32(nsec)}
}
func NsecToTimeval(nsec int64) (tv Timeval) {
nsec += 999 // round up to microsecond
tv.Usec = int32(nsec % 1e9 / 1e3)
tv.Sec = nsec / 1e9
return
func setTimeval(sec, usec int64) Timeval {
return Timeval{Sec: sec, Usec: int32(usec)}
}
func SetKevent(k *Kevent_t, fd, mode, flags int) {

View File

@ -36,6 +36,59 @@ func Creat(path string, mode uint32) (fd int, err error) {
return Open(path, O_CREAT|O_WRONLY|O_TRUNC, mode)
}
//sys fchmodat(dirfd int, path string, mode uint32) (err error)
func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) {
// Linux fchmodat doesn't support the flags parameter. Mimick glibc's behavior
// and check the flags. Otherwise the mode would be applied to the symlink
// destination which is not what the user expects.
if flags&^AT_SYMLINK_NOFOLLOW != 0 {
return EINVAL
} else if flags&AT_SYMLINK_NOFOLLOW != 0 {
return EOPNOTSUPP
}
return fchmodat(dirfd, path, mode)
}
//sys ioctl(fd int, req uint, arg uintptr) (err error)
// ioctl itself should not be exposed directly, but additional get/set
// functions for specific types are permissible.
// IoctlSetInt performs an ioctl operation which sets an integer value
// on fd, using the specified request number.
func IoctlSetInt(fd int, req uint, value int) error {
return ioctl(fd, req, uintptr(value))
}
func IoctlSetWinsize(fd int, req uint, value *Winsize) error {
return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
}
func IoctlSetTermios(fd int, req uint, value *Termios) error {
return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
}
// IoctlGetInt performs an ioctl operation which gets an integer value
// from fd, using the specified request number.
func IoctlGetInt(fd int, req uint) (int, error) {
var value int
err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
return value, err
}
func IoctlGetWinsize(fd int, req uint) (*Winsize, error) {
var value Winsize
err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
return &value, err
}
func IoctlGetTermios(fd int, req uint) (*Termios, error) {
var value Termios
err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
return &value, err
}
//sys Linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error)
func Link(oldpath string, newpath string) (err error) {
@ -60,10 +113,19 @@ func Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error)
return openat(dirfd, path, flags|O_LARGEFILE, mode)
}
//sys readlinkat(dirfd int, path string, buf []byte) (n int, err error)
//sys ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error)
func Ppoll(fds []PollFd, timeout *Timespec, sigmask *Sigset_t) (n int, err error) {
if len(fds) == 0 {
return ppoll(nil, 0, timeout, sigmask)
}
return ppoll(&fds[0], len(fds), timeout, sigmask)
}
//sys Readlinkat(dirfd int, path string, buf []byte) (n int, err error)
func Readlink(path string, buf []byte) (n int, err error) {
return readlinkat(AT_FDCWD, path, buf)
return Readlinkat(AT_FDCWD, path, buf)
}
func Rename(oldpath string, newpath string) (err error) {
@ -71,24 +133,20 @@ func Rename(oldpath string, newpath string) (err error) {
}
func Rmdir(path string) error {
return unlinkat(AT_FDCWD, path, AT_REMOVEDIR)
return Unlinkat(AT_FDCWD, path, AT_REMOVEDIR)
}
//sys symlinkat(oldpath string, newdirfd int, newpath string) (err error)
//sys Symlinkat(oldpath string, newdirfd int, newpath string) (err error)
func Symlink(oldpath string, newpath string) (err error) {
return symlinkat(oldpath, AT_FDCWD, newpath)
return Symlinkat(oldpath, AT_FDCWD, newpath)
}
func Unlink(path string) error {
return unlinkat(AT_FDCWD, path, 0)
return Unlinkat(AT_FDCWD, path, 0)
}
//sys unlinkat(dirfd int, path string, flags int) (err error)
func Unlinkat(dirfd int, path string, flags int) error {
return unlinkat(dirfd, path, flags)
}
//sys Unlinkat(dirfd int, path string, flags int) (err error)
//sys utimes(path string, times *[2]Timeval) (err error)
@ -134,8 +192,7 @@ func UtimesNano(path string, ts []Timespec) error {
// in 2.6.22, Released, 8 July 2007) then fall back to utimes
var tv [2]Timeval
for i := 0; i < 2; i++ {
tv[i].Sec = ts[i].Sec
tv[i].Usec = ts[i].Nsec / 1000
tv[i] = NsecToTimeval(TimespecToNsec(ts[i]))
}
return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
}
@ -198,7 +255,7 @@ func Getgroups() (gids []int, err error) {
return nil, nil
}
// Sanity check group count. Max is 1<<16 on Linux.
// Sanity check group count. Max is 1<<16 on Linux.
if n < 0 || n > 1<<20 {
return nil, EINVAL
}
@ -233,8 +290,8 @@ type WaitStatus uint32
// 0x7F (stopped), or a signal number that caused an exit.
// The 0x80 bit is whether there was a core dump.
// An extra number (exit code, signal causing a stop)
// is in the high bits. At least that's the idea.
// There are various irregularities. For example, the
// is in the high bits. At least that's the idea.
// There are various irregularities. For example, the
// "continued" status is 0xFFFF, distinguishing itself
// from stopped via the core dump bit.
@ -295,10 +352,14 @@ func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int,
return
}
func Mkfifo(path string, mode uint32) (err error) {
func Mkfifo(path string, mode uint32) error {
return Mknod(path, mode|S_IFIFO, 0)
}
func Mkfifoat(dirfd int, path string, mode uint32) error {
return Mknodat(dirfd, path, mode|S_IFIFO, 0)
}
func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {
if sa.Port < 0 || sa.Port > 0xFFFF {
return nil, 0, EINVAL
@ -407,6 +468,168 @@ func (sa *SockaddrHCI) sockaddr() (unsafe.Pointer, _Socklen, error) {
return unsafe.Pointer(&sa.raw), SizeofSockaddrHCI, nil
}
// SockaddrCAN implements the Sockaddr interface for AF_CAN type sockets.
// The RxID and TxID fields are used for transport protocol addressing in
// (CAN_TP16, CAN_TP20, CAN_MCNET, and CAN_ISOTP), they can be left with
// zero values for CAN_RAW and CAN_BCM sockets as they have no meaning.
//
// The SockaddrCAN struct must be bound to the socket file descriptor
// using Bind before the CAN socket can be used.
//
// // Read one raw CAN frame
// fd, _ := Socket(AF_CAN, SOCK_RAW, CAN_RAW)
// addr := &SockaddrCAN{Ifindex: index}
// Bind(fd, addr)
// frame := make([]byte, 16)
// Read(fd, frame)
//
// The full SocketCAN documentation can be found in the linux kernel
// archives at: https://www.kernel.org/doc/Documentation/networking/can.txt
type SockaddrCAN struct {
Ifindex int
RxID uint32
TxID uint32
raw RawSockaddrCAN
}
func (sa *SockaddrCAN) sockaddr() (unsafe.Pointer, _Socklen, error) {
if sa.Ifindex < 0 || sa.Ifindex > 0x7fffffff {
return nil, 0, EINVAL
}
sa.raw.Family = AF_CAN
sa.raw.Ifindex = int32(sa.Ifindex)
rx := (*[4]byte)(unsafe.Pointer(&sa.RxID))
for i := 0; i < 4; i++ {
sa.raw.Addr[i] = rx[i]
}
tx := (*[4]byte)(unsafe.Pointer(&sa.TxID))
for i := 0; i < 4; i++ {
sa.raw.Addr[i+4] = tx[i]
}
return unsafe.Pointer(&sa.raw), SizeofSockaddrCAN, nil
}
// SockaddrALG implements the Sockaddr interface for AF_ALG type sockets.
// SockaddrALG enables userspace access to the Linux kernel's cryptography
// subsystem. The Type and Name fields specify which type of hash or cipher
// should be used with a given socket.
//
// To create a file descriptor that provides access to a hash or cipher, both
// Bind and Accept must be used. Once the setup process is complete, input
// data can be written to the socket, processed by the kernel, and then read
// back as hash output or ciphertext.
//
// Here is an example of using an AF_ALG socket with SHA1 hashing.
// The initial socket setup process is as follows:
//
// // Open a socket to perform SHA1 hashing.
// fd, _ := unix.Socket(unix.AF_ALG, unix.SOCK_SEQPACKET, 0)
// addr := &unix.SockaddrALG{Type: "hash", Name: "sha1"}
// unix.Bind(fd, addr)
// // Note: unix.Accept does not work at this time; must invoke accept()
// // manually using unix.Syscall.
// hashfd, _, _ := unix.Syscall(unix.SYS_ACCEPT, uintptr(fd), 0, 0)
//
// Once a file descriptor has been returned from Accept, it may be used to
// perform SHA1 hashing. The descriptor is not safe for concurrent use, but
// may be re-used repeatedly with subsequent Write and Read operations.
//
// When hashing a small byte slice or string, a single Write and Read may
// be used:
//
// // Assume hashfd is already configured using the setup process.
// hash := os.NewFile(hashfd, "sha1")
// // Hash an input string and read the results. Each Write discards
// // previous hash state. Read always reads the current state.
// b := make([]byte, 20)
// for i := 0; i < 2; i++ {
// io.WriteString(hash, "Hello, world.")
// hash.Read(b)
// fmt.Println(hex.EncodeToString(b))
// }
// // Output:
// // 2ae01472317d1935a84797ec1983ae243fc6aa28
// // 2ae01472317d1935a84797ec1983ae243fc6aa28
//
// For hashing larger byte slices, or byte streams such as those read from
// a file or socket, use Sendto with MSG_MORE to instruct the kernel to update
// the hash digest instead of creating a new one for a given chunk and finalizing it.
//
// // Assume hashfd and addr are already configured using the setup process.
// hash := os.NewFile(hashfd, "sha1")
// // Hash the contents of a file.
// f, _ := os.Open("/tmp/linux-4.10-rc7.tar.xz")
// b := make([]byte, 4096)
// for {
// n, err := f.Read(b)
// if err == io.EOF {
// break
// }
// unix.Sendto(hashfd, b[:n], unix.MSG_MORE, addr)
// }
// hash.Read(b)
// fmt.Println(hex.EncodeToString(b))
// // Output: 85cdcad0c06eef66f805ecce353bec9accbeecc5
//
// For more information, see: http://www.chronox.de/crypto-API/crypto/userspace-if.html.
type SockaddrALG struct {
Type string
Name string
Feature uint32
Mask uint32
raw RawSockaddrALG
}
func (sa *SockaddrALG) sockaddr() (unsafe.Pointer, _Socklen, error) {
// Leave room for NUL byte terminator.
if len(sa.Type) > 13 {
return nil, 0, EINVAL
}
if len(sa.Name) > 63 {
return nil, 0, EINVAL
}
sa.raw.Family = AF_ALG
sa.raw.Feat = sa.Feature
sa.raw.Mask = sa.Mask
typ, err := ByteSliceFromString(sa.Type)
if err != nil {
return nil, 0, err
}
name, err := ByteSliceFromString(sa.Name)
if err != nil {
return nil, 0, err
}
copy(sa.raw.Type[:], typ)
copy(sa.raw.Name[:], name)
return unsafe.Pointer(&sa.raw), SizeofSockaddrALG, nil
}
// SockaddrVM implements the Sockaddr interface for AF_VSOCK type sockets.
// SockaddrVM provides access to Linux VM sockets: a mechanism that enables
// bidirectional communication between a hypervisor and its guest virtual
// machines.
type SockaddrVM struct {
// CID and Port specify a context ID and port address for a VM socket.
// Guests have a unique CID, and hosts may have a well-known CID of:
// - VMADDR_CID_HYPERVISOR: refers to the hypervisor process.
// - VMADDR_CID_HOST: refers to other processes on the host.
CID uint32
Port uint32
raw RawSockaddrVM
}
func (sa *SockaddrVM) sockaddr() (unsafe.Pointer, _Socklen, error) {
sa.raw.Family = AF_VSOCK
sa.raw.Port = sa.Port
sa.raw.Cid = sa.CID
return unsafe.Pointer(&sa.raw), SizeofSockaddrVM, nil
}
func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, error) {
switch rsa.Addr.Family {
case AF_NETLINK:
@ -476,6 +699,14 @@ func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, error) {
sa.Addr[i] = pp.Addr[i]
}
return sa, nil
case AF_VSOCK:
pp := (*RawSockaddrVM)(unsafe.Pointer(rsa))
sa := &SockaddrVM{
CID: pp.Cid,
Port: pp.Port,
}
return sa, nil
}
return nil, EAFNOSUPPORT
}
@ -570,10 +801,142 @@ func GetsockoptUcred(fd, level, opt int) (*Ucred, error) {
return &value, err
}
func GetsockoptTCPInfo(fd, level, opt int) (*TCPInfo, error) {
var value TCPInfo
vallen := _Socklen(SizeofTCPInfo)
err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
return &value, err
}
// GetsockoptString returns the string value of the socket option opt for the
// socket associated with fd at the given socket level.
func GetsockoptString(fd, level, opt int) (string, error) {
buf := make([]byte, 256)
vallen := _Socklen(len(buf))
err := getsockopt(fd, level, opt, unsafe.Pointer(&buf[0]), &vallen)
if err != nil {
if err == ERANGE {
buf = make([]byte, vallen)
err = getsockopt(fd, level, opt, unsafe.Pointer(&buf[0]), &vallen)
}
if err != nil {
return "", err
}
}
return string(buf[:vallen-1]), nil
}
func SetsockoptIPMreqn(fd, level, opt int, mreq *IPMreqn) (err error) {
return setsockopt(fd, level, opt, unsafe.Pointer(mreq), unsafe.Sizeof(*mreq))
}
// Keyctl Commands (http://man7.org/linux/man-pages/man2/keyctl.2.html)
// KeyctlInt calls keyctl commands in which each argument is an int.
// These commands are KEYCTL_REVOKE, KEYCTL_CHOWN, KEYCTL_CLEAR, KEYCTL_LINK,
// KEYCTL_UNLINK, KEYCTL_NEGATE, KEYCTL_SET_REQKEY_KEYRING, KEYCTL_SET_TIMEOUT,
// KEYCTL_ASSUME_AUTHORITY, KEYCTL_SESSION_TO_PARENT, KEYCTL_REJECT,
// KEYCTL_INVALIDATE, and KEYCTL_GET_PERSISTENT.
//sys KeyctlInt(cmd int, arg2 int, arg3 int, arg4 int, arg5 int) (ret int, err error) = SYS_KEYCTL
// KeyctlBuffer calls keyctl commands in which the third and fourth
// arguments are a buffer and its length, respectively.
// These commands are KEYCTL_UPDATE, KEYCTL_READ, and KEYCTL_INSTANTIATE.
//sys KeyctlBuffer(cmd int, arg2 int, buf []byte, arg5 int) (ret int, err error) = SYS_KEYCTL
// KeyctlString calls keyctl commands which return a string.
// These commands are KEYCTL_DESCRIBE and KEYCTL_GET_SECURITY.
func KeyctlString(cmd int, id int) (string, error) {
// We must loop as the string data may change in between the syscalls.
// We could allocate a large buffer here to reduce the chance that the
// syscall needs to be called twice; however, this is unnecessary as
// the performance loss is negligible.
var buffer []byte
for {
// Try to fill the buffer with data
length, err := KeyctlBuffer(cmd, id, buffer, 0)
if err != nil {
return "", err
}
// Check if the data was written
if length <= len(buffer) {
// Exclude the null terminator
return string(buffer[:length-1]), nil
}
// Make a bigger buffer if needed
buffer = make([]byte, length)
}
}
// Keyctl commands with special signatures.
// KeyctlGetKeyringID implements the KEYCTL_GET_KEYRING_ID command.
// See the full documentation at:
// http://man7.org/linux/man-pages/man3/keyctl_get_keyring_ID.3.html
func KeyctlGetKeyringID(id int, create bool) (ringid int, err error) {
createInt := 0
if create {
createInt = 1
}
return KeyctlInt(KEYCTL_GET_KEYRING_ID, id, createInt, 0, 0)
}
// KeyctlSetperm implements the KEYCTL_SETPERM command. The perm value is the
// key handle permission mask as described in the "keyctl setperm" section of
// http://man7.org/linux/man-pages/man1/keyctl.1.html.
// See the full documentation at:
// http://man7.org/linux/man-pages/man3/keyctl_setperm.3.html
func KeyctlSetperm(id int, perm uint32) error {
_, err := KeyctlInt(KEYCTL_SETPERM, id, int(perm), 0, 0)
return err
}
//sys keyctlJoin(cmd int, arg2 string) (ret int, err error) = SYS_KEYCTL
// KeyctlJoinSessionKeyring implements the KEYCTL_JOIN_SESSION_KEYRING command.
// See the full documentation at:
// http://man7.org/linux/man-pages/man3/keyctl_join_session_keyring.3.html
func KeyctlJoinSessionKeyring(name string) (ringid int, err error) {
return keyctlJoin(KEYCTL_JOIN_SESSION_KEYRING, name)
}
//sys keyctlSearch(cmd int, arg2 int, arg3 string, arg4 string, arg5 int) (ret int, err error) = SYS_KEYCTL
// KeyctlSearch implements the KEYCTL_SEARCH command.
// See the full documentation at:
// http://man7.org/linux/man-pages/man3/keyctl_search.3.html
func KeyctlSearch(ringid int, keyType, description string, destRingid int) (id int, err error) {
return keyctlSearch(KEYCTL_SEARCH, ringid, keyType, description, destRingid)
}
//sys keyctlIOV(cmd int, arg2 int, payload []Iovec, arg5 int) (err error) = SYS_KEYCTL
// KeyctlInstantiateIOV implements the KEYCTL_INSTANTIATE_IOV command. This
// command is similar to KEYCTL_INSTANTIATE, except that the payload is a slice
// of Iovec (each of which represents a buffer) instead of a single buffer.
// See the full documentation at:
// http://man7.org/linux/man-pages/man3/keyctl_instantiate_iov.3.html
func KeyctlInstantiateIOV(id int, payload []Iovec, ringid int) error {
return keyctlIOV(KEYCTL_INSTANTIATE_IOV, id, payload, ringid)
}
//sys keyctlDH(cmd int, arg2 *KeyctlDHParams, buf []byte) (ret int, err error) = SYS_KEYCTL
// KeyctlDHCompute implements the KEYCTL_DH_COMPUTE command. This command
// computes a Diffie-Hellman shared secret based on the provide params. The
// secret is written to the provided buffer and the returned size is the number
// of bytes written (returning an error if there is insufficient space in the
// buffer). If a nil buffer is passed in, this function returns the minimum
// buffer length needed to store the appropriate data. Note that this differs
// from KEYCTL_READ's behavior which always returns the requested payload size.
// See the full documentation at:
// http://man7.org/linux/man-pages/man3/keyctl_dh_compute.3.html
func KeyctlDHCompute(params *KeyctlDHParams, buffer []byte) (size int, err error) {
return keyctlDH(KEYCTL_DH_COMPUTE, params, buffer)
}
func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) {
var msg Msghdr
var rsa RawSockaddrAny
@ -581,17 +944,22 @@ func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from
msg.Namelen = uint32(SizeofSockaddrAny)
var iov Iovec
if len(p) > 0 {
iov.Base = (*byte)(unsafe.Pointer(&p[0]))
iov.Base = &p[0]
iov.SetLen(len(p))
}
var dummy byte
if len(oob) > 0 {
var sockType int
sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE)
if err != nil {
return
}
// receive at least one normal byte
if len(p) == 0 {
if sockType != SOCK_DGRAM && len(p) == 0 {
iov.Base = &dummy
iov.SetLen(1)
}
msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
msg.Control = &oob[0]
msg.SetControllen(len(oob))
}
msg.Iov = &iov
@ -624,21 +992,26 @@ func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error)
}
}
var msg Msghdr
msg.Name = (*byte)(unsafe.Pointer(ptr))
msg.Name = (*byte)(ptr)
msg.Namelen = uint32(salen)
var iov Iovec
if len(p) > 0 {
iov.Base = (*byte)(unsafe.Pointer(&p[0]))
iov.Base = &p[0]
iov.SetLen(len(p))
}
var dummy byte
if len(oob) > 0 {
var sockType int
sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE)
if err != nil {
return 0, err
}
// send at least one normal byte
if len(p) == 0 {
if sockType != SOCK_DGRAM && len(p) == 0 {
iov.Base = &dummy
iov.SetLen(1)
}
msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
msg.Control = &oob[0]
msg.SetControllen(len(oob))
}
msg.Iov = &iov
@ -668,7 +1041,7 @@ func ptracePeek(req int, pid int, addr uintptr, out []byte) (count int, err erro
var buf [sizeofPtr]byte
// Leading edge. PEEKTEXT/PEEKDATA don't require aligned
// Leading edge. PEEKTEXT/PEEKDATA don't require aligned
// access (PEEKUSER warns that it might), but if we don't
// align our reads, we might straddle an unmapped page
// boundary and not get the bytes leading up to the page
@ -707,6 +1080,10 @@ func PtracePeekData(pid int, addr uintptr, out []byte) (count int, err error) {
return ptracePeek(PTRACE_PEEKDATA, pid, addr, out)
}
func PtracePeekUser(pid int, addr uintptr, out []byte) (count int, err error) {
return ptracePeek(PTRACE_PEEKUSR, pid, addr, out)
}
func ptracePoke(pokeReq int, peekReq int, pid int, addr uintptr, data []byte) (count int, err error) {
// As for ptracePeek, we need to align our accesses to deal
// with the possibility of straddling an invalid page.
@ -766,6 +1143,10 @@ func PtracePokeData(pid int, addr uintptr, data []byte) (count int, err error) {
return ptracePoke(PTRACE_POKEDATA, PTRACE_PEEKDATA, pid, addr, data)
}
func PtracePokeUser(pid int, addr uintptr, data []byte) (count int, err error) {
return ptracePoke(PTRACE_POKEUSR, PTRACE_PEEKUSR, pid, addr, data)
}
func PtraceGetRegs(pid int, regsout *PtraceRegs) (err error) {
return ptrace(PTRACE_GETREGS, pid, 0, uintptr(unsafe.Pointer(regsout)))
}
@ -805,38 +1186,24 @@ func Reboot(cmd int) (err error) {
return reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd, "")
}
func clen(n []byte) int {
for i := 0; i < len(n); i++ {
if n[i] == 0 {
return i
}
}
return len(n)
}
func ReadDirent(fd int, buf []byte) (n int, err error) {
return Getdents(fd, buf)
}
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 {
dirent := (*Dirent)(unsafe.Pointer(&buf[0]))
buf = buf[dirent.Reclen:]
if dirent.Ino == 0 { // File absent in directory.
continue
}
bytes := (*[10000]byte)(unsafe.Pointer(&dirent.Name[0]))
var name = string(bytes[0:clen(bytes[:])])
if name == "." || name == ".." { // Useless names
continue
}
max--
count++
names = append(names, name)
func direntIno(buf []byte) (uint64, bool) {
return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino))
}
func direntReclen(buf []byte) (uint64, bool) {
return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
}
func direntNamlen(buf []byte) (uint64, bool) {
reclen, ok := direntReclen(buf)
if !ok {
return 0, false
}
return origlen - len(buf), count, names
return reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true
}
//sys mount(source string, target string, fstype string, flags uintptr, data *byte) (err error)
@ -862,22 +1229,24 @@ func Mount(source string, target string, fstype string, flags uintptr, data stri
* Direct access
*/
//sys Acct(path string) (err error)
//sys AddKey(keyType string, description string, payload []byte, ringid int) (id int, err error)
//sys Adjtimex(buf *Timex) (state int, err error)
//sys Chdir(path string) (err error)
//sys Chroot(path string) (err error)
//sys ClockGettime(clockid int32, time *Timespec) (err error)
//sys Close(fd int) (err error)
//sys CopyFileRange(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error)
//sys Dup(oldfd int) (fd int, err error)
//sys Dup3(oldfd int, newfd int, flags int) (err error)
//sysnb EpollCreate(size int) (fd int, err error)
//sysnb EpollCreate1(flag int) (fd int, err error)
//sysnb EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error)
//sys Eventfd(initval uint, flags int) (fd int, err error) = SYS_EVENTFD2
//sys Exit(code int) = SYS_EXIT_GROUP
//sys Faccessat(dirfd int, path string, mode uint32, flags int) (err error)
//sys Fallocate(fd int, mode uint32, off int64, len int64) (err error)
//sys Fchdir(fd int) (err error)
//sys Fchmod(fd int, mode uint32) (err error)
//sys Fchmodat(dirfd int, path string, mode uint32, flags int) (err error)
//sys Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error)
//sys fcntl(fd int, cmd int, arg int) (val int, err error)
//sys Fdatasync(fd int) (err error)
@ -894,7 +1263,9 @@ func Getpgrp() (pid int) {
//sysnb Getpid() (pid int)
//sysnb Getppid() (ppid int)
//sys Getpriority(which int, who int) (prio int, err error)
//sys Getrandom(buf []byte, flags int) (n int, err error)
//sysnb Getrusage(who int, rusage *Rusage) (err error)
//sysnb Getsid(pid int) (sid int, err error)
//sysnb Gettid() (tid int)
//sys Getxattr(path string, attr string, dest []byte) (sz int, err error)
//sys InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error)
@ -902,16 +1273,22 @@ func Getpgrp() (pid int) {
//sysnb InotifyRmWatch(fd int, watchdesc uint32) (success int, err error)
//sysnb Kill(pid int, sig syscall.Signal) (err error)
//sys Klogctl(typ int, buf []byte) (n int, err error) = SYS_SYSLOG
//sys Lgetxattr(path string, attr string, dest []byte) (sz int, err error)
//sys Listxattr(path string, dest []byte) (sz int, err error)
//sys Llistxattr(path string, dest []byte) (sz int, err error)
//sys Lremovexattr(path string, attr string) (err error)
//sys Lsetxattr(path string, attr string, data []byte, flags int) (err error)
//sys Mkdirat(dirfd int, path string, mode uint32) (err error)
//sys Mknodat(dirfd int, path string, mode uint32, dev int) (err error)
//sys Nanosleep(time *Timespec, leftover *Timespec) (err error)
//sys PivotRoot(newroot string, putold string) (err error) = SYS_PIVOT_ROOT
//sysnb prlimit(pid int, resource int, old *Rlimit, newlimit *Rlimit) (err error) = SYS_PRLIMIT64
//sysnb prlimit(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) = SYS_PRLIMIT64
//sys Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (err error)
//sys Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error) = SYS_PSELECT6
//sys read(fd int, p []byte) (n int, err error)
//sys Removexattr(path string, attr string) (err error)
//sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)
//sys RequestKey(keyType string, description string, callback string, destRingid int) (id int, err error)
//sys Setdomainname(p []byte) (err error)
//sys Sethostname(p []byte) (err error)
//sysnb Setpgid(pid int, pgid int) (err error)
@ -935,6 +1312,7 @@ func Setgid(uid int) (err error) {
//sys Setpriority(which int, who int, prio int) (err error)
//sys Setxattr(path string, attr string, data []byte, flags int) (err error)
//sys Sync()
//sys Syncfs(fd int) (err error)
//sysnb Sysinfo(info *Sysinfo_t) (err error)
//sys Tee(rfd int, wfd int, len int, flags int) (n int64, err error)
//sysnb Tgkill(tgid int, tid int, sig syscall.Signal) (err error)
@ -969,14 +1347,33 @@ func Munmap(b []byte) (err error) {
//sys Madvise(b []byte, advice int) (err error)
//sys Mprotect(b []byte, prot int) (err error)
//sys Mlock(b []byte) (err error)
//sys Munlock(b []byte) (err error)
//sys Mlockall(flags int) (err error)
//sys Msync(b []byte, flags int) (err error)
//sys Munlock(b []byte) (err error)
//sys Munlockall() (err error)
// Vmsplice splices user pages from a slice of Iovecs into a pipe specified by fd,
// using the specified flags.
func Vmsplice(fd int, iovs []Iovec, flags int) (int, error) {
n, _, errno := Syscall6(
SYS_VMSPLICE,
uintptr(fd),
uintptr(unsafe.Pointer(&iovs[0])),
uintptr(len(iovs)),
uintptr(flags),
0,
0,
)
if errno != 0 {
return 0, syscall.Errno(errno)
}
return int(n), nil
}
/*
* Unimplemented
*/
// AddKey
// AfsSyscall
// Alarm
// ArchPrctl
@ -992,7 +1389,6 @@ func Munmap(b []byte) (err error) {
// EpollCtlOld
// EpollPwait
// EpollWaitOld
// Eventfd
// Execve
// Fgetxattr
// Flistxattr
@ -1011,23 +1407,16 @@ func Munmap(b []byte) (err error) {
// IoGetevents
// IoSetup
// IoSubmit
// Ioctl
// IoprioGet
// IoprioSet
// KexecLoad
// Keyctl
// Lgetxattr
// Llistxattr
// LookupDcookie
// Lremovexattr
// Lsetxattr
// Mbind
// MigratePages
// Mincore
// ModifyLdt
// Mount
// MovePages
// Mprotect
// MqGetsetattr
// MqNotify
// MqOpen
@ -1039,12 +1428,8 @@ func Munmap(b []byte) (err error) {
// Msgget
// Msgrcv
// Msgsnd
// Msync
// Newfstatat
// Nfsservctl
// Personality
// Poll
// Ppoll
// Pselect6
// Ptrace
// Putpmsg
@ -1053,7 +1438,6 @@ func Munmap(b []byte) (err error) {
// Readahead
// Readv
// RemapFilePages
// RequestKey
// RestartSyscall
// RtSigaction
// RtSigpending
@ -1102,7 +1486,6 @@ func Munmap(b []byte) (err error) {
// Utimensat
// Vfork
// Vhangup
// Vmsplice
// Vserver
// Waitid
// _Sysctl

View File

@ -14,21 +14,12 @@ import (
"unsafe"
)
func Getpagesize() int { return 4096 }
func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
func NsecToTimespec(nsec int64) (ts Timespec) {
ts.Sec = int32(nsec / 1e9)
ts.Nsec = int32(nsec % 1e9)
return
func setTimespec(sec, nsec int64) Timespec {
return Timespec{Sec: int32(sec), Nsec: int32(nsec)}
}
func NsecToTimeval(nsec int64) (tv Timeval) {
nsec += 999 // round up to microsecond
tv.Sec = int32(nsec / 1e9)
tv.Usec = int32(nsec % 1e9 / 1e3)
return
func setTimeval(sec, usec int64) Timeval {
return Timeval{Sec: int32(sec), Usec: int32(usec)}
}
//sysnb pipe(p *[2]_C_int) (err error)
@ -63,6 +54,7 @@ func Pipe2(p []int, flags int) (err error) {
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64_64
//sys Fchown(fd int, uid int, gid int) (err error) = SYS_FCHOWN32
//sys Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64
//sys Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_FSTATAT64
//sys Ftruncate(fd int, length int64) (err error) = SYS_FTRUNCATE64
//sysnb Getegid() (egid int) = SYS_GETEGID32
//sysnb Geteuid() (euid int) = SYS_GETEUID32
@ -185,9 +177,9 @@ func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
// On x86 Linux, all the socket calls go through an extra indirection,
// I think because the 5-register system call interface can't handle
// the 6-argument calls like sendto and recvfrom. Instead the
// the 6-argument calls like sendto and recvfrom. Instead the
// arguments to the underlying system call are the number below
// and a pointer to an array of uintptr. We hide the pointer in the
// and a pointer to an array of uintptr. We hide the pointer in the
// socketcall assembly to avoid allocation on every system call.
const (
@ -388,3 +380,12 @@ func (msghdr *Msghdr) SetControllen(length int) {
func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint32(length)
}
//sys poll(fds *PollFd, nfds int, timeout int) (n int, err error)
func Poll(fds []PollFd, timeout int) (n int, err error) {
if len(fds) == 0 {
return poll(nil, 0, timeout)
}
return poll(&fds[0], len(fds), timeout)
}

View File

@ -6,13 +6,12 @@
package unix
import "syscall"
//sys Dup2(oldfd int, newfd int) (err error)
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64
//sys Fchown(fd int, uid int, gid int) (err error)
//sys Fstat(fd int, stat *Stat_t) (err error)
//sys Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_NEWFSTATAT
//sys Fstatfs(fd int, buf *Statfs_t) (err error)
//sys Ftruncate(fd int, length int64) (err error)
//sysnb Getegid() (egid int)
@ -63,9 +62,6 @@ import "syscall"
//sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error)
//sys mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error)
//go:noescape
func gettimeofday(tv *Timeval) (err syscall.Errno)
func Gettimeofday(tv *Timeval) (err error) {
errno := gettimeofday(tv)
if errno != 0 {
@ -74,8 +70,6 @@ func Gettimeofday(tv *Timeval) (err error) {
return nil
}
func Getpagesize() int { return 4096 }
func Time(t *Time_t) (tt Time_t, err error) {
var tv Timeval
errno := gettimeofday(&tv)
@ -90,19 +84,12 @@ func Time(t *Time_t) (tt Time_t, err error) {
//sys Utime(path string, buf *Utimbuf) (err error)
func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
func NsecToTimespec(nsec int64) (ts Timespec) {
ts.Sec = nsec / 1e9
ts.Nsec = nsec % 1e9
return
func setTimespec(sec, nsec int64) Timespec {
return Timespec{Sec: sec, Nsec: nsec}
}
func NsecToTimeval(nsec int64) (tv Timeval) {
nsec += 999 // round up to microsecond
tv.Sec = nsec / 1e9
tv.Usec = nsec % 1e9 / 1e3
return
func setTimeval(sec, usec int64) Timeval {
return Timeval{Sec: sec, Usec: usec}
}
//sysnb pipe(p *[2]_C_int) (err error)
@ -146,3 +133,12 @@ func (msghdr *Msghdr) SetControllen(length int) {
func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint64(length)
}
//sys poll(fds *PollFd, nfds int, timeout int) (n int, err error)
func Poll(fds []PollFd, timeout int) (n int, err error) {
if len(fds) == 0 {
return poll(nil, 0, timeout)
}
return poll(&fds[0], len(fds), timeout)
}

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

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

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