Bump console for windows tty handling
ref: https://github.com/containerd/console/pull/25 Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
This commit is contained in:
		
							
								
								
									
										16
									
								
								vendor/github.com/containerd/console/console_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										16
									
								
								vendor/github.com/containerd/console/console_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -72,7 +72,7 @@ func NewEpoller() (*Epoller, error) {
 | 
			
		||||
	}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Add creates a epoll console based on the provided console. The console will
 | 
			
		||||
// Add creates an epoll console based on the provided console. The console will
 | 
			
		||||
// be registered with EPOLLET (i.e. using edge-triggered notification) and its
 | 
			
		||||
// file descriptor will be set to non-blocking mode. After this, user should use
 | 
			
		||||
// the return console to perform I/O.
 | 
			
		||||
@@ -134,7 +134,7 @@ func (e *Epoller) Wait() error {
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Close unregister the console's file descriptor from epoll interface
 | 
			
		||||
// CloseConsole unregisters the console's file descriptor from epoll interface
 | 
			
		||||
func (e *Epoller) CloseConsole(fd int) error {
 | 
			
		||||
	e.mu.Lock()
 | 
			
		||||
	defer e.mu.Unlock()
 | 
			
		||||
@@ -149,12 +149,12 @@ func (e *Epoller) getConsole(sysfd int) *EpollConsole {
 | 
			
		||||
	return f
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Close the epoll fd
 | 
			
		||||
// Close closes the epoll fd
 | 
			
		||||
func (e *Epoller) Close() error {
 | 
			
		||||
	return unix.Close(e.efd)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// EpollConsole acts like a console but register its file descriptor with a
 | 
			
		||||
// EpollConsole acts like a console but registers its file descriptor with an
 | 
			
		||||
// epoll fd and uses epoll API to perform I/O.
 | 
			
		||||
type EpollConsole struct {
 | 
			
		||||
	Console
 | 
			
		||||
@@ -167,7 +167,7 @@ type EpollConsole struct {
 | 
			
		||||
// Read reads up to len(p) bytes into p. It returns the number of bytes read
 | 
			
		||||
// (0 <= n <= len(p)) and any error encountered.
 | 
			
		||||
//
 | 
			
		||||
// If the console's read returns EAGAIN or EIO, we assumes that its a
 | 
			
		||||
// If the console's read returns EAGAIN or EIO, we assume that it's a
 | 
			
		||||
// temporary error because the other side went away and wait for the signal
 | 
			
		||||
// generated by epoll event to continue.
 | 
			
		||||
func (ec *EpollConsole) Read(p []byte) (n int, err error) {
 | 
			
		||||
@@ -207,7 +207,7 @@ func (ec *EpollConsole) Read(p []byte) (n int, err error) {
 | 
			
		||||
// written from p (0 <= n <= len(p)) and any error encountered that caused
 | 
			
		||||
// the write to stop early.
 | 
			
		||||
//
 | 
			
		||||
// If writes to the console returns EAGAIN or EIO, we assumes that its a
 | 
			
		||||
// If writes to the console returns EAGAIN or EIO, we assume that it's a
 | 
			
		||||
// temporary error because the other side went away and wait for the signal
 | 
			
		||||
// generated by epoll event to continue.
 | 
			
		||||
func (ec *EpollConsole) Write(p []byte) (n int, err error) {
 | 
			
		||||
@@ -224,7 +224,7 @@ func (ec *EpollConsole) Write(p []byte) (n int, err error) {
 | 
			
		||||
			} else {
 | 
			
		||||
				hangup = (err == unix.EAGAIN || err == unix.EIO)
 | 
			
		||||
			}
 | 
			
		||||
			// if the other end disappear, assume this is temporary and wait for the
 | 
			
		||||
			// if the other end disappears, assume this is temporary and wait for the
 | 
			
		||||
			// signal to continue again.
 | 
			
		||||
			if hangup {
 | 
			
		||||
				ec.writec.Wait()
 | 
			
		||||
@@ -242,7 +242,7 @@ func (ec *EpollConsole) Write(p []byte) (n int, err error) {
 | 
			
		||||
	return n, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Close closed the file descriptor and signal call waiters for this fd.
 | 
			
		||||
// Shutdown closes the file descriptor and signals call waiters for this fd.
 | 
			
		||||
// It accepts a callback which will be called with the console's fd. The
 | 
			
		||||
// callback typically will be used to do further cleanup such as unregister the
 | 
			
		||||
// console's fd from the epoll interface.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										108
									
								
								vendor/github.com/containerd/console/console_windows.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										108
									
								
								vendor/github.com/containerd/console/console_windows.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -17,7 +17,6 @@
 | 
			
		||||
package console
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"os"
 | 
			
		||||
 | 
			
		||||
	"github.com/pkg/errors"
 | 
			
		||||
@@ -29,90 +28,55 @@ var (
 | 
			
		||||
	ErrNotImplemented = errors.New("not implemented")
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func (m *master) initStdios() {
 | 
			
		||||
	m.in = windows.Handle(os.Stdin.Fd())
 | 
			
		||||
	if err := windows.GetConsoleMode(m.in, &m.inMode); err == nil {
 | 
			
		||||
		// Validate that windows.ENABLE_VIRTUAL_TERMINAL_INPUT is supported, but do not set it.
 | 
			
		||||
		if err = windows.SetConsoleMode(m.in, m.inMode|windows.ENABLE_VIRTUAL_TERMINAL_INPUT); err == nil {
 | 
			
		||||
			vtInputSupported = true
 | 
			
		||||
		}
 | 
			
		||||
		// Unconditionally set the console mode back even on failure because SetConsoleMode
 | 
			
		||||
		// remembers invalid bits on input handles.
 | 
			
		||||
		windows.SetConsoleMode(m.in, m.inMode)
 | 
			
		||||
	} else {
 | 
			
		||||
		fmt.Printf("failed to get console mode for stdin: %v\n", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	m.out = windows.Handle(os.Stdout.Fd())
 | 
			
		||||
	if err := windows.GetConsoleMode(m.out, &m.outMode); err == nil {
 | 
			
		||||
		if err := windows.SetConsoleMode(m.out, m.outMode|windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING); err == nil {
 | 
			
		||||
			m.outMode |= windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING
 | 
			
		||||
func (m *master) init() {
 | 
			
		||||
	m.h = windows.Handle(m.f.Fd())
 | 
			
		||||
	if err := windows.GetConsoleMode(m.h, &m.mode); err == nil {
 | 
			
		||||
		if m.f == os.Stdin {
 | 
			
		||||
			// Validate that windows.ENABLE_VIRTUAL_TERMINAL_INPUT is supported, but do not set it.
 | 
			
		||||
			if err = windows.SetConsoleMode(m.h, m.mode|windows.ENABLE_VIRTUAL_TERMINAL_INPUT); err == nil {
 | 
			
		||||
				vtInputSupported = true
 | 
			
		||||
			}
 | 
			
		||||
			// Unconditionally set the console mode back even on failure because SetConsoleMode
 | 
			
		||||
			// remembers invalid bits on input handles.
 | 
			
		||||
			windows.SetConsoleMode(m.h, m.mode)
 | 
			
		||||
		} else if err := windows.SetConsoleMode(m.h, m.mode|windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING); err == nil {
 | 
			
		||||
			m.mode |= windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING
 | 
			
		||||
		} else {
 | 
			
		||||
			windows.SetConsoleMode(m.out, m.outMode)
 | 
			
		||||
			windows.SetConsoleMode(m.h, m.mode)
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		fmt.Printf("failed to get console mode for stdout: %v\n", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	m.err = windows.Handle(os.Stderr.Fd())
 | 
			
		||||
	if err := windows.GetConsoleMode(m.err, &m.errMode); err == nil {
 | 
			
		||||
		if err := windows.SetConsoleMode(m.err, m.errMode|windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING); err == nil {
 | 
			
		||||
			m.errMode |= windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING
 | 
			
		||||
		} else {
 | 
			
		||||
			windows.SetConsoleMode(m.err, m.errMode)
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		fmt.Printf("failed to get console mode for stderr: %v\n", err)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type master struct {
 | 
			
		||||
	in     windows.Handle
 | 
			
		||||
	inMode uint32
 | 
			
		||||
 | 
			
		||||
	out     windows.Handle
 | 
			
		||||
	outMode uint32
 | 
			
		||||
 | 
			
		||||
	err     windows.Handle
 | 
			
		||||
	errMode uint32
 | 
			
		||||
	h    windows.Handle
 | 
			
		||||
	mode uint32
 | 
			
		||||
	f    *os.File
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *master) SetRaw() error {
 | 
			
		||||
	if err := makeInputRaw(m.in, m.inMode); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	if m.f == os.Stdin {
 | 
			
		||||
		if err := makeInputRaw(m.h, m.mode); err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		// Set StdOut and StdErr to raw mode, we ignore failures since
 | 
			
		||||
		// windows.DISABLE_NEWLINE_AUTO_RETURN might not be supported on this version of
 | 
			
		||||
		// Windows.
 | 
			
		||||
		windows.SetConsoleMode(m.h, m.mode|windows.DISABLE_NEWLINE_AUTO_RETURN)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Set StdOut and StdErr to raw mode, we ignore failures since
 | 
			
		||||
	// windows.DISABLE_NEWLINE_AUTO_RETURN might not be supported on this version of
 | 
			
		||||
	// Windows.
 | 
			
		||||
 | 
			
		||||
	windows.SetConsoleMode(m.out, m.outMode|windows.DISABLE_NEWLINE_AUTO_RETURN)
 | 
			
		||||
 | 
			
		||||
	windows.SetConsoleMode(m.err, m.errMode|windows.DISABLE_NEWLINE_AUTO_RETURN)
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *master) Reset() error {
 | 
			
		||||
	for _, s := range []struct {
 | 
			
		||||
		fd   windows.Handle
 | 
			
		||||
		mode uint32
 | 
			
		||||
	}{
 | 
			
		||||
		{m.in, m.inMode},
 | 
			
		||||
		{m.out, m.outMode},
 | 
			
		||||
		{m.err, m.errMode},
 | 
			
		||||
	} {
 | 
			
		||||
		if err := windows.SetConsoleMode(s.fd, s.mode); err != nil {
 | 
			
		||||
			return errors.Wrap(err, "unable to restore console mode")
 | 
			
		||||
		}
 | 
			
		||||
	if err := windows.SetConsoleMode(m.h, m.mode); err != nil {
 | 
			
		||||
		return errors.Wrap(err, "unable to restore console mode")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *master) Size() (WinSize, error) {
 | 
			
		||||
	var info windows.ConsoleScreenBufferInfo
 | 
			
		||||
	err := windows.GetConsoleScreenBufferInfo(m.out, &info)
 | 
			
		||||
	err := windows.GetConsoleScreenBufferInfo(m.h, &info)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return WinSize{}, errors.Wrap(err, "unable to get console info")
 | 
			
		||||
	}
 | 
			
		||||
@@ -134,11 +98,11 @@ func (m *master) ResizeFrom(c Console) error {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *master) DisableEcho() error {
 | 
			
		||||
	mode := m.inMode &^ windows.ENABLE_ECHO_INPUT
 | 
			
		||||
	mode := m.mode &^ windows.ENABLE_ECHO_INPUT
 | 
			
		||||
	mode |= windows.ENABLE_PROCESSED_INPUT
 | 
			
		||||
	mode |= windows.ENABLE_LINE_INPUT
 | 
			
		||||
 | 
			
		||||
	if err := windows.SetConsoleMode(m.in, mode); err != nil {
 | 
			
		||||
	if err := windows.SetConsoleMode(m.h, mode); err != nil {
 | 
			
		||||
		return errors.Wrap(err, "unable to set console to disable echo")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -150,15 +114,15 @@ func (m *master) Close() error {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *master) Read(b []byte) (int, error) {
 | 
			
		||||
	panic("not implemented on windows")
 | 
			
		||||
	return m.f.Read(b)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *master) Write(b []byte) (int, error) {
 | 
			
		||||
	panic("not implemented on windows")
 | 
			
		||||
	return m.f.Write(b)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *master) Fd() uintptr {
 | 
			
		||||
	return uintptr(m.in)
 | 
			
		||||
	return uintptr(m.h)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// on windows, console can only be made from os.Std{in,out,err}, hence there
 | 
			
		||||
@@ -210,7 +174,7 @@ func newMaster(f *os.File) (Console, error) {
 | 
			
		||||
	if f != os.Stdin && f != os.Stdout && f != os.Stderr {
 | 
			
		||||
		return nil, errors.New("creating a console from a file is not supported on windows")
 | 
			
		||||
	}
 | 
			
		||||
	m := &master{}
 | 
			
		||||
	m.initStdios()
 | 
			
		||||
	m := &master{f: f}
 | 
			
		||||
	m.init()
 | 
			
		||||
	return m, nil
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user