summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd/podman/common/create.go26
-rw-r--r--cmd/podman/common/create_opts.go12
-rw-r--r--cmd/podman/containers/create.go27
-rw-r--r--cmd/podman/images/build.go8
-rw-r--r--cmd/podman/images/pull.go28
-rw-r--r--cmd/podman/manifest/add.go4
-rw-r--r--cmd/podman/manifest/annotate.go4
-rw-r--r--cmd/podman/utils/alias.go6
-rw-r--r--completions/fish/podman-remote.fish30
-rw-r--r--completions/fish/podman.fish30
-rw-r--r--docs/source/Introduction.rst4
-rw-r--r--docs/source/markdown/podman-create.1.md16
-rw-r--r--docs/source/markdown/podman-network-create.1.md3
-rw-r--r--docs/source/markdown/podman-pull.1.md22
-rw-r--r--docs/source/markdown/podman-run.1.md16
-rw-r--r--go.mod4
-rw-r--r--go.sum8
-rw-r--r--libpod/network/create.go9
-rw-r--r--libpod/networking_linux.go14
-rw-r--r--libpod/runtime.go14
-rw-r--r--libpod/shutdown/handler.go10
-rw-r--r--pkg/api/handlers/libpod/images_pull.go18
-rw-r--r--pkg/api/handlers/swagger/swagger.go3
-rw-r--r--pkg/api/server/register_images.go6
-rw-r--r--pkg/api/server/server.go8
-rw-r--r--pkg/bindings/images/types.go12
-rw-r--r--pkg/bindings/images/types_pull_options.go54
-rw-r--r--pkg/domain/entities/images.go12
-rw-r--r--pkg/domain/infra/abi/images.go6
-rw-r--r--pkg/domain/infra/tunnel/images.go4
-rw-r--r--test/e2e/create_test.go12
-rw-r--r--test/e2e/network_create_test.go17
-rw-r--r--test/e2e/pull_test.go10
-rw-r--r--test/e2e/run_test.go2
-rw-r--r--test/system/050-stop.bats43
-rw-r--r--test/system/070-build.bats31
-rw-r--r--test/system/400-unprivileged-access.bats11
-rw-r--r--test/system/410-selinux.bats11
-rw-r--r--test/system/500-networking.bats22
-rw-r--r--vendor/github.com/google/uuid/version4.go8
-rw-r--r--vendor/golang.org/x/crypto/chacha20/chacha_arm64.go2
-rw-r--r--vendor/golang.org/x/crypto/chacha20/chacha_arm64.s2
-rw-r--r--vendor/golang.org/x/crypto/chacha20/chacha_noasm.go2
-rw-r--r--vendor/golang.org/x/crypto/chacha20/chacha_ppc64le.go2
-rw-r--r--vendor/golang.org/x/crypto/chacha20/chacha_ppc64le.s2
-rw-r--r--vendor/golang.org/x/crypto/chacha20/chacha_s390x.go2
-rw-r--r--vendor/golang.org/x/crypto/chacha20/chacha_s390x.s2
-rw-r--r--vendor/golang.org/x/crypto/curve25519/curve25519_amd64.go2
-rw-r--r--vendor/golang.org/x/crypto/curve25519/curve25519_amd64.s2
-rw-r--r--vendor/golang.org/x/crypto/curve25519/curve25519_noasm.go2
-rw-r--r--vendor/golang.org/x/crypto/internal/subtle/aliasing.go2
-rw-r--r--vendor/golang.org/x/crypto/internal/subtle/aliasing_purego.go (renamed from vendor/golang.org/x/crypto/internal/subtle/aliasing_appengine.go)2
-rw-r--r--vendor/golang.org/x/crypto/poly1305/mac_noasm.go2
-rw-r--r--vendor/golang.org/x/crypto/poly1305/sum_amd64.go2
-rw-r--r--vendor/golang.org/x/crypto/poly1305/sum_amd64.s2
-rw-r--r--vendor/golang.org/x/crypto/poly1305/sum_ppc64le.go2
-rw-r--r--vendor/golang.org/x/crypto/poly1305/sum_ppc64le.s2
-rw-r--r--vendor/golang.org/x/crypto/poly1305/sum_s390x.go2
-rw-r--r--vendor/golang.org/x/crypto/poly1305/sum_s390x.s2
-rw-r--r--vendor/golang.org/x/crypto/ssh/client_auth.go2
-rw-r--r--vendor/golang.org/x/crypto/ssh/kex.go13
-rw-r--r--vendor/golang.org/x/crypto/ssh/server.go4
-rw-r--r--vendor/golang.org/x/crypto/ssh/terminal/terminal.go987
-rw-r--r--vendor/golang.org/x/sys/plan9/asm.s8
-rw-r--r--vendor/golang.org/x/sys/plan9/asm_plan9_386.s30
-rw-r--r--vendor/golang.org/x/sys/plan9/asm_plan9_amd64.s30
-rw-r--r--vendor/golang.org/x/sys/plan9/asm_plan9_arm.s25
-rw-r--r--vendor/golang.org/x/sys/plan9/const_plan9.go70
-rw-r--r--vendor/golang.org/x/sys/plan9/dir_plan9.go212
-rw-r--r--vendor/golang.org/x/sys/plan9/env_plan9.go31
-rw-r--r--vendor/golang.org/x/sys/plan9/errors_plan9.go50
-rw-r--r--vendor/golang.org/x/sys/plan9/mkall.sh150
-rw-r--r--vendor/golang.org/x/sys/plan9/mkerrors.sh246
-rw-r--r--vendor/golang.org/x/sys/plan9/mksysnum_plan9.sh23
-rw-r--r--vendor/golang.org/x/sys/plan9/pwd_go15_plan9.go21
-rw-r--r--vendor/golang.org/x/sys/plan9/pwd_plan9.go23
-rw-r--r--vendor/golang.org/x/sys/plan9/race.go30
-rw-r--r--vendor/golang.org/x/sys/plan9/race0.go25
-rw-r--r--vendor/golang.org/x/sys/plan9/str.go22
-rw-r--r--vendor/golang.org/x/sys/plan9/syscall.go116
-rw-r--r--vendor/golang.org/x/sys/plan9/syscall_plan9.go349
-rw-r--r--vendor/golang.org/x/sys/plan9/zsyscall_plan9_386.go284
-rw-r--r--vendor/golang.org/x/sys/plan9/zsyscall_plan9_amd64.go284
-rw-r--r--vendor/golang.org/x/sys/plan9/zsyscall_plan9_arm.go284
-rw-r--r--vendor/golang.org/x/sys/plan9/zsysnum_plan9.go49
-rw-r--r--vendor/golang.org/x/term/AUTHORS3
-rw-r--r--vendor/golang.org/x/term/CONTRIBUTING.md26
-rw-r--r--vendor/golang.org/x/term/CONTRIBUTORS3
-rw-r--r--vendor/golang.org/x/term/LICENSE27
-rw-r--r--vendor/golang.org/x/term/PATENTS22
-rw-r--r--vendor/golang.org/x/term/README.md17
-rw-r--r--vendor/golang.org/x/term/go.mod5
-rw-r--r--vendor/golang.org/x/term/go.sum2
-rw-r--r--vendor/golang.org/x/term/term.go (renamed from vendor/golang.org/x/crypto/ssh/terminal/util_plan9.go)36
-rw-r--r--vendor/golang.org/x/term/term_plan9.go42
-rw-r--r--vendor/golang.org/x/term/term_solaris.go (renamed from vendor/golang.org/x/crypto/ssh/terminal/util_solaris.go)41
-rw-r--r--vendor/golang.org/x/term/term_unix.go (renamed from vendor/golang.org/x/crypto/ssh/terminal/util.go)47
-rw-r--r--vendor/golang.org/x/term/term_unix_aix.go (renamed from vendor/golang.org/x/crypto/ssh/terminal/util_linux.go)4
-rw-r--r--vendor/golang.org/x/term/term_unix_bsd.go (renamed from vendor/golang.org/x/crypto/ssh/terminal/util_bsd.go)2
-rw-r--r--vendor/golang.org/x/term/term_unix_linux.go (renamed from vendor/golang.org/x/crypto/ssh/terminal/util_aix.go)6
-rw-r--r--vendor/golang.org/x/term/term_unix_zos.go10
-rw-r--r--vendor/golang.org/x/term/term_unsupported.go38
-rw-r--r--vendor/golang.org/x/term/term_windows.go (renamed from vendor/golang.org/x/crypto/ssh/terminal/util_windows.go)48
-rw-r--r--vendor/golang.org/x/term/terminal.go987
-rw-r--r--vendor/modules.txt7
105 files changed, 4041 insertions, 1323 deletions
diff --git a/cmd/podman/common/create.go b/cmd/podman/common/create.go
index 17fba5427..915ff63b6 100644
--- a/cmd/podman/common/create.go
+++ b/cmd/podman/common/create.go
@@ -474,29 +474,29 @@ func DefineCreateFlags(cmd *cobra.Command, cf *ContainerCLIOpts) {
)
_ = cmd.RegisterFlagCompletionFunc(oomScoreAdjFlagName, completion.AutocompleteNone)
- overrideArchFlagName := "override-arch"
+ archFlagName := "arch"
createFlags.StringVar(
- &cf.OverrideArch,
- overrideArchFlagName, "",
+ &cf.Arch,
+ archFlagName, "",
"use `ARCH` instead of the architecture of the machine for choosing images",
)
- _ = cmd.RegisterFlagCompletionFunc(overrideArchFlagName, completion.AutocompleteNone)
+ _ = cmd.RegisterFlagCompletionFunc(archFlagName, completion.AutocompleteArch)
- overrideOSFlagName := "override-os"
+ osFlagName := "os"
createFlags.StringVar(
- &cf.OverrideOS,
- overrideOSFlagName, "",
+ &cf.OS,
+ osFlagName, "",
"use `OS` instead of the running OS for choosing images",
)
- _ = cmd.RegisterFlagCompletionFunc(overrideOSFlagName, completion.AutocompleteNone)
+ _ = cmd.RegisterFlagCompletionFunc(osFlagName, completion.AutocompleteOS)
- overrideVariantFlagName := "override-variant"
+ variantFlagName := "variant"
createFlags.StringVar(
- &cf.OverrideVariant,
- overrideVariantFlagName, "",
+ &cf.Variant,
+ variantFlagName, "",
"Use _VARIANT_ instead of the running architecture variant for choosing images",
)
- _ = cmd.RegisterFlagCompletionFunc(overrideVariantFlagName, completion.AutocompleteNone)
+ _ = cmd.RegisterFlagCompletionFunc(variantFlagName, completion.AutocompleteNone)
pidFlagName := "pid"
createFlags.String(
@@ -516,7 +516,7 @@ func DefineCreateFlags(cmd *cobra.Command, cf *ContainerCLIOpts) {
createFlags.StringVar(
&cf.Platform,
platformFlagName, "",
- "Specify the platform for selecting the image. (Conflicts with override-arch and override-os)",
+ "Specify the platform for selecting the image. (Conflicts with --arch and --os)",
)
_ = cmd.RegisterFlagCompletionFunc(platformFlagName, completion.AutocompleteNone)
diff --git a/cmd/podman/common/create_opts.go b/cmd/podman/common/create_opts.go
index f252618ce..a4da8da9e 100644
--- a/cmd/podman/common/create_opts.go
+++ b/cmd/podman/common/create_opts.go
@@ -73,9 +73,9 @@ type ContainerCLIOpts struct {
NoHealthCheck bool
OOMKillDisable bool
OOMScoreAdj int
- OverrideArch string
- OverrideOS string
- OverrideVariant string
+ Arch string
+ OS string
+ Variant string
PID string
PIDsLimit *int64
Platform string
@@ -346,9 +346,9 @@ func ContainerCreateToContainerCLIOpts(cc handlers.CreateContainerConfig, cgroup
LogOptions: stringMaptoArray(cc.HostConfig.LogConfig.Config),
Name: cc.Name,
OOMScoreAdj: cc.HostConfig.OomScoreAdj,
- OverrideArch: "",
- OverrideOS: "",
- OverrideVariant: "",
+ Arch: "",
+ OS: "",
+ Variant: "",
PID: string(cc.HostConfig.PidMode),
PIDsLimit: cc.HostConfig.PidsLimit,
Privileged: cc.HostConfig.Privileged,
diff --git a/cmd/podman/containers/create.go b/cmd/podman/containers/create.go
index 420813ba9..5c6c773eb 100644
--- a/cmd/podman/containers/create.go
+++ b/cmd/podman/containers/create.go
@@ -237,17 +237,20 @@ func pullImage(imageName string) (string, error) {
imageMissing = !br.Value
}
- if cliVals.Platform != "" {
- if cliVals.OverrideArch != "" || cliVals.OverrideOS != "" {
- return "", errors.Errorf("--platform option can not be specified with --override-arch or --override-os")
- }
- split := strings.SplitN(cliVals.Platform, "/", 2)
- cliVals.OverrideOS = split[0]
- if len(split) > 1 {
- cliVals.OverrideArch = split[1]
+ if cliVals.Platform != "" || cliVals.Arch != "" || cliVals.OS != "" {
+ if cliVals.Platform != "" {
+ if cliVals.Arch != "" || cliVals.OS != "" {
+ return "", errors.Errorf("--platform option can not be specified with --arch or --os")
+ }
+ split := strings.SplitN(cliVals.Platform, "/", 2)
+ cliVals.OS = split[0]
+ if len(split) > 1 {
+ cliVals.Arch = split[1]
+ }
}
+
if pullPolicy != config.PullImageAlways {
- logrus.Info("--platform causes the pull policy to be \"always\"")
+ logrus.Info("--platform --arch and --os causes the pull policy to be \"always\"")
pullPolicy = config.PullImageAlways
}
}
@@ -259,9 +262,9 @@ func pullImage(imageName string) (string, error) {
pullReport, pullErr := registry.ImageEngine().Pull(registry.GetContext(), imageName, entities.ImagePullOptions{
Authfile: cliVals.Authfile,
Quiet: cliVals.Quiet,
- OverrideArch: cliVals.OverrideArch,
- OverrideOS: cliVals.OverrideOS,
- OverrideVariant: cliVals.OverrideVariant,
+ Arch: cliVals.Arch,
+ OS: cliVals.OS,
+ Variant: cliVals.Variant,
SignaturePolicy: cliVals.SignaturePolicy,
PullPolicy: pullPolicy,
})
diff --git a/cmd/podman/images/build.go b/cmd/podman/images/build.go
index 1029e03d1..4219e325b 100644
--- a/cmd/podman/images/build.go
+++ b/cmd/podman/images/build.go
@@ -423,10 +423,10 @@ func buildFlagsWrapperToOptions(c *cobra.Command, contextDir string, flags *buil
Ulimit: flags.Ulimit,
Volumes: flags.Volumes,
},
- Compression: compression,
- ConfigureNetwork: networkPolicy,
- ContextDirectory: contextDir,
- // DefaultMountsFilePath: FIXME: this requires global flags to be working!
+ Compression: compression,
+ ConfigureNetwork: networkPolicy,
+ ContextDirectory: contextDir,
+ DefaultMountsFilePath: containerConfig.Containers.DefaultMountsFile,
Devices: flags.Devices,
DropCapabilities: flags.CapDrop,
Err: stderr,
diff --git a/cmd/podman/images/pull.go b/cmd/podman/images/pull.go
index 2d881a906..fe92baebe 100644
--- a/cmd/podman/images/pull.go
+++ b/cmd/podman/images/pull.go
@@ -84,20 +84,20 @@ func pullFlags(cmd *cobra.Command) {
flags.StringVar(&pullOptions.CredentialsCLI, credsFlagName, "", "`Credentials` (USERNAME:PASSWORD) to use for authenticating to a registry")
_ = cmd.RegisterFlagCompletionFunc(credsFlagName, completion.AutocompleteNone)
- overrideArchFlagName := "override-arch"
- flags.StringVar(&pullOptions.OverrideArch, overrideArchFlagName, "", "Use `ARCH` instead of the architecture of the machine for choosing images")
- _ = cmd.RegisterFlagCompletionFunc(overrideArchFlagName, completion.AutocompleteNone)
+ archFlagName := "arch"
+ flags.StringVar(&pullOptions.Arch, archFlagName, "", "Use `ARCH` instead of the architecture of the machine for choosing images")
+ _ = cmd.RegisterFlagCompletionFunc(archFlagName, completion.AutocompleteArch)
- overrideOsFlagName := "override-os"
- flags.StringVar(&pullOptions.OverrideOS, overrideOsFlagName, "", "Use `OS` instead of the running OS for choosing images")
- _ = cmd.RegisterFlagCompletionFunc(overrideOsFlagName, completion.AutocompleteNone)
+ osFlagName := "os"
+ flags.StringVar(&pullOptions.OS, osFlagName, "", "Use `OS` instead of the running OS for choosing images")
+ _ = cmd.RegisterFlagCompletionFunc(osFlagName, completion.AutocompleteOS)
- overrideVariantFlagName := "override-variant"
- flags.StringVar(&pullOptions.OverrideVariant, overrideVariantFlagName, "", " use VARIANT instead of the running architecture variant for choosing images")
- _ = cmd.RegisterFlagCompletionFunc(overrideVariantFlagName, completion.AutocompleteNone)
+ variantFlagName := "variant"
+ flags.StringVar(&pullOptions.Variant, variantFlagName, "", " use VARIANT instead of the running architecture variant for choosing images")
+ _ = cmd.RegisterFlagCompletionFunc(variantFlagName, completion.AutocompleteNone)
platformFlagName := "platform"
- flags.String(platformFlagName, "", "Specify the platform for selecting the image. (Conflicts with override-arch and override-os)")
+ flags.String(platformFlagName, "", "Specify the platform for selecting the image. (Conflicts with arch and os)")
_ = cmd.RegisterFlagCompletionFunc(platformFlagName, completion.AutocompleteNone)
flags.Bool("disable-content-trust", false, "This is a Docker specific option and is a NOOP")
@@ -138,13 +138,13 @@ func imagePull(cmd *cobra.Command, args []string) error {
return err
}
if platform != "" {
- if pullOptions.OverrideArch != "" || pullOptions.OverrideOS != "" {
- return errors.Errorf("--platform option can not be specified with --override-arch or --override-os")
+ if pullOptions.Arch != "" || pullOptions.OS != "" {
+ return errors.Errorf("--platform option can not be specified with --arch or --os")
}
split := strings.SplitN(platform, "/", 2)
- pullOptions.OverrideOS = split[0]
+ pullOptions.OS = split[0]
if len(split) > 1 {
- pullOptions.OverrideArch = split[1]
+ pullOptions.Arch = split[1]
}
}
diff --git a/cmd/podman/manifest/add.go b/cmd/podman/manifest/add.go
index cb0838eeb..b33f01c10 100644
--- a/cmd/podman/manifest/add.go
+++ b/cmd/podman/manifest/add.go
@@ -52,7 +52,7 @@ func init() {
archFlagName := "arch"
flags.StringVar(&manifestAddOpts.Arch, archFlagName, "", "override the `architecture` of the specified image")
- _ = addCmd.RegisterFlagCompletionFunc(archFlagName, completion.AutocompleteNone)
+ _ = addCmd.RegisterFlagCompletionFunc(archFlagName, completion.AutocompleteArch)
authfileFlagName := "authfile"
flags.StringVar(&manifestAddOpts.Authfile, authfileFlagName, auth.GetDefaultAuthFile(), "path of the authentication file. Use REGISTRY_AUTH_FILE environment variable to override")
@@ -72,7 +72,7 @@ func init() {
osFlagName := "os"
flags.StringVar(&manifestAddOpts.OS, osFlagName, "", "override the `OS` of the specified image")
- _ = addCmd.RegisterFlagCompletionFunc(osFlagName, completion.AutocompleteNone)
+ _ = addCmd.RegisterFlagCompletionFunc(osFlagName, completion.AutocompleteOS)
osVersionFlagName := "os-version"
flags.StringVar(&manifestAddOpts.OSVersion, osVersionFlagName, "", "override the OS `version` of the specified image")
diff --git a/cmd/podman/manifest/annotate.go b/cmd/podman/manifest/annotate.go
index 71017e0ec..7c4f5ad01 100644
--- a/cmd/podman/manifest/annotate.go
+++ b/cmd/podman/manifest/annotate.go
@@ -39,7 +39,7 @@ func init() {
archFlagName := "arch"
flags.StringVar(&manifestAnnotateOpts.Arch, archFlagName, "", "override the `architecture` of the specified image")
- _ = annotateCmd.RegisterFlagCompletionFunc(archFlagName, completion.AutocompleteNone)
+ _ = annotateCmd.RegisterFlagCompletionFunc(archFlagName, completion.AutocompleteArch)
featuresFlagName := "features"
flags.StringSliceVar(&manifestAnnotateOpts.Features, featuresFlagName, nil, "override the `features` of the specified image")
@@ -47,7 +47,7 @@ func init() {
osFlagName := "os"
flags.StringVar(&manifestAnnotateOpts.OS, osFlagName, "", "override the `OS` of the specified image")
- _ = annotateCmd.RegisterFlagCompletionFunc(osFlagName, completion.AutocompleteNone)
+ _ = annotateCmd.RegisterFlagCompletionFunc(osFlagName, completion.AutocompleteOS)
osFeaturesFlagName := "os-features"
flags.StringSliceVar(&manifestAnnotateOpts.OSFeatures, osFeaturesFlagName, nil, "override the OS `features` of the specified image")
diff --git a/cmd/podman/utils/alias.go b/cmd/podman/utils/alias.go
index 469233b59..8d089920b 100644
--- a/cmd/podman/utils/alias.go
+++ b/cmd/podman/utils/alias.go
@@ -25,6 +25,12 @@ func AliasFlags(f *pflag.FlagSet, name string) pflag.NormalizedName {
name = "external"
case "purge":
name = "rm"
+ case "override-arch":
+ name = "arch"
+ case "override-os":
+ name = "os"
+ case "override-variant":
+ name = "variant"
}
return pflag.NormalizedName(name)
}
diff --git a/completions/fish/podman-remote.fish b/completions/fish/podman-remote.fish
index e0216844d..b3a4a173a 100644
--- a/completions/fish/podman-remote.fish
+++ b/completions/fish/podman-remote.fish
@@ -10,7 +10,7 @@ end
function __podman_remote_perform_completion
__podman_remote_debug "Starting __podman_remote_perform_completion"
- set args (string split -- " " (commandline -c))
+ set args (string split -- " " (string trim -l (commandline -c)))
set lastArg "$args[-1]"
__podman_remote_debug "args: $args"
@@ -23,16 +23,13 @@ function __podman_remote_perform_completion
end
__podman_remote_debug "emptyArg: $emptyArg"
- if not type -q "$args[1]"
- # This can happen when "complete --do-complete podman-remote" is called when running this script.
- __podman_remote_debug "Cannot find $args[1]. No completions."
- return
- end
-
set requestComp "$args[1] __complete $args[2..-1] $emptyArg"
__podman_remote_debug "Calling $requestComp"
- set results (eval $requestComp 2> /dev/null)
+ # Call the command as a sub-shell so that we can redirect any errors
+ # For example, if $requestComp has an unmatched quote
+ # https://github.com/spf13/cobra/issues/1214
+ set results (fish -c "$requestComp" 2> /dev/null)
set comps $results[1..-2]
set directiveLine $results[-1]
@@ -81,8 +78,6 @@ function __podman_remote_prepare_completions
set shellCompDirectiveNoFileComp 4
set shellCompDirectiveFilterFileExt 8
set shellCompDirectiveFilterDirs 16
- set shellCompDirectiveLegacyCustomComp 32
- set shellCompDirectiveLegacyCustomArgsComp 64
if test -z "$directive"
set directive 0
@@ -95,15 +90,6 @@ function __podman_remote_prepare_completions
return 1
end
- set legacyCustom (math (math --scale 0 $directive / $shellCompDirectiveLegacyCustomComp) % 2)
- set legacyCustomArgs (math (math --scale 0 $directive / $shellCompDirectiveLegacyCustomArgsComp) % 2)
- if test $legacyCustom -eq 1; or test $legacyCustomArgs -eq 1
- __podman_remote_debug "Legacy bash custom completion not applicable to fish"
- # Do full file completion instead
- set --global __podman_remote_comp_do_file_comp 1
- return 1
- end
-
set filefilter (math (math --scale 0 $directive / $shellCompDirectiveFilterFileExt) % 2)
set dirfilter (math (math --scale 0 $directive / $shellCompDirectiveFilterDirs) % 2)
if test $filefilter -eq 1; or test $dirfilter -eq 1
@@ -121,14 +107,14 @@ function __podman_remote_prepare_completions
# we need to count the number of valid completions.
# To do so, we will filter on prefix as the completions we have received
# may not already be filtered so as to allow fish to match on different
- # criteria than prefix.
+ # criteria than the prefix.
if test $nospace -ne 0; or test $nofiles -eq 0
set prefix (commandline -t)
__podman_remote_debug "prefix: $prefix"
set completions
for comp in $__podman_remote_comp_results
- if test (string match -e -r "^$prefix" "$comp")
+ if test (string match -e -r -- "^$prefix" "$comp")
set -a completions $comp
end
end
@@ -166,7 +152,7 @@ end
# Since Fish completions are only loaded once the user triggers them, we trigger them ourselves
# so we can properly delete any completions provided by another script.
-# The space after the the program name is essential to trigger completion for the program
+# The space after the program name is essential to trigger completion for the program
# and not completion of the program name itself.
complete --do-complete "podman-remote " > /dev/null 2>&1
# Using '> /dev/null 2>&1' since '&>' is not supported in older versions of fish.
diff --git a/completions/fish/podman.fish b/completions/fish/podman.fish
index 2a89e7118..05dd2d72b 100644
--- a/completions/fish/podman.fish
+++ b/completions/fish/podman.fish
@@ -10,7 +10,7 @@ end
function __podman_perform_completion
__podman_debug "Starting __podman_perform_completion"
- set args (string split -- " " (commandline -c))
+ set args (string split -- " " (string trim -l (commandline -c)))
set lastArg "$args[-1]"
__podman_debug "args: $args"
@@ -23,16 +23,13 @@ function __podman_perform_completion
end
__podman_debug "emptyArg: $emptyArg"
- if not type -q "$args[1]"
- # This can happen when "complete --do-complete podman" is called when running this script.
- __podman_debug "Cannot find $args[1]. No completions."
- return
- end
-
set requestComp "$args[1] __complete $args[2..-1] $emptyArg"
__podman_debug "Calling $requestComp"
- set results (eval $requestComp 2> /dev/null)
+ # Call the command as a sub-shell so that we can redirect any errors
+ # For example, if $requestComp has an unmatched quote
+ # https://github.com/spf13/cobra/issues/1214
+ set results (fish -c "$requestComp" 2> /dev/null)
set comps $results[1..-2]
set directiveLine $results[-1]
@@ -81,8 +78,6 @@ function __podman_prepare_completions
set shellCompDirectiveNoFileComp 4
set shellCompDirectiveFilterFileExt 8
set shellCompDirectiveFilterDirs 16
- set shellCompDirectiveLegacyCustomComp 32
- set shellCompDirectiveLegacyCustomArgsComp 64
if test -z "$directive"
set directive 0
@@ -95,15 +90,6 @@ function __podman_prepare_completions
return 1
end
- set legacyCustom (math (math --scale 0 $directive / $shellCompDirectiveLegacyCustomComp) % 2)
- set legacyCustomArgs (math (math --scale 0 $directive / $shellCompDirectiveLegacyCustomArgsComp) % 2)
- if test $legacyCustom -eq 1; or test $legacyCustomArgs -eq 1
- __podman_debug "Legacy bash custom completion not applicable to fish"
- # Do full file completion instead
- set --global __podman_comp_do_file_comp 1
- return 1
- end
-
set filefilter (math (math --scale 0 $directive / $shellCompDirectiveFilterFileExt) % 2)
set dirfilter (math (math --scale 0 $directive / $shellCompDirectiveFilterDirs) % 2)
if test $filefilter -eq 1; or test $dirfilter -eq 1
@@ -121,14 +107,14 @@ function __podman_prepare_completions
# we need to count the number of valid completions.
# To do so, we will filter on prefix as the completions we have received
# may not already be filtered so as to allow fish to match on different
- # criteria than prefix.
+ # criteria than the prefix.
if test $nospace -ne 0; or test $nofiles -eq 0
set prefix (commandline -t)
__podman_debug "prefix: $prefix"
set completions
for comp in $__podman_comp_results
- if test (string match -e -r "^$prefix" "$comp")
+ if test (string match -e -r -- "^$prefix" "$comp")
set -a completions $comp
end
end
@@ -166,7 +152,7 @@ end
# Since Fish completions are only loaded once the user triggers them, we trigger them ourselves
# so we can properly delete any completions provided by another script.
-# The space after the the program name is essential to trigger completion for the program
+# The space after the program name is essential to trigger completion for the program
# and not completion of the program name itself.
complete --do-complete "podman " > /dev/null 2>&1
# Using '> /dev/null 2>&1' since '&>' is not supported in older versions of fish.
diff --git a/docs/source/Introduction.rst b/docs/source/Introduction.rst
index 9dcae8a83..9fdce6962 100644
--- a/docs/source/Introduction.rst
+++ b/docs/source/Introduction.rst
@@ -34,7 +34,7 @@ Sometimes we can find a publicly available container image for the exact workloa
Container Images aren’t actually images, they’re repositories often made up of multiple layers. These layers can easily be added, saved, and shared with others by using a Containerfile (Dockerfile). This single file often contains all the instructions needed to build the new and can easily be shared with others publicly using tools like GitHub.
-Here's an example of how to build an Nginx web server on top of a Debian base image using the Dockerfile maintained by Nginx and published in GitHub::
+Here's an example of how to build a Nginx web server on top of a Debian base image using the Dockerfile maintained by Nginx and published in GitHub::
podman build -t nginx https://git.io/Jf8ol
@@ -62,7 +62,7 @@ Input::
Password: ********
Login Succeeded!
-Nex, tag the image so that we can push it into our user account::
+Next, tag the image so that we can push it into our user account::
podman tag localhost/nginx quay.io/USERNAME/nginx
diff --git a/docs/source/markdown/podman-create.1.md b/docs/source/markdown/podman-create.1.md
index 35d8474a6..b3ac8b6ee 100644
--- a/docs/source/markdown/podman-create.1.md
+++ b/docs/source/markdown/podman-create.1.md
@@ -77,6 +77,9 @@ option can be set multiple times.
Add an annotation to the container. The format is key=value.
The **--annotation** option can be set multiple times.
+#### **--arch**=*ARCH*
+Override the architecture, defaults to hosts, of the image to be pulled. For example, `arm`.
+
#### **--attach**, **-a**=*location*
Attach to STDIN, STDOUT or STDERR.
@@ -667,15 +670,9 @@ Whether to disable OOM Killer for the container or not.
Tune the host's OOM preferences for containers (accepts -1000 to 1000)
-#### **--override-arch**=*ARCH*
-Override the architecture, defaults to hosts, of the image to be pulled. For example, `arm`.
-
-#### **--override-os**=*OS*
+#### **--os**=*OS*
Override the OS, defaults to hosts, of the image to be pulled. For example, `windows`.
-#### **--override-variant**=*VARIANT*
-Use _VARIANT_ instead of the default architecture variant of the container image. Some images can use multiple variants of the arm architectures, such as arm/v5 and arm/v7.
-
#### **--pid**=*pid*
Set the PID mode for the container
@@ -691,7 +688,7 @@ Tune the container's pids limit. Set `0` to have unlimited pids for the containe
#### **--platform**=*OS/ARCH*
-Specify the platform for selecting the image. (Conflicts with override-arch and override-os)
+Specify the platform for selecting the image. (Conflicts with --arch and --os)
The `--platform` option can be used to override the current architecture and operating system.
#### **--pod**=*name*
@@ -1007,6 +1004,9 @@ Set the UTS namespace mode for the container. The following values are supported
- **ns:[path]**: run the container in the given existing UTS namespace.
- **container:[container]**: join the UTS namespace of the specified container.
+#### **--variant**=*VARIANT*
+Use _VARIANT_ instead of the default architecture variant of the container image. Some images can use multiple variants of the arm architectures, such as arm/v5 and arm/v7.
+
#### **--volume**, **-v**[=*[[SOURCE-VOLUME|HOST-DIR:]CONTAINER-DIR[:OPTIONS]]*]
Create a bind mount. If you specify, ` -v /HOST-DIR:/CONTAINER-DIR`, Podman
diff --git a/docs/source/markdown/podman-network-create.1.md b/docs/source/markdown/podman-network-create.1.md
index 16e4e3bdb..2fafd1e31 100644
--- a/docs/source/markdown/podman-network-create.1.md
+++ b/docs/source/markdown/podman-network-create.1.md
@@ -41,7 +41,8 @@ Define a gateway for the subnet. If you want to provide a gateway address, you m
#### **--internal**
-Restrict external access of this network
+Restrict external access of this network. Note when using this option, the dnsname plugin will be
+automatically disabled.
#### **--ip-range**
diff --git a/docs/source/markdown/podman-pull.1.md b/docs/source/markdown/podman-pull.1.md
index 44a7e83b6..af91a59e9 100644
--- a/docs/source/markdown/podman-pull.1.md
+++ b/docs/source/markdown/podman-pull.1.md
@@ -71,6 +71,9 @@ All tagged images in the repository will be pulled.
Note: When using the all-tags flag, Podman will not iterate over the search registries in the containers-registries.conf(5) but will always use docker.io for unqualified image names.
+#### **--arch**=*ARCH*
+Override the architecture, defaults to hosts, of the image to be pulled. For example, `arm`.
+
#### **--authfile**=*path*
Path of the authentication file. Default is ${XDG\_RUNTIME\_DIR}/containers/auth.json, which is set using `podman login`.
@@ -96,19 +99,16 @@ This is a Docker specific option to disable image verification to a Docker
registry and is not supported by Podman. This flag is a NOOP and provided
solely for scripting compatibility.
-#### **--override-arch**=*ARCH*
-Override the architecture, defaults to hosts, of the image to be pulled. For example, `arm`.
-
-#### **--override-os**=*OS*
-Override the OS, defaults to hosts, of the image to be pulled. For example, `windows`.
+#### **--help**, **-h**
-#### **--override-variant**=*VARIANT*
+Print usage statement
-Use _VARIANT_ instead of the default architecture variant of the container image. Some images can use multiple variants of the arm architectures, such as arm/v5 and arm/v7.
+#### **--os**=*OS*
+Override the OS, defaults to hosts, of the image to be pulled. For example, `windows`.
#### **--platform**=*OS/ARCH*
-Specify the platform for selecting the image. (Conflicts with override-arch and override-os)
+Specify the platform for selecting the image. (Conflicts with --arch and --os)
The `--platform` option can be used to override the current architecture and operating system.
#### **--quiet**, **-q**
@@ -121,9 +121,9 @@ Require HTTPS and verify certificates when contacting registries (default: true)
then TLS verification will be used. If set to false, then TLS verification will not be used. If not specified,
TLS verification will be used unless the target registry is listed as an insecure registry in registries.conf.
-#### **--help**, **-h**
+#### **--variant**=*VARIANT*
-Print usage statement
+Use _VARIANT_ instead of the default architecture variant of the container image. Some images can use multiple variants of the arm architectures, such as arm/v5 and arm/v7.
## EXAMPLES
@@ -189,7 +189,7 @@ Storing signatures
```
```
-$ podman pull --override-arch=arm arm32v7/debian:stretch
+$ podman pull --arch=arm arm32v7/debian:stretch
Trying to pull docker.io/arm32v7/debian:stretch...
Getting image source signatures
Copying blob b531ae4a3925 done
diff --git a/docs/source/markdown/podman-run.1.md b/docs/source/markdown/podman-run.1.md
index 89f05c308..e606c456f 100644
--- a/docs/source/markdown/podman-run.1.md
+++ b/docs/source/markdown/podman-run.1.md
@@ -93,6 +93,9 @@ This option can be set multiple times.
Add an annotation to the container.
This option can be set multiple times.
+#### **--arch**=*ARCH*
+Override the architecture, defaults to hosts, of the image to be pulled. For example, `arm`.
+
#### **--attach**, **-a**=**stdin**|**stdout**|**stderr**
Attach to STDIN, STDOUT or STDERR.
@@ -704,15 +707,9 @@ Whether to disable OOM Killer for the container or not.
Tune the host's OOM preferences for containers (accepts values from **-1000** to **1000**).
-#### **--override-arch**=*ARCH*
-Override the architecture, defaults to hosts, of the image to be pulled. For example, `arm`.
-
-#### **--override-os**=*OS*
+#### **--os**=*OS*
Override the OS, defaults to hosts, of the image to be pulled. For example, `windows`.
-#### **--override-variant**=*VARIANT*
-Use _VARIANT_ instead of the default architecture variant of the container image. Some images can use multiple variants of the arm architectures, such as arm/v5 and arm/v7.
-
#### **--pid**=*mode*
Set the PID namespace mode for the container.
@@ -729,7 +726,7 @@ Tune the container's pids limit. Set to **0** to have unlimited pids for the con
#### **--platform**=*OS/ARCH*
-Specify the platform for selecting the image. (Conflicts with override-arch and override-os)
+Specify the platform for selecting the image. (Conflicts with --arch and --os)
The `--platform` option can be used to override the current architecture and operating system.
#### **--pod**=*name*
@@ -1082,6 +1079,9 @@ Set the UTS namespace mode for the container. The following values are supported
- **ns:[path]**: run the container in the given existing UTS namespace.
- **container:[container]**: join the UTS namespace of the specified container.
+#### **--variant**=*VARIANT*
+Use _VARIANT_ instead of the default architecture variant of the container image. Some images can use multiple variants of the arm architectures, such as arm/v5 and arm/v7.
+
#### **--volume**, **-v**[=*[[SOURCE-VOLUME|HOST-DIR:]CONTAINER-DIR[:OPTIONS]]*]
Create a bind mount. If you specify _/HOST-DIR_:_/CONTAINER-DIR_, Podman
diff --git a/go.mod b/go.mod
index ad9571876..1f8ad9ece 100644
--- a/go.mod
+++ b/go.mod
@@ -29,7 +29,7 @@ require (
github.com/ghodss/yaml v1.0.0
github.com/godbus/dbus/v5 v5.0.3
github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf
- github.com/google/uuid v1.1.5
+ github.com/google/uuid v1.2.0
github.com/gorilla/mux v1.8.0
github.com/gorilla/schema v1.2.0
github.com/hashicorp/go-multierror v1.1.0
@@ -60,7 +60,7 @@ require (
github.com/vishvananda/netlink v1.1.1-0.20201029203352-d40f9887b852
go.etcd.io/bbolt v1.3.5
go.uber.org/atomic v1.7.0 // indirect
- golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899
+ golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d // indirect
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4
diff --git a/go.sum b/go.sum
index c3eba0640..5bbd30ba3 100644
--- a/go.sum
+++ b/go.sum
@@ -263,6 +263,8 @@ github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.5 h1:kxhtnfFVi+rYdOALN0B3k9UT86zVJKfBimRaciULW4I=
github.com/google/uuid v1.1.5/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs=
+github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
@@ -622,8 +624,8 @@ golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20200423211502-4bdfaf469ed5/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200429183012-4b2356b1ed79/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899 h1:DZhuSZLsGlFL4CmhA8BcRA0mnthyA/nZ00AqCUo7vHg=
-golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad h1:DN0cp81fZ3njFcrLCytUHRSUkqBjfTo4Tx9RJTWs0EY=
+golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -744,6 +746,8 @@ golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3 h1:kzM6+9dur93BcC2kVlYl34cHU
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4 h1:myAQVi0cGEoqQVR5POX+8RR2mrocKqNN1hmeMqhX27k=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
+golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
diff --git a/libpod/network/create.go b/libpod/network/create.go
index e7f65358b..a8f985af9 100644
--- a/libpod/network/create.go
+++ b/libpod/network/create.go
@@ -14,6 +14,7 @@ import (
"github.com/containers/podman/v2/pkg/rootless"
"github.com/containers/podman/v2/pkg/util"
"github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
)
// Create the CNI network
@@ -226,8 +227,12 @@ func createBridge(name string, options entities.NetworkCreateOptions, runtimeCon
// if we find the dnsname plugin or are rootless, we add configuration for it
// the rootless-cni-infra container has the dnsname plugin always installed
if (HasDNSNamePlugin(runtimeConfig.Network.CNIPluginDirs) || rootless.IsRootless()) && !options.DisableDNS {
- // Note: in the future we might like to allow for dynamic domain names
- plugins = append(plugins, NewDNSNamePlugin(DefaultPodmanDomainName))
+ if options.Internal {
+ logrus.Warnf("dnsname and --internal networks are incompatible. dnsname plugin not configured for network %s", name)
+ } else {
+ // Note: in the future we might like to allow for dynamic domain names
+ plugins = append(plugins, NewDNSNamePlugin(DefaultPodmanDomainName))
+ }
}
ncList["plugins"] = plugins
b, err := json.MarshalIndent(ncList, "", " ")
diff --git a/libpod/networking_linux.go b/libpod/networking_linux.go
index 09fdea496..ef2f034ab 100644
--- a/libpod/networking_linux.go
+++ b/libpod/networking_linux.go
@@ -550,13 +550,25 @@ func (r *Runtime) setupRootlessPortMappingViaRLK(ctr *Container, netnsPath strin
}
}
+ childIP := slirp4netnsIP
+outer:
+ for _, r := range ctr.state.NetworkStatus {
+ for _, i := range r.IPs {
+ ipv4 := i.Address.IP.To4()
+ if ipv4 != nil {
+ childIP = ipv4.String()
+ break outer
+ }
+ }
+ }
+
cfg := rootlessport.Config{
Mappings: ctr.config.PortMappings,
NetNSPath: netnsPath,
ExitFD: 3,
ReadyFD: 4,
TmpDir: ctr.runtime.config.Engine.TmpDir,
- ChildIP: slirp4netnsIP,
+ ChildIP: childIP,
}
cfgJSON, err := json.Marshal(cfg)
if err != nil {
diff --git a/libpod/runtime.go b/libpod/runtime.go
index 34c737a67..0dc220b52 100644
--- a/libpod/runtime.go
+++ b/libpod/runtime.go
@@ -180,6 +180,13 @@ func newRuntimeFromConfig(ctx context.Context, conf *config.Config, options ...R
}
}
+ if err := shutdown.Register("libpod", func(sig os.Signal) error {
+ os.Exit(1)
+ return nil
+ }); err != nil && errors.Cause(err) != shutdown.ErrHandlerExists {
+ logrus.Errorf("Error registering shutdown handler for libpod: %v", err)
+ }
+
if err := shutdown.Start(); err != nil {
return nil, errors.Wrapf(err, "error starting shutdown signal handler")
}
@@ -188,13 +195,6 @@ func newRuntimeFromConfig(ctx context.Context, conf *config.Config, options ...R
return nil, err
}
- if err := shutdown.Register("libpod", func(sig os.Signal) error {
- os.Exit(1)
- return nil
- }); err != nil && errors.Cause(err) != shutdown.ErrHandlerExists {
- logrus.Errorf("Error registering shutdown handler for libpod: %v", err)
- }
-
return runtime, nil
}
diff --git a/libpod/shutdown/handler.go b/libpod/shutdown/handler.go
index f0f228b19..ac1d33910 100644
--- a/libpod/shutdown/handler.go
+++ b/libpod/shutdown/handler.go
@@ -18,6 +18,8 @@ var (
stopped bool
sigChan chan os.Signal
cancelChan chan bool
+ // Syncronize accesses to the map
+ handlerLock sync.Mutex
// Definitions of all on-shutdown handlers
handlers map[string]func(os.Signal) error
// Ordering that on-shutdown handlers will be invoked.
@@ -50,6 +52,7 @@ func Start() error {
case sig := <-sigChan:
logrus.Infof("Received shutdown signal %v, terminating!", sig)
shutdownInhibit.Lock()
+ handlerLock.Lock()
for _, name := range handlerOrder {
handler, ok := handlers[name]
if !ok {
@@ -61,6 +64,7 @@ func Start() error {
logrus.Errorf("Error running shutdown handler %s: %v", name, err)
}
}
+ handlerLock.Unlock()
shutdownInhibit.Unlock()
return
}
@@ -97,6 +101,9 @@ func Uninhibit() {
// by a signal. Handlers are invoked LIFO - the last handler registered is the
// first run.
func Register(name string, handler func(os.Signal) error) error {
+ handlerLock.Lock()
+ defer handlerLock.Unlock()
+
if handlers == nil {
handlers = make(map[string]func(os.Signal) error)
}
@@ -113,6 +120,9 @@ func Register(name string, handler func(os.Signal) error) error {
// Unregister un-registers a given shutdown handler.
func Unregister(name string) error {
+ handlerLock.Lock()
+ defer handlerLock.Unlock()
+
if handlers == nil {
return nil
}
diff --git a/pkg/api/handlers/libpod/images_pull.go b/pkg/api/handlers/libpod/images_pull.go
index bacba006d..efb15b14d 100644
--- a/pkg/api/handlers/libpod/images_pull.go
+++ b/pkg/api/handlers/libpod/images_pull.go
@@ -30,12 +30,12 @@ func ImagesPull(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value("runtime").(*libpod.Runtime)
decoder := r.Context().Value("decoder").(*schema.Decoder)
query := struct {
- Reference string `schema:"reference"`
- OverrideOS string `schema:"overrideOS"`
- OverrideArch string `schema:"overrideArch"`
- OverrideVariant string `schema:"overrideVariant"`
- TLSVerify bool `schema:"tlsVerify"`
- AllTags bool `schema:"allTags"`
+ Reference string `schema:"reference"`
+ OS string `schema:"OS"`
+ Arch string `schema:"Arch"`
+ Variant string `schema:"Variant"`
+ TLSVerify bool `schema:"tlsVerify"`
+ AllTags bool `schema:"allTags"`
}{
TLSVerify: true,
}
@@ -83,9 +83,9 @@ func ImagesPull(w http.ResponseWriter, r *http.Request) {
// Setup the registry options
dockerRegistryOptions := image.DockerRegistryOptions{
DockerRegistryCreds: authConf,
- OSChoice: query.OverrideOS,
- ArchitectureChoice: query.OverrideArch,
- VariantChoice: query.OverrideVariant,
+ OSChoice: query.OS,
+ ArchitectureChoice: query.Arch,
+ VariantChoice: query.Variant,
}
if _, found := r.URL.Query()["tlsVerify"]; found {
dockerRegistryOptions.DockerInsecureSkipTLSVerify = types.NewOptionalBool(!query.TLSVerify)
diff --git a/pkg/api/handlers/swagger/swagger.go b/pkg/api/handlers/swagger/swagger.go
index 22670d795..32f041dd3 100644
--- a/pkg/api/handlers/swagger/swagger.go
+++ b/pkg/api/handlers/swagger/swagger.go
@@ -1,7 +1,6 @@
package swagger
import (
- "github.com/containers/podman/v2/libpod"
"github.com/containers/podman/v2/libpod/define"
"github.com/containers/podman/v2/libpod/image"
"github.com/containers/podman/v2/pkg/api/handlers"
@@ -166,7 +165,7 @@ type swagInspectPodResponse struct {
type swagInspectVolumeResponse struct {
// in:body
Body struct {
- libpod.InspectVolumeData
+ define.InspectVolumeData
}
}
diff --git a/pkg/api/server/register_images.go b/pkg/api/server/register_images.go
index 974dd287b..a7d350d50 100644
--- a/pkg/api/server/register_images.go
+++ b/pkg/api/server/register_images.go
@@ -930,15 +930,15 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
// description: "username:password for the registry"
// type: string
// - in: query
- // name: overrideArch
+ // name: Arch
// description: Pull image for the specified architecture.
// type: string
// - in: query
- // name: overrideOS
+ // name: OS
// description: Pull image for the specified operating system.
// type: string
// - in: query
- // name: overrideVariant
+ // name: Variant
// description: Pull image for the specified variant.
// type: string
// - in: query
diff --git a/pkg/api/server/server.go b/pkg/api/server/server.go
index 046f6561c..d612041f6 100644
--- a/pkg/api/server/server.go
+++ b/pkg/api/server/server.go
@@ -179,15 +179,15 @@ func setupSystemd() {
func (s *APIServer) Serve() error {
setupSystemd()
- // Start the shutdown signal handler.
- if err := shutdown.Start(); err != nil {
- return err
- }
if err := shutdown.Register("server", func(sig os.Signal) error {
return s.Shutdown()
}); err != nil {
return err
}
+ // Start the shutdown signal handler.
+ if err := shutdown.Start(); err != nil {
+ return err
+ }
errChan := make(chan error, 1)
diff --git a/pkg/bindings/images/types.go b/pkg/bindings/images/types.go
index f216dd073..0248f2fa6 100644
--- a/pkg/bindings/images/types.go
+++ b/pkg/bindings/images/types.go
@@ -171,13 +171,13 @@ type PullOptions struct {
Username *string
// Password for authenticating against the registry.
Password *string
- // OverrideArch will overwrite the local architecture for image pulls.
- OverrideArch *string
- // OverrideOS will overwrite the local operating system (OS) for image
+ // Arch will overwrite the local architecture for image pulls.
+ Arch *string
+ // OS will overwrite the local operating system (OS) for image
// pulls.
- OverrideOS *string
- // OverrideVariant will overwrite the local variant for image pulls.
- OverrideVariant *string
+ OS *string
+ // Variant will overwrite the local variant for image pulls.
+ Variant *string
// Quiet can be specified to suppress pull progress when pulling. Ignored
// for remote calls.
Quiet *bool
diff --git a/pkg/bindings/images/types_pull_options.go b/pkg/bindings/images/types_pull_options.go
index 5163a6341..2bdf2b66e 100644
--- a/pkg/bindings/images/types_pull_options.go
+++ b/pkg/bindings/images/types_pull_options.go
@@ -168,52 +168,52 @@ func (o *PullOptions) GetPassword() string {
return *o.Password
}
-// WithOverrideArch
-func (o *PullOptions) WithOverrideArch(value string) *PullOptions {
+// WithArch
+func (o *PullOptions) WithArch(value string) *PullOptions {
v := &value
- o.OverrideArch = v
+ o.Arch = v
return o
}
-// GetOverrideArch
-func (o *PullOptions) GetOverrideArch() string {
- var overrideArch string
- if o.OverrideArch == nil {
- return overrideArch
+// GetArch
+func (o *PullOptions) GetArch() string {
+ var arch string
+ if o.Arch == nil {
+ return arch
}
- return *o.OverrideArch
+ return *o.Arch
}
-// WithOverrideOS
-func (o *PullOptions) WithOverrideOS(value string) *PullOptions {
+// WithOS
+func (o *PullOptions) WithOS(value string) *PullOptions {
v := &value
- o.OverrideOS = v
+ o.OS = v
return o
}
-// GetOverrideOS
-func (o *PullOptions) GetOverrideOS() string {
- var overrideOS string
- if o.OverrideOS == nil {
- return overrideOS
+// GetOS
+func (o *PullOptions) GetOS() string {
+ var oS string
+ if o.OS == nil {
+ return oS
}
- return *o.OverrideOS
+ return *o.OS
}
-// WithOverrideVariant
-func (o *PullOptions) WithOverrideVariant(value string) *PullOptions {
+// WithVariant
+func (o *PullOptions) WithVariant(value string) *PullOptions {
v := &value
- o.OverrideVariant = v
+ o.Variant = v
return o
}
-// GetOverrideVariant
-func (o *PullOptions) GetOverrideVariant() string {
- var overrideVariant string
- if o.OverrideVariant == nil {
- return overrideVariant
+// GetVariant
+func (o *PullOptions) GetVariant() string {
+ var variant string
+ if o.Variant == nil {
+ return variant
}
- return *o.OverrideVariant
+ return *o.Variant
}
// WithQuiet
diff --git a/pkg/domain/entities/images.go b/pkg/domain/entities/images.go
index 78a7d8aa7..ef40d5490 100644
--- a/pkg/domain/entities/images.go
+++ b/pkg/domain/entities/images.go
@@ -133,13 +133,13 @@ type ImagePullOptions struct {
Username string
// Password for authenticating against the registry.
Password string
- // OverrideArch will overwrite the local architecture for image pulls.
- OverrideArch string
- // OverrideOS will overwrite the local operating system (OS) for image
+ // Arch will overwrite the local architecture for image pulls.
+ Arch string
+ // OS will overwrite the local operating system (OS) for image
// pulls.
- OverrideOS string
- // OverrideVariant will overwrite the local variant for image pulls.
- OverrideVariant string
+ OS string
+ // Variant will overwrite the local variant for image pulls.
+ Variant string
// Quiet can be specified to suppress pull progress when pulling. Ignored
// for remote calls.
Quiet bool
diff --git a/pkg/domain/infra/abi/images.go b/pkg/domain/infra/abi/images.go
index 1288ab09b..8ca93e770 100644
--- a/pkg/domain/infra/abi/images.go
+++ b/pkg/domain/infra/abi/images.go
@@ -241,9 +241,9 @@ func pull(ctx context.Context, runtime *image.Runtime, rawImage string, options
dockerRegistryOptions := image.DockerRegistryOptions{
DockerRegistryCreds: registryCreds,
DockerCertPath: options.CertDir,
- OSChoice: options.OverrideOS,
- ArchitectureChoice: options.OverrideArch,
- VariantChoice: options.OverrideVariant,
+ OSChoice: options.OS,
+ ArchitectureChoice: options.Arch,
+ VariantChoice: options.Variant,
DockerInsecureSkipTLSVerify: options.SkipTLSVerify,
}
diff --git a/pkg/domain/infra/tunnel/images.go b/pkg/domain/infra/tunnel/images.go
index 2d686b2aa..0de756756 100644
--- a/pkg/domain/infra/tunnel/images.go
+++ b/pkg/domain/infra/tunnel/images.go
@@ -106,8 +106,8 @@ func (ir *ImageEngine) Prune(ctx context.Context, opts entities.ImagePruneOption
func (ir *ImageEngine) Pull(ctx context.Context, rawImage string, opts entities.ImagePullOptions) (*entities.ImagePullReport, error) {
options := new(images.PullOptions)
- options.WithAllTags(opts.AllTags).WithAuthfile(opts.Authfile).WithCertDir(opts.CertDir).WithOverrideArch(opts.OverrideArch).WithOverrideOS(opts.OverrideOS)
- options.WithOverrideVariant(opts.OverrideVariant).WithPassword(opts.Password).WithPullPolicy(opts.PullPolicy)
+ options.WithAllTags(opts.AllTags).WithAuthfile(opts.Authfile).WithCertDir(opts.CertDir).WithArch(opts.Arch).WithOS(opts.OS)
+ options.WithVariant(opts.Variant).WithPassword(opts.Password).WithPullPolicy(opts.PullPolicy)
if s := opts.SkipTLSVerify; s != types.OptionalBoolUndefined {
if s == types.OptionalBoolTrue {
options.WithSkipTLSVerify(true)
diff --git a/test/e2e/create_test.go b/test/e2e/create_test.go
index a4931ff2d..73d92e5a0 100644
--- a/test/e2e/create_test.go
+++ b/test/e2e/create_test.go
@@ -282,7 +282,7 @@ var _ = Describe("Podman create", func() {
})
It("podman create using image list by tag", func() {
- session := podmanTest.Podman([]string{"create", "--pull=always", "--override-arch=arm64", "--name=foo", ALPINELISTTAG})
+ session := podmanTest.Podman([]string{"create", "--pull=always", "--arch=arm64", "--name=foo", ALPINELISTTAG})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To((Equal(0)))
session = podmanTest.Podman([]string{"inspect", "--format", "{{.Image}}", "foo"})
@@ -296,7 +296,7 @@ var _ = Describe("Podman create", func() {
})
It("podman create using image list by digest", func() {
- session := podmanTest.Podman([]string{"create", "--pull=always", "--override-arch=arm64", "--name=foo", ALPINELISTDIGEST})
+ session := podmanTest.Podman([]string{"create", "--pull=always", "--arch=arm64", "--name=foo", ALPINELISTDIGEST})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To((Equal(0)))
session = podmanTest.Podman([]string{"inspect", "--format", "{{.Image}}", "foo"})
@@ -310,7 +310,7 @@ var _ = Describe("Podman create", func() {
})
It("podman create using image list instance by digest", func() {
- session := podmanTest.Podman([]string{"create", "--pull=always", "--override-arch=arm64", "--name=foo", ALPINEARM64DIGEST})
+ session := podmanTest.Podman([]string{"create", "--pull=always", "--arch=arm64", "--name=foo", ALPINEARM64DIGEST})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To((Equal(0)))
session = podmanTest.Podman([]string{"inspect", "--format", "{{.Image}}", "foo"})
@@ -324,7 +324,7 @@ var _ = Describe("Podman create", func() {
})
It("podman create using cross-arch image list instance by digest", func() {
- session := podmanTest.Podman([]string{"create", "--pull=always", "--override-arch=arm64", "--name=foo", ALPINEARM64DIGEST})
+ session := podmanTest.Podman([]string{"create", "--pull=always", "--arch=arm64", "--name=foo", ALPINEARM64DIGEST})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To((Equal(0)))
session = podmanTest.Podman([]string{"inspect", "--format", "{{.Image}}", "foo"})
@@ -652,10 +652,10 @@ var _ = Describe("Podman create", func() {
expectedError := "no image found in manifest list for architecture bogus"
Expect(session.ErrorToString()).To(ContainSubstring(expectedError))
- session = podmanTest.Podman([]string{"create", "--platform=linux/arm64", "--override-os", "windows", ALPINE})
+ session = podmanTest.Podman([]string{"create", "--platform=linux/arm64", "--os", "windows", ALPINE})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(125))
- expectedError = "--platform option can not be specified with --override-arch or --override-os"
+ expectedError = "--platform option can not be specified with --arch or --os"
Expect(session.ErrorToString()).To(ContainSubstring(expectedError))
session = podmanTest.Podman([]string{"create", "-q", "--platform=linux/arm64", ALPINE})
diff --git a/test/e2e/network_create_test.go b/test/e2e/network_create_test.go
index 73e18cbce..1bf2a2691 100644
--- a/test/e2e/network_create_test.go
+++ b/test/e2e/network_create_test.go
@@ -375,4 +375,21 @@ var _ = Describe("Podman network create", func() {
Expect(nc).To(ExitWithError())
})
+ It("podman network create with internal should not have dnsname", func() {
+ net := "internal-test" + stringid.GenerateNonCryptoID()
+ nc := podmanTest.Podman([]string{"network", "create", "--internal", net})
+ nc.WaitWithDefaultTimeout()
+ defer podmanTest.removeCNINetwork(net)
+ Expect(nc.ExitCode()).To(BeZero())
+ // Not performing this check on remote tests because it is a logrus error which does
+ // not come back via stderr on the remote client.
+ if !IsRemote() {
+ Expect(nc.ErrorToString()).To(ContainSubstring("dnsname and --internal networks are incompatible"))
+ }
+ nc = podmanTest.Podman([]string{"network", "inspect", net})
+ nc.WaitWithDefaultTimeout()
+ Expect(nc.ExitCode()).To(BeZero())
+ Expect(nc.OutputToString()).ToNot(ContainSubstring("dnsname"))
+ })
+
})
diff --git a/test/e2e/pull_test.go b/test/e2e/pull_test.go
index 7099a2904..4b73004da 100644
--- a/test/e2e/pull_test.go
+++ b/test/e2e/pull_test.go
@@ -92,7 +92,7 @@ var _ = Describe("Podman pull", func() {
})
It("podman pull by digest (image list)", func() {
- session := podmanTest.Podman([]string{"pull", "--override-arch=arm64", ALPINELISTDIGEST})
+ session := podmanTest.Podman([]string{"pull", "--arch=arm64", ALPINELISTDIGEST})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
// inspect using the digest of the list
@@ -135,7 +135,7 @@ var _ = Describe("Podman pull", func() {
})
It("podman pull by instance digest (image list)", func() {
- session := podmanTest.Podman([]string{"pull", "--override-arch=arm64", ALPINEARM64DIGEST})
+ session := podmanTest.Podman([]string{"pull", "--arch=arm64", ALPINEARM64DIGEST})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
// inspect using the digest of the list
@@ -175,7 +175,7 @@ var _ = Describe("Podman pull", func() {
})
It("podman pull by tag (image list)", func() {
- session := podmanTest.Podman([]string{"pull", "--override-arch=arm64", ALPINELISTTAG})
+ session := podmanTest.Podman([]string{"pull", "--arch=arm64", ALPINELISTTAG})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
// inspect using the tag we used for pulling
@@ -503,10 +503,10 @@ var _ = Describe("Podman pull", func() {
expectedError := "no image found in manifest list for architecture bogus"
Expect(session.ErrorToString()).To(ContainSubstring(expectedError))
- session = podmanTest.Podman([]string{"pull", "--platform=linux/arm64", "--override-os", "windows", ALPINE})
+ session = podmanTest.Podman([]string{"pull", "--platform=linux/arm64", "--os", "windows", ALPINE})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(125))
- expectedError = "--platform option can not be specified with --override-arch or --override-os"
+ expectedError = "--platform option can not be specified with --arch or --os"
Expect(session.ErrorToString()).To(ContainSubstring(expectedError))
session = podmanTest.Podman([]string{"pull", "-q", "--platform=linux/arm64", ALPINE})
diff --git a/test/e2e/run_test.go b/test/e2e/run_test.go
index 19060ecdc..caeaf190e 100644
--- a/test/e2e/run_test.go
+++ b/test/e2e/run_test.go
@@ -669,7 +669,7 @@ USER bin`
})
It("podman run with secrets", func() {
- SkipIfRemote("--default-mount-file option is not supported in podman-remote")
+ SkipIfRemote("--default-mounts-file option is not supported in podman-remote")
containersDir := filepath.Join(podmanTest.TempDir, "containers")
err := os.MkdirAll(containersDir, 0755)
Expect(err).To(BeNil())
diff --git a/test/system/050-stop.bats b/test/system/050-stop.bats
index 548fd56ee..7d9f1fcb3 100644
--- a/test/system/050-stop.bats
+++ b/test/system/050-stop.bats
@@ -30,6 +30,49 @@ load helpers
run_podman rm $cid
}
+# #9051 : podman stop --all was not working with podman-remote
+@test "podman stop --all" {
+ # Start three containers, create (without running) a fourth
+ run_podman run -d --name c1 $IMAGE sleep 20
+ run_podman run -d --name c2 $IMAGE sleep 40
+ run_podman run -d --name c3 $IMAGE sleep 60
+ run_podman create --name c4 $IMAGE sleep 80
+
+ # podman ps (without -a) should show the three running containers
+ run_podman ps --sort names --format '{{.Names}}--{{.Status}}'
+ is "${#lines[*]}" "3" "podman ps shows exactly three containers"
+ is "${lines[0]}" "c1--Up.*" "podman ps shows running container (1)"
+ is "${lines[1]}" "c2--Up.*" "podman ps shows running container (2)"
+ is "${lines[2]}" "c3--Up.*" "podman ps shows running container (3)"
+
+ # Stop -a
+ run_podman stop -a -t 1
+
+ # Now podman ps (without -a) should show nothing.
+ run_podman ps --format '{{.Names}}'
+ is "$output" "" "podman ps, after stop -a, shows no running containers"
+
+ # ...but with -a, containers are shown
+ run_podman ps -a --sort names --format '{{.Names}}--{{.Status}}'
+ is "${#lines[*]}" "4" "podman ps -a shows exactly four containers"
+ is "${lines[0]}" "c1--Exited.*" "ps -a, first stopped container"
+ is "${lines[1]}" "c2--Exited.*" "ps -a, second stopped container"
+ is "${lines[2]}" "c3--Exited.*" "ps -a, third stopped container"
+ is "${lines[3]}" "c4--Created.*" "ps -a, created container (unaffected)"
+}
+
+# #9051 : podman stop --ignore was not working with podman-remote
+@test "podman stop --ignore" {
+ name=thiscontainerdoesnotexist
+ run_podman 125 stop $name
+ is "$output" \
+ "Error: no container with name or ID $name found: no such container" \
+ "podman stop nonexistent container"
+
+ run_podman stop --ignore $name
+ is "$output" "" "podman stop nonexistent container, with --ignore"
+}
+
# Test fallback
diff --git a/test/system/070-build.bats b/test/system/070-build.bats
index 0e83a184b..05518d8fc 100644
--- a/test/system/070-build.bats
+++ b/test/system/070-build.bats
@@ -126,6 +126,23 @@ EOF
label_name=l$(random_string 8)
label_value=$(random_string 12)
+ # #8679: Create a secrets directory, and mount it in the container
+ # (can only test locally; podman-remote has no --default-mounts-file opt)
+ MOUNTS_CONF=
+ secret_contents="ceci nest pas un secret"
+ CAT_SECRET="echo $secret_contents"
+ if ! is_remote; then
+ mkdir $tmpdir/secrets
+ echo $tmpdir/secrets:/run/secrets > $tmpdir/mounts.conf
+
+ secret_filename=secretfile-$(random_string 20)
+ secret_contents=shhh-$(random_string 30)-shhh
+ echo $secret_contents >$tmpdir/secrets/$secret_filename
+
+ MOUNTS_CONF=--default-mounts-file=$tmpdir/mounts.conf
+ CAT_SECRET="cat /run/secrets/$secret_filename"
+ fi
+
# Command to run on container startup with no args
cat >$tmpdir/mycmd <<EOF
#!/bin/sh
@@ -133,6 +150,7 @@ PATH=/usr/bin:/bin
pwd
echo "\$1"
printenv | grep MYENV | sort | sed -e 's/^MYENV.=//'
+$CAT_SECRET
EOF
# For overriding with --env-file; using multiple files confirms that
@@ -169,14 +187,20 @@ ENV ftp_proxy ftp-proxy-in-image
ADD mycmd /bin/mydefaultcmd
RUN chmod 755 /bin/mydefaultcmd
RUN chown 2:3 /bin/mydefaultcmd
+
+RUN $CAT_SECRET
+
CMD ["/bin/mydefaultcmd","$s_echo"]
EOF
# cd to the dir, so we test relative paths (important for podman-remote)
cd $PODMAN_TMPDIR
- run_podman build -t build_test -f build-test/Containerfile build-test
+ run_podman ${MOUNTS_CONF} build \
+ -t build_test -f build-test/Containerfile build-test
local iid="${lines[-1]}"
+ # Make sure 'podman build' had the secret mounted
+ is "$output" ".*$secret_contents.*" "podman build has /run/secrets mounted"
if is_remote; then
ENVHOST=""
@@ -187,7 +211,7 @@ EOF
# Run without args - should run the above script. Verify its output.
export MYENV2="$s_env2"
export MYENV3="env-file-should-override-env-host!"
- run_podman run --rm \
+ run_podman ${MOUNTS_CONF} run --rm \
--env-file=$PODMAN_TMPDIR/env-file1 \
--env-file=$PODMAN_TMPDIR/env-file2 \
${ENVHOST} \
@@ -207,6 +231,9 @@ EOF
is "${lines[4]}" "$s_env3" "container default command: env3 (from envfile)"
is "${lines[5]}" "$s_env4" "container default command: env4 (from cmdline)"
+ is "${lines[6]}" "$secret_contents" \
+ "Contents of /run/secrets/$secret_filename in container"
+
# Proxies - environment should override container, but not env-file
http_proxy=http-proxy-from-env ftp_proxy=ftp-proxy-from-env \
run_podman run --rm \
diff --git a/test/system/400-unprivileged-access.bats b/test/system/400-unprivileged-access.bats
index 6a89247e6..f26c97d1e 100644
--- a/test/system/400-unprivileged-access.bats
+++ b/test/system/400-unprivileged-access.bats
@@ -132,7 +132,11 @@ EOF
# Run 'stat' on all the files, plus /dev/null. Get path, file type,
# number of links, major, and minor (see below for why). Do it all
# in one go, to avoid multiple podman-runs
- run_podman run --rm $IMAGE stat -c'%n:%F:%h:%T:%t' /dev/null ${subset[@]}
+ run_podman '?' run --rm $IMAGE stat -c'%n:%F:%h:%T:%t' /dev/null ${subset[@]}
+ if [[ $status -gt 1 ]]; then
+ die "Unexpected exit status $status: expected 0 or 1"
+ fi
+
local devnull=
for result in "${lines[@]}"; do
# e.g. /proc/acpi:character special file:1:3:1
@@ -161,6 +165,11 @@ EOF
# If you can think of a better way to do this check,
# please feel free to fix it.
is "$nlinks" "2" "$path: directory link count"
+ elif [[ $result =~ stat:.*No.such.file.or.directory ]]; then
+ # No matter what the path is, this is OK. It has to do with #8949
+ # and RHEL8 and rootless and cgroups v1. Bottom line, what we care
+ # about is that the path not be available inside the container.
+ :
else
die "$path: Unknown file type '$type'"
fi
diff --git a/test/system/410-selinux.bats b/test/system/410-selinux.bats
index 1e44fe06c..7482d3e55 100644
--- a/test/system/410-selinux.bats
+++ b/test/system/410-selinux.bats
@@ -171,4 +171,15 @@ function check_label() {
run_podman pod rm myselinuxpod
}
+# #8946 - better diagnostics for nonexistent attributes
+@test "podman with nonexistent labels" {
+ skip_if_no_selinux
+
+ # The '.*' in the error below is for dealing with podman-remote, which
+ # includes "error preparing container <sha> for attach" in output.
+ run_podman 126 run --security-opt label=type:foo.bar $IMAGE true
+ is "$output" "Error.*: \`/proc/thread-self/attr/exec\`: OCI runtime error: unable to assign security attribute" "useful diagnostic"
+}
+
+
# vim: filetype=sh
diff --git a/test/system/500-networking.bats b/test/system/500-networking.bats
index bcc6737b7..0d976a6af 100644
--- a/test/system/500-networking.bats
+++ b/test/system/500-networking.bats
@@ -98,6 +98,7 @@ load helpers
# "network create" now works rootless, with the help of a special container
@test "podman network create" {
skip_if_remote "FIXME: pending #7808"
+ myport=54322
local mynetname=testnet-$(random_string 10)
local mysubnet=$(random_rfc1918_subnet)
@@ -115,6 +116,27 @@ load helpers
is "$output" ".* inet ${mysubnet}\.2/24 brd ${mysubnet}\.255 " \
"sdfsdf"
+ run_podman run --rm -d --network $mynetname -p 127.0.0.1:$myport:$myport \
+ $IMAGE nc -l -n -v -p $myport
+ cid="$output"
+
+ # emit random string, and check it
+ teststring=$(random_string 30)
+ echo "$teststring" | nc 127.0.0.1 $myport
+
+ run_podman logs $cid
+ # Sigh. We can't check line-by-line, because 'nc' output order is
+ # unreliable. We usually get the 'connect to' line before the random
+ # string, but sometimes we get it after. So, just do substring checks.
+ is "$output" ".*listening on \[::\]:$myport .*" "nc -v shows right port"
+
+ # This is the truly important check: make sure the remote IP is
+ # in the 172.X range, not 127.X.
+ is "$output" \
+ ".*connect to \[::ffff:172\..*\]:$myport from \[::ffff:172\..*\]:.*" \
+ "nc -v shows remote IP address in 172.X space (not 127.0.0.1)"
+ is "$output" ".*${teststring}.*" "test string received on container"
+
# Cannot create network with the same name
run_podman 125 network create $mynetname
is "$output" "Error: the network name $mynetname is already used" \
diff --git a/vendor/github.com/google/uuid/version4.go b/vendor/github.com/google/uuid/version4.go
index c110465db..86160fbd0 100644
--- a/vendor/github.com/google/uuid/version4.go
+++ b/vendor/github.com/google/uuid/version4.go
@@ -14,6 +14,14 @@ func New() UUID {
return Must(NewRandom())
}
+// NewString creates a new random UUID and returns it as a string or panics.
+// NewString is equivalent to the expression
+//
+// uuid.New().String()
+func NewString() string {
+ return Must(NewRandom()).String()
+}
+
// NewRandom returns a Random (Version 4) UUID.
//
// The strength of the UUIDs is based on the strength of the crypto/rand
diff --git a/vendor/golang.org/x/crypto/chacha20/chacha_arm64.go b/vendor/golang.org/x/crypto/chacha20/chacha_arm64.go
index b799e440b..c474e5a80 100644
--- a/vendor/golang.org/x/crypto/chacha20/chacha_arm64.go
+++ b/vendor/golang.org/x/crypto/chacha20/chacha_arm64.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build go1.11,!gccgo,!purego
+// +build go1.11,gc,!purego
package chacha20
diff --git a/vendor/golang.org/x/crypto/chacha20/chacha_arm64.s b/vendor/golang.org/x/crypto/chacha20/chacha_arm64.s
index 891481539..8fb49a13e 100644
--- a/vendor/golang.org/x/crypto/chacha20/chacha_arm64.s
+++ b/vendor/golang.org/x/crypto/chacha20/chacha_arm64.s
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build go1.11,!gccgo,!purego
+// +build go1.11,gc,!purego
#include "textflag.h"
diff --git a/vendor/golang.org/x/crypto/chacha20/chacha_noasm.go b/vendor/golang.org/x/crypto/chacha20/chacha_noasm.go
index 4635307b8..3e8a609fb 100644
--- a/vendor/golang.org/x/crypto/chacha20/chacha_noasm.go
+++ b/vendor/golang.org/x/crypto/chacha20/chacha_noasm.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !arm64,!s390x,!ppc64le arm64,!go1.11 gccgo purego
+// +build !arm64,!s390x,!ppc64le arm64,!go1.11 !gc purego
package chacha20
diff --git a/vendor/golang.org/x/crypto/chacha20/chacha_ppc64le.go b/vendor/golang.org/x/crypto/chacha20/chacha_ppc64le.go
index b79933034..2806c6325 100644
--- a/vendor/golang.org/x/crypto/chacha20/chacha_ppc64le.go
+++ b/vendor/golang.org/x/crypto/chacha20/chacha_ppc64le.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !gccgo,!purego
+// +build gc,!purego
package chacha20
diff --git a/vendor/golang.org/x/crypto/chacha20/chacha_ppc64le.s b/vendor/golang.org/x/crypto/chacha20/chacha_ppc64le.s
index 23c602164..3dad4b2fa 100644
--- a/vendor/golang.org/x/crypto/chacha20/chacha_ppc64le.s
+++ b/vendor/golang.org/x/crypto/chacha20/chacha_ppc64le.s
@@ -19,7 +19,7 @@
// The differences in this and the original implementation are
// due to the calling conventions and initialization of constants.
-// +build !gccgo,!purego
+// +build gc,!purego
#include "textflag.h"
diff --git a/vendor/golang.org/x/crypto/chacha20/chacha_s390x.go b/vendor/golang.org/x/crypto/chacha20/chacha_s390x.go
index a9244bdf4..a0774dde1 100644
--- a/vendor/golang.org/x/crypto/chacha20/chacha_s390x.go
+++ b/vendor/golang.org/x/crypto/chacha20/chacha_s390x.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !gccgo,!purego
+// +build gc,!purego
package chacha20
diff --git a/vendor/golang.org/x/crypto/chacha20/chacha_s390x.s b/vendor/golang.org/x/crypto/chacha20/chacha_s390x.s
index 89c658c41..818161189 100644
--- a/vendor/golang.org/x/crypto/chacha20/chacha_s390x.s
+++ b/vendor/golang.org/x/crypto/chacha20/chacha_s390x.s
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !gccgo,!purego
+// +build gc,!purego
#include "go_asm.h"
#include "textflag.h"
diff --git a/vendor/golang.org/x/crypto/curve25519/curve25519_amd64.go b/vendor/golang.org/x/crypto/curve25519/curve25519_amd64.go
index 5120b779b..877b6de29 100644
--- a/vendor/golang.org/x/crypto/curve25519/curve25519_amd64.go
+++ b/vendor/golang.org/x/crypto/curve25519/curve25519_amd64.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build amd64,!gccgo,!appengine,!purego
+// +build amd64,gc,!purego
package curve25519
diff --git a/vendor/golang.org/x/crypto/curve25519/curve25519_amd64.s b/vendor/golang.org/x/crypto/curve25519/curve25519_amd64.s
index 0250c8885..6c5338092 100644
--- a/vendor/golang.org/x/crypto/curve25519/curve25519_amd64.s
+++ b/vendor/golang.org/x/crypto/curve25519/curve25519_amd64.s
@@ -5,7 +5,7 @@
// This code was translated into a form compatible with 6a from the public
// domain sources in SUPERCOP: https://bench.cr.yp.to/supercop.html
-// +build amd64,!gccgo,!appengine,!purego
+// +build amd64,gc,!purego
#define REDMASK51 0x0007FFFFFFFFFFFF
diff --git a/vendor/golang.org/x/crypto/curve25519/curve25519_noasm.go b/vendor/golang.org/x/crypto/curve25519/curve25519_noasm.go
index 047d49afc..80d3300af 100644
--- a/vendor/golang.org/x/crypto/curve25519/curve25519_noasm.go
+++ b/vendor/golang.org/x/crypto/curve25519/curve25519_noasm.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !amd64 gccgo appengine purego
+// +build !amd64 !gc purego
package curve25519
diff --git a/vendor/golang.org/x/crypto/internal/subtle/aliasing.go b/vendor/golang.org/x/crypto/internal/subtle/aliasing.go
index f38797bfa..281c27ef0 100644
--- a/vendor/golang.org/x/crypto/internal/subtle/aliasing.go
+++ b/vendor/golang.org/x/crypto/internal/subtle/aliasing.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !appengine
+// +build !purego
// Package subtle implements functions that are often useful in cryptographic
// code but require careful thought to use correctly.
diff --git a/vendor/golang.org/x/crypto/internal/subtle/aliasing_appengine.go b/vendor/golang.org/x/crypto/internal/subtle/aliasing_purego.go
index 0cc4a8a64..e20a29659 100644
--- a/vendor/golang.org/x/crypto/internal/subtle/aliasing_appengine.go
+++ b/vendor/golang.org/x/crypto/internal/subtle/aliasing_purego.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build appengine
+// +build purego
// Package subtle implements functions that are often useful in cryptographic
// code but require careful thought to use correctly.
diff --git a/vendor/golang.org/x/crypto/poly1305/mac_noasm.go b/vendor/golang.org/x/crypto/poly1305/mac_noasm.go
index d118f30ed..af6c94f92 100644
--- a/vendor/golang.org/x/crypto/poly1305/mac_noasm.go
+++ b/vendor/golang.org/x/crypto/poly1305/mac_noasm.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !amd64,!ppc64le,!s390x gccgo purego
+// +build !amd64,!ppc64le,!s390x !gc purego
package poly1305
diff --git a/vendor/golang.org/x/crypto/poly1305/sum_amd64.go b/vendor/golang.org/x/crypto/poly1305/sum_amd64.go
index 99e5a1d50..cf3a69ed3 100644
--- a/vendor/golang.org/x/crypto/poly1305/sum_amd64.go
+++ b/vendor/golang.org/x/crypto/poly1305/sum_amd64.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !gccgo,!purego
+// +build gc,!purego
package poly1305
diff --git a/vendor/golang.org/x/crypto/poly1305/sum_amd64.s b/vendor/golang.org/x/crypto/poly1305/sum_amd64.s
index 8d394a212..2cb037314 100644
--- a/vendor/golang.org/x/crypto/poly1305/sum_amd64.s
+++ b/vendor/golang.org/x/crypto/poly1305/sum_amd64.s
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !gccgo,!purego
+// +build gc,!purego
#include "textflag.h"
diff --git a/vendor/golang.org/x/crypto/poly1305/sum_ppc64le.go b/vendor/golang.org/x/crypto/poly1305/sum_ppc64le.go
index 2e7a120b1..cb4b7185d 100644
--- a/vendor/golang.org/x/crypto/poly1305/sum_ppc64le.go
+++ b/vendor/golang.org/x/crypto/poly1305/sum_ppc64le.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !gccgo,!purego
+// +build gc,!purego
package poly1305
diff --git a/vendor/golang.org/x/crypto/poly1305/sum_ppc64le.s b/vendor/golang.org/x/crypto/poly1305/sum_ppc64le.s
index 4e0281387..5cd7494b2 100644
--- a/vendor/golang.org/x/crypto/poly1305/sum_ppc64le.s
+++ b/vendor/golang.org/x/crypto/poly1305/sum_ppc64le.s
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !gccgo,!purego
+// +build gc,!purego
#include "textflag.h"
diff --git a/vendor/golang.org/x/crypto/poly1305/sum_s390x.go b/vendor/golang.org/x/crypto/poly1305/sum_s390x.go
index 958fedc07..188a665e1 100644
--- a/vendor/golang.org/x/crypto/poly1305/sum_s390x.go
+++ b/vendor/golang.org/x/crypto/poly1305/sum_s390x.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !gccgo,!purego
+// +build gc,!purego
package poly1305
diff --git a/vendor/golang.org/x/crypto/poly1305/sum_s390x.s b/vendor/golang.org/x/crypto/poly1305/sum_s390x.s
index 0fa9ee6e0..bdd882c60 100644
--- a/vendor/golang.org/x/crypto/poly1305/sum_s390x.s
+++ b/vendor/golang.org/x/crypto/poly1305/sum_s390x.s
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !gccgo,!purego
+// +build gc,!purego
#include "textflag.h"
diff --git a/vendor/golang.org/x/crypto/ssh/client_auth.go b/vendor/golang.org/x/crypto/ssh/client_auth.go
index f3265655e..c611aeb68 100644
--- a/vendor/golang.org/x/crypto/ssh/client_auth.go
+++ b/vendor/golang.org/x/crypto/ssh/client_auth.go
@@ -471,7 +471,7 @@ func (cb KeyboardInteractiveChallenge) auth(session []byte, user string, c packe
}
if len(answers) != len(prompts) {
- return authFailure, nil, errors.New("ssh: not enough answers from keyboard-interactive callback")
+ return authFailure, nil, fmt.Errorf("ssh: incorrect number of answers from keyboard-interactive callback %d (expected %d)", len(answers), len(prompts))
}
responseLength := 1 + 4
for _, a := range answers {
diff --git a/vendor/golang.org/x/crypto/ssh/kex.go b/vendor/golang.org/x/crypto/ssh/kex.go
index 7eedb209f..766e92939 100644
--- a/vendor/golang.org/x/crypto/ssh/kex.go
+++ b/vendor/golang.org/x/crypto/ssh/kex.go
@@ -557,8 +557,6 @@ type dhGEXSHA struct {
hashFunc crypto.Hash
}
-const numMRTests = 64
-
const (
dhGroupExchangeMinimumBits = 2048
dhGroupExchangePreferredBits = 2048
@@ -602,15 +600,8 @@ func (gex dhGEXSHA) Client(c packetConn, randSource io.Reader, magics *handshake
gex.p = kexDHGexGroup.P
gex.g = kexDHGexGroup.G
- // Check if p is safe by verifing that p and (p-1)/2 are primes
- one := big.NewInt(1)
- var pHalf = &big.Int{}
- pHalf.Rsh(gex.p, 1)
- if !gex.p.ProbablyPrime(numMRTests) || !pHalf.ProbablyPrime(numMRTests) {
- return nil, fmt.Errorf("ssh: server provided gex p is not safe")
- }
-
// Check if g is safe by verifing that g > 1 and g < p - 1
+ one := big.NewInt(1)
var pMinusOne = &big.Int{}
pMinusOne.Sub(gex.p, one)
if gex.g.Cmp(one) != 1 && gex.g.Cmp(pMinusOne) != -1 {
@@ -618,6 +609,8 @@ func (gex dhGEXSHA) Client(c packetConn, randSource io.Reader, magics *handshake
}
// Send GexInit
+ var pHalf = &big.Int{}
+ pHalf.Rsh(gex.p, 1)
x, err := rand.Int(randSource, pHalf)
if err != nil {
return nil, err
diff --git a/vendor/golang.org/x/crypto/ssh/server.go b/vendor/golang.org/x/crypto/ssh/server.go
index 7d42a8c88..b6911e830 100644
--- a/vendor/golang.org/x/crypto/ssh/server.go
+++ b/vendor/golang.org/x/crypto/ssh/server.go
@@ -572,6 +572,10 @@ userAuthLoop:
perms = candidate.perms
}
case "gssapi-with-mic":
+ if config.GSSAPIWithMICConfig == nil {
+ authErr = errors.New("ssh: gssapi-with-mic auth not configured")
+ break
+ }
gssapiConfig := config.GSSAPIWithMICConfig
userAuthRequestGSSAPI, err := parseGSSAPIPayload(userAuthReq.Payload)
if err != nil {
diff --git a/vendor/golang.org/x/crypto/ssh/terminal/terminal.go b/vendor/golang.org/x/crypto/ssh/terminal/terminal.go
index 2ffb97bfb..a4d1919a9 100644
--- a/vendor/golang.org/x/crypto/ssh/terminal/terminal.go
+++ b/vendor/golang.org/x/crypto/ssh/terminal/terminal.go
@@ -2,986 +2,75 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+// Package terminal provides support functions for dealing with terminals, as
+// commonly found on UNIX systems.
+//
+// Deprecated: this package moved to golang.org/x/term.
package terminal
import (
- "bytes"
"io"
- "runtime"
- "strconv"
- "sync"
- "unicode/utf8"
+
+ "golang.org/x/term"
)
// EscapeCodes contains escape sequences that can be written to the terminal in
// order to achieve different styles of text.
-type EscapeCodes struct {
- // Foreground colors
- Black, Red, Green, Yellow, Blue, Magenta, Cyan, White []byte
-
- // Reset all attributes
- Reset []byte
-}
-
-var vt100EscapeCodes = EscapeCodes{
- Black: []byte{keyEscape, '[', '3', '0', 'm'},
- Red: []byte{keyEscape, '[', '3', '1', 'm'},
- Green: []byte{keyEscape, '[', '3', '2', 'm'},
- Yellow: []byte{keyEscape, '[', '3', '3', 'm'},
- Blue: []byte{keyEscape, '[', '3', '4', 'm'},
- Magenta: []byte{keyEscape, '[', '3', '5', 'm'},
- Cyan: []byte{keyEscape, '[', '3', '6', 'm'},
- White: []byte{keyEscape, '[', '3', '7', 'm'},
-
- Reset: []byte{keyEscape, '[', '0', 'm'},
-}
+type EscapeCodes = term.EscapeCodes
// Terminal contains the state for running a VT100 terminal that is capable of
// reading lines of input.
-type Terminal struct {
- // AutoCompleteCallback, if non-null, is called for each keypress with
- // the full input line and the current position of the cursor (in
- // bytes, as an index into |line|). If it returns ok=false, the key
- // press is processed normally. Otherwise it returns a replacement line
- // and the new cursor position.
- AutoCompleteCallback func(line string, pos int, key rune) (newLine string, newPos int, ok bool)
-
- // Escape contains a pointer to the escape codes for this terminal.
- // It's always a valid pointer, although the escape codes themselves
- // may be empty if the terminal doesn't support them.
- Escape *EscapeCodes
-
- // lock protects the terminal and the state in this object from
- // concurrent processing of a key press and a Write() call.
- lock sync.Mutex
-
- c io.ReadWriter
- prompt []rune
-
- // line is the current line being entered.
- line []rune
- // pos is the logical position of the cursor in line
- pos int
- // echo is true if local echo is enabled
- echo bool
- // pasteActive is true iff there is a bracketed paste operation in
- // progress.
- pasteActive bool
-
- // cursorX contains the current X value of the cursor where the left
- // edge is 0. cursorY contains the row number where the first row of
- // the current line is 0.
- cursorX, cursorY int
- // maxLine is the greatest value of cursorY so far.
- maxLine int
-
- termWidth, termHeight int
-
- // outBuf contains the terminal data to be sent.
- outBuf []byte
- // remainder contains the remainder of any partial key sequences after
- // a read. It aliases into inBuf.
- remainder []byte
- inBuf [256]byte
-
- // history contains previously entered commands so that they can be
- // accessed with the up and down keys.
- history stRingBuffer
- // historyIndex stores the currently accessed history entry, where zero
- // means the immediately previous entry.
- historyIndex int
- // When navigating up and down the history it's possible to return to
- // the incomplete, initial line. That value is stored in
- // historyPending.
- historyPending string
-}
+type Terminal = term.Terminal
// NewTerminal runs a VT100 terminal on the given ReadWriter. If the ReadWriter is
// a local terminal, that terminal must first have been put into raw mode.
// prompt is a string that is written at the start of each input line (i.e.
// "> ").
func NewTerminal(c io.ReadWriter, prompt string) *Terminal {
- return &Terminal{
- Escape: &vt100EscapeCodes,
- c: c,
- prompt: []rune(prompt),
- termWidth: 80,
- termHeight: 24,
- echo: true,
- historyIndex: -1,
- }
-}
-
-const (
- keyCtrlC = 3
- keyCtrlD = 4
- keyCtrlU = 21
- keyEnter = '\r'
- keyEscape = 27
- keyBackspace = 127
- keyUnknown = 0xd800 /* UTF-16 surrogate area */ + iota
- keyUp
- keyDown
- keyLeft
- keyRight
- keyAltLeft
- keyAltRight
- keyHome
- keyEnd
- keyDeleteWord
- keyDeleteLine
- keyClearScreen
- keyPasteStart
- keyPasteEnd
-)
-
-var (
- crlf = []byte{'\r', '\n'}
- pasteStart = []byte{keyEscape, '[', '2', '0', '0', '~'}
- pasteEnd = []byte{keyEscape, '[', '2', '0', '1', '~'}
-)
-
-// bytesToKey tries to parse a key sequence from b. If successful, it returns
-// the key and the remainder of the input. Otherwise it returns utf8.RuneError.
-func bytesToKey(b []byte, pasteActive bool) (rune, []byte) {
- if len(b) == 0 {
- return utf8.RuneError, nil
- }
-
- if !pasteActive {
- switch b[0] {
- case 1: // ^A
- return keyHome, b[1:]
- case 2: // ^B
- return keyLeft, b[1:]
- case 5: // ^E
- return keyEnd, b[1:]
- case 6: // ^F
- return keyRight, b[1:]
- case 8: // ^H
- return keyBackspace, b[1:]
- case 11: // ^K
- return keyDeleteLine, b[1:]
- case 12: // ^L
- return keyClearScreen, b[1:]
- case 23: // ^W
- return keyDeleteWord, b[1:]
- case 14: // ^N
- return keyDown, b[1:]
- case 16: // ^P
- return keyUp, b[1:]
- }
- }
-
- if b[0] != keyEscape {
- if !utf8.FullRune(b) {
- return utf8.RuneError, b
- }
- r, l := utf8.DecodeRune(b)
- return r, b[l:]
- }
-
- if !pasteActive && len(b) >= 3 && b[0] == keyEscape && b[1] == '[' {
- switch b[2] {
- case 'A':
- return keyUp, b[3:]
- case 'B':
- return keyDown, b[3:]
- case 'C':
- return keyRight, b[3:]
- case 'D':
- return keyLeft, b[3:]
- case 'H':
- return keyHome, b[3:]
- case 'F':
- return keyEnd, b[3:]
- }
- }
-
- if !pasteActive && len(b) >= 6 && b[0] == keyEscape && b[1] == '[' && b[2] == '1' && b[3] == ';' && b[4] == '3' {
- switch b[5] {
- case 'C':
- return keyAltRight, b[6:]
- case 'D':
- return keyAltLeft, b[6:]
- }
- }
-
- if !pasteActive && len(b) >= 6 && bytes.Equal(b[:6], pasteStart) {
- return keyPasteStart, b[6:]
- }
-
- if pasteActive && len(b) >= 6 && bytes.Equal(b[:6], pasteEnd) {
- return keyPasteEnd, b[6:]
- }
-
- // If we get here then we have a key that we don't recognise, or a
- // partial sequence. It's not clear how one should find the end of a
- // sequence without knowing them all, but it seems that [a-zA-Z~] only
- // appears at the end of a sequence.
- for i, c := range b[0:] {
- if c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c == '~' {
- return keyUnknown, b[i+1:]
- }
- }
-
- return utf8.RuneError, b
-}
-
-// queue appends data to the end of t.outBuf
-func (t *Terminal) queue(data []rune) {
- t.outBuf = append(t.outBuf, []byte(string(data))...)
-}
-
-var eraseUnderCursor = []rune{' ', keyEscape, '[', 'D'}
-var space = []rune{' '}
-
-func isPrintable(key rune) bool {
- isInSurrogateArea := key >= 0xd800 && key <= 0xdbff
- return key >= 32 && !isInSurrogateArea
-}
-
-// moveCursorToPos appends data to t.outBuf which will move the cursor to the
-// given, logical position in the text.
-func (t *Terminal) moveCursorToPos(pos int) {
- if !t.echo {
- return
- }
-
- x := visualLength(t.prompt) + pos
- y := x / t.termWidth
- x = x % t.termWidth
-
- up := 0
- if y < t.cursorY {
- up = t.cursorY - y
- }
-
- down := 0
- if y > t.cursorY {
- down = y - t.cursorY
- }
-
- left := 0
- if x < t.cursorX {
- left = t.cursorX - x
- }
-
- right := 0
- if x > t.cursorX {
- right = x - t.cursorX
- }
-
- t.cursorX = x
- t.cursorY = y
- t.move(up, down, left, right)
-}
-
-func (t *Terminal) move(up, down, left, right int) {
- m := []rune{}
-
- // 1 unit up can be expressed as ^[[A or ^[A
- // 5 units up can be expressed as ^[[5A
-
- if up == 1 {
- m = append(m, keyEscape, '[', 'A')
- } else if up > 1 {
- m = append(m, keyEscape, '[')
- m = append(m, []rune(strconv.Itoa(up))...)
- m = append(m, 'A')
- }
-
- if down == 1 {
- m = append(m, keyEscape, '[', 'B')
- } else if down > 1 {
- m = append(m, keyEscape, '[')
- m = append(m, []rune(strconv.Itoa(down))...)
- m = append(m, 'B')
- }
-
- if right == 1 {
- m = append(m, keyEscape, '[', 'C')
- } else if right > 1 {
- m = append(m, keyEscape, '[')
- m = append(m, []rune(strconv.Itoa(right))...)
- m = append(m, 'C')
- }
-
- if left == 1 {
- m = append(m, keyEscape, '[', 'D')
- } else if left > 1 {
- m = append(m, keyEscape, '[')
- m = append(m, []rune(strconv.Itoa(left))...)
- m = append(m, 'D')
- }
-
- t.queue(m)
-}
-
-func (t *Terminal) clearLineToRight() {
- op := []rune{keyEscape, '[', 'K'}
- t.queue(op)
-}
-
-const maxLineLength = 4096
-
-func (t *Terminal) setLine(newLine []rune, newPos int) {
- if t.echo {
- t.moveCursorToPos(0)
- t.writeLine(newLine)
- for i := len(newLine); i < len(t.line); i++ {
- t.writeLine(space)
- }
- t.moveCursorToPos(newPos)
- }
- t.line = newLine
- t.pos = newPos
-}
-
-func (t *Terminal) advanceCursor(places int) {
- t.cursorX += places
- t.cursorY += t.cursorX / t.termWidth
- if t.cursorY > t.maxLine {
- t.maxLine = t.cursorY
- }
- t.cursorX = t.cursorX % t.termWidth
-
- if places > 0 && t.cursorX == 0 {
- // Normally terminals will advance the current position
- // when writing a character. But that doesn't happen
- // for the last character in a line. However, when
- // writing a character (except a new line) that causes
- // a line wrap, the position will be advanced two
- // places.
- //
- // So, if we are stopping at the end of a line, we
- // need to write a newline so that our cursor can be
- // advanced to the next line.
- t.outBuf = append(t.outBuf, '\r', '\n')
- }
-}
-
-func (t *Terminal) eraseNPreviousChars(n int) {
- if n == 0 {
- return
- }
-
- if t.pos < n {
- n = t.pos
- }
- t.pos -= n
- t.moveCursorToPos(t.pos)
-
- copy(t.line[t.pos:], t.line[n+t.pos:])
- t.line = t.line[:len(t.line)-n]
- if t.echo {
- t.writeLine(t.line[t.pos:])
- for i := 0; i < n; i++ {
- t.queue(space)
- }
- t.advanceCursor(n)
- t.moveCursorToPos(t.pos)
- }
-}
-
-// countToLeftWord returns then number of characters from the cursor to the
-// start of the previous word.
-func (t *Terminal) countToLeftWord() int {
- if t.pos == 0 {
- return 0
- }
-
- pos := t.pos - 1
- for pos > 0 {
- if t.line[pos] != ' ' {
- break
- }
- pos--
- }
- for pos > 0 {
- if t.line[pos] == ' ' {
- pos++
- break
- }
- pos--
- }
-
- return t.pos - pos
-}
-
-// countToRightWord returns then number of characters from the cursor to the
-// start of the next word.
-func (t *Terminal) countToRightWord() int {
- pos := t.pos
- for pos < len(t.line) {
- if t.line[pos] == ' ' {
- break
- }
- pos++
- }
- for pos < len(t.line) {
- if t.line[pos] != ' ' {
- break
- }
- pos++
- }
- return pos - t.pos
-}
-
-// visualLength returns the number of visible glyphs in s.
-func visualLength(runes []rune) int {
- inEscapeSeq := false
- length := 0
-
- for _, r := range runes {
- switch {
- case inEscapeSeq:
- if (r >= 'a' && r <= 'z') || (r >= 'A' && r <= 'Z') {
- inEscapeSeq = false
- }
- case r == '\x1b':
- inEscapeSeq = true
- default:
- length++
- }
- }
-
- return length
-}
-
-// handleKey processes the given key and, optionally, returns a line of text
-// that the user has entered.
-func (t *Terminal) handleKey(key rune) (line string, ok bool) {
- if t.pasteActive && key != keyEnter {
- t.addKeyToLine(key)
- return
- }
-
- switch key {
- case keyBackspace:
- if t.pos == 0 {
- return
- }
- t.eraseNPreviousChars(1)
- case keyAltLeft:
- // move left by a word.
- t.pos -= t.countToLeftWord()
- t.moveCursorToPos(t.pos)
- case keyAltRight:
- // move right by a word.
- t.pos += t.countToRightWord()
- t.moveCursorToPos(t.pos)
- case keyLeft:
- if t.pos == 0 {
- return
- }
- t.pos--
- t.moveCursorToPos(t.pos)
- case keyRight:
- if t.pos == len(t.line) {
- return
- }
- t.pos++
- t.moveCursorToPos(t.pos)
- case keyHome:
- if t.pos == 0 {
- return
- }
- t.pos = 0
- t.moveCursorToPos(t.pos)
- case keyEnd:
- if t.pos == len(t.line) {
- return
- }
- t.pos = len(t.line)
- t.moveCursorToPos(t.pos)
- case keyUp:
- entry, ok := t.history.NthPreviousEntry(t.historyIndex + 1)
- if !ok {
- return "", false
- }
- if t.historyIndex == -1 {
- t.historyPending = string(t.line)
- }
- t.historyIndex++
- runes := []rune(entry)
- t.setLine(runes, len(runes))
- case keyDown:
- switch t.historyIndex {
- case -1:
- return
- case 0:
- runes := []rune(t.historyPending)
- t.setLine(runes, len(runes))
- t.historyIndex--
- default:
- entry, ok := t.history.NthPreviousEntry(t.historyIndex - 1)
- if ok {
- t.historyIndex--
- runes := []rune(entry)
- t.setLine(runes, len(runes))
- }
- }
- case keyEnter:
- t.moveCursorToPos(len(t.line))
- t.queue([]rune("\r\n"))
- line = string(t.line)
- ok = true
- t.line = t.line[:0]
- t.pos = 0
- t.cursorX = 0
- t.cursorY = 0
- t.maxLine = 0
- case keyDeleteWord:
- // Delete zero or more spaces and then one or more characters.
- t.eraseNPreviousChars(t.countToLeftWord())
- case keyDeleteLine:
- // Delete everything from the current cursor position to the
- // end of line.
- for i := t.pos; i < len(t.line); i++ {
- t.queue(space)
- t.advanceCursor(1)
- }
- t.line = t.line[:t.pos]
- t.moveCursorToPos(t.pos)
- case keyCtrlD:
- // Erase the character under the current position.
- // The EOF case when the line is empty is handled in
- // readLine().
- if t.pos < len(t.line) {
- t.pos++
- t.eraseNPreviousChars(1)
- }
- case keyCtrlU:
- t.eraseNPreviousChars(t.pos)
- case keyClearScreen:
- // Erases the screen and moves the cursor to the home position.
- t.queue([]rune("\x1b[2J\x1b[H"))
- t.queue(t.prompt)
- t.cursorX, t.cursorY = 0, 0
- t.advanceCursor(visualLength(t.prompt))
- t.setLine(t.line, t.pos)
- default:
- if t.AutoCompleteCallback != nil {
- prefix := string(t.line[:t.pos])
- suffix := string(t.line[t.pos:])
-
- t.lock.Unlock()
- newLine, newPos, completeOk := t.AutoCompleteCallback(prefix+suffix, len(prefix), key)
- t.lock.Lock()
-
- if completeOk {
- t.setLine([]rune(newLine), utf8.RuneCount([]byte(newLine)[:newPos]))
- return
- }
- }
- if !isPrintable(key) {
- return
- }
- if len(t.line) == maxLineLength {
- return
- }
- t.addKeyToLine(key)
- }
- return
-}
-
-// addKeyToLine inserts the given key at the current position in the current
-// line.
-func (t *Terminal) addKeyToLine(key rune) {
- if len(t.line) == cap(t.line) {
- newLine := make([]rune, len(t.line), 2*(1+len(t.line)))
- copy(newLine, t.line)
- t.line = newLine
- }
- t.line = t.line[:len(t.line)+1]
- copy(t.line[t.pos+1:], t.line[t.pos:])
- t.line[t.pos] = key
- if t.echo {
- t.writeLine(t.line[t.pos:])
- }
- t.pos++
- t.moveCursorToPos(t.pos)
-}
-
-func (t *Terminal) writeLine(line []rune) {
- for len(line) != 0 {
- remainingOnLine := t.termWidth - t.cursorX
- todo := len(line)
- if todo > remainingOnLine {
- todo = remainingOnLine
- }
- t.queue(line[:todo])
- t.advanceCursor(visualLength(line[:todo]))
- line = line[todo:]
- }
-}
-
-// writeWithCRLF writes buf to w but replaces all occurrences of \n with \r\n.
-func writeWithCRLF(w io.Writer, buf []byte) (n int, err error) {
- for len(buf) > 0 {
- i := bytes.IndexByte(buf, '\n')
- todo := len(buf)
- if i >= 0 {
- todo = i
- }
-
- var nn int
- nn, err = w.Write(buf[:todo])
- n += nn
- if err != nil {
- return n, err
- }
- buf = buf[todo:]
-
- if i >= 0 {
- if _, err = w.Write(crlf); err != nil {
- return n, err
- }
- n++
- buf = buf[1:]
- }
- }
-
- return n, nil
-}
-
-func (t *Terminal) Write(buf []byte) (n int, err error) {
- t.lock.Lock()
- defer t.lock.Unlock()
-
- if t.cursorX == 0 && t.cursorY == 0 {
- // This is the easy case: there's nothing on the screen that we
- // have to move out of the way.
- return writeWithCRLF(t.c, buf)
- }
-
- // We have a prompt and possibly user input on the screen. We
- // have to clear it first.
- t.move(0 /* up */, 0 /* down */, t.cursorX /* left */, 0 /* right */)
- t.cursorX = 0
- t.clearLineToRight()
-
- for t.cursorY > 0 {
- t.move(1 /* up */, 0, 0, 0)
- t.cursorY--
- t.clearLineToRight()
- }
-
- if _, err = t.c.Write(t.outBuf); err != nil {
- return
- }
- t.outBuf = t.outBuf[:0]
-
- if n, err = writeWithCRLF(t.c, buf); err != nil {
- return
- }
-
- t.writeLine(t.prompt)
- if t.echo {
- t.writeLine(t.line)
- }
-
- t.moveCursorToPos(t.pos)
-
- if _, err = t.c.Write(t.outBuf); err != nil {
- return
- }
- t.outBuf = t.outBuf[:0]
- return
-}
-
-// ReadPassword temporarily changes the prompt and reads a password, without
-// echo, from the terminal.
-func (t *Terminal) ReadPassword(prompt string) (line string, err error) {
- t.lock.Lock()
- defer t.lock.Unlock()
-
- oldPrompt := t.prompt
- t.prompt = []rune(prompt)
- t.echo = false
-
- line, err = t.readLine()
-
- t.prompt = oldPrompt
- t.echo = true
-
- return
-}
-
-// ReadLine returns a line of input from the terminal.
-func (t *Terminal) ReadLine() (line string, err error) {
- t.lock.Lock()
- defer t.lock.Unlock()
-
- return t.readLine()
-}
-
-func (t *Terminal) readLine() (line string, err error) {
- // t.lock must be held at this point
-
- if t.cursorX == 0 && t.cursorY == 0 {
- t.writeLine(t.prompt)
- t.c.Write(t.outBuf)
- t.outBuf = t.outBuf[:0]
- }
-
- lineIsPasted := t.pasteActive
-
- for {
- rest := t.remainder
- lineOk := false
- for !lineOk {
- var key rune
- key, rest = bytesToKey(rest, t.pasteActive)
- if key == utf8.RuneError {
- break
- }
- if !t.pasteActive {
- if key == keyCtrlD {
- if len(t.line) == 0 {
- return "", io.EOF
- }
- }
- if key == keyCtrlC {
- return "", io.EOF
- }
- if key == keyPasteStart {
- t.pasteActive = true
- if len(t.line) == 0 {
- lineIsPasted = true
- }
- continue
- }
- } else if key == keyPasteEnd {
- t.pasteActive = false
- continue
- }
- if !t.pasteActive {
- lineIsPasted = false
- }
- line, lineOk = t.handleKey(key)
- }
- if len(rest) > 0 {
- n := copy(t.inBuf[:], rest)
- t.remainder = t.inBuf[:n]
- } else {
- t.remainder = nil
- }
- t.c.Write(t.outBuf)
- t.outBuf = t.outBuf[:0]
- if lineOk {
- if t.echo {
- t.historyIndex = -1
- t.history.Add(line)
- }
- if lineIsPasted {
- err = ErrPasteIndicator
- }
- return
- }
-
- // t.remainder is a slice at the beginning of t.inBuf
- // containing a partial key sequence
- readBuf := t.inBuf[len(t.remainder):]
- var n int
-
- t.lock.Unlock()
- n, err = t.c.Read(readBuf)
- t.lock.Lock()
-
- if err != nil {
- return
- }
-
- t.remainder = t.inBuf[:n+len(t.remainder)]
- }
-}
-
-// SetPrompt sets the prompt to be used when reading subsequent lines.
-func (t *Terminal) SetPrompt(prompt string) {
- t.lock.Lock()
- defer t.lock.Unlock()
-
- t.prompt = []rune(prompt)
-}
-
-func (t *Terminal) clearAndRepaintLinePlusNPrevious(numPrevLines int) {
- // Move cursor to column zero at the start of the line.
- t.move(t.cursorY, 0, t.cursorX, 0)
- t.cursorX, t.cursorY = 0, 0
- t.clearLineToRight()
- for t.cursorY < numPrevLines {
- // Move down a line
- t.move(0, 1, 0, 0)
- t.cursorY++
- t.clearLineToRight()
- }
- // Move back to beginning.
- t.move(t.cursorY, 0, 0, 0)
- t.cursorX, t.cursorY = 0, 0
-
- t.queue(t.prompt)
- t.advanceCursor(visualLength(t.prompt))
- t.writeLine(t.line)
- t.moveCursorToPos(t.pos)
-}
-
-func (t *Terminal) SetSize(width, height int) error {
- t.lock.Lock()
- defer t.lock.Unlock()
-
- if width == 0 {
- width = 1
- }
-
- oldWidth := t.termWidth
- t.termWidth, t.termHeight = width, height
-
- switch {
- case width == oldWidth:
- // If the width didn't change then nothing else needs to be
- // done.
- return nil
- case len(t.line) == 0 && t.cursorX == 0 && t.cursorY == 0:
- // If there is nothing on current line and no prompt printed,
- // just do nothing
- return nil
- case width < oldWidth:
- // Some terminals (e.g. xterm) will truncate lines that were
- // too long when shinking. Others, (e.g. gnome-terminal) will
- // attempt to wrap them. For the former, repainting t.maxLine
- // works great, but that behaviour goes badly wrong in the case
- // of the latter because they have doubled every full line.
-
- // We assume that we are working on a terminal that wraps lines
- // and adjust the cursor position based on every previous line
- // wrapping and turning into two. This causes the prompt on
- // xterms to move upwards, which isn't great, but it avoids a
- // huge mess with gnome-terminal.
- if t.cursorX >= t.termWidth {
- t.cursorX = t.termWidth - 1
- }
- t.cursorY *= 2
- t.clearAndRepaintLinePlusNPrevious(t.maxLine * 2)
- case width > oldWidth:
- // If the terminal expands then our position calculations will
- // be wrong in the future because we think the cursor is
- // |t.pos| chars into the string, but there will be a gap at
- // the end of any wrapped line.
- //
- // But the position will actually be correct until we move, so
- // we can move back to the beginning and repaint everything.
- t.clearAndRepaintLinePlusNPrevious(t.maxLine)
- }
-
- _, err := t.c.Write(t.outBuf)
- t.outBuf = t.outBuf[:0]
- return err
-}
-
-type pasteIndicatorError struct{}
-
-func (pasteIndicatorError) Error() string {
- return "terminal: ErrPasteIndicator not correctly handled"
+ return term.NewTerminal(c, prompt)
}
// ErrPasteIndicator may be returned from ReadLine as the error, in addition
// to valid line data. It indicates that bracketed paste mode is enabled and
// that the returned line consists only of pasted data. Programs may wish to
// interpret pasted data more literally than typed data.
-var ErrPasteIndicator = pasteIndicatorError{}
+var ErrPasteIndicator = term.ErrPasteIndicator
-// SetBracketedPasteMode requests that the terminal bracket paste operations
-// with markers. Not all terminals support this but, if it is supported, then
-// enabling this mode will stop any autocomplete callback from running due to
-// pastes. Additionally, any lines that are completely pasted will be returned
-// from ReadLine with the error set to ErrPasteIndicator.
-func (t *Terminal) SetBracketedPasteMode(on bool) {
- if on {
- io.WriteString(t.c, "\x1b[?2004h")
- } else {
- io.WriteString(t.c, "\x1b[?2004l")
- }
-}
+// State contains the state of a terminal.
+type State = term.State
-// stRingBuffer is a ring buffer of strings.
-type stRingBuffer struct {
- // entries contains max elements.
- entries []string
- max int
- // head contains the index of the element most recently added to the ring.
- head int
- // size contains the number of elements in the ring.
- size int
+// IsTerminal returns whether the given file descriptor is a terminal.
+func IsTerminal(fd int) bool {
+ return term.IsTerminal(fd)
}
-func (s *stRingBuffer) Add(a string) {
- if s.entries == nil {
- const defaultNumEntries = 100
- s.entries = make([]string, defaultNumEntries)
- s.max = defaultNumEntries
- }
+// ReadPassword reads a line of input from a terminal without local echo. This
+// is commonly used for inputting passwords and other sensitive data. The slice
+// returned does not include the \n.
+func ReadPassword(fd int) ([]byte, error) {
+ return term.ReadPassword(fd)
+}
- s.head = (s.head + 1) % s.max
- s.entries[s.head] = a
- if s.size < s.max {
- s.size++
- }
+// MakeRaw puts the terminal connected to the given file descriptor into raw
+// mode and returns the previous state of the terminal so that it can be
+// restored.
+func MakeRaw(fd int) (*State, error) {
+ return term.MakeRaw(fd)
}
-// NthPreviousEntry returns the value passed to the nth previous call to Add.
-// If n is zero then the immediately prior value is returned, if one, then the
-// next most recent, and so on. If such an element doesn't exist then ok is
-// false.
-func (s *stRingBuffer) NthPreviousEntry(n int) (value string, ok bool) {
- if n >= s.size {
- return "", false
- }
- index := s.head - n
- if index < 0 {
- index += s.max
- }
- return s.entries[index], true
+// Restore restores the terminal connected to the given file descriptor to a
+// previous state.
+func Restore(fd int, oldState *State) error {
+ return term.Restore(fd, oldState)
}
-// readPasswordLine reads from reader until it finds \n or io.EOF.
-// The slice returned does not include the \n.
-// readPasswordLine also ignores any \r it finds.
-// Windows uses \r as end of line. So, on Windows, readPasswordLine
-// reads until it finds \r and ignores any \n it finds during processing.
-func readPasswordLine(reader io.Reader) ([]byte, error) {
- var buf [1]byte
- var ret []byte
+// GetState returns the current state of a terminal which may be useful to
+// restore the terminal after a signal.
+func GetState(fd int) (*State, error) {
+ return term.GetState(fd)
+}
- for {
- n, err := reader.Read(buf[:])
- if n > 0 {
- switch buf[0] {
- case '\b':
- if len(ret) > 0 {
- ret = ret[:len(ret)-1]
- }
- case '\n':
- if runtime.GOOS != "windows" {
- return ret, nil
- }
- // otherwise ignore \n
- case '\r':
- if runtime.GOOS == "windows" {
- return ret, nil
- }
- // otherwise ignore \r
- default:
- ret = append(ret, buf[0])
- }
- continue
- }
- if err != nil {
- if err == io.EOF && len(ret) > 0 {
- return ret, nil
- }
- return ret, err
- }
- }
+// GetSize returns the dimensions of the given terminal.
+func GetSize(fd int) (width, height int, err error) {
+ return term.GetSize(fd)
}
diff --git a/vendor/golang.org/x/sys/plan9/asm.s b/vendor/golang.org/x/sys/plan9/asm.s
new file mode 100644
index 000000000..06449ebfa
--- /dev/null
+++ b/vendor/golang.org/x/sys/plan9/asm.s
@@ -0,0 +1,8 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT ·use(SB),NOSPLIT,$0
+ RET
diff --git a/vendor/golang.org/x/sys/plan9/asm_plan9_386.s b/vendor/golang.org/x/sys/plan9/asm_plan9_386.s
new file mode 100644
index 000000000..bc5cab1f3
--- /dev/null
+++ b/vendor/golang.org/x/sys/plan9/asm_plan9_386.s
@@ -0,0 +1,30 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+//
+// System call support for 386, Plan 9
+//
+
+// Just jump to package syscall's implementation for all these functions.
+// The runtime may know about them.
+
+TEXT ·Syscall(SB),NOSPLIT,$0-32
+ JMP syscall·Syscall(SB)
+
+TEXT ·Syscall6(SB),NOSPLIT,$0-44
+ JMP syscall·Syscall6(SB)
+
+TEXT ·RawSyscall(SB),NOSPLIT,$0-28
+ JMP syscall·RawSyscall(SB)
+
+TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
+ JMP syscall·RawSyscall6(SB)
+
+TEXT ·seek(SB),NOSPLIT,$0-36
+ JMP syscall·seek(SB)
+
+TEXT ·exit(SB),NOSPLIT,$4-4
+ JMP syscall·exit(SB)
diff --git a/vendor/golang.org/x/sys/plan9/asm_plan9_amd64.s b/vendor/golang.org/x/sys/plan9/asm_plan9_amd64.s
new file mode 100644
index 000000000..d3448e675
--- /dev/null
+++ b/vendor/golang.org/x/sys/plan9/asm_plan9_amd64.s
@@ -0,0 +1,30 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+//
+// System call support for amd64, Plan 9
+//
+
+// Just jump to package syscall's implementation for all these functions.
+// The runtime may know about them.
+
+TEXT ·Syscall(SB),NOSPLIT,$0-64
+ JMP syscall·Syscall(SB)
+
+TEXT ·Syscall6(SB),NOSPLIT,$0-88
+ JMP syscall·Syscall6(SB)
+
+TEXT ·RawSyscall(SB),NOSPLIT,$0-56
+ JMP syscall·RawSyscall(SB)
+
+TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
+ JMP syscall·RawSyscall6(SB)
+
+TEXT ·seek(SB),NOSPLIT,$0-56
+ JMP syscall·seek(SB)
+
+TEXT ·exit(SB),NOSPLIT,$8-8
+ JMP syscall·exit(SB)
diff --git a/vendor/golang.org/x/sys/plan9/asm_plan9_arm.s b/vendor/golang.org/x/sys/plan9/asm_plan9_arm.s
new file mode 100644
index 000000000..afb7c0a9b
--- /dev/null
+++ b/vendor/golang.org/x/sys/plan9/asm_plan9_arm.s
@@ -0,0 +1,25 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+// System call support for plan9 on arm
+
+// Just jump to package syscall's implementation for all these functions.
+// The runtime may know about them.
+
+TEXT ·Syscall(SB),NOSPLIT,$0-32
+ JMP syscall·Syscall(SB)
+
+TEXT ·Syscall6(SB),NOSPLIT,$0-44
+ JMP syscall·Syscall6(SB)
+
+TEXT ·RawSyscall(SB),NOSPLIT,$0-28
+ JMP syscall·RawSyscall(SB)
+
+TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
+ JMP syscall·RawSyscall6(SB)
+
+TEXT ·seek(SB),NOSPLIT,$0-36
+ JMP syscall·exit(SB)
diff --git a/vendor/golang.org/x/sys/plan9/const_plan9.go b/vendor/golang.org/x/sys/plan9/const_plan9.go
new file mode 100644
index 000000000..b4e85a3a9
--- /dev/null
+++ b/vendor/golang.org/x/sys/plan9/const_plan9.go
@@ -0,0 +1,70 @@
+package plan9
+
+// Plan 9 Constants
+
+// Open modes
+const (
+ O_RDONLY = 0
+ O_WRONLY = 1
+ O_RDWR = 2
+ O_TRUNC = 16
+ O_CLOEXEC = 32
+ O_EXCL = 0x1000
+)
+
+// Rfork flags
+const (
+ RFNAMEG = 1 << 0
+ RFENVG = 1 << 1
+ RFFDG = 1 << 2
+ RFNOTEG = 1 << 3
+ RFPROC = 1 << 4
+ RFMEM = 1 << 5
+ RFNOWAIT = 1 << 6
+ RFCNAMEG = 1 << 10
+ RFCENVG = 1 << 11
+ RFCFDG = 1 << 12
+ RFREND = 1 << 13
+ RFNOMNT = 1 << 14
+)
+
+// Qid.Type bits
+const (
+ QTDIR = 0x80
+ QTAPPEND = 0x40
+ QTEXCL = 0x20
+ QTMOUNT = 0x10
+ QTAUTH = 0x08
+ QTTMP = 0x04
+ QTFILE = 0x00
+)
+
+// Dir.Mode bits
+const (
+ DMDIR = 0x80000000
+ DMAPPEND = 0x40000000
+ DMEXCL = 0x20000000
+ DMMOUNT = 0x10000000
+ DMAUTH = 0x08000000
+ DMTMP = 0x04000000
+ DMREAD = 0x4
+ DMWRITE = 0x2
+ DMEXEC = 0x1
+)
+
+const (
+ STATMAX = 65535
+ ERRMAX = 128
+ STATFIXLEN = 49
+)
+
+// Mount and bind flags
+const (
+ MREPL = 0x0000
+ MBEFORE = 0x0001
+ MAFTER = 0x0002
+ MORDER = 0x0003
+ MCREATE = 0x0004
+ MCACHE = 0x0010
+ MMASK = 0x0017
+)
diff --git a/vendor/golang.org/x/sys/plan9/dir_plan9.go b/vendor/golang.org/x/sys/plan9/dir_plan9.go
new file mode 100644
index 000000000..0955e0c53
--- /dev/null
+++ b/vendor/golang.org/x/sys/plan9/dir_plan9.go
@@ -0,0 +1,212 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Plan 9 directory marshalling. See intro(5).
+
+package plan9
+
+import "errors"
+
+var (
+ ErrShortStat = errors.New("stat buffer too short")
+ ErrBadStat = errors.New("malformed stat buffer")
+ ErrBadName = errors.New("bad character in file name")
+)
+
+// A Qid represents a 9P server's unique identification for a file.
+type Qid struct {
+ Path uint64 // the file server's unique identification for the file
+ Vers uint32 // version number for given Path
+ Type uint8 // the type of the file (plan9.QTDIR for example)
+}
+
+// A Dir contains the metadata for a file.
+type Dir struct {
+ // system-modified data
+ Type uint16 // server type
+ Dev uint32 // server subtype
+
+ // file data
+ Qid Qid // unique id from server
+ Mode uint32 // permissions
+ Atime uint32 // last read time
+ Mtime uint32 // last write time
+ Length int64 // file length
+ Name string // last element of path
+ Uid string // owner name
+ Gid string // group name
+ Muid string // last modifier name
+}
+
+var nullDir = Dir{
+ Type: ^uint16(0),
+ Dev: ^uint32(0),
+ Qid: Qid{
+ Path: ^uint64(0),
+ Vers: ^uint32(0),
+ Type: ^uint8(0),
+ },
+ Mode: ^uint32(0),
+ Atime: ^uint32(0),
+ Mtime: ^uint32(0),
+ Length: ^int64(0),
+}
+
+// Null assigns special "don't touch" values to members of d to
+// avoid modifying them during plan9.Wstat.
+func (d *Dir) Null() { *d = nullDir }
+
+// Marshal encodes a 9P stat message corresponding to d into b
+//
+// If there isn't enough space in b for a stat message, ErrShortStat is returned.
+func (d *Dir) Marshal(b []byte) (n int, err error) {
+ n = STATFIXLEN + len(d.Name) + len(d.Uid) + len(d.Gid) + len(d.Muid)
+ if n > len(b) {
+ return n, ErrShortStat
+ }
+
+ for _, c := range d.Name {
+ if c == '/' {
+ return n, ErrBadName
+ }
+ }
+
+ b = pbit16(b, uint16(n)-2)
+ b = pbit16(b, d.Type)
+ b = pbit32(b, d.Dev)
+ b = pbit8(b, d.Qid.Type)
+ b = pbit32(b, d.Qid.Vers)
+ b = pbit64(b, d.Qid.Path)
+ b = pbit32(b, d.Mode)
+ b = pbit32(b, d.Atime)
+ b = pbit32(b, d.Mtime)
+ b = pbit64(b, uint64(d.Length))
+ b = pstring(b, d.Name)
+ b = pstring(b, d.Uid)
+ b = pstring(b, d.Gid)
+ b = pstring(b, d.Muid)
+
+ return n, nil
+}
+
+// UnmarshalDir decodes a single 9P stat message from b and returns the resulting Dir.
+//
+// If b is too small to hold a valid stat message, ErrShortStat is returned.
+//
+// If the stat message itself is invalid, ErrBadStat is returned.
+func UnmarshalDir(b []byte) (*Dir, error) {
+ if len(b) < STATFIXLEN {
+ return nil, ErrShortStat
+ }
+ size, buf := gbit16(b)
+ if len(b) != int(size)+2 {
+ return nil, ErrBadStat
+ }
+ b = buf
+
+ var d Dir
+ d.Type, b = gbit16(b)
+ d.Dev, b = gbit32(b)
+ d.Qid.Type, b = gbit8(b)
+ d.Qid.Vers, b = gbit32(b)
+ d.Qid.Path, b = gbit64(b)
+ d.Mode, b = gbit32(b)
+ d.Atime, b = gbit32(b)
+ d.Mtime, b = gbit32(b)
+
+ n, b := gbit64(b)
+ d.Length = int64(n)
+
+ var ok bool
+ if d.Name, b, ok = gstring(b); !ok {
+ return nil, ErrBadStat
+ }
+ if d.Uid, b, ok = gstring(b); !ok {
+ return nil, ErrBadStat
+ }
+ if d.Gid, b, ok = gstring(b); !ok {
+ return nil, ErrBadStat
+ }
+ if d.Muid, b, ok = gstring(b); !ok {
+ return nil, ErrBadStat
+ }
+
+ return &d, nil
+}
+
+// pbit8 copies the 8-bit number v to b and returns the remaining slice of b.
+func pbit8(b []byte, v uint8) []byte {
+ b[0] = byte(v)
+ return b[1:]
+}
+
+// pbit16 copies the 16-bit number v to b in little-endian order and returns the remaining slice of b.
+func pbit16(b []byte, v uint16) []byte {
+ b[0] = byte(v)
+ b[1] = byte(v >> 8)
+ return b[2:]
+}
+
+// pbit32 copies the 32-bit number v to b in little-endian order and returns the remaining slice of b.
+func pbit32(b []byte, v uint32) []byte {
+ b[0] = byte(v)
+ b[1] = byte(v >> 8)
+ b[2] = byte(v >> 16)
+ b[3] = byte(v >> 24)
+ return b[4:]
+}
+
+// pbit64 copies the 64-bit number v to b in little-endian order and returns the remaining slice of b.
+func pbit64(b []byte, v uint64) []byte {
+ b[0] = byte(v)
+ b[1] = byte(v >> 8)
+ b[2] = byte(v >> 16)
+ b[3] = byte(v >> 24)
+ b[4] = byte(v >> 32)
+ b[5] = byte(v >> 40)
+ b[6] = byte(v >> 48)
+ b[7] = byte(v >> 56)
+ return b[8:]
+}
+
+// pstring copies the string s to b, prepending it with a 16-bit length in little-endian order, and
+// returning the remaining slice of b..
+func pstring(b []byte, s string) []byte {
+ b = pbit16(b, uint16(len(s)))
+ n := copy(b, s)
+ return b[n:]
+}
+
+// gbit8 reads an 8-bit number from b and returns it with the remaining slice of b.
+func gbit8(b []byte) (uint8, []byte) {
+ return uint8(b[0]), b[1:]
+}
+
+// gbit16 reads a 16-bit number in little-endian order from b and returns it with the remaining slice of b.
+func gbit16(b []byte) (uint16, []byte) {
+ return uint16(b[0]) | uint16(b[1])<<8, b[2:]
+}
+
+// gbit32 reads a 32-bit number in little-endian order from b and returns it with the remaining slice of b.
+func gbit32(b []byte) (uint32, []byte) {
+ return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24, b[4:]
+}
+
+// gbit64 reads a 64-bit number in little-endian order from b and returns it with the remaining slice of b.
+func gbit64(b []byte) (uint64, []byte) {
+ lo := uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
+ hi := uint32(b[4]) | uint32(b[5])<<8 | uint32(b[6])<<16 | uint32(b[7])<<24
+ return uint64(lo) | uint64(hi)<<32, b[8:]
+}
+
+// gstring reads a string from b, prefixed with a 16-bit length in little-endian order.
+// It returns the string with the remaining slice of b and a boolean. If the length is
+// greater than the number of bytes in b, the boolean will be false.
+func gstring(b []byte) (string, []byte, bool) {
+ n, b := gbit16(b)
+ if int(n) > len(b) {
+ return "", b, false
+ }
+ return string(b[:n]), b[n:], true
+}
diff --git a/vendor/golang.org/x/sys/plan9/env_plan9.go b/vendor/golang.org/x/sys/plan9/env_plan9.go
new file mode 100644
index 000000000..8f1918004
--- /dev/null
+++ b/vendor/golang.org/x/sys/plan9/env_plan9.go
@@ -0,0 +1,31 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Plan 9 environment variables.
+
+package plan9
+
+import (
+ "syscall"
+)
+
+func Getenv(key string) (value string, found bool) {
+ return syscall.Getenv(key)
+}
+
+func Setenv(key, value string) error {
+ return syscall.Setenv(key, value)
+}
+
+func Clearenv() {
+ syscall.Clearenv()
+}
+
+func Environ() []string {
+ return syscall.Environ()
+}
+
+func Unsetenv(key string) error {
+ return syscall.Unsetenv(key)
+}
diff --git a/vendor/golang.org/x/sys/plan9/errors_plan9.go b/vendor/golang.org/x/sys/plan9/errors_plan9.go
new file mode 100644
index 000000000..65fe74d3e
--- /dev/null
+++ b/vendor/golang.org/x/sys/plan9/errors_plan9.go
@@ -0,0 +1,50 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package plan9
+
+import "syscall"
+
+// Constants
+const (
+ // Invented values to support what package os expects.
+ O_CREAT = 0x02000
+ O_APPEND = 0x00400
+ O_NOCTTY = 0x00000
+ O_NONBLOCK = 0x00000
+ O_SYNC = 0x00000
+ O_ASYNC = 0x00000
+
+ S_IFMT = 0x1f000
+ S_IFIFO = 0x1000
+ S_IFCHR = 0x2000
+ S_IFDIR = 0x4000
+ S_IFBLK = 0x6000
+ S_IFREG = 0x8000
+ S_IFLNK = 0xa000
+ S_IFSOCK = 0xc000
+)
+
+// Errors
+var (
+ EINVAL = syscall.NewError("bad arg in system call")
+ ENOTDIR = syscall.NewError("not a directory")
+ EISDIR = syscall.NewError("file is a directory")
+ ENOENT = syscall.NewError("file does not exist")
+ EEXIST = syscall.NewError("file already exists")
+ EMFILE = syscall.NewError("no free file descriptors")
+ EIO = syscall.NewError("i/o error")
+ ENAMETOOLONG = syscall.NewError("file name too long")
+ EINTR = syscall.NewError("interrupted")
+ EPERM = syscall.NewError("permission denied")
+ EBUSY = syscall.NewError("no free devices")
+ ETIMEDOUT = syscall.NewError("connection timed out")
+ EPLAN9 = syscall.NewError("not supported by plan 9")
+
+ // The following errors do not correspond to any
+ // Plan 9 system messages. Invented to support
+ // what package os and others expect.
+ EACCES = syscall.NewError("access permission denied")
+ EAFNOSUPPORT = syscall.NewError("address family not supported by protocol")
+)
diff --git a/vendor/golang.org/x/sys/plan9/mkall.sh b/vendor/golang.org/x/sys/plan9/mkall.sh
new file mode 100644
index 000000000..1650fbcc7
--- /dev/null
+++ b/vendor/golang.org/x/sys/plan9/mkall.sh
@@ -0,0 +1,150 @@
+#!/usr/bin/env bash
+# Copyright 2009 The Go Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
+
+# The plan9 package provides access to the raw system call
+# interface of the underlying operating system. Porting Go to
+# a new architecture/operating system combination requires
+# some manual effort, though there are tools that automate
+# much of the process. The auto-generated files have names
+# beginning with z.
+#
+# This script runs or (given -n) prints suggested commands to generate z files
+# for the current system. Running those commands is not automatic.
+# This script is documentation more than anything else.
+#
+# * asm_${GOOS}_${GOARCH}.s
+#
+# This hand-written assembly file implements system call dispatch.
+# There are three entry points:
+#
+# func Syscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr);
+# func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr);
+# func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr);
+#
+# The first and second are the standard ones; they differ only in
+# how many arguments can be passed to the kernel.
+# The third is for low-level use by the ForkExec wrapper;
+# unlike the first two, it does not call into the scheduler to
+# let it know that a system call is running.
+#
+# * syscall_${GOOS}.go
+#
+# This hand-written Go file implements system calls that need
+# special handling and lists "//sys" comments giving prototypes
+# for ones that can be auto-generated. Mksyscall reads those
+# comments to generate the stubs.
+#
+# * syscall_${GOOS}_${GOARCH}.go
+#
+# Same as syscall_${GOOS}.go except that it contains code specific
+# to ${GOOS} on one particular architecture.
+#
+# * types_${GOOS}.c
+#
+# This hand-written C file includes standard C headers and then
+# creates typedef or enum names beginning with a dollar sign
+# (use of $ in variable names is a gcc extension). The hardest
+# part about preparing this file is figuring out which headers to
+# include and which symbols need to be #defined to get the
+# actual data structures that pass through to the kernel system calls.
+# Some C libraries present alternate versions for binary compatibility
+# and translate them on the way in and out of system calls, but
+# there is almost always a #define that can get the real ones.
+# See types_darwin.c and types_linux.c for examples.
+#
+# * zerror_${GOOS}_${GOARCH}.go
+#
+# This machine-generated file defines the system's error numbers,
+# error strings, and signal numbers. The generator is "mkerrors.sh".
+# Usually no arguments are needed, but mkerrors.sh will pass its
+# arguments on to godefs.
+#
+# * zsyscall_${GOOS}_${GOARCH}.go
+#
+# Generated by mksyscall.pl; see syscall_${GOOS}.go above.
+#
+# * zsysnum_${GOOS}_${GOARCH}.go
+#
+# Generated by mksysnum_${GOOS}.
+#
+# * ztypes_${GOOS}_${GOARCH}.go
+#
+# Generated by godefs; see types_${GOOS}.c above.
+
+GOOSARCH="${GOOS}_${GOARCH}"
+
+# defaults
+mksyscall="go run mksyscall.go"
+mkerrors="./mkerrors.sh"
+zerrors="zerrors_$GOOSARCH.go"
+mksysctl=""
+zsysctl="zsysctl_$GOOSARCH.go"
+mksysnum=
+mktypes=
+run="sh"
+
+case "$1" in
+-syscalls)
+ for i in zsyscall*go
+ do
+ sed 1q $i | sed 's;^// ;;' | sh > _$i && gofmt < _$i > $i
+ rm _$i
+ done
+ exit 0
+ ;;
+-n)
+ run="cat"
+ shift
+esac
+
+case "$#" in
+0)
+ ;;
+*)
+ echo 'usage: mkall.sh [-n]' 1>&2
+ exit 2
+esac
+
+case "$GOOSARCH" in
+_* | *_ | _)
+ echo 'undefined $GOOS_$GOARCH:' "$GOOSARCH" 1>&2
+ exit 1
+ ;;
+plan9_386)
+ mkerrors=
+ mksyscall="go run mksyscall.go -l32 -plan9 -tags plan9,386"
+ mksysnum="./mksysnum_plan9.sh /n/sources/plan9/sys/src/libc/9syscall/sys.h"
+ mktypes="XXX"
+ ;;
+plan9_amd64)
+ mkerrors=
+ mksyscall="go run mksyscall.go -l32 -plan9 -tags plan9,amd64"
+ mksysnum="./mksysnum_plan9.sh /n/sources/plan9/sys/src/libc/9syscall/sys.h"
+ mktypes="XXX"
+ ;;
+plan9_arm)
+ mkerrors=
+ mksyscall="go run mksyscall.go -l32 -plan9 -tags plan9,arm"
+ mksysnum="./mksysnum_plan9.sh /n/sources/plan9/sys/src/libc/9syscall/sys.h"
+ mktypes="XXX"
+ ;;
+*)
+ echo 'unrecognized $GOOS_$GOARCH: ' "$GOOSARCH" 1>&2
+ exit 1
+ ;;
+esac
+
+(
+ if [ -n "$mkerrors" ]; then echo "$mkerrors |gofmt >$zerrors"; fi
+ case "$GOOS" in
+ plan9)
+ syscall_goos="syscall_$GOOS.go"
+ if [ -n "$mksyscall" ]; then echo "$mksyscall $syscall_goos |gofmt >zsyscall_$GOOSARCH.go"; fi
+ ;;
+ esac
+ if [ -n "$mksysctl" ]; then echo "$mksysctl |gofmt >$zsysctl"; fi
+ if [ -n "$mksysnum" ]; then echo "$mksysnum |gofmt >zsysnum_$GOOSARCH.go"; fi
+ if [ -n "$mktypes" ]; then echo "$mktypes types_$GOOS.go |gofmt >ztypes_$GOOSARCH.go"; fi
+) | $run
diff --git a/vendor/golang.org/x/sys/plan9/mkerrors.sh b/vendor/golang.org/x/sys/plan9/mkerrors.sh
new file mode 100644
index 000000000..85309c4a5
--- /dev/null
+++ b/vendor/golang.org/x/sys/plan9/mkerrors.sh
@@ -0,0 +1,246 @@
+#!/usr/bin/env bash
+# Copyright 2009 The Go Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
+
+# Generate Go code listing errors and other #defined constant
+# values (ENAMETOOLONG etc.), by asking the preprocessor
+# about the definitions.
+
+unset LANG
+export LC_ALL=C
+export LC_CTYPE=C
+
+CC=${CC:-gcc}
+
+uname=$(uname)
+
+includes='
+#include <sys/types.h>
+#include <sys/file.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <netinet/ip6.h>
+#include <netinet/tcp.h>
+#include <errno.h>
+#include <sys/signal.h>
+#include <signal.h>
+#include <sys/resource.h>
+'
+
+ccflags="$@"
+
+# Write go tool cgo -godefs input.
+(
+ echo package plan9
+ echo
+ echo '/*'
+ indirect="includes_$(uname)"
+ echo "${!indirect} $includes"
+ echo '*/'
+ echo 'import "C"'
+ echo
+ echo 'const ('
+
+ # The gcc command line prints all the #defines
+ # it encounters while processing the input
+ echo "${!indirect} $includes" | $CC -x c - -E -dM $ccflags |
+ awk '
+ $1 != "#define" || $2 ~ /\(/ || $3 == "" {next}
+
+ $2 ~ /^E([ABCD]X|[BIS]P|[SD]I|S|FL)$/ {next} # 386 registers
+ $2 ~ /^(SIGEV_|SIGSTKSZ|SIGRT(MIN|MAX))/ {next}
+ $2 ~ /^(SCM_SRCRT)$/ {next}
+ $2 ~ /^(MAP_FAILED)$/ {next}
+
+ $2 !~ /^ETH_/ &&
+ $2 !~ /^EPROC_/ &&
+ $2 !~ /^EQUIV_/ &&
+ $2 !~ /^EXPR_/ &&
+ $2 ~ /^E[A-Z0-9_]+$/ ||
+ $2 ~ /^B[0-9_]+$/ ||
+ $2 ~ /^V[A-Z0-9]+$/ ||
+ $2 ~ /^CS[A-Z0-9]/ ||
+ $2 ~ /^I(SIG|CANON|CRNL|EXTEN|MAXBEL|STRIP|UTF8)$/ ||
+ $2 ~ /^IGN/ ||
+ $2 ~ /^IX(ON|ANY|OFF)$/ ||
+ $2 ~ /^IN(LCR|PCK)$/ ||
+ $2 ~ /(^FLU?SH)|(FLU?SH$)/ ||
+ $2 ~ /^C(LOCAL|READ)$/ ||
+ $2 == "BRKINT" ||
+ $2 == "HUPCL" ||
+ $2 == "PENDIN" ||
+ $2 == "TOSTOP" ||
+ $2 ~ /^PAR/ ||
+ $2 ~ /^SIG[^_]/ ||
+ $2 ~ /^O[CNPFP][A-Z]+[^_][A-Z]+$/ ||
+ $2 ~ /^IN_/ ||
+ $2 ~ /^LOCK_(SH|EX|NB|UN)$/ ||
+ $2 ~ /^(AF|SOCK|SO|SOL|IPPROTO|IP|IPV6|ICMP6|TCP|EVFILT|NOTE|EV|SHUT|PROT|MAP|PACKET|MSG|SCM|MCL|DT|MADV|PR)_/ ||
+ $2 == "ICMPV6_FILTER" ||
+ $2 == "SOMAXCONN" ||
+ $2 == "NAME_MAX" ||
+ $2 == "IFNAMSIZ" ||
+ $2 ~ /^CTL_(MAXNAME|NET|QUERY)$/ ||
+ $2 ~ /^SYSCTL_VERS/ ||
+ $2 ~ /^(MS|MNT)_/ ||
+ $2 ~ /^TUN(SET|GET|ATTACH|DETACH)/ ||
+ $2 ~ /^(O|F|FD|NAME|S|PTRACE|PT)_/ ||
+ $2 ~ /^LINUX_REBOOT_CMD_/ ||
+ $2 ~ /^LINUX_REBOOT_MAGIC[12]$/ ||
+ $2 !~ "NLA_TYPE_MASK" &&
+ $2 ~ /^(NETLINK|NLM|NLMSG|NLA|IFA|IFAN|RT|RTCF|RTN|RTPROT|RTNH|ARPHRD|ETH_P)_/ ||
+ $2 ~ /^SIOC/ ||
+ $2 ~ /^TIOC/ ||
+ $2 !~ "RTF_BITS" &&
+ $2 ~ /^(IFF|IFT|NET_RT|RTM|RTF|RTV|RTA|RTAX)_/ ||
+ $2 ~ /^BIOC/ ||
+ $2 ~ /^RUSAGE_(SELF|CHILDREN|THREAD)/ ||
+ $2 ~ /^RLIMIT_(AS|CORE|CPU|DATA|FSIZE|NOFILE|STACK)|RLIM_INFINITY/ ||
+ $2 ~ /^PRIO_(PROCESS|PGRP|USER)/ ||
+ $2 ~ /^CLONE_[A-Z_]+/ ||
+ $2 !~ /^(BPF_TIMEVAL)$/ &&
+ $2 ~ /^(BPF|DLT)_/ ||
+ $2 !~ "WMESGLEN" &&
+ $2 ~ /^W[A-Z0-9]+$/ {printf("\t%s = C.%s\n", $2, $2)}
+ $2 ~ /^__WCOREFLAG$/ {next}
+ $2 ~ /^__W[A-Z0-9]+$/ {printf("\t%s = C.%s\n", substr($2,3), $2)}
+
+ {next}
+ ' | sort
+
+ echo ')'
+) >_const.go
+
+# Pull out the error names for later.
+errors=$(
+ echo '#include <errno.h>' | $CC -x c - -E -dM $ccflags |
+ awk '$1=="#define" && $2 ~ /^E[A-Z0-9_]+$/ { print $2 }' |
+ sort
+)
+
+# Pull out the signal names for later.
+signals=$(
+ echo '#include <signal.h>' | $CC -x c - -E -dM $ccflags |
+ awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print $2 }' |
+ egrep -v '(SIGSTKSIZE|SIGSTKSZ|SIGRT)' |
+ sort
+)
+
+# Again, writing regexps to a file.
+echo '#include <errno.h>' | $CC -x c - -E -dM $ccflags |
+ awk '$1=="#define" && $2 ~ /^E[A-Z0-9_]+$/ { print "^\t" $2 "[ \t]*=" }' |
+ sort >_error.grep
+echo '#include <signal.h>' | $CC -x c - -E -dM $ccflags |
+ awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print "^\t" $2 "[ \t]*=" }' |
+ egrep -v '(SIGSTKSIZE|SIGSTKSZ|SIGRT)' |
+ sort >_signal.grep
+
+echo '// mkerrors.sh' "$@"
+echo '// Code generated by the command above; DO NOT EDIT.'
+echo
+go tool cgo -godefs -- "$@" _const.go >_error.out
+cat _error.out | grep -vf _error.grep | grep -vf _signal.grep
+echo
+echo '// Errors'
+echo 'const ('
+cat _error.out | grep -f _error.grep | sed 's/=\(.*\)/= Errno(\1)/'
+echo ')'
+
+echo
+echo '// Signals'
+echo 'const ('
+cat _error.out | grep -f _signal.grep | sed 's/=\(.*\)/= Signal(\1)/'
+echo ')'
+
+# Run C program to print error and syscall strings.
+(
+ echo -E "
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <ctype.h>
+#include <string.h>
+#include <signal.h>
+
+#define nelem(x) (sizeof(x)/sizeof((x)[0]))
+
+enum { A = 'A', Z = 'Z', a = 'a', z = 'z' }; // avoid need for single quotes below
+
+int errors[] = {
+"
+ for i in $errors
+ do
+ echo -E ' '$i,
+ done
+
+ echo -E "
+};
+
+int signals[] = {
+"
+ for i in $signals
+ do
+ echo -E ' '$i,
+ done
+
+ # Use -E because on some systems bash builtin interprets \n itself.
+ echo -E '
+};
+
+static int
+intcmp(const void *a, const void *b)
+{
+ return *(int*)a - *(int*)b;
+}
+
+int
+main(void)
+{
+ int i, j, e;
+ char buf[1024], *p;
+
+ printf("\n\n// Error table\n");
+ printf("var errors = [...]string {\n");
+ qsort(errors, nelem(errors), sizeof errors[0], intcmp);
+ for(i=0; i<nelem(errors); i++) {
+ e = errors[i];
+ if(i > 0 && errors[i-1] == e)
+ continue;
+ strcpy(buf, strerror(e));
+ // lowercase first letter: Bad -> bad, but STREAM -> STREAM.
+ if(A <= buf[0] && buf[0] <= Z && a <= buf[1] && buf[1] <= z)
+ buf[0] += a - A;
+ printf("\t%d: \"%s\",\n", e, buf);
+ }
+ printf("}\n\n");
+
+ printf("\n\n// Signal table\n");
+ printf("var signals = [...]string {\n");
+ qsort(signals, nelem(signals), sizeof signals[0], intcmp);
+ for(i=0; i<nelem(signals); i++) {
+ e = signals[i];
+ if(i > 0 && signals[i-1] == e)
+ continue;
+ strcpy(buf, strsignal(e));
+ // lowercase first letter: Bad -> bad, but STREAM -> STREAM.
+ if(A <= buf[0] && buf[0] <= Z && a <= buf[1] && buf[1] <= z)
+ buf[0] += a - A;
+ // cut trailing : number.
+ p = strrchr(buf, ":"[0]);
+ if(p)
+ *p = '\0';
+ printf("\t%d: \"%s\",\n", e, buf);
+ }
+ printf("}\n\n");
+
+ return 0;
+}
+
+'
+) >_errors.c
+
+$CC $ccflags -o _errors _errors.c && $GORUN ./_errors && rm -f _errors.c _errors _const.go _error.grep _signal.grep _error.out
diff --git a/vendor/golang.org/x/sys/plan9/mksysnum_plan9.sh b/vendor/golang.org/x/sys/plan9/mksysnum_plan9.sh
new file mode 100644
index 000000000..3c3ab0581
--- /dev/null
+++ b/vendor/golang.org/x/sys/plan9/mksysnum_plan9.sh
@@ -0,0 +1,23 @@
+#!/bin/sh
+# 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.
+
+COMMAND="mksysnum_plan9.sh $@"
+
+cat <<EOF
+// $COMMAND
+// MACHINE GENERATED BY THE ABOVE COMMAND; DO NOT EDIT
+
+package plan9
+
+const(
+EOF
+
+SP='[ ]' # space or tab
+sed "s/^#define${SP}\\([A-Z0-9_][A-Z0-9_]*\\)${SP}${SP}*\\([0-9][0-9]*\\)/SYS_\\1=\\2/g" \
+ < $1 | grep -v SYS__
+
+cat <<EOF
+)
+EOF
diff --git a/vendor/golang.org/x/sys/plan9/pwd_go15_plan9.go b/vendor/golang.org/x/sys/plan9/pwd_go15_plan9.go
new file mode 100644
index 000000000..87ae9d2a3
--- /dev/null
+++ b/vendor/golang.org/x/sys/plan9/pwd_go15_plan9.go
@@ -0,0 +1,21 @@
+// 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 go1.5
+
+package plan9
+
+import "syscall"
+
+func fixwd() {
+ syscall.Fixwd()
+}
+
+func Getwd() (wd string, err error) {
+ return syscall.Getwd()
+}
+
+func Chdir(path string) error {
+ return syscall.Chdir(path)
+}
diff --git a/vendor/golang.org/x/sys/plan9/pwd_plan9.go b/vendor/golang.org/x/sys/plan9/pwd_plan9.go
new file mode 100644
index 000000000..c07c798bc
--- /dev/null
+++ b/vendor/golang.org/x/sys/plan9/pwd_plan9.go
@@ -0,0 +1,23 @@
+// 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 !go1.5
+
+package plan9
+
+func fixwd() {
+}
+
+func Getwd() (wd string, err error) {
+ fd, err := open(".", O_RDONLY)
+ if err != nil {
+ return "", err
+ }
+ defer Close(fd)
+ return Fd2path(fd)
+}
+
+func Chdir(path string) error {
+ return chdir(path)
+}
diff --git a/vendor/golang.org/x/sys/plan9/race.go b/vendor/golang.org/x/sys/plan9/race.go
new file mode 100644
index 000000000..42edd93ef
--- /dev/null
+++ b/vendor/golang.org/x/sys/plan9/race.go
@@ -0,0 +1,30 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build plan9,race
+
+package plan9
+
+import (
+ "runtime"
+ "unsafe"
+)
+
+const raceenabled = true
+
+func raceAcquire(addr unsafe.Pointer) {
+ runtime.RaceAcquire(addr)
+}
+
+func raceReleaseMerge(addr unsafe.Pointer) {
+ runtime.RaceReleaseMerge(addr)
+}
+
+func raceReadRange(addr unsafe.Pointer, len int) {
+ runtime.RaceReadRange(addr, len)
+}
+
+func raceWriteRange(addr unsafe.Pointer, len int) {
+ runtime.RaceWriteRange(addr, len)
+}
diff --git a/vendor/golang.org/x/sys/plan9/race0.go b/vendor/golang.org/x/sys/plan9/race0.go
new file mode 100644
index 000000000..c89cf8fc0
--- /dev/null
+++ b/vendor/golang.org/x/sys/plan9/race0.go
@@ -0,0 +1,25 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build plan9,!race
+
+package plan9
+
+import (
+ "unsafe"
+)
+
+const raceenabled = false
+
+func raceAcquire(addr unsafe.Pointer) {
+}
+
+func raceReleaseMerge(addr unsafe.Pointer) {
+}
+
+func raceReadRange(addr unsafe.Pointer, len int) {
+}
+
+func raceWriteRange(addr unsafe.Pointer, len int) {
+}
diff --git a/vendor/golang.org/x/sys/plan9/str.go b/vendor/golang.org/x/sys/plan9/str.go
new file mode 100644
index 000000000..4f7f9ad7c
--- /dev/null
+++ b/vendor/golang.org/x/sys/plan9/str.go
@@ -0,0 +1,22 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build plan9
+
+package plan9
+
+func itoa(val int) string { // do it here rather than with fmt to avoid dependency
+ if val < 0 {
+ return "-" + itoa(-val)
+ }
+ var buf [32]byte // big enough for int64
+ i := len(buf) - 1
+ for val >= 10 {
+ buf[i] = byte(val%10 + '0')
+ i--
+ val /= 10
+ }
+ buf[i] = byte(val + '0')
+ return string(buf[i:])
+}
diff --git a/vendor/golang.org/x/sys/plan9/syscall.go b/vendor/golang.org/x/sys/plan9/syscall.go
new file mode 100644
index 000000000..e7363a2f5
--- /dev/null
+++ b/vendor/golang.org/x/sys/plan9/syscall.go
@@ -0,0 +1,116 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build plan9
+
+// Package plan9 contains an interface to the low-level operating system
+// primitives. OS details vary depending on the underlying system, and
+// by default, godoc will display the OS-specific documentation for the current
+// system. If you want godoc to display documentation for another
+// system, set $GOOS and $GOARCH to the desired system. For example, if
+// you want to view documentation for freebsd/arm on linux/amd64, set $GOOS
+// to freebsd and $GOARCH to arm.
+//
+// The primary use of this package is inside other packages that provide a more
+// portable interface to the system, such as "os", "time" and "net". Use
+// those packages rather than this one if you can.
+//
+// For details of the functions and data types in this package consult
+// the manuals for the appropriate operating system.
+//
+// These calls return err == nil to indicate success; otherwise
+// err represents an operating system error describing the failure and
+// holds a value of type syscall.ErrorString.
+package plan9 // import "golang.org/x/sys/plan9"
+
+import (
+ "bytes"
+ "strings"
+ "unsafe"
+
+ "golang.org/x/sys/internal/unsafeheader"
+)
+
+// ByteSliceFromString returns a NUL-terminated slice of bytes
+// containing the text of s. If s contains a NUL byte at any
+// location, it returns (nil, EINVAL).
+func ByteSliceFromString(s string) ([]byte, error) {
+ if strings.IndexByte(s, 0) != -1 {
+ return nil, EINVAL
+ }
+ a := make([]byte, len(s)+1)
+ copy(a, s)
+ return a, nil
+}
+
+// BytePtrFromString returns a pointer to a NUL-terminated array of
+// bytes containing the text of s. If s contains a NUL byte at any
+// location, it returns (nil, EINVAL).
+func BytePtrFromString(s string) (*byte, error) {
+ a, err := ByteSliceFromString(s)
+ if err != nil {
+ return nil, err
+ }
+ return &a[0], nil
+}
+
+// ByteSliceToString returns a string form of the text represented by the slice s, with a terminating NUL and any
+// bytes after the NUL removed.
+func ByteSliceToString(s []byte) string {
+ if i := bytes.IndexByte(s, 0); i != -1 {
+ s = s[:i]
+ }
+ return string(s)
+}
+
+// BytePtrToString takes a pointer to a sequence of text and returns the corresponding string.
+// If the pointer is nil, it returns the empty string. It assumes that the text sequence is terminated
+// at a zero byte; if the zero byte is not present, the program may crash.
+func BytePtrToString(p *byte) string {
+ if p == nil {
+ return ""
+ }
+ if *p == 0 {
+ return ""
+ }
+
+ // Find NUL terminator.
+ n := 0
+ for ptr := unsafe.Pointer(p); *(*byte)(ptr) != 0; n++ {
+ ptr = unsafe.Pointer(uintptr(ptr) + 1)
+ }
+
+ var s []byte
+ h := (*unsafeheader.Slice)(unsafe.Pointer(&s))
+ h.Data = unsafe.Pointer(p)
+ h.Len = n
+ h.Cap = n
+
+ return string(s)
+}
+
+// Single-word zero for use when we need a valid pointer to 0 bytes.
+// See mksyscall.pl.
+var _zero uintptr
+
+func (ts *Timespec) Unix() (sec int64, nsec int64) {
+ return int64(ts.Sec), int64(ts.Nsec)
+}
+
+func (tv *Timeval) Unix() (sec int64, nsec int64) {
+ return int64(tv.Sec), int64(tv.Usec) * 1000
+}
+
+func (ts *Timespec) Nano() int64 {
+ return int64(ts.Sec)*1e9 + int64(ts.Nsec)
+}
+
+func (tv *Timeval) Nano() int64 {
+ return int64(tv.Sec)*1e9 + int64(tv.Usec)*1000
+}
+
+// use is a no-op, but the compiler cannot see that it is.
+// Calling use(p) ensures that p is kept live until that point.
+//go:noescape
+func use(p unsafe.Pointer)
diff --git a/vendor/golang.org/x/sys/plan9/syscall_plan9.go b/vendor/golang.org/x/sys/plan9/syscall_plan9.go
new file mode 100644
index 000000000..84e147148
--- /dev/null
+++ b/vendor/golang.org/x/sys/plan9/syscall_plan9.go
@@ -0,0 +1,349 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Plan 9 system calls.
+// This file is compiled as ordinary Go code,
+// but it is also input to mksyscall,
+// which parses the //sys lines and generates system call stubs.
+// Note that sometimes we use a lowercase //sys name and
+// wrap it in our own nicer implementation.
+
+package plan9
+
+import (
+ "bytes"
+ "syscall"
+ "unsafe"
+)
+
+// A Note is a string describing a process note.
+// It implements the os.Signal interface.
+type Note string
+
+func (n Note) Signal() {}
+
+func (n Note) String() string {
+ return string(n)
+}
+
+var (
+ Stdin = 0
+ Stdout = 1
+ Stderr = 2
+)
+
+// For testing: clients can set this flag to force
+// creation of IPv6 sockets to return EAFNOSUPPORT.
+var SocketDisableIPv6 bool
+
+func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.ErrorString)
+func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.ErrorString)
+func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr)
+func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr)
+
+func atoi(b []byte) (n uint) {
+ n = 0
+ for i := 0; i < len(b); i++ {
+ n = n*10 + uint(b[i]-'0')
+ }
+ return
+}
+
+func cstring(s []byte) string {
+ i := bytes.IndexByte(s, 0)
+ if i == -1 {
+ i = len(s)
+ }
+ return string(s[:i])
+}
+
+func errstr() string {
+ var buf [ERRMAX]byte
+
+ RawSyscall(SYS_ERRSTR, uintptr(unsafe.Pointer(&buf[0])), uintptr(len(buf)), 0)
+
+ buf[len(buf)-1] = 0
+ return cstring(buf[:])
+}
+
+// Implemented in assembly to import from runtime.
+func exit(code int)
+
+func Exit(code int) { exit(code) }
+
+func readnum(path string) (uint, error) {
+ var b [12]byte
+
+ fd, e := Open(path, O_RDONLY)
+ if e != nil {
+ return 0, e
+ }
+ defer Close(fd)
+
+ n, e := Pread(fd, b[:], 0)
+
+ if e != nil {
+ return 0, e
+ }
+
+ m := 0
+ for ; m < n && b[m] == ' '; m++ {
+ }
+
+ return atoi(b[m : n-1]), nil
+}
+
+func Getpid() (pid int) {
+ n, _ := readnum("#c/pid")
+ return int(n)
+}
+
+func Getppid() (ppid int) {
+ n, _ := readnum("#c/ppid")
+ return int(n)
+}
+
+func Read(fd int, p []byte) (n int, err error) {
+ return Pread(fd, p, -1)
+}
+
+func Write(fd int, p []byte) (n int, err error) {
+ return Pwrite(fd, p, -1)
+}
+
+var ioSync int64
+
+//sys fd2path(fd int, buf []byte) (err error)
+func Fd2path(fd int) (path string, err error) {
+ var buf [512]byte
+
+ e := fd2path(fd, buf[:])
+ if e != nil {
+ return "", e
+ }
+ return cstring(buf[:]), nil
+}
+
+//sys pipe(p *[2]int32) (err error)
+func Pipe(p []int) (err error) {
+ if len(p) != 2 {
+ return syscall.ErrorString("bad arg in system call")
+ }
+ var pp [2]int32
+ err = pipe(&pp)
+ p[0] = int(pp[0])
+ p[1] = int(pp[1])
+ return
+}
+
+// Underlying system call writes to newoffset via pointer.
+// Implemented in assembly to avoid allocation.
+func seek(placeholder uintptr, fd int, offset int64, whence int) (newoffset int64, err string)
+
+func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
+ newoffset, e := seek(0, fd, offset, whence)
+
+ if newoffset == -1 {
+ err = syscall.ErrorString(e)
+ }
+ return
+}
+
+func Mkdir(path string, mode uint32) (err error) {
+ fd, err := Create(path, O_RDONLY, DMDIR|mode)
+
+ if fd != -1 {
+ Close(fd)
+ }
+
+ return
+}
+
+type Waitmsg struct {
+ Pid int
+ Time [3]uint32
+ Msg string
+}
+
+func (w Waitmsg) Exited() bool { return true }
+func (w Waitmsg) Signaled() bool { return false }
+
+func (w Waitmsg) ExitStatus() int {
+ if len(w.Msg) == 0 {
+ // a normal exit returns no message
+ return 0
+ }
+ return 1
+}
+
+//sys await(s []byte) (n int, err error)
+func Await(w *Waitmsg) (err error) {
+ var buf [512]byte
+ var f [5][]byte
+
+ n, err := await(buf[:])
+
+ if err != nil || w == nil {
+ return
+ }
+
+ nf := 0
+ p := 0
+ for i := 0; i < n && nf < len(f)-1; i++ {
+ if buf[i] == ' ' {
+ f[nf] = buf[p:i]
+ p = i + 1
+ nf++
+ }
+ }
+ f[nf] = buf[p:]
+ nf++
+
+ if nf != len(f) {
+ return syscall.ErrorString("invalid wait message")
+ }
+ w.Pid = int(atoi(f[0]))
+ w.Time[0] = uint32(atoi(f[1]))
+ w.Time[1] = uint32(atoi(f[2]))
+ w.Time[2] = uint32(atoi(f[3]))
+ w.Msg = cstring(f[4])
+ if w.Msg == "''" {
+ // await() returns '' for no error
+ w.Msg = ""
+ }
+ return
+}
+
+func Unmount(name, old string) (err error) {
+ fixwd()
+ oldp, err := BytePtrFromString(old)
+ if err != nil {
+ return err
+ }
+ oldptr := uintptr(unsafe.Pointer(oldp))
+
+ var r0 uintptr
+ var e syscall.ErrorString
+
+ // bind(2) man page: If name is zero, everything bound or mounted upon old is unbound or unmounted.
+ if name == "" {
+ r0, _, e = Syscall(SYS_UNMOUNT, _zero, oldptr, 0)
+ } else {
+ namep, err := BytePtrFromString(name)
+ if err != nil {
+ return err
+ }
+ r0, _, e = Syscall(SYS_UNMOUNT, uintptr(unsafe.Pointer(namep)), oldptr, 0)
+ }
+
+ if int32(r0) == -1 {
+ err = e
+ }
+ return
+}
+
+func Fchdir(fd int) (err error) {
+ path, err := Fd2path(fd)
+
+ if err != nil {
+ return
+ }
+
+ return Chdir(path)
+}
+
+type Timespec struct {
+ Sec int32
+ Nsec int32
+}
+
+type Timeval struct {
+ Sec int32
+ Usec int32
+}
+
+func NsecToTimeval(nsec int64) (tv Timeval) {
+ nsec += 999 // round up to microsecond
+ tv.Usec = int32(nsec % 1e9 / 1e3)
+ tv.Sec = int32(nsec / 1e9)
+ return
+}
+
+func nsec() int64 {
+ var scratch int64
+
+ r0, _, _ := Syscall(SYS_NSEC, uintptr(unsafe.Pointer(&scratch)), 0, 0)
+ // TODO(aram): remove hack after I fix _nsec in the pc64 kernel.
+ if r0 == 0 {
+ return scratch
+ }
+ return int64(r0)
+}
+
+func Gettimeofday(tv *Timeval) error {
+ nsec := nsec()
+ *tv = NsecToTimeval(nsec)
+ return nil
+}
+
+func Getpagesize() int { return 0x1000 }
+
+func Getegid() (egid int) { return -1 }
+func Geteuid() (euid int) { return -1 }
+func Getgid() (gid int) { return -1 }
+func Getuid() (uid int) { return -1 }
+
+func Getgroups() (gids []int, err error) {
+ return make([]int, 0), nil
+}
+
+//sys open(path string, mode int) (fd int, err error)
+func Open(path string, mode int) (fd int, err error) {
+ fixwd()
+ return open(path, mode)
+}
+
+//sys create(path string, mode int, perm uint32) (fd int, err error)
+func Create(path string, mode int, perm uint32) (fd int, err error) {
+ fixwd()
+ return create(path, mode, perm)
+}
+
+//sys remove(path string) (err error)
+func Remove(path string) error {
+ fixwd()
+ return remove(path)
+}
+
+//sys stat(path string, edir []byte) (n int, err error)
+func Stat(path string, edir []byte) (n int, err error) {
+ fixwd()
+ return stat(path, edir)
+}
+
+//sys bind(name string, old string, flag int) (err error)
+func Bind(name string, old string, flag int) (err error) {
+ fixwd()
+ return bind(name, old, flag)
+}
+
+//sys mount(fd int, afd int, old string, flag int, aname string) (err error)
+func Mount(fd int, afd int, old string, flag int, aname string) (err error) {
+ fixwd()
+ return mount(fd, afd, old, flag, aname)
+}
+
+//sys wstat(path string, edir []byte) (err error)
+func Wstat(path string, edir []byte) (err error) {
+ fixwd()
+ return wstat(path, edir)
+}
+
+//sys chdir(path string) (err error)
+//sys Dup(oldfd int, newfd int) (fd int, err error)
+//sys Pread(fd int, p []byte, offset int64) (n int, err error)
+//sys Pwrite(fd int, p []byte, offset int64) (n int, err error)
+//sys Close(fd int) (err error)
+//sys Fstat(fd int, edir []byte) (n int, err error)
+//sys Fwstat(fd int, edir []byte) (err error)
diff --git a/vendor/golang.org/x/sys/plan9/zsyscall_plan9_386.go b/vendor/golang.org/x/sys/plan9/zsyscall_plan9_386.go
new file mode 100644
index 000000000..6819bc209
--- /dev/null
+++ b/vendor/golang.org/x/sys/plan9/zsyscall_plan9_386.go
@@ -0,0 +1,284 @@
+// go run mksyscall.go -l32 -plan9 -tags plan9,386 syscall_plan9.go
+// Code generated by the command above; see README.md. DO NOT EDIT.
+
+// +build plan9,386
+
+package plan9
+
+import "unsafe"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func fd2path(fd int, buf []byte) (err error) {
+ var _p0 unsafe.Pointer
+ if len(buf) > 0 {
+ _p0 = unsafe.Pointer(&buf[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := Syscall(SYS_FD2PATH, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func pipe(p *[2]int32) (err error) {
+ r0, _, e1 := Syscall(SYS_PIPE, uintptr(unsafe.Pointer(p)), 0, 0)
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func await(s []byte) (n int, err error) {
+ var _p0 unsafe.Pointer
+ if len(s) > 0 {
+ _p0 = unsafe.Pointer(&s[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := Syscall(SYS_AWAIT, uintptr(_p0), uintptr(len(s)), 0)
+ n = int(r0)
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func open(path string, mode int) (fd int, err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+ fd = int(r0)
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func create(path string, mode int, perm uint32) (fd int, err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ r0, _, e1 := Syscall(SYS_CREATE, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
+ fd = int(r0)
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func remove(path string) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ r0, _, e1 := Syscall(SYS_REMOVE, uintptr(unsafe.Pointer(_p0)), 0, 0)
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func stat(path string, edir []byte) (n int, err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ var _p1 unsafe.Pointer
+ if len(edir) > 0 {
+ _p1 = unsafe.Pointer(&edir[0])
+ } else {
+ _p1 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(edir)))
+ n = int(r0)
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func bind(name string, old string, flag int) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(name)
+ if err != nil {
+ return
+ }
+ var _p1 *byte
+ _p1, err = BytePtrFromString(old)
+ if err != nil {
+ return
+ }
+ r0, _, e1 := Syscall(SYS_BIND, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(flag))
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func mount(fd int, afd int, old string, flag int, aname string) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(old)
+ if err != nil {
+ return
+ }
+ var _p1 *byte
+ _p1, err = BytePtrFromString(aname)
+ if err != nil {
+ return
+ }
+ r0, _, e1 := Syscall6(SYS_MOUNT, uintptr(fd), uintptr(afd), uintptr(unsafe.Pointer(_p0)), uintptr(flag), uintptr(unsafe.Pointer(_p1)), 0)
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func wstat(path string, edir []byte) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ var _p1 unsafe.Pointer
+ if len(edir) > 0 {
+ _p1 = unsafe.Pointer(&edir[0])
+ } else {
+ _p1 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := Syscall(SYS_WSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(edir)))
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func chdir(path string) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ r0, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup(oldfd int, newfd int) (fd int, err error) {
+ r0, _, e1 := Syscall(SYS_DUP, uintptr(oldfd), uintptr(newfd), 0)
+ fd = int(r0)
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pread(fd int, p []byte, offset int64) (n int, err error) {
+ var _p0 unsafe.Pointer
+ if len(p) > 0 {
+ _p0 = unsafe.Pointer(&p[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := Syscall6(SYS_PREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0)
+ n = int(r0)
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
+ var _p0 unsafe.Pointer
+ if len(p) > 0 {
+ _p0 = unsafe.Pointer(&p[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := Syscall6(SYS_PWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0)
+ n = int(r0)
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Close(fd int) (err error) {
+ r0, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fstat(fd int, edir []byte) (n int, err error) {
+ var _p0 unsafe.Pointer
+ if len(edir) > 0 {
+ _p0 = unsafe.Pointer(&edir[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(_p0), uintptr(len(edir)))
+ n = int(r0)
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fwstat(fd int, edir []byte) (err error) {
+ var _p0 unsafe.Pointer
+ if len(edir) > 0 {
+ _p0 = unsafe.Pointer(&edir[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := Syscall(SYS_FWSTAT, uintptr(fd), uintptr(_p0), uintptr(len(edir)))
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
diff --git a/vendor/golang.org/x/sys/plan9/zsyscall_plan9_amd64.go b/vendor/golang.org/x/sys/plan9/zsyscall_plan9_amd64.go
new file mode 100644
index 000000000..418abbbfc
--- /dev/null
+++ b/vendor/golang.org/x/sys/plan9/zsyscall_plan9_amd64.go
@@ -0,0 +1,284 @@
+// go run mksyscall.go -l32 -plan9 -tags plan9,amd64 syscall_plan9.go
+// Code generated by the command above; see README.md. DO NOT EDIT.
+
+// +build plan9,amd64
+
+package plan9
+
+import "unsafe"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func fd2path(fd int, buf []byte) (err error) {
+ var _p0 unsafe.Pointer
+ if len(buf) > 0 {
+ _p0 = unsafe.Pointer(&buf[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := Syscall(SYS_FD2PATH, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func pipe(p *[2]int32) (err error) {
+ r0, _, e1 := Syscall(SYS_PIPE, uintptr(unsafe.Pointer(p)), 0, 0)
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func await(s []byte) (n int, err error) {
+ var _p0 unsafe.Pointer
+ if len(s) > 0 {
+ _p0 = unsafe.Pointer(&s[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := Syscall(SYS_AWAIT, uintptr(_p0), uintptr(len(s)), 0)
+ n = int(r0)
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func open(path string, mode int) (fd int, err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+ fd = int(r0)
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func create(path string, mode int, perm uint32) (fd int, err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ r0, _, e1 := Syscall(SYS_CREATE, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
+ fd = int(r0)
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func remove(path string) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ r0, _, e1 := Syscall(SYS_REMOVE, uintptr(unsafe.Pointer(_p0)), 0, 0)
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func stat(path string, edir []byte) (n int, err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ var _p1 unsafe.Pointer
+ if len(edir) > 0 {
+ _p1 = unsafe.Pointer(&edir[0])
+ } else {
+ _p1 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(edir)))
+ n = int(r0)
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func bind(name string, old string, flag int) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(name)
+ if err != nil {
+ return
+ }
+ var _p1 *byte
+ _p1, err = BytePtrFromString(old)
+ if err != nil {
+ return
+ }
+ r0, _, e1 := Syscall(SYS_BIND, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(flag))
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func mount(fd int, afd int, old string, flag int, aname string) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(old)
+ if err != nil {
+ return
+ }
+ var _p1 *byte
+ _p1, err = BytePtrFromString(aname)
+ if err != nil {
+ return
+ }
+ r0, _, e1 := Syscall6(SYS_MOUNT, uintptr(fd), uintptr(afd), uintptr(unsafe.Pointer(_p0)), uintptr(flag), uintptr(unsafe.Pointer(_p1)), 0)
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func wstat(path string, edir []byte) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ var _p1 unsafe.Pointer
+ if len(edir) > 0 {
+ _p1 = unsafe.Pointer(&edir[0])
+ } else {
+ _p1 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := Syscall(SYS_WSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(edir)))
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func chdir(path string) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ r0, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup(oldfd int, newfd int) (fd int, err error) {
+ r0, _, e1 := Syscall(SYS_DUP, uintptr(oldfd), uintptr(newfd), 0)
+ fd = int(r0)
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pread(fd int, p []byte, offset int64) (n int, err error) {
+ var _p0 unsafe.Pointer
+ if len(p) > 0 {
+ _p0 = unsafe.Pointer(&p[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := Syscall6(SYS_PREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0)
+ n = int(r0)
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
+ var _p0 unsafe.Pointer
+ if len(p) > 0 {
+ _p0 = unsafe.Pointer(&p[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := Syscall6(SYS_PWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0)
+ n = int(r0)
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Close(fd int) (err error) {
+ r0, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fstat(fd int, edir []byte) (n int, err error) {
+ var _p0 unsafe.Pointer
+ if len(edir) > 0 {
+ _p0 = unsafe.Pointer(&edir[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(_p0), uintptr(len(edir)))
+ n = int(r0)
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fwstat(fd int, edir []byte) (err error) {
+ var _p0 unsafe.Pointer
+ if len(edir) > 0 {
+ _p0 = unsafe.Pointer(&edir[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := Syscall(SYS_FWSTAT, uintptr(fd), uintptr(_p0), uintptr(len(edir)))
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
diff --git a/vendor/golang.org/x/sys/plan9/zsyscall_plan9_arm.go b/vendor/golang.org/x/sys/plan9/zsyscall_plan9_arm.go
new file mode 100644
index 000000000..3e8a1a58c
--- /dev/null
+++ b/vendor/golang.org/x/sys/plan9/zsyscall_plan9_arm.go
@@ -0,0 +1,284 @@
+// go run mksyscall.go -l32 -plan9 -tags plan9,arm syscall_plan9.go
+// Code generated by the command above; see README.md. DO NOT EDIT.
+
+// +build plan9,arm
+
+package plan9
+
+import "unsafe"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func fd2path(fd int, buf []byte) (err error) {
+ var _p0 unsafe.Pointer
+ if len(buf) > 0 {
+ _p0 = unsafe.Pointer(&buf[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := Syscall(SYS_FD2PATH, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func pipe(p *[2]int32) (err error) {
+ r0, _, e1 := Syscall(SYS_PIPE, uintptr(unsafe.Pointer(p)), 0, 0)
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func await(s []byte) (n int, err error) {
+ var _p0 unsafe.Pointer
+ if len(s) > 0 {
+ _p0 = unsafe.Pointer(&s[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := Syscall(SYS_AWAIT, uintptr(_p0), uintptr(len(s)), 0)
+ n = int(r0)
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func open(path string, mode int) (fd int, err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+ fd = int(r0)
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func create(path string, mode int, perm uint32) (fd int, err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ r0, _, e1 := Syscall(SYS_CREATE, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
+ fd = int(r0)
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func remove(path string) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ r0, _, e1 := Syscall(SYS_REMOVE, uintptr(unsafe.Pointer(_p0)), 0, 0)
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func stat(path string, edir []byte) (n int, err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ var _p1 unsafe.Pointer
+ if len(edir) > 0 {
+ _p1 = unsafe.Pointer(&edir[0])
+ } else {
+ _p1 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(edir)))
+ n = int(r0)
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func bind(name string, old string, flag int) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(name)
+ if err != nil {
+ return
+ }
+ var _p1 *byte
+ _p1, err = BytePtrFromString(old)
+ if err != nil {
+ return
+ }
+ r0, _, e1 := Syscall(SYS_BIND, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(flag))
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func mount(fd int, afd int, old string, flag int, aname string) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(old)
+ if err != nil {
+ return
+ }
+ var _p1 *byte
+ _p1, err = BytePtrFromString(aname)
+ if err != nil {
+ return
+ }
+ r0, _, e1 := Syscall6(SYS_MOUNT, uintptr(fd), uintptr(afd), uintptr(unsafe.Pointer(_p0)), uintptr(flag), uintptr(unsafe.Pointer(_p1)), 0)
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func wstat(path string, edir []byte) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ var _p1 unsafe.Pointer
+ if len(edir) > 0 {
+ _p1 = unsafe.Pointer(&edir[0])
+ } else {
+ _p1 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := Syscall(SYS_WSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(edir)))
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func chdir(path string) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ r0, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup(oldfd int, newfd int) (fd int, err error) {
+ r0, _, e1 := Syscall(SYS_DUP, uintptr(oldfd), uintptr(newfd), 0)
+ fd = int(r0)
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pread(fd int, p []byte, offset int64) (n int, err error) {
+ var _p0 unsafe.Pointer
+ if len(p) > 0 {
+ _p0 = unsafe.Pointer(&p[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := Syscall6(SYS_PREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0)
+ n = int(r0)
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
+ var _p0 unsafe.Pointer
+ if len(p) > 0 {
+ _p0 = unsafe.Pointer(&p[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := Syscall6(SYS_PWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0)
+ n = int(r0)
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Close(fd int) (err error) {
+ r0, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fstat(fd int, edir []byte) (n int, err error) {
+ var _p0 unsafe.Pointer
+ if len(edir) > 0 {
+ _p0 = unsafe.Pointer(&edir[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(_p0), uintptr(len(edir)))
+ n = int(r0)
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fwstat(fd int, edir []byte) (err error) {
+ var _p0 unsafe.Pointer
+ if len(edir) > 0 {
+ _p0 = unsafe.Pointer(&edir[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := Syscall(SYS_FWSTAT, uintptr(fd), uintptr(_p0), uintptr(len(edir)))
+ if int32(r0) == -1 {
+ err = e1
+ }
+ return
+}
diff --git a/vendor/golang.org/x/sys/plan9/zsysnum_plan9.go b/vendor/golang.org/x/sys/plan9/zsysnum_plan9.go
new file mode 100644
index 000000000..22e8abd43
--- /dev/null
+++ b/vendor/golang.org/x/sys/plan9/zsysnum_plan9.go
@@ -0,0 +1,49 @@
+// mksysnum_plan9.sh /opt/plan9/sys/src/libc/9syscall/sys.h
+// MACHINE GENERATED BY THE ABOVE COMMAND; DO NOT EDIT
+
+package plan9
+
+const (
+ SYS_SYSR1 = 0
+ SYS_BIND = 2
+ SYS_CHDIR = 3
+ SYS_CLOSE = 4
+ SYS_DUP = 5
+ SYS_ALARM = 6
+ SYS_EXEC = 7
+ SYS_EXITS = 8
+ SYS_FAUTH = 10
+ SYS_SEGBRK = 12
+ SYS_OPEN = 14
+ SYS_OSEEK = 16
+ SYS_SLEEP = 17
+ SYS_RFORK = 19
+ SYS_PIPE = 21
+ SYS_CREATE = 22
+ SYS_FD2PATH = 23
+ SYS_BRK_ = 24
+ SYS_REMOVE = 25
+ SYS_NOTIFY = 28
+ SYS_NOTED = 29
+ SYS_SEGATTACH = 30
+ SYS_SEGDETACH = 31
+ SYS_SEGFREE = 32
+ SYS_SEGFLUSH = 33
+ SYS_RENDEZVOUS = 34
+ SYS_UNMOUNT = 35
+ SYS_SEMACQUIRE = 37
+ SYS_SEMRELEASE = 38
+ SYS_SEEK = 39
+ SYS_FVERSION = 40
+ SYS_ERRSTR = 41
+ SYS_STAT = 42
+ SYS_FSTAT = 43
+ SYS_WSTAT = 44
+ SYS_FWSTAT = 45
+ SYS_MOUNT = 46
+ SYS_AWAIT = 47
+ SYS_PREAD = 50
+ SYS_PWRITE = 51
+ SYS_TSEMACQUIRE = 52
+ SYS_NSEC = 53
+)
diff --git a/vendor/golang.org/x/term/AUTHORS b/vendor/golang.org/x/term/AUTHORS
new file mode 100644
index 000000000..15167cd74
--- /dev/null
+++ b/vendor/golang.org/x/term/AUTHORS
@@ -0,0 +1,3 @@
+# This source code refers to The Go Authors for copyright purposes.
+# The master list of authors is in the main Go distribution,
+# visible at http://tip.golang.org/AUTHORS.
diff --git a/vendor/golang.org/x/term/CONTRIBUTING.md b/vendor/golang.org/x/term/CONTRIBUTING.md
new file mode 100644
index 000000000..d0485e887
--- /dev/null
+++ b/vendor/golang.org/x/term/CONTRIBUTING.md
@@ -0,0 +1,26 @@
+# Contributing to Go
+
+Go is an open source project.
+
+It is the work of hundreds of contributors. We appreciate your help!
+
+## Filing issues
+
+When [filing an issue](https://golang.org/issue/new), make sure to answer these five questions:
+
+1. What version of Go are you using (`go version`)?
+2. What operating system and processor architecture are you using?
+3. What did you do?
+4. What did you expect to see?
+5. What did you see instead?
+
+General questions should go to the [golang-nuts mailing list](https://groups.google.com/group/golang-nuts) instead of the issue tracker.
+The gophers there will answer or ask you to file an issue if you've tripped over a bug.
+
+## Contributing code
+
+Please read the [Contribution Guidelines](https://golang.org/doc/contribute.html)
+before sending patches.
+
+Unless otherwise noted, the Go source files are distributed under
+the BSD-style license found in the LICENSE file.
diff --git a/vendor/golang.org/x/term/CONTRIBUTORS b/vendor/golang.org/x/term/CONTRIBUTORS
new file mode 100644
index 000000000..1c4577e96
--- /dev/null
+++ b/vendor/golang.org/x/term/CONTRIBUTORS
@@ -0,0 +1,3 @@
+# This source code was written by the Go contributors.
+# The master list of contributors is in the main Go distribution,
+# visible at http://tip.golang.org/CONTRIBUTORS.
diff --git a/vendor/golang.org/x/term/LICENSE b/vendor/golang.org/x/term/LICENSE
new file mode 100644
index 000000000..6a66aea5e
--- /dev/null
+++ b/vendor/golang.org/x/term/LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) 2009 The Go Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+ * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/golang.org/x/term/PATENTS b/vendor/golang.org/x/term/PATENTS
new file mode 100644
index 000000000..733099041
--- /dev/null
+++ b/vendor/golang.org/x/term/PATENTS
@@ -0,0 +1,22 @@
+Additional IP Rights Grant (Patents)
+
+"This implementation" means the copyrightable works distributed by
+Google as part of the Go project.
+
+Google hereby grants to You a perpetual, worldwide, non-exclusive,
+no-charge, royalty-free, irrevocable (except as stated in this section)
+patent license to make, have made, use, offer to sell, sell, import,
+transfer and otherwise run, modify and propagate the contents of this
+implementation of Go, where such license applies only to those patent
+claims, both currently owned or controlled by Google and acquired in
+the future, licensable by Google that are necessarily infringed by this
+implementation of Go. This grant does not include claims that would be
+infringed only as a consequence of further modification of this
+implementation. If you or your agent or exclusive licensee institute or
+order or agree to the institution of patent litigation against any
+entity (including a cross-claim or counterclaim in a lawsuit) alleging
+that this implementation of Go or any code incorporated within this
+implementation of Go constitutes direct or contributory patent
+infringement, or inducement of patent infringement, then any patent
+rights granted to you under this License for this implementation of Go
+shall terminate as of the date such litigation is filed.
diff --git a/vendor/golang.org/x/term/README.md b/vendor/golang.org/x/term/README.md
new file mode 100644
index 000000000..e0f390cb2
--- /dev/null
+++ b/vendor/golang.org/x/term/README.md
@@ -0,0 +1,17 @@
+# Go terminal/console support
+
+This repository provides Go terminal and console support packages.
+
+## Download/Install
+
+The easiest way to install is to run `go get -u golang.org/x/term`. You can
+also manually git clone the repository to `$GOPATH/src/golang.org/x/term`.
+
+## Report Issues / Send Patches
+
+This repository uses Gerrit for code changes. To learn how to submit changes to
+this repository, see https://golang.org/doc/contribute.html.
+
+The main issue tracker for the term repository is located at
+https://github.com/golang/go/issues. Prefix your issue with "x/term:" in the
+subject line, so it is easy to find.
diff --git a/vendor/golang.org/x/term/go.mod b/vendor/golang.org/x/term/go.mod
new file mode 100644
index 000000000..d45f52851
--- /dev/null
+++ b/vendor/golang.org/x/term/go.mod
@@ -0,0 +1,5 @@
+module golang.org/x/term
+
+go 1.11
+
+require golang.org/x/sys v0.0.0-20201119102817-f84b799fce68
diff --git a/vendor/golang.org/x/term/go.sum b/vendor/golang.org/x/term/go.sum
new file mode 100644
index 000000000..de9e09c65
--- /dev/null
+++ b/vendor/golang.org/x/term/go.sum
@@ -0,0 +1,2 @@
+golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 h1:nxC68pudNYkKU6jWhgrqdreuFiOQWj1Fs7T3VrH4Pjw=
+golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
diff --git a/vendor/golang.org/x/crypto/ssh/terminal/util_plan9.go b/vendor/golang.org/x/term/term.go
index 9317ac7ed..69931cc84 100644
--- a/vendor/golang.org/x/crypto/ssh/terminal/util_plan9.go
+++ b/vendor/golang.org/x/term/term.go
@@ -1,8 +1,8 @@
-// Copyright 2016 The Go Authors. All rights reserved.
+// 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.
-// Package terminal provides support functions for dealing with terminals, as
+// Package term provides support functions for dealing with terminals, as
// commonly found on UNIX systems.
//
// Putting a terminal into raw mode is the most common requirement:
@@ -12,47 +12,47 @@
// panic(err)
// }
// defer terminal.Restore(0, oldState)
-package terminal
+package term
-import (
- "fmt"
- "runtime"
-)
-
-type State struct{}
+// State contains the state of a terminal.
+type State struct {
+ state
+}
// IsTerminal returns whether the given file descriptor is a terminal.
func IsTerminal(fd int) bool {
- return false
+ return isTerminal(fd)
}
-// MakeRaw put the terminal connected to the given file descriptor into raw
+// MakeRaw puts the terminal connected to the given file descriptor into raw
// mode and returns the previous state of the terminal so that it can be
// restored.
func MakeRaw(fd int) (*State, error) {
- return nil, fmt.Errorf("terminal: MakeRaw not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
+ return makeRaw(fd)
}
// GetState returns the current state of a terminal which may be useful to
// restore the terminal after a signal.
func GetState(fd int) (*State, error) {
- return nil, fmt.Errorf("terminal: GetState not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
+ return getState(fd)
}
// Restore restores the terminal connected to the given file descriptor to a
// previous state.
-func Restore(fd int, state *State) error {
- return fmt.Errorf("terminal: Restore not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
+func Restore(fd int, oldState *State) error {
+ return restore(fd, oldState)
}
-// GetSize returns the dimensions of the given terminal.
+// GetSize returns the visible dimensions of the given terminal.
+//
+// These dimensions don't include any scrollback buffer height.
func GetSize(fd int) (width, height int, err error) {
- return 0, 0, fmt.Errorf("terminal: GetSize not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
+ return getSize(fd)
}
// ReadPassword reads a line of input from a terminal without local echo. This
// is commonly used for inputting passwords and other sensitive data. The slice
// returned does not include the \n.
func ReadPassword(fd int) ([]byte, error) {
- return nil, fmt.Errorf("terminal: ReadPassword not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
+ return readPassword(fd)
}
diff --git a/vendor/golang.org/x/term/term_plan9.go b/vendor/golang.org/x/term/term_plan9.go
new file mode 100644
index 000000000..21afa55cd
--- /dev/null
+++ b/vendor/golang.org/x/term/term_plan9.go
@@ -0,0 +1,42 @@
+// 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.
+
+package term
+
+import (
+ "fmt"
+ "runtime"
+
+ "golang.org/x/sys/plan9"
+)
+
+type state struct{}
+
+func isTerminal(fd int) bool {
+ path, err := plan9.Fd2path(fd)
+ if err != nil {
+ return false
+ }
+ return path == "/dev/cons" || path == "/mnt/term/dev/cons"
+}
+
+func makeRaw(fd int) (*State, error) {
+ return nil, fmt.Errorf("terminal: MakeRaw not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
+}
+
+func getState(fd int) (*State, error) {
+ return nil, fmt.Errorf("terminal: GetState not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
+}
+
+func restore(fd int, state *State) error {
+ return fmt.Errorf("terminal: Restore not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
+}
+
+func getSize(fd int) (width, height int, err error) {
+ return 0, 0, fmt.Errorf("terminal: GetSize not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
+}
+
+func readPassword(fd int) ([]byte, error) {
+ return nil, fmt.Errorf("terminal: ReadPassword not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
+}
diff --git a/vendor/golang.org/x/crypto/ssh/terminal/util_solaris.go b/vendor/golang.org/x/term/term_solaris.go
index 3d5f06a9f..b9da29744 100644
--- a/vendor/golang.org/x/crypto/ssh/terminal/util_solaris.go
+++ b/vendor/golang.org/x/term/term_solaris.go
@@ -1,32 +1,27 @@
-// Copyright 2015 The Go Authors. All rights reserved.
+// 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 solaris
-
-package terminal // import "golang.org/x/crypto/ssh/terminal"
+package term
import (
- "golang.org/x/sys/unix"
"io"
"syscall"
+
+ "golang.org/x/sys/unix"
)
// State contains the state of a terminal.
-type State struct {
+type state struct {
termios unix.Termios
}
-// IsTerminal returns whether the given file descriptor is a terminal.
-func IsTerminal(fd int) bool {
+func isTerminal(fd int) bool {
_, err := unix.IoctlGetTermio(fd, unix.TCGETA)
return err == nil
}
-// ReadPassword reads a line of input from a terminal without local echo. This
-// is commonly used for inputting passwords and other sensitive data. The slice
-// returned does not include the \n.
-func ReadPassword(fd int) ([]byte, error) {
+func readPassword(fd int) ([]byte, error) {
// see also: http://src.illumos.org/source/xref/illumos-gate/usr/src/lib/libast/common/uwin/getpass.c
val, err := unix.IoctlGetTermios(fd, unix.TCGETS)
if err != nil {
@@ -70,17 +65,14 @@ func ReadPassword(fd int) ([]byte, error) {
return ret, nil
}
-// MakeRaw puts the terminal connected to the given file descriptor into raw
-// mode and returns the previous state of the terminal so that it can be
-// restored.
-// see http://cr.illumos.org/~webrev/andy_js/1060/
-func MakeRaw(fd int) (*State, error) {
+func makeRaw(fd int) (*State, error) {
+ // see http://cr.illumos.org/~webrev/andy_js/1060/
termios, err := unix.IoctlGetTermios(fd, unix.TCGETS)
if err != nil {
return nil, err
}
- oldState := State{termios: *termios}
+ oldState := State{state{termios: *termios}}
termios.Iflag &^= unix.IGNBRK | unix.BRKINT | unix.PARMRK | unix.ISTRIP | unix.INLCR | unix.IGNCR | unix.ICRNL | unix.IXON
termios.Oflag &^= unix.OPOST
@@ -97,25 +89,20 @@ func MakeRaw(fd int) (*State, error) {
return &oldState, nil
}
-// Restore restores the terminal connected to the given file descriptor to a
-// previous state.
-func Restore(fd int, oldState *State) error {
+func restore(fd int, oldState *State) error {
return unix.IoctlSetTermios(fd, unix.TCSETS, &oldState.termios)
}
-// GetState returns the current state of a terminal which may be useful to
-// restore the terminal after a signal.
-func GetState(fd int) (*State, error) {
+func getState(fd int) (*State, error) {
termios, err := unix.IoctlGetTermios(fd, unix.TCGETS)
if err != nil {
return nil, err
}
- return &State{termios: *termios}, nil
+ return &State{state{termios: *termios}}, nil
}
-// GetSize returns the dimensions of the given terminal.
-func GetSize(fd int) (width, height int, err error) {
+func getSize(fd int) (width, height int, err error) {
ws, err := unix.IoctlGetWinsize(fd, unix.TIOCGWINSZ)
if err != nil {
return 0, 0, err
diff --git a/vendor/golang.org/x/crypto/ssh/terminal/util.go b/vendor/golang.org/x/term/term_unix.go
index 391104084..4c60e457d 100644
--- a/vendor/golang.org/x/crypto/ssh/terminal/util.go
+++ b/vendor/golang.org/x/term/term_unix.go
@@ -1,46 +1,31 @@
-// Copyright 2011 The Go Authors. All rights reserved.
+// 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 aix darwin dragonfly freebsd linux,!appengine netbsd openbsd
+// +build aix darwin dragonfly freebsd linux netbsd openbsd zos
-// Package terminal provides support functions for dealing with terminals, as
-// commonly found on UNIX systems.
-//
-// Putting a terminal into raw mode is the most common requirement:
-//
-// oldState, err := terminal.MakeRaw(0)
-// if err != nil {
-// panic(err)
-// }
-// defer terminal.Restore(0, oldState)
-package terminal // import "golang.org/x/crypto/ssh/terminal"
+package term
import (
"golang.org/x/sys/unix"
)
-// State contains the state of a terminal.
-type State struct {
+type state struct {
termios unix.Termios
}
-// IsTerminal returns whether the given file descriptor is a terminal.
-func IsTerminal(fd int) bool {
+func isTerminal(fd int) bool {
_, err := unix.IoctlGetTermios(fd, ioctlReadTermios)
return err == nil
}
-// MakeRaw put the terminal connected to the given file descriptor into raw
-// mode and returns the previous state of the terminal so that it can be
-// restored.
-func MakeRaw(fd int) (*State, error) {
+func makeRaw(fd int) (*State, error) {
termios, err := unix.IoctlGetTermios(fd, ioctlReadTermios)
if err != nil {
return nil, err
}
- oldState := State{termios: *termios}
+ oldState := State{state{termios: *termios}}
// This attempts to replicate the behaviour documented for cfmakeraw in
// the termios(3) manpage.
@@ -58,25 +43,20 @@ func MakeRaw(fd int) (*State, error) {
return &oldState, nil
}
-// GetState returns the current state of a terminal which may be useful to
-// restore the terminal after a signal.
-func GetState(fd int) (*State, error) {
+func getState(fd int) (*State, error) {
termios, err := unix.IoctlGetTermios(fd, ioctlReadTermios)
if err != nil {
return nil, err
}
- return &State{termios: *termios}, nil
+ return &State{state{termios: *termios}}, nil
}
-// Restore restores the terminal connected to the given file descriptor to a
-// previous state.
-func Restore(fd int, state *State) error {
+func restore(fd int, state *State) error {
return unix.IoctlSetTermios(fd, ioctlWriteTermios, &state.termios)
}
-// GetSize returns the dimensions of the given terminal.
-func GetSize(fd int) (width, height int, err error) {
+func getSize(fd int) (width, height int, err error) {
ws, err := unix.IoctlGetWinsize(fd, unix.TIOCGWINSZ)
if err != nil {
return -1, -1, err
@@ -91,10 +71,7 @@ func (r passwordReader) Read(buf []byte) (int, error) {
return unix.Read(int(r), buf)
}
-// ReadPassword reads a line of input from a terminal without local echo. This
-// is commonly used for inputting passwords and other sensitive data. The slice
-// returned does not include the \n.
-func ReadPassword(fd int) ([]byte, error) {
+func readPassword(fd int) ([]byte, error) {
termios, err := unix.IoctlGetTermios(fd, ioctlReadTermios)
if err != nil {
return nil, err
diff --git a/vendor/golang.org/x/crypto/ssh/terminal/util_linux.go b/vendor/golang.org/x/term/term_unix_aix.go
index 5fadfe8a1..2d5efd26a 100644
--- a/vendor/golang.org/x/crypto/ssh/terminal/util_linux.go
+++ b/vendor/golang.org/x/term/term_unix_aix.go
@@ -1,8 +1,8 @@
-// Copyright 2013 The Go Authors. All rights reserved.
+// 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.
-package terminal
+package term
import "golang.org/x/sys/unix"
diff --git a/vendor/golang.org/x/crypto/ssh/terminal/util_bsd.go b/vendor/golang.org/x/term/term_unix_bsd.go
index cb23a5904..3342be00b 100644
--- a/vendor/golang.org/x/crypto/ssh/terminal/util_bsd.go
+++ b/vendor/golang.org/x/term/term_unix_bsd.go
@@ -4,7 +4,7 @@
// +build darwin dragonfly freebsd netbsd openbsd
-package terminal
+package term
import "golang.org/x/sys/unix"
diff --git a/vendor/golang.org/x/crypto/ssh/terminal/util_aix.go b/vendor/golang.org/x/term/term_unix_linux.go
index dfcd62785..2d5efd26a 100644
--- a/vendor/golang.org/x/crypto/ssh/terminal/util_aix.go
+++ b/vendor/golang.org/x/term/term_unix_linux.go
@@ -1,10 +1,8 @@
-// Copyright 2018 The Go Authors. All rights reserved.
+// 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 aix
-
-package terminal
+package term
import "golang.org/x/sys/unix"
diff --git a/vendor/golang.org/x/term/term_unix_zos.go b/vendor/golang.org/x/term/term_unix_zos.go
new file mode 100644
index 000000000..b85ab8998
--- /dev/null
+++ b/vendor/golang.org/x/term/term_unix_zos.go
@@ -0,0 +1,10 @@
+// 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.
+
+package term
+
+import "golang.org/x/sys/unix"
+
+const ioctlReadTermios = unix.TCGETS
+const ioctlWriteTermios = unix.TCSETS
diff --git a/vendor/golang.org/x/term/term_unsupported.go b/vendor/golang.org/x/term/term_unsupported.go
new file mode 100644
index 000000000..8b5d1bad0
--- /dev/null
+++ b/vendor/golang.org/x/term/term_unsupported.go
@@ -0,0 +1,38 @@
+// 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 !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!zos,!windows,!solaris,!plan9
+
+package term
+
+import (
+ "fmt"
+ "runtime"
+)
+
+type state struct{}
+
+func isTerminal(fd int) bool {
+ return false
+}
+
+func makeRaw(fd int) (*State, error) {
+ return nil, fmt.Errorf("terminal: MakeRaw not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
+}
+
+func getState(fd int) (*State, error) {
+ return nil, fmt.Errorf("terminal: GetState not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
+}
+
+func restore(fd int, state *State) error {
+ return fmt.Errorf("terminal: Restore not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
+}
+
+func getSize(fd int) (width, height int, err error) {
+ return 0, 0, fmt.Errorf("terminal: GetSize not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
+}
+
+func readPassword(fd int) ([]byte, error) {
+ return nil, fmt.Errorf("terminal: ReadPassword not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
+}
diff --git a/vendor/golang.org/x/crypto/ssh/terminal/util_windows.go b/vendor/golang.org/x/term/term_windows.go
index f614e9cb6..465f56060 100644
--- a/vendor/golang.org/x/crypto/ssh/terminal/util_windows.go
+++ b/vendor/golang.org/x/term/term_windows.go
@@ -1,20 +1,8 @@
-// Copyright 2011 The Go Authors. All rights reserved.
+// 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 windows
-
-// Package terminal provides support functions for dealing with terminals, as
-// commonly found on UNIX systems.
-//
-// Putting a terminal into raw mode is the most common requirement:
-//
-// oldState, err := terminal.MakeRaw(0)
-// if err != nil {
-// panic(err)
-// }
-// defer terminal.Restore(0, oldState)
-package terminal
+package term
import (
"os"
@@ -22,21 +10,17 @@ import (
"golang.org/x/sys/windows"
)
-type State struct {
+type state struct {
mode uint32
}
-// IsTerminal returns whether the given file descriptor is a terminal.
-func IsTerminal(fd int) bool {
+func isTerminal(fd int) bool {
var st uint32
err := windows.GetConsoleMode(windows.Handle(fd), &st)
return err == nil
}
-// MakeRaw put the terminal connected to the given file descriptor into raw
-// mode and returns the previous state of the terminal so that it can be
-// restored.
-func MakeRaw(fd int) (*State, error) {
+func makeRaw(fd int) (*State, error) {
var st uint32
if err := windows.GetConsoleMode(windows.Handle(fd), &st); err != nil {
return nil, err
@@ -45,29 +29,22 @@ func MakeRaw(fd int) (*State, error) {
if err := windows.SetConsoleMode(windows.Handle(fd), raw); err != nil {
return nil, err
}
- return &State{st}, nil
+ return &State{state{st}}, nil
}
-// GetState returns the current state of a terminal which may be useful to
-// restore the terminal after a signal.
-func GetState(fd int) (*State, error) {
+func getState(fd int) (*State, error) {
var st uint32
if err := windows.GetConsoleMode(windows.Handle(fd), &st); err != nil {
return nil, err
}
- return &State{st}, nil
+ return &State{state{st}}, nil
}
-// Restore restores the terminal connected to the given file descriptor to a
-// previous state.
-func Restore(fd int, state *State) error {
+func restore(fd int, state *State) error {
return windows.SetConsoleMode(windows.Handle(fd), state.mode)
}
-// GetSize returns the visible dimensions of the given terminal.
-//
-// These dimensions don't include any scrollback buffer height.
-func GetSize(fd int) (width, height int, err error) {
+func getSize(fd int) (width, height int, err error) {
var info windows.ConsoleScreenBufferInfo
if err := windows.GetConsoleScreenBufferInfo(windows.Handle(fd), &info); err != nil {
return 0, 0, err
@@ -75,10 +52,7 @@ func GetSize(fd int) (width, height int, err error) {
return int(info.Window.Right - info.Window.Left + 1), int(info.Window.Bottom - info.Window.Top + 1), nil
}
-// ReadPassword reads a line of input from a terminal without local echo. This
-// is commonly used for inputting passwords and other sensitive data. The slice
-// returned does not include the \n.
-func ReadPassword(fd int) ([]byte, error) {
+func readPassword(fd int) ([]byte, error) {
var st uint32
if err := windows.GetConsoleMode(windows.Handle(fd), &st); err != nil {
return nil, err
diff --git a/vendor/golang.org/x/term/terminal.go b/vendor/golang.org/x/term/terminal.go
new file mode 100644
index 000000000..535ab8257
--- /dev/null
+++ b/vendor/golang.org/x/term/terminal.go
@@ -0,0 +1,987 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package term
+
+import (
+ "bytes"
+ "io"
+ "runtime"
+ "strconv"
+ "sync"
+ "unicode/utf8"
+)
+
+// EscapeCodes contains escape sequences that can be written to the terminal in
+// order to achieve different styles of text.
+type EscapeCodes struct {
+ // Foreground colors
+ Black, Red, Green, Yellow, Blue, Magenta, Cyan, White []byte
+
+ // Reset all attributes
+ Reset []byte
+}
+
+var vt100EscapeCodes = EscapeCodes{
+ Black: []byte{keyEscape, '[', '3', '0', 'm'},
+ Red: []byte{keyEscape, '[', '3', '1', 'm'},
+ Green: []byte{keyEscape, '[', '3', '2', 'm'},
+ Yellow: []byte{keyEscape, '[', '3', '3', 'm'},
+ Blue: []byte{keyEscape, '[', '3', '4', 'm'},
+ Magenta: []byte{keyEscape, '[', '3', '5', 'm'},
+ Cyan: []byte{keyEscape, '[', '3', '6', 'm'},
+ White: []byte{keyEscape, '[', '3', '7', 'm'},
+
+ Reset: []byte{keyEscape, '[', '0', 'm'},
+}
+
+// Terminal contains the state for running a VT100 terminal that is capable of
+// reading lines of input.
+type Terminal struct {
+ // AutoCompleteCallback, if non-null, is called for each keypress with
+ // the full input line and the current position of the cursor (in
+ // bytes, as an index into |line|). If it returns ok=false, the key
+ // press is processed normally. Otherwise it returns a replacement line
+ // and the new cursor position.
+ AutoCompleteCallback func(line string, pos int, key rune) (newLine string, newPos int, ok bool)
+
+ // Escape contains a pointer to the escape codes for this terminal.
+ // It's always a valid pointer, although the escape codes themselves
+ // may be empty if the terminal doesn't support them.
+ Escape *EscapeCodes
+
+ // lock protects the terminal and the state in this object from
+ // concurrent processing of a key press and a Write() call.
+ lock sync.Mutex
+
+ c io.ReadWriter
+ prompt []rune
+
+ // line is the current line being entered.
+ line []rune
+ // pos is the logical position of the cursor in line
+ pos int
+ // echo is true if local echo is enabled
+ echo bool
+ // pasteActive is true iff there is a bracketed paste operation in
+ // progress.
+ pasteActive bool
+
+ // cursorX contains the current X value of the cursor where the left
+ // edge is 0. cursorY contains the row number where the first row of
+ // the current line is 0.
+ cursorX, cursorY int
+ // maxLine is the greatest value of cursorY so far.
+ maxLine int
+
+ termWidth, termHeight int
+
+ // outBuf contains the terminal data to be sent.
+ outBuf []byte
+ // remainder contains the remainder of any partial key sequences after
+ // a read. It aliases into inBuf.
+ remainder []byte
+ inBuf [256]byte
+
+ // history contains previously entered commands so that they can be
+ // accessed with the up and down keys.
+ history stRingBuffer
+ // historyIndex stores the currently accessed history entry, where zero
+ // means the immediately previous entry.
+ historyIndex int
+ // When navigating up and down the history it's possible to return to
+ // the incomplete, initial line. That value is stored in
+ // historyPending.
+ historyPending string
+}
+
+// NewTerminal runs a VT100 terminal on the given ReadWriter. If the ReadWriter is
+// a local terminal, that terminal must first have been put into raw mode.
+// prompt is a string that is written at the start of each input line (i.e.
+// "> ").
+func NewTerminal(c io.ReadWriter, prompt string) *Terminal {
+ return &Terminal{
+ Escape: &vt100EscapeCodes,
+ c: c,
+ prompt: []rune(prompt),
+ termWidth: 80,
+ termHeight: 24,
+ echo: true,
+ historyIndex: -1,
+ }
+}
+
+const (
+ keyCtrlC = 3
+ keyCtrlD = 4
+ keyCtrlU = 21
+ keyEnter = '\r'
+ keyEscape = 27
+ keyBackspace = 127
+ keyUnknown = 0xd800 /* UTF-16 surrogate area */ + iota
+ keyUp
+ keyDown
+ keyLeft
+ keyRight
+ keyAltLeft
+ keyAltRight
+ keyHome
+ keyEnd
+ keyDeleteWord
+ keyDeleteLine
+ keyClearScreen
+ keyPasteStart
+ keyPasteEnd
+)
+
+var (
+ crlf = []byte{'\r', '\n'}
+ pasteStart = []byte{keyEscape, '[', '2', '0', '0', '~'}
+ pasteEnd = []byte{keyEscape, '[', '2', '0', '1', '~'}
+)
+
+// bytesToKey tries to parse a key sequence from b. If successful, it returns
+// the key and the remainder of the input. Otherwise it returns utf8.RuneError.
+func bytesToKey(b []byte, pasteActive bool) (rune, []byte) {
+ if len(b) == 0 {
+ return utf8.RuneError, nil
+ }
+
+ if !pasteActive {
+ switch b[0] {
+ case 1: // ^A
+ return keyHome, b[1:]
+ case 2: // ^B
+ return keyLeft, b[1:]
+ case 5: // ^E
+ return keyEnd, b[1:]
+ case 6: // ^F
+ return keyRight, b[1:]
+ case 8: // ^H
+ return keyBackspace, b[1:]
+ case 11: // ^K
+ return keyDeleteLine, b[1:]
+ case 12: // ^L
+ return keyClearScreen, b[1:]
+ case 23: // ^W
+ return keyDeleteWord, b[1:]
+ case 14: // ^N
+ return keyDown, b[1:]
+ case 16: // ^P
+ return keyUp, b[1:]
+ }
+ }
+
+ if b[0] != keyEscape {
+ if !utf8.FullRune(b) {
+ return utf8.RuneError, b
+ }
+ r, l := utf8.DecodeRune(b)
+ return r, b[l:]
+ }
+
+ if !pasteActive && len(b) >= 3 && b[0] == keyEscape && b[1] == '[' {
+ switch b[2] {
+ case 'A':
+ return keyUp, b[3:]
+ case 'B':
+ return keyDown, b[3:]
+ case 'C':
+ return keyRight, b[3:]
+ case 'D':
+ return keyLeft, b[3:]
+ case 'H':
+ return keyHome, b[3:]
+ case 'F':
+ return keyEnd, b[3:]
+ }
+ }
+
+ if !pasteActive && len(b) >= 6 && b[0] == keyEscape && b[1] == '[' && b[2] == '1' && b[3] == ';' && b[4] == '3' {
+ switch b[5] {
+ case 'C':
+ return keyAltRight, b[6:]
+ case 'D':
+ return keyAltLeft, b[6:]
+ }
+ }
+
+ if !pasteActive && len(b) >= 6 && bytes.Equal(b[:6], pasteStart) {
+ return keyPasteStart, b[6:]
+ }
+
+ if pasteActive && len(b) >= 6 && bytes.Equal(b[:6], pasteEnd) {
+ return keyPasteEnd, b[6:]
+ }
+
+ // If we get here then we have a key that we don't recognise, or a
+ // partial sequence. It's not clear how one should find the end of a
+ // sequence without knowing them all, but it seems that [a-zA-Z~] only
+ // appears at the end of a sequence.
+ for i, c := range b[0:] {
+ if c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c == '~' {
+ return keyUnknown, b[i+1:]
+ }
+ }
+
+ return utf8.RuneError, b
+}
+
+// queue appends data to the end of t.outBuf
+func (t *Terminal) queue(data []rune) {
+ t.outBuf = append(t.outBuf, []byte(string(data))...)
+}
+
+var eraseUnderCursor = []rune{' ', keyEscape, '[', 'D'}
+var space = []rune{' '}
+
+func isPrintable(key rune) bool {
+ isInSurrogateArea := key >= 0xd800 && key <= 0xdbff
+ return key >= 32 && !isInSurrogateArea
+}
+
+// moveCursorToPos appends data to t.outBuf which will move the cursor to the
+// given, logical position in the text.
+func (t *Terminal) moveCursorToPos(pos int) {
+ if !t.echo {
+ return
+ }
+
+ x := visualLength(t.prompt) + pos
+ y := x / t.termWidth
+ x = x % t.termWidth
+
+ up := 0
+ if y < t.cursorY {
+ up = t.cursorY - y
+ }
+
+ down := 0
+ if y > t.cursorY {
+ down = y - t.cursorY
+ }
+
+ left := 0
+ if x < t.cursorX {
+ left = t.cursorX - x
+ }
+
+ right := 0
+ if x > t.cursorX {
+ right = x - t.cursorX
+ }
+
+ t.cursorX = x
+ t.cursorY = y
+ t.move(up, down, left, right)
+}
+
+func (t *Terminal) move(up, down, left, right int) {
+ m := []rune{}
+
+ // 1 unit up can be expressed as ^[[A or ^[A
+ // 5 units up can be expressed as ^[[5A
+
+ if up == 1 {
+ m = append(m, keyEscape, '[', 'A')
+ } else if up > 1 {
+ m = append(m, keyEscape, '[')
+ m = append(m, []rune(strconv.Itoa(up))...)
+ m = append(m, 'A')
+ }
+
+ if down == 1 {
+ m = append(m, keyEscape, '[', 'B')
+ } else if down > 1 {
+ m = append(m, keyEscape, '[')
+ m = append(m, []rune(strconv.Itoa(down))...)
+ m = append(m, 'B')
+ }
+
+ if right == 1 {
+ m = append(m, keyEscape, '[', 'C')
+ } else if right > 1 {
+ m = append(m, keyEscape, '[')
+ m = append(m, []rune(strconv.Itoa(right))...)
+ m = append(m, 'C')
+ }
+
+ if left == 1 {
+ m = append(m, keyEscape, '[', 'D')
+ } else if left > 1 {
+ m = append(m, keyEscape, '[')
+ m = append(m, []rune(strconv.Itoa(left))...)
+ m = append(m, 'D')
+ }
+
+ t.queue(m)
+}
+
+func (t *Terminal) clearLineToRight() {
+ op := []rune{keyEscape, '[', 'K'}
+ t.queue(op)
+}
+
+const maxLineLength = 4096
+
+func (t *Terminal) setLine(newLine []rune, newPos int) {
+ if t.echo {
+ t.moveCursorToPos(0)
+ t.writeLine(newLine)
+ for i := len(newLine); i < len(t.line); i++ {
+ t.writeLine(space)
+ }
+ t.moveCursorToPos(newPos)
+ }
+ t.line = newLine
+ t.pos = newPos
+}
+
+func (t *Terminal) advanceCursor(places int) {
+ t.cursorX += places
+ t.cursorY += t.cursorX / t.termWidth
+ if t.cursorY > t.maxLine {
+ t.maxLine = t.cursorY
+ }
+ t.cursorX = t.cursorX % t.termWidth
+
+ if places > 0 && t.cursorX == 0 {
+ // Normally terminals will advance the current position
+ // when writing a character. But that doesn't happen
+ // for the last character in a line. However, when
+ // writing a character (except a new line) that causes
+ // a line wrap, the position will be advanced two
+ // places.
+ //
+ // So, if we are stopping at the end of a line, we
+ // need to write a newline so that our cursor can be
+ // advanced to the next line.
+ t.outBuf = append(t.outBuf, '\r', '\n')
+ }
+}
+
+func (t *Terminal) eraseNPreviousChars(n int) {
+ if n == 0 {
+ return
+ }
+
+ if t.pos < n {
+ n = t.pos
+ }
+ t.pos -= n
+ t.moveCursorToPos(t.pos)
+
+ copy(t.line[t.pos:], t.line[n+t.pos:])
+ t.line = t.line[:len(t.line)-n]
+ if t.echo {
+ t.writeLine(t.line[t.pos:])
+ for i := 0; i < n; i++ {
+ t.queue(space)
+ }
+ t.advanceCursor(n)
+ t.moveCursorToPos(t.pos)
+ }
+}
+
+// countToLeftWord returns then number of characters from the cursor to the
+// start of the previous word.
+func (t *Terminal) countToLeftWord() int {
+ if t.pos == 0 {
+ return 0
+ }
+
+ pos := t.pos - 1
+ for pos > 0 {
+ if t.line[pos] != ' ' {
+ break
+ }
+ pos--
+ }
+ for pos > 0 {
+ if t.line[pos] == ' ' {
+ pos++
+ break
+ }
+ pos--
+ }
+
+ return t.pos - pos
+}
+
+// countToRightWord returns then number of characters from the cursor to the
+// start of the next word.
+func (t *Terminal) countToRightWord() int {
+ pos := t.pos
+ for pos < len(t.line) {
+ if t.line[pos] == ' ' {
+ break
+ }
+ pos++
+ }
+ for pos < len(t.line) {
+ if t.line[pos] != ' ' {
+ break
+ }
+ pos++
+ }
+ return pos - t.pos
+}
+
+// visualLength returns the number of visible glyphs in s.
+func visualLength(runes []rune) int {
+ inEscapeSeq := false
+ length := 0
+
+ for _, r := range runes {
+ switch {
+ case inEscapeSeq:
+ if (r >= 'a' && r <= 'z') || (r >= 'A' && r <= 'Z') {
+ inEscapeSeq = false
+ }
+ case r == '\x1b':
+ inEscapeSeq = true
+ default:
+ length++
+ }
+ }
+
+ return length
+}
+
+// handleKey processes the given key and, optionally, returns a line of text
+// that the user has entered.
+func (t *Terminal) handleKey(key rune) (line string, ok bool) {
+ if t.pasteActive && key != keyEnter {
+ t.addKeyToLine(key)
+ return
+ }
+
+ switch key {
+ case keyBackspace:
+ if t.pos == 0 {
+ return
+ }
+ t.eraseNPreviousChars(1)
+ case keyAltLeft:
+ // move left by a word.
+ t.pos -= t.countToLeftWord()
+ t.moveCursorToPos(t.pos)
+ case keyAltRight:
+ // move right by a word.
+ t.pos += t.countToRightWord()
+ t.moveCursorToPos(t.pos)
+ case keyLeft:
+ if t.pos == 0 {
+ return
+ }
+ t.pos--
+ t.moveCursorToPos(t.pos)
+ case keyRight:
+ if t.pos == len(t.line) {
+ return
+ }
+ t.pos++
+ t.moveCursorToPos(t.pos)
+ case keyHome:
+ if t.pos == 0 {
+ return
+ }
+ t.pos = 0
+ t.moveCursorToPos(t.pos)
+ case keyEnd:
+ if t.pos == len(t.line) {
+ return
+ }
+ t.pos = len(t.line)
+ t.moveCursorToPos(t.pos)
+ case keyUp:
+ entry, ok := t.history.NthPreviousEntry(t.historyIndex + 1)
+ if !ok {
+ return "", false
+ }
+ if t.historyIndex == -1 {
+ t.historyPending = string(t.line)
+ }
+ t.historyIndex++
+ runes := []rune(entry)
+ t.setLine(runes, len(runes))
+ case keyDown:
+ switch t.historyIndex {
+ case -1:
+ return
+ case 0:
+ runes := []rune(t.historyPending)
+ t.setLine(runes, len(runes))
+ t.historyIndex--
+ default:
+ entry, ok := t.history.NthPreviousEntry(t.historyIndex - 1)
+ if ok {
+ t.historyIndex--
+ runes := []rune(entry)
+ t.setLine(runes, len(runes))
+ }
+ }
+ case keyEnter:
+ t.moveCursorToPos(len(t.line))
+ t.queue([]rune("\r\n"))
+ line = string(t.line)
+ ok = true
+ t.line = t.line[:0]
+ t.pos = 0
+ t.cursorX = 0
+ t.cursorY = 0
+ t.maxLine = 0
+ case keyDeleteWord:
+ // Delete zero or more spaces and then one or more characters.
+ t.eraseNPreviousChars(t.countToLeftWord())
+ case keyDeleteLine:
+ // Delete everything from the current cursor position to the
+ // end of line.
+ for i := t.pos; i < len(t.line); i++ {
+ t.queue(space)
+ t.advanceCursor(1)
+ }
+ t.line = t.line[:t.pos]
+ t.moveCursorToPos(t.pos)
+ case keyCtrlD:
+ // Erase the character under the current position.
+ // The EOF case when the line is empty is handled in
+ // readLine().
+ if t.pos < len(t.line) {
+ t.pos++
+ t.eraseNPreviousChars(1)
+ }
+ case keyCtrlU:
+ t.eraseNPreviousChars(t.pos)
+ case keyClearScreen:
+ // Erases the screen and moves the cursor to the home position.
+ t.queue([]rune("\x1b[2J\x1b[H"))
+ t.queue(t.prompt)
+ t.cursorX, t.cursorY = 0, 0
+ t.advanceCursor(visualLength(t.prompt))
+ t.setLine(t.line, t.pos)
+ default:
+ if t.AutoCompleteCallback != nil {
+ prefix := string(t.line[:t.pos])
+ suffix := string(t.line[t.pos:])
+
+ t.lock.Unlock()
+ newLine, newPos, completeOk := t.AutoCompleteCallback(prefix+suffix, len(prefix), key)
+ t.lock.Lock()
+
+ if completeOk {
+ t.setLine([]rune(newLine), utf8.RuneCount([]byte(newLine)[:newPos]))
+ return
+ }
+ }
+ if !isPrintable(key) {
+ return
+ }
+ if len(t.line) == maxLineLength {
+ return
+ }
+ t.addKeyToLine(key)
+ }
+ return
+}
+
+// addKeyToLine inserts the given key at the current position in the current
+// line.
+func (t *Terminal) addKeyToLine(key rune) {
+ if len(t.line) == cap(t.line) {
+ newLine := make([]rune, len(t.line), 2*(1+len(t.line)))
+ copy(newLine, t.line)
+ t.line = newLine
+ }
+ t.line = t.line[:len(t.line)+1]
+ copy(t.line[t.pos+1:], t.line[t.pos:])
+ t.line[t.pos] = key
+ if t.echo {
+ t.writeLine(t.line[t.pos:])
+ }
+ t.pos++
+ t.moveCursorToPos(t.pos)
+}
+
+func (t *Terminal) writeLine(line []rune) {
+ for len(line) != 0 {
+ remainingOnLine := t.termWidth - t.cursorX
+ todo := len(line)
+ if todo > remainingOnLine {
+ todo = remainingOnLine
+ }
+ t.queue(line[:todo])
+ t.advanceCursor(visualLength(line[:todo]))
+ line = line[todo:]
+ }
+}
+
+// writeWithCRLF writes buf to w but replaces all occurrences of \n with \r\n.
+func writeWithCRLF(w io.Writer, buf []byte) (n int, err error) {
+ for len(buf) > 0 {
+ i := bytes.IndexByte(buf, '\n')
+ todo := len(buf)
+ if i >= 0 {
+ todo = i
+ }
+
+ var nn int
+ nn, err = w.Write(buf[:todo])
+ n += nn
+ if err != nil {
+ return n, err
+ }
+ buf = buf[todo:]
+
+ if i >= 0 {
+ if _, err = w.Write(crlf); err != nil {
+ return n, err
+ }
+ n++
+ buf = buf[1:]
+ }
+ }
+
+ return n, nil
+}
+
+func (t *Terminal) Write(buf []byte) (n int, err error) {
+ t.lock.Lock()
+ defer t.lock.Unlock()
+
+ if t.cursorX == 0 && t.cursorY == 0 {
+ // This is the easy case: there's nothing on the screen that we
+ // have to move out of the way.
+ return writeWithCRLF(t.c, buf)
+ }
+
+ // We have a prompt and possibly user input on the screen. We
+ // have to clear it first.
+ t.move(0 /* up */, 0 /* down */, t.cursorX /* left */, 0 /* right */)
+ t.cursorX = 0
+ t.clearLineToRight()
+
+ for t.cursorY > 0 {
+ t.move(1 /* up */, 0, 0, 0)
+ t.cursorY--
+ t.clearLineToRight()
+ }
+
+ if _, err = t.c.Write(t.outBuf); err != nil {
+ return
+ }
+ t.outBuf = t.outBuf[:0]
+
+ if n, err = writeWithCRLF(t.c, buf); err != nil {
+ return
+ }
+
+ t.writeLine(t.prompt)
+ if t.echo {
+ t.writeLine(t.line)
+ }
+
+ t.moveCursorToPos(t.pos)
+
+ if _, err = t.c.Write(t.outBuf); err != nil {
+ return
+ }
+ t.outBuf = t.outBuf[:0]
+ return
+}
+
+// ReadPassword temporarily changes the prompt and reads a password, without
+// echo, from the terminal.
+func (t *Terminal) ReadPassword(prompt string) (line string, err error) {
+ t.lock.Lock()
+ defer t.lock.Unlock()
+
+ oldPrompt := t.prompt
+ t.prompt = []rune(prompt)
+ t.echo = false
+
+ line, err = t.readLine()
+
+ t.prompt = oldPrompt
+ t.echo = true
+
+ return
+}
+
+// ReadLine returns a line of input from the terminal.
+func (t *Terminal) ReadLine() (line string, err error) {
+ t.lock.Lock()
+ defer t.lock.Unlock()
+
+ return t.readLine()
+}
+
+func (t *Terminal) readLine() (line string, err error) {
+ // t.lock must be held at this point
+
+ if t.cursorX == 0 && t.cursorY == 0 {
+ t.writeLine(t.prompt)
+ t.c.Write(t.outBuf)
+ t.outBuf = t.outBuf[:0]
+ }
+
+ lineIsPasted := t.pasteActive
+
+ for {
+ rest := t.remainder
+ lineOk := false
+ for !lineOk {
+ var key rune
+ key, rest = bytesToKey(rest, t.pasteActive)
+ if key == utf8.RuneError {
+ break
+ }
+ if !t.pasteActive {
+ if key == keyCtrlD {
+ if len(t.line) == 0 {
+ return "", io.EOF
+ }
+ }
+ if key == keyCtrlC {
+ return "", io.EOF
+ }
+ if key == keyPasteStart {
+ t.pasteActive = true
+ if len(t.line) == 0 {
+ lineIsPasted = true
+ }
+ continue
+ }
+ } else if key == keyPasteEnd {
+ t.pasteActive = false
+ continue
+ }
+ if !t.pasteActive {
+ lineIsPasted = false
+ }
+ line, lineOk = t.handleKey(key)
+ }
+ if len(rest) > 0 {
+ n := copy(t.inBuf[:], rest)
+ t.remainder = t.inBuf[:n]
+ } else {
+ t.remainder = nil
+ }
+ t.c.Write(t.outBuf)
+ t.outBuf = t.outBuf[:0]
+ if lineOk {
+ if t.echo {
+ t.historyIndex = -1
+ t.history.Add(line)
+ }
+ if lineIsPasted {
+ err = ErrPasteIndicator
+ }
+ return
+ }
+
+ // t.remainder is a slice at the beginning of t.inBuf
+ // containing a partial key sequence
+ readBuf := t.inBuf[len(t.remainder):]
+ var n int
+
+ t.lock.Unlock()
+ n, err = t.c.Read(readBuf)
+ t.lock.Lock()
+
+ if err != nil {
+ return
+ }
+
+ t.remainder = t.inBuf[:n+len(t.remainder)]
+ }
+}
+
+// SetPrompt sets the prompt to be used when reading subsequent lines.
+func (t *Terminal) SetPrompt(prompt string) {
+ t.lock.Lock()
+ defer t.lock.Unlock()
+
+ t.prompt = []rune(prompt)
+}
+
+func (t *Terminal) clearAndRepaintLinePlusNPrevious(numPrevLines int) {
+ // Move cursor to column zero at the start of the line.
+ t.move(t.cursorY, 0, t.cursorX, 0)
+ t.cursorX, t.cursorY = 0, 0
+ t.clearLineToRight()
+ for t.cursorY < numPrevLines {
+ // Move down a line
+ t.move(0, 1, 0, 0)
+ t.cursorY++
+ t.clearLineToRight()
+ }
+ // Move back to beginning.
+ t.move(t.cursorY, 0, 0, 0)
+ t.cursorX, t.cursorY = 0, 0
+
+ t.queue(t.prompt)
+ t.advanceCursor(visualLength(t.prompt))
+ t.writeLine(t.line)
+ t.moveCursorToPos(t.pos)
+}
+
+func (t *Terminal) SetSize(width, height int) error {
+ t.lock.Lock()
+ defer t.lock.Unlock()
+
+ if width == 0 {
+ width = 1
+ }
+
+ oldWidth := t.termWidth
+ t.termWidth, t.termHeight = width, height
+
+ switch {
+ case width == oldWidth:
+ // If the width didn't change then nothing else needs to be
+ // done.
+ return nil
+ case len(t.line) == 0 && t.cursorX == 0 && t.cursorY == 0:
+ // If there is nothing on current line and no prompt printed,
+ // just do nothing
+ return nil
+ case width < oldWidth:
+ // Some terminals (e.g. xterm) will truncate lines that were
+ // too long when shinking. Others, (e.g. gnome-terminal) will
+ // attempt to wrap them. For the former, repainting t.maxLine
+ // works great, but that behaviour goes badly wrong in the case
+ // of the latter because they have doubled every full line.
+
+ // We assume that we are working on a terminal that wraps lines
+ // and adjust the cursor position based on every previous line
+ // wrapping and turning into two. This causes the prompt on
+ // xterms to move upwards, which isn't great, but it avoids a
+ // huge mess with gnome-terminal.
+ if t.cursorX >= t.termWidth {
+ t.cursorX = t.termWidth - 1
+ }
+ t.cursorY *= 2
+ t.clearAndRepaintLinePlusNPrevious(t.maxLine * 2)
+ case width > oldWidth:
+ // If the terminal expands then our position calculations will
+ // be wrong in the future because we think the cursor is
+ // |t.pos| chars into the string, but there will be a gap at
+ // the end of any wrapped line.
+ //
+ // But the position will actually be correct until we move, so
+ // we can move back to the beginning and repaint everything.
+ t.clearAndRepaintLinePlusNPrevious(t.maxLine)
+ }
+
+ _, err := t.c.Write(t.outBuf)
+ t.outBuf = t.outBuf[:0]
+ return err
+}
+
+type pasteIndicatorError struct{}
+
+func (pasteIndicatorError) Error() string {
+ return "terminal: ErrPasteIndicator not correctly handled"
+}
+
+// ErrPasteIndicator may be returned from ReadLine as the error, in addition
+// to valid line data. It indicates that bracketed paste mode is enabled and
+// that the returned line consists only of pasted data. Programs may wish to
+// interpret pasted data more literally than typed data.
+var ErrPasteIndicator = pasteIndicatorError{}
+
+// SetBracketedPasteMode requests that the terminal bracket paste operations
+// with markers. Not all terminals support this but, if it is supported, then
+// enabling this mode will stop any autocomplete callback from running due to
+// pastes. Additionally, any lines that are completely pasted will be returned
+// from ReadLine with the error set to ErrPasteIndicator.
+func (t *Terminal) SetBracketedPasteMode(on bool) {
+ if on {
+ io.WriteString(t.c, "\x1b[?2004h")
+ } else {
+ io.WriteString(t.c, "\x1b[?2004l")
+ }
+}
+
+// stRingBuffer is a ring buffer of strings.
+type stRingBuffer struct {
+ // entries contains max elements.
+ entries []string
+ max int
+ // head contains the index of the element most recently added to the ring.
+ head int
+ // size contains the number of elements in the ring.
+ size int
+}
+
+func (s *stRingBuffer) Add(a string) {
+ if s.entries == nil {
+ const defaultNumEntries = 100
+ s.entries = make([]string, defaultNumEntries)
+ s.max = defaultNumEntries
+ }
+
+ s.head = (s.head + 1) % s.max
+ s.entries[s.head] = a
+ if s.size < s.max {
+ s.size++
+ }
+}
+
+// NthPreviousEntry returns the value passed to the nth previous call to Add.
+// If n is zero then the immediately prior value is returned, if one, then the
+// next most recent, and so on. If such an element doesn't exist then ok is
+// false.
+func (s *stRingBuffer) NthPreviousEntry(n int) (value string, ok bool) {
+ if n >= s.size {
+ return "", false
+ }
+ index := s.head - n
+ if index < 0 {
+ index += s.max
+ }
+ return s.entries[index], true
+}
+
+// readPasswordLine reads from reader until it finds \n or io.EOF.
+// The slice returned does not include the \n.
+// readPasswordLine also ignores any \r it finds.
+// Windows uses \r as end of line. So, on Windows, readPasswordLine
+// reads until it finds \r and ignores any \n it finds during processing.
+func readPasswordLine(reader io.Reader) ([]byte, error) {
+ var buf [1]byte
+ var ret []byte
+
+ for {
+ n, err := reader.Read(buf[:])
+ if n > 0 {
+ switch buf[0] {
+ case '\b':
+ if len(ret) > 0 {
+ ret = ret[:len(ret)-1]
+ }
+ case '\n':
+ if runtime.GOOS != "windows" {
+ return ret, nil
+ }
+ // otherwise ignore \n
+ case '\r':
+ if runtime.GOOS == "windows" {
+ return ret, nil
+ }
+ // otherwise ignore \r
+ default:
+ ret = append(ret, buf[0])
+ }
+ continue
+ }
+ if err != nil {
+ if err == io.EOF && len(ret) > 0 {
+ return ret, nil
+ }
+ return ret, err
+ }
+ }
+}
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 224d0dd4a..397ab70be 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -319,7 +319,7 @@ github.com/golang/protobuf/ptypes/timestamp
github.com/google/gofuzz
# github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf
github.com/google/shlex
-# github.com/google/uuid v1.1.5
+# github.com/google/uuid v1.2.0
github.com/google/uuid
# github.com/gorilla/mux v1.8.0
github.com/gorilla/mux
@@ -592,7 +592,7 @@ go.opencensus.io/trace/internal
go.opencensus.io/trace/tracestate
# go.uber.org/atomic v1.7.0
go.uber.org/atomic
-# golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899
+# golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad
golang.org/x/crypto/blowfish
golang.org/x/crypto/cast5
golang.org/x/crypto/chacha20
@@ -634,8 +634,11 @@ golang.org/x/sync/semaphore
# golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4
golang.org/x/sys/cpu
golang.org/x/sys/internal/unsafeheader
+golang.org/x/sys/plan9
golang.org/x/sys/unix
golang.org/x/sys/windows
+# golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1
+golang.org/x/term
# golang.org/x/text v0.3.4
golang.org/x/text/encoding
golang.org/x/text/encoding/charmap