diff options
author | Santiago M. Mola <santi@mola.io> | 2017-07-07 11:10:37 +0200 |
---|---|---|
committer | Santiago M. Mola <santi@mola.io> | 2017-07-07 11:10:37 +0200 |
commit | 6506d377f7dc70b72d7454f5901d8199023dd8ed (patch) | |
tree | 96dacfe133ae23d5c200b62c78dcd16306c3a7f6 /plumbing | |
parent | 22d8c7082f547acdc245fd836c1962583c0c87a1 (diff) | |
download | go-git-6506d377f7dc70b72d7454f5901d8199023dd8ed.tar.gz |
transport/file: avoid race with Command.Wait, fixes #463
Pipe returned by Command.StderrPipe() has a race with Read and
Command.Wait(). We use a io.Pipe() instead and ensure it is closed
after Wait().
Diffstat (limited to 'plumbing')
-rw-r--r-- | plumbing/transport/file/client.go | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/plumbing/transport/file/client.go b/plumbing/transport/file/client.go index a199b01..b6d60c1 100644 --- a/plumbing/transport/file/client.go +++ b/plumbing/transport/file/client.go @@ -46,8 +46,9 @@ func (r *runner) Command(cmd string, ep transport.Endpoint, auth transport.AuthM } type command struct { - cmd *exec.Cmd - closed bool + cmd *exec.Cmd + stderrCloser io.Closer + closed bool } func (c *command) Start() error { @@ -55,7 +56,12 @@ func (c *command) Start() error { } func (c *command) StderrPipe() (io.Reader, error) { - return c.cmd.StderrPipe() + // Pipe returned by Command.StderrPipe has a race with Read + Command.Wait. + // We use an io.Pipe and close it after the command finishes. + r, w := io.Pipe() + c.cmd.Stderr = w + c.stderrCloser = r + return r, nil } func (c *command) StdinPipe() (io.WriteCloser, error) { @@ -72,7 +78,11 @@ func (c *command) Close() error { return nil } - defer func() { c.closed = true }() + defer func() { + c.closed = true + _ = c.stderrCloser.Close() + }() + err := c.cmd.Wait() if _, ok := err.(*os.PathError); ok { return nil |