Skip to content

Commit 116e770

Browse files
crosbymichaelestesp
authored andcommitted
Call CloseIO when stdin closes in ctr
Fixes #2439 Signed-off-by: Michael Crosby <[email protected]> Signed-off-by: Phil Estes <[email protected]>
1 parent becb04a commit 116e770

2 files changed

Lines changed: 39 additions & 3 deletions

File tree

cmd/ctr/commands/tasks/exec.go

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,11 @@ package tasks
1818

1919
import (
2020
"errors"
21+
"io"
22+
"os"
2123

2224
"github.com/containerd/console"
25+
"github.com/containerd/containerd"
2326
"github.com/containerd/containerd/cio"
2427
"github.com/containerd/containerd/cmd/ctr/commands"
2528
"github.com/sirupsen/logrus"
@@ -80,7 +83,12 @@ var execCommand = cli.Command{
8083
pspec.Terminal = tty
8184
pspec.Args = args
8285

83-
cioOpts := []cio.Opt{cio.WithStdio, cio.WithFIFODir(context.String("fifo-dir"))}
86+
var (
87+
stdinC = &stdinCloser{
88+
stdin: os.Stdin,
89+
}
90+
)
91+
cioOpts := []cio.Opt{cio.WithStreams(stdinC, os.Stdout, os.Stderr), cio.WithFIFODir(context.String("fifo-dir"))}
8492
if tty {
8593
cioOpts = append(cioOpts, cio.WithTerminal)
8694
}
@@ -89,6 +97,9 @@ var execCommand = cli.Command{
8997
if err != nil {
9098
return err
9199
}
100+
stdinC.closer = func() {
101+
process.CloseIO(ctx, containerd.WithStdinCloser)
102+
}
92103
defer process.Delete(ctx)
93104

94105
statusC, err := process.Wait(ctx)
@@ -127,3 +138,18 @@ var execCommand = cli.Command{
127138
return nil
128139
},
129140
}
141+
142+
type stdinCloser struct {
143+
stdin *os.File
144+
closer func()
145+
}
146+
147+
func (s *stdinCloser) Read(p []byte) (int, error) {
148+
n, err := s.stdin.Read(p)
149+
if err == io.EOF {
150+
if s.closer != nil {
151+
s.closer()
152+
}
153+
}
154+
return n, err
155+
}

cmd/ctr/commands/tasks/tasks_unix.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,10 @@ func HandleConsoleResize(ctx gocontext.Context, task resizer, con console.Consol
6868

6969
// NewTask creates a new task
7070
func NewTask(ctx gocontext.Context, client *containerd.Client, container containerd.Container, checkpoint string, con console.Console, nullIO bool, ioOpts []cio.Opt, opts ...containerd.NewTaskOpts) (containerd.Task, error) {
71-
stdio := cio.NewCreator(append([]cio.Opt{cio.WithStdio}, ioOpts...)...)
71+
stdinC := &stdinCloser{
72+
stdin: os.Stdin,
73+
}
74+
stdio := cio.NewCreator(append([]cio.Opt{cio.WithStreams(stdinC, os.Stdout, os.Stderr)}, ioOpts...)...)
7275
if checkpoint != "" {
7376
im, err := client.GetImage(ctx, checkpoint)
7477
if err != nil {
@@ -86,7 +89,14 @@ func NewTask(ctx gocontext.Context, client *containerd.Client, container contain
8689
}
8790
ioCreator = cio.NullIO
8891
}
89-
return container.NewTask(ctx, ioCreator, opts...)
92+
t, err := container.NewTask(ctx, ioCreator, opts...)
93+
if err != nil {
94+
return nil, err
95+
}
96+
stdinC.closer = func() {
97+
t.CloseIO(ctx, containerd.WithStdinCloser)
98+
}
99+
return t, nil
90100
}
91101

92102
func getNewTaskOpts(context *cli.Context) []containerd.NewTaskOpts {

0 commit comments

Comments
 (0)