Merge pull request #64283 from jessfraz/ProcMountType

Automatic merge from submit-queue (batch tested with PRs 64283, 67910, 67803, 68100). If you want to cherry-pick this change to another branch, please follow the instructions here: https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md.

Add a ProcMount option to the SecurityContext & AllowedProcMountTypes to PodSecurityPolicy

So there is a bit of a chicken and egg problem here in that the CRI runtimes will need to implement this for there to be any sort of e2e testing.

**What this PR does / why we need it**: This PR implements design proposal https://github.com/kubernetes/community/pull/1934. This adds a ProcMount option to the SecurityContext and AllowedProcMountTypes to PodSecurityPolicy

Relies on https://github.com/google/cadvisor/pull/1967

**Release note**:

```release-note
ProcMount added to SecurityContext and AllowedProcMounts added to PodSecurityPolicy to allow paths in the container's /proc to not be masked.
```

cc @Random-Liu @mrunalp

Kubernetes-commit: 39004e852bb523d0497343705ee2bf42b4e9c3e3
This commit is contained in:
Kubernetes Publisher 2018-08-31 16:46:33 -07:00
commit b080aefffc
25 changed files with 465 additions and 513 deletions

258
Godeps/Godeps.json generated
View File

@ -12,11 +12,11 @@
}, },
{ {
"ImportPath": "github.com/Azure/go-ansiterm", "ImportPath": "github.com/Azure/go-ansiterm",
"Rev": "19f72df4d05d31cbe1c56bfc8045c96babff6c7e" "Rev": "d6e3b3328b783f23731bc4d058875b0371ff8109"
}, },
{ {
"ImportPath": "github.com/Azure/go-ansiterm/winterm", "ImportPath": "github.com/Azure/go-ansiterm/winterm",
"Rev": "19f72df4d05d31cbe1c56bfc8045c96babff6c7e" "Rev": "d6e3b3328b783f23731bc4d058875b0371ff8109"
}, },
{ {
"ImportPath": "github.com/NYTimes/gziphandler", "ImportPath": "github.com/NYTimes/gziphandler",
@ -364,11 +364,11 @@
}, },
{ {
"ImportPath": "github.com/docker/docker/pkg/term", "ImportPath": "github.com/docker/docker/pkg/term",
"Rev": "4f3616fb1c112e206b88cb7a9922bf49067a7756" "Rev": "a9fbbdc8dd8794b20af358382ab780559bca589d"
}, },
{ {
"ImportPath": "github.com/docker/docker/pkg/term/windows", "ImportPath": "github.com/docker/docker/pkg/term/windows",
"Rev": "4f3616fb1c112e206b88cb7a9922bf49067a7756" "Rev": "a9fbbdc8dd8794b20af358382ab780559bca589d"
}, },
{ {
"ImportPath": "github.com/elazarl/go-bindata-assetfs", "ImportPath": "github.com/elazarl/go-bindata-assetfs",
@ -856,343 +856,343 @@
}, },
{ {
"ImportPath": "k8s.io/api/admission/v1beta1", "ImportPath": "k8s.io/api/admission/v1beta1",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "fcb01e9febf3e72ae9b6eff41f2d02ffdea4dda1"
}, },
{ {
"ImportPath": "k8s.io/api/admissionregistration/v1alpha1", "ImportPath": "k8s.io/api/admissionregistration/v1alpha1",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "fcb01e9febf3e72ae9b6eff41f2d02ffdea4dda1"
}, },
{ {
"ImportPath": "k8s.io/api/admissionregistration/v1beta1", "ImportPath": "k8s.io/api/admissionregistration/v1beta1",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "fcb01e9febf3e72ae9b6eff41f2d02ffdea4dda1"
}, },
{ {
"ImportPath": "k8s.io/api/apps/v1", "ImportPath": "k8s.io/api/apps/v1",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "fcb01e9febf3e72ae9b6eff41f2d02ffdea4dda1"
}, },
{ {
"ImportPath": "k8s.io/api/apps/v1beta1", "ImportPath": "k8s.io/api/apps/v1beta1",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "fcb01e9febf3e72ae9b6eff41f2d02ffdea4dda1"
}, },
{ {
"ImportPath": "k8s.io/api/apps/v1beta2", "ImportPath": "k8s.io/api/apps/v1beta2",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "fcb01e9febf3e72ae9b6eff41f2d02ffdea4dda1"
}, },
{ {
"ImportPath": "k8s.io/api/authentication/v1", "ImportPath": "k8s.io/api/authentication/v1",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "fcb01e9febf3e72ae9b6eff41f2d02ffdea4dda1"
}, },
{ {
"ImportPath": "k8s.io/api/authentication/v1beta1", "ImportPath": "k8s.io/api/authentication/v1beta1",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "fcb01e9febf3e72ae9b6eff41f2d02ffdea4dda1"
}, },
{ {
"ImportPath": "k8s.io/api/authorization/v1", "ImportPath": "k8s.io/api/authorization/v1",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "fcb01e9febf3e72ae9b6eff41f2d02ffdea4dda1"
}, },
{ {
"ImportPath": "k8s.io/api/authorization/v1beta1", "ImportPath": "k8s.io/api/authorization/v1beta1",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "fcb01e9febf3e72ae9b6eff41f2d02ffdea4dda1"
}, },
{ {
"ImportPath": "k8s.io/api/autoscaling/v1", "ImportPath": "k8s.io/api/autoscaling/v1",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "fcb01e9febf3e72ae9b6eff41f2d02ffdea4dda1"
}, },
{ {
"ImportPath": "k8s.io/api/autoscaling/v2beta1", "ImportPath": "k8s.io/api/autoscaling/v2beta1",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "fcb01e9febf3e72ae9b6eff41f2d02ffdea4dda1"
}, },
{ {
"ImportPath": "k8s.io/api/autoscaling/v2beta2", "ImportPath": "k8s.io/api/autoscaling/v2beta2",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "fcb01e9febf3e72ae9b6eff41f2d02ffdea4dda1"
}, },
{ {
"ImportPath": "k8s.io/api/batch/v1", "ImportPath": "k8s.io/api/batch/v1",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "fcb01e9febf3e72ae9b6eff41f2d02ffdea4dda1"
}, },
{ {
"ImportPath": "k8s.io/api/batch/v1beta1", "ImportPath": "k8s.io/api/batch/v1beta1",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "fcb01e9febf3e72ae9b6eff41f2d02ffdea4dda1"
}, },
{ {
"ImportPath": "k8s.io/api/batch/v2alpha1", "ImportPath": "k8s.io/api/batch/v2alpha1",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "fcb01e9febf3e72ae9b6eff41f2d02ffdea4dda1"
}, },
{ {
"ImportPath": "k8s.io/api/certificates/v1beta1", "ImportPath": "k8s.io/api/certificates/v1beta1",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "fcb01e9febf3e72ae9b6eff41f2d02ffdea4dda1"
}, },
{ {
"ImportPath": "k8s.io/api/coordination/v1beta1", "ImportPath": "k8s.io/api/coordination/v1beta1",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "fcb01e9febf3e72ae9b6eff41f2d02ffdea4dda1"
}, },
{ {
"ImportPath": "k8s.io/api/core/v1", "ImportPath": "k8s.io/api/core/v1",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "fcb01e9febf3e72ae9b6eff41f2d02ffdea4dda1"
}, },
{ {
"ImportPath": "k8s.io/api/events/v1beta1", "ImportPath": "k8s.io/api/events/v1beta1",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "fcb01e9febf3e72ae9b6eff41f2d02ffdea4dda1"
}, },
{ {
"ImportPath": "k8s.io/api/extensions/v1beta1", "ImportPath": "k8s.io/api/extensions/v1beta1",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "fcb01e9febf3e72ae9b6eff41f2d02ffdea4dda1"
}, },
{ {
"ImportPath": "k8s.io/api/networking/v1", "ImportPath": "k8s.io/api/networking/v1",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "fcb01e9febf3e72ae9b6eff41f2d02ffdea4dda1"
}, },
{ {
"ImportPath": "k8s.io/api/policy/v1beta1", "ImportPath": "k8s.io/api/policy/v1beta1",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "fcb01e9febf3e72ae9b6eff41f2d02ffdea4dda1"
}, },
{ {
"ImportPath": "k8s.io/api/rbac/v1", "ImportPath": "k8s.io/api/rbac/v1",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "fcb01e9febf3e72ae9b6eff41f2d02ffdea4dda1"
}, },
{ {
"ImportPath": "k8s.io/api/rbac/v1alpha1", "ImportPath": "k8s.io/api/rbac/v1alpha1",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "fcb01e9febf3e72ae9b6eff41f2d02ffdea4dda1"
}, },
{ {
"ImportPath": "k8s.io/api/rbac/v1beta1", "ImportPath": "k8s.io/api/rbac/v1beta1",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "fcb01e9febf3e72ae9b6eff41f2d02ffdea4dda1"
}, },
{ {
"ImportPath": "k8s.io/api/scheduling/v1alpha1", "ImportPath": "k8s.io/api/scheduling/v1alpha1",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "fcb01e9febf3e72ae9b6eff41f2d02ffdea4dda1"
}, },
{ {
"ImportPath": "k8s.io/api/scheduling/v1beta1", "ImportPath": "k8s.io/api/scheduling/v1beta1",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "fcb01e9febf3e72ae9b6eff41f2d02ffdea4dda1"
}, },
{ {
"ImportPath": "k8s.io/api/settings/v1alpha1", "ImportPath": "k8s.io/api/settings/v1alpha1",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "fcb01e9febf3e72ae9b6eff41f2d02ffdea4dda1"
}, },
{ {
"ImportPath": "k8s.io/api/storage/v1", "ImportPath": "k8s.io/api/storage/v1",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "fcb01e9febf3e72ae9b6eff41f2d02ffdea4dda1"
}, },
{ {
"ImportPath": "k8s.io/api/storage/v1alpha1", "ImportPath": "k8s.io/api/storage/v1alpha1",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "fcb01e9febf3e72ae9b6eff41f2d02ffdea4dda1"
}, },
{ {
"ImportPath": "k8s.io/api/storage/v1beta1", "ImportPath": "k8s.io/api/storage/v1beta1",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "fcb01e9febf3e72ae9b6eff41f2d02ffdea4dda1"
}, },
{ {
"ImportPath": "k8s.io/apimachinery/pkg/api/apitesting", "ImportPath": "k8s.io/apimachinery/pkg/api/apitesting",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "7022e8e5e6f8d55cdc303669184073a493482496"
}, },
{ {
"ImportPath": "k8s.io/apimachinery/pkg/api/apitesting/fuzzer", "ImportPath": "k8s.io/apimachinery/pkg/api/apitesting/fuzzer",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "7022e8e5e6f8d55cdc303669184073a493482496"
}, },
{ {
"ImportPath": "k8s.io/apimachinery/pkg/api/apitesting/roundtrip", "ImportPath": "k8s.io/apimachinery/pkg/api/apitesting/roundtrip",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "7022e8e5e6f8d55cdc303669184073a493482496"
}, },
{ {
"ImportPath": "k8s.io/apimachinery/pkg/api/equality", "ImportPath": "k8s.io/apimachinery/pkg/api/equality",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "7022e8e5e6f8d55cdc303669184073a493482496"
}, },
{ {
"ImportPath": "k8s.io/apimachinery/pkg/api/errors", "ImportPath": "k8s.io/apimachinery/pkg/api/errors",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "7022e8e5e6f8d55cdc303669184073a493482496"
}, },
{ {
"ImportPath": "k8s.io/apimachinery/pkg/api/meta", "ImportPath": "k8s.io/apimachinery/pkg/api/meta",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "7022e8e5e6f8d55cdc303669184073a493482496"
}, },
{ {
"ImportPath": "k8s.io/apimachinery/pkg/api/resource", "ImportPath": "k8s.io/apimachinery/pkg/api/resource",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "7022e8e5e6f8d55cdc303669184073a493482496"
}, },
{ {
"ImportPath": "k8s.io/apimachinery/pkg/api/validation", "ImportPath": "k8s.io/apimachinery/pkg/api/validation",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "7022e8e5e6f8d55cdc303669184073a493482496"
}, },
{ {
"ImportPath": "k8s.io/apimachinery/pkg/api/validation/path", "ImportPath": "k8s.io/apimachinery/pkg/api/validation/path",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "7022e8e5e6f8d55cdc303669184073a493482496"
}, },
{ {
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/fuzzer", "ImportPath": "k8s.io/apimachinery/pkg/apis/meta/fuzzer",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "7022e8e5e6f8d55cdc303669184073a493482496"
}, },
{ {
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/internalversion", "ImportPath": "k8s.io/apimachinery/pkg/apis/meta/internalversion",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "7022e8e5e6f8d55cdc303669184073a493482496"
}, },
{ {
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1", "ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "7022e8e5e6f8d55cdc303669184073a493482496"
}, },
{ {
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured", "ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "7022e8e5e6f8d55cdc303669184073a493482496"
}, },
{ {
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1/validation", "ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1/validation",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "7022e8e5e6f8d55cdc303669184073a493482496"
}, },
{ {
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1beta1", "ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1beta1",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "7022e8e5e6f8d55cdc303669184073a493482496"
}, },
{ {
"ImportPath": "k8s.io/apimachinery/pkg/conversion", "ImportPath": "k8s.io/apimachinery/pkg/conversion",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "7022e8e5e6f8d55cdc303669184073a493482496"
}, },
{ {
"ImportPath": "k8s.io/apimachinery/pkg/conversion/queryparams", "ImportPath": "k8s.io/apimachinery/pkg/conversion/queryparams",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "7022e8e5e6f8d55cdc303669184073a493482496"
}, },
{ {
"ImportPath": "k8s.io/apimachinery/pkg/fields", "ImportPath": "k8s.io/apimachinery/pkg/fields",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "7022e8e5e6f8d55cdc303669184073a493482496"
}, },
{ {
"ImportPath": "k8s.io/apimachinery/pkg/labels", "ImportPath": "k8s.io/apimachinery/pkg/labels",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "7022e8e5e6f8d55cdc303669184073a493482496"
}, },
{ {
"ImportPath": "k8s.io/apimachinery/pkg/runtime", "ImportPath": "k8s.io/apimachinery/pkg/runtime",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "7022e8e5e6f8d55cdc303669184073a493482496"
}, },
{ {
"ImportPath": "k8s.io/apimachinery/pkg/runtime/schema", "ImportPath": "k8s.io/apimachinery/pkg/runtime/schema",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "7022e8e5e6f8d55cdc303669184073a493482496"
}, },
{ {
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer", "ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "7022e8e5e6f8d55cdc303669184073a493482496"
}, },
{ {
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/json", "ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/json",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "7022e8e5e6f8d55cdc303669184073a493482496"
}, },
{ {
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/protobuf", "ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/protobuf",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "7022e8e5e6f8d55cdc303669184073a493482496"
}, },
{ {
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/recognizer", "ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/recognizer",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "7022e8e5e6f8d55cdc303669184073a493482496"
}, },
{ {
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/streaming", "ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/streaming",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "7022e8e5e6f8d55cdc303669184073a493482496"
}, },
{ {
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/versioning", "ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/versioning",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "7022e8e5e6f8d55cdc303669184073a493482496"
}, },
{ {
"ImportPath": "k8s.io/apimachinery/pkg/selection", "ImportPath": "k8s.io/apimachinery/pkg/selection",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "7022e8e5e6f8d55cdc303669184073a493482496"
}, },
{ {
"ImportPath": "k8s.io/apimachinery/pkg/types", "ImportPath": "k8s.io/apimachinery/pkg/types",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "7022e8e5e6f8d55cdc303669184073a493482496"
}, },
{ {
"ImportPath": "k8s.io/apimachinery/pkg/util/cache", "ImportPath": "k8s.io/apimachinery/pkg/util/cache",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "7022e8e5e6f8d55cdc303669184073a493482496"
}, },
{ {
"ImportPath": "k8s.io/apimachinery/pkg/util/clock", "ImportPath": "k8s.io/apimachinery/pkg/util/clock",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "7022e8e5e6f8d55cdc303669184073a493482496"
}, },
{ {
"ImportPath": "k8s.io/apimachinery/pkg/util/diff", "ImportPath": "k8s.io/apimachinery/pkg/util/diff",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "7022e8e5e6f8d55cdc303669184073a493482496"
}, },
{ {
"ImportPath": "k8s.io/apimachinery/pkg/util/errors", "ImportPath": "k8s.io/apimachinery/pkg/util/errors",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "7022e8e5e6f8d55cdc303669184073a493482496"
}, },
{ {
"ImportPath": "k8s.io/apimachinery/pkg/util/framer", "ImportPath": "k8s.io/apimachinery/pkg/util/framer",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "7022e8e5e6f8d55cdc303669184073a493482496"
}, },
{ {
"ImportPath": "k8s.io/apimachinery/pkg/util/intstr", "ImportPath": "k8s.io/apimachinery/pkg/util/intstr",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "7022e8e5e6f8d55cdc303669184073a493482496"
}, },
{ {
"ImportPath": "k8s.io/apimachinery/pkg/util/json", "ImportPath": "k8s.io/apimachinery/pkg/util/json",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "7022e8e5e6f8d55cdc303669184073a493482496"
}, },
{ {
"ImportPath": "k8s.io/apimachinery/pkg/util/mergepatch", "ImportPath": "k8s.io/apimachinery/pkg/util/mergepatch",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "7022e8e5e6f8d55cdc303669184073a493482496"
}, },
{ {
"ImportPath": "k8s.io/apimachinery/pkg/util/naming", "ImportPath": "k8s.io/apimachinery/pkg/util/naming",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "7022e8e5e6f8d55cdc303669184073a493482496"
}, },
{ {
"ImportPath": "k8s.io/apimachinery/pkg/util/net", "ImportPath": "k8s.io/apimachinery/pkg/util/net",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "7022e8e5e6f8d55cdc303669184073a493482496"
}, },
{ {
"ImportPath": "k8s.io/apimachinery/pkg/util/rand", "ImportPath": "k8s.io/apimachinery/pkg/util/rand",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "7022e8e5e6f8d55cdc303669184073a493482496"
}, },
{ {
"ImportPath": "k8s.io/apimachinery/pkg/util/runtime", "ImportPath": "k8s.io/apimachinery/pkg/util/runtime",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "7022e8e5e6f8d55cdc303669184073a493482496"
}, },
{ {
"ImportPath": "k8s.io/apimachinery/pkg/util/sets", "ImportPath": "k8s.io/apimachinery/pkg/util/sets",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "7022e8e5e6f8d55cdc303669184073a493482496"
}, },
{ {
"ImportPath": "k8s.io/apimachinery/pkg/util/strategicpatch", "ImportPath": "k8s.io/apimachinery/pkg/util/strategicpatch",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "7022e8e5e6f8d55cdc303669184073a493482496"
}, },
{ {
"ImportPath": "k8s.io/apimachinery/pkg/util/uuid", "ImportPath": "k8s.io/apimachinery/pkg/util/uuid",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "7022e8e5e6f8d55cdc303669184073a493482496"
}, },
{ {
"ImportPath": "k8s.io/apimachinery/pkg/util/validation", "ImportPath": "k8s.io/apimachinery/pkg/util/validation",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "7022e8e5e6f8d55cdc303669184073a493482496"
}, },
{ {
"ImportPath": "k8s.io/apimachinery/pkg/util/validation/field", "ImportPath": "k8s.io/apimachinery/pkg/util/validation/field",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "7022e8e5e6f8d55cdc303669184073a493482496"
}, },
{ {
"ImportPath": "k8s.io/apimachinery/pkg/util/wait", "ImportPath": "k8s.io/apimachinery/pkg/util/wait",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "7022e8e5e6f8d55cdc303669184073a493482496"
}, },
{ {
"ImportPath": "k8s.io/apimachinery/pkg/util/waitgroup", "ImportPath": "k8s.io/apimachinery/pkg/util/waitgroup",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "7022e8e5e6f8d55cdc303669184073a493482496"
}, },
{ {
"ImportPath": "k8s.io/apimachinery/pkg/util/yaml", "ImportPath": "k8s.io/apimachinery/pkg/util/yaml",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "7022e8e5e6f8d55cdc303669184073a493482496"
}, },
{ {
"ImportPath": "k8s.io/apimachinery/pkg/version", "ImportPath": "k8s.io/apimachinery/pkg/version",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "7022e8e5e6f8d55cdc303669184073a493482496"
}, },
{ {
"ImportPath": "k8s.io/apimachinery/pkg/watch", "ImportPath": "k8s.io/apimachinery/pkg/watch",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "7022e8e5e6f8d55cdc303669184073a493482496"
}, },
{ {
"ImportPath": "k8s.io/apimachinery/third_party/forked/golang/json", "ImportPath": "k8s.io/apimachinery/third_party/forked/golang/json",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "7022e8e5e6f8d55cdc303669184073a493482496"
}, },
{ {
"ImportPath": "k8s.io/apimachinery/third_party/forked/golang/reflect", "ImportPath": "k8s.io/apimachinery/third_party/forked/golang/reflect",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "7022e8e5e6f8d55cdc303669184073a493482496"
}, },
{ {
"ImportPath": "k8s.io/client-go/discovery", "ImportPath": "k8s.io/client-go/discovery",
@ -1202,6 +1202,10 @@
"ImportPath": "k8s.io/client-go/discovery/fake", "ImportPath": "k8s.io/client-go/discovery/fake",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4"
}, },
{
"ImportPath": "k8s.io/client-go/informers",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4"
},
{ {
"ImportPath": "k8s.io/client-go/informers/admissionregistration", "ImportPath": "k8s.io/client-go/informers/admissionregistration",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4"
@ -1378,6 +1382,10 @@
"ImportPath": "k8s.io/client-go/kubernetes", "ImportPath": "k8s.io/client-go/kubernetes",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4"
}, },
{
"ImportPath": "k8s.io/client-go/kubernetes/fake",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4"
},
{ {
"ImportPath": "k8s.io/client-go/kubernetes/scheme", "ImportPath": "k8s.io/client-go/kubernetes/scheme",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4"
@ -1778,6 +1786,10 @@
"ImportPath": "k8s.io/client-go/tools/cache", "ImportPath": "k8s.io/client-go/tools/cache",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4"
}, },
{
"ImportPath": "k8s.io/client-go/tools/clientcmd",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4"
},
{ {
"ImportPath": "k8s.io/client-go/tools/clientcmd/api", "ImportPath": "k8s.io/client-go/tools/clientcmd/api",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4" "Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4"
@ -1854,74 +1866,6 @@
"ImportPath": "k8s.io/kube-openapi/pkg/util/proto", "ImportPath": "k8s.io/kube-openapi/pkg/util/proto",
"Rev": "0cf8f7e6ed1d2e3d47d02e3b6e559369af24d803" "Rev": "0cf8f7e6ed1d2e3d47d02e3b6e559369af24d803"
}, },
{
"ImportPath": "k8s.io/client-go/discovery",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4"
},
{
"ImportPath": "k8s.io/client-go/informers",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4"
},
{
"ImportPath": "k8s.io/client-go/kubernetes",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4"
},
{
"ImportPath": "k8s.io/client-go/kubernetes/fake",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4"
},
{
"ImportPath": "k8s.io/client-go/kubernetes/scheme",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4"
},
{
"ImportPath": "k8s.io/client-go/kubernetes/typed/authentication/v1beta1",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4"
},
{
"ImportPath": "k8s.io/client-go/kubernetes/typed/authorization/v1beta1",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4"
},
{
"ImportPath": "k8s.io/client-go/listers/admissionregistration/v1beta1",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4"
},
{
"ImportPath": "k8s.io/client-go/listers/core/v1",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4"
},
{
"ImportPath": "k8s.io/client-go/rest",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4"
},
{
"ImportPath": "k8s.io/client-go/testing",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4"
},
{
"ImportPath": "k8s.io/client-go/tools/cache",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4"
},
{
"ImportPath": "k8s.io/client-go/tools/clientcmd",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4"
},
{
"ImportPath": "k8s.io/client-go/tools/clientcmd/api",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4"
},
{
"ImportPath": "k8s.io/client-go/tools/clientcmd/api/v1",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4"
},
{
"ImportPath": "k8s.io/client-go/util/cert",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4"
},
{
"ImportPath": "k8s.io/client-go/util/flowcontrol",
"Rev": "87935b98dd4abdf6477f29baf934d6dd0aba82d4"
},
{ {
"ImportPath": "k8s.io/utils/pointer", "ImportPath": "k8s.io/utils/pointer",
"Rev": "66066c83e385e385ccc3c964b44fd7dcd413d0ed" "Rev": "66066c83e385e385ccc3c964b44fd7dcd413d0ed"

View File

@ -5,7 +5,7 @@ type csiEntryState struct {
} }
func (csiState csiEntryState) Handle(b byte) (s state, e error) { func (csiState csiEntryState) Handle(b byte) (s state, e error) {
logger.Infof("CsiEntry::Handle %#x", b) csiState.parser.logf("CsiEntry::Handle %#x", b)
nextState, err := csiState.baseState.Handle(b) nextState, err := csiState.baseState.Handle(b)
if nextState != nil || err != nil { if nextState != nil || err != nil {
@ -25,7 +25,7 @@ func (csiState csiEntryState) Handle(b byte) (s state, e error) {
} }
func (csiState csiEntryState) Transition(s state) error { func (csiState csiEntryState) Transition(s state) error {
logger.Infof("CsiEntry::Transition %s --> %s", csiState.Name(), s.Name()) csiState.parser.logf("CsiEntry::Transition %s --> %s", csiState.Name(), s.Name())
csiState.baseState.Transition(s) csiState.baseState.Transition(s)
switch s { switch s {

View File

@ -5,7 +5,7 @@ type csiParamState struct {
} }
func (csiState csiParamState) Handle(b byte) (s state, e error) { func (csiState csiParamState) Handle(b byte) (s state, e error) {
logger.Infof("CsiParam::Handle %#x", b) csiState.parser.logf("CsiParam::Handle %#x", b)
nextState, err := csiState.baseState.Handle(b) nextState, err := csiState.baseState.Handle(b)
if nextState != nil || err != nil { if nextState != nil || err != nil {
@ -26,7 +26,7 @@ func (csiState csiParamState) Handle(b byte) (s state, e error) {
} }
func (csiState csiParamState) Transition(s state) error { func (csiState csiParamState) Transition(s state) error {
logger.Infof("CsiParam::Transition %s --> %s", csiState.Name(), s.Name()) csiState.parser.logf("CsiParam::Transition %s --> %s", csiState.Name(), s.Name())
csiState.baseState.Transition(s) csiState.baseState.Transition(s)
switch s { switch s {

View File

@ -5,7 +5,7 @@ type escapeIntermediateState struct {
} }
func (escState escapeIntermediateState) Handle(b byte) (s state, e error) { func (escState escapeIntermediateState) Handle(b byte) (s state, e error) {
logger.Infof("escapeIntermediateState::Handle %#x", b) escState.parser.logf("escapeIntermediateState::Handle %#x", b)
nextState, err := escState.baseState.Handle(b) nextState, err := escState.baseState.Handle(b)
if nextState != nil || err != nil { if nextState != nil || err != nil {
return nextState, err return nextState, err
@ -24,7 +24,7 @@ func (escState escapeIntermediateState) Handle(b byte) (s state, e error) {
} }
func (escState escapeIntermediateState) Transition(s state) error { func (escState escapeIntermediateState) Transition(s state) error {
logger.Infof("escapeIntermediateState::Transition %s --> %s", escState.Name(), s.Name()) escState.parser.logf("escapeIntermediateState::Transition %s --> %s", escState.Name(), s.Name())
escState.baseState.Transition(s) escState.baseState.Transition(s)
switch s { switch s {

View File

@ -5,7 +5,7 @@ type escapeState struct {
} }
func (escState escapeState) Handle(b byte) (s state, e error) { func (escState escapeState) Handle(b byte) (s state, e error) {
logger.Infof("escapeState::Handle %#x", b) escState.parser.logf("escapeState::Handle %#x", b)
nextState, err := escState.baseState.Handle(b) nextState, err := escState.baseState.Handle(b)
if nextState != nil || err != nil { if nextState != nil || err != nil {
return nextState, err return nextState, err
@ -28,7 +28,7 @@ func (escState escapeState) Handle(b byte) (s state, e error) {
} }
func (escState escapeState) Transition(s state) error { func (escState escapeState) Transition(s state) error {
logger.Infof("Escape::Transition %s --> %s", escState.Name(), s.Name()) escState.parser.logf("Escape::Transition %s --> %s", escState.Name(), s.Name())
escState.baseState.Transition(s) escState.baseState.Transition(s)
switch s { switch s {

View File

@ -5,7 +5,7 @@ type oscStringState struct {
} }
func (oscState oscStringState) Handle(b byte) (s state, e error) { func (oscState oscStringState) Handle(b byte) (s state, e error) {
logger.Infof("OscString::Handle %#x", b) oscState.parser.logf("OscString::Handle %#x", b)
nextState, err := oscState.baseState.Handle(b) nextState, err := oscState.baseState.Handle(b)
if nextState != nil || err != nil { if nextState != nil || err != nil {
return nextState, err return nextState, err

View File

@ -2,14 +2,10 @@ package ansiterm
import ( import (
"errors" "errors"
"io/ioutil" "log"
"os" "os"
"github.com/sirupsen/logrus"
) )
var logger *logrus.Logger
type AnsiParser struct { type AnsiParser struct {
currState state currState state
eventHandler AnsiEventHandler eventHandler AnsiEventHandler
@ -23,50 +19,69 @@ type AnsiParser struct {
ground state ground state
oscString state oscString state
stateMap []state stateMap []state
logf func(string, ...interface{})
} }
func CreateParser(initialState string, evtHandler AnsiEventHandler) *AnsiParser { type Option func(*AnsiParser)
logFile := ioutil.Discard
if isDebugEnv := os.Getenv(LogEnv); isDebugEnv == "1" { func WithLogf(f func(string, ...interface{})) Option {
logFile, _ = os.Create("ansiParser.log") return func(ap *AnsiParser) {
ap.logf = f
} }
}
logger = &logrus.Logger{ func CreateParser(initialState string, evtHandler AnsiEventHandler, opts ...Option) *AnsiParser {
Out: logFile, ap := &AnsiParser{
Formatter: new(logrus.TextFormatter),
Level: logrus.InfoLevel,
}
parser := &AnsiParser{
eventHandler: evtHandler, eventHandler: evtHandler,
context: &ansiContext{}, context: &ansiContext{},
} }
for _, o := range opts {
parser.csiEntry = csiEntryState{baseState{name: "CsiEntry", parser: parser}} o(ap)
parser.csiParam = csiParamState{baseState{name: "CsiParam", parser: parser}}
parser.dcsEntry = dcsEntryState{baseState{name: "DcsEntry", parser: parser}}
parser.escape = escapeState{baseState{name: "Escape", parser: parser}}
parser.escapeIntermediate = escapeIntermediateState{baseState{name: "EscapeIntermediate", parser: parser}}
parser.error = errorState{baseState{name: "Error", parser: parser}}
parser.ground = groundState{baseState{name: "Ground", parser: parser}}
parser.oscString = oscStringState{baseState{name: "OscString", parser: parser}}
parser.stateMap = []state{
parser.csiEntry,
parser.csiParam,
parser.dcsEntry,
parser.escape,
parser.escapeIntermediate,
parser.error,
parser.ground,
parser.oscString,
} }
parser.currState = getState(initialState, parser.stateMap) if isDebugEnv := os.Getenv(LogEnv); isDebugEnv == "1" {
logFile, _ := os.Create("ansiParser.log")
logger := log.New(logFile, "", log.LstdFlags)
if ap.logf != nil {
l := ap.logf
ap.logf = func(s string, v ...interface{}) {
l(s, v...)
logger.Printf(s, v...)
}
} else {
ap.logf = logger.Printf
}
}
logger.Infof("CreateParser: parser %p", parser) if ap.logf == nil {
return parser ap.logf = func(string, ...interface{}) {}
}
ap.csiEntry = csiEntryState{baseState{name: "CsiEntry", parser: ap}}
ap.csiParam = csiParamState{baseState{name: "CsiParam", parser: ap}}
ap.dcsEntry = dcsEntryState{baseState{name: "DcsEntry", parser: ap}}
ap.escape = escapeState{baseState{name: "Escape", parser: ap}}
ap.escapeIntermediate = escapeIntermediateState{baseState{name: "EscapeIntermediate", parser: ap}}
ap.error = errorState{baseState{name: "Error", parser: ap}}
ap.ground = groundState{baseState{name: "Ground", parser: ap}}
ap.oscString = oscStringState{baseState{name: "OscString", parser: ap}}
ap.stateMap = []state{
ap.csiEntry,
ap.csiParam,
ap.dcsEntry,
ap.escape,
ap.escapeIntermediate,
ap.error,
ap.ground,
ap.oscString,
}
ap.currState = getState(initialState, ap.stateMap)
ap.logf("CreateParser: parser %p", ap)
return ap
} }
func getState(name string, states []state) state { func getState(name string, states []state) state {
@ -97,7 +112,7 @@ func (ap *AnsiParser) handle(b byte) error {
} }
if newState == nil { if newState == nil {
logger.Warning("newState is nil") ap.logf("WARNING: newState is nil")
return errors.New("New state of 'nil' is invalid.") return errors.New("New state of 'nil' is invalid.")
} }
@ -111,23 +126,23 @@ func (ap *AnsiParser) handle(b byte) error {
} }
func (ap *AnsiParser) changeState(newState state) error { func (ap *AnsiParser) changeState(newState state) error {
logger.Infof("ChangeState %s --> %s", ap.currState.Name(), newState.Name()) ap.logf("ChangeState %s --> %s", ap.currState.Name(), newState.Name())
// Exit old state // Exit old state
if err := ap.currState.Exit(); err != nil { if err := ap.currState.Exit(); err != nil {
logger.Infof("Exit state '%s' failed with : '%v'", ap.currState.Name(), err) ap.logf("Exit state '%s' failed with : '%v'", ap.currState.Name(), err)
return err return err
} }
// Perform transition action // Perform transition action
if err := ap.currState.Transition(newState); err != nil { if err := ap.currState.Transition(newState); err != nil {
logger.Infof("Transition from '%s' to '%s' failed with: '%v'", ap.currState.Name(), newState.Name, err) ap.logf("Transition from '%s' to '%s' failed with: '%v'", ap.currState.Name(), newState.Name, err)
return err return err
} }
// Enter new state // Enter new state
if err := newState.Enter(); err != nil { if err := newState.Enter(); err != nil {
logger.Infof("Enter state '%s' failed with: '%v'", newState.Name(), err) ap.logf("Enter state '%s' failed with: '%v'", newState.Name(), err)
return err return err
} }

View File

@ -27,7 +27,6 @@ func parseParams(bytes []byte) ([]string, error) {
params = append(params, s) params = append(params, s)
} }
logger.Infof("Parsed params: %v with length: %d", params, len(params))
return params, nil return params, nil
} }
@ -37,7 +36,6 @@ func parseCmd(context ansiContext) (string, error) {
func getInt(params []string, dflt int) int { func getInt(params []string, dflt int) int {
i := getInts(params, 1, dflt)[0] i := getInts(params, 1, dflt)[0]
logger.Infof("getInt: %v", i)
return i return i
} }
@ -60,8 +58,6 @@ func getInts(params []string, minCount int, dflt int) []int {
} }
} }
logger.Infof("getInts: %v", ints)
return ints return ints
} }

View File

@ -1,19 +1,15 @@
package ansiterm package ansiterm
import (
"fmt"
)
func (ap *AnsiParser) collectParam() error { func (ap *AnsiParser) collectParam() error {
currChar := ap.context.currentChar currChar := ap.context.currentChar
logger.Infof("collectParam %#x", currChar) ap.logf("collectParam %#x", currChar)
ap.context.paramBuffer = append(ap.context.paramBuffer, currChar) ap.context.paramBuffer = append(ap.context.paramBuffer, currChar)
return nil return nil
} }
func (ap *AnsiParser) collectInter() error { func (ap *AnsiParser) collectInter() error {
currChar := ap.context.currentChar currChar := ap.context.currentChar
logger.Infof("collectInter %#x", currChar) ap.logf("collectInter %#x", currChar)
ap.context.paramBuffer = append(ap.context.interBuffer, currChar) ap.context.paramBuffer = append(ap.context.interBuffer, currChar)
return nil return nil
} }
@ -21,8 +17,8 @@ func (ap *AnsiParser) collectInter() error {
func (ap *AnsiParser) escDispatch() error { func (ap *AnsiParser) escDispatch() error {
cmd, _ := parseCmd(*ap.context) cmd, _ := parseCmd(*ap.context)
intermeds := ap.context.interBuffer intermeds := ap.context.interBuffer
logger.Infof("escDispatch currentChar: %#x", ap.context.currentChar) ap.logf("escDispatch currentChar: %#x", ap.context.currentChar)
logger.Infof("escDispatch: %v(%v)", cmd, intermeds) ap.logf("escDispatch: %v(%v)", cmd, intermeds)
switch cmd { switch cmd {
case "D": // IND case "D": // IND
@ -43,8 +39,9 @@ func (ap *AnsiParser) escDispatch() error {
func (ap *AnsiParser) csiDispatch() error { func (ap *AnsiParser) csiDispatch() error {
cmd, _ := parseCmd(*ap.context) cmd, _ := parseCmd(*ap.context)
params, _ := parseParams(ap.context.paramBuffer) params, _ := parseParams(ap.context.paramBuffer)
ap.logf("Parsed params: %v with length: %d", params, len(params))
logger.Infof("csiDispatch: %v(%v)", cmd, params) ap.logf("csiDispatch: %v(%v)", cmd, params)
switch cmd { switch cmd {
case "@": case "@":
@ -102,7 +99,7 @@ func (ap *AnsiParser) csiDispatch() error {
top, bottom := ints[0], ints[1] top, bottom := ints[0], ints[1]
return ap.eventHandler.DECSTBM(top, bottom) return ap.eventHandler.DECSTBM(top, bottom)
default: default:
logger.Errorf(fmt.Sprintf("Unsupported CSI command: '%s', with full context: %v", cmd, ap.context)) ap.logf("ERROR: Unsupported CSI command: '%s', with full context: %v", cmd, ap.context)
return nil return nil
} }

View File

@ -175,7 +175,7 @@ func GetStdFile(nFile int) (*os.File, uintptr) {
fd, err := syscall.GetStdHandle(nFile) fd, err := syscall.GetStdHandle(nFile)
if err != nil { if err != nil {
panic(fmt.Errorf("Invalid standard handle indentifier: %v -- %v", nFile, err)) panic(fmt.Errorf("Invalid standard handle identifier: %v -- %v", nFile, err))
} }
return file, uintptr(fd) return file, uintptr(fd)

View File

@ -49,17 +49,22 @@ var (
const ( const (
// Console modes // Console modes
// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms686033(v=vs.85).aspx. // See https://msdn.microsoft.com/en-us/library/windows/desktop/ms686033(v=vs.85).aspx.
ENABLE_PROCESSED_INPUT = 0x0001 ENABLE_PROCESSED_INPUT = 0x0001
ENABLE_LINE_INPUT = 0x0002 ENABLE_LINE_INPUT = 0x0002
ENABLE_ECHO_INPUT = 0x0004 ENABLE_ECHO_INPUT = 0x0004
ENABLE_WINDOW_INPUT = 0x0008 ENABLE_WINDOW_INPUT = 0x0008
ENABLE_MOUSE_INPUT = 0x0010 ENABLE_MOUSE_INPUT = 0x0010
ENABLE_INSERT_MODE = 0x0020 ENABLE_INSERT_MODE = 0x0020
ENABLE_QUICK_EDIT_MODE = 0x0040 ENABLE_QUICK_EDIT_MODE = 0x0040
ENABLE_EXTENDED_FLAGS = 0x0080 ENABLE_EXTENDED_FLAGS = 0x0080
ENABLE_AUTO_POSITION = 0x0100
ENABLE_VIRTUAL_TERMINAL_INPUT = 0x0200
ENABLE_PROCESSED_OUTPUT = 0x0001 ENABLE_PROCESSED_OUTPUT = 0x0001
ENABLE_WRAP_AT_EOL_OUTPUT = 0x0002 ENABLE_WRAP_AT_EOL_OUTPUT = 0x0002
ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004
DISABLE_NEWLINE_AUTO_RETURN = 0x0008
ENABLE_LVB_GRID_WORLDWIDE = 0x0010
// Character attributes // Character attributes
// Note: // Note:

View File

@ -34,7 +34,7 @@ func (h *windowsAnsiEventHandler) setCursorPosition(position COORD, window SMALL
if err != nil { if err != nil {
return err return err
} }
logger.Infof("Cursor position set: (%d, %d)", position.X, position.Y) h.logf("Cursor position set: (%d, %d)", position.X, position.Y)
return err return err
} }

View File

@ -50,8 +50,8 @@ func (h *windowsAnsiEventHandler) insertLines(param int) error {
// scroll scrolls the provided scroll region by param lines. The scroll region is in buffer coordinates. // scroll scrolls the provided scroll region by param lines. The scroll region is in buffer coordinates.
func (h *windowsAnsiEventHandler) scroll(param int, sr scrollRegion, info *CONSOLE_SCREEN_BUFFER_INFO) error { func (h *windowsAnsiEventHandler) scroll(param int, sr scrollRegion, info *CONSOLE_SCREEN_BUFFER_INFO) error {
logger.Infof("scroll: scrollTop: %d, scrollBottom: %d", sr.top, sr.bottom) h.logf("scroll: scrollTop: %d, scrollBottom: %d", sr.top, sr.bottom)
logger.Infof("scroll: windowTop: %d, windowBottom: %d", info.Window.Top, info.Window.Bottom) h.logf("scroll: windowTop: %d, windowBottom: %d", info.Window.Top, info.Window.Bottom)
// Copy from and clip to the scroll region (full buffer width) // Copy from and clip to the scroll region (full buffer width)
scrollRect := SMALL_RECT{ scrollRect := SMALL_RECT{

View File

@ -4,16 +4,13 @@ package winterm
import ( import (
"bytes" "bytes"
"io/ioutil" "log"
"os" "os"
"strconv" "strconv"
"github.com/Azure/go-ansiterm" "github.com/Azure/go-ansiterm"
"github.com/sirupsen/logrus"
) )
var logger *logrus.Logger
type windowsAnsiEventHandler struct { type windowsAnsiEventHandler struct {
fd uintptr fd uintptr
file *os.File file *os.File
@ -28,32 +25,52 @@ type windowsAnsiEventHandler struct {
marginByte byte marginByte byte
curInfo *CONSOLE_SCREEN_BUFFER_INFO curInfo *CONSOLE_SCREEN_BUFFER_INFO
curPos COORD curPos COORD
logf func(string, ...interface{})
} }
func CreateWinEventHandler(fd uintptr, file *os.File) ansiterm.AnsiEventHandler { type Option func(*windowsAnsiEventHandler)
logFile := ioutil.Discard
if isDebugEnv := os.Getenv(ansiterm.LogEnv); isDebugEnv == "1" { func WithLogf(f func(string, ...interface{})) Option {
logFile, _ = os.Create("winEventHandler.log") return func(w *windowsAnsiEventHandler) {
} w.logf = f
logger = &logrus.Logger{
Out: logFile,
Formatter: new(logrus.TextFormatter),
Level: logrus.DebugLevel,
} }
}
func CreateWinEventHandler(fd uintptr, file *os.File, opts ...Option) ansiterm.AnsiEventHandler {
infoReset, err := GetConsoleScreenBufferInfo(fd) infoReset, err := GetConsoleScreenBufferInfo(fd)
if err != nil { if err != nil {
return nil return nil
} }
return &windowsAnsiEventHandler{ h := &windowsAnsiEventHandler{
fd: fd, fd: fd,
file: file, file: file,
infoReset: infoReset, infoReset: infoReset,
attributes: infoReset.Attributes, attributes: infoReset.Attributes,
} }
for _, o := range opts {
o(h)
}
if isDebugEnv := os.Getenv(ansiterm.LogEnv); isDebugEnv == "1" {
logFile, _ := os.Create("winEventHandler.log")
logger := log.New(logFile, "", log.LstdFlags)
if h.logf != nil {
l := h.logf
h.logf = func(s string, v ...interface{}) {
l(s, v...)
logger.Printf(s, v...)
}
} else {
h.logf = logger.Printf
}
}
if h.logf == nil {
h.logf = func(string, ...interface{}) {}
}
return h
} }
type scrollRegion struct { type scrollRegion struct {
@ -96,7 +113,7 @@ func (h *windowsAnsiEventHandler) simulateLF(includeCR bool) (bool, error) {
if err := h.Flush(); err != nil { if err := h.Flush(); err != nil {
return false, err return false, err
} }
logger.Info("Simulating LF inside scroll region") h.logf("Simulating LF inside scroll region")
if err := h.scrollUp(1); err != nil { if err := h.scrollUp(1); err != nil {
return false, err return false, err
} }
@ -119,7 +136,7 @@ func (h *windowsAnsiEventHandler) simulateLF(includeCR bool) (bool, error) {
} else { } else {
// The cursor is at the bottom of the screen but outside the scroll // The cursor is at the bottom of the screen but outside the scroll
// region. Skip the LF. // region. Skip the LF.
logger.Info("Simulating LF outside scroll region") h.logf("Simulating LF outside scroll region")
if includeCR { if includeCR {
if err := h.Flush(); err != nil { if err := h.Flush(); err != nil {
return false, err return false, err
@ -151,7 +168,7 @@ func (h *windowsAnsiEventHandler) executeLF() error {
if err := h.Flush(); err != nil { if err := h.Flush(); err != nil {
return err return err
} }
logger.Info("Resetting cursor position for LF without CR") h.logf("Resetting cursor position for LF without CR")
if err := SetConsoleCursorPosition(h.fd, pos); err != nil { if err := SetConsoleCursorPosition(h.fd, pos); err != nil {
return err return err
} }
@ -186,7 +203,7 @@ func (h *windowsAnsiEventHandler) Print(b byte) error {
func (h *windowsAnsiEventHandler) Execute(b byte) error { func (h *windowsAnsiEventHandler) Execute(b byte) error {
switch b { switch b {
case ansiterm.ANSI_TAB: case ansiterm.ANSI_TAB:
logger.Info("Execute(TAB)") h.logf("Execute(TAB)")
// Move to the next tab stop, but preserve auto-wrap if already set. // Move to the next tab stop, but preserve auto-wrap if already set.
if !h.wrapNext { if !h.wrapNext {
pos, info, err := h.getCurrentInfo() pos, info, err := h.getCurrentInfo()
@ -269,7 +286,7 @@ func (h *windowsAnsiEventHandler) CUU(param int) error {
if err := h.Flush(); err != nil { if err := h.Flush(); err != nil {
return err return err
} }
logger.Infof("CUU: [%v]", []string{strconv.Itoa(param)}) h.logf("CUU: [%v]", []string{strconv.Itoa(param)})
h.clearWrap() h.clearWrap()
return h.moveCursorVertical(-param) return h.moveCursorVertical(-param)
} }
@ -278,7 +295,7 @@ func (h *windowsAnsiEventHandler) CUD(param int) error {
if err := h.Flush(); err != nil { if err := h.Flush(); err != nil {
return err return err
} }
logger.Infof("CUD: [%v]", []string{strconv.Itoa(param)}) h.logf("CUD: [%v]", []string{strconv.Itoa(param)})
h.clearWrap() h.clearWrap()
return h.moveCursorVertical(param) return h.moveCursorVertical(param)
} }
@ -287,7 +304,7 @@ func (h *windowsAnsiEventHandler) CUF(param int) error {
if err := h.Flush(); err != nil { if err := h.Flush(); err != nil {
return err return err
} }
logger.Infof("CUF: [%v]", []string{strconv.Itoa(param)}) h.logf("CUF: [%v]", []string{strconv.Itoa(param)})
h.clearWrap() h.clearWrap()
return h.moveCursorHorizontal(param) return h.moveCursorHorizontal(param)
} }
@ -296,7 +313,7 @@ func (h *windowsAnsiEventHandler) CUB(param int) error {
if err := h.Flush(); err != nil { if err := h.Flush(); err != nil {
return err return err
} }
logger.Infof("CUB: [%v]", []string{strconv.Itoa(param)}) h.logf("CUB: [%v]", []string{strconv.Itoa(param)})
h.clearWrap() h.clearWrap()
return h.moveCursorHorizontal(-param) return h.moveCursorHorizontal(-param)
} }
@ -305,7 +322,7 @@ func (h *windowsAnsiEventHandler) CNL(param int) error {
if err := h.Flush(); err != nil { if err := h.Flush(); err != nil {
return err return err
} }
logger.Infof("CNL: [%v]", []string{strconv.Itoa(param)}) h.logf("CNL: [%v]", []string{strconv.Itoa(param)})
h.clearWrap() h.clearWrap()
return h.moveCursorLine(param) return h.moveCursorLine(param)
} }
@ -314,7 +331,7 @@ func (h *windowsAnsiEventHandler) CPL(param int) error {
if err := h.Flush(); err != nil { if err := h.Flush(); err != nil {
return err return err
} }
logger.Infof("CPL: [%v]", []string{strconv.Itoa(param)}) h.logf("CPL: [%v]", []string{strconv.Itoa(param)})
h.clearWrap() h.clearWrap()
return h.moveCursorLine(-param) return h.moveCursorLine(-param)
} }
@ -323,7 +340,7 @@ func (h *windowsAnsiEventHandler) CHA(param int) error {
if err := h.Flush(); err != nil { if err := h.Flush(); err != nil {
return err return err
} }
logger.Infof("CHA: [%v]", []string{strconv.Itoa(param)}) h.logf("CHA: [%v]", []string{strconv.Itoa(param)})
h.clearWrap() h.clearWrap()
return h.moveCursorColumn(param) return h.moveCursorColumn(param)
} }
@ -332,7 +349,7 @@ func (h *windowsAnsiEventHandler) VPA(param int) error {
if err := h.Flush(); err != nil { if err := h.Flush(); err != nil {
return err return err
} }
logger.Infof("VPA: [[%d]]", param) h.logf("VPA: [[%d]]", param)
h.clearWrap() h.clearWrap()
info, err := GetConsoleScreenBufferInfo(h.fd) info, err := GetConsoleScreenBufferInfo(h.fd)
if err != nil { if err != nil {
@ -348,7 +365,7 @@ func (h *windowsAnsiEventHandler) CUP(row int, col int) error {
if err := h.Flush(); err != nil { if err := h.Flush(); err != nil {
return err return err
} }
logger.Infof("CUP: [[%d %d]]", row, col) h.logf("CUP: [[%d %d]]", row, col)
h.clearWrap() h.clearWrap()
info, err := GetConsoleScreenBufferInfo(h.fd) info, err := GetConsoleScreenBufferInfo(h.fd)
if err != nil { if err != nil {
@ -364,7 +381,7 @@ func (h *windowsAnsiEventHandler) HVP(row int, col int) error {
if err := h.Flush(); err != nil { if err := h.Flush(); err != nil {
return err return err
} }
logger.Infof("HVP: [[%d %d]]", row, col) h.logf("HVP: [[%d %d]]", row, col)
h.clearWrap() h.clearWrap()
return h.CUP(row, col) return h.CUP(row, col)
} }
@ -373,7 +390,7 @@ func (h *windowsAnsiEventHandler) DECTCEM(visible bool) error {
if err := h.Flush(); err != nil { if err := h.Flush(); err != nil {
return err return err
} }
logger.Infof("DECTCEM: [%v]", []string{strconv.FormatBool(visible)}) h.logf("DECTCEM: [%v]", []string{strconv.FormatBool(visible)})
h.clearWrap() h.clearWrap()
return nil return nil
} }
@ -382,7 +399,7 @@ func (h *windowsAnsiEventHandler) DECOM(enable bool) error {
if err := h.Flush(); err != nil { if err := h.Flush(); err != nil {
return err return err
} }
logger.Infof("DECOM: [%v]", []string{strconv.FormatBool(enable)}) h.logf("DECOM: [%v]", []string{strconv.FormatBool(enable)})
h.clearWrap() h.clearWrap()
h.originMode = enable h.originMode = enable
return h.CUP(1, 1) return h.CUP(1, 1)
@ -392,7 +409,7 @@ func (h *windowsAnsiEventHandler) DECCOLM(use132 bool) error {
if err := h.Flush(); err != nil { if err := h.Flush(); err != nil {
return err return err
} }
logger.Infof("DECCOLM: [%v]", []string{strconv.FormatBool(use132)}) h.logf("DECCOLM: [%v]", []string{strconv.FormatBool(use132)})
h.clearWrap() h.clearWrap()
if err := h.ED(2); err != nil { if err := h.ED(2); err != nil {
return err return err
@ -407,7 +424,7 @@ func (h *windowsAnsiEventHandler) DECCOLM(use132 bool) error {
} }
if info.Size.X < targetWidth { if info.Size.X < targetWidth {
if err := SetConsoleScreenBufferSize(h.fd, COORD{targetWidth, info.Size.Y}); err != nil { if err := SetConsoleScreenBufferSize(h.fd, COORD{targetWidth, info.Size.Y}); err != nil {
logger.Info("set buffer failed:", err) h.logf("set buffer failed: %v", err)
return err return err
} }
} }
@ -415,12 +432,12 @@ func (h *windowsAnsiEventHandler) DECCOLM(use132 bool) error {
window.Left = 0 window.Left = 0
window.Right = targetWidth - 1 window.Right = targetWidth - 1
if err := SetConsoleWindowInfo(h.fd, true, window); err != nil { if err := SetConsoleWindowInfo(h.fd, true, window); err != nil {
logger.Info("set window failed:", err) h.logf("set window failed: %v", err)
return err return err
} }
if info.Size.X > targetWidth { if info.Size.X > targetWidth {
if err := SetConsoleScreenBufferSize(h.fd, COORD{targetWidth, info.Size.Y}); err != nil { if err := SetConsoleScreenBufferSize(h.fd, COORD{targetWidth, info.Size.Y}); err != nil {
logger.Info("set buffer failed:", err) h.logf("set buffer failed: %v", err)
return err return err
} }
} }
@ -431,7 +448,7 @@ func (h *windowsAnsiEventHandler) ED(param int) error {
if err := h.Flush(); err != nil { if err := h.Flush(); err != nil {
return err return err
} }
logger.Infof("ED: [%v]", []string{strconv.Itoa(param)}) h.logf("ED: [%v]", []string{strconv.Itoa(param)})
h.clearWrap() h.clearWrap()
// [J -- Erases from the cursor to the end of the screen, including the cursor position. // [J -- Erases from the cursor to the end of the screen, including the cursor position.
@ -490,7 +507,7 @@ func (h *windowsAnsiEventHandler) EL(param int) error {
if err := h.Flush(); err != nil { if err := h.Flush(); err != nil {
return err return err
} }
logger.Infof("EL: [%v]", strconv.Itoa(param)) h.logf("EL: [%v]", strconv.Itoa(param))
h.clearWrap() h.clearWrap()
// [K -- Erases from the cursor to the end of the line, including the cursor position. // [K -- Erases from the cursor to the end of the line, including the cursor position.
@ -531,7 +548,7 @@ func (h *windowsAnsiEventHandler) IL(param int) error {
if err := h.Flush(); err != nil { if err := h.Flush(); err != nil {
return err return err
} }
logger.Infof("IL: [%v]", strconv.Itoa(param)) h.logf("IL: [%v]", strconv.Itoa(param))
h.clearWrap() h.clearWrap()
return h.insertLines(param) return h.insertLines(param)
} }
@ -540,7 +557,7 @@ func (h *windowsAnsiEventHandler) DL(param int) error {
if err := h.Flush(); err != nil { if err := h.Flush(); err != nil {
return err return err
} }
logger.Infof("DL: [%v]", strconv.Itoa(param)) h.logf("DL: [%v]", strconv.Itoa(param))
h.clearWrap() h.clearWrap()
return h.deleteLines(param) return h.deleteLines(param)
} }
@ -549,7 +566,7 @@ func (h *windowsAnsiEventHandler) ICH(param int) error {
if err := h.Flush(); err != nil { if err := h.Flush(); err != nil {
return err return err
} }
logger.Infof("ICH: [%v]", strconv.Itoa(param)) h.logf("ICH: [%v]", strconv.Itoa(param))
h.clearWrap() h.clearWrap()
return h.insertCharacters(param) return h.insertCharacters(param)
} }
@ -558,7 +575,7 @@ func (h *windowsAnsiEventHandler) DCH(param int) error {
if err := h.Flush(); err != nil { if err := h.Flush(); err != nil {
return err return err
} }
logger.Infof("DCH: [%v]", strconv.Itoa(param)) h.logf("DCH: [%v]", strconv.Itoa(param))
h.clearWrap() h.clearWrap()
return h.deleteCharacters(param) return h.deleteCharacters(param)
} }
@ -572,7 +589,7 @@ func (h *windowsAnsiEventHandler) SGR(params []int) error {
strings = append(strings, strconv.Itoa(v)) strings = append(strings, strconv.Itoa(v))
} }
logger.Infof("SGR: [%v]", strings) h.logf("SGR: [%v]", strings)
if len(params) <= 0 { if len(params) <= 0 {
h.attributes = h.infoReset.Attributes h.attributes = h.infoReset.Attributes
@ -606,7 +623,7 @@ func (h *windowsAnsiEventHandler) SU(param int) error {
if err := h.Flush(); err != nil { if err := h.Flush(); err != nil {
return err return err
} }
logger.Infof("SU: [%v]", []string{strconv.Itoa(param)}) h.logf("SU: [%v]", []string{strconv.Itoa(param)})
h.clearWrap() h.clearWrap()
return h.scrollUp(param) return h.scrollUp(param)
} }
@ -615,13 +632,13 @@ func (h *windowsAnsiEventHandler) SD(param int) error {
if err := h.Flush(); err != nil { if err := h.Flush(); err != nil {
return err return err
} }
logger.Infof("SD: [%v]", []string{strconv.Itoa(param)}) h.logf("SD: [%v]", []string{strconv.Itoa(param)})
h.clearWrap() h.clearWrap()
return h.scrollDown(param) return h.scrollDown(param)
} }
func (h *windowsAnsiEventHandler) DA(params []string) error { func (h *windowsAnsiEventHandler) DA(params []string) error {
logger.Infof("DA: [%v]", params) h.logf("DA: [%v]", params)
// DA cannot be implemented because it must send data on the VT100 input stream, // DA cannot be implemented because it must send data on the VT100 input stream,
// which is not available to go-ansiterm. // which is not available to go-ansiterm.
return nil return nil
@ -631,7 +648,7 @@ func (h *windowsAnsiEventHandler) DECSTBM(top int, bottom int) error {
if err := h.Flush(); err != nil { if err := h.Flush(); err != nil {
return err return err
} }
logger.Infof("DECSTBM: [%d, %d]", top, bottom) h.logf("DECSTBM: [%d, %d]", top, bottom)
// Windows is 0 indexed, Linux is 1 indexed // Windows is 0 indexed, Linux is 1 indexed
h.sr.top = int16(top - 1) h.sr.top = int16(top - 1)
@ -646,7 +663,7 @@ func (h *windowsAnsiEventHandler) RI() error {
if err := h.Flush(); err != nil { if err := h.Flush(); err != nil {
return err return err
} }
logger.Info("RI: []") h.logf("RI: []")
h.clearWrap() h.clearWrap()
info, err := GetConsoleScreenBufferInfo(h.fd) info, err := GetConsoleScreenBufferInfo(h.fd)
@ -663,21 +680,21 @@ func (h *windowsAnsiEventHandler) RI() error {
} }
func (h *windowsAnsiEventHandler) IND() error { func (h *windowsAnsiEventHandler) IND() error {
logger.Info("IND: []") h.logf("IND: []")
return h.executeLF() return h.executeLF()
} }
func (h *windowsAnsiEventHandler) Flush() error { func (h *windowsAnsiEventHandler) Flush() error {
h.curInfo = nil h.curInfo = nil
if h.buffer.Len() > 0 { if h.buffer.Len() > 0 {
logger.Infof("Flush: [%s]", h.buffer.Bytes()) h.logf("Flush: [%s]", h.buffer.Bytes())
if _, err := h.buffer.WriteTo(h.file); err != nil { if _, err := h.buffer.WriteTo(h.file); err != nil {
return err return err
} }
} }
if h.wrapNext && !h.drewMarginByte { if h.wrapNext && !h.drewMarginByte {
logger.Infof("Flush: drawing margin byte '%c'", h.marginByte) h.logf("Flush: drawing margin byte '%c'", h.marginByte)
info, err := GetConsoleScreenBufferInfo(h.fd) info, err := GetConsoleScreenBufferInfo(h.fd)
if err != nil { if err != nil {

File diff suppressed because it is too large Load Diff

View File

@ -59,7 +59,7 @@ next:
return nil, fmt.Errorf("Unknown character: '%s'", key) return nil, fmt.Errorf("Unknown character: '%s'", key)
} }
} else { } else {
codes = append(codes, byte(key[0])) codes = append(codes, key[0])
} }
} }
return codes, nil return codes, nil

View File

@ -34,6 +34,10 @@ func NewEscapeProxy(r io.Reader, escapeKeys []byte) io.Reader {
func (r *escapeProxy) Read(buf []byte) (int, error) { func (r *escapeProxy) Read(buf []byte) (int, error) {
nr, err := r.r.Read(buf) nr, err := r.r.Read(buf)
if len(r.escapeKeys) == 0 {
return nr, err
}
preserve := func() { preserve := func() {
// this preserves the original key presses in the passed in buffer // this preserves the original key presses in the passed in buffer
nr += r.escapeKeyPos nr += r.escapeKeyPos

View File

@ -1,5 +1,4 @@
// +build !windows // +build !windows
// +build !solaris !cgo
package term package term

View File

@ -1,65 +0,0 @@
// +build solaris,cgo
package term
import (
"syscall"
"unsafe"
"golang.org/x/sys/unix"
)
// #include <termios.h>
import "C"
// Termios is the Unix API for terminal I/O.
// It is passthrough for unix.Termios in order to make it portable with
// other platforms where it is not available or handled differently.
type Termios unix.Termios
// MakeRaw put the terminal connected to the given file descriptor into raw
// mode and returns the previous state of the terminal so that it can be
// restored.
func MakeRaw(fd uintptr) (*State, error) {
var oldState State
if err := tcget(fd, &oldState.termios); err != 0 {
return nil, err
}
newState := oldState.termios
newState.Iflag &^= (unix.IGNBRK | unix.BRKINT | unix.PARMRK | unix.ISTRIP | unix.INLCR | unix.IGNCR | unix.ICRNL | unix.IXON | unix.IXANY)
newState.Oflag &^= unix.OPOST
newState.Lflag &^= (unix.ECHO | unix.ECHONL | unix.ICANON | unix.ISIG | unix.IEXTEN)
newState.Cflag &^= (unix.CSIZE | unix.PARENB)
newState.Cflag |= unix.CS8
/*
VMIN is the minimum number of characters that needs to be read in non-canonical mode for it to be returned
Since VMIN is overloaded with another element in canonical mode when we switch modes it defaults to 4. It
needs to be explicitly set to 1.
*/
newState.Cc[C.VMIN] = 1
newState.Cc[C.VTIME] = 0
if err := tcset(fd, &newState); err != 0 {
return nil, err
}
return &oldState, nil
}
func tcget(fd uintptr, p *Termios) syscall.Errno {
ret, err := C.tcgetattr(C.int(fd), (*C.struct_termios)(unsafe.Pointer(p)))
if ret != 0 {
return err.(syscall.Errno)
}
return 0
}
func tcset(fd uintptr, p *Termios) syscall.Errno {
ret, err := C.tcsetattr(C.int(fd), C.TCSANOW, (*C.struct_termios)(unsafe.Pointer(p)))
if ret != 0 {
return err.(syscall.Errno)
}
return 0
}

View File

@ -1,5 +1,3 @@
// +build windows
package term package term
import ( import (
@ -23,14 +21,7 @@ type Winsize struct {
Width uint16 Width uint16
} }
const ( // vtInputSupported is true if winterm.ENABLE_VIRTUAL_TERMINAL_INPUT is supported by the console
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms683167(v=vs.85).aspx
enableVirtualTerminalInput = 0x0200
enableVirtualTerminalProcessing = 0x0004
disableNewlineAutoReturn = 0x0008
)
// vtInputSupported is true if enableVirtualTerminalInput is supported by the console
var vtInputSupported bool var vtInputSupported bool
// StdStreams returns the standard streams (stdin, stdout, stderr). // StdStreams returns the standard streams (stdin, stdout, stderr).
@ -40,8 +31,8 @@ func StdStreams() (stdIn io.ReadCloser, stdOut, stdErr io.Writer) {
var emulateStdin, emulateStdout, emulateStderr bool var emulateStdin, emulateStdout, emulateStderr bool
fd := os.Stdin.Fd() fd := os.Stdin.Fd()
if mode, err := winterm.GetConsoleMode(fd); err == nil { if mode, err := winterm.GetConsoleMode(fd); err == nil {
// Validate that enableVirtualTerminalInput is supported, but do not set it. // Validate that winterm.ENABLE_VIRTUAL_TERMINAL_INPUT is supported, but do not set it.
if err = winterm.SetConsoleMode(fd, mode|enableVirtualTerminalInput); err != nil { if err = winterm.SetConsoleMode(fd, mode|winterm.ENABLE_VIRTUAL_TERMINAL_INPUT); err != nil {
emulateStdin = true emulateStdin = true
} else { } else {
vtInputSupported = true vtInputSupported = true
@ -53,21 +44,21 @@ func StdStreams() (stdIn io.ReadCloser, stdOut, stdErr io.Writer) {
fd = os.Stdout.Fd() fd = os.Stdout.Fd()
if mode, err := winterm.GetConsoleMode(fd); err == nil { if mode, err := winterm.GetConsoleMode(fd); err == nil {
// Validate disableNewlineAutoReturn is supported, but do not set it. // Validate winterm.DISABLE_NEWLINE_AUTO_RETURN is supported, but do not set it.
if err = winterm.SetConsoleMode(fd, mode|enableVirtualTerminalProcessing|disableNewlineAutoReturn); err != nil { if err = winterm.SetConsoleMode(fd, mode|winterm.ENABLE_VIRTUAL_TERMINAL_PROCESSING|winterm.DISABLE_NEWLINE_AUTO_RETURN); err != nil {
emulateStdout = true emulateStdout = true
} else { } else {
winterm.SetConsoleMode(fd, mode|enableVirtualTerminalProcessing) winterm.SetConsoleMode(fd, mode|winterm.ENABLE_VIRTUAL_TERMINAL_PROCESSING)
} }
} }
fd = os.Stderr.Fd() fd = os.Stderr.Fd()
if mode, err := winterm.GetConsoleMode(fd); err == nil { if mode, err := winterm.GetConsoleMode(fd); err == nil {
// Validate disableNewlineAutoReturn is supported, but do not set it. // Validate winterm.DISABLE_NEWLINE_AUTO_RETURN is supported, but do not set it.
if err = winterm.SetConsoleMode(fd, mode|enableVirtualTerminalProcessing|disableNewlineAutoReturn); err != nil { if err = winterm.SetConsoleMode(fd, mode|winterm.ENABLE_VIRTUAL_TERMINAL_PROCESSING|winterm.DISABLE_NEWLINE_AUTO_RETURN); err != nil {
emulateStderr = true emulateStderr = true
} else { } else {
winterm.SetConsoleMode(fd, mode|enableVirtualTerminalProcessing) winterm.SetConsoleMode(fd, mode|winterm.ENABLE_VIRTUAL_TERMINAL_PROCESSING)
} }
} }
@ -183,9 +174,9 @@ func SetRawTerminalOutput(fd uintptr) (*State, error) {
return nil, err return nil, err
} }
// Ignore failures, since disableNewlineAutoReturn might not be supported on this // Ignore failures, since winterm.DISABLE_NEWLINE_AUTO_RETURN might not be supported on this
// version of Windows. // version of Windows.
winterm.SetConsoleMode(fd, state.mode|disableNewlineAutoReturn) winterm.SetConsoleMode(fd, state.mode|winterm.DISABLE_NEWLINE_AUTO_RETURN)
return state, err return state, err
} }
@ -215,7 +206,7 @@ func MakeRaw(fd uintptr) (*State, error) {
mode |= winterm.ENABLE_INSERT_MODE mode |= winterm.ENABLE_INSERT_MODE
mode |= winterm.ENABLE_QUICK_EDIT_MODE mode |= winterm.ENABLE_QUICK_EDIT_MODE
if vtInputSupported { if vtInputSupported {
mode |= enableVirtualTerminalInput mode |= winterm.ENABLE_VIRTUAL_TERMINAL_INPUT
} }
err = winterm.SetConsoleMode(fd, mode) err = winterm.SetConsoleMode(fd, mode)

View File

@ -1,4 +1,4 @@
// +build darwin freebsd openbsd // +build darwin freebsd openbsd netbsd
package term package term

View File

@ -29,6 +29,8 @@ func MakeRaw(fd uintptr) (*State, error) {
termios.Lflag &^= (unix.ECHO | unix.ECHONL | unix.ICANON | unix.ISIG | unix.IEXTEN) termios.Lflag &^= (unix.ECHO | unix.ECHONL | unix.ICANON | unix.ISIG | unix.IEXTEN)
termios.Cflag &^= (unix.CSIZE | unix.PARENB) termios.Cflag &^= (unix.CSIZE | unix.PARENB)
termios.Cflag |= unix.CS8 termios.Cflag |= unix.CS8
termios.Cc[unix.VMIN] = 1
termios.Cc[unix.VTIME] = 0
if err := unix.IoctlSetTermios(int(fd), setTermios, termios); err != nil { if err := unix.IoctlSetTermios(int(fd), setTermios, termios); err != nil {
return nil, err return nil, err

View File

@ -9,7 +9,7 @@ import (
"os" "os"
"sync" "sync"
ansiterm "github.com/Azure/go-ansiterm" "github.com/Azure/go-ansiterm"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )

View File

@ -1,30 +1,20 @@
// +build !solaris,!windows // +build !windows
package term package term
import ( import (
"unsafe"
"golang.org/x/sys/unix" "golang.org/x/sys/unix"
) )
// GetWinsize returns the window size based on the specified file descriptor. // GetWinsize returns the window size based on the specified file descriptor.
func GetWinsize(fd uintptr) (*Winsize, error) { func GetWinsize(fd uintptr) (*Winsize, error) {
ws := &Winsize{} uws, err := unix.IoctlGetWinsize(int(fd), unix.TIOCGWINSZ)
_, _, err := unix.Syscall(unix.SYS_IOCTL, fd, uintptr(unix.TIOCGWINSZ), uintptr(unsafe.Pointer(ws))) ws := &Winsize{Height: uws.Row, Width: uws.Col, x: uws.Xpixel, y: uws.Ypixel}
// Skipp errno = 0
if err == 0 {
return ws, nil
}
return ws, err return ws, err
} }
// SetWinsize tries to set the specified window size for the specified file descriptor. // SetWinsize tries to set the specified window size for the specified file descriptor.
func SetWinsize(fd uintptr, ws *Winsize) error { func SetWinsize(fd uintptr, ws *Winsize) error {
_, _, err := unix.Syscall(unix.SYS_IOCTL, fd, uintptr(unix.TIOCSWINSZ), uintptr(unsafe.Pointer(ws))) uws := &unix.Winsize{Row: ws.Height, Col: ws.Width, Xpixel: ws.x, Ypixel: ws.y}
// Skipp errno = 0 return unix.IoctlSetWinsize(int(fd), unix.TIOCSWINSZ, uws)
if err == 0 {
return nil
}
return err
} }

View File

@ -1,42 +0,0 @@
// +build solaris,cgo
package term
import (
"unsafe"
"golang.org/x/sys/unix"
)
/*
#include <unistd.h>
#include <stropts.h>
#include <termios.h>
// Small wrapper to get rid of variadic args of ioctl()
int my_ioctl(int fd, int cmd, struct winsize *ws) {
return ioctl(fd, cmd, ws);
}
*/
import "C"
// GetWinsize returns the window size based on the specified file descriptor.
func GetWinsize(fd uintptr) (*Winsize, error) {
ws := &Winsize{}
ret, err := C.my_ioctl(C.int(fd), C.int(unix.TIOCGWINSZ), (*C.struct_winsize)(unsafe.Pointer(ws)))
// Skip retval = 0
if ret == 0 {
return ws, nil
}
return ws, err
}
// SetWinsize tries to set the specified window size for the specified file descriptor.
func SetWinsize(fd uintptr, ws *Winsize) error {
ret, err := C.my_ioctl(C.int(fd), C.int(unix.TIOCSWINSZ), (*C.struct_winsize)(unsafe.Pointer(ws)))
// Skip retval = 0
if ret == 0 {
return nil
}
return err
}