@@ -204,7 +204,7 @@ func newTerm(alias string, pty *os.File, cmd *exec.Cmd, options TermOptions) (*T
204
204
205
205
timeout := options .ReadTimeout
206
206
if timeout == 0 {
207
- timeout = 1 << 63 - 1
207
+ timeout = NoTimeout
208
208
}
209
209
res := & Term {
210
210
PTY : pty ,
@@ -244,6 +244,9 @@ func newTerm(alias string, pty *os.File, cmd *exec.Cmd, options TermOptions) (*T
244
244
return res , nil
245
245
}
246
246
247
+ // NoTimeout means that listener can block read forever
248
+ var NoTimeout time.Duration = 1 << 63 - 1
249
+
247
250
// TermOptions is a pseudo-terminal configuration.
248
251
type TermOptions struct {
249
252
// timeout after which a listener is dropped. Use 0 for no timeout.
@@ -375,6 +378,7 @@ var (
375
378
376
379
type multiWriterListener struct {
377
380
io.Reader
381
+ timeout time.Duration
378
382
379
383
closed bool
380
384
once sync.Once
@@ -413,22 +417,40 @@ func (closedTerminalListener) Read(p []byte) (n int, err error) {
413
417
414
418
var closedListener = io .NopCloser (closedTerminalListener {})
415
419
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
+
416
426
// Listen listens in on the multi-writer stream.
417
427
func (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 {
418
435
mw .mu .Lock ()
419
436
defer mw .mu .Unlock ()
420
437
421
438
if mw .closed {
422
439
return closedListener
423
440
}
424
441
442
+ timeout := options .ReadTimeout
443
+ if timeout == 0 {
444
+ timeout = mw .timeout
445
+ }
425
446
r , w := io .Pipe ()
426
447
cchan , done , closeChan := make (chan []byte ), make (chan struct {}, 1 ), make (chan struct {}, 1 )
427
448
res := & multiWriterListener {
428
449
Reader : r ,
429
450
cchan : cchan ,
430
451
done : done ,
431
452
closeChan : closeChan ,
453
+ timeout : timeout ,
432
454
}
433
455
434
456
recording := mw .recorder .Bytes ()
@@ -489,13 +511,13 @@ func (mw *multiWriter) Write(p []byte) (n int, err error) {
489
511
490
512
select {
491
513
case lstr .cchan <- p :
492
- case <- time .After (mw .timeout ):
514
+ case <- time .After (lstr .timeout ):
493
515
lstr .CloseWithError (ErrReadTimeout )
494
516
}
495
517
496
518
select {
497
519
case <- lstr .done :
498
- case <- time .After (mw .timeout ):
520
+ case <- time .After (lstr .timeout ):
499
521
lstr .CloseWithError (ErrReadTimeout )
500
522
}
501
523
}
0 commit comments