Ver Fonte

Use syscall consts, check for errors,

Also rename func for non-windows specific names.

Signed-off-by: Sachin Joshi <sachin_jayant_joshi@hotmail.com>
Sachin Joshi há 10 anos atrás
pai
commit
45262c4cb0

+ 2 - 2
api/client/cli.go

@@ -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 {

+ 1 - 1
pkg/term/term.go

@@ -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 {

+ 2 - 2
pkg/term/term_windows.go

@@ -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)
 }
 

+ 23 - 15
pkg/term/winconsole/console_windows.go

@@ -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
 }
 

+ 10 - 8
pkg/term/winconsole/term_emulator.go

@@ -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

+ 4 - 4
pkg/term/winconsole/term_emulator_test.go

@@ -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
 }