Browse code

windows: monitorTtySize correctly by polling

This change makes `monitorTtySize` work correctly on windows by polling
into win32 API to get terminal size (because there's no SIGWINCH on
windows) and send it to the engine over Remove API properly.

Average getttysize syscall takes around 30-40 ms on an average windows
machine as far as I can tell, therefore in a `for` loop, checking every
250ms if size has changed or not.

I'm not sure if there's a better way to do it on windows, if so,
somebody please send a link 'cause I could not find.

Signed-off-by: Ahmet Alp Balkan <ahmetalpbalkan@gmail.com>

Ahmet Alp Balkan authored on 2015/03/27 07:52:16
Showing 1 changed files
... ...
@@ -12,8 +12,10 @@ import (
12 12
 	"net/url"
13 13
 	"os"
14 14
 	gosignal "os/signal"
15
+	"runtime"
15 16
 	"strconv"
16 17
 	"strings"
18
+	"time"
17 19
 
18 20
 	log "github.com/Sirupsen/logrus"
19 21
 	"github.com/docker/docker/api"
... ...
@@ -279,13 +281,29 @@ func getExecExitCode(cli *DockerCli, execID string) (bool, int, error) {
279 279
 func (cli *DockerCli) monitorTtySize(id string, isExec bool) error {
280 280
 	cli.resizeTty(id, isExec)
281 281
 
282
-	sigchan := make(chan os.Signal, 1)
283
-	gosignal.Notify(sigchan, signal.SIGWINCH)
284
-	go func() {
285
-		for _ = range sigchan {
286
-			cli.resizeTty(id, isExec)
287
-		}
288
-	}()
282
+	if runtime.GOOS == "windows" {
283
+		go func() {
284
+			prevW, prevH := cli.getTtySize()
285
+			for {
286
+				time.Sleep(time.Millisecond * 250)
287
+				w, h := cli.getTtySize()
288
+
289
+				if prevW != w || prevH != h {
290
+					cli.resizeTty(id, isExec)
291
+				}
292
+				prevW = w
293
+				prevH = h
294
+			}
295
+		}()
296
+	} else {
297
+		sigchan := make(chan os.Signal, 1)
298
+		gosignal.Notify(sigchan, signal.SIGWINCH)
299
+		go func() {
300
+			for _ = range sigchan {
301
+				cli.resizeTty(id, isExec)
302
+			}
303
+		}()
304
+	}
289 305
 	return nil
290 306
 }
291 307