Open tonistiigi opened 6 years ago
Misread on the first pass.
Isn't this by design and how exec.Cmd has always worked?
What part is by design? exec.Cmd.Wait()
isn't necessarily doing anything wrong in here but it can't be used in a way runc.Create
does because exec.Cmd
counts stdio as part of the command and runc.Create
has different lifecycle for the command and the io streams.
The behavior is that exec.Cmd.Wait()
waits for process to close and MAY wait for passed stdio to close as well. Waiting on the stdio depends if it was backed by files or not.
os/exec
allows 2 ways to wait on command:Cmd.Wait()
makes sure all the goroutines that can be created byCmd.Start()
are cleaned up and doesn't return before stdio is closed.Process.Wait()
returns after the process has exited but leaks goroutines. Previouslymonitor.Wait()
in this package waited only for process but was changed to fix those leaks.Problem is that there is one command
Create()
that by design takes stdio, forwards it to its children and then exits itself. That means thatCmd.Wait()
does not return because the attach stdio has not finished. In containerd this does not appear because the interfaces passed in are always regular files(fifos) and don't create extra goroutines inos/exec
internals.I'd recommend either changing
CreateOpt
to take*io.File
or implementing pipe copy in this library so it can be cleaned up outside of stdlib(that would probably mean adding a cleanup function to the IO interface).@crosbymichael