Skip to content

Commit 29b139f

Browse files
committed
Move STDIO initialization to libcontainer.Process
Signed-off-by: Michael Crosby <[email protected]>
1 parent 0267ad0 commit 29b139f

File tree

5 files changed

+62
-44
lines changed

5 files changed

+62
-44
lines changed

libcontainer/process.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"io"
66
"math"
77
"os"
8+
"syscall"
89
)
910

1011
type processOperations interface {
@@ -78,6 +79,54 @@ func (p Process) Signal(sig os.Signal) error {
7879
return p.ops.signal(sig)
7980
}
8081

82+
// IO holds the process's STDIO
83+
type IO struct {
84+
Stdin io.WriteCloser
85+
Stdout io.ReadCloser
86+
Stderr io.ReadCloser
87+
}
88+
89+
// InitializeIO creates pipes for use with the process's STDIO
90+
// and returns the opposite side for each
91+
func (p *Process) InitializeIO(rootuid int) (i *IO, err error) {
92+
var fds []uintptr
93+
i = &IO{}
94+
// cleanup in case of an error
95+
defer func() {
96+
if err != nil {
97+
for _, fd := range fds {
98+
syscall.Close(int(fd))
99+
}
100+
}
101+
}()
102+
// STDIN
103+
r, w, err := os.Pipe()
104+
if err != nil {
105+
return nil, err
106+
}
107+
fds = append(fds, r.Fd(), w.Fd())
108+
p.Stdin, i.Stdin = r, w
109+
// STDOUT
110+
if r, w, err = os.Pipe(); err != nil {
111+
return nil, err
112+
}
113+
fds = append(fds, r.Fd(), w.Fd())
114+
p.Stdout, i.Stdout = w, r
115+
// STDERR
116+
if r, w, err = os.Pipe(); err != nil {
117+
return nil, err
118+
}
119+
fds = append(fds, r.Fd(), w.Fd())
120+
p.Stderr, i.Stderr = w, r
121+
// change ownership of the pipes incase we are in a user namespace
122+
for _, fd := range fds {
123+
if err := syscall.Fchown(int(fd), rootuid, rootuid); err != nil {
124+
return nil, err
125+
}
126+
}
127+
return i, nil
128+
}
129+
81130
// NewConsole creates new console for process and returns it
82131
func (p *Process) NewConsole(rootuid int) (Console, error) {
83132
console, err := NewConsole(rootuid, rootuid)

restore.go

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -126,11 +126,7 @@ func restoreContainer(context *cli.Context, spec *specs.LinuxSpec, config *confi
126126
}
127127
}
128128
}()
129-
process := &libcontainer.Process{
130-
Stdin: os.Stdin,
131-
Stdout: os.Stdout,
132-
Stderr: os.Stderr,
133-
}
129+
process := &libcontainer.Process{}
134130
tty, err := newTty(spec.Process.Terminal, process, rootuid)
135131
if err != nil {
136132
return -1, err

start.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,12 +110,10 @@ func startContainer(context *cli.Context, spec *specs.LinuxSpec, rspec *specs.Li
110110
if err != nil {
111111
return -1, err
112112
}
113-
114113
for i := SD_LISTEN_FDS_START; i < (listenFdsInt + SD_LISTEN_FDS_START); i++ {
115114
process.ExtraFiles = append(process.ExtraFiles, os.NewFile(uintptr(i), ""))
116115
}
117116
}
118-
119117
tty, err := newTty(spec.Process.Terminal, process, rootuid)
120118
if err != nil {
121119
return -1, err

tty.go

Lines changed: 10 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import (
66
"fmt"
77
"io"
88
"os"
9-
"syscall"
109

1110
"github.com/docker/docker/pkg/term"
1211
"github.com/opencontainers/runc/libcontainer"
@@ -25,38 +24,20 @@ func newTty(create bool, p *libcontainer.Process, rootuid int) (*tty, error) {
2524
// setup standard pipes so that the TTY of the calling runc process
2625
// is not inherited by the container.
2726
func createStdioPipes(p *libcontainer.Process, rootuid int) (*tty, error) {
28-
var (
29-
t = &tty{}
30-
fds []int
31-
)
32-
r, w, err := os.Pipe()
27+
i, err := p.InitializeIO(rootuid)
3328
if err != nil {
3429
return nil, err
3530
}
36-
fds = append(fds, int(r.Fd()), int(w.Fd()))
37-
go io.Copy(w, os.Stdin)
38-
t.closers = append(t.closers, w)
39-
p.Stdin = r
40-
if r, w, err = os.Pipe(); err != nil {
41-
return nil, err
42-
}
43-
fds = append(fds, int(r.Fd()), int(w.Fd()))
44-
go io.Copy(os.Stdout, r)
45-
p.Stdout = w
46-
t.closers = append(t.closers, r)
47-
if r, w, err = os.Pipe(); err != nil {
48-
return nil, err
49-
}
50-
fds = append(fds, int(r.Fd()), int(w.Fd()))
51-
go io.Copy(os.Stderr, r)
52-
p.Stderr = w
53-
t.closers = append(t.closers, r)
54-
// change the ownership of the pipe fds incase we are in a user namespace.
55-
for _, fd := range fds {
56-
if err := syscall.Fchown(fd, rootuid, rootuid); err != nil {
57-
return nil, err
58-
}
31+
t := &tty{
32+
closers: []io.Closer{
33+
i.Stdin,
34+
i.Stdout,
35+
i.Stderr,
36+
},
5937
}
38+
go io.Copy(i.Stdin, os.Stdin)
39+
go io.Copy(os.Stdout, i.Stdout)
40+
go io.Copy(os.Stderr, i.Stderr)
6041
return t, nil
6142
}
6243

@@ -78,9 +59,6 @@ func createTty(p *libcontainer.Process, rootuid int) (*tty, error) {
7859
console,
7960
},
8061
}
81-
p.Stderr = nil
82-
p.Stdout = nil
83-
p.Stdin = nil
8462
return t, nil
8563
}
8664

utils.go

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -161,10 +161,7 @@ func newProcess(p specs.Process) *libcontainer.Process {
161161
Args: p.Args,
162162
Env: p.Env,
163163
// TODO: fix libcontainer's API to better support uid/gid in a typesafe way.
164-
User: fmt.Sprintf("%d:%d", p.User.UID, p.User.GID),
165-
Cwd: p.Cwd,
166-
Stdin: os.Stdin,
167-
Stdout: os.Stdout,
168-
Stderr: os.Stderr,
164+
User: fmt.Sprintf("%d:%d", p.User.UID, p.User.GID),
165+
Cwd: p.Cwd,
169166
}
170167
}

0 commit comments

Comments
 (0)