@@ -204,7 +204,7 @@ func newTerm(alias string, pty *os.File, cmd *exec.Cmd, options TermOptions) (*T
204204
205205 timeout := options .ReadTimeout
206206 if timeout == 0 {
207- timeout = 1 << 63 - 1
207+ timeout = NoTimeout
208208 }
209209 res := & Term {
210210 PTY : pty ,
@@ -244,6 +244,9 @@ func newTerm(alias string, pty *os.File, cmd *exec.Cmd, options TermOptions) (*T
244244 return res , nil
245245}
246246
247+ // NoTimeout means that listener can block read forever
248+ var NoTimeout time.Duration = 1 << 63 - 1
249+
247250// TermOptions is a pseudo-terminal configuration.
248251type TermOptions struct {
249252 // timeout after which a listener is dropped. Use 0 for no timeout.
@@ -375,6 +378,7 @@ var (
375378
376379type multiWriterListener struct {
377380 io.Reader
381+ timeout time.Duration
378382
379383 closed bool
380384 once sync.Once
@@ -413,22 +417,40 @@ func (closedTerminalListener) Read(p []byte) (n int, err error) {
413417
414418var closedListener = io .NopCloser (closedTerminalListener {})
415419
420+ // TermListenOptions is a configuration to listen to the pseudo-terminal .
421+ type TermListenOptions struct {
422+ // timeout after which a listener is dropped. Use 0 for default timeout.
423+ ReadTimeout time.Duration
424+ }
425+
416426// Listen listens in on the multi-writer stream.
417427func (mw * multiWriter ) Listen () io.ReadCloser {
428+ return mw .ListenWithOptions (TermListenOptions {
429+ ReadTimeout : 0 ,
430+ })
431+ }
432+
433+ // Listen listens in on the multi-writer stream with given options.
434+ func (mw * multiWriter ) ListenWithOptions (options TermListenOptions ) io.ReadCloser {
418435 mw .mu .Lock ()
419436 defer mw .mu .Unlock ()
420437
421438 if mw .closed {
422439 return closedListener
423440 }
424441
442+ timeout := options .ReadTimeout
443+ if timeout == 0 {
444+ timeout = mw .timeout
445+ }
425446 r , w := io .Pipe ()
426447 cchan , done , closeChan := make (chan []byte ), make (chan struct {}, 1 ), make (chan struct {}, 1 )
427448 res := & multiWriterListener {
428449 Reader : r ,
429450 cchan : cchan ,
430451 done : done ,
431452 closeChan : closeChan ,
453+ timeout : timeout ,
432454 }
433455
434456 recording := mw .recorder .Bytes ()
@@ -489,13 +511,13 @@ func (mw *multiWriter) Write(p []byte) (n int, err error) {
489511
490512 select {
491513 case lstr .cchan <- p :
492- case <- time .After (mw .timeout ):
514+ case <- time .After (lstr .timeout ):
493515 lstr .CloseWithError (ErrReadTimeout )
494516 }
495517
496518 select {
497519 case <- lstr .done :
498- case <- time .After (mw .timeout ):
520+ case <- time .After (lstr .timeout ):
499521 lstr .CloseWithError (ErrReadTimeout )
500522 }
501523 }
0 commit comments