Skip to content

Commit 0c099fa

Browse files
authored
Merge pull request moby#39860 from stbenjam/cmd-race
archive: fix race condition in cmdStream
2 parents fe33a4e + 89dd10b commit 0c099fa

File tree

2 files changed

+14
-2
lines changed

2 files changed

+14
-2
lines changed

pkg/archive/archive.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1218,16 +1218,26 @@ func cmdStream(cmd *exec.Cmd, input io.Reader) (io.ReadCloser, error) {
12181218
return nil, err
12191219
}
12201220

1221+
// Ensure the command has exited before we clean anything up
1222+
done := make(chan struct{})
1223+
12211224
// Copy stdout to the returned pipe
12221225
go func() {
12231226
if err := cmd.Wait(); err != nil {
12241227
pipeW.CloseWithError(fmt.Errorf("%s: %s", err, errBuf.String()))
12251228
} else {
12261229
pipeW.Close()
12271230
}
1231+
close(done)
12281232
}()
12291233

1230-
return pipeR, nil
1234+
return ioutils.NewReadCloserWrapper(pipeR, func() error {
1235+
// Close pipeR, and then wait for the command to complete before returning. We have to close pipeR first, as
1236+
// cmd.Wait waits for any non-file stdout/stderr/stdin to close.
1237+
err := pipeR.Close()
1238+
<-done
1239+
return err
1240+
}), nil
12311241
}
12321242

12331243
// NewTempArchive reads the content of src into a temporary file, and returns the contents

pkg/archive/archive_test.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1332,7 +1332,9 @@ func TestPigz(t *testing.T) {
13321332
_, err := exec.LookPath("unpigz")
13331333
if err == nil {
13341334
t.Log("Tested whether Pigz is used, as it installed")
1335-
assert.Equal(t, reflect.TypeOf(contextReaderCloserWrapper.Reader), reflect.TypeOf(&io.PipeReader{}))
1335+
// For the command wait wrapper
1336+
cmdWaitCloserWrapper := contextReaderCloserWrapper.Reader.(*ioutils.ReadCloserWrapper)
1337+
assert.Equal(t, reflect.TypeOf(cmdWaitCloserWrapper.Reader), reflect.TypeOf(&io.PipeReader{}))
13361338
} else {
13371339
t.Log("Tested whether Pigz is not used, as it not installed")
13381340
assert.Equal(t, reflect.TypeOf(contextReaderCloserWrapper.Reader), reflect.TypeOf(&gzip.Reader{}))

0 commit comments

Comments
 (0)