@@ -12,6 +12,7 @@ import (
12
12
"path/filepath"
13
13
"runtime"
14
14
"strings"
15
+ "syscall"
15
16
"time"
16
17
17
18
"github.com/mattn/go-isatty"
@@ -220,7 +221,7 @@ func batchDefaultTempDirPrefix() string {
220
221
return os .TempDir ()
221
222
}
222
223
223
- func batchOpenFileFlag (flag string ) (io. ReadCloser , error ) {
224
+ func batchOpenFileFlag (flag string ) (* os. File , error ) {
224
225
if flag == "" || flag == "-" {
225
226
if flag != "-" {
226
227
// If the flag wasn't set, we want to check stdin. If it's not a TTY,
@@ -238,8 +239,13 @@ func batchOpenFileFlag(flag string) (io.ReadCloser, error) {
238
239
}
239
240
}
240
241
}
242
+ // https://github.com/golang/go/issues/24842
243
+ if err := syscall .SetNonblock (0 , true ); err != nil {
244
+ panic (err )
245
+ }
246
+ stdin := os .NewFile (0 , "stdin" )
241
247
242
- return os . Stdin , nil
248
+ return stdin , nil
243
249
}
244
250
245
251
file , err := os .Open (flag )
@@ -292,7 +298,7 @@ func executeBatchSpec(ctx context.Context, ui ui.ExecUI, opts executeBatchSpecOp
292
298
293
299
// Parse flags and build up our service and executor options.
294
300
ui .ParsingBatchSpec ()
295
- batchSpec , rawSpec , err := parseBatchSpec (opts .file , svc , false )
301
+ batchSpec , rawSpec , err := parseBatchSpec (ctx , opts .file , svc , false )
296
302
if err != nil {
297
303
var multiErr errors.MultiError
298
304
if errors .As (err , & multiErr ) {
@@ -481,18 +487,33 @@ func executeBatchSpec(ctx context.Context, ui ui.ExecUI, opts executeBatchSpecOp
481
487
return nil
482
488
}
483
489
490
+ type ReadDeadliner interface {
491
+ SetReadDeadline (t time.Time ) error
492
+ }
493
+
494
+ func SetReadDeadlineOnCancel (ctx context.Context , d ReadDeadliner ) {
495
+ go func () {
496
+ <- ctx .Done ()
497
+ d .SetReadDeadline (time .Now ())
498
+ }()
499
+ }
500
+
484
501
// parseBatchSpec parses and validates the given batch spec. If the spec has
485
502
// validation errors, they are returned.
486
503
//
487
504
// isRemote argument is a temporary argument used to determine if the batch spec is being parsed for remote
488
505
// (server-side) processing. Remote processing does not support mounts yet.
489
- func parseBatchSpec (file string , svc * service.Service , isRemote bool ) (* batcheslib.BatchSpec , string , error ) {
506
+ func parseBatchSpec (ctx context. Context , file string , svc * service.Service , isRemote bool ) (* batcheslib.BatchSpec , string , error ) {
490
507
f , err := batchOpenFileFlag (file )
491
508
if err != nil {
492
509
return nil , "" , err
493
510
}
494
511
defer f .Close ()
495
512
513
+ ctx , cancel := context .WithCancel (ctx )
514
+ defer cancel ()
515
+ SetReadDeadlineOnCancel (ctx , f )
516
+
496
517
data , err := io .ReadAll (f )
497
518
if err != nil {
498
519
return nil , "" , errors .Wrap (err , "reading batch spec" )
0 commit comments