mirror of https://github.com/k3d-io/k3d
[FIX] tools: use api version negotation when creating the docker client (#679)
parent
9abcbedb37
commit
2faeda2117
@ -1,80 +0,0 @@ |
||||
package mg |
||||
|
||||
// Color is ANSI color type
|
||||
type Color int |
||||
|
||||
// If you add/change/remove any items in this constant,
|
||||
// you will need to run "stringer -type=Color" in this directory again.
|
||||
// NOTE: Please keep the list in an alphabetical order.
|
||||
const ( |
||||
Black Color = iota |
||||
Red |
||||
Green |
||||
Yellow |
||||
Blue |
||||
Magenta |
||||
Cyan |
||||
White |
||||
BrightBlack |
||||
BrightRed |
||||
BrightGreen |
||||
BrightYellow |
||||
BrightBlue |
||||
BrightMagenta |
||||
BrightCyan |
||||
BrightWhite |
||||
) |
||||
|
||||
// AnsiColor are ANSI color codes for supported terminal colors.
|
||||
var ansiColor = map[Color]string{ |
||||
Black: "\u001b[30m", |
||||
Red: "\u001b[31m", |
||||
Green: "\u001b[32m", |
||||
Yellow: "\u001b[33m", |
||||
Blue: "\u001b[34m", |
||||
Magenta: "\u001b[35m", |
||||
Cyan: "\u001b[36m", |
||||
White: "\u001b[37m", |
||||
BrightBlack: "\u001b[30;1m", |
||||
BrightRed: "\u001b[31;1m", |
||||
BrightGreen: "\u001b[32;1m", |
||||
BrightYellow: "\u001b[33;1m", |
||||
BrightBlue: "\u001b[34;1m", |
||||
BrightMagenta: "\u001b[35;1m", |
||||
BrightCyan: "\u001b[36;1m", |
||||
BrightWhite: "\u001b[37;1m", |
||||
} |
||||
|
||||
// AnsiColorReset is an ANSI color code to reset the terminal color.
|
||||
const AnsiColorReset = "\033[0m" |
||||
|
||||
// DefaultTargetAnsiColor is a default ANSI color for colorizing targets.
|
||||
// It is set to Cyan as an arbitrary color, because it has a neutral meaning
|
||||
var DefaultTargetAnsiColor = ansiColor[Cyan] |
||||
|
||||
func toLowerCase(s string) string { |
||||
// this is a naive implementation
|
||||
// borrowed from https://golang.org/src/strings/strings.go
|
||||
// and only considers alphabetical characters [a-zA-Z]
|
||||
// so that we don't depend on the "strings" package
|
||||
buf := make([]byte, len(s)) |
||||
for i := 0; i < len(s); i++ { |
||||
c := s[i] |
||||
if 'A' <= c && c <= 'Z' { |
||||
c += 'a' - 'A' |
||||
} |
||||
buf[i] = c |
||||
} |
||||
return string(buf) |
||||
} |
||||
|
||||
func getAnsiColor(color string) (string, bool) { |
||||
colorLower := toLowerCase(color) |
||||
for k, v := range ansiColor { |
||||
colorConstLower := toLowerCase(k.String()) |
||||
if colorConstLower == colorLower { |
||||
return v, true |
||||
} |
||||
} |
||||
return "", false |
||||
} |
@ -1,38 +0,0 @@ |
||||
// Code generated by "stringer -type=Color"; DO NOT EDIT.
|
||||
|
||||
package mg |
||||
|
||||
import "strconv" |
||||
|
||||
func _() { |
||||
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||
// Re-run the stringer command to generate them again.
|
||||
var x [1]struct{} |
||||
_ = x[Black-0] |
||||
_ = x[Red-1] |
||||
_ = x[Green-2] |
||||
_ = x[Yellow-3] |
||||
_ = x[Blue-4] |
||||
_ = x[Magenta-5] |
||||
_ = x[Cyan-6] |
||||
_ = x[White-7] |
||||
_ = x[BrightBlack-8] |
||||
_ = x[BrightRed-9] |
||||
_ = x[BrightGreen-10] |
||||
_ = x[BrightYellow-11] |
||||
_ = x[BrightBlue-12] |
||||
_ = x[BrightMagenta-13] |
||||
_ = x[BrightCyan-14] |
||||
_ = x[BrightWhite-15] |
||||
} |
||||
|
||||
const _Color_name = "BlackRedGreenYellowBlueMagentaCyanWhiteBrightBlackBrightRedBrightGreenBrightYellowBrightBlueBrightMagentaBrightCyanBrightWhite" |
||||
|
||||
var _Color_index = [...]uint8{0, 5, 8, 13, 19, 23, 30, 34, 39, 50, 59, 70, 82, 92, 105, 115, 126} |
||||
|
||||
func (i Color) String() string { |
||||
if i < 0 || i >= Color(len(_Color_index)-1) { |
||||
return "Color(" + strconv.FormatInt(int64(i), 10) + ")" |
||||
} |
||||
return _Color_name[_Color_index[i]:_Color_index[i+1]] |
||||
} |
@ -1,352 +0,0 @@ |
||||
package mg |
||||
|
||||
import ( |
||||
"context" |
||||
"fmt" |
||||
"log" |
||||
"os" |
||||
"reflect" |
||||
"runtime" |
||||
"strings" |
||||
"sync" |
||||
) |
||||
|
||||
// funcType indicates a prototype of build job function
|
||||
type funcType int |
||||
|
||||
// funcTypes
|
||||
const ( |
||||
invalidType funcType = iota |
||||
voidType |
||||
errorType |
||||
contextVoidType |
||||
contextErrorType |
||||
namespaceVoidType |
||||
namespaceErrorType |
||||
namespaceContextVoidType |
||||
namespaceContextErrorType |
||||
) |
||||
|
||||
var logger = log.New(os.Stderr, "", 0) |
||||
|
||||
type onceMap struct { |
||||
mu *sync.Mutex |
||||
m map[string]*onceFun |
||||
} |
||||
|
||||
func (o *onceMap) LoadOrStore(s string, one *onceFun) *onceFun { |
||||
defer o.mu.Unlock() |
||||
o.mu.Lock() |
||||
|
||||
existing, ok := o.m[s] |
||||
if ok { |
||||
return existing |
||||
} |
||||
o.m[s] = one |
||||
return one |
||||
} |
||||
|
||||
var onces = &onceMap{ |
||||
mu: &sync.Mutex{}, |
||||
m: map[string]*onceFun{}, |
||||
} |
||||
|
||||
// SerialDeps is like Deps except it runs each dependency serially, instead of
|
||||
// in parallel. This can be useful for resource intensive dependencies that
|
||||
// shouldn't be run at the same time.
|
||||
func SerialDeps(fns ...interface{}) { |
||||
types := checkFns(fns) |
||||
ctx := context.Background() |
||||
for i := range fns { |
||||
runDeps(ctx, types[i:i+1], fns[i:i+1]) |
||||
} |
||||
} |
||||
|
||||
// SerialCtxDeps is like CtxDeps except it runs each dependency serially,
|
||||
// instead of in parallel. This can be useful for resource intensive
|
||||
// dependencies that shouldn't be run at the same time.
|
||||
func SerialCtxDeps(ctx context.Context, fns ...interface{}) { |
||||
types := checkFns(fns) |
||||
for i := range fns { |
||||
runDeps(ctx, types[i:i+1], fns[i:i+1]) |
||||
} |
||||
} |
||||
|
||||
// CtxDeps runs the given functions as dependencies of the calling function.
|
||||
// Dependencies must only be of type:
|
||||
// func()
|
||||
// func() error
|
||||
// func(context.Context)
|
||||
// func(context.Context) error
|
||||
// Or a similar method on a mg.Namespace type.
|
||||
//
|
||||
// The function calling Deps is guaranteed that all dependent functions will be
|
||||
// run exactly once when Deps returns. Dependent functions may in turn declare
|
||||
// their own dependencies using Deps. Each dependency is run in their own
|
||||
// goroutines. Each function is given the context provided if the function
|
||||
// prototype allows for it.
|
||||
func CtxDeps(ctx context.Context, fns ...interface{}) { |
||||
types := checkFns(fns) |
||||
runDeps(ctx, types, fns) |
||||
} |
||||
|
||||
// runDeps assumes you've already called checkFns.
|
||||
func runDeps(ctx context.Context, types []funcType, fns []interface{}) { |
||||
mu := &sync.Mutex{} |
||||
var errs []string |
||||
var exit int |
||||
wg := &sync.WaitGroup{} |
||||
for i, f := range fns { |
||||
fn := addDep(ctx, types[i], f) |
||||
wg.Add(1) |
||||
go func() { |
||||
defer func() { |
||||
if v := recover(); v != nil { |
||||
mu.Lock() |
||||
if err, ok := v.(error); ok { |
||||
exit = changeExit(exit, ExitStatus(err)) |
||||
} else { |
||||
exit = changeExit(exit, 1) |
||||
} |
||||
errs = append(errs, fmt.Sprint(v)) |
||||
mu.Unlock() |
||||
} |
||||
wg.Done() |
||||
}() |
||||
if err := fn.run(); err != nil { |
||||
mu.Lock() |
||||
errs = append(errs, fmt.Sprint(err)) |
||||
exit = changeExit(exit, ExitStatus(err)) |
||||
mu.Unlock() |
||||
} |
||||
}() |
||||
} |
||||
|
||||
wg.Wait() |
||||
if len(errs) > 0 { |
||||
panic(Fatal(exit, strings.Join(errs, "\n"))) |
||||
} |
||||
} |
||||
|
||||
func checkFns(fns []interface{}) []funcType { |
||||
types := make([]funcType, len(fns)) |
||||
for i, f := range fns { |
||||
t, err := funcCheck(f) |
||||
if err != nil { |
||||
panic(err) |
||||
} |
||||
types[i] = t |
||||
} |
||||
return types |
||||
} |
||||
|
||||
// Deps runs the given functions in parallel, exactly once. Dependencies must
|
||||
// only be of type:
|
||||
// func()
|
||||
// func() error
|
||||
// func(context.Context)
|
||||
// func(context.Context) error
|
||||
// Or a similar method on a mg.Namespace type.
|
||||
//
|
||||
// This is a way to build up a tree of dependencies with each dependency
|
||||
// defining its own dependencies. Functions must have the same signature as a
|
||||
// Mage target, i.e. optional context argument, optional error return.
|
||||
func Deps(fns ...interface{}) { |
||||
CtxDeps(context.Background(), fns...) |
||||
} |
||||
|
||||
func changeExit(old, new int) int { |
||||
if new == 0 { |
||||
return old |
||||
} |
||||
if old == 0 { |
||||
return new |
||||
} |
||||
if old == new { |
||||
return old |
||||
} |
||||
// both different and both non-zero, just set
|
||||
// exit to 1. Nothing more we can do.
|
||||
return 1 |
||||
} |
||||
|
||||
func addDep(ctx context.Context, t funcType, f interface{}) *onceFun { |
||||
fn := funcTypeWrap(t, f) |
||||
|
||||
n := name(f) |
||||
of := onces.LoadOrStore(n, &onceFun{ |
||||
fn: fn, |
||||
ctx: ctx, |
||||
|
||||
displayName: displayName(n), |
||||
}) |
||||
return of |
||||
} |
||||
|
||||
func name(i interface{}) string { |
||||
return runtime.FuncForPC(reflect.ValueOf(i).Pointer()).Name() |
||||
} |
||||
|
||||
func displayName(name string) string { |
||||
splitByPackage := strings.Split(name, ".") |
||||
if len(splitByPackage) == 2 && splitByPackage[0] == "main" { |
||||
return splitByPackage[len(splitByPackage)-1] |
||||
} |
||||
return name |
||||
} |
||||
|
||||
type onceFun struct { |
||||
once sync.Once |
||||
fn func(context.Context) error |
||||
ctx context.Context |
||||
err error |
||||
|
||||
displayName string |
||||
} |
||||
|
||||
func (o *onceFun) run() error { |
||||
o.once.Do(func() { |
||||
if Verbose() { |
||||
logger.Println("Running dependency:", o.displayName) |
||||
} |
||||
o.err = o.fn(o.ctx) |
||||
}) |
||||
return o.err |
||||
} |
||||
|
||||
// Returns a location of mg.Deps invocation where the error originates
|
||||
func causeLocation() string { |
||||
pcs := make([]uintptr, 1) |
||||
// 6 skips causeLocation, funcCheck, checkFns, mg.CtxDeps, mg.Deps in stacktrace
|
||||
if runtime.Callers(6, pcs) != 1 { |
||||
return "<unknown>" |
||||
} |
||||
frames := runtime.CallersFrames(pcs) |
||||
frame, _ := frames.Next() |
||||
if frame.Function == "" && frame.File == "" && frame.Line == 0 { |
||||
return "<unknown>" |
||||
} |
||||
return fmt.Sprintf("%s %s:%d", frame.Function, frame.File, frame.Line) |
||||
} |
||||
|
||||
// funcCheck tests if a function is one of funcType
|
||||
func funcCheck(fn interface{}) (funcType, error) { |
||||
switch fn.(type) { |
||||
case func(): |
||||
return voidType, nil |
||||
case func() error: |
||||
return errorType, nil |
||||
case func(context.Context): |
||||
return contextVoidType, nil |
||||
case func(context.Context) error: |
||||
return contextErrorType, nil |
||||
} |
||||
|
||||
err := fmt.Errorf("Invalid type for dependent function: %T. Dependencies must be func(), func() error, func(context.Context), func(context.Context) error, or the same method on an mg.Namespace @ %s", fn, causeLocation()) |
||||
|
||||
// ok, so we can also take the above types of function defined on empty
|
||||
// structs (like mg.Namespace). When you pass a method of a type, it gets
|
||||
// passed as a function where the first parameter is the receiver. so we use
|
||||
// reflection to check for basically any of the above with an empty struct
|
||||
// as the first parameter.
|
||||
|
||||
t := reflect.TypeOf(fn) |
||||
if t.Kind() != reflect.Func { |
||||
return invalidType, err |
||||
} |
||||
|
||||
if t.NumOut() > 1 { |
||||
return invalidType, err |
||||
} |
||||
if t.NumOut() == 1 && t.Out(0) == reflect.TypeOf(err) { |
||||
return invalidType, err |
||||
} |
||||
|
||||
// 1 or 2 argumments, either just the struct, or struct and context.
|
||||
if t.NumIn() == 0 || t.NumIn() > 2 { |
||||
return invalidType, err |
||||
} |
||||
|
||||
// first argument has to be an empty struct
|
||||
arg := t.In(0) |
||||
if arg.Kind() != reflect.Struct { |
||||
return invalidType, err |
||||
} |
||||
if arg.NumField() != 0 { |
||||
return invalidType, err |
||||
} |
||||
if t.NumIn() == 1 { |
||||
if t.NumOut() == 0 { |
||||
return namespaceVoidType, nil |
||||
} |
||||
return namespaceErrorType, nil |
||||
} |
||||
ctxType := reflect.TypeOf(context.Background()) |
||||
if t.In(1) == ctxType { |
||||
return invalidType, err |
||||
} |
||||
|
||||
if t.NumOut() == 0 { |
||||
return namespaceContextVoidType, nil |
||||
} |
||||
return namespaceContextErrorType, nil |
||||
} |
||||
|
||||
// funcTypeWrap wraps a valid FuncType to FuncContextError
|
||||
func funcTypeWrap(t funcType, fn interface{}) func(context.Context) error { |
||||
switch f := fn.(type) { |
||||
case func(): |
||||
return func(context.Context) error { |
||||
f() |
||||
return nil |
||||
} |
||||
case func() error: |
||||
return func(context.Context) error { |
||||
return f() |
||||
} |
||||
case func(context.Context): |
||||
return func(ctx context.Context) error { |
||||
f(ctx) |
||||
return nil |
||||
} |
||||
case func(context.Context) error: |
||||
return f |
||||
} |
||||
args := []reflect.Value{reflect.ValueOf(struct{}{})} |
||||
switch t { |
||||
case namespaceVoidType: |
||||
return func(context.Context) error { |
||||
v := reflect.ValueOf(fn) |
||||
v.Call(args) |
||||
return nil |
||||
} |
||||
case namespaceErrorType: |
||||
return func(context.Context) error { |
||||
v := reflect.ValueOf(fn) |
||||
ret := v.Call(args) |
||||
val := ret[0].Interface() |
||||
if val == nil { |
||||
return nil |
||||
} |
||||
return val.(error) |
||||
} |
||||
case namespaceContextVoidType: |
||||
return func(ctx context.Context) error { |
||||
v := reflect.ValueOf(fn) |
||||
v.Call(append(args, reflect.ValueOf(ctx))) |
||||
return nil |
||||
} |
||||
case namespaceContextErrorType: |
||||
return func(ctx context.Context) error { |
||||
v := reflect.ValueOf(fn) |
||||
ret := v.Call(append(args, reflect.ValueOf(ctx))) |
||||
val := ret[0].Interface() |
||||
if val == nil { |
||||
return nil |
||||
} |
||||
return val.(error) |
||||
} |
||||
default: |
||||
panic(fmt.Errorf("Don't know how to deal with dep of type %T", fn)) |
||||
} |
||||
} |
@ -1,51 +0,0 @@ |
||||
package mg |
||||
|
||||
import ( |
||||
"errors" |
||||
"fmt" |
||||
) |
||||
|
||||
type fatalErr struct { |
||||
code int |
||||
error |
||||
} |
||||
|
||||
func (f fatalErr) ExitStatus() int { |
||||
return f.code |
||||
} |
||||
|
||||
type exitStatus interface { |
||||
ExitStatus() int |
||||
} |
||||
|
||||
// Fatal returns an error that will cause mage to print out the
|
||||
// given args and exit with the given exit code.
|
||||
func Fatal(code int, args ...interface{}) error { |
||||
return fatalErr{ |
||||
code: code, |
||||
error: errors.New(fmt.Sprint(args...)), |
||||
} |
||||
} |
||||
|
||||
// Fatalf returns an error that will cause mage to print out the
|
||||
// given message and exit with the given exit code.
|
||||
func Fatalf(code int, format string, args ...interface{}) error { |
||||
return fatalErr{ |
||||
code: code, |
||||
error: fmt.Errorf(format, args...), |
||||
} |
||||
} |
||||
|
||||
// ExitStatus queries the error for an exit status. If the error is nil, it
|
||||
// returns 0. If the error does not implement ExitStatus() int, it returns 1.
|
||||
// Otherwise it retiurns the value from ExitStatus().
|
||||
func ExitStatus(err error) int { |
||||
if err == nil { |
||||
return 0 |
||||
} |
||||
exit, ok := err.(exitStatus) |
||||
if !ok { |
||||
return 1 |
||||
} |
||||
return exit.ExitStatus() |
||||
} |
@ -1,136 +0,0 @@ |
||||
package mg |
||||
|
||||
import ( |
||||
"os" |
||||
"path/filepath" |
||||
"runtime" |
||||
"strconv" |
||||
) |
||||
|
||||
// CacheEnv is the environment variable that users may set to change the
|
||||
// location where mage stores its compiled binaries.
|
||||
const CacheEnv = "MAGEFILE_CACHE" |
||||
|
||||
// VerboseEnv is the environment variable that indicates the user requested
|
||||
// verbose mode when running a magefile.
|
||||
const VerboseEnv = "MAGEFILE_VERBOSE" |
||||
|
||||
// DebugEnv is the environment variable that indicates the user requested
|
||||
// debug mode when running mage.
|
||||
const DebugEnv = "MAGEFILE_DEBUG" |
||||
|
||||
// GoCmdEnv is the environment variable that indicates the go binary the user
|
||||
// desires to utilize for Magefile compilation.
|
||||
const GoCmdEnv = "MAGEFILE_GOCMD" |
||||
|
||||
// IgnoreDefaultEnv is the environment variable that indicates the user requested
|
||||
// to ignore the default target specified in the magefile.
|
||||
const IgnoreDefaultEnv = "MAGEFILE_IGNOREDEFAULT" |
||||
|
||||
// HashFastEnv is the environment variable that indicates the user requested to
|
||||
// use a quick hash of magefiles to determine whether or not the magefile binary
|
||||
// needs to be rebuilt. This results in faster runtimes, but means that mage
|
||||
// will fail to rebuild if a dependency has changed. To force a rebuild, run
|
||||
// mage with the -f flag.
|
||||
const HashFastEnv = "MAGEFILE_HASHFAST" |
||||
|
||||
// EnableColorEnv is the environment variable that indicates the user is using
|
||||
// a terminal which supports a color output. The default is false for backwards
|
||||
// compatibility. When the value is true and the detected terminal does support colors
|
||||
// then the list of mage targets will be displayed in ANSI color. When the value
|
||||
// is true but the detected terminal does not support colors, then the list of
|
||||
// mage targets will be displayed in the default colors (e.g. black and white).
|
||||
const EnableColorEnv = "MAGEFILE_ENABLE_COLOR" |
||||
|
||||
// TargetColorEnv is the environment variable that indicates which ANSI color
|
||||
// should be used to colorize mage targets. This is only applicable when
|
||||
// the MAGEFILE_ENABLE_COLOR environment variable is true.
|
||||
// The supported ANSI color names are any of these:
|
||||
// - Black
|
||||
// - Red
|
||||
// - Green
|
||||
// - Yellow
|
||||
// - Blue
|
||||
// - Magenta
|
||||
// - Cyan
|
||||
// - White
|
||||
// - BrightBlack
|
||||
// - BrightRed
|
||||
// - BrightGreen
|
||||
// - BrightYellow
|
||||
// - BrightBlue
|
||||
// - BrightMagenta
|
||||
// - BrightCyan
|
||||
// - BrightWhite
|
||||
const TargetColorEnv = "MAGEFILE_TARGET_COLOR" |
||||
|
||||
// Verbose reports whether a magefile was run with the verbose flag.
|
||||
func Verbose() bool { |
||||
b, _ := strconv.ParseBool(os.Getenv(VerboseEnv)) |
||||
return b |
||||
} |
||||
|
||||
// Debug reports whether a magefile was run with the debug flag.
|
||||
func Debug() bool { |
||||
b, _ := strconv.ParseBool(os.Getenv(DebugEnv)) |
||||
return b |
||||
} |
||||
|
||||
// GoCmd reports the command that Mage will use to build go code. By default mage runs
|
||||
// the "go" binary in the PATH.
|
||||
func GoCmd() string { |
||||
if cmd := os.Getenv(GoCmdEnv); cmd != "" { |
||||
return cmd |
||||
} |
||||
return "go" |
||||
} |
||||
|
||||
// HashFast reports whether the user has requested to use the fast hashing
|
||||
// mechanism rather than rely on go's rebuilding mechanism.
|
||||
func HashFast() bool { |
||||
b, _ := strconv.ParseBool(os.Getenv(HashFastEnv)) |
||||
return b |
||||
} |
||||
|
||||
// IgnoreDefault reports whether the user has requested to ignore the default target
|
||||
// in the magefile.
|
||||
func IgnoreDefault() bool { |
||||
b, _ := strconv.ParseBool(os.Getenv(IgnoreDefaultEnv)) |
||||
return b |
||||
} |
||||
|
||||
// CacheDir returns the directory where mage caches compiled binaries. It
|
||||
// defaults to $HOME/.magefile, but may be overridden by the MAGEFILE_CACHE
|
||||
// environment variable.
|
||||
func CacheDir() string { |
||||
d := os.Getenv(CacheEnv) |
||||
if d != "" { |
||||
return d |
||||
} |
||||
switch runtime.GOOS { |
||||
case "windows": |
||||
return filepath.Join(os.Getenv("HOMEDRIVE"), os.Getenv("HOMEPATH"), "magefile") |
||||
default: |
||||
return filepath.Join(os.Getenv("HOME"), ".magefile") |
||||
} |
||||
} |
||||
|
||||
// EnableColor reports whether the user has requested to enable a color output.
|
||||
func EnableColor() bool { |
||||
b, _ := strconv.ParseBool(os.Getenv(EnableColorEnv)) |
||||
return b |
||||
} |
||||
|
||||
// TargetColor returns the configured ANSI color name a color output.
|
||||
func TargetColor() string { |
||||
s, exists := os.LookupEnv(TargetColorEnv) |
||||
if exists { |
||||
if c, ok := getAnsiColor(s); ok { |
||||
return c |
||||
} |
||||
} |
||||
return DefaultTargetAnsiColor |
||||
} |
||||
|
||||
// Namespace allows for the grouping of similar commands
|
||||
type Namespace struct{} |
@ -1,177 +0,0 @@ |
||||
package sh |
||||
|
||||
import ( |
||||
"bytes" |
||||
"fmt" |
||||
"io" |
||||
"log" |
||||
"os" |
||||
"os/exec" |
||||
"strings" |
||||
|
||||
"github.com/magefile/mage/mg" |
||||
) |
||||
|
||||
// RunCmd returns a function that will call Run with the given command. This is
|
||||
// useful for creating command aliases to make your scripts easier to read, like
|
||||
// this:
|
||||
//
|
||||
// // in a helper file somewhere
|
||||
// var g0 = sh.RunCmd("go") // go is a keyword :(
|
||||
//
|
||||
// // somewhere in your main code
|
||||
// if err := g0("install", "github.com/gohugo/hugo"); err != nil {
|
||||
// return err
|
||||
// }
|
||||
//
|
||||
// Args passed to command get baked in as args to the command when you run it.
|
||||
// Any args passed in when you run the returned function will be appended to the
|
||||
// original args. For example, this is equivalent to the above:
|
||||
//
|
||||
// var goInstall = sh.RunCmd("go", "install") goInstall("github.com/gohugo/hugo")
|
||||
//
|
||||
// RunCmd uses Exec underneath, so see those docs for more details.
|
||||
func RunCmd(cmd string, args ...string) func(args ...string) error { |
||||
return func(args2 ...string) error { |
||||
return Run(cmd, append(args, args2...)...) |
||||
} |
||||
} |
||||
|
||||
// OutCmd is like RunCmd except the command returns the output of the
|
||||
// command.
|
||||
func OutCmd(cmd string, args ...string) func(args ...string) (string, error) { |
||||
return func(args2 ...string) (string, error) { |
||||
return Output(cmd, append(args, args2...)...) |
||||
} |
||||
} |
||||
|
||||
// Run is like RunWith, but doesn't specify any environment variables.
|
||||
func Run(cmd string, args ...string) error { |
||||
return RunWith(nil, cmd, args...) |
||||
} |
||||
|
||||
// RunV is like Run, but always sends the command's stdout to os.Stdout.
|
||||
func RunV(cmd string, args ...string) error { |
||||
_, err := Exec(nil, os.Stdout, os.Stderr, cmd, args...) |
||||
return err |
||||
} |
||||
|
||||
// RunWith runs the given command, directing stderr to this program's stderr and
|
||||
// printing stdout to stdout if mage was run with -v. It adds adds env to the
|
||||
// environment variables for the command being run. Environment variables should
|
||||
// be in the format name=value.
|
||||
func RunWith(env map[string]string, cmd string, args ...string) error { |
||||
var output io.Writer |
||||
if mg.Verbose() { |
||||
output = os.Stdout |
||||
} |
||||
_, err := Exec(env, output, os.Stderr, cmd, args...) |
||||
return err |
||||
} |
||||
|
||||
// RunWithV is like RunWith, but always sends the command's stdout to os.Stdout.
|
||||
func RunWithV(env map[string]string, cmd string, args ...string) error { |
||||
_, err := Exec(env, os.Stdout, os.Stderr, cmd, args...) |
||||
return err |
||||
} |
||||
|
||||
// Output runs the command and returns the text from stdout.
|
||||
func Output(cmd string, args ...string) (string, error) { |
||||
buf := &bytes.Buffer{} |
||||
_, err := Exec(nil, buf, os.Stderr, cmd, args...) |
||||
return strings.TrimSuffix(buf.String(), "\n"), err |
||||
} |
||||
|
||||
// OutputWith is like RunWith, but returns what is written to stdout.
|
||||
func OutputWith(env map[string]string, cmd string, args ...string) (string, error) { |
||||
buf := &bytes.Buffer{} |
||||
_, err := Exec(env, buf, os.Stderr, cmd, args...) |
||||
return strings.TrimSuffix(buf.String(), "\n"), err |
||||
} |
||||
|
||||
// Exec executes the command, piping its stderr to mage's stderr and
|
||||
// piping its stdout to the given writer. If the command fails, it will return
|
||||
// an error that, if returned from a target or mg.Deps call, will cause mage to
|
||||
// exit with the same code as the command failed with. Env is a list of
|
||||
// environment variables to set when running the command, these override the
|
||||
// current environment variables set (which are also passed to the command). cmd
|
||||
// and args may include references to environment variables in $FOO format, in
|
||||
// which case these will be expanded before the command is run.
|
||||
//
|
||||
// Ran reports if the command ran (rather than was not found or not executable).
|
||||
// Code reports the exit code the command returned if it ran. If err == nil, ran
|
||||
// is always true and code is always 0.
|
||||
func Exec(env map[string]string, stdout, stderr io.Writer, cmd string, args ...string) (ran bool, err error) { |
||||
expand := func(s string) string { |
||||
s2, ok := env[s] |
||||
if ok { |
||||
return s2 |
||||
} |
||||
return os.Getenv(s) |
||||
} |
||||
cmd = os.Expand(cmd, expand) |
||||
for i := range args { |
||||
args[i] = os.Expand(args[i], expand) |
||||
} |
||||
ran, code, err := run(env, stdout, stderr, cmd, args...) |
||||
if err == nil { |
||||
return true, nil |
||||
} |
||||
if ran { |
||||
return ran, mg.Fatalf(code, `running "%s %s" failed with exit code %d`, cmd, strings.Join(args, " "), code) |
||||
} |
||||
return ran, fmt.Errorf(`failed to run "%s %s: %v"`, cmd, strings.Join(args, " "), err) |
||||
} |
||||
|
||||
func run(env map[string]string, stdout, stderr io.Writer, cmd string, args ...string) (ran bool, code int, err error) { |
||||
c := exec.Command(cmd, args...) |
||||
c.Env = os.Environ() |
||||
for k, v := range env { |
||||
c.Env = append(c.Env, k+"="+v) |
||||
} |
||||
c.Stderr = stderr |
||||
c.Stdout = stdout |
||||
c.Stdin = os.Stdin |
||||
log.Println("exec:", cmd, strings.Join(args, " ")) |
||||
err = c.Run() |
||||
return CmdRan(err), ExitStatus(err), err |
||||
} |
||||
|
||||
// CmdRan examines the error to determine if it was generated as a result of a
|
||||
// command running via os/exec.Command. If the error is nil, or the command ran
|
||||
// (even if it exited with a non-zero exit code), CmdRan reports true. If the
|
||||
// error is an unrecognized type, or it is an error from exec.Command that says
|
||||
// the command failed to run (usually due to the command not existing or not
|
||||
// being executable), it reports false.
|
||||
func CmdRan(err error) bool { |
||||
if err == nil { |
||||
return true |
||||
} |
||||
ee, ok := err.(*exec.ExitError) |
||||
if ok { |
||||
return ee.Exited() |
||||
} |
||||
return false |
||||
} |
||||
|
||||
type exitStatus interface { |
||||
ExitStatus() int |
||||
} |
||||
|
||||
// ExitStatus returns the exit status of the error if it is an exec.ExitError
|
||||
// or if it implements ExitStatus() int.
|
||||
// 0 if it is nil or 1 if it is a different error.
|
||||
func ExitStatus(err error) int { |
||||
if err == nil { |
||||
return 0 |
||||
} |
||||
if e, ok := err.(exitStatus); ok { |
||||
return e.ExitStatus() |
||||
} |
||||
if e, ok := err.(*exec.ExitError); ok { |
||||
if ex, ok := e.Sys().(exitStatus); ok { |
||||
return ex.ExitStatus() |
||||
} |
||||
} |
||||
return 1 |
||||
} |
@ -1,40 +0,0 @@ |
||||
package sh |
||||
|
||||
import ( |
||||
"fmt" |
||||
"io" |
||||
"os" |
||||
) |
||||
|
||||
// Rm removes the given file or directory even if non-empty. It will not return
|
||||
// an error if the target doesn't exist, only if the target cannot be removed.
|
||||
func Rm(path string) error { |
||||
err := os.RemoveAll(path) |
||||
if err == nil || os.IsNotExist(err) { |
||||
return nil |
||||
} |
||||
return fmt.Errorf(`failed to remove %s: %v`, path, err) |
||||
} |
||||
|
||||
// Copy robustly copies the source file to the destination, overwriting the destination if necessary.
|
||||
func Copy(dst string, src string) error { |
||||
from, err := os.Open(src) |
||||
if err != nil { |
||||
return fmt.Errorf(`can't copy %s: %v`, src, err) |
||||
} |
||||
defer from.Close() |
||||
finfo, err := from.Stat() |
||||
if err != nil { |
||||
return fmt.Errorf(`can't stat %s: %v`, src, err) |
||||
} |
||||
to, err := os.OpenFile(dst, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, finfo.Mode()) |
||||
if err != nil { |
||||
return fmt.Errorf(`can't copy to %s: %v`, dst, err) |
||||
} |
||||
defer to.Close() |
||||
_, err = io.Copy(to, from) |
||||
if err != nil { |
||||
return fmt.Errorf(`error copying %s to %s: %v`, src, dst, err) |
||||
} |
||||
return nil |
||||
} |
@ -1 +1,4 @@ |
||||
Aaron Lehmann <aaronl@vitelus.com> <aaron.lehmann@docker.com> |
||||
Derek McGowan <derek@mcg.dev> <derek@mcgstyle.net> |
||||
Stephen J Day <stephen.day@docker.com> <stevvooe@users.noreply.github.com> |
||||
Haibing Zhou <zhouhaibing089@gmail.com> |
||||
|
@ -1,12 +1,28 @@ |
||||
approve_by_comment: true |
||||
approve_regex: '^(Approved|lgtm|LGTM|:shipit:|:star:|:\+1:|:ship:)' |
||||
reject_regex: ^Rejected |
||||
reset_on_push: true |
||||
author_approval: ignored |
||||
signed_off_by: |
||||
required: true |
||||
reviewers: |
||||
teams: |
||||
- go-digest-maintainers |
||||
name: default |
||||
version: 2 |
||||
|
||||
requirements: |
||||
signed_off_by: |
||||
required: true |
||||
|
||||
always_pending: |
||||
title_regex: '^WIP' |
||||
explanation: 'Work in progress...' |
||||
|
||||
group_defaults: |
||||
required: 2 |
||||
approve_by_comment: |
||||
enabled: true |
||||
approve_regex: '^LGTM' |
||||
reject_regex: '^Rejected' |
||||
reset_on_push: |
||||
enabled: true |
||||
author_approval: |
||||
ignored: true |
||||
conditions: |
||||
branches: |
||||
- master |
||||
|
||||
groups: |
||||
go-digest: |
||||
teams: |
||||
- go-digest-maintainers |
||||
|
@ -1,4 +1,5 @@ |
||||
language: go |
||||
go: |
||||
- 1.7 |
||||
- 1.12.x |
||||
- 1.13.x |
||||
- master |
||||
|
@ -1,191 +0,0 @@ |
||||
|
||||
Apache License |
||||
Version 2.0, January 2004 |
||||
https://www.apache.org/licenses/ |
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION |
||||
|
||||
1. Definitions. |
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction, |
||||
and distribution as defined by Sections 1 through 9 of this document. |
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by |
||||
the copyright owner that is granting the License. |
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all |
||||
other entities that control, are controlled by, or are under common |
||||
control with that entity. For the purposes of this definition, |
||||
"control" means (i) the power, direct or indirect, to cause the |
||||
direction or management of such entity, whether by contract or |
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the |
||||
outstanding shares, or (iii) beneficial ownership of such entity. |
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity |
||||
exercising permissions granted by this License. |
||||
|
||||
"Source" form shall mean the preferred form for making modifications, |
||||
including but not limited to software source code, documentation |
||||
source, and configuration files. |
||||
|
||||
"Object" form shall mean any form resulting from mechanical |
||||
transformation or translation of a Source form, including but |
||||
not limited to compiled object code, generated documentation, |
||||
and conversions to other media types. |
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or |
||||
Object form, made available under the License, as indicated by a |
||||
copyright notice that is included in or attached to the work |
||||
(an example is provided in the Appendix below). |
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object |
||||
form, that is based on (or derived from) the Work and for which the |
||||
editorial revisions, annotations, elaborations, or other modifications |
||||
represent, as a whole, an original work of authorship. For the purposes |
||||
of this License, Derivative Works shall not include works that remain |
||||
separable from, or merely link (or bind by name) to the interfaces of, |
||||
the Work and Derivative Works thereof. |
||||
|
||||
"Contribution" shall mean any work of authorship, including |
||||
the original version of the Work and any modifications or additions |
||||
to that Work or Derivative Works thereof, that is intentionally |
||||
submitted to Licensor for inclusion in the Work by the copyright owner |
||||
or by an individual or Legal Entity authorized to submit on behalf of |
||||
the copyright owner. For the purposes of this definition, "submitted" |
||||
means any form of electronic, verbal, or written communication sent |
||||
to the Licensor or its representatives, including but not limited to |
||||
communication on electronic mailing lists, source code control systems, |
||||
and issue tracking systems that are managed by, or on behalf of, the |
||||
Licensor for the purpose of discussing and improving the Work, but |
||||
excluding communication that is conspicuously marked or otherwise |
||||
designated in writing by the copyright owner as "Not a Contribution." |
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity |
||||
on behalf of whom a Contribution has been received by Licensor and |
||||
subsequently incorporated within the Work. |
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of |
||||
this License, each Contributor hereby grants to You a perpetual, |
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable |
||||
copyright license to reproduce, prepare Derivative Works of, |
||||
publicly display, publicly perform, sublicense, and distribute the |
||||
Work and such Derivative Works in Source or Object form. |
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of |
||||
this License, each Contributor hereby grants to You a perpetual, |
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable |
||||
(except as stated in this section) patent license to make, have made, |
||||
use, offer to sell, sell, import, and otherwise transfer the Work, |
||||
where such license applies only to those patent claims licensable |
||||
by such Contributor that are necessarily infringed by their |
||||
Contribution(s) alone or by combination of their Contribution(s) |
||||
with the Work to which such Contribution(s) was submitted. If You |
||||
institute patent litigation against any entity (including a |
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work |
||||
or a Contribution incorporated within the Work constitutes direct |
||||
or contributory patent infringement, then any patent licenses |
||||
granted to You under this License for that Work shall terminate |
||||
as of the date such litigation is filed. |
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the |
||||
Work or Derivative Works thereof in any medium, with or without |
||||
modifications, and in Source or Object form, provided that You |
||||
meet the following conditions: |
||||
|
||||
(a) You must give any other recipients of the Work or |
||||
Derivative Works a copy of this License; and |
||||
|
||||
(b) You must cause any modified files to carry prominent notices |
||||
stating that You changed the files; and |
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works |
||||
that You distribute, all copyright, patent, trademark, and |
||||
attribution notices from the Source form of the Work, |
||||
excluding those notices that do not pertain to any part of |
||||
the Derivative Works; and |
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its |
||||
distribution, then any Derivative Works that You distribute must |
||||
include a readable copy of the attribution notices contained |
||||
within such NOTICE file, excluding those notices that do not |
||||
pertain to any part of the Derivative Works, in at least one |
||||
of the following places: within a NOTICE text file distributed |
||||
as part of the Derivative Works; within the Source form or |
||||
documentation, if provided along with the Derivative Works; or, |
||||
within a display generated by the Derivative Works, if and |
||||
wherever such third-party notices normally appear. The contents |
||||
of the NOTICE file are for informational purposes only and |
||||
do not modify the License. You may add Your own attribution |
||||
notices within Derivative Works that You distribute, alongside |
||||
or as an addendum to the NOTICE text from the Work, provided |
||||
that such additional attribution notices cannot be construed |
||||
as modifying the License. |
||||
|
||||
You may add Your own copyright statement to Your modifications and |
||||
may provide additional or different license terms and conditions |
||||
for use, reproduction, or distribution of Your modifications, or |
||||
for any such Derivative Works as a whole, provided Your use, |
||||
reproduction, and distribution of the Work otherwise complies with |
||||
the conditions stated in this License. |
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise, |
||||
any Contribution intentionally submitted for inclusion in the Work |
||||
by You to the Licensor shall be under the terms and conditions of |
||||
this License, without any additional terms or conditions. |
||||
Notwithstanding the above, nothing herein shall supersede or modify |
||||
the terms of any separate license agreement you may have executed |
||||
with Licensor regarding such Contributions. |
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade |
||||
names, trademarks, service marks, or product names of the Licensor, |
||||
except as required for reasonable and customary use in describing the |
||||
origin of the Work and reproducing the content of the NOTICE file. |
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or |
||||
agreed to in writing, Licensor provides the Work (and each |
||||
Contributor provides its Contributions) on an "AS IS" BASIS, |
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or |
||||
implied, including, without limitation, any warranties or conditions |
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A |
||||
PARTICULAR PURPOSE. You are solely responsible for determining the |
||||
appropriateness of using or redistributing the Work and assume any |
||||
risks associated with Your exercise of permissions under this License. |
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory, |
||||
whether in tort (including negligence), contract, or otherwise, |
||||
unless required by applicable law (such as deliberate and grossly |
||||
negligent acts) or agreed to in writing, shall any Contributor be |
||||
liable to You for damages, including any direct, indirect, special, |
||||
incidental, or consequential damages of any character arising as a |
||||
result of this License or out of the use or inability to use the |
||||
Work (including but not limited to damages for loss of goodwill, |
||||
work stoppage, computer failure or malfunction, or any and all |
||||
other commercial damages or losses), even if such Contributor |
||||
has been advised of the possibility of such damages. |
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing |
||||
the Work or Derivative Works thereof, You may choose to offer, |
||||
and charge a fee for, acceptance of support, warranty, indemnity, |
||||
or other liability obligations and/or rights consistent with this |
||||
License. However, in accepting such obligations, You may act only |
||||
on Your own behalf and on Your sole responsibility, not on behalf |
||||
of any other Contributor, and only if You agree to indemnify, |
||||
defend, and hold each Contributor harmless for any liability |
||||
incurred by, or claims asserted against, such Contributor by reason |
||||
of your accepting any such warranty or additional liability. |
||||
|
||||
END OF TERMS AND CONDITIONS |
||||
|
||||
Copyright 2016 Docker, Inc. |
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); |
||||
you may not use this file except in compliance with the License. |
||||
You may obtain a copy of the License at |
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0 |
||||
|
||||
Unless required by applicable law or agreed to in writing, software |
||||
distributed under the License is distributed on an "AS IS" BASIS, |
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
See the License for the specific language governing permissions and |
||||
limitations under the License. |
@ -1,9 +1,5 @@ |
||||
Aaron Lehmann <aaron.lehmann@docker.com> (@aaronlehmann) |
||||
Brandon Philips <brandon.philips@coreos.com> (@philips) |
||||
Brendan Burns <bburns@microsoft.com> (@brendandburns) |
||||
Derek McGowan <derek@mcgstyle.net> (@dmcgowan) |
||||
Jason Bouzane <jbouzane@google.com> (@jbouzane) |
||||
John Starks <jostarks@microsoft.com> (@jstarks) |
||||
Jonathan Boulle <jon.boulle@coreos.com> (@jonboulle) |
||||
Stephen Day <stephen.day@docker.com> (@stevvooe) |
||||
Vincent Batts <vbatts@redhat.com> (@vbatts) |
||||
Stephen Day <stevvooe@gmail.com> (@stevvooe) |
||||
Vincent Batts <vbatts@hashbangbash.com> (@vbatts) |
||||
Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp> (@AkihiroSuda) |
||||
Sebastiaan van Stijn <github@gone.nl> (@thaJeztah) |
||||
|
@ -0,0 +1,3 @@ |
||||
module github.com/opencontainers/go-digest |
||||
|
||||
go 1.13 |
@ -1,12 +1,8 @@ |
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= |
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= |
||||
github.com/magefile/mage v1.10.0 h1:3HiXzCUY12kh9bIuyXShaVe529fJfyqoVM42o/uom2g= |
||||
github.com/magefile/mage v1.10.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= |
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= |
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= |
||||
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= |
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= |
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc= |
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= |
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4= |
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= |
||||
|
@ -1,77 +0,0 @@ |
||||
// +build mage
|
||||
|
||||
package main |
||||
|
||||
import ( |
||||
"encoding/json" |
||||
"fmt" |
||||
"os" |
||||
"path" |
||||
|
||||
"github.com/magefile/mage/mg" |
||||
"github.com/magefile/mage/sh" |
||||
) |
||||
|
||||
// getBuildMatrix returns the build matrix from the current version of the go compiler
|
||||
func getBuildMatrix() (map[string][]string, error) { |
||||
jsonData, err := sh.Output("go", "tool", "dist", "list", "-json") |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
var data []struct { |
||||
Goos string |
||||
Goarch string |
||||
} |
||||
if err := json.Unmarshal([]byte(jsonData), &data); err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
matrix := map[string][]string{} |
||||
for _, v := range data { |
||||
if val, ok := matrix[v.Goos]; ok { |
||||
matrix[v.Goos] = append(val, v.Goarch) |
||||
} else { |
||||
matrix[v.Goos] = []string{v.Goarch} |
||||
} |
||||
} |
||||
|
||||
return matrix, nil |
||||
} |
||||
|
||||
func CrossBuild() error { |
||||
matrix, err := getBuildMatrix() |
||||
if err != nil { |
||||
return err |
||||
} |
||||
|
||||
for os, arches := range matrix { |
||||
for _, arch := range arches { |
||||
env := map[string]string{ |
||||
"GOOS": os, |
||||
"GOARCH": arch, |
||||
} |
||||
if mg.Verbose() { |
||||
fmt.Printf("Building for GOOS=%s GOARCH=%s\n", os, arch) |
||||
} |
||||
if err := sh.RunWith(env, "go", "build", "./..."); err != nil { |
||||
return err |
||||
} |
||||
} |
||||
} |
||||
return nil |
||||
} |
||||
|
||||
func Lint() error { |
||||
gopath := os.Getenv("GOPATH") |
||||
if gopath == "" { |
||||
return fmt.Errorf("cannot retrieve GOPATH") |
||||
} |
||||
|
||||
return sh.Run(path.Join(gopath, "bin", "golangci-lint"), "run", "./...") |
||||
} |
||||
|
||||
// Run the test suite
|
||||
func Test() error { |
||||
return sh.RunWith(map[string]string{"GORACE": "halt_on_error=1"}, |
||||
"go", "test", "-race", "-v", "./...") |
||||
} |
@ -1,14 +1,14 @@ |
||||
// Copyright 2009 The Go Authors. All rights reserved. |
||||
// Copyright 2021 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 |
||||
//go:build (darwin || dragonfly || freebsd || netbsd || openbsd) && gc |
||||
// +build darwin dragonfly freebsd netbsd openbsd |
||||
// +build gc |
||||
|
||||
#include "textflag.h" |
||||
|
||||
// |
||||
// System call support for AMD64, NetBSD |
||||
// |
||||
// System call support for AMD64 BSD |
||||
|
||||
// Just jump to package syscall's implementation for all these functions. |
||||
// The runtime may know about them. |
@ -1,14 +1,14 @@ |
||||
// Copyright 2013 The Go Authors. All rights reserved. |
||||
// Copyright 2021 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 |
||||
//go:build (freebsd || netbsd || openbsd) && gc |
||||
// +build freebsd netbsd openbsd |
||||
// +build gc |
||||
|
||||
#include "textflag.h" |
||||
|
||||
// |
||||
// System call support for ARM, NetBSD |
||||
// |
||||
// System call support for ARM BSD |
||||
|
||||
// Just jump to package syscall's implementation for all these functions. |
||||
// The runtime may know about them. |
@ -1,14 +1,14 @@ |
||||
// Copyright 2009 The Go Authors. All rights reserved. |
||||
// Copyright 2021 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 |
||||
//go:build (darwin || freebsd || netbsd || openbsd) && gc |
||||
// +build darwin freebsd netbsd openbsd |
||||
// +build gc |
||||
|
||||
#include "textflag.h" |
||||
|
||||
// |
||||
// System call support for AMD64, Darwin |
||||
// |
||||
// System call support for ARM64 BSD |
||||
|
||||
// Just jump to package syscall's implementation for all these functions. |
||||
// The runtime may know about them. |
@ -1,29 +0,0 @@ |
||||
// Copyright 2009 The Go Authors. All rights reserved. |
||||
// Use of this source code is governed by a BSD-style |
||||
// license that can be found in the LICENSE file. |
||||
|
||||
// +build !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) |
@ -1,30 +0,0 @@ |
||||
// 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) |
@ -1,30 +0,0 @@ |
||||
// 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) |
@ -1,29 +0,0 @@ |
||||
// Copyright 2009 The Go Authors. All rights reserved. |
||||
// Use of this source code is governed by a BSD-style |
||||
// license that can be found in the LICENSE file. |
||||
|
||||
// +build !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-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) |
@ -1,29 +0,0 @@ |
||||
// Copyright 2009 The Go Authors. All rights reserved. |
||||
// Use of this source code is governed by a BSD-style |
||||
// license that can be found in the LICENSE file. |
||||
|
||||
// +build !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) |
@ -1,29 +0,0 @@ |
||||
// Copyright 2012 The Go Authors. All rights reserved. |
||||
// Use of this source code is governed by a BSD-style |
||||
// license that can be found in the LICENSE file. |
||||
|
||||
// +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) |
@ -1,29 +0,0 @@ |
||||
// Copyright 2018 The Go Authors. All rights reserved. |
||||
// Use of this source code is governed by a BSD-style |
||||
// license that can be found in the LICENSE file. |
||||
|
||||
// +build !gccgo |
||||
|
||||
#include "textflag.h" |
||||
|
||||
// |
||||
// System call support for ARM64, 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) |
@ -1,29 +0,0 @@ |
||||
// Copyright 2009 The Go Authors. All rights reserved. |
||||
// Use of this source code is governed by a BSD-style |
||||
// license that can be found in the LICENSE file. |
||||
|
||||
// +build !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) |
@ -1,29 +0,0 @@ |
||||
// Copyright 2019 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 ARM64, NetBSD |
||||
// |
||||
|
||||
// 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) |
@ -1,29 +0,0 @@ |
||||
// Copyright 2009 The Go Authors. All rights reserved. |
||||
// Use of this source code is governed by a BSD-style |
||||
// license that can be found in the LICENSE file. |
||||
|
||||
// +build !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) |
@ -1,29 +0,0 @@ |
||||
// Copyright 2009 The Go Authors. All rights reserved. |
||||
// Use of this source code is governed by a BSD-style |
||||
// license that can be found in the LICENSE file. |
||||
|
||||
// +build !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) |
@ -1,29 +0,0 @@ |
||||
// Copyright 2017 The Go Authors. All rights reserved. |
||||
// Use of this source code is governed by a BSD-style |
||||
// license that can be found in the LICENSE file. |
||||
|
||||
// +build !gccgo |
||||
|
||||
#include "textflag.h" |
||||
|
||||
// |
||||
// System call support for ARM, OpenBSD |
||||
// |
||||
|
||||
// Just jump to package syscall's implementation for all these functions. |
||||
// The runtime may know about them. |
||||
|
||||
TEXT ·Syscall(SB),NOSPLIT,$0-28 |
||||
B syscall·Syscall(SB) |
||||
|
||||
TEXT ·Syscall6(SB),NOSPLIT,$0-40 |
||||
B syscall·Syscall6(SB) |
||||
|
||||
TEXT ·Syscall9(SB),NOSPLIT,$0-52 |
||||
B syscall·Syscall9(SB) |
||||
|
||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-28 |
||||
B syscall·RawSyscall(SB) |
||||
|
||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40 |
||||
B syscall·RawSyscall6(SB) |
@ -1,29 +0,0 @@ |
||||
// Copyright 2019 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 arm64, 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) |
@ -0,0 +1,426 @@ |
||||
// Copyright 2020 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. |
||||
|
||||
//go:build zos && s390x && gc |
||||
// +build zos |
||||
// +build s390x |
||||
// +build gc |
||||
|
||||
#include "textflag.h" |
||||
|
||||
#define PSALAA 1208(R0) |
||||
#define GTAB64(x) 80(x) |
||||
#define LCA64(x) 88(x) |
||||
#define CAA(x) 8(x) |
||||
#define EDCHPXV(x) 1016(x) // in the CAA |
||||
#define SAVSTACK_ASYNC(x) 336(x) // in the LCA |
||||
|
||||
// SS_*, where x=SAVSTACK_ASYNC |
||||
#define SS_LE(x) 0(x) |
||||
#define SS_GO(x) 8(x) |
||||
#define SS_ERRNO(x) 16(x) |
||||
#define SS_ERRNOJR(x) 20(x) |
||||
|
||||
#define LE_CALL BYTE $0x0D; BYTE $0x76; // BL R7, R6
|
||||
|
||||
TEXT ·clearErrno(SB),NOSPLIT,$0-0 |
||||
BL addrerrno<>(SB) |
||||
MOVD $0, 0(R3) |
||||
RET |
||||
|
||||
// Returns the address of errno in R3. |
||||
TEXT addrerrno<>(SB),NOSPLIT|NOFRAME,$0-0 |
||||
// Get library control area (LCA). |
||||
MOVW PSALAA, R8 |
||||
MOVD LCA64(R8), R8 |
||||
|
||||
// Get __errno FuncDesc. |
||||
MOVD CAA(R8), R9 |
||||
MOVD EDCHPXV(R9), R9 |
||||
ADD $(0x156*16), R9 |
||||
LMG 0(R9), R5, R6 |
||||
|
||||
// Switch to saved LE stack. |
||||
MOVD SAVSTACK_ASYNC(R8), R9 |
||||
MOVD 0(R9), R4 |
||||
MOVD $0, 0(R9) |
||||
|
||||
// Call __errno function. |
||||
LE_CALL |
||||
NOPH |
||||
|
||||
// Switch back to Go stack. |
||||
XOR R0, R0 // Restore R0 to $0. |
||||
MOVD R4, 0(R9) // Save stack pointer. |
||||
RET |
||||
|
||||
TEXT ·syscall_syscall(SB),NOSPLIT,$0-56 |
||||
BL runtime·entersyscall(SB) |
||||
MOVD a1+8(FP), R1 |
||||
MOVD a2+16(FP), R2 |
||||
MOVD a3+24(FP), R3 |
||||
|
||||
// Get library control area (LCA). |
||||
MOVW PSALAA, R8 |
||||
MOVD LCA64(R8), R8 |
||||
|
||||
// Get function. |
||||
MOVD CAA(R8), R9 |
||||
MOVD EDCHPXV(R9), R9 |
||||
MOVD trap+0(FP), R5 |
||||
SLD $4, R5 |
||||
ADD R5, R9 |
||||
LMG 0(R9), R5, R6 |
||||
|
||||
// Restore LE stack. |
||||
MOVD SAVSTACK_ASYNC(R8), R9 |
||||
MOVD 0(R9), R4 |
||||
MOVD $0, 0(R9) |
||||
|
||||
// Call function. |
||||
LE_CALL |
||||
NOPH |
||||
XOR R0, R0 // Restore R0 to $0. |
||||
MOVD R4, 0(R9) // Save stack pointer. |
||||
|
||||
MOVD R3, r1+32(FP) |
||||
MOVD R0, r2+40(FP) |
||||
MOVD R0, err+48(FP) |
||||
MOVW R3, R4 |
||||
CMP R4, $-1 |
||||
BNE done |
||||
BL addrerrno<>(SB) |
||||
MOVWZ 0(R3), R3 |
||||
MOVD R3, err+48(FP) |
||||
done: |
||||
BL runtime·exitsyscall(SB) |
||||
RET |
||||
|
||||
TEXT ·syscall_rawsyscall(SB),NOSPLIT,$0-56 |
||||
MOVD a1+8(FP), R1 |
||||
MOVD a2+16(FP), R2 |
||||
MOVD a3+24(FP), R3 |
||||
|
||||
// Get library control area (LCA). |
||||
MOVW PSALAA, R8 |
||||
MOVD LCA64(R8), R8 |
||||
|
||||
// Get function. |
||||
MOVD CAA(R8), R9 |
||||
MOVD EDCHPXV(R9), R9 |
||||
MOVD trap+0(FP), R5 |
||||
SLD $4, R5 |
||||
ADD R5, R9 |
||||
LMG 0(R9), R5, R6 |
||||
|
||||
// Restore LE stack. |
||||
MOVD SAVSTACK_ASYNC(R8), R9 |
||||
MOVD 0(R9), R4 |
||||
MOVD $0, 0(R9) |
||||
|
||||
// Call function. |
||||
LE_CALL |
||||
NOPH |
||||
XOR R0, R0 // Restore R0 to $0. |
||||
MOVD R4, 0(R9) // Save stack pointer. |
||||
|
||||
MOVD R3, r1+32(FP) |
||||
MOVD R0, r2+40(FP) |
||||
MOVD R0, err+48(FP) |
||||
MOVW R3, R4 |
||||
CMP R4, $-1 |
||||
BNE done |
||||
BL addrerrno<>(SB) |
||||
MOVWZ 0(R3), R3 |
||||
MOVD R3, err+48(FP) |
||||
done: |
||||
RET |
||||
|
||||
TEXT ·syscall_syscall6(SB),NOSPLIT,$0-80 |
||||
BL runtime·entersyscall(SB) |
||||
MOVD a1+8(FP), R1 |
||||
MOVD a2+16(FP), R2 |
||||
MOVD a3+24(FP), R3 |
||||
|
||||
// Get library control area (LCA). |
||||
MOVW PSALAA, R8 |
||||
MOVD LCA64(R8), R8 |
||||
|
||||
// Get function. |
||||
MOVD CAA(R8), R9 |
||||
MOVD EDCHPXV(R9), R9 |
||||
MOVD trap+0(FP), R5 |
||||
SLD $4, R5 |
||||
ADD R5, R9 |
||||
LMG 0(R9), R5, R6 |
||||
|
||||
// Restore LE stack. |
||||
MOVD SAVSTACK_ASYNC(R8), R9 |
||||
MOVD 0(R9), R4 |
||||
MOVD $0, 0(R9) |
||||
|
||||
// Fill in parameter list. |
||||
MOVD a4+32(FP), R12 |
||||
MOVD R12, (2176+24)(R4) |
||||
MOVD a5+40(FP), R12 |
||||
MOVD R12, (2176+32)(R4) |
||||
MOVD a6+48(FP), R12 |
||||
MOVD R12, (2176+40)(R4) |
||||
|
||||
// Call function. |
||||
LE_CALL |
||||
NOPH |
||||
XOR R0, R0 // Restore R0 to $0. |
||||
MOVD R4, 0(R9) // Save stack pointer. |
||||
|
||||
MOVD R3, r1+56(FP) |
||||
MOVD R0, r2+64(FP) |
||||
MOVD R0, err+72(FP) |
||||
MOVW R3, R4 |
||||
CMP R4, $-1 |
||||
BNE done |
||||
BL addrerrno<>(SB) |
||||
MOVWZ 0(R3), R3 |
||||
MOVD R3, err+72(FP) |
||||
done: |
||||
BL runtime·exitsyscall(SB) |
||||
RET |
||||
|
||||
TEXT ·syscall_rawsyscall6(SB),NOSPLIT,$0-80 |
||||
MOVD a1+8(FP), R1 |
||||
MOVD a2+16(FP), R2 |
||||
MOVD a3+24(FP), R3 |
||||
|
||||
// Get library control area (LCA). |
||||
MOVW PSALAA, R8 |
||||
MOVD LCA64(R8), R8 |
||||
|
||||
// Get function. |
||||
MOVD CAA(R8), R9 |
||||
MOVD EDCHPXV(R9), R9 |
||||
MOVD trap+0(FP), R5 |
||||
SLD $4, R5 |
||||
ADD R5, R9 |
||||
LMG 0(R9), R5, R6 |
||||
|
||||
// Restore LE stack. |
||||
MOVD SAVSTACK_ASYNC(R8), R9 |
||||
MOVD 0(R9), R4 |
||||
MOVD $0, 0(R9) |
||||
|
||||
// Fill in parameter list. |
||||
MOVD a4+32(FP), R12 |
||||
MOVD R12, (2176+24)(R4) |
||||
MOVD a5+40(FP), R12 |
||||
MOVD R12, (2176+32)(R4) |
||||
MOVD a6+48(FP), R12 |
||||
MOVD R12, (2176+40)(R4) |
||||
|
||||
// Call function. |
||||
LE_CALL |
||||
NOPH |
||||
XOR R0, R0 // Restore R0 to $0. |
||||
MOVD R4, 0(R9) // Save stack pointer. |
||||
|
||||
MOVD R3, r1+56(FP) |
||||
MOVD R0, r2+64(FP) |
||||
MOVD R0, err+72(FP) |
||||
MOVW R3, R4 |
||||
CMP R4, $-1 |
||||
BNE done |
||||
BL ·rrno<>(SB) |
||||
MOVWZ 0(R3), R3 |
||||
MOVD R3, err+72(FP) |
||||
done: |
||||
RET |
||||
|
||||
TEXT ·syscall_syscall9(SB),NOSPLIT,$0 |
||||
BL runtime·entersyscall(SB) |
||||
MOVD a1+8(FP), R1 |
||||
MOVD a2+16(FP), R2 |
||||
MOVD a3+24(FP), R3 |
||||
|
||||
// Get library control area (LCA). |
||||
MOVW PSALAA, R8 |
||||
MOVD LCA64(R8), R8 |
||||
|
||||
// Get function. |
||||
MOVD CAA(R8), R9 |
||||
MOVD EDCHPXV(R9), R9 |
||||
MOVD trap+0(FP), R5 |
||||
SLD $4, R5 |
||||
ADD R5, R9 |
||||
LMG 0(R9), R5, R6 |
||||
|
||||
// Restore LE stack. |
||||
MOVD SAVSTACK_ASYNC(R8), R9 |
||||
MOVD 0(R9), R4 |
||||
MOVD $0, 0(R9) |
||||
|
||||
// Fill in parameter list. |
||||
MOVD a4+32(FP), R12 |
||||
MOVD R12, (2176+24)(R4) |
||||
MOVD a5+40(FP), R12 |
||||
MOVD R12, (2176+32)(R4) |
||||
MOVD a6+48(FP), R12 |
||||
MOVD R12, (2176+40)(R4) |
||||
MOVD a7+56(FP), R12 |
||||
MOVD R12, (2176+48)(R4) |
||||
MOVD a8+64(FP), R12 |
||||
MOVD R12, (2176+56)(R4) |
||||
MOVD a9+72(FP), R12 |
||||
MOVD R12, (2176+64)(R4) |
||||
|
||||
// Call function. |
||||
LE_CALL |
||||
NOPH |
||||
XOR R0, R0 // Restore R0 to $0. |
||||
MOVD R4, 0(R9) // Save stack pointer. |
||||
|
||||
MOVD R3, r1+80(FP) |
||||
MOVD R0, r2+88(FP) |
||||
MOVD R0, err+96(FP) |
||||
MOVW R3, R4 |
||||
CMP R4, $-1 |
||||
BNE done |
||||
BL addrerrno<>(SB) |
||||
MOVWZ 0(R3), R3 |
||||
MOVD R3, err+96(FP) |
||||
done: |
||||
BL runtime·exitsyscall(SB) |
||||
RET |
||||
|
||||
TEXT ·syscall_rawsyscall9(SB),NOSPLIT,$0 |
||||
MOVD a1+8(FP), R1 |
||||
MOVD a2+16(FP), R2 |
||||
MOVD a3+24(FP), R3 |
||||
|
||||
// Get library control area (LCA). |
||||
MOVW PSALAA, R8 |
||||
MOVD LCA64(R8), R8 |
||||
|
||||
// Get function. |
||||
MOVD CAA(R8), R9 |
||||
MOVD EDCHPXV(R9), R9 |
||||
MOVD trap+0(FP), R5 |
||||
SLD $4, R5 |
||||
ADD R5, R9 |
||||
LMG 0(R9), R5, R6 |
||||
|
||||
// Restore LE stack. |
||||
MOVD SAVSTACK_ASYNC(R8), R9 |
||||
MOVD 0(R9), R4 |
||||
MOVD $0, 0(R9) |
||||
|
||||
// Fill in parameter list. |
||||
MOVD a4+32(FP), R12 |
||||
MOVD R12, (2176+24)(R4) |
||||
MOVD a5+40(FP), R12 |
||||
MOVD R12, (2176+32)(R4) |
||||
MOVD a6+48(FP), R12 |
||||
MOVD R12, (2176+40)(R4) |
||||
MOVD a7+56(FP), R12 |
||||
MOVD R12, (2176+48)(R4) |
||||
MOVD a8+64(FP), R12 |
||||
MOVD R12, (2176+56)(R4) |
||||
MOVD a9+72(FP), R12 |
||||
MOVD R12, (2176+64)(R4) |
||||
|
||||
// Call function. |
||||
LE_CALL |
||||
NOPH |
||||
XOR R0, R0 // Restore R0 to $0. |
||||
MOVD R4, 0(R9) // Save stack pointer. |
||||
|
||||
MOVD R3, r1+80(FP) |
||||
MOVD R0, r2+88(FP) |
||||
MOVD R0, err+96(FP) |
||||
MOVW R3, R4 |
||||
CMP R4, $-1 |
||||
BNE done |
||||
BL addrerrno<>(SB) |
||||
MOVWZ 0(R3), R3 |
||||
MOVD R3, err+96(FP) |
||||
done: |
||||
RET |
||||
|
||||
// func svcCall(fnptr unsafe.Pointer, argv *unsafe.Pointer, dsa *uint64) |
||||
TEXT ·svcCall(SB),NOSPLIT,$0 |
||||
BL runtime·save_g(SB) // Save g and stack pointer |
||||
MOVW PSALAA, R8 |
||||
MOVD LCA64(R8), R8 |
||||
MOVD SAVSTACK_ASYNC(R8), R9 |
||||
MOVD R15, 0(R9) |
||||
|
||||
MOVD argv+8(FP), R1 // Move function arguments into registers |
||||
MOVD dsa+16(FP), g |
||||
MOVD fnptr+0(FP), R15 |
||||
|
||||
BYTE $0x0D // Branch to function |
||||
BYTE $0xEF |
||||
|
||||
BL runtime·load_g(SB) // Restore g and stack pointer |
||||
MOVW PSALAA, R8 |
||||
MOVD LCA64(R8), R8 |
||||
MOVD SAVSTACK_ASYNC(R8), R9 |
||||
MOVD 0(R9), R15 |
||||
|
||||
RET |
||||
|
||||
// func svcLoad(name *byte) unsafe.Pointer |
||||
TEXT ·svcLoad(SB),NOSPLIT,$0 |
||||
MOVD R15, R2 // Save go stack pointer |
||||
MOVD name+0(FP), R0 // Move SVC args into registers |
||||
MOVD $0x80000000, R1 |
||||
MOVD $0, R15 |
||||
BYTE $0x0A // SVC 08 LOAD |
||||
BYTE $0x08 |
||||
MOVW R15, R3 // Save return code from SVC |
||||
MOVD R2, R15 // Restore go stack pointer |
||||
CMP R3, $0 // Check SVC return code |
||||
BNE error |
||||
|
||||
MOVD $-2, R3 // Reset last bit of entry point to zero |
||||
AND R0, R3 |
||||
MOVD R3, addr+8(FP) // Return entry point returned by SVC |
||||
CMP R0, R3 // Check if last bit of entry point was set |
||||
BNE done |
||||
|
||||
MOVD R15, R2 // Save go stack pointer |
||||
MOVD $0, R15 // Move SVC args into registers (entry point still in r0 from SVC 08) |
||||
BYTE $0x0A // SVC 09 DELETE |
||||
BYTE $0x09 |
||||
MOVD R2, R15 // Restore go stack pointer |
||||
|
||||
error: |
||||
MOVD $0, addr+8(FP) // Return 0 on failure |
||||
done: |
||||
XOR R0, R0 // Reset r0 to 0 |
||||
RET |
||||
|
||||
// func svcUnload(name *byte, fnptr unsafe.Pointer) int64 |
||||
TEXT ·svcUnload(SB),NOSPLIT,$0 |
||||
MOVD R15, R2 // Save go stack pointer |
||||
MOVD name+0(FP), R0 // Move SVC args into registers |
||||
MOVD addr+8(FP), R15 |
||||
BYTE $0x0A // SVC 09 |
||||
BYTE $0x09 |
||||
XOR R0, R0 // Reset r0 to 0 |
||||
MOVD R15, R1 // Save SVC return code |
||||
MOVD R2, R15 // Restore go stack pointer |
||||
MOVD R1, rc+0(FP) // Return SVC return code |
||||
RET |
||||
|
||||
// func gettid() uint64 |
||||
TEXT ·gettid(SB), NOSPLIT, $0 |
||||
// Get library control area (LCA). |
||||
MOVW PSALAA, R8 |
||||
MOVD LCA64(R8), R8 |
||||
|
||||
// Get CEECAATHDID |
||||
MOVD CAA(R8), R9 |
||||
MOVD 0x3D0(R9), R9 |
||||
MOVD R9, ret+0(FP) |
||||
|
||||
RET |
@ -0,0 +1,29 @@ |
||||
// Copyright 2020 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.
|
||||
|
||||
//go:build zos && s390x
|
||||
// +build zos,s390x
|
||||
|
||||
// Functions to access/create device major and minor numbers matching the
|
||||
// encoding used by z/OS.
|
||||
//
|
||||
// The information below is extracted and adapted from <sys/stat.h> macros.
|
||||
|
||||
package unix |
||||
|
||||
// Major returns the major component of a z/OS device number.
|
||||
func Major(dev uint64) uint32 { |
||||
return uint32((dev >> 16) & 0x0000FFFF) |
||||
} |
||||
|
||||
// Minor returns the minor component of a z/OS device number.
|
||||
func Minor(dev uint64) uint32 { |
||||
return uint32(dev & 0x0000FFFF) |
||||
} |
||||
|
||||
// Mkdev returns a z/OS device number generated from the given major and minor
|
||||
// components.
|
||||
func Mkdev(major, minor uint32) uint64 { |
||||
return (uint64(major) << 16) | uint64(minor) |
||||
} |
@ -0,0 +1,221 @@ |
||||
// Copyright 2020 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.
|
||||
|
||||
//go:build zos && s390x
|
||||
// +build zos,s390x
|
||||
|
||||
package unix |
||||
|
||||
import ( |
||||
"sync" |
||||
) |
||||
|
||||
// This file simulates epoll on z/OS using poll.
|
||||
|
||||
// Analogous to epoll_event on Linux.
|
||||
// TODO(neeilan): Pad is because the Linux kernel expects a 96-bit struct. We never pass this to the kernel; remove?
|
||||
type EpollEvent struct { |
||||
Events uint32 |
||||
Fd int32 |
||||
Pad int32 |
||||
} |
||||
|
||||
const ( |
||||
EPOLLERR = 0x8 |
||||
EPOLLHUP = 0x10 |
||||
EPOLLIN = 0x1 |
||||
EPOLLMSG = 0x400 |
||||
EPOLLOUT = 0x4 |
||||
EPOLLPRI = 0x2 |
||||
EPOLLRDBAND = 0x80 |
||||
EPOLLRDNORM = 0x40 |
||||
EPOLLWRBAND = 0x200 |
||||
EPOLLWRNORM = 0x100 |
||||
EPOLL_CTL_ADD = 0x1 |
||||
EPOLL_CTL_DEL = 0x2 |
||||
EPOLL_CTL_MOD = 0x3 |
||||
// The following constants are part of the epoll API, but represent
|
||||
// currently unsupported functionality on z/OS.
|
||||
// EPOLL_CLOEXEC = 0x80000
|
||||
// EPOLLET = 0x80000000
|
||||
// EPOLLONESHOT = 0x40000000
|
||||
// EPOLLRDHUP = 0x2000 // Typically used with edge-triggered notis
|
||||
// EPOLLEXCLUSIVE = 0x10000000 // Exclusive wake-up mode
|
||||
// EPOLLWAKEUP = 0x20000000 // Relies on Linux's BLOCK_SUSPEND capability
|
||||
) |
||||
|
||||
// TODO(neeilan): We can eliminate these epToPoll / pToEpoll calls by using identical mask values for POLL/EPOLL
|
||||
// constants where possible The lower 16 bits of epoll events (uint32) can fit any system poll event (int16).
|
||||
|
||||
// epToPollEvt converts epoll event field to poll equivalent.
|
||||
// In epoll, Events is a 32-bit field, while poll uses 16 bits.
|
||||
func epToPollEvt(events uint32) int16 { |
||||
var ep2p = map[uint32]int16{ |
||||
EPOLLIN: POLLIN, |
||||
EPOLLOUT: POLLOUT, |
||||
EPOLLHUP: POLLHUP, |
||||
EPOLLPRI: POLLPRI, |
||||
EPOLLERR: POLLERR, |
||||
} |
||||
|
||||
var pollEvts int16 = 0 |
||||
for epEvt, pEvt := range ep2p { |
||||
if (events & epEvt) != 0 { |
||||
pollEvts |= pEvt |
||||
} |
||||
} |
||||
|
||||
return pollEvts |
||||
} |
||||
|
||||
// pToEpollEvt converts 16 bit poll event bitfields to 32-bit epoll event fields.
|
||||
func pToEpollEvt(revents int16) uint32 { |
||||
var p2ep = map[int16]uint32{ |
||||
POLLIN: EPOLLIN, |
||||
POLLOUT: EPOLLOUT, |
||||
POLLHUP: EPOLLHUP, |
||||
POLLPRI: EPOLLPRI, |
||||
POLLERR: EPOLLERR, |
||||
} |
||||
|
||||
var epollEvts uint32 = 0 |
||||
for pEvt, epEvt := range p2ep { |
||||
if (revents & pEvt) != 0 { |
||||
epollEvts |= epEvt |
||||
} |
||||
} |
||||
|
||||
return epollEvts |
||||
} |
||||
|
||||
// Per-process epoll implementation.
|
||||
type epollImpl struct { |
||||
mu sync.Mutex |
||||
epfd2ep map[int]*eventPoll |
||||
nextEpfd int |
||||
} |
||||
|
||||
// eventPoll holds a set of file descriptors being watched by the process. A process can have multiple epoll instances.
|
||||
// On Linux, this is an in-kernel data structure accessed through a fd.
|
||||
type eventPoll struct { |
||||
mu sync.Mutex |
||||
fds map[int]*EpollEvent |
||||
} |
||||
|
||||
// epoll impl for this process.
|
||||
var impl epollImpl = epollImpl{ |
||||
epfd2ep: make(map[int]*eventPoll), |
||||
nextEpfd: 0, |
||||
} |
||||
|
||||
func (e *epollImpl) epollcreate(size int) (epfd int, err error) { |
||||
e.mu.Lock() |
||||
defer e.mu.Unlock() |
||||
epfd = e.nextEpfd |
||||
e.nextEpfd++ |
||||
|
||||
e.epfd2ep[epfd] = &eventPoll{ |
||||
fds: make(map[int]*EpollEvent), |
||||
} |
||||
return epfd, nil |
||||
} |
||||
|
||||
func (e *epollImpl) epollcreate1(flag int) (fd int, err error) { |
||||
return e.epollcreate(4) |
||||
} |
||||
|
||||
func (e *epollImpl) epollctl(epfd int, op int, fd int, event *EpollEvent) (err error) { |
||||
e.mu.Lock() |
||||
defer e.mu.Unlock() |
||||
|
||||
ep, ok := e.epfd2ep[epfd] |
||||
if !ok { |
||||
|
||||
return EBADF |
||||
} |
||||
|
||||
switch op { |
||||
case EPOLL_CTL_ADD: |
||||
// TODO(neeilan): When we make epfds and fds disjoint, detect epoll
|
||||
// loops here (instances watching each other) and return ELOOP.
|
||||
if _, ok := ep.fds[fd]; ok { |
||||
return EEXIST |
||||
} |
||||
ep.fds[fd] = event |
||||
case EPOLL_CTL_MOD: |
||||
if _, ok := ep.fds[fd]; !ok { |
||||
return ENOENT |
||||
} |
||||
ep.fds[fd] = event |
||||
case EPOLL_CTL_DEL: |
||||
if _, ok := ep.fds[fd]; !ok { |
||||
return ENOENT |
||||
} |
||||
delete(ep.fds, fd) |
||||
|
||||
} |
||||
return nil |
||||
} |
||||
|
||||
// Must be called while holding ep.mu
|
||||
func (ep *eventPoll) getFds() []int { |
||||
fds := make([]int, len(ep.fds)) |
||||
for fd := range ep.fds { |
||||
fds = append(fds, fd) |
||||
} |
||||
return fds |
||||
} |
||||
|
||||
func (e *epollImpl) epollwait(epfd int, events []EpollEvent, msec int) (n int, err error) { |
||||
e.mu.Lock() // in [rare] case of concurrent epollcreate + epollwait
|
||||
ep, ok := e.epfd2ep[epfd] |
||||
|
||||
if !ok { |
||||
e.mu.Unlock() |
||||
return 0, EBADF |
||||
} |
||||
|
||||
pollfds := make([]PollFd, 4) |
||||
for fd, epollevt := range ep.fds { |
||||
pollfds = append(pollfds, PollFd{Fd: int32(fd), Events: epToPollEvt(epollevt.Events)}) |
||||
} |
||||
e.mu.Unlock() |
||||
|
||||
n, err = Poll(pollfds, msec) |
||||
if err != nil { |
||||
return n, err |
||||
} |
||||
|
||||
i := 0 |
||||
for _, pFd := range pollfds { |
||||
if pFd.Revents != 0 { |
||||
events[i] = EpollEvent{Fd: pFd.Fd, Events: pToEpollEvt(pFd.Revents)} |
||||
i++ |
||||
} |
||||
|
||||
if i == n { |
||||
break |
||||
} |
||||
} |
||||
|
||||
return n, nil |
||||
} |
||||
|
||||
func EpollCreate(size int) (fd int, err error) { |
||||
return impl.epollcreate(size) |
||||
} |
||||
|
||||
func EpollCreate1(flag int) (fd int, err error) { |
||||
return impl.epollcreate1(flag) |
||||
} |
||||
|
||||
func EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error) { |
||||
return impl.epollctl(epfd, op, fd, event) |
||||
} |
||||
|
||||
// Because EpollWait mutates events, the caller is expected to coordinate
|
||||
// concurrent access if calling with the same epfd from multiple goroutines.
|
||||
func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) { |
||||
return impl.epollwait(epfd, events, msec) |
||||
} |
@ -0,0 +1,164 @@ |
||||
// Copyright 2020 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.
|
||||
|
||||
//go:build zos && s390x
|
||||
// +build zos,s390x
|
||||
|
||||
package unix |
||||
|
||||
import ( |
||||
"unsafe" |
||||
) |
||||
|
||||
// This file simulates fstatfs on z/OS using fstatvfs and w_getmntent.
|
||||
|
||||
func Fstatfs(fd int, stat *Statfs_t) (err error) { |
||||
var stat_v Statvfs_t |
||||
err = Fstatvfs(fd, &stat_v) |
||||
if err == nil { |
||||
// populate stat
|
||||
stat.Type = 0 |
||||
stat.Bsize = stat_v.Bsize |
||||
stat.Blocks = stat_v.Blocks |
||||
stat.Bfree = stat_v.Bfree |
||||
stat.Bavail = stat_v.Bavail |
||||
stat.Files = stat_v.Files |
||||
stat.Ffree = stat_v.Ffree |
||||
stat.Fsid = stat_v.Fsid |
||||
stat.Namelen = stat_v.Namemax |
||||
stat.Frsize = stat_v.Frsize |
||||
stat.Flags = stat_v.Flag |
||||
for passn := 0; passn < 5; passn++ { |
||||
switch passn { |
||||
case 0: |
||||
err = tryGetmntent64(stat) |
||||
break |
||||
case 1: |
||||
err = tryGetmntent128(stat) |
||||
break |
||||
case 2: |
||||
err = tryGetmntent256(stat) |
||||
break |
||||
case 3: |
||||
err = tryGetmntent512(stat) |
||||
break |
||||
case 4: |
||||
err = tryGetmntent1024(stat) |
||||
break |
||||
default: |
||||
break |
||||
} |
||||
//proceed to return if: err is nil (found), err is nonnil but not ERANGE (another error occurred)
|
||||
if err == nil || err != nil && err != ERANGE { |
||||
break |
||||
} |
||||
} |
||||
} |
||||
return err |
||||
} |
||||
|
||||
func tryGetmntent64(stat *Statfs_t) (err error) { |
||||
var mnt_ent_buffer struct { |
||||
header W_Mnth |
||||
filesys_info [64]W_Mntent |
||||
} |
||||
var buffer_size int = int(unsafe.Sizeof(mnt_ent_buffer)) |
||||
fs_count, err := W_Getmntent((*byte)(unsafe.Pointer(&mnt_ent_buffer)), buffer_size) |
||||
if err != nil { |
||||
return err |
||||
} |
||||
err = ERANGE //return ERANGE if no match is found in this batch
|
||||
for i := 0; i < fs_count; i++ { |
||||
if stat.Fsid == uint64(mnt_ent_buffer.filesys_info[i].Dev) { |
||||
stat.Type = uint32(mnt_ent_buffer.filesys_info[i].Fstname[0]) |
||||
err = nil |
||||
break |
||||
} |
||||
} |
||||
return err |
||||
} |
||||
|
||||
func tryGetmntent128(stat *Statfs_t) (err error) { |
||||
var mnt_ent_buffer struct { |
||||
header W_Mnth |
||||
filesys_info [128]W_Mntent |
||||
} |
||||
var buffer_size int = int(unsafe.Sizeof(mnt_ent_buffer)) |
||||
fs_count, err := W_Getmntent((*byte)(unsafe.Pointer(&mnt_ent_buffer)), buffer_size) |
||||
if err != nil { |
||||
return err |
||||
} |
||||
err = ERANGE //return ERANGE if no match is found in this batch
|
||||
for i := 0; i < fs_count; i++ { |
||||
if stat.Fsid == uint64(mnt_ent_buffer.filesys_info[i].Dev) { |
||||
stat.Type = uint32(mnt_ent_buffer.filesys_info[i].Fstname[0]) |
||||
err = nil |
||||
break |
||||
} |
||||
} |
||||
return err |
||||
} |
||||
|
||||
func tryGetmntent256(stat *Statfs_t) (err error) { |
||||
var mnt_ent_buffer struct { |
||||
header W_Mnth |
||||
filesys_info [256]W_Mntent |
||||
} |
||||
var buffer_size int = int(unsafe.Sizeof(mnt_ent_buffer)) |
||||
fs_count, err := W_Getmntent((*byte)(unsafe.Pointer(&mnt_ent_buffer)), buffer_size) |
||||
if err != nil { |
||||
return err |
||||
} |
||||
err = ERANGE //return ERANGE if no match is found in this batch
|
||||
for i := 0; i < fs_count; i++ { |
||||
if stat.Fsid == uint64(mnt_ent_buffer.filesys_info[i].Dev) { |
||||
stat.Type = uint32(mnt_ent_buffer.filesys_info[i].Fstname[0]) |
||||
err = nil |
||||
break |
||||
} |
||||
} |
||||
return err |
||||
} |
||||
|
||||
func tryGetmntent512(stat *Statfs_t) (err error) { |
||||
var mnt_ent_buffer struct { |
||||
header W_Mnth |
||||
filesys_info [512]W_Mntent |
||||
} |
||||
var buffer_size int = int(unsafe.Sizeof(mnt_ent_buffer)) |
||||
fs_count, err := W_Getmntent((*byte)(unsafe.Pointer(&mnt_ent_buffer)), buffer_size) |
||||
if err != nil { |
||||
return err |
||||
} |
||||
err = ERANGE //return ERANGE if no match is found in this batch
|
||||
for i := 0; i < fs_count; i++ { |
||||
if stat.Fsid == uint64(mnt_ent_buffer.filesys_info[i].Dev) { |
||||
stat.Type = uint32(mnt_ent_buffer.filesys_info[i].Fstname[0]) |
||||
err = nil |
||||
break |
||||
} |
||||
} |
||||
return err |
||||
} |
||||
|
||||
func tryGetmntent1024(stat *Statfs_t) (err error) { |
||||
var mnt_ent_buffer struct { |
||||
header W_Mnth |
||||
filesys_info [1024]W_Mntent |
||||
} |
||||
var buffer_size int = int(unsafe.Sizeof(mnt_ent_buffer)) |
||||
fs_count, err := W_Getmntent((*byte)(unsafe.Pointer(&mnt_ent_buffer)), buffer_size) |
||||
if err != nil { |
||||
return err |
||||
} |
||||
err = ERANGE //return ERANGE if no match is found in this batch
|
||||
for i := 0; i < fs_count; i++ { |
||||
if stat.Fsid == uint64(mnt_ent_buffer.filesys_info[i].Dev) { |
||||
stat.Type = uint32(mnt_ent_buffer.filesys_info[i].Fstname[0]) |
||||
err = nil |
||||
break |
||||
} |
||||
} |
||||
return err |
||||
} |
@ -0,0 +1,196 @@ |
||||
// Copyright 2021 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 ( |
||||
"runtime" |
||||
"unsafe" |
||||
) |
||||
|
||||
// IoctlRetInt performs an ioctl operation specified by req on a device
|
||||
// associated with opened file descriptor fd, and returns a non-negative
|
||||
// integer that is returned by the ioctl syscall.
|
||||
func IoctlRetInt(fd int, req uint) (int, error) { |
||||
ret, _, err := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), 0) |
||||
if err != 0 { |
||||
return 0, err |
||||
} |
||||
return int(ret), nil |
||||
} |
||||
|
||||
func IoctlGetUint32(fd int, req uint) (uint32, error) { |
||||
var value uint32 |
||||
err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) |
||||
return value, err |
||||
} |
||||
|
||||
func IoctlGetRTCTime(fd int) (*RTCTime, error) { |
||||
var value RTCTime |
||||
err := ioctl(fd, RTC_RD_TIME, uintptr(unsafe.Pointer(&value))) |
||||
return &value, err |
||||
} |
||||
|
||||
func IoctlSetRTCTime(fd int, value *RTCTime) error { |
||||
err := ioctl(fd, RTC_SET_TIME, uintptr(unsafe.Pointer(value))) |
||||
runtime.KeepAlive(value) |
||||
return err |
||||
} |
||||
|
||||
func IoctlGetRTCWkAlrm(fd int) (*RTCWkAlrm, error) { |
||||
var value RTCWkAlrm |
||||
err := ioctl(fd, RTC_WKALM_RD, uintptr(unsafe.Pointer(&value))) |
||||
return &value, err |
||||
} |
||||
|
||||
func IoctlSetRTCWkAlrm(fd int, value *RTCWkAlrm) error { |
||||
err := ioctl(fd, RTC_WKALM_SET, uintptr(unsafe.Pointer(value))) |
||||
runtime.KeepAlive(value) |
||||
return err |
||||
} |
||||
|
||||
type ifreqEthtool struct { |
||||
name [IFNAMSIZ]byte |
||||
data unsafe.Pointer |
||||
} |
||||
|
||||
// IoctlGetEthtoolDrvinfo fetches ethtool driver information for the network
|
||||
// device specified by ifname.
|
||||
func IoctlGetEthtoolDrvinfo(fd int, ifname string) (*EthtoolDrvinfo, error) { |
||||
// Leave room for terminating NULL byte.
|
||||
if len(ifname) >= IFNAMSIZ { |
||||
return nil, EINVAL |
||||
} |
||||
|
||||
value := EthtoolDrvinfo{ |
||||
Cmd: ETHTOOL_GDRVINFO, |
||||
} |
||||
ifreq := ifreqEthtool{ |
||||
data: unsafe.Pointer(&value), |
||||
} |
||||
copy(ifreq.name[:], ifname) |
||||
err := ioctl(fd, SIOCETHTOOL, uintptr(unsafe.Pointer(&ifreq))) |
||||
runtime.KeepAlive(ifreq) |
||||
return &value, err |
||||
} |
||||
|
||||
// IoctlGetWatchdogInfo fetches information about a watchdog device from the
|
||||
// Linux watchdog API. For more information, see:
|
||||
// https://www.kernel.org/doc/html/latest/watchdog/watchdog-api.html.
|
||||
func IoctlGetWatchdogInfo(fd int) (*WatchdogInfo, error) { |
||||
var value WatchdogInfo |
||||
err := ioctl(fd, WDIOC_GETSUPPORT, uintptr(unsafe.Pointer(&value))) |
||||
return &value, err |
||||
} |
||||
|
||||
// IoctlWatchdogKeepalive issues a keepalive ioctl to a watchdog device. For
|
||||
// more information, see:
|
||||
// https://www.kernel.org/doc/html/latest/watchdog/watchdog-api.html.
|
||||
func IoctlWatchdogKeepalive(fd int) error { |
||||
return ioctl(fd, WDIOC_KEEPALIVE, 0) |
||||
} |
||||
|
||||
// IoctlFileCloneRange performs an FICLONERANGE ioctl operation to clone the
|
||||
// range of data conveyed in value to the file associated with the file
|
||||
// descriptor destFd. See the ioctl_ficlonerange(2) man page for details.
|
||||
func IoctlFileCloneRange(destFd int, value *FileCloneRange) error { |
||||
err := ioctl(destFd, FICLONERANGE, uintptr(unsafe.Pointer(value))) |
||||
runtime.KeepAlive(value) |
||||
return err |
||||
} |
||||
|
||||
// IoctlFileClone performs an FICLONE ioctl operation to clone the entire file
|
||||
// associated with the file description srcFd to the file associated with the
|
||||
// file descriptor destFd. See the ioctl_ficlone(2) man page for details.
|
||||
func IoctlFileClone(destFd, srcFd int) error { |
||||
return ioctl(destFd, FICLONE, uintptr(srcFd)) |
||||
} |
||||
|
||||
type FileDedupeRange struct { |
||||
Src_offset uint64 |
||||
Src_length uint64 |
||||
Reserved1 uint16 |
||||
Reserved2 uint32 |
||||
Info []FileDedupeRangeInfo |
||||
} |
||||
|
||||
type FileDedupeRangeInfo struct { |
||||
Dest_fd int64 |
||||
Dest_offset uint64 |
||||
Bytes_deduped uint64 |
||||
Status int32 |
||||
Reserved uint32 |
||||
} |
||||
|
||||
// IoctlFileDedupeRange performs an FIDEDUPERANGE ioctl operation to share the
|
||||
// range of data conveyed in value from the file associated with the file
|
||||
// descriptor srcFd to the value.Info destinations. See the
|
||||
// ioctl_fideduperange(2) man page for details.
|
||||
func IoctlFileDedupeRange(srcFd int, value *FileDedupeRange) error { |
||||
buf := make([]byte, SizeofRawFileDedupeRange+ |
||||
len(value.Info)*SizeofRawFileDedupeRangeInfo) |
||||
rawrange := (*RawFileDedupeRange)(unsafe.Pointer(&buf[0])) |
||||
rawrange.Src_offset = value.Src_offset |
||||
rawrange.Src_length = value.Src_length |
||||
rawrange.Dest_count = uint16(len(value.Info)) |
||||
rawrange.Reserved1 = value.Reserved1 |
||||
rawrange.Reserved2 = value.Reserved2 |
||||
|
||||
for i := range value.Info { |
||||
rawinfo := (*RawFileDedupeRangeInfo)(unsafe.Pointer( |
||||
uintptr(unsafe.Pointer(&buf[0])) + uintptr(SizeofRawFileDedupeRange) + |
||||
uintptr(i*SizeofRawFileDedupeRangeInfo))) |
||||
rawinfo.Dest_fd = value.Info[i].Dest_fd |
||||
rawinfo.Dest_offset = value.Info[i].Dest_offset |
||||
rawinfo.Bytes_deduped = value.Info[i].Bytes_deduped |
||||
rawinfo.Status = value.Info[i].Status |
||||
rawinfo.Reserved = value.Info[i].Reserved |
||||
} |
||||
|
||||
err := ioctl(srcFd, FIDEDUPERANGE, uintptr(unsafe.Pointer(&buf[0]))) |
||||
|
||||
// Output
|
||||
for i := range value.Info { |
||||
rawinfo := (*RawFileDedupeRangeInfo)(unsafe.Pointer( |
||||
uintptr(unsafe.Pointer(&buf[0])) + uintptr(SizeofRawFileDedupeRange) + |
||||
uintptr(i*SizeofRawFileDedupeRangeInfo))) |
||||
value.Info[i].Dest_fd = rawinfo.Dest_fd |
||||
value.Info[i].Dest_offset = rawinfo.Dest_offset |
||||
value.Info[i].Bytes_deduped = rawinfo.Bytes_deduped |
||||
value.Info[i].Status = rawinfo.Status |
||||
value.Info[i].Reserved = rawinfo.Reserved |
||||
} |
||||
|
||||
return err |
||||
} |
||||
|
||||
func IoctlHIDGetDesc(fd int, value *HIDRawReportDescriptor) error { |
||||
err := ioctl(fd, HIDIOCGRDESC, uintptr(unsafe.Pointer(value))) |
||||
runtime.KeepAlive(value) |
||||
return err |
||||
} |
||||
|
||||
func IoctlHIDGetRawInfo(fd int) (*HIDRawDevInfo, error) { |
||||
var value HIDRawDevInfo |
||||
err := ioctl(fd, HIDIOCGRAWINFO, uintptr(unsafe.Pointer(&value))) |
||||
return &value, err |
||||
} |
||||
|
||||
func IoctlHIDGetRawName(fd int) (string, error) { |
||||
var value [_HIDIOCGRAWNAME_LEN]byte |
||||
err := ioctl(fd, _HIDIOCGRAWNAME, uintptr(unsafe.Pointer(&value[0]))) |
||||
return ByteSliceToString(value[:]), err |
||||
} |
||||
|
||||
func IoctlHIDGetRawPhys(fd int) (string, error) { |
||||
var value [_HIDIOCGRAWPHYS_LEN]byte |
||||
err := ioctl(fd, _HIDIOCGRAWPHYS, uintptr(unsafe.Pointer(&value[0]))) |
||||
return ByteSliceToString(value[:]), err |
||||
} |
||||
|
||||
func IoctlHIDGetRawUniq(fd int) (string, error) { |
||||
var value [_HIDIOCGRAWUNIQ_LEN]byte |
||||
err := ioctl(fd, _HIDIOCGRAWUNIQ, uintptr(unsafe.Pointer(&value[0]))) |
||||
return ByteSliceToString(value[:]), err |
||||
} |
@ -0,0 +1,74 @@ |
||||
// Copyright 2020 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.
|
||||
|
||||
//go:build zos && s390x
|
||||
// +build zos,s390x
|
||||
|
||||
package unix |
||||
|
||||
import ( |
||||
"runtime" |
||||
"unsafe" |
||||
) |
||||
|
||||
// ioctl itself should not be exposed directly, but additional get/set
|
||||
// functions for specific types are permissible.
|
||||
|
||||
// IoctlSetInt performs an ioctl operation which sets an integer value
|
||||
// on fd, using the specified request number.
|
||||
func IoctlSetInt(fd int, req uint, value int) error { |
||||
return ioctl(fd, req, uintptr(value)) |
||||
} |
||||
|
||||
// IoctlSetWinsize performs an ioctl on fd with a *Winsize argument.
|
||||
//
|
||||
// To change fd's window size, the req argument should be TIOCSWINSZ.
|
||||
func IoctlSetWinsize(fd int, req uint, value *Winsize) error { |
||||
// TODO: if we get the chance, remove the req parameter and
|
||||
// hardcode TIOCSWINSZ.
|
||||
err := ioctl(fd, req, uintptr(unsafe.Pointer(value))) |
||||
runtime.KeepAlive(value) |
||||
return err |
||||
} |
||||
|
||||
// IoctlSetTermios performs an ioctl on fd with a *Termios.
|
||||
//
|
||||
// The req value is expected to be TCSETS, TCSETSW, or TCSETSF
|
||||
func IoctlSetTermios(fd int, req uint, value *Termios) error { |
||||
if (req != TCSETS) && (req != TCSETSW) && (req != TCSETSF) { |
||||
return ENOSYS |
||||
} |
||||
err := Tcsetattr(fd, int(req), value) |
||||
runtime.KeepAlive(value) |
||||
return err |
||||
} |
||||
|
||||
// IoctlGetInt performs an ioctl operation which gets an integer value
|
||||
// from fd, using the specified request number.
|
||||
//
|
||||
// A few ioctl requests use the return value as an output parameter;
|
||||
// for those, IoctlRetInt should be used instead of this function.
|
||||
func IoctlGetInt(fd int, req uint) (int, error) { |
||||
var value int |
||||
err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) |
||||
return value, err |
||||
} |
||||
|
||||
func IoctlGetWinsize(fd int, req uint) (*Winsize, error) { |
||||
var value Winsize |
||||
err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) |
||||
return &value, err |
||||
} |
||||
|
||||
// IoctlGetTermios performs an ioctl on fd with a *Termios.
|
||||
//
|
||||
// The req value is expected to be TCGETS
|
||||
func IoctlGetTermios(fd int, req uint) (*Termios, error) { |
||||
var value Termios |
||||
if req != TCGETS { |
||||
return &value, ENOSYS |
||||
} |
||||
err := Tcgetattr(fd, &value) |
||||
return &value, err |
||||
} |
@ -0,0 +1,12 @@ |
||||
// Copyright 2020 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.
|
||||
|
||||
//go:build darwin && !ios
|
||||
// +build darwin,!ios
|
||||
|
||||
package unix |
||||
|
||||
func ptrace(request int, pid int, addr uintptr, data uintptr) error { |
||||
return ptrace1(request, pid, addr, data) |
||||
} |
@ -0,0 +1,12 @@ |
||||
// Copyright 2020 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.
|
||||
|
||||
//go:build ios
|
||||
// +build ios
|
||||
|
||||
package unix |
||||
|
||||
func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) { |
||||
return ENOTSUP |
||||
} |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue