فهرست منبع

ssh: add Session.WindowChange to send window change events

Change-Id: Ib89c0a4e46c9a7f90a53f21b06fcddfdf13c7fd9
Reviewed-on: https://go-review.googlesource.com/50490
Reviewed-by: Han-Wen Nienhuys <hanwen@google.com>
Run-TryBot: Han-Wen Nienhuys <hanwen@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Tobias Assarsson 8 سال پیش
والد
کامیت
8c55ac71e0
2فایلهای تغییر یافته به همراه68 افزوده شده و 0 حذف شده
  1. 20 0
      ssh/session.go
  2. 48 0
      ssh/test/session_test.go

+ 20 - 0
ssh/session.go

@@ -231,6 +231,26 @@ func (s *Session) RequestSubsystem(subsystem string) error {
 	return err
 }
 
+// RFC 4254 Section 6.7.
+type ptyWindowChangeMsg struct {
+	Columns uint32
+	Rows    uint32
+	Width   uint32
+	Height  uint32
+}
+
+// WindowChange informs the remote host about a terminal window dimension change to h rows and w columns.
+func (s *Session) WindowChange(h, w int) error {
+	req := ptyWindowChangeMsg{
+		Columns: uint32(w),
+		Rows:    uint32(h),
+		Width:   uint32(w * 8),
+		Height:  uint32(h * 8),
+	}
+	_, err := s.ch.SendRequest("window-change", false, Marshal(&req))
+	return err
+}
+
 // RFC 4254 Section 6.9.
 type signalMsg struct {
 	Signal string

+ 48 - 0
ssh/test/session_test.go

@@ -276,6 +276,54 @@ func TestValidTerminalMode(t *testing.T) {
 	}
 }
 
+func TestWindowChange(t *testing.T) {
+	server := newServer(t)
+	defer server.Shutdown()
+	conn := server.Dial(clientConfig())
+	defer conn.Close()
+
+	session, err := conn.NewSession()
+	if err != nil {
+		t.Fatalf("session failed: %v", err)
+	}
+	defer session.Close()
+
+	stdout, err := session.StdoutPipe()
+	if err != nil {
+		t.Fatalf("unable to acquire stdout pipe: %s", err)
+	}
+
+	stdin, err := session.StdinPipe()
+	if err != nil {
+		t.Fatalf("unable to acquire stdin pipe: %s", err)
+	}
+
+	tm := ssh.TerminalModes{ssh.ECHO: 0}
+	if err = session.RequestPty("xterm", 80, 40, tm); err != nil {
+		t.Fatalf("req-pty failed: %s", err)
+	}
+
+	if err := session.WindowChange(100, 100); err != nil {
+		t.Fatalf("window-change failed: %s", err)
+	}
+
+	err = session.Shell()
+	if err != nil {
+		t.Fatalf("session failed: %s", err)
+	}
+
+	stdin.Write([]byte("stty size && exit\n"))
+
+	var buf bytes.Buffer
+	if _, err := io.Copy(&buf, stdout); err != nil {
+		t.Fatalf("reading failed: %s", err)
+	}
+
+	if sttyOutput := buf.String(); !strings.Contains(sttyOutput, "100 100") {
+		t.Fatalf("terminal WindowChange failure: expected \"100 100\" stty output, got %s", sttyOutput)
+	}
+}
+
 func TestCiphers(t *testing.T) {
 	var config ssh.Config
 	config.SetDefaults()