mirror of
				https://github.com/moby/moby.git
				synced 2022-11-09 12:21:53 -05:00 
			
		
		
		
	Use syscall consts, check for errors,
Also rename func for non-windows specific names. Signed-off-by: Sachin Joshi <sachin_jayant_joshi@hotmail.com>
This commit is contained in:
		
							parent
							
								
									898d2763c5
								
							
						
					
					
						commit
						45262c4cb0
					
				
					 6 changed files with 42 additions and 32 deletions
				
			
		| 
						 | 
				
			
			@ -138,11 +138,11 @@ func NewDockerCli(in io.ReadCloser, out, err io.Writer, keyFile string, proto, a
 | 
			
		|||
		scheme = "https"
 | 
			
		||||
	}
 | 
			
		||||
	if in != nil {
 | 
			
		||||
		inFd, isTerminalIn = term.GetHandleInfo(in)
 | 
			
		||||
		inFd, isTerminalIn = term.GetFdInfo(in)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if out != nil {
 | 
			
		||||
		outFd, isTerminalOut = term.GetHandleInfo(out)
 | 
			
		||||
		outFd, isTerminalOut = term.GetFdInfo(out)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err == nil {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,7 +30,7 @@ func StdStreams() (stdOut io.Writer, stdErr io.Writer, stdIn io.ReadCloser) {
 | 
			
		|||
	return os.Stdout, os.Stderr, os.Stdin
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func GetHandleInfo(in interface{}) (uintptr, bool) {
 | 
			
		||||
func GetFdInfo(in interface{}) (uintptr, bool) {
 | 
			
		||||
	var inFd uintptr
 | 
			
		||||
	var isTerminalIn bool
 | 
			
		||||
	if file, ok := in.(*os.File); ok {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -107,8 +107,8 @@ func MakeRaw(fd uintptr) (*State, error) {
 | 
			
		|||
	return state, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetHandleInfo returns file descriptor and bool indicating whether the file is a terminal
 | 
			
		||||
func GetHandleInfo(in interface{}) (uintptr, bool) {
 | 
			
		||||
// GetFdInfo returns file descriptor and bool indicating whether the file is a terminal
 | 
			
		||||
func GetFdInfo(in interface{}) (uintptr, bool) {
 | 
			
		||||
	return winconsole.GetHandleInfo(in)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -83,11 +83,6 @@ const (
 | 
			
		|||
 | 
			
		||||
	ANSI_MAX_CMD_LENGTH = 256
 | 
			
		||||
 | 
			
		||||
	// https://msdn.microsoft.com/en-us/library/windows/desktop/ms683231(v=vs.85).aspx
 | 
			
		||||
	STD_INPUT_HANDLE  = -10
 | 
			
		||||
	STD_OUTPUT_HANDLE = -11
 | 
			
		||||
	STD_ERROR_HANDLE  = -12
 | 
			
		||||
 | 
			
		||||
	MAX_INPUT_BUFFER = 1024
 | 
			
		||||
	DEFAULT_WIDTH    = 80
 | 
			
		||||
	DEFAULT_HEIGHT   = 24
 | 
			
		||||
| 
						 | 
				
			
			@ -212,7 +207,10 @@ func StdStreams() (stdOut io.Writer, stdErr io.Writer, stdIn io.ReadCloser) {
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	// Save current screen buffer info
 | 
			
		||||
	handle, _ := syscall.GetStdHandle(STD_OUTPUT_HANDLE)
 | 
			
		||||
	handle, err := syscall.GetStdHandle(syscall.STD_OUTPUT_HANDLE)
 | 
			
		||||
	if nil != err {
 | 
			
		||||
		panic("This should never happen as it is predefined handle.")
 | 
			
		||||
	}
 | 
			
		||||
	screenBufferInfo, err := GetConsoleScreenBufferInfo(uintptr(handle))
 | 
			
		||||
	if err == nil {
 | 
			
		||||
		handler.screenBufferInfo = screenBufferInfo
 | 
			
		||||
| 
						 | 
				
			
			@ -225,26 +223,36 @@ func StdStreams() (stdOut io.Writer, stdErr io.Writer, stdIn io.ReadCloser) {
 | 
			
		|||
			wrappedWriter: os.Stdout,
 | 
			
		||||
			emulator:      handler,
 | 
			
		||||
			command:       make([]byte, 0, ANSI_MAX_CMD_LENGTH),
 | 
			
		||||
			fd:            uintptr(handle),
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		stdOut = os.Stdout
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
	if IsTerminal(os.Stderr.Fd()) {
 | 
			
		||||
		handle, err := syscall.GetStdHandle(syscall.STD_ERROR_HANDLE)
 | 
			
		||||
		if nil != err {
 | 
			
		||||
			panic("This should never happen as it is predefined handle.")
 | 
			
		||||
		}
 | 
			
		||||
		stdErr = &terminalWriter{
 | 
			
		||||
			wrappedWriter: os.Stderr,
 | 
			
		||||
			emulator:      handler,
 | 
			
		||||
			command:       make([]byte, 0, ANSI_MAX_CMD_LENGTH),
 | 
			
		||||
			fd:            uintptr(handle),
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		stdErr = os.Stderr
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
	if IsTerminal(os.Stdin.Fd()) {
 | 
			
		||||
		handle, err := syscall.GetStdHandle(syscall.STD_INPUT_HANDLE)
 | 
			
		||||
		if nil != err {
 | 
			
		||||
			panic("This should never happen as it is predefined handle.")
 | 
			
		||||
		}
 | 
			
		||||
		stdIn = &terminalReader{
 | 
			
		||||
			wrappedReader: os.Stdin,
 | 
			
		||||
			emulator:      handler,
 | 
			
		||||
			command:       make([]byte, 0, ANSI_MAX_CMD_LENGTH),
 | 
			
		||||
			fd:            uintptr(handle),
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		stdIn = os.Stdin
 | 
			
		||||
| 
						 | 
				
			
			@ -626,7 +634,7 @@ func getWindowsTextAttributeForAnsiValue(originalFlag WORD, defaultValue WORD, a
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
// HandleOutputCommand interpretes the Ansi commands and then makes appropriate Win32 calls
 | 
			
		||||
func (term *WindowsTerminal) HandleOutputCommand(command []byte) (n int, err error) {
 | 
			
		||||
func (term *WindowsTerminal) HandleOutputCommand(fd uintptr, command []byte) (n int, err error) {
 | 
			
		||||
	// console settings changes need to happen in atomic way
 | 
			
		||||
	term.outMutex.Lock()
 | 
			
		||||
	defer term.outMutex.Unlock()
 | 
			
		||||
| 
						 | 
				
			
			@ -636,7 +644,7 @@ func (term *WindowsTerminal) HandleOutputCommand(command []byte) (n int, err err
 | 
			
		|||
	parsedCommand := parseAnsiCommand(command)
 | 
			
		||||
 | 
			
		||||
	// use appropriate handle
 | 
			
		||||
	handle, _ := syscall.GetStdHandle(STD_OUTPUT_HANDLE)
 | 
			
		||||
	handle := syscall.Handle(fd)
 | 
			
		||||
 | 
			
		||||
	switch parsedCommand.Command {
 | 
			
		||||
	case "m":
 | 
			
		||||
| 
						 | 
				
			
			@ -891,7 +899,7 @@ func (term *WindowsTerminal) HandleOutputCommand(command []byte) (n int, err err
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
// WriteChars writes the bytes to given writer.
 | 
			
		||||
func (term *WindowsTerminal) WriteChars(w io.Writer, p []byte) (n int, err error) {
 | 
			
		||||
func (term *WindowsTerminal) WriteChars(fd uintptr, w io.Writer, p []byte) (n int, err error) {
 | 
			
		||||
	return w.Write(p)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1027,8 +1035,8 @@ func mapKeystokeToTerminalString(keyEvent *KEY_EVENT_RECORD, escapeSequence []by
 | 
			
		|||
 | 
			
		||||
// getAvailableInputEvents polls the console for availble events
 | 
			
		||||
// The function does not return until at least one input record has been read.
 | 
			
		||||
func getAvailableInputEvents() (inputEvents []INPUT_RECORD, err error) {
 | 
			
		||||
	handle, _ := syscall.GetStdHandle(STD_INPUT_HANDLE)
 | 
			
		||||
func getAvailableInputEvents(fd uintptr) (inputEvents []INPUT_RECORD, err error) {
 | 
			
		||||
	handle := syscall.Handle(fd)
 | 
			
		||||
	if nil != err {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -1064,7 +1072,7 @@ func getTranslatedKeyCodes(inputEvents []INPUT_RECORD, escapeSequence []byte) st
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
// ReadChars reads the characters from the given reader
 | 
			
		||||
func (term *WindowsTerminal) ReadChars(w io.Reader, p []byte) (n int, err error) {
 | 
			
		||||
func (term *WindowsTerminal) ReadChars(fd uintptr, w io.Reader, p []byte) (n int, err error) {
 | 
			
		||||
	n = 0
 | 
			
		||||
	for n < len(p) {
 | 
			
		||||
		select {
 | 
			
		||||
| 
						 | 
				
			
			@ -1076,7 +1084,7 @@ func (term *WindowsTerminal) ReadChars(w io.Reader, p []byte) (n int, err error)
 | 
			
		|||
			if n > 0 {
 | 
			
		||||
				return n, nil
 | 
			
		||||
			}
 | 
			
		||||
			inputEvents, _ := getAvailableInputEvents()
 | 
			
		||||
			inputEvents, _ := getAvailableInputEvents(fd)
 | 
			
		||||
			if inputEvents != nil {
 | 
			
		||||
				if len(inputEvents) == 0 && nil != err {
 | 
			
		||||
					return n, err
 | 
			
		||||
| 
						 | 
				
			
			@ -1094,7 +1102,7 @@ func (term *WindowsTerminal) ReadChars(w io.Reader, p []byte) (n int, err error)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
// HandleInputSequence interprets the input sequence command
 | 
			
		||||
func (term *WindowsTerminal) HandleInputSequence(command []byte) (n int, err error) {
 | 
			
		||||
func (term *WindowsTerminal) HandleInputSequence(fd uintptr, command []byte) (n int, err error) {
 | 
			
		||||
	return 0, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -27,10 +27,10 @@ const (
 | 
			
		|||
 | 
			
		||||
// Interface that implements terminal handling
 | 
			
		||||
type terminalEmulator interface {
 | 
			
		||||
	HandleOutputCommand(command []byte) (n int, err error)
 | 
			
		||||
	HandleInputSequence(command []byte) (n int, err error)
 | 
			
		||||
	WriteChars(w io.Writer, p []byte) (n int, err error)
 | 
			
		||||
	ReadChars(w io.Reader, p []byte) (n int, err error)
 | 
			
		||||
	HandleOutputCommand(fd uintptr, command []byte) (n int, err error)
 | 
			
		||||
	HandleInputSequence(fd uintptr, command []byte) (n int, err error)
 | 
			
		||||
	WriteChars(fd uintptr, w io.Writer, p []byte) (n int, err error)
 | 
			
		||||
	ReadChars(fd uintptr, w io.Reader, p []byte) (n int, err error)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type terminalWriter struct {
 | 
			
		||||
| 
						 | 
				
			
			@ -38,6 +38,7 @@ type terminalWriter struct {
 | 
			
		|||
	emulator      terminalEmulator
 | 
			
		||||
	command       []byte
 | 
			
		||||
	inSequence    bool
 | 
			
		||||
	fd            uintptr
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type terminalReader struct {
 | 
			
		||||
| 
						 | 
				
			
			@ -45,6 +46,7 @@ type terminalReader struct {
 | 
			
		|||
	emulator      terminalEmulator
 | 
			
		||||
	command       []byte
 | 
			
		||||
	inSequence    bool
 | 
			
		||||
	fd            uintptr
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// http://manpages.ubuntu.com/manpages/intrepid/man4/console_codes.4.html
 | 
			
		||||
| 
						 | 
				
			
			@ -91,7 +93,7 @@ func (tw *terminalWriter) Write(p []byte) (n int, err error) {
 | 
			
		|||
				if !isXtermOscSequence(tw.command, p[current]) {
 | 
			
		||||
					// found the last command character.
 | 
			
		||||
					// Now we have a complete command.
 | 
			
		||||
					nchar, err := tw.emulator.HandleOutputCommand(tw.command)
 | 
			
		||||
					nchar, err := tw.emulator.HandleOutputCommand(tw.fd, tw.command)
 | 
			
		||||
					totalWritten += nchar
 | 
			
		||||
					if err != nil {
 | 
			
		||||
						return totalWritten, err
 | 
			
		||||
| 
						 | 
				
			
			@ -110,7 +112,7 @@ func (tw *terminalWriter) Write(p []byte) (n int, err error) {
 | 
			
		|||
				tw.inSequence = true
 | 
			
		||||
				// indicates end of "normal sequence", write whatever you have so far
 | 
			
		||||
				if len(p[start:current]) > 0 {
 | 
			
		||||
					nw, err := tw.emulator.WriteChars(tw.wrappedWriter, p[start:current])
 | 
			
		||||
					nw, err := tw.emulator.WriteChars(tw.fd, tw.wrappedWriter, p[start:current])
 | 
			
		||||
					totalWritten += nw
 | 
			
		||||
					if err != nil {
 | 
			
		||||
						return totalWritten, err
 | 
			
		||||
| 
						 | 
				
			
			@ -126,7 +128,7 @@ func (tw *terminalWriter) Write(p []byte) (n int, err error) {
 | 
			
		|||
	if !tw.inSequence {
 | 
			
		||||
		// assumption is that we can't be inside sequence and therefore command should be empty
 | 
			
		||||
		if len(p[start:]) > 0 {
 | 
			
		||||
			nw, err := tw.emulator.WriteChars(tw.wrappedWriter, p[start:])
 | 
			
		||||
			nw, err := tw.emulator.WriteChars(tw.fd, tw.wrappedWriter, p[start:])
 | 
			
		||||
			totalWritten += nw
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return totalWritten, err
 | 
			
		||||
| 
						 | 
				
			
			@ -148,7 +150,7 @@ func (tr *terminalReader) Read(p []byte) (n int, err error) {
 | 
			
		|||
	if nil == tr.emulator {
 | 
			
		||||
		return tr.readFromWrappedReader(p)
 | 
			
		||||
	}
 | 
			
		||||
	return tr.emulator.ReadChars(tr.wrappedReader, p)
 | 
			
		||||
	return tr.emulator.ReadChars(tr.fd, tr.wrappedReader, p)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Close the underlying stream
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -71,21 +71,21 @@ func (mt *mockTerminal) record(operation int, data []byte) {
 | 
			
		|||
	mt.OutputCommandSequence = append(mt.OutputCommandSequence, op)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (mt *mockTerminal) HandleOutputCommand(command []byte) (n int, err error) {
 | 
			
		||||
func (mt *mockTerminal) HandleOutputCommand(fd uintptr, command []byte) (n int, err error) {
 | 
			
		||||
	mt.record(COMMAND_OPERATION, command)
 | 
			
		||||
	return len(command), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (mt *mockTerminal) HandleInputSequence(command []byte) (n int, err error) {
 | 
			
		||||
func (mt *mockTerminal) HandleInputSequence(fd uintptr, command []byte) (n int, err error) {
 | 
			
		||||
	return 0, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (mt *mockTerminal) WriteChars(w io.Writer, p []byte) (n int, err error) {
 | 
			
		||||
func (mt *mockTerminal) WriteChars(fd uintptr, w io.Writer, p []byte) (n int, err error) {
 | 
			
		||||
	mt.record(WRITE_OPERATION, p)
 | 
			
		||||
	return len(p), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (mt *mockTerminal) ReadChars(w io.Reader, p []byte) (n int, err error) {
 | 
			
		||||
func (mt *mockTerminal) ReadChars(fd uintptr, w io.Reader, p []byte) (n int, err error) {
 | 
			
		||||
	return len(p), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue