Skip to content

Commit de85314

Browse files
thepwagnerthaJeztah
authored andcommitted
runtime: guard Close() until both streams are complete
Signed-off-by: Peter Wagner <[email protected]> Signed-off-by: Sebastiaan van Stijn <[email protected]>
1 parent 255da2a commit de85314

1 file changed

Lines changed: 20 additions & 2 deletions

File tree

linux/proc/io.go

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"io"
2525
"os"
2626
"sync"
27+
"sync/atomic"
2728
"syscall"
2829

2930
"github.com/containerd/containerd/log"
@@ -39,7 +40,7 @@ var bufPool = sync.Pool{
3940
}
4041

4142
func copyPipes(ctx context.Context, rio runc.IO, stdin, stdout, stderr string, wg, cwg *sync.WaitGroup) error {
42-
var sameFile io.WriteCloser
43+
var sameFile *countingWriteCloser
4344
for _, i := range []struct {
4445
name string
4546
dest func(wc io.WriteCloser, rc io.Closer)
@@ -101,14 +102,18 @@ func copyPipes(ctx context.Context, rio runc.IO, stdin, stdout, stderr string, w
101102
}
102103
} else {
103104
if sameFile != nil {
105+
sameFile.count++
104106
i.dest(sameFile, nil)
105107
continue
106108
}
107109
if fw, err = os.OpenFile(i.name, syscall.O_WRONLY|syscall.O_APPEND, 0); err != nil {
108110
return fmt.Errorf("containerd-shim: opening %s failed: %s", i.name, err)
109111
}
110112
if stdout == stderr {
111-
sameFile = fw
113+
sameFile = &countingWriteCloser{
114+
WriteCloser: fw,
115+
count: 1,
116+
}
112117
}
113118
}
114119
i.dest(fw, fr)
@@ -134,6 +139,19 @@ func copyPipes(ctx context.Context, rio runc.IO, stdin, stdout, stderr string, w
134139
return nil
135140
}
136141

142+
// countingWriteCloser masks io.Closer() until close has been invoked a certain number of times.
143+
type countingWriteCloser struct {
144+
io.WriteCloser
145+
count int64
146+
}
147+
148+
func (c *countingWriteCloser) Close() error {
149+
if atomic.AddInt64(&c.count, -1) > 0 {
150+
return nil
151+
}
152+
return c.WriteCloser.Close()
153+
}
154+
137155
// isFifo checks if a file is a fifo
138156
// if the file does not exist then it returns false
139157
func isFifo(path string) (bool, error) {

0 commit comments

Comments
 (0)