github.com/haraldrudell/parl@v0.4.176/pexec/exec-stream.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 ) 13 14 var ErrArgsListEmpty = errors.New("args list empty") 15 16 // ExecStream executes a system command using the exec.Cmd type and flexible streaming. 17 // - ExecStream blocks during command execution 18 // - ExecStream returns any error occurring during launch or execution including 19 // errors in copy threads 20 // - successful exit is: statusCode == 0, isCancel == false, err == nil 21 // - statusCode may be set by the process but is otherwise: 22 // - — 0 successful exit 23 // - — -1 process was killed by signal such as ^C or SIGTERM 24 // - context cancel exit is: statusCode == -1, isCancel == true, err == nil 25 // - failure exit is: statusCode != 0, isCancel == false, err != nil 26 // - — 27 // - args is the command followed by arguments. 28 // - args[0] must specify an executable in the file system. 29 // env.PATH is used to resolve the command executable 30 // - if stdin stdout or stderr are nil, the are /dev/null 31 // Additional threads are used to copy data when stdin stdout or stderr are non-nil 32 // - os.Stdin os.Stdout os.Stderr can be provided 33 // - for stdout and stderr pio has usable types: 34 // - — pio.NewWriteCloserToString 35 // - — pio.NewWriteCloserToChan 36 // - — pio.NewWriteCloserToChanLine 37 // - — pio.NewReadWriteCloserSlice 38 // - any stream provided is not closed. However, upon return from ExecStream all i/o operations 39 // have completed and streams may be closed as the case may be 40 // - ctx is used to kill the process (by calling os.Process.Kill) if the context becomes 41 // done before the command completes on its own 42 // - use ExecStream with parl.EchoModerator 43 // - if system commands slow down or lock-up, too many (dozens) invoking goroutines 44 // may cause increased memory consumption, thrashing or exhaust of file handles, ie. 45 // an uncontrollable host state 46 func ExecStream(stdin io.Reader, stdout io.WriteCloser, stderr io.WriteCloser, 47 ctx context.Context, args ...string) (statusCode int, isCancel bool, err error) { 48 return ExecStreamFull(stdin, stdout, stderr, nil, ctx, nil, nil, args...) 49 }