@@ -11,15 +11,21 @@ import (
1111// In is an input stream to read user input. It implements [io.ReadCloser]
1212// with additional utilities, such as putting the terminal in raw mode.
1313type In struct {
14- commonStream
1514 in io.ReadCloser
15+ cs commonStream
1616}
1717
1818// NewIn returns a new [In] from an [io.ReadCloser].
1919func NewIn (in io.ReadCloser ) * In {
20- i := & In {in : in }
21- i .fd , i .isTerminal = term .GetFdInfo (in )
22- return i
20+ return & In {
21+ in : in ,
22+ cs : newCommonStream (in ),
23+ }
24+ }
25+
26+ // FD returns the file descriptor number for this stream.
27+ func (i * In ) FD () uintptr {
28+ return i .cs .fd
2329}
2430
2531// Read implements the [io.Reader] interface.
@@ -32,11 +38,21 @@ func (i *In) Close() error {
3238 return i .in .Close ()
3339}
3440
41+ // IsTerminal returns whether this stream is connected to a terminal.
42+ func (i * In ) IsTerminal () bool {
43+ return i .cs .isTerminal ()
44+ }
45+
3546// SetRawTerminal sets raw mode on the input terminal. It is a no-op if In
3647// is not a TTY, or if the "NORAW" environment variable is set to a non-empty
3748// value.
3849func (i * In ) SetRawTerminal () error {
39- return i .setRawTerminal (term .SetRawTerminal )
50+ return i .cs .setRawTerminal (term .SetRawTerminal )
51+ }
52+
53+ // RestoreTerminal restores the terminal state if SetRawTerminal succeeded earlier.
54+ func (i * In ) RestoreTerminal () {
55+ i .cs .restoreTerminal ()
4056}
4157
4258// CheckTty checks if we are trying to attach to a container TTY
@@ -45,7 +61,7 @@ func (i *In) CheckTty(attachStdin, ttyMode bool) error {
4561 // In order to attach to a container tty, input stream for the client must
4662 // be a tty itself: redirecting or piping the client standard input is
4763 // incompatible with `docker run -t`, `docker exec -t` or `docker attach`.
48- if ttyMode && attachStdin && ! i .isTerminal {
64+ if ttyMode && attachStdin && ! i .cs . isTerminal () {
4965 const eText = "the input device is not a TTY"
5066 if runtime .GOOS == "windows" {
5167 return errors .New (eText + ". If you are using mintty, try prefixing the command with 'winpty'" )
@@ -54,3 +70,10 @@ func (i *In) CheckTty(attachStdin, ttyMode bool) error {
5470 }
5571 return nil
5672}
73+
74+ // SetIsTerminal overrides whether a terminal is connected. It is used to
75+ // override this property in unit-tests, and should not be depended on for
76+ // other purposes.
77+ func (i * In ) SetIsTerminal (isTerminal bool ) {
78+ i .cs .setIsTerminal (isTerminal )
79+ }
0 commit comments