Browse code

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 authored on 2015/03/07 10:04:35
Showing 6 changed files
... ...
@@ -138,11 +138,11 @@ func NewDockerCli(in io.ReadCloser, out, err io.Writer, keyFile string, proto, a
138 138
 		scheme = "https"
139 139
 	}
140 140
 	if in != nil {
141
-		inFd, isTerminalIn = term.GetHandleInfo(in)
141
+		inFd, isTerminalIn = term.GetFdInfo(in)
142 142
 	}
143 143
 
144 144
 	if out != nil {
145
-		outFd, isTerminalOut = term.GetHandleInfo(out)
145
+		outFd, isTerminalOut = term.GetFdInfo(out)
146 146
 	}
147 147
 
148 148
 	if err == nil {
... ...
@@ -30,7 +30,7 @@ func StdStreams() (stdOut io.Writer, stdErr io.Writer, stdIn io.ReadCloser) {
30 30
 	return os.Stdout, os.Stderr, os.Stdin
31 31
 }
32 32
 
33
-func GetHandleInfo(in interface{}) (uintptr, bool) {
33
+func GetFdInfo(in interface{}) (uintptr, bool) {
34 34
 	var inFd uintptr
35 35
 	var isTerminalIn bool
36 36
 	if file, ok := in.(*os.File); ok {
... ...
@@ -107,8 +107,8 @@ func MakeRaw(fd uintptr) (*State, error) {
107 107
 	return state, nil
108 108
 }
109 109
 
110
-// GetHandleInfo returns file descriptor and bool indicating whether the file is a terminal
111
-func GetHandleInfo(in interface{}) (uintptr, bool) {
110
+// GetFdInfo returns file descriptor and bool indicating whether the file is a terminal
111
+func GetFdInfo(in interface{}) (uintptr, bool) {
112 112
 	return winconsole.GetHandleInfo(in)
113 113
 }
114 114
 
... ...
@@ -83,11 +83,6 @@ const (
83 83
 
84 84
 	ANSI_MAX_CMD_LENGTH = 256
85 85
 
86
-	// https://msdn.microsoft.com/en-us/library/windows/desktop/ms683231(v=vs.85).aspx
87
-	STD_INPUT_HANDLE  = -10
88
-	STD_OUTPUT_HANDLE = -11
89
-	STD_ERROR_HANDLE  = -12
90
-
91 86
 	MAX_INPUT_BUFFER = 1024
92 87
 	DEFAULT_WIDTH    = 80
93 88
 	DEFAULT_HEIGHT   = 24
... ...
@@ -212,7 +207,10 @@ func StdStreams() (stdOut io.Writer, stdErr io.Writer, stdIn io.ReadCloser) {
212 212
 	}
213 213
 
214 214
 	// Save current screen buffer info
215
-	handle, _ := syscall.GetStdHandle(STD_OUTPUT_HANDLE)
215
+	handle, err := syscall.GetStdHandle(syscall.STD_OUTPUT_HANDLE)
216
+	if nil != err {
217
+		panic("This should never happen as it is predefined handle.")
218
+	}
216 219
 	screenBufferInfo, err := GetConsoleScreenBufferInfo(uintptr(handle))
217 220
 	if err == nil {
218 221
 		handler.screenBufferInfo = screenBufferInfo
... ...
@@ -225,26 +223,36 @@ func StdStreams() (stdOut io.Writer, stdErr io.Writer, stdIn io.ReadCloser) {
225 225
 			wrappedWriter: os.Stdout,
226 226
 			emulator:      handler,
227 227
 			command:       make([]byte, 0, ANSI_MAX_CMD_LENGTH),
228
+			fd:            uintptr(handle),
228 229
 		}
229 230
 	} else {
230 231
 		stdOut = os.Stdout
231 232
 
232 233
 	}
233 234
 	if IsTerminal(os.Stderr.Fd()) {
235
+		handle, err := syscall.GetStdHandle(syscall.STD_ERROR_HANDLE)
236
+		if nil != err {
237
+			panic("This should never happen as it is predefined handle.")
238
+		}
234 239
 		stdErr = &terminalWriter{
235 240
 			wrappedWriter: os.Stderr,
236 241
 			emulator:      handler,
237 242
 			command:       make([]byte, 0, ANSI_MAX_CMD_LENGTH),
243
+			fd:            uintptr(handle),
238 244
 		}
239 245
 	} else {
240 246
 		stdErr = os.Stderr
241
-
242 247
 	}
243 248
 	if IsTerminal(os.Stdin.Fd()) {
249
+		handle, err := syscall.GetStdHandle(syscall.STD_INPUT_HANDLE)
250
+		if nil != err {
251
+			panic("This should never happen as it is predefined handle.")
252
+		}
244 253
 		stdIn = &terminalReader{
245 254
 			wrappedReader: os.Stdin,
246 255
 			emulator:      handler,
247 256
 			command:       make([]byte, 0, ANSI_MAX_CMD_LENGTH),
257
+			fd:            uintptr(handle),
248 258
 		}
249 259
 	} else {
250 260
 		stdIn = os.Stdin
... ...
@@ -626,7 +634,7 @@ func getWindowsTextAttributeForAnsiValue(originalFlag WORD, defaultValue WORD, a
626 626
 }
627 627
 
628 628
 // HandleOutputCommand interpretes the Ansi commands and then makes appropriate Win32 calls
629
-func (term *WindowsTerminal) HandleOutputCommand(command []byte) (n int, err error) {
629
+func (term *WindowsTerminal) HandleOutputCommand(fd uintptr, command []byte) (n int, err error) {
630 630
 	// console settings changes need to happen in atomic way
631 631
 	term.outMutex.Lock()
632 632
 	defer term.outMutex.Unlock()
... ...
@@ -636,7 +644,7 @@ func (term *WindowsTerminal) HandleOutputCommand(command []byte) (n int, err err
636 636
 	parsedCommand := parseAnsiCommand(command)
637 637
 
638 638
 	// use appropriate handle
639
-	handle, _ := syscall.GetStdHandle(STD_OUTPUT_HANDLE)
639
+	handle := syscall.Handle(fd)
640 640
 
641 641
 	switch parsedCommand.Command {
642 642
 	case "m":
... ...
@@ -891,7 +899,7 @@ func (term *WindowsTerminal) HandleOutputCommand(command []byte) (n int, err err
891 891
 }
892 892
 
893 893
 // WriteChars writes the bytes to given writer.
894
-func (term *WindowsTerminal) WriteChars(w io.Writer, p []byte) (n int, err error) {
894
+func (term *WindowsTerminal) WriteChars(fd uintptr, w io.Writer, p []byte) (n int, err error) {
895 895
 	return w.Write(p)
896 896
 }
897 897
 
... ...
@@ -1027,8 +1035,8 @@ func mapKeystokeToTerminalString(keyEvent *KEY_EVENT_RECORD, escapeSequence []by
1027 1027
 
1028 1028
 // getAvailableInputEvents polls the console for availble events
1029 1029
 // The function does not return until at least one input record has been read.
1030
-func getAvailableInputEvents() (inputEvents []INPUT_RECORD, err error) {
1031
-	handle, _ := syscall.GetStdHandle(STD_INPUT_HANDLE)
1030
+func getAvailableInputEvents(fd uintptr) (inputEvents []INPUT_RECORD, err error) {
1031
+	handle := syscall.Handle(fd)
1032 1032
 	if nil != err {
1033 1033
 		return nil, err
1034 1034
 	}
... ...
@@ -1064,7 +1072,7 @@ func getTranslatedKeyCodes(inputEvents []INPUT_RECORD, escapeSequence []byte) st
1064 1064
 }
1065 1065
 
1066 1066
 // ReadChars reads the characters from the given reader
1067
-func (term *WindowsTerminal) ReadChars(w io.Reader, p []byte) (n int, err error) {
1067
+func (term *WindowsTerminal) ReadChars(fd uintptr, w io.Reader, p []byte) (n int, err error) {
1068 1068
 	n = 0
1069 1069
 	for n < len(p) {
1070 1070
 		select {
... ...
@@ -1076,7 +1084,7 @@ func (term *WindowsTerminal) ReadChars(w io.Reader, p []byte) (n int, err error)
1076 1076
 			if n > 0 {
1077 1077
 				return n, nil
1078 1078
 			}
1079
-			inputEvents, _ := getAvailableInputEvents()
1079
+			inputEvents, _ := getAvailableInputEvents(fd)
1080 1080
 			if inputEvents != nil {
1081 1081
 				if len(inputEvents) == 0 && nil != err {
1082 1082
 					return n, err
... ...
@@ -1094,7 +1102,7 @@ func (term *WindowsTerminal) ReadChars(w io.Reader, p []byte) (n int, err error)
1094 1094
 }
1095 1095
 
1096 1096
 // HandleInputSequence interprets the input sequence command
1097
-func (term *WindowsTerminal) HandleInputSequence(command []byte) (n int, err error) {
1097
+func (term *WindowsTerminal) HandleInputSequence(fd uintptr, command []byte) (n int, err error) {
1098 1098
 	return 0, nil
1099 1099
 }
1100 1100
 
... ...
@@ -27,10 +27,10 @@ const (
27 27
 
28 28
 // Interface that implements terminal handling
29 29
 type terminalEmulator interface {
30
-	HandleOutputCommand(command []byte) (n int, err error)
31
-	HandleInputSequence(command []byte) (n int, err error)
32
-	WriteChars(w io.Writer, p []byte) (n int, err error)
33
-	ReadChars(w io.Reader, p []byte) (n int, err error)
30
+	HandleOutputCommand(fd uintptr, command []byte) (n int, err error)
31
+	HandleInputSequence(fd uintptr, command []byte) (n int, err error)
32
+	WriteChars(fd uintptr, w io.Writer, p []byte) (n int, err error)
33
+	ReadChars(fd uintptr, w io.Reader, p []byte) (n int, err error)
34 34
 }
35 35
 
36 36
 type terminalWriter struct {
... ...
@@ -38,6 +38,7 @@ type terminalWriter struct {
38 38
 	emulator      terminalEmulator
39 39
 	command       []byte
40 40
 	inSequence    bool
41
+	fd            uintptr
41 42
 }
42 43
 
43 44
 type terminalReader struct {
... ...
@@ -45,6 +46,7 @@ type terminalReader struct {
45 45
 	emulator      terminalEmulator
46 46
 	command       []byte
47 47
 	inSequence    bool
48
+	fd            uintptr
48 49
 }
49 50
 
50 51
 // 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) {
91 91
 				if !isXtermOscSequence(tw.command, p[current]) {
92 92
 					// found the last command character.
93 93
 					// Now we have a complete command.
94
-					nchar, err := tw.emulator.HandleOutputCommand(tw.command)
94
+					nchar, err := tw.emulator.HandleOutputCommand(tw.fd, tw.command)
95 95
 					totalWritten += nchar
96 96
 					if err != nil {
97 97
 						return totalWritten, err
... ...
@@ -110,7 +112,7 @@ func (tw *terminalWriter) Write(p []byte) (n int, err error) {
110 110
 				tw.inSequence = true
111 111
 				// indicates end of "normal sequence", write whatever you have so far
112 112
 				if len(p[start:current]) > 0 {
113
-					nw, err := tw.emulator.WriteChars(tw.wrappedWriter, p[start:current])
113
+					nw, err := tw.emulator.WriteChars(tw.fd, tw.wrappedWriter, p[start:current])
114 114
 					totalWritten += nw
115 115
 					if err != nil {
116 116
 						return totalWritten, err
... ...
@@ -126,7 +128,7 @@ func (tw *terminalWriter) Write(p []byte) (n int, err error) {
126 126
 	if !tw.inSequence {
127 127
 		// assumption is that we can't be inside sequence and therefore command should be empty
128 128
 		if len(p[start:]) > 0 {
129
-			nw, err := tw.emulator.WriteChars(tw.wrappedWriter, p[start:])
129
+			nw, err := tw.emulator.WriteChars(tw.fd, tw.wrappedWriter, p[start:])
130 130
 			totalWritten += nw
131 131
 			if err != nil {
132 132
 				return totalWritten, err
... ...
@@ -148,7 +150,7 @@ func (tr *terminalReader) Read(p []byte) (n int, err error) {
148 148
 	if nil == tr.emulator {
149 149
 		return tr.readFromWrappedReader(p)
150 150
 	}
151
-	return tr.emulator.ReadChars(tr.wrappedReader, p)
151
+	return tr.emulator.ReadChars(tr.fd, tr.wrappedReader, p)
152 152
 }
153 153
 
154 154
 // Close the underlying stream
... ...
@@ -71,21 +71,21 @@ func (mt *mockTerminal) record(operation int, data []byte) {
71 71
 	mt.OutputCommandSequence = append(mt.OutputCommandSequence, op)
72 72
 }
73 73
 
74
-func (mt *mockTerminal) HandleOutputCommand(command []byte) (n int, err error) {
74
+func (mt *mockTerminal) HandleOutputCommand(fd uintptr, command []byte) (n int, err error) {
75 75
 	mt.record(COMMAND_OPERATION, command)
76 76
 	return len(command), nil
77 77
 }
78 78
 
79
-func (mt *mockTerminal) HandleInputSequence(command []byte) (n int, err error) {
79
+func (mt *mockTerminal) HandleInputSequence(fd uintptr, command []byte) (n int, err error) {
80 80
 	return 0, nil
81 81
 }
82 82
 
83
-func (mt *mockTerminal) WriteChars(w io.Writer, p []byte) (n int, err error) {
83
+func (mt *mockTerminal) WriteChars(fd uintptr, w io.Writer, p []byte) (n int, err error) {
84 84
 	mt.record(WRITE_OPERATION, p)
85 85
 	return len(p), nil
86 86
 }
87 87
 
88
-func (mt *mockTerminal) ReadChars(w io.Reader, p []byte) (n int, err error) {
88
+func (mt *mockTerminal) ReadChars(fd uintptr, w io.Reader, p []byte) (n int, err error) {
89 89
 	return len(p), nil
90 90
 }
91 91