Skip to content

Commit f543f2f

Browse files
committed
Call CloseIO when stdin closes in ctr
Fixes containerd#2439 Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
1 parent ab78270 commit f543f2f

File tree

2 files changed

+40
-4
lines changed

2 files changed

+40
-4
lines changed

cmd/ctr/commands/tasks/exec.go

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,12 @@ package tasks
1818

1919
import (
2020
"errors"
21+
"io"
2122
"net/url"
23+
"os"
2224

2325
"github.com/containerd/console"
26+
"github.com/containerd/containerd"
2427
"github.com/containerd/containerd/cio"
2528
"github.com/containerd/containerd/cmd/ctr/commands"
2629
"github.com/sirupsen/logrus"
@@ -91,7 +94,12 @@ var execCommand = cli.Command{
9194
pspec.Terminal = tty
9295
pspec.Args = args
9396

94-
var ioCreator cio.Creator
97+
var (
98+
ioCreator cio.Creator
99+
stdinC = &stdinCloser{
100+
stdin: os.Stdin,
101+
}
102+
)
95103

96104
if logURI := context.String("log-uri"); logURI != "" {
97105
uri, err := url.Parse(logURI)
@@ -109,7 +117,7 @@ var execCommand = cli.Command{
109117

110118
ioCreator = cio.LogURI(uri)
111119
} else {
112-
cioOpts := []cio.Opt{cio.WithStdio, cio.WithFIFODir(context.String("fifo-dir"))}
120+
cioOpts := []cio.Opt{cio.WithStreams(stdinC, os.Stdout, os.Stderr), cio.WithFIFODir(context.String("fifo-dir"))}
113121
if tty {
114122
cioOpts = append(cioOpts, cio.WithTerminal)
115123
}
@@ -120,6 +128,9 @@ var execCommand = cli.Command{
120128
if err != nil {
121129
return err
122130
}
131+
stdinC.closer = func() {
132+
process.CloseIO(ctx, containerd.WithStdinCloser)
133+
}
123134
// if detach, we should not call this defer
124135
if !detach {
125136
defer process.Delete(ctx)
@@ -166,3 +177,18 @@ var execCommand = cli.Command{
166177
return nil
167178
},
168179
}
180+
181+
type stdinCloser struct {
182+
stdin *os.File
183+
closer func()
184+
}
185+
186+
func (s *stdinCloser) Read(p []byte) (int, error) {
187+
n, err := s.stdin.Read(p)
188+
if err == io.EOF {
189+
if s.closer != nil {
190+
s.closer()
191+
}
192+
}
193+
return n, err
194+
}

cmd/ctr/commands/tasks/tasks_unix.go

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

7070
// NewTask creates a new task
7171
func NewTask(ctx gocontext.Context, client *containerd.Client, container containerd.Container, checkpoint string, con console.Console, nullIO bool, logURI string, ioOpts []cio.Opt, opts ...containerd.NewTaskOpts) (containerd.Task, error) {
72-
stdio := cio.NewCreator(append([]cio.Opt{cio.WithStdio}, ioOpts...)...)
72+
stdinC := &stdinCloser{
73+
stdin: os.Stdin,
74+
}
75+
stdio := cio.NewCreator(append([]cio.Opt{cio.WithStreams(stdinC, os.Stdout, os.Stderr)}, ioOpts...)...)
7376
if checkpoint != "" {
7477
im, err := client.GetImage(ctx, checkpoint)
7578
if err != nil {
@@ -94,7 +97,14 @@ func NewTask(ctx gocontext.Context, client *containerd.Client, container contain
9497
}
9598
ioCreator = cio.LogURI(u)
9699
}
97-
return container.NewTask(ctx, ioCreator, opts...)
100+
t, err := container.NewTask(ctx, ioCreator, opts...)
101+
if err != nil {
102+
return nil, err
103+
}
104+
stdinC.closer = func() {
105+
t.CloseIO(ctx, containerd.WithStdinCloser)
106+
}
107+
return t, nil
98108
}
99109

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

0 commit comments

Comments
 (0)