github.com/haraldrudell/parl@v0.4.176/pexec/copy-thread.go (about) 1 /* 2 © 2021–present Harald Rudell <harald.rudell@gmail.com> (https://haraldrudell.github.io/haraldrudell/) 3 ISC License 4 */ 5 6 package pexec 7 8 import ( 9 "context" 10 "errors" 11 "io" 12 "io/fs" 13 "sync" 14 15 "github.com/haraldrudell/parl" 16 "github.com/haraldrudell/parl/perrors" 17 ) 18 19 // copyThread copies from a io.Reader to io.Writer. 20 // - label is used for thread identification on panics 21 // - reader could be the stdin io.Reader being copied to the execCmd.StdinPipe Writer 22 // - addError receives panics 23 // - on panic exeCtx context is cancelled 24 // - the thread itself never fails 25 func copyThread(label string, 26 reader io.Reader, writer io.Writer, 27 addError func(err error), execCtx context.Context, 28 wg *sync.WaitGroup) { 29 defer wg.Done() 30 var err error 31 defer parl.CancelOnError(&err, execCtx) // cancel the command if copyThread failes 32 defer parl.RecoverAnnotation("copy command i/o "+label, &err, addError) 33 34 if _, err = io.Copy(writer, reader); perrors.Is(&err, "%s io.Copy %w", label, err) { 35 36 // if the process terminates quickly, exec.Command might have already closed 37 // stdout stderr before the copyThread is scheduled to start 38 if errors.Is(err, fs.ErrClosed) { 39 err = nil // ignore quickly closed errors 40 } 41 42 return 43 } 44 }