...
1
16
17 package term
18
19 import (
20 "fmt"
21
22 "github.com/moby/term"
23 "k8s.io/apimachinery/pkg/util/runtime"
24 "k8s.io/client-go/tools/remotecommand"
25 )
26
27
28
29 func (t TTY) GetSize() *remotecommand.TerminalSize {
30 outFd, isTerminal := term.GetFdInfo(t.Out)
31 if !isTerminal {
32 return nil
33 }
34 return GetSize(outFd)
35 }
36
37
38 func GetSize(fd uintptr) *remotecommand.TerminalSize {
39 winsize, err := term.GetWinsize(fd)
40 if err != nil {
41 runtime.HandleError(fmt.Errorf("unable to get terminal size: %v", err))
42 return nil
43 }
44
45 return &remotecommand.TerminalSize{Width: winsize.Width, Height: winsize.Height}
46 }
47
48
49
50 func (t *TTY) MonitorSize(initialSizes ...*remotecommand.TerminalSize) remotecommand.TerminalSizeQueue {
51 outFd, isTerminal := term.GetFdInfo(t.Out)
52 if !isTerminal {
53 return nil
54 }
55
56 t.sizeQueue = &sizeQueue{
57 t: *t,
58
59
60 resizeChan: make(chan remotecommand.TerminalSize, len(initialSizes)),
61 stopResizing: make(chan struct{}),
62 }
63
64 t.sizeQueue.monitorSize(outFd, initialSizes...)
65
66 return t.sizeQueue
67 }
68
69
70 type sizeQueue struct {
71 t TTY
72
73 resizeChan chan remotecommand.TerminalSize
74 stopResizing chan struct{}
75 }
76
77
78 var _ remotecommand.TerminalSizeQueue = &sizeQueue{}
79
80
81
82 func (s *sizeQueue) monitorSize(outFd uintptr, initialSizes ...*remotecommand.TerminalSize) {
83
84 for i := range initialSizes {
85 if initialSizes[i] != nil {
86 s.resizeChan <- *initialSizes[i]
87 }
88 }
89
90 resizeEvents := make(chan remotecommand.TerminalSize, 1)
91
92 monitorResizeEvents(outFd, resizeEvents, s.stopResizing)
93
94
95 go func() {
96 defer runtime.HandleCrash()
97
98 for {
99 select {
100 case size, ok := <-resizeEvents:
101 if !ok {
102 return
103 }
104
105 select {
106
107 case s.resizeChan <- size:
108
109 default:
110
111 }
112 case <-s.stopResizing:
113 return
114 }
115 }
116 }()
117 }
118
119
120
121 func (s *sizeQueue) Next() *remotecommand.TerminalSize {
122 size, ok := <-s.resizeChan
123 if !ok {
124 return nil
125 }
126 return &size
127 }
128
129
130 func (s *sizeQueue) stop() {
131 close(s.stopResizing)
132 }
133
View as plain text