Merge pull request #417 from mlaventure/containerd-shim
Add containerd-shim runtime
This commit is contained in:
commit
3945ca3c58
248 changed files with 130459 additions and 120 deletions
9
Makefile
9
Makefile
|
@ -14,7 +14,7 @@ PACKAGES=$(shell go list ./... | grep -v /vendor/)
|
||||||
INTEGRATION_PACKAGE=${PROJECT_ROOT}/integration
|
INTEGRATION_PACKAGE=${PROJECT_ROOT}/integration
|
||||||
|
|
||||||
# Project binaries.
|
# Project binaries.
|
||||||
COMMANDS=ctr containerd protoc-gen-gogoctrd
|
COMMANDS=ctr containerd containerd-shim protoc-gen-gogoctrd
|
||||||
BINARIES=$(addprefix bin/,$(COMMANDS))
|
BINARIES=$(addprefix bin/,$(COMMANDS))
|
||||||
|
|
||||||
# TODO(stevvooe): This will set version from git tag, but overrides major,
|
# TODO(stevvooe): This will set version from git tag, but overrides major,
|
||||||
|
@ -22,7 +22,7 @@ BINARIES=$(addprefix bin/,$(COMMANDS))
|
||||||
# time.
|
# time.
|
||||||
GO_LDFLAGS=-ldflags "-X `go list`.Version=$(VERSION)"
|
GO_LDFLAGS=-ldflags "-X `go list`.Version=$(VERSION)"
|
||||||
|
|
||||||
.PHONY: clean all AUTHORS fmt vet lint build binaries test integration setup generate checkprotos coverage ci check help install uninstall
|
.PHONY: clean all AUTHORS fmt vet lint build binaries test integration setup generate checkprotos coverage ci check help install uninstall vendor
|
||||||
.DEFAULT: default
|
.DEFAULT: default
|
||||||
|
|
||||||
all: binaries
|
all: binaries
|
||||||
|
@ -128,6 +128,9 @@ coverage-integration: ## generate coverprofiles from the integration tests
|
||||||
@echo "🐳 $@"
|
@echo "🐳 $@"
|
||||||
go test -race -tags "${DOCKER_BUILDTAGS}" -test.short -coverprofile="../../../${INTEGRATION_PACKAGE}/coverage.txt" -covermode=atomic ${INTEGRATION_PACKAGE}
|
go test -race -tags "${DOCKER_BUILDTAGS}" -test.short -coverprofile="../../../${INTEGRATION_PACKAGE}/coverage.txt" -covermode=atomic ${INTEGRATION_PACKAGE}
|
||||||
|
|
||||||
|
vendor:
|
||||||
|
@echo "🐳 $@"
|
||||||
|
@vndr
|
||||||
|
|
||||||
help: ## this help
|
help: ## this help
|
||||||
@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST) | sort
|
@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST) | sort
|
||||||
|
|
||||||
|
|
56
cmd/containerd-shim/console.go
Normal file
56
cmd/containerd-shim/console.go
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
// +build !solaris
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewConsole returns an initialized console that can be used within a container by copying bytes
|
||||||
|
// from the master side to the slave that is attached as the tty for the container's init process.
|
||||||
|
func newConsole(uid, gid int) (*os.File, string, error) {
|
||||||
|
master, err := os.OpenFile("/dev/ptmx", syscall.O_RDWR|syscall.O_NOCTTY|syscall.O_CLOEXEC, 0)
|
||||||
|
if err != nil {
|
||||||
|
return nil, "", err
|
||||||
|
}
|
||||||
|
console, err := ptsname(master)
|
||||||
|
if err != nil {
|
||||||
|
return nil, "", err
|
||||||
|
}
|
||||||
|
if err := unlockpt(master); err != nil {
|
||||||
|
return nil, "", err
|
||||||
|
}
|
||||||
|
if err := os.Chmod(console, 0600); err != nil {
|
||||||
|
return nil, "", err
|
||||||
|
}
|
||||||
|
if err := os.Chown(console, uid, gid); err != nil {
|
||||||
|
return nil, "", err
|
||||||
|
}
|
||||||
|
return master, console, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ioctl(fd uintptr, flag, data uintptr) error {
|
||||||
|
if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, flag, data); err != 0 {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// unlockpt unlocks the slave pseudoterminal device corresponding to the master pseudoterminal referred to by f.
|
||||||
|
// unlockpt should be called before opening the slave side of a pty.
|
||||||
|
func unlockpt(f *os.File) error {
|
||||||
|
var u int32
|
||||||
|
return ioctl(f.Fd(), syscall.TIOCSPTLCK, uintptr(unsafe.Pointer(&u)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ptsname retrieves the name of the first available pts for the given master.
|
||||||
|
func ptsname(f *os.File) (string, error) {
|
||||||
|
var n int32
|
||||||
|
if err := ioctl(f.Fd(), syscall.TIOCGPTN, uintptr(unsafe.Pointer(&n))); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("/dev/pts/%d", n), nil
|
||||||
|
}
|
14
cmd/containerd-shim/console_solaris.go
Normal file
14
cmd/containerd-shim/console_solaris.go
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
// +build solaris
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewConsole returns an initalized console that can be used within a container by copying bytes
|
||||||
|
// from the master side to the slave that is attached as the tty for the container's init process.
|
||||||
|
func newConsole(uid, gid int) (*os.File, string, error) {
|
||||||
|
return nil, "", errors.New("newConsole not implemented on Solaris")
|
||||||
|
}
|
213
cmd/containerd-shim/main.go
Normal file
213
cmd/containerd-shim/main.go
Normal file
|
@ -0,0 +1,213 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"os/signal"
|
||||||
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
|
"github.com/docker/containerd/sys"
|
||||||
|
"github.com/docker/docker/pkg/term"
|
||||||
|
)
|
||||||
|
|
||||||
|
var logFile *os.File
|
||||||
|
|
||||||
|
func writeMessage(f *os.File, level string, err error) {
|
||||||
|
fmt.Fprintf(f, `{"level": "%s","msg": "%s"}`, level, err)
|
||||||
|
f.Sync()
|
||||||
|
}
|
||||||
|
|
||||||
|
type controlMessage struct {
|
||||||
|
Type int
|
||||||
|
Width int
|
||||||
|
Height int
|
||||||
|
}
|
||||||
|
|
||||||
|
// containerd-shim is a small shim that sits in front of a runtime implementation
|
||||||
|
// that allows it to be repartented to init and handle reattach from the caller.
|
||||||
|
//
|
||||||
|
// the cwd of the shim should be the path to the state directory where the shim
|
||||||
|
// can locate fifos and other information.
|
||||||
|
// Arg0: id of the container
|
||||||
|
// Arg1: bundle path
|
||||||
|
// Arg2: runtime binary
|
||||||
|
func main() {
|
||||||
|
flag.Parse()
|
||||||
|
cwd, err := os.Getwd()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
f, err := os.OpenFile(filepath.Join(cwd, "shim-log.json"), os.O_CREATE|os.O_WRONLY|os.O_APPEND|os.O_SYNC, 0666)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if err := start(f); err != nil {
|
||||||
|
// this means that the runtime failed starting the container and will have the
|
||||||
|
// proper error messages in the runtime log so we should to treat this as a
|
||||||
|
// shim failure because the sim executed properly
|
||||||
|
if err == errRuntime {
|
||||||
|
f.Close()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// log the error instead of writing to stderr because the shim will have
|
||||||
|
// /dev/null as it's stdio because it is supposed to be reparented to system
|
||||||
|
// init and will not have anyone to read from it
|
||||||
|
writeMessage(f, "error", err)
|
||||||
|
f.Close()
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func start(log *os.File) error {
|
||||||
|
// start handling signals as soon as possible so that things are properly reaped
|
||||||
|
// or if runtime exits before we hit the handler
|
||||||
|
signals := make(chan os.Signal, 2048)
|
||||||
|
signal.Notify(signals)
|
||||||
|
// set the shim as the subreaper for all orphaned processes created by the container
|
||||||
|
if err := sys.SetSubreaper(1); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// open the exit pipe
|
||||||
|
f, err := os.OpenFile("exit", syscall.O_WRONLY, 0)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
control, err := os.OpenFile("control", syscall.O_RDWR, 0)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer control.Close()
|
||||||
|
p, err := newProcess(flag.Arg(0), flag.Arg(1), flag.Arg(2))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
if err := p.Close(); err != nil {
|
||||||
|
writeMessage(log, "warn", err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
if err := p.create(); err != nil {
|
||||||
|
p.delete()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
msgC := make(chan controlMessage, 32)
|
||||||
|
go func() {
|
||||||
|
for {
|
||||||
|
var m controlMessage
|
||||||
|
if _, err := fmt.Fscanf(control, "%d %d %d\n", &m.Type, &m.Width, &m.Height); err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
msgC <- m
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
if runtime.GOOS == "solaris" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
var exitShim bool
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case s := <-signals:
|
||||||
|
switch s {
|
||||||
|
case syscall.SIGCHLD:
|
||||||
|
exits, _ := Reap(false)
|
||||||
|
for _, e := range exits {
|
||||||
|
// check to see if runtime is one of the processes that has exited
|
||||||
|
if e.Pid == p.pid() {
|
||||||
|
exitShim = true
|
||||||
|
writeInt("exitStatus", e.Status)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// runtime has exited so the shim can also exit
|
||||||
|
if exitShim {
|
||||||
|
// kill all processes in the container incase it was not running in
|
||||||
|
// its own PID namespace
|
||||||
|
p.killAll()
|
||||||
|
// wait for all the processes and IO to finish
|
||||||
|
p.Wait()
|
||||||
|
// delete the container from the runtime
|
||||||
|
p.delete()
|
||||||
|
// the close of the exit fifo will happen when the shim exits
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
case msg := <-msgC:
|
||||||
|
switch msg.Type {
|
||||||
|
case 0:
|
||||||
|
// close stdin
|
||||||
|
if p.stdinCloser != nil {
|
||||||
|
p.stdinCloser.Close()
|
||||||
|
}
|
||||||
|
case 1:
|
||||||
|
if p.console == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
ws := term.Winsize{
|
||||||
|
Width: uint16(msg.Width),
|
||||||
|
Height: uint16(msg.Height),
|
||||||
|
}
|
||||||
|
term.SetWinsize(p.console.Fd(), &ws)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeInt(path string, i int) error {
|
||||||
|
f, err := os.Create(path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
_, err = fmt.Fprintf(f, "%d", i)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exit is the wait4 information from an exited process
|
||||||
|
type Exit struct {
|
||||||
|
Pid int
|
||||||
|
Status int
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reap reaps all child processes for the calling process and returns their
|
||||||
|
// exit information
|
||||||
|
func Reap(wait bool) (exits []Exit, err error) {
|
||||||
|
var (
|
||||||
|
ws syscall.WaitStatus
|
||||||
|
rus syscall.Rusage
|
||||||
|
)
|
||||||
|
flag := syscall.WNOHANG
|
||||||
|
if wait {
|
||||||
|
flag = 0
|
||||||
|
}
|
||||||
|
for {
|
||||||
|
pid, err := syscall.Wait4(-1, &ws, flag, &rus)
|
||||||
|
if err != nil {
|
||||||
|
if err == syscall.ECHILD {
|
||||||
|
return exits, nil
|
||||||
|
}
|
||||||
|
return exits, err
|
||||||
|
}
|
||||||
|
if pid <= 0 {
|
||||||
|
return exits, nil
|
||||||
|
}
|
||||||
|
exits = append(exits, Exit{
|
||||||
|
Pid: pid,
|
||||||
|
Status: exitStatus(ws),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const exitSignalOffset = 128
|
||||||
|
|
||||||
|
// exitStatus returns the correct exit status for a process based on if it
|
||||||
|
// was signaled or exited cleanly
|
||||||
|
func exitStatus(status syscall.WaitStatus) int {
|
||||||
|
if status.Signaled() {
|
||||||
|
return exitSignalOffset + int(status.Signal())
|
||||||
|
}
|
||||||
|
return status.ExitStatus()
|
||||||
|
}
|
295
cmd/containerd-shim/process.go
Normal file
295
cmd/containerd-shim/process.go
Normal file
|
@ -0,0 +1,295 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
|
"strconv"
|
||||||
|
"sync"
|
||||||
|
"syscall"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
var errRuntime = errors.New("shim: runtime execution error")
|
||||||
|
|
||||||
|
type checkpoint struct {
|
||||||
|
// Timestamp is the time that checkpoint happened
|
||||||
|
Created time.Time `json:"created"`
|
||||||
|
// Name is the name of the checkpoint
|
||||||
|
Name string `json:"name"`
|
||||||
|
// TCP checkpoints open tcp connections
|
||||||
|
TCP bool `json:"tcp"`
|
||||||
|
// UnixSockets persists unix sockets in the checkpoint
|
||||||
|
UnixSockets bool `json:"unixSockets"`
|
||||||
|
// Shell persists tty sessions in the checkpoint
|
||||||
|
Shell bool `json:"shell"`
|
||||||
|
// Exit exits the container after the checkpoint is finished
|
||||||
|
Exit bool `json:"exit"`
|
||||||
|
// EmptyNS tells CRIU not to restore a particular namespace
|
||||||
|
EmptyNS []string `json:"emptyNS,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type processState struct {
|
||||||
|
Terminal bool `json:terminal`
|
||||||
|
Exec bool `json:"exec"`
|
||||||
|
Stdin string `json:"containerdStdin"`
|
||||||
|
Stdout string `json:"containerdStdout"`
|
||||||
|
Stderr string `json:"containerdStderr"`
|
||||||
|
RuntimeArgs []string `json:"runtimeArgs"`
|
||||||
|
|
||||||
|
NoPivotRoot bool `json:"noPivotRoot"`
|
||||||
|
CheckpointPath string `json:"checkpoint"`
|
||||||
|
RootUID int `json:"rootUID"`
|
||||||
|
RootGID int `json:"rootGID"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type process struct {
|
||||||
|
sync.WaitGroup
|
||||||
|
id string
|
||||||
|
bundle string
|
||||||
|
stdio *stdio
|
||||||
|
exec bool
|
||||||
|
containerPid int
|
||||||
|
checkpoint *checkpoint
|
||||||
|
checkpointPath string
|
||||||
|
shimIO *IO
|
||||||
|
stdinCloser io.Closer
|
||||||
|
console *os.File
|
||||||
|
consolePath string
|
||||||
|
state *processState
|
||||||
|
runtime string
|
||||||
|
}
|
||||||
|
|
||||||
|
func newProcess(id, bundle, runtimeName string) (*process, error) {
|
||||||
|
p := &process{
|
||||||
|
id: id,
|
||||||
|
bundle: bundle,
|
||||||
|
runtime: runtimeName,
|
||||||
|
}
|
||||||
|
s, err := loadProcess()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
p.state = s
|
||||||
|
if s.CheckpointPath != "" {
|
||||||
|
cpt, err := loadCheckpoint(s.CheckpointPath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
p.checkpoint = cpt
|
||||||
|
p.checkpointPath = s.CheckpointPath
|
||||||
|
}
|
||||||
|
if err := p.openIO(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return p, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadProcess() (*processState, error) {
|
||||||
|
f, err := os.Open("process.json")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
var s processState
|
||||||
|
if err := json.NewDecoder(f).Decode(&s); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &s, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadCheckpoint(checkpointPath string) (*checkpoint, error) {
|
||||||
|
f, err := os.Open(filepath.Join(checkpointPath, "config.json"))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
var cpt checkpoint
|
||||||
|
if err := json.NewDecoder(f).Decode(&cpt); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &cpt, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *process) create() error {
|
||||||
|
cwd, err := os.Getwd()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
logPath := filepath.Join(cwd, "log.json")
|
||||||
|
args := append([]string{
|
||||||
|
"--log", logPath,
|
||||||
|
"--log-format", "json",
|
||||||
|
}, p.state.RuntimeArgs...)
|
||||||
|
if p.state.Exec {
|
||||||
|
args = append(args, "exec",
|
||||||
|
"-d",
|
||||||
|
"--process", filepath.Join(cwd, "process.json"),
|
||||||
|
"--console", p.consolePath,
|
||||||
|
)
|
||||||
|
} else if p.checkpoint != nil {
|
||||||
|
args = append(args, "restore",
|
||||||
|
"-d",
|
||||||
|
"--image-path", p.checkpointPath,
|
||||||
|
"--work-path", filepath.Join(p.checkpointPath, "criu.work", "restore-"+time.Now().Format(time.RFC3339)),
|
||||||
|
)
|
||||||
|
add := func(flags ...string) {
|
||||||
|
args = append(args, flags...)
|
||||||
|
}
|
||||||
|
if p.checkpoint.Shell {
|
||||||
|
add("--shell-job")
|
||||||
|
}
|
||||||
|
if p.checkpoint.TCP {
|
||||||
|
add("--tcp-established")
|
||||||
|
}
|
||||||
|
if p.checkpoint.UnixSockets {
|
||||||
|
add("--ext-unix-sk")
|
||||||
|
}
|
||||||
|
if p.state.NoPivotRoot {
|
||||||
|
add("--no-pivot")
|
||||||
|
}
|
||||||
|
for _, ns := range p.checkpoint.EmptyNS {
|
||||||
|
add("--empty-ns", ns)
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
args = append(args, "create",
|
||||||
|
"--bundle", p.bundle,
|
||||||
|
"--console", p.consolePath,
|
||||||
|
)
|
||||||
|
if p.state.NoPivotRoot {
|
||||||
|
args = append(args, "--no-pivot")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
args = append(args,
|
||||||
|
"--pid-file", filepath.Join(cwd, "pid"),
|
||||||
|
p.id,
|
||||||
|
)
|
||||||
|
cmd := exec.Command(p.runtime, args...)
|
||||||
|
cmd.Dir = p.bundle
|
||||||
|
cmd.Stdin = p.stdio.stdin
|
||||||
|
cmd.Stdout = p.stdio.stdout
|
||||||
|
cmd.Stderr = p.stdio.stderr
|
||||||
|
// Call out to setPDeathSig to set SysProcAttr as elements are platform specific
|
||||||
|
cmd.SysProcAttr = setPDeathSig()
|
||||||
|
|
||||||
|
if err := cmd.Start(); err != nil {
|
||||||
|
if exErr, ok := err.(*exec.Error); ok {
|
||||||
|
if exErr.Err == exec.ErrNotFound || exErr.Err == os.ErrNotExist {
|
||||||
|
return fmt.Errorf("%s not installed on system", p.runtime)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if runtime.GOOS != "solaris" {
|
||||||
|
// Since current logic dictates that we need a pid at the end of p.create
|
||||||
|
// we need to call runtime start as well on Solaris hence we need the
|
||||||
|
// pipes to stay open.
|
||||||
|
p.stdio.stdout.Close()
|
||||||
|
p.stdio.stderr.Close()
|
||||||
|
}
|
||||||
|
if err := cmd.Wait(); err != nil {
|
||||||
|
if _, ok := err.(*exec.ExitError); ok {
|
||||||
|
return errRuntime
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
data, err := ioutil.ReadFile("pid")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
pid, err := strconv.Atoi(string(data))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
p.containerPid = pid
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *process) pid() int {
|
||||||
|
return p.containerPid
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *process) delete() error {
|
||||||
|
if !p.state.Exec {
|
||||||
|
cmd := exec.Command(p.runtime, append(p.state.RuntimeArgs, "delete", p.id)...)
|
||||||
|
cmd.SysProcAttr = setPDeathSig()
|
||||||
|
out, err := cmd.CombinedOutput()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("%s: %v", out, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// IO holds all 3 standard io Reader/Writer (stdin,stdout,stderr)
|
||||||
|
type IO struct {
|
||||||
|
Stdin io.WriteCloser
|
||||||
|
Stdout io.ReadCloser
|
||||||
|
Stderr io.ReadCloser
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *process) initializeIO(rootuid int) (i *IO, err error) {
|
||||||
|
var fds []uintptr
|
||||||
|
i = &IO{}
|
||||||
|
// cleanup in case of an error
|
||||||
|
defer func() {
|
||||||
|
if err != nil {
|
||||||
|
for _, fd := range fds {
|
||||||
|
syscall.Close(int(fd))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
// STDIN
|
||||||
|
r, w, err := os.Pipe()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
fds = append(fds, r.Fd(), w.Fd())
|
||||||
|
p.stdio.stdin, i.Stdin = r, w
|
||||||
|
// STDOUT
|
||||||
|
if r, w, err = os.Pipe(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
fds = append(fds, r.Fd(), w.Fd())
|
||||||
|
p.stdio.stdout, i.Stdout = w, r
|
||||||
|
// STDERR
|
||||||
|
if r, w, err = os.Pipe(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
fds = append(fds, r.Fd(), w.Fd())
|
||||||
|
p.stdio.stderr, i.Stderr = w, r
|
||||||
|
// change ownership of the pipes in case we are in a user namespace
|
||||||
|
for _, fd := range fds {
|
||||||
|
if err := syscall.Fchown(int(fd), rootuid, rootuid); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return i, nil
|
||||||
|
}
|
||||||
|
func (p *process) Close() error {
|
||||||
|
return p.stdio.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
type stdio struct {
|
||||||
|
stdin *os.File
|
||||||
|
stdout *os.File
|
||||||
|
stderr *os.File
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *stdio) Close() error {
|
||||||
|
err := s.stdin.Close()
|
||||||
|
if oerr := s.stdout.Close(); err == nil {
|
||||||
|
err = oerr
|
||||||
|
}
|
||||||
|
if oerr := s.stderr.Close(); err == nil {
|
||||||
|
err = oerr
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
131
cmd/containerd-shim/process_linux.go
Normal file
131
cmd/containerd-shim/process_linux.go
Normal file
|
@ -0,0 +1,131 @@
|
||||||
|
// +build !solaris
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"os/exec"
|
||||||
|
"syscall"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/tonistiigi/fifo"
|
||||||
|
"golang.org/x/net/context"
|
||||||
|
)
|
||||||
|
|
||||||
|
// setPDeathSig sets the parent death signal to SIGKILL so that if the
|
||||||
|
// shim dies the container process also dies.
|
||||||
|
func setPDeathSig() *syscall.SysProcAttr {
|
||||||
|
return &syscall.SysProcAttr{
|
||||||
|
Pdeathsig: syscall.SIGKILL,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// openIO opens the pre-created fifo's for use with the container
|
||||||
|
// in RDWR so that they remain open if the other side stops listening
|
||||||
|
func (p *process) openIO() error {
|
||||||
|
p.stdio = &stdio{}
|
||||||
|
var (
|
||||||
|
uid = p.state.RootUID
|
||||||
|
gid = p.state.RootGID
|
||||||
|
)
|
||||||
|
|
||||||
|
ctx, _ := context.WithTimeout(context.Background(), 15*time.Second)
|
||||||
|
|
||||||
|
stdinCloser, err := fifo.OpenFifo(ctx, p.state.Stdin, syscall.O_WRONLY|syscall.O_NONBLOCK, 0)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
p.stdinCloser = stdinCloser
|
||||||
|
|
||||||
|
if p.state.Terminal {
|
||||||
|
master, console, err := newConsole(uid, gid)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
p.console = master
|
||||||
|
p.consolePath = console
|
||||||
|
stdin, err := fifo.OpenFifo(ctx, p.state.Stdin, syscall.O_RDONLY, 0)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
go io.Copy(master, stdin)
|
||||||
|
stdoutw, err := fifo.OpenFifo(ctx, p.state.Stdout, syscall.O_WRONLY, 0)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
stdoutr, err := fifo.OpenFifo(ctx, p.state.Stdout, syscall.O_RDONLY, 0)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
p.Add(1)
|
||||||
|
go func() {
|
||||||
|
io.Copy(stdoutw, master)
|
||||||
|
master.Close()
|
||||||
|
stdoutr.Close()
|
||||||
|
stdoutw.Close()
|
||||||
|
p.Done()
|
||||||
|
}()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
i, err := p.initializeIO(uid)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
p.shimIO = i
|
||||||
|
// non-tty
|
||||||
|
for name, dest := range map[string]func(wc io.WriteCloser, rc io.Closer){
|
||||||
|
p.state.Stdout: func(wc io.WriteCloser, rc io.Closer) {
|
||||||
|
p.Add(1)
|
||||||
|
go func() {
|
||||||
|
io.Copy(wc, i.Stdout)
|
||||||
|
p.Done()
|
||||||
|
wc.Close()
|
||||||
|
rc.Close()
|
||||||
|
}()
|
||||||
|
},
|
||||||
|
p.state.Stderr: func(wc io.WriteCloser, rc io.Closer) {
|
||||||
|
p.Add(1)
|
||||||
|
go func() {
|
||||||
|
io.Copy(wc, i.Stderr)
|
||||||
|
p.Done()
|
||||||
|
wc.Close()
|
||||||
|
rc.Close()
|
||||||
|
}()
|
||||||
|
},
|
||||||
|
} {
|
||||||
|
fw, err := fifo.OpenFifo(ctx, name, syscall.O_WRONLY, 0)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("containerd-shim: opening %s failed: %s", name, err)
|
||||||
|
}
|
||||||
|
fr, err := fifo.OpenFifo(ctx, name, syscall.O_RDONLY, 0)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("containerd-shim: opening %s failed: %s", name, err)
|
||||||
|
}
|
||||||
|
dest(fw, fr)
|
||||||
|
}
|
||||||
|
|
||||||
|
f, err := fifo.OpenFifo(ctx, p.state.Stdin, syscall.O_RDONLY, 0)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("containerd-shim: opening %s failed: %s", p.state.Stdin, err)
|
||||||
|
}
|
||||||
|
go func() {
|
||||||
|
io.Copy(i.Stdin, f)
|
||||||
|
i.Stdin.Close()
|
||||||
|
f.Close()
|
||||||
|
}()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *process) killAll() error {
|
||||||
|
if !p.state.Exec {
|
||||||
|
cmd := exec.Command(p.runtime, append(p.state.RuntimeArgs, "kill", "--all", p.id, "SIGKILL")...)
|
||||||
|
cmd.SysProcAttr = setPDeathSig()
|
||||||
|
out, err := cmd.CombinedOutput()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("%s: %v", out, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
70
cmd/containerd-shim/process_solaris.go
Normal file
70
cmd/containerd-shim/process_solaris.go
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
// +build solaris
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"syscall"
|
||||||
|
)
|
||||||
|
|
||||||
|
// setPDeathSig is a no-op on Solaris as Pdeathsig is not defined.
|
||||||
|
func setPDeathSig() *syscall.SysProcAttr {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Update to using fifo's package in openIO. Need to
|
||||||
|
// 1. Merge and vendor changes in the package to use sys/unix.
|
||||||
|
// 2. Figure out why context.Background is timing out.
|
||||||
|
// openIO opens the pre-created fifo's for use with the container
|
||||||
|
// in RDWR so that they remain open if the other side stops listening
|
||||||
|
func (p *process) openIO() error {
|
||||||
|
p.stdio = &stdio{}
|
||||||
|
var (
|
||||||
|
uid = p.state.RootUID
|
||||||
|
)
|
||||||
|
i, err := p.initializeIO(uid)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
p.shimIO = i
|
||||||
|
// Both tty and non-tty mode are handled by the runtime using
|
||||||
|
// the following pipes
|
||||||
|
for name, dest := range map[string]func(f *os.File){
|
||||||
|
p.state.Stdout: func(f *os.File) {
|
||||||
|
p.Add(1)
|
||||||
|
go func() {
|
||||||
|
io.Copy(f, i.Stdout)
|
||||||
|
p.Done()
|
||||||
|
}()
|
||||||
|
},
|
||||||
|
p.state.Stderr: func(f *os.File) {
|
||||||
|
p.Add(1)
|
||||||
|
go func() {
|
||||||
|
io.Copy(f, i.Stderr)
|
||||||
|
p.Done()
|
||||||
|
}()
|
||||||
|
},
|
||||||
|
} {
|
||||||
|
f, err := os.OpenFile(name, syscall.O_RDWR, 0)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
dest(f)
|
||||||
|
}
|
||||||
|
|
||||||
|
f, err := os.OpenFile(p.state.Stdin, syscall.O_RDONLY, 0)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
go func() {
|
||||||
|
io.Copy(i.Stdin, f)
|
||||||
|
i.Stdin.Close()
|
||||||
|
}()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *process) killAll() error {
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -21,6 +21,7 @@ import (
|
||||||
"github.com/docker/containerd/events"
|
"github.com/docker/containerd/events"
|
||||||
"github.com/docker/containerd/execution"
|
"github.com/docker/containerd/execution"
|
||||||
"github.com/docker/containerd/execution/executors/oci"
|
"github.com/docker/containerd/execution/executors/oci"
|
||||||
|
"github.com/docker/containerd/execution/executors/shim"
|
||||||
"github.com/docker/containerd/log"
|
"github.com/docker/containerd/log"
|
||||||
metrics "github.com/docker/go-metrics"
|
metrics "github.com/docker/go-metrics"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
|
@ -103,6 +104,16 @@ high performance container runtime
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get events publisher
|
||||||
|
nec, err := getNATSPublisher(context)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer nec.Close()
|
||||||
|
ctx := log.WithModule(gocontext.Background(), "containerd")
|
||||||
|
ctx = log.WithModule(ctx, "execution")
|
||||||
|
ctx = events.WithPoster(ctx, events.GetNATSPoster(nec))
|
||||||
|
|
||||||
var (
|
var (
|
||||||
executor execution.Executor
|
executor execution.Executor
|
||||||
runtime = context.GlobalString("runtime")
|
runtime = context.GlobalString("runtime")
|
||||||
|
@ -113,20 +124,20 @@ high performance container runtime
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
case "shim":
|
||||||
|
root := filepath.Join(context.GlobalString("root"), "shim")
|
||||||
|
err = os.Mkdir(root, 0700)
|
||||||
|
if err != nil && !os.IsExist(err) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
executor, err = shim.New(log.WithModule(ctx, "shim"), root, "containerd-shim", "runc", nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("oci: runtime %q not implemented", runtime)
|
return fmt.Errorf("oci: runtime %q not implemented", runtime)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get events publisher
|
|
||||||
nec, err := getNATSPublisher(context)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer nec.Close()
|
|
||||||
|
|
||||||
ctx := log.WithModule(gocontext.Background(), "containerd")
|
|
||||||
ctx = log.WithModule(ctx, "execution")
|
|
||||||
ctx = events.WithPoster(ctx, events.GetNATSPoster(nec))
|
|
||||||
execService, err := execution.New(ctx, executor)
|
execService, err := execution.New(ctx, executor)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
50
cmd/ctr/delete.go
Normal file
50
cmd/ctr/delete.go
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
gocontext "context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/docker/containerd/api/execution"
|
||||||
|
"github.com/urfave/cli"
|
||||||
|
)
|
||||||
|
|
||||||
|
var deleteCommand = cli.Command{
|
||||||
|
Name: "delete",
|
||||||
|
Usage: "delete a process from containerd store",
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "pid, p",
|
||||||
|
Usage: "new process id",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Action: func(context *cli.Context) error {
|
||||||
|
executionService, err := getExecutionService(context)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
id := context.Args().First()
|
||||||
|
if id == "" {
|
||||||
|
return fmt.Errorf("container id must be provided")
|
||||||
|
}
|
||||||
|
|
||||||
|
pid := context.String("pid")
|
||||||
|
if pid != "" {
|
||||||
|
_, err = executionService.DeleteProcess(gocontext.Background(), &execution.DeleteProcessRequest{
|
||||||
|
ContainerID: id,
|
||||||
|
ProcessID: pid,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := executionService.Delete(gocontext.Background(), &execution.DeleteContainerRequest{
|
||||||
|
ID: id,
|
||||||
|
}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
|
@ -64,7 +64,7 @@ var execCommand = cli.Command{
|
||||||
Console: context.Bool("tty"),
|
Console: context.Bool("tty"),
|
||||||
}
|
}
|
||||||
|
|
||||||
fwg, err := prepareStdio(sOpts.Stdin, sOpts.Stdout, sOpts.Stderr)
|
fwg, err := prepareStdio(sOpts.Stdin, sOpts.Stdout, sOpts.Stderr, sOpts.Console)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,7 @@ containerd client
|
||||||
runCommand,
|
runCommand,
|
||||||
execCommand,
|
execCommand,
|
||||||
eventsCommand,
|
eventsCommand,
|
||||||
|
deleteCommand,
|
||||||
}
|
}
|
||||||
app.Before = func(context *cli.Context) error {
|
app.Before = func(context *cli.Context) error {
|
||||||
if context.GlobalBool("debug") {
|
if context.GlobalBool("debug") {
|
||||||
|
|
|
@ -85,16 +85,20 @@ var runCommand = cli.Command{
|
||||||
}
|
}
|
||||||
defer os.RemoveAll(tmpDir)
|
defer os.RemoveAll(tmpDir)
|
||||||
|
|
||||||
|
bundle, err := filepath.Abs(context.String("bundle"))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
crOpts := &execution.CreateContainerRequest{
|
crOpts := &execution.CreateContainerRequest{
|
||||||
ID: id,
|
ID: id,
|
||||||
BundlePath: context.String("bundle"),
|
BundlePath: bundle,
|
||||||
Console: context.Bool("tty"),
|
Console: context.Bool("tty"),
|
||||||
Stdin: filepath.Join(tmpDir, "stdin"),
|
Stdin: filepath.Join(tmpDir, "stdin"),
|
||||||
Stdout: filepath.Join(tmpDir, "stdout"),
|
Stdout: filepath.Join(tmpDir, "stdout"),
|
||||||
Stderr: filepath.Join(tmpDir, "stderr"),
|
Stderr: filepath.Join(tmpDir, "stderr"),
|
||||||
}
|
}
|
||||||
|
|
||||||
fwg, err := prepareStdio(crOpts.Stdin, crOpts.Stdout, crOpts.Stderr)
|
fwg, err := prepareStdio(crOpts.Stdin, crOpts.Stdout, crOpts.Stderr, crOpts.Console)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -116,7 +120,6 @@ var runCommand = cli.Command{
|
||||||
select {
|
select {
|
||||||
case e, more := <-evCh:
|
case e, more := <-evCh:
|
||||||
if !more {
|
if !more {
|
||||||
fmt.Println("No More!")
|
|
||||||
break eventLoop
|
break eventLoop
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,27 +23,11 @@ import (
|
||||||
|
|
||||||
var grpcConn *grpc.ClientConn
|
var grpcConn *grpc.ClientConn
|
||||||
|
|
||||||
func prepareStdio(in, out, err string) (*sync.WaitGroup, error) {
|
func prepareStdio(stdin, stdout, stderr string, console bool) (*sync.WaitGroup, error) {
|
||||||
var (
|
var wg sync.WaitGroup
|
||||||
wg sync.WaitGroup
|
ctx := gocontext.Background()
|
||||||
|
|
||||||
dst io.Writer
|
f, err := fifo.OpenFifo(ctx, stdin, syscall.O_WRONLY|syscall.O_CREAT|syscall.O_NONBLOCK, 0700)
|
||||||
src io.Reader
|
|
||||||
close func()
|
|
||||||
)
|
|
||||||
|
|
||||||
for _, f := range []struct {
|
|
||||||
name string
|
|
||||||
flags int
|
|
||||||
src bool
|
|
||||||
reader io.Reader
|
|
||||||
writer io.Writer
|
|
||||||
}{
|
|
||||||
{in, syscall.O_WRONLY | syscall.O_CREAT | syscall.O_NONBLOCK, false, os.Stdin, nil},
|
|
||||||
{out, syscall.O_RDONLY | syscall.O_CREAT | syscall.O_NONBLOCK, true, nil, os.Stdout},
|
|
||||||
{err, syscall.O_RDONLY | syscall.O_CREAT | syscall.O_NONBLOCK, true, nil, os.Stderr},
|
|
||||||
} {
|
|
||||||
ff, err := fifo.OpenFifo(gocontext.Background(), f.name, f.flags, 0700)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -51,26 +35,44 @@ func prepareStdio(in, out, err string) (*sync.WaitGroup, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Close()
|
c.Close()
|
||||||
}
|
}
|
||||||
}(ff)
|
}(f)
|
||||||
|
go func(w io.Writer) {
|
||||||
|
io.Copy(w, os.Stdin)
|
||||||
|
f.Close()
|
||||||
|
}(f)
|
||||||
|
|
||||||
if f.src {
|
f, err = fifo.OpenFifo(ctx, stdout, syscall.O_RDONLY|syscall.O_CREAT|syscall.O_NONBLOCK, 0700)
|
||||||
src = ff
|
if err != nil {
|
||||||
dst = f.writer
|
return nil, err
|
||||||
close = func() {
|
|
||||||
ff.Close()
|
|
||||||
wg.Done()
|
|
||||||
}
|
}
|
||||||
|
defer func(c io.Closer) {
|
||||||
|
if err != nil {
|
||||||
|
c.Close()
|
||||||
|
}
|
||||||
|
}(f)
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
} else {
|
go func(r io.Reader) {
|
||||||
src = f.reader
|
io.Copy(os.Stdout, r)
|
||||||
dst = ff
|
f.Close()
|
||||||
close = func() { ff.Close() }
|
wg.Done()
|
||||||
}
|
}(f)
|
||||||
|
|
||||||
go func(dst io.Writer, src io.Reader, close func()) {
|
f, err = fifo.OpenFifo(ctx, stderr, syscall.O_RDONLY|syscall.O_CREAT|syscall.O_NONBLOCK, 0700)
|
||||||
io.Copy(dst, src)
|
if err != nil {
|
||||||
close()
|
return nil, err
|
||||||
}(dst, src, close)
|
}
|
||||||
|
defer func(c io.Closer) {
|
||||||
|
if err != nil {
|
||||||
|
c.Close()
|
||||||
|
}
|
||||||
|
}(f)
|
||||||
|
if !console {
|
||||||
|
wg.Add(1)
|
||||||
|
go func(r io.Reader) {
|
||||||
|
io.Copy(os.Stderr, r)
|
||||||
|
f.Close()
|
||||||
|
wg.Done()
|
||||||
|
}(f)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &wg, nil
|
return &wg, nil
|
||||||
|
|
|
@ -16,12 +16,11 @@ func NewContainer(stateRoot, id, bundle string) (*Container, error) {
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func LoadContainer(dir StateDir, id, bundle string, status Status, initPid int64) *Container {
|
func LoadContainer(dir StateDir, id, bundle string, status Status) *Container {
|
||||||
return &Container{
|
return &Container{
|
||||||
id: id,
|
id: id,
|
||||||
stateDir: dir,
|
stateDir: dir,
|
||||||
bundle: bundle,
|
bundle: bundle,
|
||||||
initPid: initPid,
|
|
||||||
status: status,
|
status: status,
|
||||||
processes: make(map[string]Process),
|
processes: make(map[string]Process),
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,4 +4,7 @@ import "fmt"
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ErrProcessNotFound = fmt.Errorf("process not found")
|
ErrProcessNotFound = fmt.Errorf("process not found")
|
||||||
|
ErrProcessNotExited = fmt.Errorf("process has not exited")
|
||||||
|
ErrContainerNotFound = fmt.Errorf("container not found")
|
||||||
|
ErrContainerExists = fmt.Errorf("container already exists")
|
||||||
)
|
)
|
||||||
|
|
|
@ -28,7 +28,6 @@ type Executor interface {
|
||||||
Create(ctx context.Context, id string, o CreateOpts) (*Container, error)
|
Create(ctx context.Context, id string, o CreateOpts) (*Container, error)
|
||||||
Pause(context.Context, *Container) error
|
Pause(context.Context, *Container) error
|
||||||
Resume(context.Context, *Container) error
|
Resume(context.Context, *Container) error
|
||||||
Status(context.Context, *Container) (Status, error)
|
|
||||||
List(context.Context) ([]*Container, error)
|
List(context.Context) ([]*Container, error)
|
||||||
Load(ctx context.Context, id string) (*Container, error)
|
Load(ctx context.Context, id string) (*Container, error)
|
||||||
Delete(context.Context, *Container) error
|
Delete(context.Context, *Container) error
|
||||||
|
|
|
@ -10,6 +10,7 @@ import (
|
||||||
|
|
||||||
"github.com/crosbymichael/go-runc"
|
"github.com/crosbymichael/go-runc"
|
||||||
"github.com/docker/containerd/execution"
|
"github.com/docker/containerd/execution"
|
||||||
|
"github.com/docker/containerd/sys"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -26,10 +27,13 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
func New(root string) (*OCIRuntime, error) {
|
func New(root string) (*OCIRuntime, error) {
|
||||||
err := SetSubreaper(1)
|
err := sys.SetSubreaper(1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
go func() {
|
||||||
|
syscall.Wait4(-1, nil, 0, nil)
|
||||||
|
}()
|
||||||
return &OCIRuntime{
|
return &OCIRuntime{
|
||||||
root: root,
|
root: root,
|
||||||
runc: &runc.Runc{
|
runc: &runc.Runc{
|
||||||
|
@ -118,7 +122,6 @@ func (r *OCIRuntime) load(runcC *runc.Container) (*execution.Container, error) {
|
||||||
runcC.ID,
|
runcC.ID,
|
||||||
runcC.Bundle,
|
runcC.Bundle,
|
||||||
execution.Status(runcC.Status),
|
execution.Status(runcC.Status),
|
||||||
int64(runcC.Pid),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
dirs, err := container.StateDir().Processes()
|
dirs, err := container.StateDir().Processes()
|
||||||
|
@ -243,5 +246,6 @@ func (r *OCIRuntime) DeleteProcess(ctx context.Context, c *execution.Container,
|
||||||
ioID := fmt.Sprintf("%s-%s", c.ID(), id)
|
ioID := fmt.Sprintf("%s-%s", c.ID(), id)
|
||||||
r.ios[ioID].cleanup()
|
r.ios[ioID].cleanup()
|
||||||
delete(r.ios, ioID)
|
delete(r.ios, ioID)
|
||||||
|
c.RemoveProcess(id)
|
||||||
return c.StateDir().DeleteProcess(id)
|
return c.StateDir().DeleteProcess(id)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,43 +0,0 @@
|
||||||
package oci
|
|
||||||
|
|
||||||
import (
|
|
||||||
"syscall"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
// PR_SET_CHILD_SUBREAPER allows setting the child subreaper.
|
|
||||||
// If arg2 is nonzero, set the "child subreaper" attribute of the
|
|
||||||
// calling process; if arg2 is zero, unset the attribute. When a
|
|
||||||
// process is marked as a child subreaper, all of the children
|
|
||||||
// that it creates, and their descendants, will be marked as
|
|
||||||
// having a subreaper. In effect, a subreaper fulfills the role
|
|
||||||
// of init(1) for its descendant processes. Upon termination of
|
|
||||||
// a process that is orphaned (i.e., its immediate parent has
|
|
||||||
// already terminated) and marked as having a subreaper, the
|
|
||||||
// nearest still living ancestor subreaper will receive a SIGCHLD
|
|
||||||
// signal and be able to wait(2) on the process to discover its
|
|
||||||
// termination status.
|
|
||||||
const prSetChildSubreaper = 36
|
|
||||||
|
|
||||||
// PR_GET_CHILD_SUBREAPER allows retrieving the current child
|
|
||||||
// subreaper.
|
|
||||||
// Return the "child subreaper" setting of the caller, in the
|
|
||||||
// location pointed to by (int *) arg2.
|
|
||||||
const prGetChildSubreaper = 37
|
|
||||||
|
|
||||||
// GetSubreaper returns the subreaper setting for the calling process
|
|
||||||
func GetSubreaper() (int, error) {
|
|
||||||
var i uintptr
|
|
||||||
if _, _, err := syscall.RawSyscall(syscall.SYS_PRCTL, prGetChildSubreaper, uintptr(unsafe.Pointer(&i)), 0); err != 0 {
|
|
||||||
return -1, err
|
|
||||||
}
|
|
||||||
return int(i), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetSubreaper sets the value i as the subreaper setting for the calling process
|
|
||||||
func SetSubreaper(i int) error {
|
|
||||||
if _, _, err := syscall.RawSyscall(syscall.SYS_PRCTL, prSetChildSubreaper, uintptr(i), 0); err != 0 {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
381
execution/executors/shim/process.go
Normal file
381
execution/executors/shim/process.go
Normal file
|
@ -0,0 +1,381 @@
|
||||||
|
package shim
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"path/filepath"
|
||||||
|
"strconv"
|
||||||
|
"sync"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
|
"github.com/docker/containerd/execution"
|
||||||
|
"github.com/docker/containerd/log"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
"golang.org/x/sys/unix"
|
||||||
|
|
||||||
|
runc "github.com/crosbymichael/go-runc"
|
||||||
|
starttime "github.com/opencontainers/runc/libcontainer/system"
|
||||||
|
)
|
||||||
|
|
||||||
|
type newProcessOpts struct {
|
||||||
|
shimBinary string
|
||||||
|
runtime string
|
||||||
|
runtimeArgs []string
|
||||||
|
container *execution.Container
|
||||||
|
exec bool
|
||||||
|
execution.StartProcessOpts
|
||||||
|
}
|
||||||
|
|
||||||
|
func newProcess(ctx context.Context, o newProcessOpts) (*process, error) {
|
||||||
|
procStateDir, err := o.container.StateDir().NewProcess(o.ID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
exitPipe, controlPipe, err := getControlPipes(procStateDir)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
if err != nil {
|
||||||
|
exitPipe.Close()
|
||||||
|
controlPipe.Close()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
cmd, err := newShim(o, procStateDir)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
if err != nil {
|
||||||
|
cmd.Process.Kill()
|
||||||
|
cmd.Wait()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
abortCh := make(chan syscall.WaitStatus, 1)
|
||||||
|
go func() {
|
||||||
|
var shimStatus syscall.WaitStatus
|
||||||
|
if err := cmd.Wait(); err != nil {
|
||||||
|
shimStatus = execution.UnknownStatusCode
|
||||||
|
} else {
|
||||||
|
shimStatus = cmd.ProcessState.Sys().(syscall.WaitStatus)
|
||||||
|
}
|
||||||
|
abortCh <- shimStatus
|
||||||
|
close(abortCh)
|
||||||
|
}()
|
||||||
|
|
||||||
|
process := &process{
|
||||||
|
root: procStateDir,
|
||||||
|
id: o.ID,
|
||||||
|
exitChan: make(chan struct{}),
|
||||||
|
exitPipe: exitPipe,
|
||||||
|
controlPipe: controlPipe,
|
||||||
|
}
|
||||||
|
|
||||||
|
pid, stime, status, err := waitForPid(ctx, abortCh, procStateDir)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
process.pid = int64(pid)
|
||||||
|
process.status = status
|
||||||
|
process.startTime = stime
|
||||||
|
|
||||||
|
return process, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadProcess(root, id string) (*process, error) {
|
||||||
|
pid, err := runc.ReadPidFile(filepath.Join(root, pidFilename))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
stime, err := ioutil.ReadFile(filepath.Join(root, startTimeFilename))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
path := filepath.Join(root, exitPipeFilename)
|
||||||
|
exitPipe, err := os.OpenFile(path, syscall.O_RDONLY|syscall.O_NONBLOCK, 0)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
if err != nil {
|
||||||
|
exitPipe.Close()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
path = filepath.Join(root, controlPipeFilename)
|
||||||
|
controlPipe, err := os.OpenFile(path, syscall.O_RDWR|syscall.O_NONBLOCK, 0)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
if err != nil {
|
||||||
|
controlPipe.Close()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
p := &process{
|
||||||
|
root: root,
|
||||||
|
id: id,
|
||||||
|
pid: int64(pid),
|
||||||
|
exitChan: make(chan struct{}),
|
||||||
|
exitPipe: exitPipe,
|
||||||
|
controlPipe: controlPipe,
|
||||||
|
startTime: string(stime),
|
||||||
|
// TODO: status may need to be stored on disk to handle
|
||||||
|
// Created state for init (i.e. a Start is needed to run the
|
||||||
|
// container)
|
||||||
|
status: execution.Running,
|
||||||
|
}
|
||||||
|
|
||||||
|
markAsStopped := func(p *process) (*process, error) {
|
||||||
|
p.setStatus(execution.Stopped)
|
||||||
|
return p, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = syscall.Kill(pid, 0); err != nil {
|
||||||
|
if err == syscall.ESRCH {
|
||||||
|
return markAsStopped(p)
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
cstime, err := starttime.GetProcessStartTime(pid)
|
||||||
|
if err != nil {
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
return markAsStopped(p)
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.startTime != cstime {
|
||||||
|
return markAsStopped(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
return p, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type process struct {
|
||||||
|
root string
|
||||||
|
id string
|
||||||
|
pid int64
|
||||||
|
exitChan chan struct{}
|
||||||
|
exitPipe *os.File
|
||||||
|
controlPipe *os.File
|
||||||
|
startTime string
|
||||||
|
status execution.Status
|
||||||
|
ctx context.Context
|
||||||
|
mu sync.Mutex
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *process) ID() string {
|
||||||
|
return p.id
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *process) Pid() int64 {
|
||||||
|
return p.pid
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *process) Wait() (uint32, error) {
|
||||||
|
<-p.exitChan
|
||||||
|
|
||||||
|
log.G(p.ctx).WithFields(logrus.Fields{"process-id": p.ID(), "pid": p.pid}).
|
||||||
|
Debugf("wait is over")
|
||||||
|
|
||||||
|
// Cleanup those fds
|
||||||
|
p.exitPipe.Close()
|
||||||
|
p.controlPipe.Close()
|
||||||
|
|
||||||
|
// If the container process is still alive, it means the shim crashed
|
||||||
|
// and the child process had updated it PDEATHSIG to something
|
||||||
|
// else than SIGKILL. Or that epollCtl failed
|
||||||
|
if p.isAlive() {
|
||||||
|
err := syscall.Kill(int(p.pid), syscall.SIGKILL)
|
||||||
|
if err != nil {
|
||||||
|
return execution.UnknownStatusCode, errors.Wrap(err, "failed to kill process")
|
||||||
|
}
|
||||||
|
|
||||||
|
return uint32(128 + int(syscall.SIGKILL)), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := ioutil.ReadFile(filepath.Join(p.root, exitStatusFilename))
|
||||||
|
if err != nil {
|
||||||
|
return execution.UnknownStatusCode, errors.Wrap(err, "failed to read process exit status")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(data) == 0 {
|
||||||
|
return execution.UnknownStatusCode, errors.New(execution.ErrProcessNotExited.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
status, err := strconv.Atoi(string(data))
|
||||||
|
if err != nil {
|
||||||
|
return execution.UnknownStatusCode, errors.Wrapf(err, "failed to parse exit status")
|
||||||
|
}
|
||||||
|
|
||||||
|
p.setStatus(execution.Stopped)
|
||||||
|
return uint32(status), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *process) Signal(sig os.Signal) error {
|
||||||
|
err := syscall.Kill(int(p.pid), sig.(syscall.Signal))
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "failed to signal process")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *process) Status() execution.Status {
|
||||||
|
p.mu.Lock()
|
||||||
|
s := p.status
|
||||||
|
p.mu.Unlock()
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *process) setStatus(s execution.Status) {
|
||||||
|
p.mu.Lock()
|
||||||
|
p.status = s
|
||||||
|
p.mu.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *process) isAlive() bool {
|
||||||
|
if err := syscall.Kill(int(p.pid), 0); err != nil {
|
||||||
|
if err == syscall.ESRCH {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
log.G(p.ctx).WithFields(logrus.Fields{"process-id": p.ID(), "pid": p.pid}).
|
||||||
|
Warnf("kill(0) failed: %v", err)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// check that we have the same startttime
|
||||||
|
stime, err := starttime.GetProcessStartTime(int(p.pid))
|
||||||
|
if err != nil {
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
log.G(p.ctx).WithFields(logrus.Fields{"process-id": p.ID(), "pid": p.pid}).
|
||||||
|
Warnf("failed to get process start time: %v", err)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.startTime != stime {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func waitForPid(ctx context.Context, abortCh chan syscall.WaitStatus, root string) (pid int, stime string, status execution.Status, err error) {
|
||||||
|
status = execution.Unknown
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
return
|
||||||
|
case wait := <-abortCh:
|
||||||
|
if wait.Signaled() {
|
||||||
|
err = errors.Errorf("shim died prematurarily: %v", wait.Signal())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = errors.Errorf("shim exited prematurarily with exit code %v", wait.ExitStatus())
|
||||||
|
return
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
pid, err = runc.ReadPidFile(filepath.Join(root, pidFilename))
|
||||||
|
if err == nil {
|
||||||
|
break
|
||||||
|
} else if !os.IsNotExist(err) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
status = execution.Created
|
||||||
|
stime, err = starttime.GetProcessStartTime(pid)
|
||||||
|
switch {
|
||||||
|
case os.IsNotExist(err):
|
||||||
|
status = execution.Stopped
|
||||||
|
case err != nil:
|
||||||
|
return
|
||||||
|
default:
|
||||||
|
var b []byte
|
||||||
|
path := filepath.Join(root, startTimeFilename)
|
||||||
|
b, err = ioutil.ReadFile(path)
|
||||||
|
switch {
|
||||||
|
case os.IsNotExist(err):
|
||||||
|
err = ioutil.WriteFile(path, []byte(stime), 0600)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
case err != nil:
|
||||||
|
err = errors.Wrapf(err, "failed to get start time for pid %d", pid)
|
||||||
|
return
|
||||||
|
case string(b) != stime:
|
||||||
|
status = execution.Stopped
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return pid, stime, status, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func newShim(o newProcessOpts, workDir string) (*exec.Cmd, error) {
|
||||||
|
cmd := exec.Command(o.shimBinary, o.container.ID(), o.container.Bundle(), o.runtime)
|
||||||
|
cmd.Dir = workDir
|
||||||
|
cmd.SysProcAttr = &syscall.SysProcAttr{
|
||||||
|
Setpgid: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
state := processState{
|
||||||
|
Process: o.Spec,
|
||||||
|
Exec: o.exec,
|
||||||
|
Stdin: o.Stdin,
|
||||||
|
Stdout: o.Stdout,
|
||||||
|
Stderr: o.Stderr,
|
||||||
|
RuntimeArgs: o.runtimeArgs,
|
||||||
|
NoPivotRoot: false,
|
||||||
|
CheckpointPath: "",
|
||||||
|
RootUID: int(o.Spec.User.UID),
|
||||||
|
RootGID: int(o.Spec.User.GID),
|
||||||
|
}
|
||||||
|
|
||||||
|
f, err := os.Create(filepath.Join(workDir, "process.json"))
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "failed to create shim's process.json for container %s", o.container.ID())
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
if err := json.NewEncoder(f).Encode(state); err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "failed to create shim's processState for container %s", o.container.ID())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := cmd.Start(); err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "failed to start shim for container %s", o.container.ID())
|
||||||
|
}
|
||||||
|
|
||||||
|
return cmd, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getControlPipes(root string) (exitPipe *os.File, controlPipe *os.File, err error) {
|
||||||
|
path := filepath.Join(root, exitPipeFilename)
|
||||||
|
if err = unix.Mkfifo(path, 0700); err != nil {
|
||||||
|
return exitPipe, controlPipe, errors.Wrap(err, "failed to create shim exit fifo")
|
||||||
|
}
|
||||||
|
if exitPipe, err = os.OpenFile(path, syscall.O_RDONLY|syscall.O_NONBLOCK, 0); err != nil {
|
||||||
|
return exitPipe, controlPipe, errors.Wrap(err, "failed to open shim exit fifo")
|
||||||
|
}
|
||||||
|
|
||||||
|
path = filepath.Join(root, controlPipeFilename)
|
||||||
|
if err = unix.Mkfifo(path, 0700); err != nil {
|
||||||
|
return exitPipe, controlPipe, errors.Wrap(err, "failed to create shim control fifo")
|
||||||
|
}
|
||||||
|
if controlPipe, err = os.OpenFile(path, syscall.O_RDWR|syscall.O_NONBLOCK, 0); err != nil {
|
||||||
|
return exitPipe, controlPipe, errors.Wrap(err, "failed to open shim control fifo")
|
||||||
|
}
|
||||||
|
|
||||||
|
return exitPipe, controlPipe, nil
|
||||||
|
}
|
420
execution/executors/shim/shim.go
Normal file
420
execution/executors/shim/shim.go
Normal file
|
@ -0,0 +1,420 @@
|
||||||
|
package shim
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"path/filepath"
|
||||||
|
"sync"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
|
"github.com/docker/containerd/execution"
|
||||||
|
"github.com/docker/containerd/log"
|
||||||
|
"github.com/opencontainers/runtime-spec/specs-go"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
DefaultShimBinary = "containerd-shim"
|
||||||
|
|
||||||
|
pidFilename = "pid"
|
||||||
|
startTimeFilename = "starttime"
|
||||||
|
exitPipeFilename = "exit"
|
||||||
|
controlPipeFilename = "control"
|
||||||
|
initProcessID = "init"
|
||||||
|
exitStatusFilename = "exitStatus"
|
||||||
|
)
|
||||||
|
|
||||||
|
func New(ctx context.Context, root, shim, runtime string, runtimeArgs []string) (*ShimRuntime, error) {
|
||||||
|
fd, err := syscall.EpollCreate1(0)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "epollcreate1 failed")
|
||||||
|
}
|
||||||
|
s := &ShimRuntime{
|
||||||
|
ctx: ctx,
|
||||||
|
epollFd: fd,
|
||||||
|
root: root,
|
||||||
|
binaryName: shim,
|
||||||
|
runtime: runtime,
|
||||||
|
runtimeArgs: runtimeArgs,
|
||||||
|
exitChannels: make(map[int]*process),
|
||||||
|
containers: make(map[string]*execution.Container),
|
||||||
|
}
|
||||||
|
|
||||||
|
s.loadContainers()
|
||||||
|
|
||||||
|
go s.monitor()
|
||||||
|
|
||||||
|
return s, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type ShimRuntime struct {
|
||||||
|
ctx context.Context
|
||||||
|
|
||||||
|
mutex sync.Mutex
|
||||||
|
exitChannels map[int]*process
|
||||||
|
containers map[string]*execution.Container
|
||||||
|
|
||||||
|
epollFd int
|
||||||
|
root string
|
||||||
|
binaryName string
|
||||||
|
runtime string
|
||||||
|
runtimeArgs []string
|
||||||
|
}
|
||||||
|
|
||||||
|
type ProcessOpts struct {
|
||||||
|
Bundle string
|
||||||
|
Terminal bool
|
||||||
|
Stdin string
|
||||||
|
Stdout string
|
||||||
|
Stderr string
|
||||||
|
}
|
||||||
|
|
||||||
|
type processState struct {
|
||||||
|
specs.Process
|
||||||
|
Exec bool `json:"exec"`
|
||||||
|
Stdin string `json:"containerdStdin"`
|
||||||
|
Stdout string `json:"containerdStdout"`
|
||||||
|
Stderr string `json:"containerdStderr"`
|
||||||
|
RuntimeArgs []string `json:"runtimeArgs"`
|
||||||
|
NoPivotRoot bool `json:"noPivotRoot"`
|
||||||
|
CheckpointPath string `json:"checkpoint"`
|
||||||
|
RootUID int `json:"rootUID"`
|
||||||
|
RootGID int `json:"rootGID"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ShimRuntime) Create(ctx context.Context, id string, o execution.CreateOpts) (*execution.Container, error) {
|
||||||
|
log.G(s.ctx).WithFields(logrus.Fields{"container-id": id, "options": o}).Debug("Create()")
|
||||||
|
|
||||||
|
if s.getContainer(id) != nil {
|
||||||
|
return nil, execution.ErrContainerExists
|
||||||
|
}
|
||||||
|
|
||||||
|
container, err := execution.NewContainer(s.root, id, o.Bundle)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
if err != nil {
|
||||||
|
container.StateDir().Delete()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
err = ioutil.WriteFile(filepath.Join(string(container.StateDir()), "bundle"), []byte(o.Bundle), 0600)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "failed to save bundle path to disk")
|
||||||
|
}
|
||||||
|
|
||||||
|
// extract Process spec from bundle's config.json
|
||||||
|
var spec specs.Spec
|
||||||
|
f, err := os.Open(filepath.Join(o.Bundle, "config.json"))
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "failed to open config.json")
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
if err := json.NewDecoder(f).Decode(&spec); err != nil {
|
||||||
|
return nil, errors.Wrap(err, "failed to decode container OCI specs")
|
||||||
|
}
|
||||||
|
|
||||||
|
processOpts := newProcessOpts{
|
||||||
|
shimBinary: s.binaryName,
|
||||||
|
runtime: s.runtime,
|
||||||
|
runtimeArgs: s.runtimeArgs,
|
||||||
|
container: container,
|
||||||
|
exec: false,
|
||||||
|
StartProcessOpts: execution.StartProcessOpts{
|
||||||
|
ID: initProcessID,
|
||||||
|
Spec: spec.Process,
|
||||||
|
Console: o.Console,
|
||||||
|
Stdin: o.Stdin,
|
||||||
|
Stdout: o.Stdout,
|
||||||
|
Stderr: o.Stderr,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
process, err := newProcess(ctx, processOpts)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
process.ctx = log.WithModule(log.WithModule(s.ctx, "container"), id)
|
||||||
|
|
||||||
|
s.monitorProcess(process)
|
||||||
|
container.AddProcess(process, true)
|
||||||
|
|
||||||
|
s.addContainer(container)
|
||||||
|
|
||||||
|
return container, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ShimRuntime) Start(ctx context.Context, c *execution.Container) error {
|
||||||
|
log.G(s.ctx).WithFields(logrus.Fields{"container": c}).Debug("Start()")
|
||||||
|
|
||||||
|
cmd := exec.CommandContext(ctx, s.runtime, append(s.runtimeArgs, "start", c.ID())...)
|
||||||
|
out, err := cmd.CombinedOutput()
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrapf(err, "'%s start' failed with output: %v", s.runtime, string(out))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ShimRuntime) List(ctx context.Context) ([]*execution.Container, error) {
|
||||||
|
log.G(s.ctx).Debug("List()")
|
||||||
|
|
||||||
|
containers := make([]*execution.Container, 0)
|
||||||
|
s.mutex.Lock()
|
||||||
|
for _, c := range s.containers {
|
||||||
|
containers = append(containers, c)
|
||||||
|
}
|
||||||
|
s.mutex.Unlock()
|
||||||
|
|
||||||
|
return containers, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ShimRuntime) Load(ctx context.Context, id string) (*execution.Container, error) {
|
||||||
|
log.G(s.ctx).WithFields(logrus.Fields{"container-id": id}).Debug("Start()")
|
||||||
|
|
||||||
|
s.mutex.Lock()
|
||||||
|
c, ok := s.containers[id]
|
||||||
|
s.mutex.Unlock()
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
return nil, errors.New(execution.ErrContainerNotFound.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
return c, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ShimRuntime) Delete(ctx context.Context, c *execution.Container) error {
|
||||||
|
log.G(s.ctx).WithFields(logrus.Fields{"container": c}).Debug("Delete()")
|
||||||
|
|
||||||
|
if c.Status() != execution.Stopped {
|
||||||
|
return errors.Errorf("cannot delete a container in the '%s' state", c.Status())
|
||||||
|
}
|
||||||
|
|
||||||
|
c.StateDir().Delete()
|
||||||
|
s.removeContainer(c)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ShimRuntime) Pause(ctx context.Context, c *execution.Container) error {
|
||||||
|
log.G(s.ctx).WithFields(logrus.Fields{"container": c}).Debug("Pause()")
|
||||||
|
|
||||||
|
cmd := exec.CommandContext(ctx, s.runtime, append(s.runtimeArgs, "pause", c.ID())...)
|
||||||
|
out, err := cmd.CombinedOutput()
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrapf(err, "'%s pause' failed with output: %v", s.runtime, string(out))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ShimRuntime) Resume(ctx context.Context, c *execution.Container) error {
|
||||||
|
log.G(s.ctx).WithFields(logrus.Fields{"container": c}).Debug("Resume()")
|
||||||
|
|
||||||
|
cmd := exec.CommandContext(ctx, s.runtime, append(s.runtimeArgs, "resume", c.ID())...)
|
||||||
|
out, err := cmd.CombinedOutput()
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrapf(err, "'%s resume' failed with output: %v", s.runtime, string(out))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ShimRuntime) StartProcess(ctx context.Context, c *execution.Container, o execution.StartProcessOpts) (p execution.Process, err error) {
|
||||||
|
log.G(s.ctx).WithFields(logrus.Fields{"container": c, "options": o}).Debug("StartProcess()")
|
||||||
|
|
||||||
|
processOpts := newProcessOpts{
|
||||||
|
shimBinary: s.binaryName,
|
||||||
|
runtime: s.runtime,
|
||||||
|
runtimeArgs: s.runtimeArgs,
|
||||||
|
container: c,
|
||||||
|
exec: true,
|
||||||
|
StartProcessOpts: o,
|
||||||
|
}
|
||||||
|
process, err := newProcess(ctx, processOpts)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
process.status = execution.Running
|
||||||
|
s.monitorProcess(process)
|
||||||
|
|
||||||
|
c.AddProcess(process, false)
|
||||||
|
return process, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ShimRuntime) SignalProcess(ctx context.Context, c *execution.Container, id string, sig os.Signal) error {
|
||||||
|
log.G(s.ctx).WithFields(logrus.Fields{"container": c, "process-id": id, "signal": sig}).
|
||||||
|
Debug("SignalProcess()")
|
||||||
|
|
||||||
|
process := c.GetProcess(id)
|
||||||
|
if process == nil {
|
||||||
|
return errors.Errorf("no such process %s", id)
|
||||||
|
}
|
||||||
|
err := syscall.Kill(int(process.Pid()), sig.(syscall.Signal))
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrapf(err, "failed to send %v signal to process %v", sig, process.Pid())
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ShimRuntime) DeleteProcess(ctx context.Context, c *execution.Container, id string) error {
|
||||||
|
log.G(s.ctx).WithFields(logrus.Fields{"container": c, "process-id": id}).
|
||||||
|
Debug("DeleteProcess()")
|
||||||
|
|
||||||
|
c.RemoveProcess(id)
|
||||||
|
return c.StateDir().DeleteProcess(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
func (s *ShimRuntime) monitor() {
|
||||||
|
var events [128]syscall.EpollEvent
|
||||||
|
for {
|
||||||
|
n, err := syscall.EpollWait(s.epollFd, events[:], -1)
|
||||||
|
if err != nil {
|
||||||
|
if err == syscall.EINTR {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
log.G(s.ctx).Error("epollwait failed:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
|
fd := int(events[i].Fd)
|
||||||
|
|
||||||
|
s.mutex.Lock()
|
||||||
|
p := s.exitChannels[fd]
|
||||||
|
delete(s.exitChannels, fd)
|
||||||
|
s.mutex.Unlock()
|
||||||
|
|
||||||
|
if err = syscall.EpollCtl(s.epollFd, syscall.EPOLL_CTL_DEL, fd, &syscall.EpollEvent{
|
||||||
|
Events: syscall.EPOLLHUP,
|
||||||
|
Fd: int32(fd),
|
||||||
|
}); err != nil {
|
||||||
|
log.G(s.ctx).Error("epollctl deletion failed:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
close(p.exitChan)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ShimRuntime) addContainer(c *execution.Container) {
|
||||||
|
s.mutex.Lock()
|
||||||
|
s.containers[c.ID()] = c
|
||||||
|
s.mutex.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ShimRuntime) removeContainer(c *execution.Container) {
|
||||||
|
s.mutex.Lock()
|
||||||
|
delete(s.containers, c.ID())
|
||||||
|
s.mutex.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ShimRuntime) getContainer(id string) *execution.Container {
|
||||||
|
s.mutex.Lock()
|
||||||
|
c := s.containers[id]
|
||||||
|
s.mutex.Unlock()
|
||||||
|
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// monitorProcess adds a process to the list of monitored process if
|
||||||
|
// we fail to do so, we closed the exitChan channel used by Wait().
|
||||||
|
// Since service always call on Wait() for generating "exit" events,
|
||||||
|
// this will ensure the process gets killed
|
||||||
|
func (s *ShimRuntime) monitorProcess(p *process) {
|
||||||
|
if p.status == execution.Stopped {
|
||||||
|
close(p.exitChan)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fd := int(p.exitPipe.Fd())
|
||||||
|
event := syscall.EpollEvent{
|
||||||
|
Fd: int32(fd),
|
||||||
|
Events: syscall.EPOLLHUP,
|
||||||
|
}
|
||||||
|
s.mutex.Lock()
|
||||||
|
s.exitChannels[fd] = p
|
||||||
|
s.mutex.Unlock()
|
||||||
|
if err := syscall.EpollCtl(s.epollFd, syscall.EPOLL_CTL_ADD, fd, &event); err != nil {
|
||||||
|
s.mutex.Lock()
|
||||||
|
delete(s.exitChannels, fd)
|
||||||
|
s.mutex.Unlock()
|
||||||
|
close(p.exitChan)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: take care of the OOM handler
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ShimRuntime) unmonitorProcess(p *process) {
|
||||||
|
s.mutex.Lock()
|
||||||
|
for fd, proc := range s.exitChannels {
|
||||||
|
if proc == p {
|
||||||
|
delete(s.exitChannels, fd)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.mutex.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ShimRuntime) loadContainers() {
|
||||||
|
cs, err := ioutil.ReadDir(s.root)
|
||||||
|
if err != nil {
|
||||||
|
log.G(s.ctx).WithField("statedir", s.root).
|
||||||
|
Warn("failed to load containers, state dir cannot be listed:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, c := range cs {
|
||||||
|
if !c.IsDir() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
stateDir, err := execution.LoadStateDir(s.root, c.Name())
|
||||||
|
if err != nil {
|
||||||
|
// We should never fail the above call unless someone
|
||||||
|
// delete the directory while we're loading
|
||||||
|
log.G(s.ctx).WithFields(logrus.Fields{"container": c.Name(), "statedir": s.root}).
|
||||||
|
Warn("failed to load container statedir:", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
bundle, err := ioutil.ReadFile(filepath.Join(string(stateDir), "bundle"))
|
||||||
|
if err != nil {
|
||||||
|
log.G(s.ctx).WithField("container", c.Name()).
|
||||||
|
Warn("failed to load container bundle path:", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
container := execution.LoadContainer(stateDir, c.Name(), string(bundle), execution.Unknown)
|
||||||
|
s.addContainer(container)
|
||||||
|
|
||||||
|
processDirs, err := stateDir.Processes()
|
||||||
|
if err != nil {
|
||||||
|
log.G(s.ctx).WithField("container", c.Name()).
|
||||||
|
Warn("failed to retrieve container processes:", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, procStateRoot := range processDirs {
|
||||||
|
id := filepath.Base(procStateRoot)
|
||||||
|
proc, err := loadProcess(procStateRoot, id)
|
||||||
|
if err != nil {
|
||||||
|
log.G(s.ctx).WithFields(logrus.Fields{"container": c.Name(), "process": id}).
|
||||||
|
Warn("failed to load process:", err)
|
||||||
|
s.removeContainer(container)
|
||||||
|
for _, p := range container.Processes() {
|
||||||
|
s.unmonitorProcess(p.(*process))
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
proc.ctx = log.WithModule(log.WithModule(s.ctx, "container"), container.ID())
|
||||||
|
container.AddProcess(proc, proc.ID() == initProcessID)
|
||||||
|
s.monitorProcess(proc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -31,11 +31,11 @@ func New(ctx context.Context, executor Executor) (*Service, error) {
|
||||||
|
|
||||||
for _, c := range containers {
|
for _, c := range containers {
|
||||||
status := c.Status()
|
status := c.Status()
|
||||||
if status == Stopped || status == Deleted {
|
|
||||||
// generate exit event for all processes, (generate event for init last)
|
// generate exit event for all processes, (generate event for init last)
|
||||||
processes := c.Processes()
|
processes := c.Processes()
|
||||||
processes = append(processes[1:], processes[0])
|
processes = append(processes[1:], processes[0])
|
||||||
for _, p := range processes {
|
for _, p := range c.processes {
|
||||||
|
if status == Stopped || status == Deleted {
|
||||||
if p.Status() != Stopped {
|
if p.Status() != Stopped {
|
||||||
p.Signal(os.Kill)
|
p.Signal(os.Kill)
|
||||||
}
|
}
|
||||||
|
@ -53,6 +53,8 @@ func New(ctx context.Context, executor Executor) (*Service, error) {
|
||||||
PID: p.ID(),
|
PID: p.ID(),
|
||||||
StatusCode: sc,
|
StatusCode: sc,
|
||||||
})
|
})
|
||||||
|
} else {
|
||||||
|
svc.monitorProcess(ctx, c, p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -156,7 +158,6 @@ func (s *Service) StartProcess(ctx context.Context, r *api.StartProcessRequest)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: generate spec
|
|
||||||
spec := specs.Process{
|
spec := specs.Process{
|
||||||
Terminal: r.Process.Terminal,
|
Terminal: r.Process.Terminal,
|
||||||
ConsoleSize: specs.Box{
|
ConsoleSize: specs.Box{
|
||||||
|
|
|
@ -4,32 +4,46 @@ import (
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
const processesDirName = "processes"
|
const processesDirName = "processes"
|
||||||
|
|
||||||
type StateDir string
|
type StateDir string
|
||||||
|
|
||||||
|
func LoadStateDir(root, id string) (StateDir, error) {
|
||||||
|
path := filepath.Join(root, id)
|
||||||
|
if _, err := os.Stat(path); err != nil {
|
||||||
|
return "", errors.Wrap(err, "could not find container statedir")
|
||||||
|
}
|
||||||
|
return StateDir(path), nil
|
||||||
|
}
|
||||||
|
|
||||||
func NewStateDir(root, id string) (StateDir, error) {
|
func NewStateDir(root, id string) (StateDir, error) {
|
||||||
path := filepath.Join(root, id)
|
path := filepath.Join(root, id)
|
||||||
if err := os.Mkdir(path, 0700); err != nil {
|
if err := os.Mkdir(path, 0700); err != nil {
|
||||||
return "", err
|
return "", errors.Wrap(err, "could not create container statedir")
|
||||||
}
|
}
|
||||||
if err := os.Mkdir(StateDir(path).processesDir(), 0700); err != nil {
|
if err := os.Mkdir(StateDir(path).processesDir(), 0700); err != nil {
|
||||||
os.RemoveAll(path)
|
os.RemoveAll(path)
|
||||||
return "", err
|
return "", errors.Wrap(err, "could not create processes statedir")
|
||||||
}
|
}
|
||||||
return StateDir(path), nil
|
return StateDir(path), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s StateDir) Delete() error {
|
func (s StateDir) Delete() error {
|
||||||
return os.RemoveAll(string(s))
|
err := os.RemoveAll(string(s))
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrapf(err, "failed to remove statedir %s", string(s))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s StateDir) NewProcess(id string) (dir string, err error) {
|
func (s StateDir) NewProcess(id string) (dir string, err error) {
|
||||||
dir = filepath.Join(s.processesDir(), id)
|
dir = filepath.Join(s.processesDir(), id)
|
||||||
if err = os.Mkdir(dir, 0700); err != nil {
|
if err = os.Mkdir(dir, 0700); err != nil {
|
||||||
return "", err
|
return "", errors.Wrap(err, "could not create process statedir")
|
||||||
}
|
}
|
||||||
|
|
||||||
return dir, nil
|
return dir, nil
|
||||||
|
@ -40,14 +54,18 @@ func (s StateDir) ProcessDir(id string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s StateDir) DeleteProcess(id string) error {
|
func (s StateDir) DeleteProcess(id string) error {
|
||||||
return os.RemoveAll(filepath.Join(s.processesDir(), id))
|
err := os.RemoveAll(filepath.Join(s.processesDir(), id))
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrapf(err, "failed to remove process %d statedir", id)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s StateDir) Processes() ([]string, error) {
|
func (s StateDir) Processes() ([]string, error) {
|
||||||
procsDir := s.processesDir()
|
procsDir := s.processesDir()
|
||||||
dirs, err := ioutil.ReadDir(procsDir)
|
dirs, err := ioutil.ReadDir(procsDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "could not list processes statedir")
|
||||||
}
|
}
|
||||||
|
|
||||||
paths := make([]string, 0)
|
paths := make([]string, 0)
|
||||||
|
|
|
@ -8,6 +8,7 @@ const (
|
||||||
Running Status = "running"
|
Running Status = "running"
|
||||||
Stopped Status = "stopped"
|
Stopped Status = "stopped"
|
||||||
Deleted Status = "deleted"
|
Deleted Status = "deleted"
|
||||||
|
Unknown Status = "unknown"
|
||||||
|
|
||||||
UnknownStatusCode = 255
|
UnknownStatusCode = 255
|
||||||
)
|
)
|
||||||
|
|
|
@ -67,3 +67,5 @@ github.com/nightlyone/lockfile 1d49c987357a327b5b03aa84cbddd582c328615d
|
||||||
github.com/docker/docker v1.13.0-rc6
|
github.com/docker/docker v1.13.0-rc6
|
||||||
# go-digest; master as of 1/12/2017
|
# go-digest; master as of 1/12/2017
|
||||||
github.com/opencontainers/go-digest 21dfd564fd89c944783d00d069f33e3e7123c448
|
github.com/opencontainers/go-digest 21dfd564fd89c944783d00d069f33e3e7123c448
|
||||||
|
# sys/unix; master as of 1/12/2017
|
||||||
|
golang.org/x/sys/unix d75a52659825e75fff6158388dddc6a5b04f9ba5
|
||||||
|
|
66
vendor/github.com/docker/docker/pkg/term/ascii.go
generated
vendored
Normal file
66
vendor/github.com/docker/docker/pkg/term/ascii.go
generated
vendored
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
package term
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ASCII list the possible supported ASCII key sequence
|
||||||
|
var ASCII = []string{
|
||||||
|
"ctrl-@",
|
||||||
|
"ctrl-a",
|
||||||
|
"ctrl-b",
|
||||||
|
"ctrl-c",
|
||||||
|
"ctrl-d",
|
||||||
|
"ctrl-e",
|
||||||
|
"ctrl-f",
|
||||||
|
"ctrl-g",
|
||||||
|
"ctrl-h",
|
||||||
|
"ctrl-i",
|
||||||
|
"ctrl-j",
|
||||||
|
"ctrl-k",
|
||||||
|
"ctrl-l",
|
||||||
|
"ctrl-m",
|
||||||
|
"ctrl-n",
|
||||||
|
"ctrl-o",
|
||||||
|
"ctrl-p",
|
||||||
|
"ctrl-q",
|
||||||
|
"ctrl-r",
|
||||||
|
"ctrl-s",
|
||||||
|
"ctrl-t",
|
||||||
|
"ctrl-u",
|
||||||
|
"ctrl-v",
|
||||||
|
"ctrl-w",
|
||||||
|
"ctrl-x",
|
||||||
|
"ctrl-y",
|
||||||
|
"ctrl-z",
|
||||||
|
"ctrl-[",
|
||||||
|
"ctrl-\\",
|
||||||
|
"ctrl-]",
|
||||||
|
"ctrl-^",
|
||||||
|
"ctrl-_",
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToBytes converts a string representing a suite of key-sequence to the corresponding ASCII code.
|
||||||
|
func ToBytes(keys string) ([]byte, error) {
|
||||||
|
codes := []byte{}
|
||||||
|
next:
|
||||||
|
for _, key := range strings.Split(keys, ",") {
|
||||||
|
if len(key) != 1 {
|
||||||
|
for code, ctrl := range ASCII {
|
||||||
|
if ctrl == key {
|
||||||
|
codes = append(codes, byte(code))
|
||||||
|
continue next
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if key == "DEL" {
|
||||||
|
codes = append(codes, 127)
|
||||||
|
} else {
|
||||||
|
return nil, fmt.Errorf("Unknown character: '%s'", key)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
codes = append(codes, byte(key[0]))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return codes, nil
|
||||||
|
}
|
50
vendor/github.com/docker/docker/pkg/term/tc_linux_cgo.go
generated
vendored
Normal file
50
vendor/github.com/docker/docker/pkg/term/tc_linux_cgo.go
generated
vendored
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
// +build linux,cgo
|
||||||
|
|
||||||
|
package term
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
// #include <termios.h>
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
// Termios is the Unix API for terminal I/O.
|
||||||
|
// It is passthrough for syscall.Termios in order to make it portable with
|
||||||
|
// other platforms where it is not available or handled differently.
|
||||||
|
type Termios syscall.Termios
|
||||||
|
|
||||||
|
// 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 uintptr) (*State, error) {
|
||||||
|
var oldState State
|
||||||
|
if err := tcget(fd, &oldState.termios); err != 0 {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
newState := oldState.termios
|
||||||
|
|
||||||
|
C.cfmakeraw((*C.struct_termios)(unsafe.Pointer(&newState)))
|
||||||
|
if err := tcset(fd, &newState); err != 0 {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &oldState, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func tcget(fd uintptr, p *Termios) syscall.Errno {
|
||||||
|
ret, err := C.tcgetattr(C.int(fd), (*C.struct_termios)(unsafe.Pointer(p)))
|
||||||
|
if ret != 0 {
|
||||||
|
return err.(syscall.Errno)
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func tcset(fd uintptr, p *Termios) syscall.Errno {
|
||||||
|
ret, err := C.tcsetattr(C.int(fd), C.TCSANOW, (*C.struct_termios)(unsafe.Pointer(p)))
|
||||||
|
if ret != 0 {
|
||||||
|
return err.(syscall.Errno)
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
20
vendor/github.com/docker/docker/pkg/term/tc_other.go
generated
vendored
Normal file
20
vendor/github.com/docker/docker/pkg/term/tc_other.go
generated
vendored
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
// +build !windows
|
||||||
|
// +build !linux !cgo
|
||||||
|
// +build !solaris !cgo
|
||||||
|
|
||||||
|
package term
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
func tcget(fd uintptr, p *Termios) syscall.Errno {
|
||||||
|
_, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(getTermios), uintptr(unsafe.Pointer(p)))
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func tcset(fd uintptr, p *Termios) syscall.Errno {
|
||||||
|
_, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, setTermios, uintptr(unsafe.Pointer(p)))
|
||||||
|
return err
|
||||||
|
}
|
63
vendor/github.com/docker/docker/pkg/term/tc_solaris_cgo.go
generated
vendored
Normal file
63
vendor/github.com/docker/docker/pkg/term/tc_solaris_cgo.go
generated
vendored
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
// +build solaris,cgo
|
||||||
|
|
||||||
|
package term
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
// #include <termios.h>
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
// Termios is the Unix API for terminal I/O.
|
||||||
|
// It is passthrough for syscall.Termios in order to make it portable with
|
||||||
|
// other platforms where it is not available or handled differently.
|
||||||
|
type Termios syscall.Termios
|
||||||
|
|
||||||
|
// 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 uintptr) (*State, error) {
|
||||||
|
var oldState State
|
||||||
|
if err := tcget(fd, &oldState.termios); err != 0 {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
newState := oldState.termios
|
||||||
|
|
||||||
|
newState.Iflag &^= (syscall.IGNBRK | syscall.BRKINT | syscall.PARMRK | syscall.ISTRIP | syscall.INLCR | syscall.IGNCR | syscall.ICRNL | syscall.IXON | syscall.IXANY)
|
||||||
|
newState.Oflag &^= syscall.OPOST
|
||||||
|
newState.Lflag &^= (syscall.ECHO | syscall.ECHONL | syscall.ICANON | syscall.ISIG | syscall.IEXTEN)
|
||||||
|
newState.Cflag &^= (syscall.CSIZE | syscall.PARENB)
|
||||||
|
newState.Cflag |= syscall.CS8
|
||||||
|
|
||||||
|
/*
|
||||||
|
VMIN is the minimum number of characters that needs to be read in non-canonical mode for it to be returned
|
||||||
|
Since VMIN is overloaded with another element in canonical mode when we switch modes it defaults to 4. It
|
||||||
|
needs to be explicitly set to 1.
|
||||||
|
*/
|
||||||
|
newState.Cc[C.VMIN] = 1
|
||||||
|
newState.Cc[C.VTIME] = 0
|
||||||
|
|
||||||
|
if err := tcset(fd, &newState); err != 0 {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &oldState, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func tcget(fd uintptr, p *Termios) syscall.Errno {
|
||||||
|
ret, err := C.tcgetattr(C.int(fd), (*C.struct_termios)(unsafe.Pointer(p)))
|
||||||
|
if ret != 0 {
|
||||||
|
return err.(syscall.Errno)
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func tcset(fd uintptr, p *Termios) syscall.Errno {
|
||||||
|
ret, err := C.tcsetattr(C.int(fd), C.TCSANOW, (*C.struct_termios)(unsafe.Pointer(p)))
|
||||||
|
if ret != 0 {
|
||||||
|
return err.(syscall.Errno)
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
123
vendor/github.com/docker/docker/pkg/term/term.go
generated
vendored
Normal file
123
vendor/github.com/docker/docker/pkg/term/term.go
generated
vendored
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
// +build !windows
|
||||||
|
|
||||||
|
// Package term provides structures and helper functions to work with
|
||||||
|
// terminal (state, sizes).
|
||||||
|
package term
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"os/signal"
|
||||||
|
"syscall"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// ErrInvalidState is returned if the state of the terminal is invalid.
|
||||||
|
ErrInvalidState = errors.New("Invalid terminal state")
|
||||||
|
)
|
||||||
|
|
||||||
|
// State represents the state of the terminal.
|
||||||
|
type State struct {
|
||||||
|
termios Termios
|
||||||
|
}
|
||||||
|
|
||||||
|
// Winsize represents the size of the terminal window.
|
||||||
|
type Winsize struct {
|
||||||
|
Height uint16
|
||||||
|
Width uint16
|
||||||
|
x uint16
|
||||||
|
y uint16
|
||||||
|
}
|
||||||
|
|
||||||
|
// StdStreams returns the standard streams (stdin, stdout, stedrr).
|
||||||
|
func StdStreams() (stdIn io.ReadCloser, stdOut, stdErr io.Writer) {
|
||||||
|
return os.Stdin, os.Stdout, os.Stderr
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetFdInfo returns the file descriptor for an os.File and indicates whether the file represents a terminal.
|
||||||
|
func GetFdInfo(in interface{}) (uintptr, bool) {
|
||||||
|
var inFd uintptr
|
||||||
|
var isTerminalIn bool
|
||||||
|
if file, ok := in.(*os.File); ok {
|
||||||
|
inFd = file.Fd()
|
||||||
|
isTerminalIn = IsTerminal(inFd)
|
||||||
|
}
|
||||||
|
return inFd, isTerminalIn
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsTerminal returns true if the given file descriptor is a terminal.
|
||||||
|
func IsTerminal(fd uintptr) bool {
|
||||||
|
var termios Termios
|
||||||
|
return tcget(fd, &termios) == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// RestoreTerminal restores the terminal connected to the given file descriptor
|
||||||
|
// to a previous state.
|
||||||
|
func RestoreTerminal(fd uintptr, state *State) error {
|
||||||
|
if state == nil {
|
||||||
|
return ErrInvalidState
|
||||||
|
}
|
||||||
|
if err := tcset(fd, &state.termios); err != 0 {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SaveState saves the state of the terminal connected to the given file descriptor.
|
||||||
|
func SaveState(fd uintptr) (*State, error) {
|
||||||
|
var oldState State
|
||||||
|
if err := tcget(fd, &oldState.termios); err != 0 {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &oldState, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DisableEcho applies the specified state to the terminal connected to the file
|
||||||
|
// descriptor, with echo disabled.
|
||||||
|
func DisableEcho(fd uintptr, state *State) error {
|
||||||
|
newState := state.termios
|
||||||
|
newState.Lflag &^= syscall.ECHO
|
||||||
|
|
||||||
|
if err := tcset(fd, &newState); err != 0 {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
handleInterrupt(fd, state)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetRawTerminal puts the terminal connected to the given file descriptor into
|
||||||
|
// raw mode and returns the previous state. On UNIX, this puts both the input
|
||||||
|
// and output into raw mode. On Windows, it only puts the input into raw mode.
|
||||||
|
func SetRawTerminal(fd uintptr) (*State, error) {
|
||||||
|
oldState, err := MakeRaw(fd)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
handleInterrupt(fd, oldState)
|
||||||
|
return oldState, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetRawTerminalOutput puts the output of terminal connected to the given file
|
||||||
|
// descriptor into raw mode. On UNIX, this does nothing and returns nil for the
|
||||||
|
// state. On Windows, it disables LF -> CRLF translation.
|
||||||
|
func SetRawTerminalOutput(fd uintptr) (*State, error) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleInterrupt(fd uintptr, state *State) {
|
||||||
|
sigchan := make(chan os.Signal, 1)
|
||||||
|
signal.Notify(sigchan, os.Interrupt)
|
||||||
|
go func() {
|
||||||
|
for range sigchan {
|
||||||
|
// quit cleanly and the new terminal item is on a new line
|
||||||
|
fmt.Println()
|
||||||
|
signal.Stop(sigchan)
|
||||||
|
close(sigchan)
|
||||||
|
RestoreTerminal(fd, state)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
41
vendor/github.com/docker/docker/pkg/term/term_solaris.go
generated
vendored
Normal file
41
vendor/github.com/docker/docker/pkg/term/term_solaris.go
generated
vendored
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
// +build solaris
|
||||||
|
|
||||||
|
package term
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
/*
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stropts.h>
|
||||||
|
#include <termios.h>
|
||||||
|
|
||||||
|
// Small wrapper to get rid of variadic args of ioctl()
|
||||||
|
int my_ioctl(int fd, int cmd, struct winsize *ws) {
|
||||||
|
return ioctl(fd, cmd, ws);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
// GetWinsize returns the window size based on the specified file descriptor.
|
||||||
|
func GetWinsize(fd uintptr) (*Winsize, error) {
|
||||||
|
ws := &Winsize{}
|
||||||
|
ret, err := C.my_ioctl(C.int(fd), C.int(syscall.TIOCGWINSZ), (*C.struct_winsize)(unsafe.Pointer(ws)))
|
||||||
|
// Skip retval = 0
|
||||||
|
if ret == 0 {
|
||||||
|
return ws, nil
|
||||||
|
}
|
||||||
|
return ws, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetWinsize tries to set the specified window size for the specified file descriptor.
|
||||||
|
func SetWinsize(fd uintptr, ws *Winsize) error {
|
||||||
|
ret, err := C.my_ioctl(C.int(fd), C.int(syscall.TIOCSWINSZ), (*C.struct_winsize)(unsafe.Pointer(ws)))
|
||||||
|
// Skip retval = 0
|
||||||
|
if ret == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
29
vendor/github.com/docker/docker/pkg/term/term_unix.go
generated
vendored
Normal file
29
vendor/github.com/docker/docker/pkg/term/term_unix.go
generated
vendored
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
// +build !solaris,!windows
|
||||||
|
|
||||||
|
package term
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GetWinsize returns the window size based on the specified file descriptor.
|
||||||
|
func GetWinsize(fd uintptr) (*Winsize, error) {
|
||||||
|
ws := &Winsize{}
|
||||||
|
_, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(syscall.TIOCGWINSZ), uintptr(unsafe.Pointer(ws)))
|
||||||
|
// Skipp errno = 0
|
||||||
|
if err == 0 {
|
||||||
|
return ws, nil
|
||||||
|
}
|
||||||
|
return ws, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetWinsize tries to set the specified window size for the specified file descriptor.
|
||||||
|
func SetWinsize(fd uintptr, ws *Winsize) error {
|
||||||
|
_, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(syscall.TIOCSWINSZ), uintptr(unsafe.Pointer(ws)))
|
||||||
|
// Skipp errno = 0
|
||||||
|
if err == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
233
vendor/github.com/docker/docker/pkg/term/term_windows.go
generated
vendored
Normal file
233
vendor/github.com/docker/docker/pkg/term/term_windows.go
generated
vendored
Normal file
|
@ -0,0 +1,233 @@
|
||||||
|
// +build windows
|
||||||
|
|
||||||
|
package term
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"os/signal"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
|
"github.com/Azure/go-ansiterm/winterm"
|
||||||
|
"github.com/docker/docker/pkg/term/windows"
|
||||||
|
)
|
||||||
|
|
||||||
|
// State holds the console mode for the terminal.
|
||||||
|
type State struct {
|
||||||
|
mode uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// Winsize is used for window size.
|
||||||
|
type Winsize struct {
|
||||||
|
Height uint16
|
||||||
|
Width uint16
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms683167(v=vs.85).aspx
|
||||||
|
enableVirtualTerminalInput = 0x0200
|
||||||
|
enableVirtualTerminalProcessing = 0x0004
|
||||||
|
disableNewlineAutoReturn = 0x0008
|
||||||
|
)
|
||||||
|
|
||||||
|
// vtInputSupported is true if enableVirtualTerminalInput is supported by the console
|
||||||
|
var vtInputSupported bool
|
||||||
|
|
||||||
|
// StdStreams returns the standard streams (stdin, stdout, stedrr).
|
||||||
|
func StdStreams() (stdIn io.ReadCloser, stdOut, stdErr io.Writer) {
|
||||||
|
// Turn on VT handling on all std handles, if possible. This might
|
||||||
|
// fail, in which case we will fall back to terminal emulation.
|
||||||
|
var emulateStdin, emulateStdout, emulateStderr bool
|
||||||
|
fd := os.Stdin.Fd()
|
||||||
|
if mode, err := winterm.GetConsoleMode(fd); err == nil {
|
||||||
|
// Validate that enableVirtualTerminalInput is supported, but do not set it.
|
||||||
|
if err = winterm.SetConsoleMode(fd, mode|enableVirtualTerminalInput); err != nil {
|
||||||
|
emulateStdin = true
|
||||||
|
} else {
|
||||||
|
vtInputSupported = true
|
||||||
|
}
|
||||||
|
// Unconditionally set the console mode back even on failure because SetConsoleMode
|
||||||
|
// remembers invalid bits on input handles.
|
||||||
|
winterm.SetConsoleMode(fd, mode)
|
||||||
|
}
|
||||||
|
|
||||||
|
fd = os.Stdout.Fd()
|
||||||
|
if mode, err := winterm.GetConsoleMode(fd); err == nil {
|
||||||
|
// Validate disableNewlineAutoReturn is supported, but do not set it.
|
||||||
|
if err = winterm.SetConsoleMode(fd, mode|enableVirtualTerminalProcessing|disableNewlineAutoReturn); err != nil {
|
||||||
|
emulateStdout = true
|
||||||
|
} else {
|
||||||
|
winterm.SetConsoleMode(fd, mode|enableVirtualTerminalProcessing)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fd = os.Stderr.Fd()
|
||||||
|
if mode, err := winterm.GetConsoleMode(fd); err == nil {
|
||||||
|
// Validate disableNewlineAutoReturn is supported, but do not set it.
|
||||||
|
if err = winterm.SetConsoleMode(fd, mode|enableVirtualTerminalProcessing|disableNewlineAutoReturn); err != nil {
|
||||||
|
emulateStderr = true
|
||||||
|
} else {
|
||||||
|
winterm.SetConsoleMode(fd, mode|enableVirtualTerminalProcessing)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if os.Getenv("ConEmuANSI") == "ON" || os.Getenv("ConsoleZVersion") != "" {
|
||||||
|
// The ConEmu and ConsoleZ terminals emulate ANSI on output streams well.
|
||||||
|
emulateStdin = true
|
||||||
|
emulateStdout = false
|
||||||
|
emulateStderr = false
|
||||||
|
}
|
||||||
|
|
||||||
|
if emulateStdin {
|
||||||
|
stdIn = windows.NewAnsiReader(syscall.STD_INPUT_HANDLE)
|
||||||
|
} else {
|
||||||
|
stdIn = os.Stdin
|
||||||
|
}
|
||||||
|
|
||||||
|
if emulateStdout {
|
||||||
|
stdOut = windows.NewAnsiWriter(syscall.STD_OUTPUT_HANDLE)
|
||||||
|
} else {
|
||||||
|
stdOut = os.Stdout
|
||||||
|
}
|
||||||
|
|
||||||
|
if emulateStderr {
|
||||||
|
stdErr = windows.NewAnsiWriter(syscall.STD_ERROR_HANDLE)
|
||||||
|
} else {
|
||||||
|
stdErr = os.Stderr
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetFdInfo returns the file descriptor for an os.File and indicates whether the file represents a terminal.
|
||||||
|
func GetFdInfo(in interface{}) (uintptr, bool) {
|
||||||
|
return windows.GetHandleInfo(in)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetWinsize returns the window size based on the specified file descriptor.
|
||||||
|
func GetWinsize(fd uintptr) (*Winsize, error) {
|
||||||
|
info, err := winterm.GetConsoleScreenBufferInfo(fd)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
winsize := &Winsize{
|
||||||
|
Width: uint16(info.Window.Right - info.Window.Left + 1),
|
||||||
|
Height: uint16(info.Window.Bottom - info.Window.Top + 1),
|
||||||
|
}
|
||||||
|
|
||||||
|
return winsize, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsTerminal returns true if the given file descriptor is a terminal.
|
||||||
|
func IsTerminal(fd uintptr) bool {
|
||||||
|
return windows.IsConsole(fd)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RestoreTerminal restores the terminal connected to the given file descriptor
|
||||||
|
// to a previous state.
|
||||||
|
func RestoreTerminal(fd uintptr, state *State) error {
|
||||||
|
return winterm.SetConsoleMode(fd, state.mode)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SaveState saves the state of the terminal connected to the given file descriptor.
|
||||||
|
func SaveState(fd uintptr) (*State, error) {
|
||||||
|
mode, e := winterm.GetConsoleMode(fd)
|
||||||
|
if e != nil {
|
||||||
|
return nil, e
|
||||||
|
}
|
||||||
|
|
||||||
|
return &State{mode: mode}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DisableEcho disables echo for the terminal connected to the given file descriptor.
|
||||||
|
// -- See https://msdn.microsoft.com/en-us/library/windows/desktop/ms683462(v=vs.85).aspx
|
||||||
|
func DisableEcho(fd uintptr, state *State) error {
|
||||||
|
mode := state.mode
|
||||||
|
mode &^= winterm.ENABLE_ECHO_INPUT
|
||||||
|
mode |= winterm.ENABLE_PROCESSED_INPUT | winterm.ENABLE_LINE_INPUT
|
||||||
|
err := winterm.SetConsoleMode(fd, mode)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Register an interrupt handler to catch and restore prior state
|
||||||
|
restoreAtInterrupt(fd, state)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetRawTerminal puts the terminal connected to the given file descriptor into
|
||||||
|
// raw mode and returns the previous state. On UNIX, this puts both the input
|
||||||
|
// and output into raw mode. On Windows, it only puts the input into raw mode.
|
||||||
|
func SetRawTerminal(fd uintptr) (*State, error) {
|
||||||
|
state, err := MakeRaw(fd)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Register an interrupt handler to catch and restore prior state
|
||||||
|
restoreAtInterrupt(fd, state)
|
||||||
|
return state, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetRawTerminalOutput puts the output of terminal connected to the given file
|
||||||
|
// descriptor into raw mode. On UNIX, this does nothing and returns nil for the
|
||||||
|
// state. On Windows, it disables LF -> CRLF translation.
|
||||||
|
func SetRawTerminalOutput(fd uintptr) (*State, error) {
|
||||||
|
state, err := SaveState(fd)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ignore failures, since disableNewlineAutoReturn might not be supported on this
|
||||||
|
// version of Windows.
|
||||||
|
winterm.SetConsoleMode(fd, state.mode|disableNewlineAutoReturn)
|
||||||
|
return state, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// MakeRaw puts the terminal (Windows Console) 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 uintptr) (*State, error) {
|
||||||
|
state, err := SaveState(fd)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
mode := state.mode
|
||||||
|
|
||||||
|
// See
|
||||||
|
// -- https://msdn.microsoft.com/en-us/library/windows/desktop/ms686033(v=vs.85).aspx
|
||||||
|
// -- https://msdn.microsoft.com/en-us/library/windows/desktop/ms683462(v=vs.85).aspx
|
||||||
|
|
||||||
|
// Disable these modes
|
||||||
|
mode &^= winterm.ENABLE_ECHO_INPUT
|
||||||
|
mode &^= winterm.ENABLE_LINE_INPUT
|
||||||
|
mode &^= winterm.ENABLE_MOUSE_INPUT
|
||||||
|
mode &^= winterm.ENABLE_WINDOW_INPUT
|
||||||
|
mode &^= winterm.ENABLE_PROCESSED_INPUT
|
||||||
|
|
||||||
|
// Enable these modes
|
||||||
|
mode |= winterm.ENABLE_EXTENDED_FLAGS
|
||||||
|
mode |= winterm.ENABLE_INSERT_MODE
|
||||||
|
mode |= winterm.ENABLE_QUICK_EDIT_MODE
|
||||||
|
if vtInputSupported {
|
||||||
|
mode |= enableVirtualTerminalInput
|
||||||
|
}
|
||||||
|
|
||||||
|
err = winterm.SetConsoleMode(fd, mode)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return state, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func restoreAtInterrupt(fd uintptr, state *State) {
|
||||||
|
sigchan := make(chan os.Signal, 1)
|
||||||
|
signal.Notify(sigchan, os.Interrupt)
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
_ = <-sigchan
|
||||||
|
RestoreTerminal(fd, state)
|
||||||
|
os.Exit(0)
|
||||||
|
}()
|
||||||
|
}
|
69
vendor/github.com/docker/docker/pkg/term/termios_darwin.go
generated
vendored
Normal file
69
vendor/github.com/docker/docker/pkg/term/termios_darwin.go
generated
vendored
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
package term
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
getTermios = syscall.TIOCGETA
|
||||||
|
setTermios = syscall.TIOCSETA
|
||||||
|
)
|
||||||
|
|
||||||
|
// Termios magic numbers, passthrough to the ones defined in syscall.
|
||||||
|
const (
|
||||||
|
IGNBRK = syscall.IGNBRK
|
||||||
|
PARMRK = syscall.PARMRK
|
||||||
|
INLCR = syscall.INLCR
|
||||||
|
IGNCR = syscall.IGNCR
|
||||||
|
ECHONL = syscall.ECHONL
|
||||||
|
CSIZE = syscall.CSIZE
|
||||||
|
ICRNL = syscall.ICRNL
|
||||||
|
ISTRIP = syscall.ISTRIP
|
||||||
|
PARENB = syscall.PARENB
|
||||||
|
ECHO = syscall.ECHO
|
||||||
|
ICANON = syscall.ICANON
|
||||||
|
ISIG = syscall.ISIG
|
||||||
|
IXON = syscall.IXON
|
||||||
|
BRKINT = syscall.BRKINT
|
||||||
|
INPCK = syscall.INPCK
|
||||||
|
OPOST = syscall.OPOST
|
||||||
|
CS8 = syscall.CS8
|
||||||
|
IEXTEN = syscall.IEXTEN
|
||||||
|
)
|
||||||
|
|
||||||
|
// Termios is the Unix API for terminal I/O.
|
||||||
|
type Termios struct {
|
||||||
|
Iflag uint64
|
||||||
|
Oflag uint64
|
||||||
|
Cflag uint64
|
||||||
|
Lflag uint64
|
||||||
|
Cc [20]byte
|
||||||
|
Ispeed uint64
|
||||||
|
Ospeed uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 uintptr) (*State, error) {
|
||||||
|
var oldState State
|
||||||
|
if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(getTermios), uintptr(unsafe.Pointer(&oldState.termios))); err != 0 {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
newState := oldState.termios
|
||||||
|
newState.Iflag &^= (IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON)
|
||||||
|
newState.Oflag &^= OPOST
|
||||||
|
newState.Lflag &^= (ECHO | ECHONL | ICANON | ISIG | IEXTEN)
|
||||||
|
newState.Cflag &^= (CSIZE | PARENB)
|
||||||
|
newState.Cflag |= CS8
|
||||||
|
newState.Cc[syscall.VMIN] = 1
|
||||||
|
newState.Cc[syscall.VTIME] = 0
|
||||||
|
|
||||||
|
if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(setTermios), uintptr(unsafe.Pointer(&newState))); err != 0 {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &oldState, nil
|
||||||
|
}
|
69
vendor/github.com/docker/docker/pkg/term/termios_freebsd.go
generated
vendored
Normal file
69
vendor/github.com/docker/docker/pkg/term/termios_freebsd.go
generated
vendored
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
package term
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
getTermios = syscall.TIOCGETA
|
||||||
|
setTermios = syscall.TIOCSETA
|
||||||
|
)
|
||||||
|
|
||||||
|
// Termios magic numbers, passthrough to the ones defined in syscall.
|
||||||
|
const (
|
||||||
|
IGNBRK = syscall.IGNBRK
|
||||||
|
PARMRK = syscall.PARMRK
|
||||||
|
INLCR = syscall.INLCR
|
||||||
|
IGNCR = syscall.IGNCR
|
||||||
|
ECHONL = syscall.ECHONL
|
||||||
|
CSIZE = syscall.CSIZE
|
||||||
|
ICRNL = syscall.ICRNL
|
||||||
|
ISTRIP = syscall.ISTRIP
|
||||||
|
PARENB = syscall.PARENB
|
||||||
|
ECHO = syscall.ECHO
|
||||||
|
ICANON = syscall.ICANON
|
||||||
|
ISIG = syscall.ISIG
|
||||||
|
IXON = syscall.IXON
|
||||||
|
BRKINT = syscall.BRKINT
|
||||||
|
INPCK = syscall.INPCK
|
||||||
|
OPOST = syscall.OPOST
|
||||||
|
CS8 = syscall.CS8
|
||||||
|
IEXTEN = syscall.IEXTEN
|
||||||
|
)
|
||||||
|
|
||||||
|
// Termios is the Unix API for terminal I/O.
|
||||||
|
type Termios struct {
|
||||||
|
Iflag uint32
|
||||||
|
Oflag uint32
|
||||||
|
Cflag uint32
|
||||||
|
Lflag uint32
|
||||||
|
Cc [20]byte
|
||||||
|
Ispeed uint32
|
||||||
|
Ospeed uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 uintptr) (*State, error) {
|
||||||
|
var oldState State
|
||||||
|
if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(getTermios), uintptr(unsafe.Pointer(&oldState.termios))); err != 0 {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
newState := oldState.termios
|
||||||
|
newState.Iflag &^= (IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON)
|
||||||
|
newState.Oflag &^= OPOST
|
||||||
|
newState.Lflag &^= (ECHO | ECHONL | ICANON | ISIG | IEXTEN)
|
||||||
|
newState.Cflag &^= (CSIZE | PARENB)
|
||||||
|
newState.Cflag |= CS8
|
||||||
|
newState.Cc[syscall.VMIN] = 1
|
||||||
|
newState.Cc[syscall.VTIME] = 0
|
||||||
|
|
||||||
|
if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(setTermios), uintptr(unsafe.Pointer(&newState))); err != 0 {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &oldState, nil
|
||||||
|
}
|
47
vendor/github.com/docker/docker/pkg/term/termios_linux.go
generated
vendored
Normal file
47
vendor/github.com/docker/docker/pkg/term/termios_linux.go
generated
vendored
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
// +build !cgo
|
||||||
|
|
||||||
|
package term
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
getTermios = syscall.TCGETS
|
||||||
|
setTermios = syscall.TCSETS
|
||||||
|
)
|
||||||
|
|
||||||
|
// Termios is the Unix API for terminal I/O.
|
||||||
|
type Termios struct {
|
||||||
|
Iflag uint32
|
||||||
|
Oflag uint32
|
||||||
|
Cflag uint32
|
||||||
|
Lflag uint32
|
||||||
|
Cc [20]byte
|
||||||
|
Ispeed uint32
|
||||||
|
Ospeed uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 uintptr) (*State, error) {
|
||||||
|
var oldState State
|
||||||
|
if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, getTermios, uintptr(unsafe.Pointer(&oldState.termios))); err != 0 {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
newState := oldState.termios
|
||||||
|
|
||||||
|
newState.Iflag &^= (syscall.IGNBRK | syscall.BRKINT | syscall.PARMRK | syscall.ISTRIP | syscall.INLCR | syscall.IGNCR | syscall.ICRNL | syscall.IXON)
|
||||||
|
newState.Oflag &^= syscall.OPOST
|
||||||
|
newState.Lflag &^= (syscall.ECHO | syscall.ECHONL | syscall.ICANON | syscall.ISIG | syscall.IEXTEN)
|
||||||
|
newState.Cflag &^= (syscall.CSIZE | syscall.PARENB)
|
||||||
|
newState.Cflag |= syscall.CS8
|
||||||
|
|
||||||
|
if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, setTermios, uintptr(unsafe.Pointer(&newState))); err != 0 {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &oldState, nil
|
||||||
|
}
|
69
vendor/github.com/docker/docker/pkg/term/termios_openbsd.go
generated
vendored
Normal file
69
vendor/github.com/docker/docker/pkg/term/termios_openbsd.go
generated
vendored
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
package term
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
getTermios = syscall.TIOCGETA
|
||||||
|
setTermios = syscall.TIOCSETA
|
||||||
|
)
|
||||||
|
|
||||||
|
// Termios magic numbers, passthrough to the ones defined in syscall.
|
||||||
|
const (
|
||||||
|
IGNBRK = syscall.IGNBRK
|
||||||
|
PARMRK = syscall.PARMRK
|
||||||
|
INLCR = syscall.INLCR
|
||||||
|
IGNCR = syscall.IGNCR
|
||||||
|
ECHONL = syscall.ECHONL
|
||||||
|
CSIZE = syscall.CSIZE
|
||||||
|
ICRNL = syscall.ICRNL
|
||||||
|
ISTRIP = syscall.ISTRIP
|
||||||
|
PARENB = syscall.PARENB
|
||||||
|
ECHO = syscall.ECHO
|
||||||
|
ICANON = syscall.ICANON
|
||||||
|
ISIG = syscall.ISIG
|
||||||
|
IXON = syscall.IXON
|
||||||
|
BRKINT = syscall.BRKINT
|
||||||
|
INPCK = syscall.INPCK
|
||||||
|
OPOST = syscall.OPOST
|
||||||
|
CS8 = syscall.CS8
|
||||||
|
IEXTEN = syscall.IEXTEN
|
||||||
|
)
|
||||||
|
|
||||||
|
// Termios is the Unix API for terminal I/O.
|
||||||
|
type Termios struct {
|
||||||
|
Iflag uint32
|
||||||
|
Oflag uint32
|
||||||
|
Cflag uint32
|
||||||
|
Lflag uint32
|
||||||
|
Cc [20]byte
|
||||||
|
Ispeed uint32
|
||||||
|
Ospeed uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 uintptr) (*State, error) {
|
||||||
|
var oldState State
|
||||||
|
if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(getTermios), uintptr(unsafe.Pointer(&oldState.termios))); err != 0 {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
newState := oldState.termios
|
||||||
|
newState.Iflag &^= (IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON)
|
||||||
|
newState.Oflag &^= OPOST
|
||||||
|
newState.Lflag &^= (ECHO | ECHONL | ICANON | ISIG | IEXTEN)
|
||||||
|
newState.Cflag &^= (CSIZE | PARENB)
|
||||||
|
newState.Cflag |= CS8
|
||||||
|
newState.Cc[syscall.VMIN] = 1
|
||||||
|
newState.Cc[syscall.VTIME] = 0
|
||||||
|
|
||||||
|
if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(setTermios), uintptr(unsafe.Pointer(&newState))); err != 0 {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &oldState, nil
|
||||||
|
}
|
263
vendor/github.com/docker/docker/pkg/term/windows/ansi_reader.go
generated
vendored
Normal file
263
vendor/github.com/docker/docker/pkg/term/windows/ansi_reader.go
generated
vendored
Normal file
|
@ -0,0 +1,263 @@
|
||||||
|
// +build windows
|
||||||
|
|
||||||
|
package windows
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
ansiterm "github.com/Azure/go-ansiterm"
|
||||||
|
"github.com/Azure/go-ansiterm/winterm"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
escapeSequence = ansiterm.KEY_ESC_CSI
|
||||||
|
)
|
||||||
|
|
||||||
|
// ansiReader wraps a standard input file (e.g., os.Stdin) providing ANSI sequence translation.
|
||||||
|
type ansiReader struct {
|
||||||
|
file *os.File
|
||||||
|
fd uintptr
|
||||||
|
buffer []byte
|
||||||
|
cbBuffer int
|
||||||
|
command []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewAnsiReader returns an io.ReadCloser that provides VT100 terminal emulation on top of a
|
||||||
|
// Windows console input handle.
|
||||||
|
func NewAnsiReader(nFile int) io.ReadCloser {
|
||||||
|
initLogger()
|
||||||
|
file, fd := winterm.GetStdFile(nFile)
|
||||||
|
return &ansiReader{
|
||||||
|
file: file,
|
||||||
|
fd: fd,
|
||||||
|
command: make([]byte, 0, ansiterm.ANSI_MAX_CMD_LENGTH),
|
||||||
|
buffer: make([]byte, 0),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close closes the wrapped file.
|
||||||
|
func (ar *ansiReader) Close() (err error) {
|
||||||
|
return ar.file.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fd returns the file descriptor of the wrapped file.
|
||||||
|
func (ar *ansiReader) Fd() uintptr {
|
||||||
|
return ar.fd
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read reads up to len(p) bytes of translated input events into p.
|
||||||
|
func (ar *ansiReader) Read(p []byte) (int, error) {
|
||||||
|
if len(p) == 0 {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Previously read bytes exist, read as much as we can and return
|
||||||
|
if len(ar.buffer) > 0 {
|
||||||
|
logger.Debugf("Reading previously cached bytes")
|
||||||
|
|
||||||
|
originalLength := len(ar.buffer)
|
||||||
|
copiedLength := copy(p, ar.buffer)
|
||||||
|
|
||||||
|
if copiedLength == originalLength {
|
||||||
|
ar.buffer = make([]byte, 0, len(p))
|
||||||
|
} else {
|
||||||
|
ar.buffer = ar.buffer[copiedLength:]
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Debugf("Read from cache p[%d]: % x", copiedLength, p)
|
||||||
|
return copiedLength, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read and translate key events
|
||||||
|
events, err := readInputEvents(ar.fd, len(p))
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
} else if len(events) == 0 {
|
||||||
|
logger.Debug("No input events detected")
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
keyBytes := translateKeyEvents(events, []byte(escapeSequence))
|
||||||
|
|
||||||
|
// Save excess bytes and right-size keyBytes
|
||||||
|
if len(keyBytes) > len(p) {
|
||||||
|
logger.Debugf("Received %d keyBytes, only room for %d bytes", len(keyBytes), len(p))
|
||||||
|
ar.buffer = keyBytes[len(p):]
|
||||||
|
keyBytes = keyBytes[:len(p)]
|
||||||
|
} else if len(keyBytes) == 0 {
|
||||||
|
logger.Debug("No key bytes returned from the translator")
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
copiedLength := copy(p, keyBytes)
|
||||||
|
if copiedLength != len(keyBytes) {
|
||||||
|
return 0, errors.New("unexpected copy length encountered")
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Debugf("Read p[%d]: % x", copiedLength, p)
|
||||||
|
logger.Debugf("Read keyBytes[%d]: % x", copiedLength, keyBytes)
|
||||||
|
return copiedLength, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// readInputEvents polls until at least one event is available.
|
||||||
|
func readInputEvents(fd uintptr, maxBytes int) ([]winterm.INPUT_RECORD, error) {
|
||||||
|
// Determine the maximum number of records to retrieve
|
||||||
|
// -- Cast around the type system to obtain the size of a single INPUT_RECORD.
|
||||||
|
// unsafe.Sizeof requires an expression vs. a type-reference; the casting
|
||||||
|
// tricks the type system into believing it has such an expression.
|
||||||
|
recordSize := int(unsafe.Sizeof(*((*winterm.INPUT_RECORD)(unsafe.Pointer(&maxBytes)))))
|
||||||
|
countRecords := maxBytes / recordSize
|
||||||
|
if countRecords > ansiterm.MAX_INPUT_EVENTS {
|
||||||
|
countRecords = ansiterm.MAX_INPUT_EVENTS
|
||||||
|
} else if countRecords == 0 {
|
||||||
|
countRecords = 1
|
||||||
|
}
|
||||||
|
logger.Debugf("[windows] readInputEvents: Reading %v records (buffer size %v, record size %v)", countRecords, maxBytes, recordSize)
|
||||||
|
|
||||||
|
// Wait for and read input events
|
||||||
|
events := make([]winterm.INPUT_RECORD, countRecords)
|
||||||
|
nEvents := uint32(0)
|
||||||
|
eventsExist, err := winterm.WaitForSingleObject(fd, winterm.WAIT_INFINITE)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if eventsExist {
|
||||||
|
err = winterm.ReadConsoleInput(fd, events, &nEvents)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return a slice restricted to the number of returned records
|
||||||
|
logger.Debugf("[windows] readInputEvents: Read %v events", nEvents)
|
||||||
|
return events[:nEvents], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// KeyEvent Translation Helpers
|
||||||
|
|
||||||
|
var arrowKeyMapPrefix = map[uint16]string{
|
||||||
|
winterm.VK_UP: "%s%sA",
|
||||||
|
winterm.VK_DOWN: "%s%sB",
|
||||||
|
winterm.VK_RIGHT: "%s%sC",
|
||||||
|
winterm.VK_LEFT: "%s%sD",
|
||||||
|
}
|
||||||
|
|
||||||
|
var keyMapPrefix = map[uint16]string{
|
||||||
|
winterm.VK_UP: "\x1B[%sA",
|
||||||
|
winterm.VK_DOWN: "\x1B[%sB",
|
||||||
|
winterm.VK_RIGHT: "\x1B[%sC",
|
||||||
|
winterm.VK_LEFT: "\x1B[%sD",
|
||||||
|
winterm.VK_HOME: "\x1B[1%s~", // showkey shows ^[[1
|
||||||
|
winterm.VK_END: "\x1B[4%s~", // showkey shows ^[[4
|
||||||
|
winterm.VK_INSERT: "\x1B[2%s~",
|
||||||
|
winterm.VK_DELETE: "\x1B[3%s~",
|
||||||
|
winterm.VK_PRIOR: "\x1B[5%s~",
|
||||||
|
winterm.VK_NEXT: "\x1B[6%s~",
|
||||||
|
winterm.VK_F1: "",
|
||||||
|
winterm.VK_F2: "",
|
||||||
|
winterm.VK_F3: "\x1B[13%s~",
|
||||||
|
winterm.VK_F4: "\x1B[14%s~",
|
||||||
|
winterm.VK_F5: "\x1B[15%s~",
|
||||||
|
winterm.VK_F6: "\x1B[17%s~",
|
||||||
|
winterm.VK_F7: "\x1B[18%s~",
|
||||||
|
winterm.VK_F8: "\x1B[19%s~",
|
||||||
|
winterm.VK_F9: "\x1B[20%s~",
|
||||||
|
winterm.VK_F10: "\x1B[21%s~",
|
||||||
|
winterm.VK_F11: "\x1B[23%s~",
|
||||||
|
winterm.VK_F12: "\x1B[24%s~",
|
||||||
|
}
|
||||||
|
|
||||||
|
// translateKeyEvents converts the input events into the appropriate ANSI string.
|
||||||
|
func translateKeyEvents(events []winterm.INPUT_RECORD, escapeSequence []byte) []byte {
|
||||||
|
var buffer bytes.Buffer
|
||||||
|
for _, event := range events {
|
||||||
|
if event.EventType == winterm.KEY_EVENT && event.KeyEvent.KeyDown != 0 {
|
||||||
|
buffer.WriteString(keyToString(&event.KeyEvent, escapeSequence))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return buffer.Bytes()
|
||||||
|
}
|
||||||
|
|
||||||
|
// keyToString maps the given input event record to the corresponding string.
|
||||||
|
func keyToString(keyEvent *winterm.KEY_EVENT_RECORD, escapeSequence []byte) string {
|
||||||
|
if keyEvent.UnicodeChar == 0 {
|
||||||
|
return formatVirtualKey(keyEvent.VirtualKeyCode, keyEvent.ControlKeyState, escapeSequence)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, alt, control := getControlKeys(keyEvent.ControlKeyState)
|
||||||
|
if control {
|
||||||
|
// TODO(azlinux): Implement following control sequences
|
||||||
|
// <Ctrl>-D Signals the end of input from the keyboard; also exits current shell.
|
||||||
|
// <Ctrl>-H Deletes the first character to the left of the cursor. Also called the ERASE key.
|
||||||
|
// <Ctrl>-Q Restarts printing after it has been stopped with <Ctrl>-s.
|
||||||
|
// <Ctrl>-S Suspends printing on the screen (does not stop the program).
|
||||||
|
// <Ctrl>-U Deletes all characters on the current line. Also called the KILL key.
|
||||||
|
// <Ctrl>-E Quits current command and creates a core
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// <Alt>+Key generates ESC N Key
|
||||||
|
if !control && alt {
|
||||||
|
return ansiterm.KEY_ESC_N + strings.ToLower(string(keyEvent.UnicodeChar))
|
||||||
|
}
|
||||||
|
|
||||||
|
return string(keyEvent.UnicodeChar)
|
||||||
|
}
|
||||||
|
|
||||||
|
// formatVirtualKey converts a virtual key (e.g., up arrow) into the appropriate ANSI string.
|
||||||
|
func formatVirtualKey(key uint16, controlState uint32, escapeSequence []byte) string {
|
||||||
|
shift, alt, control := getControlKeys(controlState)
|
||||||
|
modifier := getControlKeysModifier(shift, alt, control)
|
||||||
|
|
||||||
|
if format, ok := arrowKeyMapPrefix[key]; ok {
|
||||||
|
return fmt.Sprintf(format, escapeSequence, modifier)
|
||||||
|
}
|
||||||
|
|
||||||
|
if format, ok := keyMapPrefix[key]; ok {
|
||||||
|
return fmt.Sprintf(format, modifier)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// getControlKeys extracts the shift, alt, and ctrl key states.
|
||||||
|
func getControlKeys(controlState uint32) (shift, alt, control bool) {
|
||||||
|
shift = 0 != (controlState & winterm.SHIFT_PRESSED)
|
||||||
|
alt = 0 != (controlState & (winterm.LEFT_ALT_PRESSED | winterm.RIGHT_ALT_PRESSED))
|
||||||
|
control = 0 != (controlState & (winterm.LEFT_CTRL_PRESSED | winterm.RIGHT_CTRL_PRESSED))
|
||||||
|
return shift, alt, control
|
||||||
|
}
|
||||||
|
|
||||||
|
// getControlKeysModifier returns the ANSI modifier for the given combination of control keys.
|
||||||
|
func getControlKeysModifier(shift, alt, control bool) string {
|
||||||
|
if shift && alt && control {
|
||||||
|
return ansiterm.KEY_CONTROL_PARAM_8
|
||||||
|
}
|
||||||
|
if alt && control {
|
||||||
|
return ansiterm.KEY_CONTROL_PARAM_7
|
||||||
|
}
|
||||||
|
if shift && control {
|
||||||
|
return ansiterm.KEY_CONTROL_PARAM_6
|
||||||
|
}
|
||||||
|
if control {
|
||||||
|
return ansiterm.KEY_CONTROL_PARAM_5
|
||||||
|
}
|
||||||
|
if shift && alt {
|
||||||
|
return ansiterm.KEY_CONTROL_PARAM_4
|
||||||
|
}
|
||||||
|
if alt {
|
||||||
|
return ansiterm.KEY_CONTROL_PARAM_3
|
||||||
|
}
|
||||||
|
if shift {
|
||||||
|
return ansiterm.KEY_CONTROL_PARAM_2
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
64
vendor/github.com/docker/docker/pkg/term/windows/ansi_writer.go
generated
vendored
Normal file
64
vendor/github.com/docker/docker/pkg/term/windows/ansi_writer.go
generated
vendored
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
// +build windows
|
||||||
|
|
||||||
|
package windows
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
ansiterm "github.com/Azure/go-ansiterm"
|
||||||
|
"github.com/Azure/go-ansiterm/winterm"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ansiWriter wraps a standard output file (e.g., os.Stdout) providing ANSI sequence translation.
|
||||||
|
type ansiWriter struct {
|
||||||
|
file *os.File
|
||||||
|
fd uintptr
|
||||||
|
infoReset *winterm.CONSOLE_SCREEN_BUFFER_INFO
|
||||||
|
command []byte
|
||||||
|
escapeSequence []byte
|
||||||
|
inAnsiSequence bool
|
||||||
|
parser *ansiterm.AnsiParser
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewAnsiWriter returns an io.Writer that provides VT100 terminal emulation on top of a
|
||||||
|
// Windows console output handle.
|
||||||
|
func NewAnsiWriter(nFile int) io.Writer {
|
||||||
|
initLogger()
|
||||||
|
file, fd := winterm.GetStdFile(nFile)
|
||||||
|
info, err := winterm.GetConsoleScreenBufferInfo(fd)
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
parser := ansiterm.CreateParser("Ground", winterm.CreateWinEventHandler(fd, file))
|
||||||
|
logger.Infof("newAnsiWriter: parser %p", parser)
|
||||||
|
|
||||||
|
aw := &ansiWriter{
|
||||||
|
file: file,
|
||||||
|
fd: fd,
|
||||||
|
infoReset: info,
|
||||||
|
command: make([]byte, 0, ansiterm.ANSI_MAX_CMD_LENGTH),
|
||||||
|
escapeSequence: []byte(ansiterm.KEY_ESC_CSI),
|
||||||
|
parser: parser,
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Infof("newAnsiWriter: aw.parser %p", aw.parser)
|
||||||
|
logger.Infof("newAnsiWriter: %v", aw)
|
||||||
|
return aw
|
||||||
|
}
|
||||||
|
|
||||||
|
func (aw *ansiWriter) Fd() uintptr {
|
||||||
|
return aw.fd
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write writes len(p) bytes from p to the underlying data stream.
|
||||||
|
func (aw *ansiWriter) Write(p []byte) (total int, err error) {
|
||||||
|
if len(p) == 0 {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Infof("Write: % x", p)
|
||||||
|
logger.Infof("Write: %s", string(p))
|
||||||
|
return aw.parser.Parse(p)
|
||||||
|
}
|
35
vendor/github.com/docker/docker/pkg/term/windows/console.go
generated
vendored
Normal file
35
vendor/github.com/docker/docker/pkg/term/windows/console.go
generated
vendored
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
// +build windows
|
||||||
|
|
||||||
|
package windows
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/Azure/go-ansiterm/winterm"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GetHandleInfo returns file descriptor and bool indicating whether the file is a console.
|
||||||
|
func GetHandleInfo(in interface{}) (uintptr, bool) {
|
||||||
|
switch t := in.(type) {
|
||||||
|
case *ansiReader:
|
||||||
|
return t.Fd(), true
|
||||||
|
case *ansiWriter:
|
||||||
|
return t.Fd(), true
|
||||||
|
}
|
||||||
|
|
||||||
|
var inFd uintptr
|
||||||
|
var isTerminal bool
|
||||||
|
|
||||||
|
if file, ok := in.(*os.File); ok {
|
||||||
|
inFd = file.Fd()
|
||||||
|
isTerminal = IsConsole(inFd)
|
||||||
|
}
|
||||||
|
return inFd, isTerminal
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsConsole returns true if the given file descriptor is a Windows Console.
|
||||||
|
// The code assumes that GetConsoleMode will return an error for file descriptors that are not a console.
|
||||||
|
func IsConsole(fd uintptr) bool {
|
||||||
|
_, e := winterm.GetConsoleMode(fd)
|
||||||
|
return e == nil
|
||||||
|
}
|
33
vendor/github.com/docker/docker/pkg/term/windows/windows.go
generated
vendored
Normal file
33
vendor/github.com/docker/docker/pkg/term/windows/windows.go
generated
vendored
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
// These files implement ANSI-aware input and output streams for use by the Docker Windows client.
|
||||||
|
// When asked for the set of standard streams (e.g., stdin, stdout, stderr), the code will create
|
||||||
|
// and return pseudo-streams that convert ANSI sequences to / from Windows Console API calls.
|
||||||
|
|
||||||
|
package windows
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
ansiterm "github.com/Azure/go-ansiterm"
|
||||||
|
"github.com/Sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
var logger *logrus.Logger
|
||||||
|
var initOnce sync.Once
|
||||||
|
|
||||||
|
func initLogger() {
|
||||||
|
initOnce.Do(func() {
|
||||||
|
logFile := ioutil.Discard
|
||||||
|
|
||||||
|
if isDebugEnv := os.Getenv(ansiterm.LogEnv); isDebugEnv == "1" {
|
||||||
|
logFile, _ = os.Create("ansiReaderWriter.log")
|
||||||
|
}
|
||||||
|
|
||||||
|
logger = &logrus.Logger{
|
||||||
|
Out: logFile,
|
||||||
|
Formatter: new(logrus.TextFormatter),
|
||||||
|
Level: logrus.DebugLevel,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
27
vendor/golang.org/x/sys/LICENSE
generated
vendored
Normal file
27
vendor/golang.org/x/sys/LICENSE
generated
vendored
Normal 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/sys/PATENTS
generated
vendored
Normal file
22
vendor/golang.org/x/sys/PATENTS
generated
vendored
Normal 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.
|
10
vendor/golang.org/x/sys/unix/asm.s
generated
vendored
Normal file
10
vendor/golang.org/x/sys/unix/asm.s
generated
vendored
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
// 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
|
29
vendor/golang.org/x/sys/unix/asm_darwin_386.s
generated
vendored
Normal file
29
vendor/golang.org/x/sys/unix/asm_darwin_386.s
generated
vendored
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !gccgo
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// System call support for 386, Darwin
|
||||||
|
//
|
||||||
|
|
||||||
|
// Just jump to package syscall's implementation for all these functions.
|
||||||
|
// The runtime may know about them.
|
||||||
|
|
||||||
|
TEXT ·Syscall(SB),NOSPLIT,$0-28
|
||||||
|
JMP syscall·Syscall(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall6(SB),NOSPLIT,$0-40
|
||||||
|
JMP syscall·Syscall6(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall9(SB),NOSPLIT,$0-52
|
||||||
|
JMP syscall·Syscall9(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall(SB),NOSPLIT,$0-28
|
||||||
|
JMP syscall·RawSyscall(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
|
||||||
|
JMP syscall·RawSyscall6(SB)
|
29
vendor/golang.org/x/sys/unix/asm_darwin_amd64.s
generated
vendored
Normal file
29
vendor/golang.org/x/sys/unix/asm_darwin_amd64.s
generated
vendored
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !gccgo
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// System call support for AMD64, Darwin
|
||||||
|
//
|
||||||
|
|
||||||
|
// Just jump to package syscall's implementation for all these functions.
|
||||||
|
// The runtime may know about them.
|
||||||
|
|
||||||
|
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
||||||
|
JMP syscall·Syscall(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
||||||
|
JMP syscall·Syscall6(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall9(SB),NOSPLIT,$0-104
|
||||||
|
JMP syscall·Syscall9(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
||||||
|
JMP syscall·RawSyscall(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
||||||
|
JMP syscall·RawSyscall6(SB)
|
30
vendor/golang.org/x/sys/unix/asm_darwin_arm.s
generated
vendored
Normal file
30
vendor/golang.org/x/sys/unix/asm_darwin_arm.s
generated
vendored
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
// Copyright 2015 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !gccgo
|
||||||
|
// +build arm,darwin
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// System call support for ARM, Darwin
|
||||||
|
//
|
||||||
|
|
||||||
|
// Just jump to package syscall's implementation for all these functions.
|
||||||
|
// The runtime may know about them.
|
||||||
|
|
||||||
|
TEXT ·Syscall(SB),NOSPLIT,$0-28
|
||||||
|
B syscall·Syscall(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall6(SB),NOSPLIT,$0-40
|
||||||
|
B syscall·Syscall6(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall9(SB),NOSPLIT,$0-52
|
||||||
|
B syscall·Syscall9(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall(SB),NOSPLIT,$0-28
|
||||||
|
B syscall·RawSyscall(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
|
||||||
|
B syscall·RawSyscall6(SB)
|
30
vendor/golang.org/x/sys/unix/asm_darwin_arm64.s
generated
vendored
Normal file
30
vendor/golang.org/x/sys/unix/asm_darwin_arm64.s
generated
vendored
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
// Copyright 2015 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !gccgo
|
||||||
|
// +build arm64,darwin
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// System call support for AMD64, Darwin
|
||||||
|
//
|
||||||
|
|
||||||
|
// Just jump to package syscall's implementation for all these functions.
|
||||||
|
// The runtime may know about them.
|
||||||
|
|
||||||
|
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
||||||
|
B syscall·Syscall(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
||||||
|
B syscall·Syscall6(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall9(SB),NOSPLIT,$0-104
|
||||||
|
B syscall·Syscall9(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
||||||
|
B syscall·RawSyscall(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
||||||
|
B syscall·RawSyscall6(SB)
|
29
vendor/golang.org/x/sys/unix/asm_dragonfly_amd64.s
generated
vendored
Normal file
29
vendor/golang.org/x/sys/unix/asm_dragonfly_amd64.s
generated
vendored
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !gccgo
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// System call support for AMD64, DragonFly
|
||||||
|
//
|
||||||
|
|
||||||
|
// Just jump to package syscall's implementation for all these functions.
|
||||||
|
// The runtime may know about them.
|
||||||
|
|
||||||
|
TEXT ·Syscall(SB),NOSPLIT,$0-64
|
||||||
|
JMP syscall·Syscall(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall6(SB),NOSPLIT,$0-88
|
||||||
|
JMP syscall·Syscall6(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall9(SB),NOSPLIT,$0-112
|
||||||
|
JMP syscall·Syscall9(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall(SB),NOSPLIT,$0-64
|
||||||
|
JMP syscall·RawSyscall(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall6(SB),NOSPLIT,$0-88
|
||||||
|
JMP syscall·RawSyscall6(SB)
|
29
vendor/golang.org/x/sys/unix/asm_freebsd_386.s
generated
vendored
Normal file
29
vendor/golang.org/x/sys/unix/asm_freebsd_386.s
generated
vendored
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !gccgo
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// System call support for 386, FreeBSD
|
||||||
|
//
|
||||||
|
|
||||||
|
// Just jump to package syscall's implementation for all these functions.
|
||||||
|
// The runtime may know about them.
|
||||||
|
|
||||||
|
TEXT ·Syscall(SB),NOSPLIT,$0-28
|
||||||
|
JMP syscall·Syscall(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall6(SB),NOSPLIT,$0-40
|
||||||
|
JMP syscall·Syscall6(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall9(SB),NOSPLIT,$0-52
|
||||||
|
JMP syscall·Syscall9(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall(SB),NOSPLIT,$0-28
|
||||||
|
JMP syscall·RawSyscall(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
|
||||||
|
JMP syscall·RawSyscall6(SB)
|
29
vendor/golang.org/x/sys/unix/asm_freebsd_amd64.s
generated
vendored
Normal file
29
vendor/golang.org/x/sys/unix/asm_freebsd_amd64.s
generated
vendored
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !gccgo
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// System call support for AMD64, FreeBSD
|
||||||
|
//
|
||||||
|
|
||||||
|
// Just jump to package syscall's implementation for all these functions.
|
||||||
|
// The runtime may know about them.
|
||||||
|
|
||||||
|
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
||||||
|
JMP syscall·Syscall(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
||||||
|
JMP syscall·Syscall6(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall9(SB),NOSPLIT,$0-104
|
||||||
|
JMP syscall·Syscall9(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
||||||
|
JMP syscall·RawSyscall(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
||||||
|
JMP syscall·RawSyscall6(SB)
|
29
vendor/golang.org/x/sys/unix/asm_freebsd_arm.s
generated
vendored
Normal file
29
vendor/golang.org/x/sys/unix/asm_freebsd_arm.s
generated
vendored
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
// Copyright 2012 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !gccgo
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// System call support for ARM, FreeBSD
|
||||||
|
//
|
||||||
|
|
||||||
|
// Just jump to package syscall's implementation for all these functions.
|
||||||
|
// The runtime may know about them.
|
||||||
|
|
||||||
|
TEXT ·Syscall(SB),NOSPLIT,$0-28
|
||||||
|
B syscall·Syscall(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall6(SB),NOSPLIT,$0-40
|
||||||
|
B syscall·Syscall6(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall9(SB),NOSPLIT,$0-52
|
||||||
|
B syscall·Syscall9(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall(SB),NOSPLIT,$0-28
|
||||||
|
B syscall·RawSyscall(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
|
||||||
|
B syscall·RawSyscall6(SB)
|
35
vendor/golang.org/x/sys/unix/asm_linux_386.s
generated
vendored
Normal file
35
vendor/golang.org/x/sys/unix/asm_linux_386.s
generated
vendored
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !gccgo
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// System calls for 386, Linux
|
||||||
|
//
|
||||||
|
|
||||||
|
// Just jump to package syscall's implementation for all these functions.
|
||||||
|
// The runtime may know about them.
|
||||||
|
|
||||||
|
TEXT ·Syscall(SB),NOSPLIT,$0-28
|
||||||
|
JMP syscall·Syscall(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall6(SB),NOSPLIT,$0-40
|
||||||
|
JMP syscall·Syscall6(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall(SB),NOSPLIT,$0-28
|
||||||
|
JMP syscall·RawSyscall(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
|
||||||
|
JMP syscall·RawSyscall6(SB)
|
||||||
|
|
||||||
|
TEXT ·socketcall(SB),NOSPLIT,$0-36
|
||||||
|
JMP syscall·socketcall(SB)
|
||||||
|
|
||||||
|
TEXT ·rawsocketcall(SB),NOSPLIT,$0-36
|
||||||
|
JMP syscall·rawsocketcall(SB)
|
||||||
|
|
||||||
|
TEXT ·seek(SB),NOSPLIT,$0-28
|
||||||
|
JMP syscall·seek(SB)
|
29
vendor/golang.org/x/sys/unix/asm_linux_amd64.s
generated
vendored
Normal file
29
vendor/golang.org/x/sys/unix/asm_linux_amd64.s
generated
vendored
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !gccgo
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// System calls for AMD64, Linux
|
||||||
|
//
|
||||||
|
|
||||||
|
// Just jump to package syscall's implementation for all these functions.
|
||||||
|
// The runtime may know about them.
|
||||||
|
|
||||||
|
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
||||||
|
JMP syscall·Syscall(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
||||||
|
JMP syscall·Syscall6(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
||||||
|
JMP syscall·RawSyscall(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
||||||
|
JMP syscall·RawSyscall6(SB)
|
||||||
|
|
||||||
|
TEXT ·gettimeofday(SB),NOSPLIT,$0-16
|
||||||
|
JMP syscall·gettimeofday(SB)
|
29
vendor/golang.org/x/sys/unix/asm_linux_arm.s
generated
vendored
Normal file
29
vendor/golang.org/x/sys/unix/asm_linux_arm.s
generated
vendored
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !gccgo
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// System calls for arm, Linux
|
||||||
|
//
|
||||||
|
|
||||||
|
// Just jump to package syscall's implementation for all these functions.
|
||||||
|
// The runtime may know about them.
|
||||||
|
|
||||||
|
TEXT ·Syscall(SB),NOSPLIT,$0-28
|
||||||
|
B syscall·Syscall(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall6(SB),NOSPLIT,$0-40
|
||||||
|
B syscall·Syscall6(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall(SB),NOSPLIT,$0-28
|
||||||
|
B syscall·RawSyscall(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
|
||||||
|
B syscall·RawSyscall6(SB)
|
||||||
|
|
||||||
|
TEXT ·seek(SB),NOSPLIT,$0-32
|
||||||
|
B syscall·seek(SB)
|
24
vendor/golang.org/x/sys/unix/asm_linux_arm64.s
generated
vendored
Normal file
24
vendor/golang.org/x/sys/unix/asm_linux_arm64.s
generated
vendored
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
// Copyright 2015 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build linux
|
||||||
|
// +build arm64
|
||||||
|
// +build !gccgo
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
// Just jump to package syscall's implementation for all these functions.
|
||||||
|
// The runtime may know about them.
|
||||||
|
|
||||||
|
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
||||||
|
B syscall·Syscall(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
||||||
|
B syscall·Syscall6(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
||||||
|
B syscall·RawSyscall(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
||||||
|
B syscall·RawSyscall6(SB)
|
28
vendor/golang.org/x/sys/unix/asm_linux_mips64x.s
generated
vendored
Normal file
28
vendor/golang.org/x/sys/unix/asm_linux_mips64x.s
generated
vendored
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
// Copyright 2015 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build linux
|
||||||
|
// +build mips64 mips64le
|
||||||
|
// +build !gccgo
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// System calls for mips64, Linux
|
||||||
|
//
|
||||||
|
|
||||||
|
// Just jump to package syscall's implementation for all these functions.
|
||||||
|
// The runtime may know about them.
|
||||||
|
|
||||||
|
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
||||||
|
JMP syscall·Syscall(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
||||||
|
JMP syscall·Syscall6(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
||||||
|
JMP syscall·RawSyscall(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
||||||
|
JMP syscall·RawSyscall6(SB)
|
31
vendor/golang.org/x/sys/unix/asm_linux_mipsx.s
generated
vendored
Normal file
31
vendor/golang.org/x/sys/unix/asm_linux_mipsx.s
generated
vendored
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
// Copyright 2016 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build linux
|
||||||
|
// +build mips mipsle
|
||||||
|
// +build !gccgo
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// System calls for mips, Linux
|
||||||
|
//
|
||||||
|
|
||||||
|
// Just jump to package syscall's implementation for all these functions.
|
||||||
|
// The runtime may know about them.
|
||||||
|
|
||||||
|
TEXT ·Syscall(SB),NOSPLIT,$0-28
|
||||||
|
JMP syscall·Syscall(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall6(SB),NOSPLIT,$0-40
|
||||||
|
JMP syscall·Syscall6(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall9(SB),NOSPLIT,$0-52
|
||||||
|
JMP syscall·Syscall9(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall(SB),NOSPLIT,$0-28
|
||||||
|
JMP syscall·RawSyscall(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
|
||||||
|
JMP syscall·RawSyscall6(SB)
|
28
vendor/golang.org/x/sys/unix/asm_linux_ppc64x.s
generated
vendored
Normal file
28
vendor/golang.org/x/sys/unix/asm_linux_ppc64x.s
generated
vendored
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build linux
|
||||||
|
// +build ppc64 ppc64le
|
||||||
|
// +build !gccgo
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// System calls for ppc64, Linux
|
||||||
|
//
|
||||||
|
|
||||||
|
// Just jump to package syscall's implementation for all these functions.
|
||||||
|
// The runtime may know about them.
|
||||||
|
|
||||||
|
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
||||||
|
BR syscall·Syscall(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
||||||
|
BR syscall·Syscall6(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
||||||
|
BR syscall·RawSyscall(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
||||||
|
BR syscall·RawSyscall6(SB)
|
28
vendor/golang.org/x/sys/unix/asm_linux_s390x.s
generated
vendored
Normal file
28
vendor/golang.org/x/sys/unix/asm_linux_s390x.s
generated
vendored
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
// Copyright 2016 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build s390x
|
||||||
|
// +build linux
|
||||||
|
// +build !gccgo
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// System calls for s390x, Linux
|
||||||
|
//
|
||||||
|
|
||||||
|
// Just jump to package syscall's implementation for all these functions.
|
||||||
|
// The runtime may know about them.
|
||||||
|
|
||||||
|
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
||||||
|
BR syscall·Syscall(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
||||||
|
BR syscall·Syscall6(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
||||||
|
BR syscall·RawSyscall(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
||||||
|
BR syscall·RawSyscall6(SB)
|
29
vendor/golang.org/x/sys/unix/asm_netbsd_386.s
generated
vendored
Normal file
29
vendor/golang.org/x/sys/unix/asm_netbsd_386.s
generated
vendored
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !gccgo
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// System call support for 386, NetBSD
|
||||||
|
//
|
||||||
|
|
||||||
|
// Just jump to package syscall's implementation for all these functions.
|
||||||
|
// The runtime may know about them.
|
||||||
|
|
||||||
|
TEXT ·Syscall(SB),NOSPLIT,$0-28
|
||||||
|
JMP syscall·Syscall(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall6(SB),NOSPLIT,$0-40
|
||||||
|
JMP syscall·Syscall6(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall9(SB),NOSPLIT,$0-52
|
||||||
|
JMP syscall·Syscall9(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall(SB),NOSPLIT,$0-28
|
||||||
|
JMP syscall·RawSyscall(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
|
||||||
|
JMP syscall·RawSyscall6(SB)
|
29
vendor/golang.org/x/sys/unix/asm_netbsd_amd64.s
generated
vendored
Normal file
29
vendor/golang.org/x/sys/unix/asm_netbsd_amd64.s
generated
vendored
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !gccgo
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// System call support for AMD64, NetBSD
|
||||||
|
//
|
||||||
|
|
||||||
|
// Just jump to package syscall's implementation for all these functions.
|
||||||
|
// The runtime may know about them.
|
||||||
|
|
||||||
|
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
||||||
|
JMP syscall·Syscall(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
||||||
|
JMP syscall·Syscall6(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall9(SB),NOSPLIT,$0-104
|
||||||
|
JMP syscall·Syscall9(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
||||||
|
JMP syscall·RawSyscall(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
||||||
|
JMP syscall·RawSyscall6(SB)
|
29
vendor/golang.org/x/sys/unix/asm_netbsd_arm.s
generated
vendored
Normal file
29
vendor/golang.org/x/sys/unix/asm_netbsd_arm.s
generated
vendored
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
// Copyright 2013 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !gccgo
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// System call support for ARM, NetBSD
|
||||||
|
//
|
||||||
|
|
||||||
|
// Just jump to package syscall's implementation for all these functions.
|
||||||
|
// The runtime may know about them.
|
||||||
|
|
||||||
|
TEXT ·Syscall(SB),NOSPLIT,$0-28
|
||||||
|
B syscall·Syscall(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall6(SB),NOSPLIT,$0-40
|
||||||
|
B syscall·Syscall6(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall9(SB),NOSPLIT,$0-52
|
||||||
|
B syscall·Syscall9(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall(SB),NOSPLIT,$0-28
|
||||||
|
B syscall·RawSyscall(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
|
||||||
|
B syscall·RawSyscall6(SB)
|
29
vendor/golang.org/x/sys/unix/asm_openbsd_386.s
generated
vendored
Normal file
29
vendor/golang.org/x/sys/unix/asm_openbsd_386.s
generated
vendored
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !gccgo
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// System call support for 386, OpenBSD
|
||||||
|
//
|
||||||
|
|
||||||
|
// Just jump to package syscall's implementation for all these functions.
|
||||||
|
// The runtime may know about them.
|
||||||
|
|
||||||
|
TEXT ·Syscall(SB),NOSPLIT,$0-28
|
||||||
|
JMP syscall·Syscall(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall6(SB),NOSPLIT,$0-40
|
||||||
|
JMP syscall·Syscall6(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall9(SB),NOSPLIT,$0-52
|
||||||
|
JMP syscall·Syscall9(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall(SB),NOSPLIT,$0-28
|
||||||
|
JMP syscall·RawSyscall(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
|
||||||
|
JMP syscall·RawSyscall6(SB)
|
29
vendor/golang.org/x/sys/unix/asm_openbsd_amd64.s
generated
vendored
Normal file
29
vendor/golang.org/x/sys/unix/asm_openbsd_amd64.s
generated
vendored
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !gccgo
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// System call support for AMD64, OpenBSD
|
||||||
|
//
|
||||||
|
|
||||||
|
// Just jump to package syscall's implementation for all these functions.
|
||||||
|
// The runtime may know about them.
|
||||||
|
|
||||||
|
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
||||||
|
JMP syscall·Syscall(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
||||||
|
JMP syscall·Syscall6(SB)
|
||||||
|
|
||||||
|
TEXT ·Syscall9(SB),NOSPLIT,$0-104
|
||||||
|
JMP syscall·Syscall9(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
||||||
|
JMP syscall·RawSyscall(SB)
|
||||||
|
|
||||||
|
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
||||||
|
JMP syscall·RawSyscall6(SB)
|
17
vendor/golang.org/x/sys/unix/asm_solaris_amd64.s
generated
vendored
Normal file
17
vendor/golang.org/x/sys/unix/asm_solaris_amd64.s
generated
vendored
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !gccgo
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// System calls for amd64, Solaris are implemented in runtime/syscall_solaris.go
|
||||||
|
//
|
||||||
|
|
||||||
|
TEXT ·sysvicall6(SB),NOSPLIT,$0-64
|
||||||
|
JMP syscall·sysvicall6(SB)
|
||||||
|
|
||||||
|
TEXT ·rawSysvicall6(SB),NOSPLIT,$0-64
|
||||||
|
JMP syscall·rawSysvicall6(SB)
|
35
vendor/golang.org/x/sys/unix/bluetooth_linux.go
generated
vendored
Normal file
35
vendor/golang.org/x/sys/unix/bluetooth_linux.go
generated
vendored
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
// Copyright 2016 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Bluetooth sockets and messages
|
||||||
|
|
||||||
|
package unix
|
||||||
|
|
||||||
|
// Bluetooth Protocols
|
||||||
|
const (
|
||||||
|
BTPROTO_L2CAP = 0
|
||||||
|
BTPROTO_HCI = 1
|
||||||
|
BTPROTO_SCO = 2
|
||||||
|
BTPROTO_RFCOMM = 3
|
||||||
|
BTPROTO_BNEP = 4
|
||||||
|
BTPROTO_CMTP = 5
|
||||||
|
BTPROTO_HIDP = 6
|
||||||
|
BTPROTO_AVDTP = 7
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
HCI_CHANNEL_RAW = 0
|
||||||
|
HCI_CHANNEL_USER = 1
|
||||||
|
HCI_CHANNEL_MONITOR = 2
|
||||||
|
HCI_CHANNEL_CONTROL = 3
|
||||||
|
)
|
||||||
|
|
||||||
|
// Socketoption Level
|
||||||
|
const (
|
||||||
|
SOL_BLUETOOTH = 0x112
|
||||||
|
SOL_HCI = 0x0
|
||||||
|
SOL_L2CAP = 0x6
|
||||||
|
SOL_RFCOMM = 0x12
|
||||||
|
SOL_SCO = 0x11
|
||||||
|
)
|
13
vendor/golang.org/x/sys/unix/constants.go
generated
vendored
Normal file
13
vendor/golang.org/x/sys/unix/constants.go
generated
vendored
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
// Copyright 2015 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build darwin dragonfly freebsd linux netbsd openbsd solaris
|
||||||
|
|
||||||
|
package unix
|
||||||
|
|
||||||
|
const (
|
||||||
|
R_OK = 0x4
|
||||||
|
W_OK = 0x2
|
||||||
|
X_OK = 0x1
|
||||||
|
)
|
27
vendor/golang.org/x/sys/unix/env_unix.go
generated
vendored
Normal file
27
vendor/golang.org/x/sys/unix/env_unix.go
generated
vendored
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
// Copyright 2010 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build darwin dragonfly freebsd linux netbsd openbsd solaris
|
||||||
|
|
||||||
|
// Unix environment variables.
|
||||||
|
|
||||||
|
package unix
|
||||||
|
|
||||||
|
import "syscall"
|
||||||
|
|
||||||
|
func Getenv(key string) (value string, found bool) {
|
||||||
|
return syscall.Getenv(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Setenv(key, value string) error {
|
||||||
|
return syscall.Setenv(key, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Clearenv() {
|
||||||
|
syscall.Clearenv()
|
||||||
|
}
|
||||||
|
|
||||||
|
func Environ() []string {
|
||||||
|
return syscall.Environ()
|
||||||
|
}
|
14
vendor/golang.org/x/sys/unix/env_unset.go
generated
vendored
Normal file
14
vendor/golang.org/x/sys/unix/env_unset.go
generated
vendored
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build go1.4
|
||||||
|
|
||||||
|
package unix
|
||||||
|
|
||||||
|
import "syscall"
|
||||||
|
|
||||||
|
func Unsetenv(key string) error {
|
||||||
|
// This was added in Go 1.4.
|
||||||
|
return syscall.Unsetenv(key)
|
||||||
|
}
|
24
vendor/golang.org/x/sys/unix/flock.go
generated
vendored
Normal file
24
vendor/golang.org/x/sys/unix/flock.go
generated
vendored
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
// +build linux darwin freebsd openbsd netbsd dragonfly
|
||||||
|
|
||||||
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build darwin dragonfly freebsd linux netbsd openbsd
|
||||||
|
|
||||||
|
package unix
|
||||||
|
|
||||||
|
import "unsafe"
|
||||||
|
|
||||||
|
// fcntl64Syscall is usually SYS_FCNTL, but is overridden on 32-bit Linux
|
||||||
|
// systems by flock_linux_32bit.go to be SYS_FCNTL64.
|
||||||
|
var fcntl64Syscall uintptr = SYS_FCNTL
|
||||||
|
|
||||||
|
// FcntlFlock performs a fcntl syscall for the F_GETLK, F_SETLK or F_SETLKW command.
|
||||||
|
func FcntlFlock(fd uintptr, cmd int, lk *Flock_t) error {
|
||||||
|
_, _, errno := Syscall(fcntl64Syscall, fd, uintptr(cmd), uintptr(unsafe.Pointer(lk)))
|
||||||
|
if errno == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return errno
|
||||||
|
}
|
13
vendor/golang.org/x/sys/unix/flock_linux_32bit.go
generated
vendored
Normal file
13
vendor/golang.org/x/sys/unix/flock_linux_32bit.go
generated
vendored
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
// +build linux,386 linux,arm linux,mips linux,mipsle
|
||||||
|
|
||||||
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package unix
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
// On 32-bit Linux systems, the fcntl syscall that matches Go's
|
||||||
|
// Flock_t type is SYS_FCNTL64, not SYS_FCNTL.
|
||||||
|
fcntl64Syscall = SYS_FCNTL64
|
||||||
|
}
|
46
vendor/golang.org/x/sys/unix/gccgo.go
generated
vendored
Normal file
46
vendor/golang.org/x/sys/unix/gccgo.go
generated
vendored
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
// Copyright 2015 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build gccgo
|
||||||
|
|
||||||
|
package unix
|
||||||
|
|
||||||
|
import "syscall"
|
||||||
|
|
||||||
|
// We can't use the gc-syntax .s files for gccgo. On the plus side
|
||||||
|
// much of the functionality can be written directly in Go.
|
||||||
|
|
||||||
|
//extern gccgoRealSyscall
|
||||||
|
func realSyscall(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r, errno uintptr)
|
||||||
|
|
||||||
|
func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno) {
|
||||||
|
syscall.Entersyscall()
|
||||||
|
r, errno := realSyscall(trap, a1, a2, a3, 0, 0, 0, 0, 0, 0)
|
||||||
|
syscall.Exitsyscall()
|
||||||
|
return r, 0, syscall.Errno(errno)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno) {
|
||||||
|
syscall.Entersyscall()
|
||||||
|
r, errno := realSyscall(trap, a1, a2, a3, a4, a5, a6, 0, 0, 0)
|
||||||
|
syscall.Exitsyscall()
|
||||||
|
return r, 0, syscall.Errno(errno)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno) {
|
||||||
|
syscall.Entersyscall()
|
||||||
|
r, errno := realSyscall(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9)
|
||||||
|
syscall.Exitsyscall()
|
||||||
|
return r, 0, syscall.Errno(errno)
|
||||||
|
}
|
||||||
|
|
||||||
|
func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno) {
|
||||||
|
r, errno := realSyscall(trap, a1, a2, a3, 0, 0, 0, 0, 0, 0)
|
||||||
|
return r, 0, syscall.Errno(errno)
|
||||||
|
}
|
||||||
|
|
||||||
|
func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno) {
|
||||||
|
r, errno := realSyscall(trap, a1, a2, a3, a4, a5, a6, 0, 0, 0)
|
||||||
|
return r, 0, syscall.Errno(errno)
|
||||||
|
}
|
41
vendor/golang.org/x/sys/unix/gccgo_c.c
generated
vendored
Normal file
41
vendor/golang.org/x/sys/unix/gccgo_c.c
generated
vendored
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
// Copyright 2015 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build gccgo
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#define _STRINGIFY2_(x) #x
|
||||||
|
#define _STRINGIFY_(x) _STRINGIFY2_(x)
|
||||||
|
#define GOSYM_PREFIX _STRINGIFY_(__USER_LABEL_PREFIX__)
|
||||||
|
|
||||||
|
// Call syscall from C code because the gccgo support for calling from
|
||||||
|
// Go to C does not support varargs functions.
|
||||||
|
|
||||||
|
struct ret {
|
||||||
|
uintptr_t r;
|
||||||
|
uintptr_t err;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ret
|
||||||
|
gccgoRealSyscall(uintptr_t trap, uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, uintptr_t a5, uintptr_t a6, uintptr_t a7, uintptr_t a8, uintptr_t a9)
|
||||||
|
{
|
||||||
|
struct ret r;
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
r.r = syscall(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9);
|
||||||
|
r.err = errno;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Define the use function in C so that it is not inlined.
|
||||||
|
|
||||||
|
extern void use(void *) __asm__ (GOSYM_PREFIX GOPKGPATH ".use") __attribute__((noinline));
|
||||||
|
|
||||||
|
void
|
||||||
|
use(void *p __attribute__ ((unused)))
|
||||||
|
{
|
||||||
|
}
|
20
vendor/golang.org/x/sys/unix/gccgo_linux_amd64.go
generated
vendored
Normal file
20
vendor/golang.org/x/sys/unix/gccgo_linux_amd64.go
generated
vendored
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
// Copyright 2015 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build gccgo,linux,amd64
|
||||||
|
|
||||||
|
package unix
|
||||||
|
|
||||||
|
import "syscall"
|
||||||
|
|
||||||
|
//extern gettimeofday
|
||||||
|
func realGettimeofday(*Timeval, *byte) int32
|
||||||
|
|
||||||
|
func gettimeofday(tv *Timeval) (err syscall.Errno) {
|
||||||
|
r := realGettimeofday(tv, nil)
|
||||||
|
if r < 0 {
|
||||||
|
return syscall.GetErrno()
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
20
vendor/golang.org/x/sys/unix/gccgo_linux_sparc64.go
generated
vendored
Normal file
20
vendor/golang.org/x/sys/unix/gccgo_linux_sparc64.go
generated
vendored
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
// Copyright 2016 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build gccgo,linux,sparc64
|
||||||
|
|
||||||
|
package unix
|
||||||
|
|
||||||
|
import "syscall"
|
||||||
|
|
||||||
|
//extern sysconf
|
||||||
|
func realSysconf(name int) int64
|
||||||
|
|
||||||
|
func sysconf(name int) (n int64, err syscall.Errno) {
|
||||||
|
r := realSysconf(name)
|
||||||
|
if r < 0 {
|
||||||
|
return 0, syscall.GetErrno()
|
||||||
|
}
|
||||||
|
return r, 0
|
||||||
|
}
|
62
vendor/golang.org/x/sys/unix/mkpost.go
generated
vendored
Normal file
62
vendor/golang.org/x/sys/unix/mkpost.go
generated
vendored
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
// Copyright 2016 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build ignore
|
||||||
|
|
||||||
|
// mkpost processes the output of cgo -godefs to
|
||||||
|
// modify the generated types. It is used to clean up
|
||||||
|
// the sys API in an architecture specific manner.
|
||||||
|
//
|
||||||
|
// mkpost is run after cgo -godefs by mkall.sh.
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"go/format"
|
||||||
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"regexp"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
b, err := ioutil.ReadAll(os.Stdin)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
s := string(b)
|
||||||
|
|
||||||
|
goarch := os.Getenv("GOARCH")
|
||||||
|
goos := os.Getenv("GOOS")
|
||||||
|
if goarch == "s390x" && goos == "linux" {
|
||||||
|
// Export the types of PtraceRegs fields.
|
||||||
|
re := regexp.MustCompile("ptrace(Psw|Fpregs|Per)")
|
||||||
|
s = re.ReplaceAllString(s, "Ptrace$1")
|
||||||
|
|
||||||
|
// Replace padding fields inserted by cgo with blank identifiers.
|
||||||
|
re = regexp.MustCompile("Pad_cgo[A-Za-z0-9_]*")
|
||||||
|
s = re.ReplaceAllString(s, "_")
|
||||||
|
|
||||||
|
// Replace other unwanted fields with blank identifiers.
|
||||||
|
re = regexp.MustCompile("X_[A-Za-z0-9_]*")
|
||||||
|
s = re.ReplaceAllString(s, "_")
|
||||||
|
|
||||||
|
// Replace the control_regs union with a blank identifier for now.
|
||||||
|
re = regexp.MustCompile("(Control_regs)\\s+\\[0\\]uint64")
|
||||||
|
s = re.ReplaceAllString(s, "_ [0]uint64")
|
||||||
|
}
|
||||||
|
|
||||||
|
// gofmt
|
||||||
|
b, err = format.Source([]byte(s))
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Append this command to the header to show where the new file
|
||||||
|
// came from.
|
||||||
|
re := regexp.MustCompile("(cgo -godefs [a-zA-Z0-9_]+\\.go.*)")
|
||||||
|
b = re.ReplaceAll(b, []byte("$1 | go run mkpost.go"))
|
||||||
|
|
||||||
|
fmt.Printf("%s", b)
|
||||||
|
}
|
30
vendor/golang.org/x/sys/unix/race.go
generated
vendored
Normal file
30
vendor/golang.org/x/sys/unix/race.go
generated
vendored
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
// Copyright 2012 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build darwin,race linux,race freebsd,race
|
||||||
|
|
||||||
|
package unix
|
||||||
|
|
||||||
|
import (
|
||||||
|
"runtime"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
const raceenabled = true
|
||||||
|
|
||||||
|
func raceAcquire(addr unsafe.Pointer) {
|
||||||
|
runtime.RaceAcquire(addr)
|
||||||
|
}
|
||||||
|
|
||||||
|
func raceReleaseMerge(addr unsafe.Pointer) {
|
||||||
|
runtime.RaceReleaseMerge(addr)
|
||||||
|
}
|
||||||
|
|
||||||
|
func raceReadRange(addr unsafe.Pointer, len int) {
|
||||||
|
runtime.RaceReadRange(addr, len)
|
||||||
|
}
|
||||||
|
|
||||||
|
func raceWriteRange(addr unsafe.Pointer, len int) {
|
||||||
|
runtime.RaceWriteRange(addr, len)
|
||||||
|
}
|
25
vendor/golang.org/x/sys/unix/race0.go
generated
vendored
Normal file
25
vendor/golang.org/x/sys/unix/race0.go
generated
vendored
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
// Copyright 2012 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build darwin,!race linux,!race freebsd,!race netbsd openbsd solaris dragonfly
|
||||||
|
|
||||||
|
package unix
|
||||||
|
|
||||||
|
import (
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
const raceenabled = false
|
||||||
|
|
||||||
|
func raceAcquire(addr unsafe.Pointer) {
|
||||||
|
}
|
||||||
|
|
||||||
|
func raceReleaseMerge(addr unsafe.Pointer) {
|
||||||
|
}
|
||||||
|
|
||||||
|
func raceReadRange(addr unsafe.Pointer, len int) {
|
||||||
|
}
|
||||||
|
|
||||||
|
func raceWriteRange(addr unsafe.Pointer, len int) {
|
||||||
|
}
|
36
vendor/golang.org/x/sys/unix/sockcmsg_linux.go
generated
vendored
Normal file
36
vendor/golang.org/x/sys/unix/sockcmsg_linux.go
generated
vendored
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
// Socket control messages
|
||||||
|
|
||||||
|
package unix
|
||||||
|
|
||||||
|
import "unsafe"
|
||||||
|
|
||||||
|
// UnixCredentials encodes credentials into a socket control message
|
||||||
|
// for sending to another process. This can be used for
|
||||||
|
// authentication.
|
||||||
|
func UnixCredentials(ucred *Ucred) []byte {
|
||||||
|
b := make([]byte, CmsgSpace(SizeofUcred))
|
||||||
|
h := (*Cmsghdr)(unsafe.Pointer(&b[0]))
|
||||||
|
h.Level = SOL_SOCKET
|
||||||
|
h.Type = SCM_CREDENTIALS
|
||||||
|
h.SetLen(CmsgLen(SizeofUcred))
|
||||||
|
*((*Ucred)(cmsgData(h))) = *ucred
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseUnixCredentials decodes a socket control message that contains
|
||||||
|
// credentials in a Ucred structure. To receive such a message, the
|
||||||
|
// SO_PASSCRED option must be enabled on the socket.
|
||||||
|
func ParseUnixCredentials(m *SocketControlMessage) (*Ucred, error) {
|
||||||
|
if m.Header.Level != SOL_SOCKET {
|
||||||
|
return nil, EINVAL
|
||||||
|
}
|
||||||
|
if m.Header.Type != SCM_CREDENTIALS {
|
||||||
|
return nil, EINVAL
|
||||||
|
}
|
||||||
|
ucred := *(*Ucred)(unsafe.Pointer(&m.Data[0]))
|
||||||
|
return &ucred, nil
|
||||||
|
}
|
103
vendor/golang.org/x/sys/unix/sockcmsg_unix.go
generated
vendored
Normal file
103
vendor/golang.org/x/sys/unix/sockcmsg_unix.go
generated
vendored
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
// 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 netbsd openbsd solaris
|
||||||
|
|
||||||
|
// Socket control messages
|
||||||
|
|
||||||
|
package unix
|
||||||
|
|
||||||
|
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 {
|
||||||
|
salign = 4
|
||||||
|
}
|
||||||
|
return (salen + salign - 1) & ^(salign - 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CmsgLen returns the value to store in the Len field of the Cmsghdr
|
||||||
|
// structure, taking into account any necessary alignment.
|
||||||
|
func CmsgLen(datalen int) int {
|
||||||
|
return cmsgAlignOf(SizeofCmsghdr) + datalen
|
||||||
|
}
|
||||||
|
|
||||||
|
// CmsgSpace returns the number of bytes an ancillary element with
|
||||||
|
// payload of the passed data length occupies.
|
||||||
|
func CmsgSpace(datalen int) int {
|
||||||
|
return cmsgAlignOf(SizeofCmsghdr) + cmsgAlignOf(datalen)
|
||||||
|
}
|
||||||
|
|
||||||
|
func cmsgData(h *Cmsghdr) unsafe.Pointer {
|
||||||
|
return unsafe.Pointer(uintptr(unsafe.Pointer(h)) + uintptr(cmsgAlignOf(SizeofCmsghdr)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// SocketControlMessage represents a socket control message.
|
||||||
|
type SocketControlMessage struct {
|
||||||
|
Header Cmsghdr
|
||||||
|
Data []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseSocketControlMessage parses b as an array of socket control
|
||||||
|
// messages.
|
||||||
|
func ParseSocketControlMessage(b []byte) ([]SocketControlMessage, error) {
|
||||||
|
var msgs []SocketControlMessage
|
||||||
|
i := 0
|
||||||
|
for i+CmsgLen(0) <= len(b) {
|
||||||
|
h, dbuf, err := socketControlMessageHeaderAndData(b[i:])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
m := SocketControlMessage{Header: *h, Data: dbuf}
|
||||||
|
msgs = append(msgs, m)
|
||||||
|
i += cmsgAlignOf(int(h.Len))
|
||||||
|
}
|
||||||
|
return msgs, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func socketControlMessageHeaderAndData(b []byte) (*Cmsghdr, []byte, error) {
|
||||||
|
h := (*Cmsghdr)(unsafe.Pointer(&b[0]))
|
||||||
|
if h.Len < SizeofCmsghdr || uint64(h.Len) > uint64(len(b)) {
|
||||||
|
return nil, nil, EINVAL
|
||||||
|
}
|
||||||
|
return h, b[cmsgAlignOf(SizeofCmsghdr):h.Len], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnixRights encodes a set of open file descriptors into a socket
|
||||||
|
// control message for sending to another process.
|
||||||
|
func UnixRights(fds ...int) []byte {
|
||||||
|
datalen := len(fds) * 4
|
||||||
|
b := make([]byte, CmsgSpace(datalen))
|
||||||
|
h := (*Cmsghdr)(unsafe.Pointer(&b[0]))
|
||||||
|
h.Level = SOL_SOCKET
|
||||||
|
h.Type = SCM_RIGHTS
|
||||||
|
h.SetLen(CmsgLen(datalen))
|
||||||
|
data := cmsgData(h)
|
||||||
|
for _, fd := range fds {
|
||||||
|
*(*int32)(data) = int32(fd)
|
||||||
|
data = unsafe.Pointer(uintptr(data) + 4)
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseUnixRights decodes a socket control message that contains an
|
||||||
|
// integer array of open file descriptors from another process.
|
||||||
|
func ParseUnixRights(m *SocketControlMessage) ([]int, error) {
|
||||||
|
if m.Header.Level != SOL_SOCKET {
|
||||||
|
return nil, EINVAL
|
||||||
|
}
|
||||||
|
if m.Header.Type != SCM_RIGHTS {
|
||||||
|
return nil, EINVAL
|
||||||
|
}
|
||||||
|
fds := make([]int, len(m.Data)>>2)
|
||||||
|
for i, j := 0, 0; i < len(m.Data); i += 4 {
|
||||||
|
fds[j] = int(*(*int32)(unsafe.Pointer(&m.Data[i])))
|
||||||
|
j++
|
||||||
|
}
|
||||||
|
return fds, nil
|
||||||
|
}
|
26
vendor/golang.org/x/sys/unix/str.go
generated
vendored
Normal file
26
vendor/golang.org/x/sys/unix/str.go
generated
vendored
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
// 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 netbsd openbsd solaris
|
||||||
|
|
||||||
|
package unix
|
||||||
|
|
||||||
|
func itoa(val int) string { // do it here rather than with fmt to avoid dependency
|
||||||
|
if val < 0 {
|
||||||
|
return "-" + uitoa(uint(-val))
|
||||||
|
}
|
||||||
|
return uitoa(uint(val))
|
||||||
|
}
|
||||||
|
|
||||||
|
func uitoa(val uint) string {
|
||||||
|
var buf [32]byte // big enough for int64
|
||||||
|
i := len(buf) - 1
|
||||||
|
for val >= 10 {
|
||||||
|
buf[i] = byte(val%10 + '0')
|
||||||
|
i--
|
||||||
|
val /= 10
|
||||||
|
}
|
||||||
|
buf[i] = byte(val + '0')
|
||||||
|
return string(buf[i:])
|
||||||
|
}
|
76
vendor/golang.org/x/sys/unix/syscall.go
generated
vendored
Normal file
76
vendor/golang.org/x/sys/unix/syscall.go
generated
vendored
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
// 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 netbsd openbsd solaris
|
||||||
|
|
||||||
|
// Package unix contains an interface to the low-level operating system
|
||||||
|
// 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
|
||||||
|
// you want to view documentation for freebsd/arm on linux/amd64, set $GOOS
|
||||||
|
// to freebsd and $GOARCH to arm.
|
||||||
|
// The primary use of this package is inside other packages that provide a more
|
||||||
|
// portable interface to the system, such as "os", "time" and "net". Use
|
||||||
|
// those packages rather than this one if you can.
|
||||||
|
// For details of the functions and data types in this package consult
|
||||||
|
// the manuals for the appropriate operating system.
|
||||||
|
// These calls return err == nil to indicate success; otherwise
|
||||||
|
// err represents an operating system error describing the failure and
|
||||||
|
// holds a value of type syscall.Errno.
|
||||||
|
package unix // import "golang.org/x/sys/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).
|
||||||
|
func ByteSliceFromString(s string) ([]byte, error) {
|
||||||
|
for i := 0; i < len(s); i++ {
|
||||||
|
if s[i] == 0 {
|
||||||
|
return nil, EINVAL
|
||||||
|
}
|
||||||
|
}
|
||||||
|
a := make([]byte, len(s)+1)
|
||||||
|
copy(a, s)
|
||||||
|
return a, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// BytePtrFromString returns a pointer to a NUL-terminated array of
|
||||||
|
// bytes containing the text of s. If s contains a NUL byte at any
|
||||||
|
// location, it returns (nil, EINVAL).
|
||||||
|
func BytePtrFromString(s string) (*byte, error) {
|
||||||
|
a, err := ByteSliceFromString(s)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &a[0], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Single-word zero for use when we need a valid pointer to 0 bytes.
|
||||||
|
// See 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)
|
614
vendor/golang.org/x/sys/unix/syscall_bsd.go
generated
vendored
Normal file
614
vendor/golang.org/x/sys/unix/syscall_bsd.go
generated
vendored
Normal file
|
@ -0,0 +1,614 @@
|
||||||
|
// 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 netbsd openbsd
|
||||||
|
|
||||||
|
// BSD system call wrappers shared by *BSD based systems
|
||||||
|
// including OS X (Darwin) and FreeBSD. Like the other
|
||||||
|
// syscall_*.go files it is compiled as Go code but also
|
||||||
|
// used as input to mksyscall which parses the //sys
|
||||||
|
// lines and generates system call stubs.
|
||||||
|
|
||||||
|
package unix
|
||||||
|
|
||||||
|
import (
|
||||||
|
"runtime"
|
||||||
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Wrapped
|
||||||
|
*/
|
||||||
|
|
||||||
|
//sysnb getgroups(ngid int, gid *_Gid_t) (n int, err error)
|
||||||
|
//sysnb setgroups(ngid int, gid *_Gid_t) (err error)
|
||||||
|
|
||||||
|
func Getgroups() (gids []int, err error) {
|
||||||
|
n, err := getgroups(0, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if n == 0 {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sanity check group count. Max is 16 on BSD.
|
||||||
|
if n < 0 || n > 1000 {
|
||||||
|
return nil, EINVAL
|
||||||
|
}
|
||||||
|
|
||||||
|
a := make([]_Gid_t, n)
|
||||||
|
n, err = getgroups(n, &a[0])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
gids = make([]int, n)
|
||||||
|
for i, v := range a[0:n] {
|
||||||
|
gids[i] = int(v)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func Setgroups(gids []int) (err error) {
|
||||||
|
if len(gids) == 0 {
|
||||||
|
return setgroups(0, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
a := make([]_Gid_t, len(gids))
|
||||||
|
for i, v := range gids {
|
||||||
|
a[i] = _Gid_t(v)
|
||||||
|
}
|
||||||
|
return setgroups(len(a), &a[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
func ReadDirent(fd int, buf []byte) (n int, err error) {
|
||||||
|
// Final argument is (basep *uintptr) and the syscall doesn't take nil.
|
||||||
|
// 64 bits should be enough. (32 bits isn't even on 386). Since the
|
||||||
|
// actual system call is getdirentries64, 64 is a good guess.
|
||||||
|
// TODO(rsc): Can we use a single global basep for all calls?
|
||||||
|
var base = (*uintptr)(unsafe.Pointer(new(uint64)))
|
||||||
|
return Getdirentries(fd, buf, base)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait status is 7 bits at bottom, either 0 (exited),
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
type WaitStatus uint32
|
||||||
|
|
||||||
|
const (
|
||||||
|
mask = 0x7F
|
||||||
|
core = 0x80
|
||||||
|
shift = 8
|
||||||
|
|
||||||
|
exited = 0
|
||||||
|
stopped = 0x7F
|
||||||
|
)
|
||||||
|
|
||||||
|
func (w WaitStatus) Exited() bool { return w&mask == exited }
|
||||||
|
|
||||||
|
func (w WaitStatus) ExitStatus() int {
|
||||||
|
if w&mask != exited {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
return int(w >> shift)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w WaitStatus) Signaled() bool { return w&mask != stopped && w&mask != 0 }
|
||||||
|
|
||||||
|
func (w WaitStatus) Signal() syscall.Signal {
|
||||||
|
sig := syscall.Signal(w & mask)
|
||||||
|
if sig == stopped || sig == 0 {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
return sig
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w WaitStatus) CoreDump() bool { return w.Signaled() && w&core != 0 }
|
||||||
|
|
||||||
|
func (w WaitStatus) Stopped() bool { return w&mask == stopped && syscall.Signal(w>>shift) != SIGSTOP }
|
||||||
|
|
||||||
|
func (w WaitStatus) Continued() bool { return w&mask == stopped && syscall.Signal(w>>shift) == SIGSTOP }
|
||||||
|
|
||||||
|
func (w WaitStatus) StopSignal() syscall.Signal {
|
||||||
|
if !w.Stopped() {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
return syscall.Signal(w>>shift) & 0xFF
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w WaitStatus) TrapCause() int { return -1 }
|
||||||
|
|
||||||
|
//sys wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error)
|
||||||
|
|
||||||
|
func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
|
||||||
|
var status _C_int
|
||||||
|
wpid, err = wait4(pid, &status, options, rusage)
|
||||||
|
if wstatus != nil {
|
||||||
|
*wstatus = WaitStatus(status)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error)
|
||||||
|
//sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
|
||||||
|
//sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
|
||||||
|
//sysnb socket(domain int, typ int, proto int) (fd int, err error)
|
||||||
|
//sys getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error)
|
||||||
|
//sys setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error)
|
||||||
|
//sysnb getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)
|
||||||
|
//sysnb getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)
|
||||||
|
//sys Shutdown(s int, how int) (err error)
|
||||||
|
|
||||||
|
func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {
|
||||||
|
if sa.Port < 0 || sa.Port > 0xFFFF {
|
||||||
|
return nil, 0, EINVAL
|
||||||
|
}
|
||||||
|
sa.raw.Len = SizeofSockaddrInet4
|
||||||
|
sa.raw.Family = AF_INET
|
||||||
|
p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
|
||||||
|
p[0] = byte(sa.Port >> 8)
|
||||||
|
p[1] = byte(sa.Port)
|
||||||
|
for i := 0; i < len(sa.Addr); i++ {
|
||||||
|
sa.raw.Addr[i] = sa.Addr[i]
|
||||||
|
}
|
||||||
|
return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) {
|
||||||
|
if sa.Port < 0 || sa.Port > 0xFFFF {
|
||||||
|
return nil, 0, EINVAL
|
||||||
|
}
|
||||||
|
sa.raw.Len = SizeofSockaddrInet6
|
||||||
|
sa.raw.Family = AF_INET6
|
||||||
|
p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
|
||||||
|
p[0] = byte(sa.Port >> 8)
|
||||||
|
p[1] = byte(sa.Port)
|
||||||
|
sa.raw.Scope_id = sa.ZoneId
|
||||||
|
for i := 0; i < len(sa.Addr); i++ {
|
||||||
|
sa.raw.Addr[i] = sa.Addr[i]
|
||||||
|
}
|
||||||
|
return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) {
|
||||||
|
name := sa.Name
|
||||||
|
n := len(name)
|
||||||
|
if n >= len(sa.raw.Path) || n == 0 {
|
||||||
|
return nil, 0, EINVAL
|
||||||
|
}
|
||||||
|
sa.raw.Len = byte(3 + n) // 2 for Family, Len; 1 for NUL
|
||||||
|
sa.raw.Family = AF_UNIX
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
|
sa.raw.Path[i] = int8(name[i])
|
||||||
|
}
|
||||||
|
return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sa *SockaddrDatalink) sockaddr() (unsafe.Pointer, _Socklen, error) {
|
||||||
|
if sa.Index == 0 {
|
||||||
|
return nil, 0, EINVAL
|
||||||
|
}
|
||||||
|
sa.raw.Len = sa.Len
|
||||||
|
sa.raw.Family = AF_LINK
|
||||||
|
sa.raw.Index = sa.Index
|
||||||
|
sa.raw.Type = sa.Type
|
||||||
|
sa.raw.Nlen = sa.Nlen
|
||||||
|
sa.raw.Alen = sa.Alen
|
||||||
|
sa.raw.Slen = sa.Slen
|
||||||
|
for i := 0; i < len(sa.raw.Data); i++ {
|
||||||
|
sa.raw.Data[i] = sa.Data[i]
|
||||||
|
}
|
||||||
|
return unsafe.Pointer(&sa.raw), SizeofSockaddrDatalink, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, error) {
|
||||||
|
switch rsa.Addr.Family {
|
||||||
|
case AF_LINK:
|
||||||
|
pp := (*RawSockaddrDatalink)(unsafe.Pointer(rsa))
|
||||||
|
sa := new(SockaddrDatalink)
|
||||||
|
sa.Len = pp.Len
|
||||||
|
sa.Family = pp.Family
|
||||||
|
sa.Index = pp.Index
|
||||||
|
sa.Type = pp.Type
|
||||||
|
sa.Nlen = pp.Nlen
|
||||||
|
sa.Alen = pp.Alen
|
||||||
|
sa.Slen = pp.Slen
|
||||||
|
for i := 0; i < len(sa.Data); i++ {
|
||||||
|
sa.Data[i] = pp.Data[i]
|
||||||
|
}
|
||||||
|
return sa, nil
|
||||||
|
|
||||||
|
case AF_UNIX:
|
||||||
|
pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))
|
||||||
|
if pp.Len < 2 || pp.Len > SizeofSockaddrUnix {
|
||||||
|
return nil, EINVAL
|
||||||
|
}
|
||||||
|
sa := new(SockaddrUnix)
|
||||||
|
|
||||||
|
// Some BSDs include the trailing NUL in the length, whereas
|
||||||
|
// others do not. Work around this by subtracting the leading
|
||||||
|
// family and len. The path is then scanned to see if a NUL
|
||||||
|
// terminator still exists within the length.
|
||||||
|
n := int(pp.Len) - 2 // subtract leading Family, Len
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
|
if pp.Path[i] == 0 {
|
||||||
|
// found early NUL; assume Len included the NUL
|
||||||
|
// or was overestimating.
|
||||||
|
n = i
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bytes := (*[10000]byte)(unsafe.Pointer(&pp.Path[0]))[0:n]
|
||||||
|
sa.Name = string(bytes)
|
||||||
|
return sa, nil
|
||||||
|
|
||||||
|
case AF_INET:
|
||||||
|
pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
|
||||||
|
sa := new(SockaddrInet4)
|
||||||
|
p := (*[2]byte)(unsafe.Pointer(&pp.Port))
|
||||||
|
sa.Port = int(p[0])<<8 + int(p[1])
|
||||||
|
for i := 0; i < len(sa.Addr); i++ {
|
||||||
|
sa.Addr[i] = pp.Addr[i]
|
||||||
|
}
|
||||||
|
return sa, nil
|
||||||
|
|
||||||
|
case AF_INET6:
|
||||||
|
pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))
|
||||||
|
sa := new(SockaddrInet6)
|
||||||
|
p := (*[2]byte)(unsafe.Pointer(&pp.Port))
|
||||||
|
sa.Port = int(p[0])<<8 + int(p[1])
|
||||||
|
sa.ZoneId = pp.Scope_id
|
||||||
|
for i := 0; i < len(sa.Addr); i++ {
|
||||||
|
sa.Addr[i] = pp.Addr[i]
|
||||||
|
}
|
||||||
|
return sa, nil
|
||||||
|
}
|
||||||
|
return nil, EAFNOSUPPORT
|
||||||
|
}
|
||||||
|
|
||||||
|
func Accept(fd int) (nfd int, sa Sockaddr, err error) {
|
||||||
|
var rsa RawSockaddrAny
|
||||||
|
var len _Socklen = SizeofSockaddrAny
|
||||||
|
nfd, err = accept(fd, &rsa, &len)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if runtime.GOOS == "darwin" && len == 0 {
|
||||||
|
// Accepted socket has no address.
|
||||||
|
// This is likely due to a bug in xnu kernels,
|
||||||
|
// where instead of ECONNABORTED error socket
|
||||||
|
// is accepted, but has no address.
|
||||||
|
Close(nfd)
|
||||||
|
return 0, nil, ECONNABORTED
|
||||||
|
}
|
||||||
|
sa, err = anyToSockaddr(&rsa)
|
||||||
|
if err != nil {
|
||||||
|
Close(nfd)
|
||||||
|
nfd = 0
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func Getsockname(fd int) (sa Sockaddr, err error) {
|
||||||
|
var rsa RawSockaddrAny
|
||||||
|
var len _Socklen = SizeofSockaddrAny
|
||||||
|
if err = getsockname(fd, &rsa, &len); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// TODO(jsing): DragonFly has a "bug" (see issue 3349), which should be
|
||||||
|
// reported upstream.
|
||||||
|
if runtime.GOOS == "dragonfly" && rsa.Addr.Family == AF_UNSPEC && rsa.Addr.Len == 0 {
|
||||||
|
rsa.Addr.Family = AF_UNIX
|
||||||
|
rsa.Addr.Len = SizeofSockaddrUnix
|
||||||
|
}
|
||||||
|
return anyToSockaddr(&rsa)
|
||||||
|
}
|
||||||
|
|
||||||
|
//sysnb socketpair(domain int, typ int, proto int, fd *[2]int32) (err error)
|
||||||
|
|
||||||
|
func GetsockoptByte(fd, level, opt int) (value byte, err error) {
|
||||||
|
var n byte
|
||||||
|
vallen := _Socklen(1)
|
||||||
|
err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen)
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetsockoptInet4Addr(fd, level, opt int) (value [4]byte, err error) {
|
||||||
|
vallen := _Socklen(4)
|
||||||
|
err = getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen)
|
||||||
|
return value, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetsockoptIPMreq(fd, level, opt int) (*IPMreq, error) {
|
||||||
|
var value IPMreq
|
||||||
|
vallen := _Socklen(SizeofIPMreq)
|
||||||
|
err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
|
||||||
|
return &value, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetsockoptIPv6Mreq(fd, level, opt int) (*IPv6Mreq, error) {
|
||||||
|
var value IPv6Mreq
|
||||||
|
vallen := _Socklen(SizeofIPv6Mreq)
|
||||||
|
err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
|
||||||
|
return &value, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetsockoptIPv6MTUInfo(fd, level, opt int) (*IPv6MTUInfo, error) {
|
||||||
|
var value IPv6MTUInfo
|
||||||
|
vallen := _Socklen(SizeofIPv6MTUInfo)
|
||||||
|
err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
|
||||||
|
return &value, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetsockoptICMPv6Filter(fd, level, opt int) (*ICMPv6Filter, error) {
|
||||||
|
var value ICMPv6Filter
|
||||||
|
vallen := _Socklen(SizeofICMPv6Filter)
|
||||||
|
err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
|
||||||
|
return &value, err
|
||||||
|
}
|
||||||
|
|
||||||
|
//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)
|
||||||
|
|
||||||
|
func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) {
|
||||||
|
var msg Msghdr
|
||||||
|
var rsa RawSockaddrAny
|
||||||
|
msg.Name = (*byte)(unsafe.Pointer(&rsa))
|
||||||
|
msg.Namelen = uint32(SizeofSockaddrAny)
|
||||||
|
var iov Iovec
|
||||||
|
if len(p) > 0 {
|
||||||
|
iov.Base = (*byte)(unsafe.Pointer(&p[0]))
|
||||||
|
iov.SetLen(len(p))
|
||||||
|
}
|
||||||
|
var dummy byte
|
||||||
|
if len(oob) > 0 {
|
||||||
|
// receive at least one normal byte
|
||||||
|
if len(p) == 0 {
|
||||||
|
iov.Base = &dummy
|
||||||
|
iov.SetLen(1)
|
||||||
|
}
|
||||||
|
msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
|
||||||
|
msg.SetControllen(len(oob))
|
||||||
|
}
|
||||||
|
msg.Iov = &iov
|
||||||
|
msg.Iovlen = 1
|
||||||
|
if n, err = recvmsg(fd, &msg, flags); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
oobn = int(msg.Controllen)
|
||||||
|
recvflags = int(msg.Flags)
|
||||||
|
// source address is only specified if the socket is unconnected
|
||||||
|
if rsa.Addr.Family != AF_UNSPEC {
|
||||||
|
from, err = anyToSockaddr(&rsa)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error)
|
||||||
|
|
||||||
|
func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) {
|
||||||
|
_, err = SendmsgN(fd, p, oob, to, flags)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) {
|
||||||
|
var ptr unsafe.Pointer
|
||||||
|
var salen _Socklen
|
||||||
|
if to != nil {
|
||||||
|
ptr, salen, err = to.sockaddr()
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var msg Msghdr
|
||||||
|
msg.Name = (*byte)(unsafe.Pointer(ptr))
|
||||||
|
msg.Namelen = uint32(salen)
|
||||||
|
var iov Iovec
|
||||||
|
if len(p) > 0 {
|
||||||
|
iov.Base = (*byte)(unsafe.Pointer(&p[0]))
|
||||||
|
iov.SetLen(len(p))
|
||||||
|
}
|
||||||
|
var dummy byte
|
||||||
|
if len(oob) > 0 {
|
||||||
|
// send at least one normal byte
|
||||||
|
if len(p) == 0 {
|
||||||
|
iov.Base = &dummy
|
||||||
|
iov.SetLen(1)
|
||||||
|
}
|
||||||
|
msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
|
||||||
|
msg.SetControllen(len(oob))
|
||||||
|
}
|
||||||
|
msg.Iov = &iov
|
||||||
|
msg.Iovlen = 1
|
||||||
|
if n, err = sendmsg(fd, &msg, flags); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
if len(oob) > 0 && len(p) == 0 {
|
||||||
|
n = 0
|
||||||
|
}
|
||||||
|
return n, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//sys kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, nevent int, timeout *Timespec) (n int, err error)
|
||||||
|
|
||||||
|
func Kevent(kq int, changes, events []Kevent_t, timeout *Timespec) (n int, err error) {
|
||||||
|
var change, event unsafe.Pointer
|
||||||
|
if len(changes) > 0 {
|
||||||
|
change = unsafe.Pointer(&changes[0])
|
||||||
|
}
|
||||||
|
if len(events) > 0 {
|
||||||
|
event = unsafe.Pointer(&events[0])
|
||||||
|
}
|
||||||
|
return kevent(kq, change, len(changes), event, len(events), timeout)
|
||||||
|
}
|
||||||
|
|
||||||
|
//sys sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) = SYS___SYSCTL
|
||||||
|
|
||||||
|
// sysctlmib translates name to mib number and appends any additional args.
|
||||||
|
func sysctlmib(name string, args ...int) ([]_C_int, error) {
|
||||||
|
// Translate name to mib number.
|
||||||
|
mib, err := nametomib(name)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, a := range args {
|
||||||
|
mib = append(mib, _C_int(a))
|
||||||
|
}
|
||||||
|
|
||||||
|
return mib, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func Sysctl(name string) (string, error) {
|
||||||
|
return SysctlArgs(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func SysctlArgs(name string, args ...int) (string, error) {
|
||||||
|
buf, err := SysctlRaw(name, args...)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
n := len(buf)
|
||||||
|
|
||||||
|
// Throw away terminating NUL.
|
||||||
|
if n > 0 && buf[n-1] == '\x00' {
|
||||||
|
n--
|
||||||
|
}
|
||||||
|
return string(buf[0:n]), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func SysctlUint32(name string) (uint32, error) {
|
||||||
|
return SysctlUint32Args(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func SysctlUint32Args(name string, args ...int) (uint32, error) {
|
||||||
|
mib, err := sysctlmib(name, args...)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
n := uintptr(4)
|
||||||
|
buf := make([]byte, 4)
|
||||||
|
if err := sysctl(mib, &buf[0], &n, nil, 0); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
if n != 4 {
|
||||||
|
return 0, EIO
|
||||||
|
}
|
||||||
|
return *(*uint32)(unsafe.Pointer(&buf[0])), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func SysctlUint64(name string, args ...int) (uint64, error) {
|
||||||
|
mib, err := sysctlmib(name, args...)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
n := uintptr(8)
|
||||||
|
buf := make([]byte, 8)
|
||||||
|
if err := sysctl(mib, &buf[0], &n, nil, 0); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
if n != 8 {
|
||||||
|
return 0, EIO
|
||||||
|
}
|
||||||
|
return *(*uint64)(unsafe.Pointer(&buf[0])), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func SysctlRaw(name string, args ...int) ([]byte, error) {
|
||||||
|
mib, err := sysctlmib(name, args...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find size.
|
||||||
|
n := uintptr(0)
|
||||||
|
if err := sysctl(mib, nil, &n, nil, 0); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if n == 0 {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read into buffer of that size.
|
||||||
|
buf := make([]byte, n)
|
||||||
|
if err := sysctl(mib, &buf[0], &n, nil, 0); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// The actual call may return less than the original reported required
|
||||||
|
// size so ensure we deal with that.
|
||||||
|
return buf[:n], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//sys utimes(path string, timeval *[2]Timeval) (err error)
|
||||||
|
|
||||||
|
func Utimes(path string, tv []Timeval) error {
|
||||||
|
if tv == nil {
|
||||||
|
return utimes(path, nil)
|
||||||
|
}
|
||||||
|
if len(tv) != 2 {
|
||||||
|
return EINVAL
|
||||||
|
}
|
||||||
|
return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
|
||||||
|
}
|
||||||
|
|
||||||
|
func UtimesNano(path string, ts []Timespec) error {
|
||||||
|
if ts == nil {
|
||||||
|
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
|
||||||
|
}
|
||||||
|
// Not as efficient as it could be because Timespec and
|
||||||
|
// Timeval have different types in the different OSes
|
||||||
|
tv := [2]Timeval{
|
||||||
|
NsecToTimeval(TimespecToNsec(ts[0])),
|
||||||
|
NsecToTimeval(TimespecToNsec(ts[1])),
|
||||||
|
}
|
||||||
|
return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
|
||||||
|
}
|
||||||
|
|
||||||
|
//sys futimes(fd int, timeval *[2]Timeval) (err error)
|
||||||
|
|
||||||
|
func Futimes(fd int, tv []Timeval) error {
|
||||||
|
if tv == nil {
|
||||||
|
return futimes(fd, nil)
|
||||||
|
}
|
||||||
|
if len(tv) != 2 {
|
||||||
|
return EINVAL
|
||||||
|
}
|
||||||
|
return futimes(fd, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
|
||||||
|
}
|
||||||
|
|
||||||
|
//sys fcntl(fd int, cmd int, arg int) (val int, err error)
|
||||||
|
|
||||||
|
// 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{
|
||||||
|
active: make(map[*byte][]byte),
|
||||||
|
mmap: mmap,
|
||||||
|
munmap: munmap,
|
||||||
|
}
|
||||||
|
|
||||||
|
func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
|
||||||
|
return mapper.Mmap(fd, offset, length, prot, flags)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Munmap(b []byte) (err error) {
|
||||||
|
return mapper.Munmap(b)
|
||||||
|
}
|
511
vendor/golang.org/x/sys/unix/syscall_darwin.go
generated
vendored
Normal file
511
vendor/golang.org/x/sys/unix/syscall_darwin.go
generated
vendored
Normal file
|
@ -0,0 +1,511 @@
|
||||||
|
// Copyright 2009,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.
|
||||||
|
|
||||||
|
// Darwin system calls.
|
||||||
|
// This file is compiled as ordinary Go code,
|
||||||
|
// but it is also input to mksyscall,
|
||||||
|
// which parses the //sys lines and generates system call stubs.
|
||||||
|
// Note that sometimes we use a lowercase //sys name and wrap
|
||||||
|
// it in our own nicer implementation, either here or in
|
||||||
|
// syscall_bsd.go or syscall_unix.go.
|
||||||
|
|
||||||
|
package unix
|
||||||
|
|
||||||
|
import (
|
||||||
|
errorspkg "errors"
|
||||||
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
const ImplementsGetwd = true
|
||||||
|
|
||||||
|
func Getwd() (string, error) {
|
||||||
|
buf := make([]byte, 2048)
|
||||||
|
attrs, err := getAttrList(".", attrList{CommonAttr: attrCmnFullpath}, buf, 0)
|
||||||
|
if err == nil && len(attrs) == 1 && len(attrs[0]) >= 2 {
|
||||||
|
wd := string(attrs[0])
|
||||||
|
// Sanity check that it's an absolute path and ends
|
||||||
|
// in a null byte, which we then strip.
|
||||||
|
if wd[0] == '/' && wd[len(wd)-1] == 0 {
|
||||||
|
return wd[:len(wd)-1], nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If pkg/os/getwd.go gets ENOTSUP, it will fall back to the
|
||||||
|
// slow algorithm.
|
||||||
|
return "", ENOTSUP
|
||||||
|
}
|
||||||
|
|
||||||
|
type SockaddrDatalink struct {
|
||||||
|
Len uint8
|
||||||
|
Family uint8
|
||||||
|
Index uint16
|
||||||
|
Type uint8
|
||||||
|
Nlen uint8
|
||||||
|
Alen uint8
|
||||||
|
Slen uint8
|
||||||
|
Data [12]int8
|
||||||
|
raw RawSockaddrDatalink
|
||||||
|
}
|
||||||
|
|
||||||
|
// Translate "kern.hostname" to []_C_int{0,1,2,3}.
|
||||||
|
func nametomib(name string) (mib []_C_int, err error) {
|
||||||
|
const siz = unsafe.Sizeof(mib[0])
|
||||||
|
|
||||||
|
// 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
|
||||||
|
// 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
|
||||||
|
// and we'll get memory corruption.
|
||||||
|
var buf [CTL_MAXNAME + 2]_C_int
|
||||||
|
n := uintptr(CTL_MAXNAME) * siz
|
||||||
|
|
||||||
|
p := (*byte)(unsafe.Pointer(&buf[0]))
|
||||||
|
bytes, err := ByteSliceFromString(name)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Magic sysctl: "setting" 0.3 to a string name
|
||||||
|
// lets you read back the array of integers form.
|
||||||
|
if err = sysctl([]_C_int{0, 3}, p, &n, &bytes[0], uintptr(len(name))); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
//sys ptrace(request int, pid int, addr uintptr, data uintptr) (err error)
|
||||||
|
func PtraceAttach(pid int) (err error) { return ptrace(PT_ATTACH, pid, 0, 0) }
|
||||||
|
func PtraceDetach(pid int) (err error) { return ptrace(PT_DETACH, pid, 0, 0) }
|
||||||
|
|
||||||
|
const (
|
||||||
|
attrBitMapCount = 5
|
||||||
|
attrCmnFullpath = 0x08000000
|
||||||
|
)
|
||||||
|
|
||||||
|
type attrList struct {
|
||||||
|
bitmapCount uint16
|
||||||
|
_ uint16
|
||||||
|
CommonAttr uint32
|
||||||
|
VolAttr uint32
|
||||||
|
DirAttr uint32
|
||||||
|
FileAttr uint32
|
||||||
|
Forkattr uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
func getAttrList(path string, attrList attrList, attrBuf []byte, options uint) (attrs [][]byte, err error) {
|
||||||
|
if len(attrBuf) < 4 {
|
||||||
|
return nil, errorspkg.New("attrBuf too small")
|
||||||
|
}
|
||||||
|
attrList.bitmapCount = attrBitMapCount
|
||||||
|
|
||||||
|
var _p0 *byte
|
||||||
|
_p0, err = BytePtrFromString(path)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, _, e1 := Syscall6(
|
||||||
|
SYS_GETATTRLIST,
|
||||||
|
uintptr(unsafe.Pointer(_p0)),
|
||||||
|
uintptr(unsafe.Pointer(&attrList)),
|
||||||
|
uintptr(unsafe.Pointer(&attrBuf[0])),
|
||||||
|
uintptr(len(attrBuf)),
|
||||||
|
uintptr(options),
|
||||||
|
0,
|
||||||
|
)
|
||||||
|
use(unsafe.Pointer(_p0))
|
||||||
|
if e1 != 0 {
|
||||||
|
return nil, e1
|
||||||
|
}
|
||||||
|
size := *(*uint32)(unsafe.Pointer(&attrBuf[0]))
|
||||||
|
|
||||||
|
// dat is the section of attrBuf that contains valid data,
|
||||||
|
// without the 4 byte length header. All attribute offsets
|
||||||
|
// are relative to dat.
|
||||||
|
dat := attrBuf
|
||||||
|
if int(size) < len(attrBuf) {
|
||||||
|
dat = dat[:size]
|
||||||
|
}
|
||||||
|
dat = dat[4:] // remove length prefix
|
||||||
|
|
||||||
|
for i := uint32(0); int(i) < len(dat); {
|
||||||
|
header := dat[i:]
|
||||||
|
if len(header) < 8 {
|
||||||
|
return attrs, errorspkg.New("truncated attribute header")
|
||||||
|
}
|
||||||
|
datOff := *(*int32)(unsafe.Pointer(&header[0]))
|
||||||
|
attrLen := *(*uint32)(unsafe.Pointer(&header[4]))
|
||||||
|
if datOff < 0 || uint32(datOff)+attrLen > uint32(len(dat)) {
|
||||||
|
return attrs, errorspkg.New("truncated results; attrBuf too small")
|
||||||
|
}
|
||||||
|
end := uint32(datOff) + attrLen
|
||||||
|
attrs = append(attrs, dat[datOff:end])
|
||||||
|
i = end
|
||||||
|
if r := i % 4; r != 0 {
|
||||||
|
i += (4 - r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//sysnb pipe() (r int, w int, err error)
|
||||||
|
|
||||||
|
func Pipe(p []int) (err error) {
|
||||||
|
if len(p) != 2 {
|
||||||
|
return EINVAL
|
||||||
|
}
|
||||||
|
p[0], p[1], err = pipe()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
|
||||||
|
var _p0 unsafe.Pointer
|
||||||
|
var bufsize uintptr
|
||||||
|
if len(buf) > 0 {
|
||||||
|
_p0 = unsafe.Pointer(&buf[0])
|
||||||
|
bufsize = unsafe.Sizeof(Statfs_t{}) * uintptr(len(buf))
|
||||||
|
}
|
||||||
|
r0, _, e1 := Syscall(SYS_GETFSSTAT64, uintptr(_p0), bufsize, uintptr(flags))
|
||||||
|
use(unsafe.Pointer(_p0))
|
||||||
|
n = int(r0)
|
||||||
|
if e1 != 0 {
|
||||||
|
err = e1
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Wrapped
|
||||||
|
*/
|
||||||
|
|
||||||
|
//sys kill(pid int, signum int, posix int) (err error)
|
||||||
|
|
||||||
|
func Kill(pid int, signum syscall.Signal) (err error) { return kill(pid, int(signum), 1) }
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Exposed directly
|
||||||
|
*/
|
||||||
|
//sys Access(path string, mode uint32) (err error)
|
||||||
|
//sys Adjtime(delta *Timeval, olddelta *Timeval) (err error)
|
||||||
|
//sys Chdir(path string) (err error)
|
||||||
|
//sys Chflags(path string, flags int) (err error)
|
||||||
|
//sys Chmod(path string, mode uint32) (err error)
|
||||||
|
//sys Chown(path string, uid int, gid int) (err error)
|
||||||
|
//sys Chroot(path string) (err error)
|
||||||
|
//sys Close(fd int) (err error)
|
||||||
|
//sys Dup(fd int) (nfd int, err error)
|
||||||
|
//sys Dup2(from int, to int) (err error)
|
||||||
|
//sys Exchangedata(path1 string, path2 string, options int) (err error)
|
||||||
|
//sys Exit(code int)
|
||||||
|
//sys Fchdir(fd int) (err error)
|
||||||
|
//sys Fchflags(fd int, flags int) (err error)
|
||||||
|
//sys Fchmod(fd int, mode uint32) (err error)
|
||||||
|
//sys Fchown(fd int, uid int, gid 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
|
||||||
|
//sys Fstatfs(fd int, stat *Statfs_t) (err error) = SYS_FSTATFS64
|
||||||
|
//sys Fsync(fd int) (err error)
|
||||||
|
//sys Ftruncate(fd int, length int64) (err error)
|
||||||
|
//sys Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) = SYS_GETDIRENTRIES64
|
||||||
|
//sys Getdtablesize() (size int)
|
||||||
|
//sysnb Getegid() (egid int)
|
||||||
|
//sysnb Geteuid() (uid int)
|
||||||
|
//sysnb Getgid() (gid int)
|
||||||
|
//sysnb Getpgid(pid int) (pgid int, err error)
|
||||||
|
//sysnb Getpgrp() (pgrp int)
|
||||||
|
//sysnb Getpid() (pid int)
|
||||||
|
//sysnb Getppid() (ppid int)
|
||||||
|
//sys Getpriority(which int, who int) (prio int, err error)
|
||||||
|
//sysnb Getrlimit(which int, lim *Rlimit) (err error)
|
||||||
|
//sysnb Getrusage(who int, rusage *Rusage) (err error)
|
||||||
|
//sysnb Getsid(pid int) (sid int, err error)
|
||||||
|
//sysnb Getuid() (uid int)
|
||||||
|
//sysnb Issetugid() (tainted bool)
|
||||||
|
//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 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 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 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 Rename(from string, 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
|
||||||
|
//sys Select(n int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (err error)
|
||||||
|
//sys Setegid(egid int) (err error)
|
||||||
|
//sysnb Seteuid(euid int) (err error)
|
||||||
|
//sysnb Setgid(gid int) (err error)
|
||||||
|
//sys Setlogin(name string) (err error)
|
||||||
|
//sysnb Setpgid(pid int, pgid int) (err error)
|
||||||
|
//sys Setpriority(which int, who int, prio int) (err error)
|
||||||
|
//sys Setprivexec(flag int) (err error)
|
||||||
|
//sysnb Setregid(rgid int, egid int) (err error)
|
||||||
|
//sysnb Setreuid(ruid int, euid int) (err error)
|
||||||
|
//sysnb Setrlimit(which int, lim *Rlimit) (err error)
|
||||||
|
//sysnb Setsid() (pid int, err error)
|
||||||
|
//sysnb Settimeofday(tp *Timeval) (err error)
|
||||||
|
//sysnb Setuid(uid int) (err error)
|
||||||
|
//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 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 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)
|
||||||
|
//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
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Unimplemented
|
||||||
|
*/
|
||||||
|
// Profil
|
||||||
|
// Sigaction
|
||||||
|
// Sigprocmask
|
||||||
|
// Getlogin
|
||||||
|
// Sigpending
|
||||||
|
// Sigaltstack
|
||||||
|
// Ioctl
|
||||||
|
// Reboot
|
||||||
|
// Execve
|
||||||
|
// Vfork
|
||||||
|
// Sbrk
|
||||||
|
// Sstk
|
||||||
|
// Ovadvise
|
||||||
|
// Mincore
|
||||||
|
// Setitimer
|
||||||
|
// Swapon
|
||||||
|
// Select
|
||||||
|
// Sigsuspend
|
||||||
|
// Readv
|
||||||
|
// Writev
|
||||||
|
// Nfssvc
|
||||||
|
// Getfh
|
||||||
|
// Quotactl
|
||||||
|
// Mount
|
||||||
|
// Csops
|
||||||
|
// Waitid
|
||||||
|
// Add_profil
|
||||||
|
// Kdebug_trace
|
||||||
|
// Sigreturn
|
||||||
|
// Mmap
|
||||||
|
// Mlock
|
||||||
|
// Munlock
|
||||||
|
// Atsocket
|
||||||
|
// Kqueue_from_portset_np
|
||||||
|
// Kqueue_portset
|
||||||
|
// Getattrlist
|
||||||
|
// Setattrlist
|
||||||
|
// Getdirentriesattr
|
||||||
|
// Searchfs
|
||||||
|
// Delete
|
||||||
|
// Copyfile
|
||||||
|
// Poll
|
||||||
|
// Watchevent
|
||||||
|
// Waitevent
|
||||||
|
// Modwatch
|
||||||
|
// Getxattr
|
||||||
|
// Fgetxattr
|
||||||
|
// Setxattr
|
||||||
|
// Fsetxattr
|
||||||
|
// Removexattr
|
||||||
|
// Fremovexattr
|
||||||
|
// Listxattr
|
||||||
|
// Flistxattr
|
||||||
|
// Fsctl
|
||||||
|
// Initgroups
|
||||||
|
// Posix_spawn
|
||||||
|
// Nfsclnt
|
||||||
|
// Fhopen
|
||||||
|
// Minherit
|
||||||
|
// Semsys
|
||||||
|
// Msgsys
|
||||||
|
// Shmsys
|
||||||
|
// Semctl
|
||||||
|
// Semget
|
||||||
|
// Semop
|
||||||
|
// Msgctl
|
||||||
|
// Msgget
|
||||||
|
// Msgsnd
|
||||||
|
// Msgrcv
|
||||||
|
// Shmat
|
||||||
|
// Shmctl
|
||||||
|
// Shmdt
|
||||||
|
// Shmget
|
||||||
|
// Shm_open
|
||||||
|
// Shm_unlink
|
||||||
|
// Sem_open
|
||||||
|
// Sem_close
|
||||||
|
// Sem_unlink
|
||||||
|
// Sem_wait
|
||||||
|
// Sem_trywait
|
||||||
|
// Sem_post
|
||||||
|
// Sem_getvalue
|
||||||
|
// Sem_init
|
||||||
|
// Sem_destroy
|
||||||
|
// Open_extended
|
||||||
|
// Umask_extended
|
||||||
|
// Stat_extended
|
||||||
|
// Lstat_extended
|
||||||
|
// Fstat_extended
|
||||||
|
// Chmod_extended
|
||||||
|
// Fchmod_extended
|
||||||
|
// Access_extended
|
||||||
|
// Settid
|
||||||
|
// Gettid
|
||||||
|
// Setsgroups
|
||||||
|
// Getsgroups
|
||||||
|
// Setwgroups
|
||||||
|
// Getwgroups
|
||||||
|
// Mkfifo_extended
|
||||||
|
// Mkdir_extended
|
||||||
|
// Identitysvc
|
||||||
|
// Shared_region_check_np
|
||||||
|
// Shared_region_map_np
|
||||||
|
// __pthread_mutex_destroy
|
||||||
|
// __pthread_mutex_init
|
||||||
|
// __pthread_mutex_lock
|
||||||
|
// __pthread_mutex_trylock
|
||||||
|
// __pthread_mutex_unlock
|
||||||
|
// __pthread_cond_init
|
||||||
|
// __pthread_cond_destroy
|
||||||
|
// __pthread_cond_broadcast
|
||||||
|
// __pthread_cond_signal
|
||||||
|
// Setsid_with_pid
|
||||||
|
// __pthread_cond_timedwait
|
||||||
|
// Aio_fsync
|
||||||
|
// Aio_return
|
||||||
|
// Aio_suspend
|
||||||
|
// Aio_cancel
|
||||||
|
// Aio_error
|
||||||
|
// Aio_read
|
||||||
|
// Aio_write
|
||||||
|
// Lio_listio
|
||||||
|
// __pthread_cond_wait
|
||||||
|
// Iopolicysys
|
||||||
|
// Mlockall
|
||||||
|
// Munlockall
|
||||||
|
// __pthread_kill
|
||||||
|
// __pthread_sigmask
|
||||||
|
// __sigwait
|
||||||
|
// __disable_threadsignal
|
||||||
|
// __pthread_markcancel
|
||||||
|
// __pthread_canceled
|
||||||
|
// __semwait_signal
|
||||||
|
// Proc_info
|
||||||
|
// sendfile
|
||||||
|
// Stat64_extended
|
||||||
|
// Lstat64_extended
|
||||||
|
// Fstat64_extended
|
||||||
|
// __pthread_chdir
|
||||||
|
// __pthread_fchdir
|
||||||
|
// Audit
|
||||||
|
// Auditon
|
||||||
|
// Getauid
|
||||||
|
// Setauid
|
||||||
|
// Getaudit
|
||||||
|
// Setaudit
|
||||||
|
// Getaudit_addr
|
||||||
|
// Setaudit_addr
|
||||||
|
// Auditctl
|
||||||
|
// Bsdthread_create
|
||||||
|
// Bsdthread_terminate
|
||||||
|
// Stack_snapshot
|
||||||
|
// Bsdthread_register
|
||||||
|
// Workq_open
|
||||||
|
// Workq_ops
|
||||||
|
// __mac_execve
|
||||||
|
// __mac_syscall
|
||||||
|
// __mac_get_file
|
||||||
|
// __mac_set_file
|
||||||
|
// __mac_get_link
|
||||||
|
// __mac_set_link
|
||||||
|
// __mac_get_proc
|
||||||
|
// __mac_set_proc
|
||||||
|
// __mac_get_fd
|
||||||
|
// __mac_set_fd
|
||||||
|
// __mac_get_pid
|
||||||
|
// __mac_get_lcid
|
||||||
|
// __mac_get_lctx
|
||||||
|
// __mac_set_lctx
|
||||||
|
// Setlcid
|
||||||
|
// Read_nocancel
|
||||||
|
// Write_nocancel
|
||||||
|
// Open_nocancel
|
||||||
|
// Close_nocancel
|
||||||
|
// Wait4_nocancel
|
||||||
|
// Recvmsg_nocancel
|
||||||
|
// Sendmsg_nocancel
|
||||||
|
// Recvfrom_nocancel
|
||||||
|
// Accept_nocancel
|
||||||
|
// Msync_nocancel
|
||||||
|
// Fcntl_nocancel
|
||||||
|
// Select_nocancel
|
||||||
|
// Fsync_nocancel
|
||||||
|
// Connect_nocancel
|
||||||
|
// Sigsuspend_nocancel
|
||||||
|
// Readv_nocancel
|
||||||
|
// Writev_nocancel
|
||||||
|
// Sendto_nocancel
|
||||||
|
// Pread_nocancel
|
||||||
|
// Pwrite_nocancel
|
||||||
|
// Waitid_nocancel
|
||||||
|
// Poll_nocancel
|
||||||
|
// Msgsnd_nocancel
|
||||||
|
// Msgrcv_nocancel
|
||||||
|
// Sem_wait_nocancel
|
||||||
|
// Aio_suspend_nocancel
|
||||||
|
// __sigwait_nocancel
|
||||||
|
// __semwait_signal_nocancel
|
||||||
|
// __mac_mount
|
||||||
|
// __mac_get_mount
|
||||||
|
// __mac_getfsstat
|
77
vendor/golang.org/x/sys/unix/syscall_darwin_386.go
generated
vendored
Normal file
77
vendor/golang.org/x/sys/unix/syscall_darwin_386.go
generated
vendored
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build 386,darwin
|
||||||
|
|
||||||
|
package unix
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Getpagesize() int { return 4096 }
|
||||||
|
|
||||||
|
func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
|
||||||
|
|
||||||
|
func NsecToTimespec(nsec int64) (ts Timespec) {
|
||||||
|
ts.Sec = int32(nsec / 1e9)
|
||||||
|
ts.Nsec = int32(nsec % 1e9)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func NsecToTimeval(nsec int64) (tv Timeval) {
|
||||||
|
nsec += 999 // round up to microsecond
|
||||||
|
tv.Usec = int32(nsec % 1e9 / 1e3)
|
||||||
|
tv.Sec = int32(nsec / 1e9)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//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
|
||||||
|
// in the two registers.
|
||||||
|
sec, usec, err := gettimeofday(tv)
|
||||||
|
tv.Sec = int32(sec)
|
||||||
|
tv.Usec = int32(usec)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetKevent(k *Kevent_t, fd, mode, flags int) {
|
||||||
|
k.Ident = uint32(fd)
|
||||||
|
k.Filter = int16(mode)
|
||||||
|
k.Flags = uint16(flags)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (iov *Iovec) SetLen(length int) {
|
||||||
|
iov.Len = uint32(length)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (msghdr *Msghdr) SetControllen(length int) {
|
||||||
|
msghdr.Controllen = uint32(length)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmsg *Cmsghdr) SetLen(length int) {
|
||||||
|
cmsg.Len = uint32(length)
|
||||||
|
}
|
||||||
|
|
||||||
|
func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
|
||||||
|
var length = uint64(count)
|
||||||
|
|
||||||
|
_, _, e1 := Syscall9(SYS_SENDFILE, uintptr(infd), uintptr(outfd), uintptr(*offset), uintptr(*offset>>32), uintptr(unsafe.Pointer(&length)), 0, 0, 0, 0)
|
||||||
|
|
||||||
|
written = int(length)
|
||||||
|
|
||||||
|
if e1 != 0 {
|
||||||
|
err = e1
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)
|
||||||
|
|
||||||
|
// SYS___SYSCTL is used by syscall_bsd.go for all BSDs, but in modern versions
|
||||||
|
// of darwin/386 the syscall is called sysctl instead of __sysctl.
|
||||||
|
const SYS___SYSCTL = SYS_SYSCTL
|
79
vendor/golang.org/x/sys/unix/syscall_darwin_amd64.go
generated
vendored
Normal file
79
vendor/golang.org/x/sys/unix/syscall_darwin_amd64.go
generated
vendored
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
// 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 amd64,darwin
|
||||||
|
|
||||||
|
package unix
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
"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 NsecToTimeval(nsec int64) (tv Timeval) {
|
||||||
|
nsec += 999 // round up to microsecond
|
||||||
|
tv.Usec = int32(nsec % 1e9 / 1e3)
|
||||||
|
tv.Sec = int64(nsec / 1e9)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//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
|
||||||
|
// in the two registers.
|
||||||
|
sec, usec, err := gettimeofday(tv)
|
||||||
|
tv.Sec = sec
|
||||||
|
tv.Usec = usec
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetKevent(k *Kevent_t, fd, mode, flags int) {
|
||||||
|
k.Ident = uint64(fd)
|
||||||
|
k.Filter = int16(mode)
|
||||||
|
k.Flags = uint16(flags)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (iov *Iovec) SetLen(length int) {
|
||||||
|
iov.Len = uint64(length)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (msghdr *Msghdr) SetControllen(length int) {
|
||||||
|
msghdr.Controllen = uint32(length)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmsg *Cmsghdr) SetLen(length int) {
|
||||||
|
cmsg.Len = uint32(length)
|
||||||
|
}
|
||||||
|
|
||||||
|
func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
|
||||||
|
var length = uint64(count)
|
||||||
|
|
||||||
|
_, _, e1 := Syscall6(SYS_SENDFILE, uintptr(infd), uintptr(outfd), uintptr(*offset), uintptr(unsafe.Pointer(&length)), 0, 0)
|
||||||
|
|
||||||
|
written = int(length)
|
||||||
|
|
||||||
|
if e1 != 0 {
|
||||||
|
err = e1
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)
|
||||||
|
|
||||||
|
// SYS___SYSCTL is used by syscall_bsd.go for all BSDs, but in modern versions
|
||||||
|
// of darwin/amd64 the syscall is called sysctl instead of __sysctl.
|
||||||
|
const SYS___SYSCTL = SYS_SYSCTL
|
71
vendor/golang.org/x/sys/unix/syscall_darwin_arm.go
generated
vendored
Normal file
71
vendor/golang.org/x/sys/unix/syscall_darwin_arm.go
generated
vendored
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
package unix
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Getpagesize() int { return 4096 }
|
||||||
|
|
||||||
|
func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
|
||||||
|
|
||||||
|
func NsecToTimespec(nsec int64) (ts Timespec) {
|
||||||
|
ts.Sec = int32(nsec / 1e9)
|
||||||
|
ts.Nsec = int32(nsec % 1e9)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func NsecToTimeval(nsec int64) (tv Timeval) {
|
||||||
|
nsec += 999 // round up to microsecond
|
||||||
|
tv.Usec = int32(nsec % 1e9 / 1e3)
|
||||||
|
tv.Sec = int32(nsec / 1e9)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//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
|
||||||
|
// in the two registers.
|
||||||
|
sec, usec, err := gettimeofday(tv)
|
||||||
|
tv.Sec = int32(sec)
|
||||||
|
tv.Usec = int32(usec)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetKevent(k *Kevent_t, fd, mode, flags int) {
|
||||||
|
k.Ident = uint32(fd)
|
||||||
|
k.Filter = int16(mode)
|
||||||
|
k.Flags = uint16(flags)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (iov *Iovec) SetLen(length int) {
|
||||||
|
iov.Len = uint32(length)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (msghdr *Msghdr) SetControllen(length int) {
|
||||||
|
msghdr.Controllen = uint32(length)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmsg *Cmsghdr) SetLen(length int) {
|
||||||
|
cmsg.Len = uint32(length)
|
||||||
|
}
|
||||||
|
|
||||||
|
func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
|
||||||
|
var length = uint64(count)
|
||||||
|
|
||||||
|
_, _, e1 := Syscall9(SYS_SENDFILE, uintptr(infd), uintptr(outfd), uintptr(*offset), uintptr(*offset>>32), uintptr(unsafe.Pointer(&length)), 0, 0, 0, 0)
|
||||||
|
|
||||||
|
written = int(length)
|
||||||
|
|
||||||
|
if e1 != 0 {
|
||||||
|
err = e1
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno) // sic
|
77
vendor/golang.org/x/sys/unix/syscall_darwin_arm64.go
generated
vendored
Normal file
77
vendor/golang.org/x/sys/unix/syscall_darwin_arm64.go
generated
vendored
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
// 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 arm64,darwin
|
||||||
|
|
||||||
|
package unix
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
"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 NsecToTimeval(nsec int64) (tv Timeval) {
|
||||||
|
nsec += 999 // round up to microsecond
|
||||||
|
tv.Usec = int32(nsec % 1e9 / 1e3)
|
||||||
|
tv.Sec = int64(nsec / 1e9)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//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
|
||||||
|
// in the two registers.
|
||||||
|
sec, usec, err := gettimeofday(tv)
|
||||||
|
tv.Sec = sec
|
||||||
|
tv.Usec = usec
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetKevent(k *Kevent_t, fd, mode, flags int) {
|
||||||
|
k.Ident = uint64(fd)
|
||||||
|
k.Filter = int16(mode)
|
||||||
|
k.Flags = uint16(flags)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (iov *Iovec) SetLen(length int) {
|
||||||
|
iov.Len = uint64(length)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (msghdr *Msghdr) SetControllen(length int) {
|
||||||
|
msghdr.Controllen = uint32(length)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmsg *Cmsghdr) SetLen(length int) {
|
||||||
|
cmsg.Len = uint32(length)
|
||||||
|
}
|
||||||
|
|
||||||
|
func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
|
||||||
|
var length = uint64(count)
|
||||||
|
|
||||||
|
_, _, e1 := Syscall6(SYS_SENDFILE, uintptr(infd), uintptr(outfd), uintptr(*offset), uintptr(unsafe.Pointer(&length)), 0, 0)
|
||||||
|
|
||||||
|
written = int(length)
|
||||||
|
|
||||||
|
if e1 != 0 {
|
||||||
|
err = e1
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno) // sic
|
||||||
|
|
||||||
|
// SYS___SYSCTL is used by syscall_bsd.go for all BSDs, but in modern versions
|
||||||
|
// of darwin/arm64 the syscall is called sysctl instead of __sysctl.
|
||||||
|
const SYS___SYSCTL = SYS_SYSCTL
|
412
vendor/golang.org/x/sys/unix/syscall_dragonfly.go
generated
vendored
Normal file
412
vendor/golang.org/x/sys/unix/syscall_dragonfly.go
generated
vendored
Normal file
|
@ -0,0 +1,412 @@
|
||||||
|
// Copyright 2009,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.
|
||||||
|
|
||||||
|
// FreeBSD system calls.
|
||||||
|
// This file is compiled as ordinary Go code,
|
||||||
|
// but it is also input to mksyscall,
|
||||||
|
// which parses the //sys lines and generates system call stubs.
|
||||||
|
// Note that sometimes we use a lowercase //sys name and wrap
|
||||||
|
// it in our own nicer implementation, either here or in
|
||||||
|
// syscall_bsd.go or syscall_unix.go.
|
||||||
|
|
||||||
|
package unix
|
||||||
|
|
||||||
|
import "unsafe"
|
||||||
|
|
||||||
|
type SockaddrDatalink struct {
|
||||||
|
Len uint8
|
||||||
|
Family uint8
|
||||||
|
Index uint16
|
||||||
|
Type uint8
|
||||||
|
Nlen uint8
|
||||||
|
Alen uint8
|
||||||
|
Slen uint8
|
||||||
|
Data [12]int8
|
||||||
|
Rcf uint16
|
||||||
|
Route [16]uint16
|
||||||
|
raw RawSockaddrDatalink
|
||||||
|
}
|
||||||
|
|
||||||
|
// Translate "kern.hostname" to []_C_int{0,1,2,3}.
|
||||||
|
func nametomib(name string) (mib []_C_int, err error) {
|
||||||
|
const siz = unsafe.Sizeof(mib[0])
|
||||||
|
|
||||||
|
// 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
|
||||||
|
// 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
|
||||||
|
// and we'll get memory corruption.
|
||||||
|
var buf [CTL_MAXNAME + 2]_C_int
|
||||||
|
n := uintptr(CTL_MAXNAME) * siz
|
||||||
|
|
||||||
|
p := (*byte)(unsafe.Pointer(&buf[0]))
|
||||||
|
bytes, err := ByteSliceFromString(name)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Magic sysctl: "setting" 0.3 to a string name
|
||||||
|
// lets you read back the array of integers form.
|
||||||
|
if err = sysctl([]_C_int{0, 3}, p, &n, &bytes[0], uintptr(len(name))); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
return origlen - len(buf), count, names
|
||||||
|
}
|
||||||
|
|
||||||
|
//sysnb pipe() (r int, w int, err error)
|
||||||
|
|
||||||
|
func Pipe(p []int) (err error) {
|
||||||
|
if len(p) != 2 {
|
||||||
|
return EINVAL
|
||||||
|
}
|
||||||
|
p[0], p[1], err = pipe()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//sys extpread(fd int, p []byte, flags int, offset int64) (n int, err error)
|
||||||
|
func Pread(fd int, p []byte, offset int64) (n int, err error) {
|
||||||
|
return extpread(fd, p, 0, offset)
|
||||||
|
}
|
||||||
|
|
||||||
|
//sys extpwrite(fd int, p []byte, flags int, offset int64) (n int, err error)
|
||||||
|
func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
|
||||||
|
return extpwrite(fd, p, 0, offset)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
|
||||||
|
var _p0 unsafe.Pointer
|
||||||
|
var bufsize uintptr
|
||||||
|
if len(buf) > 0 {
|
||||||
|
_p0 = unsafe.Pointer(&buf[0])
|
||||||
|
bufsize = unsafe.Sizeof(Statfs_t{}) * uintptr(len(buf))
|
||||||
|
}
|
||||||
|
r0, _, e1 := Syscall(SYS_GETFSSTAT, uintptr(_p0), bufsize, uintptr(flags))
|
||||||
|
use(unsafe.Pointer(_p0))
|
||||||
|
n = int(r0)
|
||||||
|
if e1 != 0 {
|
||||||
|
err = e1
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Exposed directly
|
||||||
|
*/
|
||||||
|
//sys Access(path string, mode uint32) (err error)
|
||||||
|
//sys Adjtime(delta *Timeval, olddelta *Timeval) (err error)
|
||||||
|
//sys Chdir(path string) (err error)
|
||||||
|
//sys Chflags(path string, flags int) (err error)
|
||||||
|
//sys Chmod(path string, mode uint32) (err error)
|
||||||
|
//sys Chown(path string, uid int, gid int) (err error)
|
||||||
|
//sys Chroot(path string) (err error)
|
||||||
|
//sys Close(fd int) (err error)
|
||||||
|
//sys Dup(fd int) (nfd int, err error)
|
||||||
|
//sys Dup2(from int, to int) (err error)
|
||||||
|
//sys Exit(code int)
|
||||||
|
//sys Fchdir(fd int) (err error)
|
||||||
|
//sys Fchflags(fd int, flags int) (err error)
|
||||||
|
//sys Fchmod(fd int, mode uint32) (err error)
|
||||||
|
//sys Fchown(fd int, uid int, gid 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 Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error)
|
||||||
|
//sys Getdtablesize() (size int)
|
||||||
|
//sysnb Getegid() (egid int)
|
||||||
|
//sysnb Geteuid() (uid int)
|
||||||
|
//sysnb Getgid() (gid int)
|
||||||
|
//sysnb Getpgid(pid int) (pgid int, err error)
|
||||||
|
//sysnb Getpgrp() (pgrp int)
|
||||||
|
//sysnb Getpid() (pid int)
|
||||||
|
//sysnb Getppid() (ppid int)
|
||||||
|
//sys Getpriority(which int, who int) (prio int, err error)
|
||||||
|
//sysnb Getrlimit(which int, lim *Rlimit) (err error)
|
||||||
|
//sysnb Getrusage(who int, rusage *Rusage) (err error)
|
||||||
|
//sysnb Getsid(pid int) (sid int, err error)
|
||||||
|
//sysnb Gettimeofday(tv *Timeval) (err error)
|
||||||
|
//sysnb Getuid() (uid int)
|
||||||
|
//sys Issetugid() (tainted bool)
|
||||||
|
//sys Kill(pid int, signum syscall.Signal) (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 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 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)
|
||||||
|
//sys read(fd int, p []byte) (n int, err error)
|
||||||
|
//sys Readlink(path string, buf []byte) (n int, err error)
|
||||||
|
//sys Rename(from string, 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
|
||||||
|
//sys Select(n int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (err error)
|
||||||
|
//sysnb Setegid(egid int) (err error)
|
||||||
|
//sysnb Seteuid(euid int) (err error)
|
||||||
|
//sysnb Setgid(gid int) (err error)
|
||||||
|
//sys Setlogin(name string) (err error)
|
||||||
|
//sysnb Setpgid(pid int, pgid int) (err error)
|
||||||
|
//sys Setpriority(which int, who int, prio int) (err error)
|
||||||
|
//sysnb Setregid(rgid int, egid int) (err error)
|
||||||
|
//sysnb Setreuid(ruid int, euid int) (err error)
|
||||||
|
//sysnb Setresgid(rgid int, egid int, sgid int) (err error)
|
||||||
|
//sysnb Setresuid(ruid int, euid int, suid int) (err error)
|
||||||
|
//sysnb Setrlimit(which int, lim *Rlimit) (err error)
|
||||||
|
//sysnb Setsid() (pid int, err error)
|
||||||
|
//sysnb Settimeofday(tp *Timeval) (err error)
|
||||||
|
//sysnb Setuid(uid 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 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 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)
|
||||||
|
//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
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Unimplemented
|
||||||
|
* TODO(jsing): Update this list for DragonFly.
|
||||||
|
*/
|
||||||
|
// Profil
|
||||||
|
// Sigaction
|
||||||
|
// Sigprocmask
|
||||||
|
// Getlogin
|
||||||
|
// Sigpending
|
||||||
|
// Sigaltstack
|
||||||
|
// Ioctl
|
||||||
|
// Reboot
|
||||||
|
// Execve
|
||||||
|
// Vfork
|
||||||
|
// Sbrk
|
||||||
|
// Sstk
|
||||||
|
// Ovadvise
|
||||||
|
// Mincore
|
||||||
|
// Setitimer
|
||||||
|
// Swapon
|
||||||
|
// Select
|
||||||
|
// Sigsuspend
|
||||||
|
// Readv
|
||||||
|
// Writev
|
||||||
|
// Nfssvc
|
||||||
|
// Getfh
|
||||||
|
// Quotactl
|
||||||
|
// Mount
|
||||||
|
// Csops
|
||||||
|
// Waitid
|
||||||
|
// Add_profil
|
||||||
|
// Kdebug_trace
|
||||||
|
// Sigreturn
|
||||||
|
// Mmap
|
||||||
|
// Atsocket
|
||||||
|
// Kqueue_from_portset_np
|
||||||
|
// Kqueue_portset
|
||||||
|
// Getattrlist
|
||||||
|
// Setattrlist
|
||||||
|
// Getdirentriesattr
|
||||||
|
// Searchfs
|
||||||
|
// Delete
|
||||||
|
// Copyfile
|
||||||
|
// Poll
|
||||||
|
// Watchevent
|
||||||
|
// Waitevent
|
||||||
|
// Modwatch
|
||||||
|
// Getxattr
|
||||||
|
// Fgetxattr
|
||||||
|
// Setxattr
|
||||||
|
// Fsetxattr
|
||||||
|
// Removexattr
|
||||||
|
// Fremovexattr
|
||||||
|
// Listxattr
|
||||||
|
// Flistxattr
|
||||||
|
// Fsctl
|
||||||
|
// Initgroups
|
||||||
|
// Posix_spawn
|
||||||
|
// Nfsclnt
|
||||||
|
// Fhopen
|
||||||
|
// Minherit
|
||||||
|
// Semsys
|
||||||
|
// Msgsys
|
||||||
|
// Shmsys
|
||||||
|
// Semctl
|
||||||
|
// Semget
|
||||||
|
// Semop
|
||||||
|
// Msgctl
|
||||||
|
// Msgget
|
||||||
|
// Msgsnd
|
||||||
|
// Msgrcv
|
||||||
|
// Shmat
|
||||||
|
// Shmctl
|
||||||
|
// Shmdt
|
||||||
|
// Shmget
|
||||||
|
// Shm_open
|
||||||
|
// Shm_unlink
|
||||||
|
// Sem_open
|
||||||
|
// Sem_close
|
||||||
|
// Sem_unlink
|
||||||
|
// Sem_wait
|
||||||
|
// Sem_trywait
|
||||||
|
// Sem_post
|
||||||
|
// Sem_getvalue
|
||||||
|
// Sem_init
|
||||||
|
// Sem_destroy
|
||||||
|
// Open_extended
|
||||||
|
// Umask_extended
|
||||||
|
// Stat_extended
|
||||||
|
// Lstat_extended
|
||||||
|
// Fstat_extended
|
||||||
|
// Chmod_extended
|
||||||
|
// Fchmod_extended
|
||||||
|
// Access_extended
|
||||||
|
// Settid
|
||||||
|
// Gettid
|
||||||
|
// Setsgroups
|
||||||
|
// Getsgroups
|
||||||
|
// Setwgroups
|
||||||
|
// Getwgroups
|
||||||
|
// Mkfifo_extended
|
||||||
|
// Mkdir_extended
|
||||||
|
// Identitysvc
|
||||||
|
// Shared_region_check_np
|
||||||
|
// Shared_region_map_np
|
||||||
|
// __pthread_mutex_destroy
|
||||||
|
// __pthread_mutex_init
|
||||||
|
// __pthread_mutex_lock
|
||||||
|
// __pthread_mutex_trylock
|
||||||
|
// __pthread_mutex_unlock
|
||||||
|
// __pthread_cond_init
|
||||||
|
// __pthread_cond_destroy
|
||||||
|
// __pthread_cond_broadcast
|
||||||
|
// __pthread_cond_signal
|
||||||
|
// Setsid_with_pid
|
||||||
|
// __pthread_cond_timedwait
|
||||||
|
// Aio_fsync
|
||||||
|
// Aio_return
|
||||||
|
// Aio_suspend
|
||||||
|
// Aio_cancel
|
||||||
|
// Aio_error
|
||||||
|
// Aio_read
|
||||||
|
// Aio_write
|
||||||
|
// Lio_listio
|
||||||
|
// __pthread_cond_wait
|
||||||
|
// Iopolicysys
|
||||||
|
// __pthread_kill
|
||||||
|
// __pthread_sigmask
|
||||||
|
// __sigwait
|
||||||
|
// __disable_threadsignal
|
||||||
|
// __pthread_markcancel
|
||||||
|
// __pthread_canceled
|
||||||
|
// __semwait_signal
|
||||||
|
// Proc_info
|
||||||
|
// Stat64_extended
|
||||||
|
// Lstat64_extended
|
||||||
|
// Fstat64_extended
|
||||||
|
// __pthread_chdir
|
||||||
|
// __pthread_fchdir
|
||||||
|
// Audit
|
||||||
|
// Auditon
|
||||||
|
// Getauid
|
||||||
|
// Setauid
|
||||||
|
// Getaudit
|
||||||
|
// Setaudit
|
||||||
|
// Getaudit_addr
|
||||||
|
// Setaudit_addr
|
||||||
|
// Auditctl
|
||||||
|
// Bsdthread_create
|
||||||
|
// Bsdthread_terminate
|
||||||
|
// Stack_snapshot
|
||||||
|
// Bsdthread_register
|
||||||
|
// Workq_open
|
||||||
|
// Workq_ops
|
||||||
|
// __mac_execve
|
||||||
|
// __mac_syscall
|
||||||
|
// __mac_get_file
|
||||||
|
// __mac_set_file
|
||||||
|
// __mac_get_link
|
||||||
|
// __mac_set_link
|
||||||
|
// __mac_get_proc
|
||||||
|
// __mac_set_proc
|
||||||
|
// __mac_get_fd
|
||||||
|
// __mac_set_fd
|
||||||
|
// __mac_get_pid
|
||||||
|
// __mac_get_lcid
|
||||||
|
// __mac_get_lctx
|
||||||
|
// __mac_set_lctx
|
||||||
|
// Setlcid
|
||||||
|
// Read_nocancel
|
||||||
|
// Write_nocancel
|
||||||
|
// Open_nocancel
|
||||||
|
// Close_nocancel
|
||||||
|
// Wait4_nocancel
|
||||||
|
// Recvmsg_nocancel
|
||||||
|
// Sendmsg_nocancel
|
||||||
|
// Recvfrom_nocancel
|
||||||
|
// Accept_nocancel
|
||||||
|
// Msync_nocancel
|
||||||
|
// Fcntl_nocancel
|
||||||
|
// Select_nocancel
|
||||||
|
// Fsync_nocancel
|
||||||
|
// Connect_nocancel
|
||||||
|
// Sigsuspend_nocancel
|
||||||
|
// Readv_nocancel
|
||||||
|
// Writev_nocancel
|
||||||
|
// Sendto_nocancel
|
||||||
|
// Pread_nocancel
|
||||||
|
// Pwrite_nocancel
|
||||||
|
// Waitid_nocancel
|
||||||
|
// Poll_nocancel
|
||||||
|
// Msgsnd_nocancel
|
||||||
|
// Msgrcv_nocancel
|
||||||
|
// Sem_wait_nocancel
|
||||||
|
// Aio_suspend_nocancel
|
||||||
|
// __sigwait_nocancel
|
||||||
|
// __semwait_signal_nocancel
|
||||||
|
// __mac_mount
|
||||||
|
// __mac_get_mount
|
||||||
|
// __mac_getfsstat
|
61
vendor/golang.org/x/sys/unix/syscall_dragonfly_amd64.go
generated
vendored
Normal file
61
vendor/golang.org/x/sys/unix/syscall_dragonfly_amd64.go
generated
vendored
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
// 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 amd64,dragonfly
|
||||||
|
|
||||||
|
package unix
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Getpagesize() int { return 4096 }
|
||||||
|
|
||||||
|
func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
|
||||||
|
|
||||||
|
func NsecToTimespec(nsec int64) (ts Timespec) {
|
||||||
|
ts.Sec = nsec / 1e9
|
||||||
|
ts.Nsec = nsec % 1e9
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func NsecToTimeval(nsec int64) (tv Timeval) {
|
||||||
|
nsec += 999 // round up to microsecond
|
||||||
|
tv.Usec = nsec % 1e9 / 1e3
|
||||||
|
tv.Sec = int64(nsec / 1e9)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetKevent(k *Kevent_t, fd, mode, flags int) {
|
||||||
|
k.Ident = uint64(fd)
|
||||||
|
k.Filter = int16(mode)
|
||||||
|
k.Flags = uint16(flags)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (iov *Iovec) SetLen(length int) {
|
||||||
|
iov.Len = uint64(length)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (msghdr *Msghdr) SetControllen(length int) {
|
||||||
|
msghdr.Controllen = uint32(length)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmsg *Cmsghdr) SetLen(length int) {
|
||||||
|
cmsg.Len = uint32(length)
|
||||||
|
}
|
||||||
|
|
||||||
|
func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
|
||||||
|
var writtenOut uint64 = 0
|
||||||
|
_, _, e1 := Syscall9(SYS_SENDFILE, uintptr(infd), uintptr(outfd), uintptr(*offset), uintptr(count), 0, uintptr(unsafe.Pointer(&writtenOut)), 0, 0, 0)
|
||||||
|
|
||||||
|
written = int(writtenOut)
|
||||||
|
|
||||||
|
if e1 != 0 {
|
||||||
|
err = e1
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)
|
683
vendor/golang.org/x/sys/unix/syscall_freebsd.go
generated
vendored
Normal file
683
vendor/golang.org/x/sys/unix/syscall_freebsd.go
generated
vendored
Normal file
|
@ -0,0 +1,683 @@
|
||||||
|
// Copyright 2009,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.
|
||||||
|
|
||||||
|
// FreeBSD system calls.
|
||||||
|
// This file is compiled as ordinary Go code,
|
||||||
|
// but it is also input to mksyscall,
|
||||||
|
// which parses the //sys lines and generates system call stubs.
|
||||||
|
// Note that sometimes we use a lowercase //sys name and wrap
|
||||||
|
// it in our own nicer implementation, either here or in
|
||||||
|
// syscall_bsd.go or syscall_unix.go.
|
||||||
|
|
||||||
|
package unix
|
||||||
|
|
||||||
|
import "unsafe"
|
||||||
|
|
||||||
|
type SockaddrDatalink struct {
|
||||||
|
Len uint8
|
||||||
|
Family uint8
|
||||||
|
Index uint16
|
||||||
|
Type uint8
|
||||||
|
Nlen uint8
|
||||||
|
Alen uint8
|
||||||
|
Slen uint8
|
||||||
|
Data [46]int8
|
||||||
|
raw RawSockaddrDatalink
|
||||||
|
}
|
||||||
|
|
||||||
|
// Translate "kern.hostname" to []_C_int{0,1,2,3}.
|
||||||
|
func nametomib(name string) (mib []_C_int, err error) {
|
||||||
|
const siz = unsafe.Sizeof(mib[0])
|
||||||
|
|
||||||
|
// 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
|
||||||
|
// 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
|
||||||
|
// and we'll get memory corruption.
|
||||||
|
var buf [CTL_MAXNAME + 2]_C_int
|
||||||
|
n := uintptr(CTL_MAXNAME) * siz
|
||||||
|
|
||||||
|
p := (*byte)(unsafe.Pointer(&buf[0]))
|
||||||
|
bytes, err := ByteSliceFromString(name)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Magic sysctl: "setting" 0.3 to a string name
|
||||||
|
// lets you read back the array of integers form.
|
||||||
|
if err = sysctl([]_C_int{0, 3}, p, &n, &bytes[0], uintptr(len(name))); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
//sysnb pipe() (r int, w int, err error)
|
||||||
|
|
||||||
|
func Pipe(p []int) (err error) {
|
||||||
|
if len(p) != 2 {
|
||||||
|
return EINVAL
|
||||||
|
}
|
||||||
|
p[0], p[1], err = pipe()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetsockoptIPMreqn(fd, level, opt int) (*IPMreqn, error) {
|
||||||
|
var value IPMreqn
|
||||||
|
vallen := _Socklen(SizeofIPMreqn)
|
||||||
|
errno := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
|
||||||
|
return &value, errno
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetsockoptIPMreqn(fd, level, opt int, mreq *IPMreqn) (err error) {
|
||||||
|
return setsockopt(fd, level, opt, unsafe.Pointer(mreq), unsafe.Sizeof(*mreq))
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
|
||||||
|
var _p0 unsafe.Pointer
|
||||||
|
var bufsize uintptr
|
||||||
|
if len(buf) > 0 {
|
||||||
|
_p0 = unsafe.Pointer(&buf[0])
|
||||||
|
bufsize = unsafe.Sizeof(Statfs_t{}) * uintptr(len(buf))
|
||||||
|
}
|
||||||
|
r0, _, e1 := Syscall(SYS_GETFSSTAT, uintptr(_p0), bufsize, uintptr(flags))
|
||||||
|
use(unsafe.Pointer(_p0))
|
||||||
|
n = int(r0)
|
||||||
|
if e1 != 0 {
|
||||||
|
err = e1
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Derive extattr namespace and attribute name
|
||||||
|
|
||||||
|
func xattrnamespace(fullattr string) (ns int, attr string, err error) {
|
||||||
|
s := -1
|
||||||
|
for idx, val := range fullattr {
|
||||||
|
if val == '.' {
|
||||||
|
s = idx
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if s == -1 {
|
||||||
|
return -1, "", ENOATTR
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace := fullattr[0:s]
|
||||||
|
attr = fullattr[s+1:]
|
||||||
|
|
||||||
|
switch namespace {
|
||||||
|
case "user":
|
||||||
|
return EXTATTR_NAMESPACE_USER, attr, nil
|
||||||
|
case "system":
|
||||||
|
return EXTATTR_NAMESPACE_SYSTEM, attr, nil
|
||||||
|
default:
|
||||||
|
return -1, "", ENOATTR
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func initxattrdest(dest []byte, idx int) (d unsafe.Pointer) {
|
||||||
|
if len(dest) > idx {
|
||||||
|
return unsafe.Pointer(&dest[idx])
|
||||||
|
} else {
|
||||||
|
return unsafe.Pointer(_zero)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FreeBSD implements its own syscalls to handle extended attributes
|
||||||
|
|
||||||
|
func Getxattr(file string, attr string, dest []byte) (sz int, err error) {
|
||||||
|
d := initxattrdest(dest, 0)
|
||||||
|
destsize := len(dest)
|
||||||
|
|
||||||
|
nsid, a, err := xattrnamespace(attr)
|
||||||
|
if err != nil {
|
||||||
|
return -1, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return ExtattrGetFile(file, nsid, a, uintptr(d), destsize)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Fgetxattr(fd int, attr string, dest []byte) (sz int, err error) {
|
||||||
|
d := initxattrdest(dest, 0)
|
||||||
|
destsize := len(dest)
|
||||||
|
|
||||||
|
nsid, a, err := xattrnamespace(attr)
|
||||||
|
if err != nil {
|
||||||
|
return -1, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return ExtattrGetFd(fd, nsid, a, uintptr(d), destsize)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Lgetxattr(link string, attr string, dest []byte) (sz int, err error) {
|
||||||
|
d := initxattrdest(dest, 0)
|
||||||
|
destsize := len(dest)
|
||||||
|
|
||||||
|
nsid, a, err := xattrnamespace(attr)
|
||||||
|
if err != nil {
|
||||||
|
return -1, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return ExtattrGetLink(link, nsid, a, uintptr(d), destsize)
|
||||||
|
}
|
||||||
|
|
||||||
|
// flags are unused on FreeBSD
|
||||||
|
|
||||||
|
func Fsetxattr(fd int, attr string, data []byte, flags int) (err error) {
|
||||||
|
d := unsafe.Pointer(&data[0])
|
||||||
|
datasiz := len(data)
|
||||||
|
|
||||||
|
nsid, a, err := xattrnamespace(attr)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = ExtattrSetFd(fd, nsid, a, uintptr(d), datasiz)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func Setxattr(file string, attr string, data []byte, flags int) (err error) {
|
||||||
|
d := unsafe.Pointer(&data[0])
|
||||||
|
datasiz := len(data)
|
||||||
|
|
||||||
|
nsid, a, err := xattrnamespace(attr)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = ExtattrSetFile(file, nsid, a, uintptr(d), datasiz)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func Lsetxattr(link string, attr string, data []byte, flags int) (err error) {
|
||||||
|
d := unsafe.Pointer(&data[0])
|
||||||
|
datasiz := len(data)
|
||||||
|
|
||||||
|
nsid, a, err := xattrnamespace(attr)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = ExtattrSetLink(link, nsid, a, uintptr(d), datasiz)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func Removexattr(file string, attr string) (err error) {
|
||||||
|
nsid, a, err := xattrnamespace(attr)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = ExtattrDeleteFile(file, nsid, a)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func Fremovexattr(fd int, attr string) (err error) {
|
||||||
|
nsid, a, err := xattrnamespace(attr)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = ExtattrDeleteFd(fd, nsid, a)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func Lremovexattr(link string, attr string) (err error) {
|
||||||
|
nsid, a, err := xattrnamespace(attr)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = ExtattrDeleteLink(link, nsid, a)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func Listxattr(file string, dest []byte) (sz int, err error) {
|
||||||
|
d := initxattrdest(dest, 0)
|
||||||
|
destsiz := len(dest)
|
||||||
|
|
||||||
|
// FreeBSD won't allow you to list xattrs from multiple namespaces
|
||||||
|
s := 0
|
||||||
|
var e error
|
||||||
|
for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} {
|
||||||
|
stmp, e := ExtattrListFile(file, nsid, uintptr(d), destsiz)
|
||||||
|
|
||||||
|
/* Errors accessing system attrs are ignored so that
|
||||||
|
* we can implement the Linux-like behavior of omitting errors that
|
||||||
|
* we don't have read permissions on
|
||||||
|
*
|
||||||
|
* Linux will still error if we ask for user attributes on a file that
|
||||||
|
* we don't have read permissions on, so don't ignore those errors
|
||||||
|
*/
|
||||||
|
if e != nil && e == EPERM && nsid != EXTATTR_NAMESPACE_USER {
|
||||||
|
e = nil
|
||||||
|
continue
|
||||||
|
} else if e != nil {
|
||||||
|
return s, e
|
||||||
|
}
|
||||||
|
|
||||||
|
s += stmp
|
||||||
|
destsiz -= s
|
||||||
|
if destsiz < 0 {
|
||||||
|
destsiz = 0
|
||||||
|
}
|
||||||
|
d = initxattrdest(dest, s)
|
||||||
|
}
|
||||||
|
|
||||||
|
return s, e
|
||||||
|
}
|
||||||
|
|
||||||
|
func Flistxattr(fd int, dest []byte) (sz int, err error) {
|
||||||
|
d := initxattrdest(dest, 0)
|
||||||
|
destsiz := len(dest)
|
||||||
|
|
||||||
|
s := 0
|
||||||
|
var e error
|
||||||
|
for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} {
|
||||||
|
stmp, e := ExtattrListFd(fd, nsid, uintptr(d), destsiz)
|
||||||
|
if e != nil && e == EPERM && nsid != EXTATTR_NAMESPACE_USER {
|
||||||
|
e = nil
|
||||||
|
continue
|
||||||
|
} else if e != nil {
|
||||||
|
return s, e
|
||||||
|
}
|
||||||
|
|
||||||
|
s += stmp
|
||||||
|
destsiz -= s
|
||||||
|
if destsiz < 0 {
|
||||||
|
destsiz = 0
|
||||||
|
}
|
||||||
|
d = initxattrdest(dest, s)
|
||||||
|
}
|
||||||
|
|
||||||
|
return s, e
|
||||||
|
}
|
||||||
|
|
||||||
|
func Llistxattr(link string, dest []byte) (sz int, err error) {
|
||||||
|
d := initxattrdest(dest, 0)
|
||||||
|
destsiz := len(dest)
|
||||||
|
|
||||||
|
s := 0
|
||||||
|
var e error
|
||||||
|
for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} {
|
||||||
|
stmp, e := ExtattrListLink(link, nsid, uintptr(d), destsiz)
|
||||||
|
if e != nil && e == EPERM && nsid != EXTATTR_NAMESPACE_USER {
|
||||||
|
e = nil
|
||||||
|
continue
|
||||||
|
} else if e != nil {
|
||||||
|
return s, e
|
||||||
|
}
|
||||||
|
|
||||||
|
s += stmp
|
||||||
|
destsiz -= s
|
||||||
|
if destsiz < 0 {
|
||||||
|
destsiz = 0
|
||||||
|
}
|
||||||
|
d = initxattrdest(dest, s)
|
||||||
|
}
|
||||||
|
|
||||||
|
return s, e
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Exposed directly
|
||||||
|
*/
|
||||||
|
//sys Access(path string, mode uint32) (err error)
|
||||||
|
//sys Adjtime(delta *Timeval, olddelta *Timeval) (err error)
|
||||||
|
//sys Chdir(path string) (err error)
|
||||||
|
//sys Chflags(path string, flags int) (err error)
|
||||||
|
//sys Chmod(path string, mode uint32) (err error)
|
||||||
|
//sys Chown(path string, uid int, gid int) (err error)
|
||||||
|
//sys Chroot(path string) (err error)
|
||||||
|
//sys Close(fd int) (err error)
|
||||||
|
//sys Dup(fd int) (nfd int, err error)
|
||||||
|
//sys Dup2(from int, to int) (err error)
|
||||||
|
//sys Exit(code int)
|
||||||
|
//sys ExtattrGetFd(fd int, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error)
|
||||||
|
//sys ExtattrSetFd(fd int, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error)
|
||||||
|
//sys ExtattrDeleteFd(fd int, attrnamespace int, attrname string) (err error)
|
||||||
|
//sys ExtattrListFd(fd int, attrnamespace int, data uintptr, nbytes int) (ret int, err error)
|
||||||
|
//sys ExtattrGetFile(file string, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error)
|
||||||
|
//sys ExtattrSetFile(file string, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error)
|
||||||
|
//sys ExtattrDeleteFile(file string, attrnamespace int, attrname string) (err error)
|
||||||
|
//sys ExtattrListFile(file string, attrnamespace int, data uintptr, nbytes int) (ret int, err error)
|
||||||
|
//sys ExtattrGetLink(link string, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error)
|
||||||
|
//sys ExtattrSetLink(link string, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error)
|
||||||
|
//sys ExtattrDeleteLink(link string, attrnamespace int, attrname string) (err error)
|
||||||
|
//sys ExtattrListLink(link string, attrnamespace int, data uintptr, nbytes int) (ret int, err error)
|
||||||
|
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_POSIX_FADVISE
|
||||||
|
//sys Fchdir(fd int) (err error)
|
||||||
|
//sys Fchflags(fd int, flags int) (err error)
|
||||||
|
//sys Fchmod(fd int, mode uint32) (err error)
|
||||||
|
//sys Fchown(fd int, uid int, gid 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 Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error)
|
||||||
|
//sys Getdtablesize() (size int)
|
||||||
|
//sysnb Getegid() (egid int)
|
||||||
|
//sysnb Geteuid() (uid int)
|
||||||
|
//sysnb Getgid() (gid int)
|
||||||
|
//sysnb Getpgid(pid int) (pgid int, err error)
|
||||||
|
//sysnb Getpgrp() (pgrp int)
|
||||||
|
//sysnb Getpid() (pid int)
|
||||||
|
//sysnb Getppid() (ppid int)
|
||||||
|
//sys Getpriority(which int, who int) (prio int, err error)
|
||||||
|
//sysnb Getrlimit(which int, lim *Rlimit) (err error)
|
||||||
|
//sysnb Getrusage(who int, rusage *Rusage) (err error)
|
||||||
|
//sysnb Getsid(pid int) (sid int, err error)
|
||||||
|
//sysnb Gettimeofday(tv *Timeval) (err error)
|
||||||
|
//sysnb Getuid() (uid int)
|
||||||
|
//sys Issetugid() (tainted bool)
|
||||||
|
//sys Kill(pid int, signum syscall.Signal) (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 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 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)
|
||||||
|
//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 Rename(from string, 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
|
||||||
|
//sys Select(n int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (err error)
|
||||||
|
//sysnb Setegid(egid int) (err error)
|
||||||
|
//sysnb Seteuid(euid int) (err error)
|
||||||
|
//sysnb Setgid(gid int) (err error)
|
||||||
|
//sys Setlogin(name string) (err error)
|
||||||
|
//sysnb Setpgid(pid int, pgid int) (err error)
|
||||||
|
//sys Setpriority(which int, who int, prio int) (err error)
|
||||||
|
//sysnb Setregid(rgid int, egid int) (err error)
|
||||||
|
//sysnb Setreuid(ruid int, euid int) (err error)
|
||||||
|
//sysnb Setresgid(rgid int, egid int, sgid int) (err error)
|
||||||
|
//sysnb Setresuid(ruid int, euid int, suid int) (err error)
|
||||||
|
//sysnb Setrlimit(which int, lim *Rlimit) (err error)
|
||||||
|
//sysnb Setsid() (pid int, err error)
|
||||||
|
//sysnb Settimeofday(tp *Timeval) (err error)
|
||||||
|
//sysnb Setuid(uid 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 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 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)
|
||||||
|
//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)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Unimplemented
|
||||||
|
*/
|
||||||
|
// Profil
|
||||||
|
// Sigaction
|
||||||
|
// Sigprocmask
|
||||||
|
// Getlogin
|
||||||
|
// Sigpending
|
||||||
|
// Sigaltstack
|
||||||
|
// Ioctl
|
||||||
|
// Reboot
|
||||||
|
// Execve
|
||||||
|
// Vfork
|
||||||
|
// Sbrk
|
||||||
|
// Sstk
|
||||||
|
// Ovadvise
|
||||||
|
// Mincore
|
||||||
|
// Setitimer
|
||||||
|
// Swapon
|
||||||
|
// Select
|
||||||
|
// Sigsuspend
|
||||||
|
// Readv
|
||||||
|
// Writev
|
||||||
|
// Nfssvc
|
||||||
|
// Getfh
|
||||||
|
// Quotactl
|
||||||
|
// Mount
|
||||||
|
// Csops
|
||||||
|
// Waitid
|
||||||
|
// Add_profil
|
||||||
|
// Kdebug_trace
|
||||||
|
// Sigreturn
|
||||||
|
// Mmap
|
||||||
|
// Mlock
|
||||||
|
// Munlock
|
||||||
|
// Atsocket
|
||||||
|
// Kqueue_from_portset_np
|
||||||
|
// Kqueue_portset
|
||||||
|
// Getattrlist
|
||||||
|
// Setattrlist
|
||||||
|
// Getdirentriesattr
|
||||||
|
// Searchfs
|
||||||
|
// Delete
|
||||||
|
// Copyfile
|
||||||
|
// Poll
|
||||||
|
// Watchevent
|
||||||
|
// Waitevent
|
||||||
|
// Modwatch
|
||||||
|
// Getxattr
|
||||||
|
// Fgetxattr
|
||||||
|
// Setxattr
|
||||||
|
// Fsetxattr
|
||||||
|
// Removexattr
|
||||||
|
// Fremovexattr
|
||||||
|
// Listxattr
|
||||||
|
// Flistxattr
|
||||||
|
// Fsctl
|
||||||
|
// Initgroups
|
||||||
|
// Posix_spawn
|
||||||
|
// Nfsclnt
|
||||||
|
// Fhopen
|
||||||
|
// Minherit
|
||||||
|
// Semsys
|
||||||
|
// Msgsys
|
||||||
|
// Shmsys
|
||||||
|
// Semctl
|
||||||
|
// Semget
|
||||||
|
// Semop
|
||||||
|
// Msgctl
|
||||||
|
// Msgget
|
||||||
|
// Msgsnd
|
||||||
|
// Msgrcv
|
||||||
|
// Shmat
|
||||||
|
// Shmctl
|
||||||
|
// Shmdt
|
||||||
|
// Shmget
|
||||||
|
// Shm_open
|
||||||
|
// Shm_unlink
|
||||||
|
// Sem_open
|
||||||
|
// Sem_close
|
||||||
|
// Sem_unlink
|
||||||
|
// Sem_wait
|
||||||
|
// Sem_trywait
|
||||||
|
// Sem_post
|
||||||
|
// Sem_getvalue
|
||||||
|
// Sem_init
|
||||||
|
// Sem_destroy
|
||||||
|
// Open_extended
|
||||||
|
// Umask_extended
|
||||||
|
// Stat_extended
|
||||||
|
// Lstat_extended
|
||||||
|
// Fstat_extended
|
||||||
|
// Chmod_extended
|
||||||
|
// Fchmod_extended
|
||||||
|
// Access_extended
|
||||||
|
// Settid
|
||||||
|
// Gettid
|
||||||
|
// Setsgroups
|
||||||
|
// Getsgroups
|
||||||
|
// Setwgroups
|
||||||
|
// Getwgroups
|
||||||
|
// Mkfifo_extended
|
||||||
|
// Mkdir_extended
|
||||||
|
// Identitysvc
|
||||||
|
// Shared_region_check_np
|
||||||
|
// Shared_region_map_np
|
||||||
|
// __pthread_mutex_destroy
|
||||||
|
// __pthread_mutex_init
|
||||||
|
// __pthread_mutex_lock
|
||||||
|
// __pthread_mutex_trylock
|
||||||
|
// __pthread_mutex_unlock
|
||||||
|
// __pthread_cond_init
|
||||||
|
// __pthread_cond_destroy
|
||||||
|
// __pthread_cond_broadcast
|
||||||
|
// __pthread_cond_signal
|
||||||
|
// Setsid_with_pid
|
||||||
|
// __pthread_cond_timedwait
|
||||||
|
// Aio_fsync
|
||||||
|
// Aio_return
|
||||||
|
// Aio_suspend
|
||||||
|
// Aio_cancel
|
||||||
|
// Aio_error
|
||||||
|
// Aio_read
|
||||||
|
// Aio_write
|
||||||
|
// Lio_listio
|
||||||
|
// __pthread_cond_wait
|
||||||
|
// Iopolicysys
|
||||||
|
// Mlockall
|
||||||
|
// Munlockall
|
||||||
|
// __pthread_kill
|
||||||
|
// __pthread_sigmask
|
||||||
|
// __sigwait
|
||||||
|
// __disable_threadsignal
|
||||||
|
// __pthread_markcancel
|
||||||
|
// __pthread_canceled
|
||||||
|
// __semwait_signal
|
||||||
|
// Proc_info
|
||||||
|
// Stat64_extended
|
||||||
|
// Lstat64_extended
|
||||||
|
// Fstat64_extended
|
||||||
|
// __pthread_chdir
|
||||||
|
// __pthread_fchdir
|
||||||
|
// Audit
|
||||||
|
// Auditon
|
||||||
|
// Getauid
|
||||||
|
// Setauid
|
||||||
|
// Getaudit
|
||||||
|
// Setaudit
|
||||||
|
// Getaudit_addr
|
||||||
|
// Setaudit_addr
|
||||||
|
// Auditctl
|
||||||
|
// Bsdthread_create
|
||||||
|
// Bsdthread_terminate
|
||||||
|
// Stack_snapshot
|
||||||
|
// Bsdthread_register
|
||||||
|
// Workq_open
|
||||||
|
// Workq_ops
|
||||||
|
// __mac_execve
|
||||||
|
// __mac_syscall
|
||||||
|
// __mac_get_file
|
||||||
|
// __mac_set_file
|
||||||
|
// __mac_get_link
|
||||||
|
// __mac_set_link
|
||||||
|
// __mac_get_proc
|
||||||
|
// __mac_set_proc
|
||||||
|
// __mac_get_fd
|
||||||
|
// __mac_set_fd
|
||||||
|
// __mac_get_pid
|
||||||
|
// __mac_get_lcid
|
||||||
|
// __mac_get_lctx
|
||||||
|
// __mac_set_lctx
|
||||||
|
// Setlcid
|
||||||
|
// Read_nocancel
|
||||||
|
// Write_nocancel
|
||||||
|
// Open_nocancel
|
||||||
|
// Close_nocancel
|
||||||
|
// Wait4_nocancel
|
||||||
|
// Recvmsg_nocancel
|
||||||
|
// Sendmsg_nocancel
|
||||||
|
// Recvfrom_nocancel
|
||||||
|
// Accept_nocancel
|
||||||
|
// Msync_nocancel
|
||||||
|
// Fcntl_nocancel
|
||||||
|
// Select_nocancel
|
||||||
|
// Fsync_nocancel
|
||||||
|
// Connect_nocancel
|
||||||
|
// Sigsuspend_nocancel
|
||||||
|
// Readv_nocancel
|
||||||
|
// Writev_nocancel
|
||||||
|
// Sendto_nocancel
|
||||||
|
// Pread_nocancel
|
||||||
|
// Pwrite_nocancel
|
||||||
|
// Waitid_nocancel
|
||||||
|
// Poll_nocancel
|
||||||
|
// Msgsnd_nocancel
|
||||||
|
// Msgrcv_nocancel
|
||||||
|
// Sem_wait_nocancel
|
||||||
|
// Aio_suspend_nocancel
|
||||||
|
// __sigwait_nocancel
|
||||||
|
// __semwait_signal_nocancel
|
||||||
|
// __mac_mount
|
||||||
|
// __mac_get_mount
|
||||||
|
// __mac_getfsstat
|
61
vendor/golang.org/x/sys/unix/syscall_freebsd_386.go
generated
vendored
Normal file
61
vendor/golang.org/x/sys/unix/syscall_freebsd_386.go
generated
vendored
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build 386,freebsd
|
||||||
|
|
||||||
|
package unix
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Getpagesize() int { return 4096 }
|
||||||
|
|
||||||
|
func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
|
||||||
|
|
||||||
|
func NsecToTimespec(nsec int64) (ts Timespec) {
|
||||||
|
ts.Sec = int32(nsec / 1e9)
|
||||||
|
ts.Nsec = int32(nsec % 1e9)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func NsecToTimeval(nsec int64) (tv Timeval) {
|
||||||
|
nsec += 999 // round up to microsecond
|
||||||
|
tv.Usec = int32(nsec % 1e9 / 1e3)
|
||||||
|
tv.Sec = int32(nsec / 1e9)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetKevent(k *Kevent_t, fd, mode, flags int) {
|
||||||
|
k.Ident = uint32(fd)
|
||||||
|
k.Filter = int16(mode)
|
||||||
|
k.Flags = uint16(flags)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (iov *Iovec) SetLen(length int) {
|
||||||
|
iov.Len = uint32(length)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (msghdr *Msghdr) SetControllen(length int) {
|
||||||
|
msghdr.Controllen = uint32(length)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmsg *Cmsghdr) SetLen(length int) {
|
||||||
|
cmsg.Len = uint32(length)
|
||||||
|
}
|
||||||
|
|
||||||
|
func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
|
||||||
|
var writtenOut uint64 = 0
|
||||||
|
_, _, e1 := Syscall9(SYS_SENDFILE, uintptr(infd), uintptr(outfd), uintptr(*offset), uintptr((*offset)>>32), uintptr(count), 0, uintptr(unsafe.Pointer(&writtenOut)), 0, 0)
|
||||||
|
|
||||||
|
written = int(writtenOut)
|
||||||
|
|
||||||
|
if e1 != 0 {
|
||||||
|
err = e1
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)
|
61
vendor/golang.org/x/sys/unix/syscall_freebsd_amd64.go
generated
vendored
Normal file
61
vendor/golang.org/x/sys/unix/syscall_freebsd_amd64.go
generated
vendored
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
// 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 amd64,freebsd
|
||||||
|
|
||||||
|
package unix
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Getpagesize() int { return 4096 }
|
||||||
|
|
||||||
|
func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
|
||||||
|
|
||||||
|
func NsecToTimespec(nsec int64) (ts Timespec) {
|
||||||
|
ts.Sec = nsec / 1e9
|
||||||
|
ts.Nsec = nsec % 1e9
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func NsecToTimeval(nsec int64) (tv Timeval) {
|
||||||
|
nsec += 999 // round up to microsecond
|
||||||
|
tv.Usec = nsec % 1e9 / 1e3
|
||||||
|
tv.Sec = int64(nsec / 1e9)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetKevent(k *Kevent_t, fd, mode, flags int) {
|
||||||
|
k.Ident = uint64(fd)
|
||||||
|
k.Filter = int16(mode)
|
||||||
|
k.Flags = uint16(flags)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (iov *Iovec) SetLen(length int) {
|
||||||
|
iov.Len = uint64(length)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (msghdr *Msghdr) SetControllen(length int) {
|
||||||
|
msghdr.Controllen = uint32(length)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmsg *Cmsghdr) SetLen(length int) {
|
||||||
|
cmsg.Len = uint32(length)
|
||||||
|
}
|
||||||
|
|
||||||
|
func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
|
||||||
|
var writtenOut uint64 = 0
|
||||||
|
_, _, e1 := Syscall9(SYS_SENDFILE, uintptr(infd), uintptr(outfd), uintptr(*offset), uintptr(count), 0, uintptr(unsafe.Pointer(&writtenOut)), 0, 0, 0)
|
||||||
|
|
||||||
|
written = int(writtenOut)
|
||||||
|
|
||||||
|
if e1 != 0 {
|
||||||
|
err = e1
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)
|
61
vendor/golang.org/x/sys/unix/syscall_freebsd_arm.go
generated
vendored
Normal file
61
vendor/golang.org/x/sys/unix/syscall_freebsd_arm.go
generated
vendored
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
// Copyright 2012 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build arm,freebsd
|
||||||
|
|
||||||
|
package unix
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
"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 NsecToTimeval(nsec int64) (tv Timeval) {
|
||||||
|
nsec += 999 // round up to microsecond
|
||||||
|
tv.Usec = int32(nsec % 1e9 / 1e3)
|
||||||
|
tv.Sec = nsec / 1e9
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetKevent(k *Kevent_t, fd, mode, flags int) {
|
||||||
|
k.Ident = uint32(fd)
|
||||||
|
k.Filter = int16(mode)
|
||||||
|
k.Flags = uint16(flags)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (iov *Iovec) SetLen(length int) {
|
||||||
|
iov.Len = uint32(length)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (msghdr *Msghdr) SetControllen(length int) {
|
||||||
|
msghdr.Controllen = uint32(length)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmsg *Cmsghdr) SetLen(length int) {
|
||||||
|
cmsg.Len = uint32(length)
|
||||||
|
}
|
||||||
|
|
||||||
|
func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
|
||||||
|
var writtenOut uint64 = 0
|
||||||
|
_, _, e1 := Syscall9(SYS_SENDFILE, uintptr(infd), uintptr(outfd), uintptr(*offset), uintptr((*offset)>>32), uintptr(count), 0, uintptr(unsafe.Pointer(&writtenOut)), 0, 0)
|
||||||
|
|
||||||
|
written = int(writtenOut)
|
||||||
|
|
||||||
|
if e1 != 0 {
|
||||||
|
err = e1
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)
|
1152
vendor/golang.org/x/sys/unix/syscall_linux.go
generated
vendored
Normal file
1152
vendor/golang.org/x/sys/unix/syscall_linux.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
399
vendor/golang.org/x/sys/unix/syscall_linux_386.go
generated
vendored
Normal file
399
vendor/golang.org/x/sys/unix/syscall_linux_386.go
generated
vendored
Normal file
|
@ -0,0 +1,399 @@
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
// TODO(rsc): Rewrite all nn(SP) references into name+(nn-8)(FP)
|
||||||
|
// so that go vet can check that they are correct.
|
||||||
|
|
||||||
|
// +build 386,linux
|
||||||
|
|
||||||
|
package unix
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Getpagesize() int { return 4096 }
|
||||||
|
|
||||||
|
func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
|
||||||
|
|
||||||
|
func NsecToTimespec(nsec int64) (ts Timespec) {
|
||||||
|
ts.Sec = int32(nsec / 1e9)
|
||||||
|
ts.Nsec = int32(nsec % 1e9)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func NsecToTimeval(nsec int64) (tv Timeval) {
|
||||||
|
nsec += 999 // round up to microsecond
|
||||||
|
tv.Sec = int32(nsec / 1e9)
|
||||||
|
tv.Usec = int32(nsec % 1e9 / 1e3)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//sysnb pipe(p *[2]_C_int) (err error)
|
||||||
|
|
||||||
|
func Pipe(p []int) (err error) {
|
||||||
|
if len(p) != 2 {
|
||||||
|
return EINVAL
|
||||||
|
}
|
||||||
|
var pp [2]_C_int
|
||||||
|
err = pipe(&pp)
|
||||||
|
p[0] = int(pp[0])
|
||||||
|
p[1] = int(pp[1])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//sysnb pipe2(p *[2]_C_int, flags int) (err error)
|
||||||
|
|
||||||
|
func Pipe2(p []int, flags int) (err error) {
|
||||||
|
if len(p) != 2 {
|
||||||
|
return EINVAL
|
||||||
|
}
|
||||||
|
var pp [2]_C_int
|
||||||
|
err = pipe2(&pp, flags)
|
||||||
|
p[0] = int(pp[0])
|
||||||
|
p[1] = int(pp[1])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 64-bit file system and 32-bit uid calls
|
||||||
|
// (386 default is 32-bit file system and 16-bit uid).
|
||||||
|
//sys Dup2(oldfd int, newfd 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 Ftruncate(fd int, length int64) (err error) = SYS_FTRUNCATE64
|
||||||
|
//sysnb Getegid() (egid int) = SYS_GETEGID32
|
||||||
|
//sysnb Geteuid() (euid int) = SYS_GETEUID32
|
||||||
|
//sysnb Getgid() (gid int) = SYS_GETGID32
|
||||||
|
//sysnb Getuid() (uid int) = SYS_GETUID32
|
||||||
|
//sysnb InotifyInit() (fd int, err error)
|
||||||
|
//sys Ioperm(from int, num int, on int) (err error)
|
||||||
|
//sys Iopl(level int) (err error)
|
||||||
|
//sys Lchown(path string, uid int, gid int) (err error) = SYS_LCHOWN32
|
||||||
|
//sys Lstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64
|
||||||
|
//sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
|
||||||
|
//sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
|
||||||
|
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = SYS_SENDFILE64
|
||||||
|
//sys Setfsgid(gid int) (err error) = SYS_SETFSGID32
|
||||||
|
//sys Setfsuid(uid int) (err error) = SYS_SETFSUID32
|
||||||
|
//sysnb Setregid(rgid int, egid int) (err error) = SYS_SETREGID32
|
||||||
|
//sysnb Setresgid(rgid int, egid int, sgid int) (err error) = SYS_SETRESGID32
|
||||||
|
//sysnb Setresuid(ruid int, euid int, suid int) (err error) = SYS_SETRESUID32
|
||||||
|
//sysnb Setreuid(ruid int, euid int) (err error) = SYS_SETREUID32
|
||||||
|
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error)
|
||||||
|
//sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64
|
||||||
|
//sys SyncFileRange(fd int, off int64, n int64, flags int) (err error)
|
||||||
|
//sys Truncate(path string, length int64) (err error) = SYS_TRUNCATE64
|
||||||
|
//sysnb getgroups(n int, list *_Gid_t) (nn int, err error) = SYS_GETGROUPS32
|
||||||
|
//sysnb setgroups(n int, list *_Gid_t) (err error) = SYS_SETGROUPS32
|
||||||
|
//sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) = SYS__NEWSELECT
|
||||||
|
|
||||||
|
//sys mmap2(addr uintptr, length uintptr, prot int, flags int, fd int, pageOffset uintptr) (xaddr uintptr, err error)
|
||||||
|
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
|
||||||
|
//sys Pause() (err error)
|
||||||
|
|
||||||
|
func mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) {
|
||||||
|
page := uintptr(offset / 4096)
|
||||||
|
if offset != int64(page)*4096 {
|
||||||
|
return 0, EINVAL
|
||||||
|
}
|
||||||
|
return mmap2(addr, length, prot, flags, fd, page)
|
||||||
|
}
|
||||||
|
|
||||||
|
type rlimit32 struct {
|
||||||
|
Cur uint32
|
||||||
|
Max uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
//sysnb getrlimit(resource int, rlim *rlimit32) (err error) = SYS_GETRLIMIT
|
||||||
|
|
||||||
|
const rlimInf32 = ^uint32(0)
|
||||||
|
const rlimInf64 = ^uint64(0)
|
||||||
|
|
||||||
|
func Getrlimit(resource int, rlim *Rlimit) (err error) {
|
||||||
|
err = prlimit(0, resource, nil, rlim)
|
||||||
|
if err != ENOSYS {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
rl := rlimit32{}
|
||||||
|
err = getrlimit(resource, &rl)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if rl.Cur == rlimInf32 {
|
||||||
|
rlim.Cur = rlimInf64
|
||||||
|
} else {
|
||||||
|
rlim.Cur = uint64(rl.Cur)
|
||||||
|
}
|
||||||
|
|
||||||
|
if rl.Max == rlimInf32 {
|
||||||
|
rlim.Max = rlimInf64
|
||||||
|
} else {
|
||||||
|
rlim.Max = uint64(rl.Max)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//sysnb setrlimit(resource int, rlim *rlimit32) (err error) = SYS_SETRLIMIT
|
||||||
|
|
||||||
|
func Setrlimit(resource int, rlim *Rlimit) (err error) {
|
||||||
|
err = prlimit(0, resource, rlim, nil)
|
||||||
|
if err != ENOSYS {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
rl := rlimit32{}
|
||||||
|
if rlim.Cur == rlimInf64 {
|
||||||
|
rl.Cur = rlimInf32
|
||||||
|
} else if rlim.Cur < uint64(rlimInf32) {
|
||||||
|
rl.Cur = uint32(rlim.Cur)
|
||||||
|
} else {
|
||||||
|
return EINVAL
|
||||||
|
}
|
||||||
|
if rlim.Max == rlimInf64 {
|
||||||
|
rl.Max = rlimInf32
|
||||||
|
} else if rlim.Max < uint64(rlimInf32) {
|
||||||
|
rl.Max = uint32(rlim.Max)
|
||||||
|
} else {
|
||||||
|
return EINVAL
|
||||||
|
}
|
||||||
|
|
||||||
|
return setrlimit(resource, &rl)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Underlying system call writes to newoffset via pointer.
|
||||||
|
// Implemented in assembly to avoid allocation.
|
||||||
|
func seek(fd int, offset int64, whence int) (newoffset int64, err syscall.Errno)
|
||||||
|
|
||||||
|
func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
|
||||||
|
newoffset, errno := seek(fd, offset, whence)
|
||||||
|
if errno != 0 {
|
||||||
|
return 0, errno
|
||||||
|
}
|
||||||
|
return newoffset, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Vsyscalls on amd64.
|
||||||
|
//sysnb Gettimeofday(tv *Timeval) (err error)
|
||||||
|
//sysnb Time(t *Time_t) (tt Time_t, err error)
|
||||||
|
|
||||||
|
//sys Utime(path string, buf *Utimbuf) (err error)
|
||||||
|
|
||||||
|
// On x86 Linux, all the socket calls go through an extra indirection,
|
||||||
|
// I think because the 5-register system call interface can't handle
|
||||||
|
// 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
|
||||||
|
// socketcall assembly to avoid allocation on every system call.
|
||||||
|
|
||||||
|
const (
|
||||||
|
// see linux/net.h
|
||||||
|
_SOCKET = 1
|
||||||
|
_BIND = 2
|
||||||
|
_CONNECT = 3
|
||||||
|
_LISTEN = 4
|
||||||
|
_ACCEPT = 5
|
||||||
|
_GETSOCKNAME = 6
|
||||||
|
_GETPEERNAME = 7
|
||||||
|
_SOCKETPAIR = 8
|
||||||
|
_SEND = 9
|
||||||
|
_RECV = 10
|
||||||
|
_SENDTO = 11
|
||||||
|
_RECVFROM = 12
|
||||||
|
_SHUTDOWN = 13
|
||||||
|
_SETSOCKOPT = 14
|
||||||
|
_GETSOCKOPT = 15
|
||||||
|
_SENDMSG = 16
|
||||||
|
_RECVMSG = 17
|
||||||
|
_ACCEPT4 = 18
|
||||||
|
_RECVMMSG = 19
|
||||||
|
_SENDMMSG = 20
|
||||||
|
)
|
||||||
|
|
||||||
|
func socketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (n int, err syscall.Errno)
|
||||||
|
func rawsocketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (n int, err syscall.Errno)
|
||||||
|
|
||||||
|
func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
|
||||||
|
fd, e := socketcall(_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0)
|
||||||
|
if e != 0 {
|
||||||
|
err = e
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) {
|
||||||
|
fd, e := socketcall(_ACCEPT4, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0)
|
||||||
|
if e != 0 {
|
||||||
|
err = e
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func getsockname(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
|
||||||
|
_, e := rawsocketcall(_GETSOCKNAME, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0)
|
||||||
|
if e != 0 {
|
||||||
|
err = e
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func getpeername(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
|
||||||
|
_, e := rawsocketcall(_GETPEERNAME, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0)
|
||||||
|
if e != 0 {
|
||||||
|
err = e
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func socketpair(domain int, typ int, flags int, fd *[2]int32) (err error) {
|
||||||
|
_, e := rawsocketcall(_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(flags), uintptr(unsafe.Pointer(fd)), 0, 0)
|
||||||
|
if e != 0 {
|
||||||
|
err = e
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
|
||||||
|
_, e := socketcall(_BIND, uintptr(s), uintptr(addr), uintptr(addrlen), 0, 0, 0)
|
||||||
|
if e != 0 {
|
||||||
|
err = e
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
|
||||||
|
_, e := socketcall(_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen), 0, 0, 0)
|
||||||
|
if e != 0 {
|
||||||
|
err = e
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func socket(domain int, typ int, proto int) (fd int, err error) {
|
||||||
|
fd, e := rawsocketcall(_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto), 0, 0, 0)
|
||||||
|
if e != 0 {
|
||||||
|
err = e
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
|
||||||
|
_, e := socketcall(_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
|
||||||
|
if e != 0 {
|
||||||
|
err = e
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
|
||||||
|
_, e := socketcall(_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), vallen, 0)
|
||||||
|
if e != 0 {
|
||||||
|
err = e
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func recvfrom(s int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) {
|
||||||
|
var base uintptr
|
||||||
|
if len(p) > 0 {
|
||||||
|
base = uintptr(unsafe.Pointer(&p[0]))
|
||||||
|
}
|
||||||
|
n, e := socketcall(_RECVFROM, uintptr(s), base, uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
|
||||||
|
if e != 0 {
|
||||||
|
err = e
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func sendto(s int, p []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) {
|
||||||
|
var base uintptr
|
||||||
|
if len(p) > 0 {
|
||||||
|
base = uintptr(unsafe.Pointer(&p[0]))
|
||||||
|
}
|
||||||
|
_, e := socketcall(_SENDTO, uintptr(s), base, uintptr(len(p)), uintptr(flags), uintptr(to), uintptr(addrlen))
|
||||||
|
if e != 0 {
|
||||||
|
err = e
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
|
||||||
|
n, e := socketcall(_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags), 0, 0, 0)
|
||||||
|
if e != 0 {
|
||||||
|
err = e
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
|
||||||
|
n, e := socketcall(_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags), 0, 0, 0)
|
||||||
|
if e != 0 {
|
||||||
|
err = e
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func Listen(s int, n int) (err error) {
|
||||||
|
_, e := socketcall(_LISTEN, uintptr(s), uintptr(n), 0, 0, 0, 0)
|
||||||
|
if e != 0 {
|
||||||
|
err = e
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func Shutdown(s, how int) (err error) {
|
||||||
|
_, e := socketcall(_SHUTDOWN, uintptr(s), uintptr(how), 0, 0, 0, 0)
|
||||||
|
if e != 0 {
|
||||||
|
err = e
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func Fstatfs(fd int, buf *Statfs_t) (err error) {
|
||||||
|
_, _, e := Syscall(SYS_FSTATFS64, uintptr(fd), unsafe.Sizeof(*buf), uintptr(unsafe.Pointer(buf)))
|
||||||
|
if e != 0 {
|
||||||
|
err = e
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func Statfs(path string, buf *Statfs_t) (err error) {
|
||||||
|
pathp, err := BytePtrFromString(path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, _, e := Syscall(SYS_STATFS64, uintptr(unsafe.Pointer(pathp)), unsafe.Sizeof(*buf), uintptr(unsafe.Pointer(buf)))
|
||||||
|
if e != 0 {
|
||||||
|
err = e
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *PtraceRegs) PC() uint64 { return uint64(uint32(r.Eip)) }
|
||||||
|
|
||||||
|
func (r *PtraceRegs) SetPC(pc uint64) { r.Eip = int32(pc) }
|
||||||
|
|
||||||
|
func (iov *Iovec) SetLen(length int) {
|
||||||
|
iov.Len = uint32(length)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (msghdr *Msghdr) SetControllen(length int) {
|
||||||
|
msghdr.Controllen = uint32(length)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmsg *Cmsghdr) SetLen(length int) {
|
||||||
|
cmsg.Len = uint32(length)
|
||||||
|
}
|
||||||
|
|
||||||
|
//sys poll(fds *PollFd, nfds int, timeout int) (n int, err error)
|
||||||
|
|
||||||
|
func Poll(fds []PollFd, timeout int) (n int, err error) {
|
||||||
|
if len(fds) == 0 {
|
||||||
|
return poll(nil, 0, timeout)
|
||||||
|
}
|
||||||
|
return poll(&fds[0], len(fds), timeout)
|
||||||
|
}
|
152
vendor/golang.org/x/sys/unix/syscall_linux_amd64.go
generated
vendored
Normal file
152
vendor/golang.org/x/sys/unix/syscall_linux_amd64.go
generated
vendored
Normal file
|
@ -0,0 +1,152 @@
|
||||||
|
// 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 amd64,linux
|
||||||
|
|
||||||
|
package unix
|
||||||
|
|
||||||
|
//sys Dup2(oldfd int, newfd int) (err error)
|
||||||
|
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
|
||||||
|
//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64
|
||||||
|
//sys Fchown(fd int, uid int, gid int) (err error)
|
||||||
|
//sys Fstat(fd int, stat *Stat_t) (err error)
|
||||||
|
//sys Fstatfs(fd int, buf *Statfs_t) (err error)
|
||||||
|
//sys Ftruncate(fd int, length int64) (err error)
|
||||||
|
//sysnb Getegid() (egid int)
|
||||||
|
//sysnb Geteuid() (euid int)
|
||||||
|
//sysnb Getgid() (gid int)
|
||||||
|
//sysnb Getrlimit(resource int, rlim *Rlimit) (err error)
|
||||||
|
//sysnb Getuid() (uid int)
|
||||||
|
//sysnb InotifyInit() (fd int, err error)
|
||||||
|
//sys Ioperm(from int, num int, on int) (err error)
|
||||||
|
//sys Iopl(level int) (err error)
|
||||||
|
//sys Lchown(path string, uid int, gid int) (err error)
|
||||||
|
//sys Listen(s int, n int) (err error)
|
||||||
|
//sys Lstat(path string, stat *Stat_t) (err error)
|
||||||
|
//sys Pause() (err error)
|
||||||
|
//sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
|
||||||
|
//sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
|
||||||
|
//sys Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK
|
||||||
|
//sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error)
|
||||||
|
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
|
||||||
|
//sys Setfsgid(gid int) (err error)
|
||||||
|
//sys Setfsuid(uid int) (err error)
|
||||||
|
//sysnb Setregid(rgid int, egid int) (err error)
|
||||||
|
//sysnb Setresgid(rgid int, egid int, sgid int) (err error)
|
||||||
|
//sysnb Setresuid(ruid int, euid int, suid int) (err error)
|
||||||
|
//sysnb Setrlimit(resource int, rlim *Rlimit) (err error)
|
||||||
|
//sysnb Setreuid(ruid int, euid int) (err error)
|
||||||
|
//sys Shutdown(fd int, how int) (err error)
|
||||||
|
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
|
||||||
|
//sys Stat(path string, stat *Stat_t) (err error)
|
||||||
|
//sys Statfs(path string, buf *Statfs_t) (err error)
|
||||||
|
//sys SyncFileRange(fd int, off int64, n int64, flags int) (err error)
|
||||||
|
//sys Truncate(path string, length int64) (err error)
|
||||||
|
//sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error)
|
||||||
|
//sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error)
|
||||||
|
//sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
|
||||||
|
//sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
|
||||||
|
//sysnb getgroups(n int, list *_Gid_t) (nn int, err error)
|
||||||
|
//sysnb setgroups(n int, list *_Gid_t) (err error)
|
||||||
|
//sys getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error)
|
||||||
|
//sys setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error)
|
||||||
|
//sysnb socket(domain int, typ int, proto int) (fd int, err error)
|
||||||
|
//sysnb socketpair(domain int, typ int, proto int, fd *[2]int32) (err error)
|
||||||
|
//sysnb getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)
|
||||||
|
//sysnb getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)
|
||||||
|
//sys recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error)
|
||||||
|
//sys sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error)
|
||||||
|
//sys recvmsg(s int, msg *Msghdr, flags int) (n int, err error)
|
||||||
|
//sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error)
|
||||||
|
//sys mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error)
|
||||||
|
|
||||||
|
func Gettimeofday(tv *Timeval) (err error) {
|
||||||
|
errno := gettimeofday(tv)
|
||||||
|
if errno != 0 {
|
||||||
|
return errno
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func Getpagesize() int { return 4096 }
|
||||||
|
|
||||||
|
func Time(t *Time_t) (tt Time_t, err error) {
|
||||||
|
var tv Timeval
|
||||||
|
errno := gettimeofday(&tv)
|
||||||
|
if errno != 0 {
|
||||||
|
return 0, errno
|
||||||
|
}
|
||||||
|
if t != nil {
|
||||||
|
*t = Time_t(tv.Sec)
|
||||||
|
}
|
||||||
|
return Time_t(tv.Sec), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//sys Utime(path string, buf *Utimbuf) (err error)
|
||||||
|
|
||||||
|
func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
|
||||||
|
|
||||||
|
func NsecToTimespec(nsec int64) (ts Timespec) {
|
||||||
|
ts.Sec = nsec / 1e9
|
||||||
|
ts.Nsec = nsec % 1e9
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func NsecToTimeval(nsec int64) (tv Timeval) {
|
||||||
|
nsec += 999 // round up to microsecond
|
||||||
|
tv.Sec = nsec / 1e9
|
||||||
|
tv.Usec = nsec % 1e9 / 1e3
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//sysnb pipe(p *[2]_C_int) (err error)
|
||||||
|
|
||||||
|
func Pipe(p []int) (err error) {
|
||||||
|
if len(p) != 2 {
|
||||||
|
return EINVAL
|
||||||
|
}
|
||||||
|
var pp [2]_C_int
|
||||||
|
err = pipe(&pp)
|
||||||
|
p[0] = int(pp[0])
|
||||||
|
p[1] = int(pp[1])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//sysnb pipe2(p *[2]_C_int, flags int) (err error)
|
||||||
|
|
||||||
|
func Pipe2(p []int, flags int) (err error) {
|
||||||
|
if len(p) != 2 {
|
||||||
|
return EINVAL
|
||||||
|
}
|
||||||
|
var pp [2]_C_int
|
||||||
|
err = pipe2(&pp, flags)
|
||||||
|
p[0] = int(pp[0])
|
||||||
|
p[1] = int(pp[1])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *PtraceRegs) PC() uint64 { return r.Rip }
|
||||||
|
|
||||||
|
func (r *PtraceRegs) SetPC(pc uint64) { r.Rip = pc }
|
||||||
|
|
||||||
|
func (iov *Iovec) SetLen(length int) {
|
||||||
|
iov.Len = uint64(length)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (msghdr *Msghdr) SetControllen(length int) {
|
||||||
|
msghdr.Controllen = uint64(length)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmsg *Cmsghdr) SetLen(length int) {
|
||||||
|
cmsg.Len = uint64(length)
|
||||||
|
}
|
||||||
|
|
||||||
|
//sys poll(fds *PollFd, nfds int, timeout int) (n int, err error)
|
||||||
|
|
||||||
|
func Poll(fds []PollFd, timeout int) (n int, err error) {
|
||||||
|
if len(fds) == 0 {
|
||||||
|
return poll(nil, 0, timeout)
|
||||||
|
}
|
||||||
|
return poll(&fds[0], len(fds), timeout)
|
||||||
|
}
|
13
vendor/golang.org/x/sys/unix/syscall_linux_amd64_gc.go
generated
vendored
Normal file
13
vendor/golang.org/x/sys/unix/syscall_linux_amd64_gc.go
generated
vendored
Normal 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)
|
263
vendor/golang.org/x/sys/unix/syscall_linux_arm.go
generated
vendored
Normal file
263
vendor/golang.org/x/sys/unix/syscall_linux_arm.go
generated
vendored
Normal file
|
@ -0,0 +1,263 @@
|
||||||
|
// 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 arm,linux
|
||||||
|
|
||||||
|
package unix
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Getpagesize() int { return 4096 }
|
||||||
|
|
||||||
|
func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
|
||||||
|
|
||||||
|
func NsecToTimespec(nsec int64) (ts Timespec) {
|
||||||
|
ts.Sec = int32(nsec / 1e9)
|
||||||
|
ts.Nsec = int32(nsec % 1e9)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func NsecToTimeval(nsec int64) (tv Timeval) {
|
||||||
|
nsec += 999 // round up to microsecond
|
||||||
|
tv.Sec = int32(nsec / 1e9)
|
||||||
|
tv.Usec = int32(nsec % 1e9 / 1e3)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func Pipe(p []int) (err error) {
|
||||||
|
if len(p) != 2 {
|
||||||
|
return EINVAL
|
||||||
|
}
|
||||||
|
var pp [2]_C_int
|
||||||
|
err = pipe2(&pp, 0)
|
||||||
|
p[0] = int(pp[0])
|
||||||
|
p[1] = int(pp[1])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//sysnb pipe2(p *[2]_C_int, flags int) (err error)
|
||||||
|
|
||||||
|
func Pipe2(p []int, flags int) (err error) {
|
||||||
|
if len(p) != 2 {
|
||||||
|
return EINVAL
|
||||||
|
}
|
||||||
|
var pp [2]_C_int
|
||||||
|
err = pipe2(&pp, flags)
|
||||||
|
p[0] = int(pp[0])
|
||||||
|
p[1] = int(pp[1])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Underlying system call writes to newoffset via pointer.
|
||||||
|
// Implemented in assembly to avoid allocation.
|
||||||
|
func seek(fd int, offset int64, whence int) (newoffset int64, err syscall.Errno)
|
||||||
|
|
||||||
|
func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
|
||||||
|
newoffset, errno := seek(fd, offset, whence)
|
||||||
|
if errno != 0 {
|
||||||
|
return 0, errno
|
||||||
|
}
|
||||||
|
return newoffset, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error)
|
||||||
|
//sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error)
|
||||||
|
//sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
|
||||||
|
//sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
|
||||||
|
//sysnb getgroups(n int, list *_Gid_t) (nn int, err error) = SYS_GETGROUPS32
|
||||||
|
//sysnb setgroups(n int, list *_Gid_t) (err error) = SYS_SETGROUPS32
|
||||||
|
//sys getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error)
|
||||||
|
//sys setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error)
|
||||||
|
//sysnb socket(domain int, typ int, proto int) (fd int, err error)
|
||||||
|
//sysnb getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)
|
||||||
|
//sysnb getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)
|
||||||
|
//sys recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error)
|
||||||
|
//sys sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error)
|
||||||
|
//sysnb socketpair(domain int, typ int, flags int, fd *[2]int32) (err error)
|
||||||
|
//sys recvmsg(s int, msg *Msghdr, flags int) (n int, err error)
|
||||||
|
//sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error)
|
||||||
|
|
||||||
|
// 64-bit file system and 32-bit uid calls
|
||||||
|
// (16-bit uid calls are not always supported in newer kernels)
|
||||||
|
//sys Dup2(oldfd int, newfd int) (err error)
|
||||||
|
//sys Fchown(fd int, uid int, gid int) (err error) = SYS_FCHOWN32
|
||||||
|
//sys Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64
|
||||||
|
//sysnb Getegid() (egid int) = SYS_GETEGID32
|
||||||
|
//sysnb Geteuid() (euid int) = SYS_GETEUID32
|
||||||
|
//sysnb Getgid() (gid int) = SYS_GETGID32
|
||||||
|
//sysnb Getuid() (uid int) = SYS_GETUID32
|
||||||
|
//sysnb InotifyInit() (fd int, err error)
|
||||||
|
//sys Lchown(path string, uid int, gid int) (err error) = SYS_LCHOWN32
|
||||||
|
//sys Listen(s int, n int) (err error)
|
||||||
|
//sys Lstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64
|
||||||
|
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = SYS_SENDFILE64
|
||||||
|
//sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) = SYS__NEWSELECT
|
||||||
|
//sys Setfsgid(gid int) (err error) = SYS_SETFSGID32
|
||||||
|
//sys Setfsuid(uid int) (err error) = SYS_SETFSUID32
|
||||||
|
//sysnb Setregid(rgid int, egid int) (err error) = SYS_SETREGID32
|
||||||
|
//sysnb Setresgid(rgid int, egid int, sgid int) (err error) = SYS_SETRESGID32
|
||||||
|
//sysnb Setresuid(ruid int, euid int, suid int) (err error) = SYS_SETRESUID32
|
||||||
|
//sysnb Setreuid(ruid int, euid int) (err error) = SYS_SETREUID32
|
||||||
|
//sys Shutdown(fd int, how int) (err error)
|
||||||
|
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error)
|
||||||
|
//sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64
|
||||||
|
|
||||||
|
// Vsyscalls on amd64.
|
||||||
|
//sysnb Gettimeofday(tv *Timeval) (err error)
|
||||||
|
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
|
||||||
|
//sys Pause() (err error)
|
||||||
|
|
||||||
|
func Time(t *Time_t) (Time_t, error) {
|
||||||
|
var tv Timeval
|
||||||
|
err := Gettimeofday(&tv)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
if t != nil {
|
||||||
|
*t = Time_t(tv.Sec)
|
||||||
|
}
|
||||||
|
return Time_t(tv.Sec), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func Utime(path string, buf *Utimbuf) error {
|
||||||
|
tv := []Timeval{
|
||||||
|
{Sec: buf.Actime},
|
||||||
|
{Sec: buf.Modtime},
|
||||||
|
}
|
||||||
|
return Utimes(path, tv)
|
||||||
|
}
|
||||||
|
|
||||||
|
//sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
|
||||||
|
//sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
|
||||||
|
//sys Truncate(path string, length int64) (err error) = SYS_TRUNCATE64
|
||||||
|
//sys Ftruncate(fd int, length int64) (err error) = SYS_FTRUNCATE64
|
||||||
|
|
||||||
|
func Fadvise(fd int, offset int64, length int64, advice int) (err error) {
|
||||||
|
_, _, e1 := Syscall6(SYS_ARM_FADVISE64_64, uintptr(fd), uintptr(advice), uintptr(offset), uintptr(offset>>32), uintptr(length), uintptr(length>>32))
|
||||||
|
if e1 != 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//sys mmap2(addr uintptr, length uintptr, prot int, flags int, fd int, pageOffset uintptr) (xaddr uintptr, err error)
|
||||||
|
|
||||||
|
func Fstatfs(fd int, buf *Statfs_t) (err error) {
|
||||||
|
_, _, e := Syscall(SYS_FSTATFS64, uintptr(fd), unsafe.Sizeof(*buf), uintptr(unsafe.Pointer(buf)))
|
||||||
|
if e != 0 {
|
||||||
|
err = e
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func Statfs(path string, buf *Statfs_t) (err error) {
|
||||||
|
pathp, err := BytePtrFromString(path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, _, e := Syscall(SYS_STATFS64, uintptr(unsafe.Pointer(pathp)), unsafe.Sizeof(*buf), uintptr(unsafe.Pointer(buf)))
|
||||||
|
if e != 0 {
|
||||||
|
err = e
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) {
|
||||||
|
page := uintptr(offset / 4096)
|
||||||
|
if offset != int64(page)*4096 {
|
||||||
|
return 0, EINVAL
|
||||||
|
}
|
||||||
|
return mmap2(addr, length, prot, flags, fd, page)
|
||||||
|
}
|
||||||
|
|
||||||
|
type rlimit32 struct {
|
||||||
|
Cur uint32
|
||||||
|
Max uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
//sysnb getrlimit(resource int, rlim *rlimit32) (err error) = SYS_UGETRLIMIT
|
||||||
|
|
||||||
|
const rlimInf32 = ^uint32(0)
|
||||||
|
const rlimInf64 = ^uint64(0)
|
||||||
|
|
||||||
|
func Getrlimit(resource int, rlim *Rlimit) (err error) {
|
||||||
|
err = prlimit(0, resource, nil, rlim)
|
||||||
|
if err != ENOSYS {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
rl := rlimit32{}
|
||||||
|
err = getrlimit(resource, &rl)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if rl.Cur == rlimInf32 {
|
||||||
|
rlim.Cur = rlimInf64
|
||||||
|
} else {
|
||||||
|
rlim.Cur = uint64(rl.Cur)
|
||||||
|
}
|
||||||
|
|
||||||
|
if rl.Max == rlimInf32 {
|
||||||
|
rlim.Max = rlimInf64
|
||||||
|
} else {
|
||||||
|
rlim.Max = uint64(rl.Max)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//sysnb setrlimit(resource int, rlim *rlimit32) (err error) = SYS_SETRLIMIT
|
||||||
|
|
||||||
|
func Setrlimit(resource int, rlim *Rlimit) (err error) {
|
||||||
|
err = prlimit(0, resource, rlim, nil)
|
||||||
|
if err != ENOSYS {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
rl := rlimit32{}
|
||||||
|
if rlim.Cur == rlimInf64 {
|
||||||
|
rl.Cur = rlimInf32
|
||||||
|
} else if rlim.Cur < uint64(rlimInf32) {
|
||||||
|
rl.Cur = uint32(rlim.Cur)
|
||||||
|
} else {
|
||||||
|
return EINVAL
|
||||||
|
}
|
||||||
|
if rlim.Max == rlimInf64 {
|
||||||
|
rl.Max = rlimInf32
|
||||||
|
} else if rlim.Max < uint64(rlimInf32) {
|
||||||
|
rl.Max = uint32(rlim.Max)
|
||||||
|
} else {
|
||||||
|
return EINVAL
|
||||||
|
}
|
||||||
|
|
||||||
|
return setrlimit(resource, &rl)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *PtraceRegs) PC() uint64 { return uint64(r.Uregs[15]) }
|
||||||
|
|
||||||
|
func (r *PtraceRegs) SetPC(pc uint64) { r.Uregs[15] = uint32(pc) }
|
||||||
|
|
||||||
|
func (iov *Iovec) SetLen(length int) {
|
||||||
|
iov.Len = uint32(length)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (msghdr *Msghdr) SetControllen(length int) {
|
||||||
|
msghdr.Controllen = uint32(length)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmsg *Cmsghdr) SetLen(length int) {
|
||||||
|
cmsg.Len = uint32(length)
|
||||||
|
}
|
||||||
|
|
||||||
|
//sys poll(fds *PollFd, nfds int, timeout int) (n int, err error)
|
||||||
|
|
||||||
|
func Poll(fds []PollFd, timeout int) (n int, err error) {
|
||||||
|
if len(fds) == 0 {
|
||||||
|
return poll(nil, 0, timeout)
|
||||||
|
}
|
||||||
|
return poll(&fds[0], len(fds), timeout)
|
||||||
|
}
|
190
vendor/golang.org/x/sys/unix/syscall_linux_arm64.go
generated
vendored
Normal file
190
vendor/golang.org/x/sys/unix/syscall_linux_arm64.go
generated
vendored
Normal file
|
@ -0,0 +1,190 @@
|
||||||
|
// 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 arm64,linux
|
||||||
|
|
||||||
|
package unix
|
||||||
|
|
||||||
|
//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) = SYS_EPOLL_PWAIT
|
||||||
|
//sys Fchown(fd int, uid int, gid int) (err error)
|
||||||
|
//sys Fstat(fd int, stat *Stat_t) (err error)
|
||||||
|
//sys Fstatat(fd int, path string, stat *Stat_t, flags int) (err error)
|
||||||
|
//sys Fstatfs(fd int, buf *Statfs_t) (err error)
|
||||||
|
//sys Ftruncate(fd int, length int64) (err error)
|
||||||
|
//sysnb Getegid() (egid int)
|
||||||
|
//sysnb Geteuid() (euid int)
|
||||||
|
//sysnb Getgid() (gid int)
|
||||||
|
//sysnb Getrlimit(resource int, rlim *Rlimit) (err error)
|
||||||
|
//sysnb Getuid() (uid int)
|
||||||
|
//sys Listen(s int, n int) (err error)
|
||||||
|
//sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
|
||||||
|
//sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
|
||||||
|
//sys Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK
|
||||||
|
//sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) = SYS_PSELECT6
|
||||||
|
//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
|
||||||
|
//sys Setfsgid(gid int) (err error)
|
||||||
|
//sys Setfsuid(uid int) (err error)
|
||||||
|
//sysnb Setregid(rgid int, egid int) (err error)
|
||||||
|
//sysnb Setresgid(rgid int, egid int, sgid int) (err error)
|
||||||
|
//sysnb Setresuid(ruid int, euid int, suid int) (err error)
|
||||||
|
//sysnb Setrlimit(resource int, rlim *Rlimit) (err error)
|
||||||
|
//sysnb Setreuid(ruid int, euid int) (err error)
|
||||||
|
//sys Shutdown(fd int, how int) (err error)
|
||||||
|
//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
|
||||||
|
|
||||||
|
func Stat(path string, stat *Stat_t) (err error) {
|
||||||
|
return Fstatat(AT_FDCWD, path, stat, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Lchown(path string, uid int, gid int) (err error) {
|
||||||
|
return Fchownat(AT_FDCWD, path, uid, gid, AT_SYMLINK_NOFOLLOW)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Lstat(path string, stat *Stat_t) (err error) {
|
||||||
|
return Fstatat(AT_FDCWD, path, stat, AT_SYMLINK_NOFOLLOW)
|
||||||
|
}
|
||||||
|
|
||||||
|
//sys Statfs(path string, buf *Statfs_t) (err error)
|
||||||
|
//sys SyncFileRange(fd int, off int64, n int64, flags int) (err error)
|
||||||
|
//sys Truncate(path string, length int64) (err error)
|
||||||
|
//sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error)
|
||||||
|
//sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error)
|
||||||
|
//sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
|
||||||
|
//sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
|
||||||
|
//sysnb getgroups(n int, list *_Gid_t) (nn int, err error)
|
||||||
|
//sysnb setgroups(n int, list *_Gid_t) (err error)
|
||||||
|
//sys getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error)
|
||||||
|
//sys setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error)
|
||||||
|
//sysnb socket(domain int, typ int, proto int) (fd int, err error)
|
||||||
|
//sysnb socketpair(domain int, typ int, proto int, fd *[2]int32) (err error)
|
||||||
|
//sysnb getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)
|
||||||
|
//sysnb getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)
|
||||||
|
//sys recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error)
|
||||||
|
//sys sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error)
|
||||||
|
//sys recvmsg(s int, msg *Msghdr, flags int) (n int, err error)
|
||||||
|
//sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error)
|
||||||
|
//sys mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error)
|
||||||
|
|
||||||
|
func Getpagesize() int { return 65536 }
|
||||||
|
|
||||||
|
//sysnb Gettimeofday(tv *Timeval) (err error)
|
||||||
|
|
||||||
|
func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
|
||||||
|
|
||||||
|
func NsecToTimespec(nsec int64) (ts Timespec) {
|
||||||
|
ts.Sec = nsec / 1e9
|
||||||
|
ts.Nsec = nsec % 1e9
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func NsecToTimeval(nsec int64) (tv Timeval) {
|
||||||
|
nsec += 999 // round up to microsecond
|
||||||
|
tv.Sec = nsec / 1e9
|
||||||
|
tv.Usec = nsec % 1e9 / 1e3
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func Time(t *Time_t) (Time_t, error) {
|
||||||
|
var tv Timeval
|
||||||
|
err := Gettimeofday(&tv)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
if t != nil {
|
||||||
|
*t = Time_t(tv.Sec)
|
||||||
|
}
|
||||||
|
return Time_t(tv.Sec), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func Utime(path string, buf *Utimbuf) error {
|
||||||
|
tv := []Timeval{
|
||||||
|
{Sec: buf.Actime},
|
||||||
|
{Sec: buf.Modtime},
|
||||||
|
}
|
||||||
|
return Utimes(path, tv)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Pipe(p []int) (err error) {
|
||||||
|
if len(p) != 2 {
|
||||||
|
return EINVAL
|
||||||
|
}
|
||||||
|
var pp [2]_C_int
|
||||||
|
err = pipe2(&pp, 0)
|
||||||
|
p[0] = int(pp[0])
|
||||||
|
p[1] = int(pp[1])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//sysnb pipe2(p *[2]_C_int, flags int) (err error)
|
||||||
|
|
||||||
|
func Pipe2(p []int, flags int) (err error) {
|
||||||
|
if len(p) != 2 {
|
||||||
|
return EINVAL
|
||||||
|
}
|
||||||
|
var pp [2]_C_int
|
||||||
|
err = pipe2(&pp, flags)
|
||||||
|
p[0] = int(pp[0])
|
||||||
|
p[1] = int(pp[1])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *PtraceRegs) PC() uint64 { return r.Pc }
|
||||||
|
|
||||||
|
func (r *PtraceRegs) SetPC(pc uint64) { r.Pc = pc }
|
||||||
|
|
||||||
|
func (iov *Iovec) SetLen(length int) {
|
||||||
|
iov.Len = uint64(length)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (msghdr *Msghdr) SetControllen(length int) {
|
||||||
|
msghdr.Controllen = uint64(length)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmsg *Cmsghdr) SetLen(length int) {
|
||||||
|
cmsg.Len = uint64(length)
|
||||||
|
}
|
||||||
|
|
||||||
|
func InotifyInit() (fd int, err error) {
|
||||||
|
return InotifyInit1(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Dup2(oldfd int, newfd int) (err error) {
|
||||||
|
return Dup3(oldfd, newfd, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Pause() (err error) {
|
||||||
|
_, _, e1 := Syscall6(SYS_PPOLL, 0, 0, 0, 0, 0, 0)
|
||||||
|
if e1 != 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(dfc): constants that should be in zsysnum_linux_arm64.go, remove
|
||||||
|
// these when the deprecated syscalls that the syscall package relies on
|
||||||
|
// are removed.
|
||||||
|
const (
|
||||||
|
SYS_GETPGRP = 1060
|
||||||
|
SYS_UTIMES = 1037
|
||||||
|
SYS_FUTIMESAT = 1066
|
||||||
|
SYS_PAUSE = 1061
|
||||||
|
SYS_USTAT = 1070
|
||||||
|
SYS_UTIME = 1063
|
||||||
|
SYS_LCHOWN = 1032
|
||||||
|
SYS_TIME = 1062
|
||||||
|
SYS_EPOLL_CREATE = 1042
|
||||||
|
SYS_EPOLL_WAIT = 1069
|
||||||
|
)
|
||||||
|
|
||||||
|
func Poll(fds []PollFd, timeout int) (n int, err error) {
|
||||||
|
var ts *Timespec
|
||||||
|
if timeout >= 0 {
|
||||||
|
ts = new(Timespec)
|
||||||
|
*ts = NsecToTimespec(int64(timeout) * 1e6)
|
||||||
|
}
|
||||||
|
if len(fds) == 0 {
|
||||||
|
return ppoll(nil, 0, ts, nil)
|
||||||
|
}
|
||||||
|
return ppoll(&fds[0], len(fds), ts, nil)
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue