diff --git a/vendor/github.com/crosbymichael/go-runc/io.go b/vendor/github.com/crosbymichael/go-runc/io.go new file mode 100644 index 0000000..150c19e --- /dev/null +++ b/vendor/github.com/crosbymichael/go-runc/io.go @@ -0,0 +1,121 @@ +package runc + +import ( + "io" + "os" + "os/exec" + "syscall" +) + +type IO interface { + io.Closer + Stdin() io.WriteCloser + Stdout() io.ReadCloser + Stderr() io.ReadCloser + Set(*exec.Cmd) +} + +// NewPipeIO creates pipe pairs to be used with runc +func NewPipeIO(uid, gid int) (i IO, err error) { + var pipes []*pipe + // cleanup in case of an error + defer func() { + if err != nil { + for _, p := range pipes { + p.Close() + } + } + }() + stdin, err := newPipe(uid, gid) + if err != nil { + return nil, err + } + pipes = append(pipes, stdin) + + stdout, err := newPipe(uid, gid) + if err != nil { + return nil, err + } + pipes = append(pipes, stdout) + + stderr, err := newPipe(uid, gid) + if err != nil { + return nil, err + } + pipes = append(pipes, stderr) + + return &pipeIO{ + in: stdin, + out: stdout, + err: stderr, + }, nil +} + +func newPipe(uid, gid int) (*pipe, error) { + r, w, err := os.Pipe() + if err != nil { + return nil, err + } + if err := syscall.Fchown(int(r.Fd()), uid, gid); err != nil { + return nil, err + } + if err := syscall.Fchown(int(w.Fd()), uid, gid); err != nil { + return nil, err + } + return &pipe{ + r: r, + w: w, + }, nil +} + +type pipe struct { + r *os.File + w *os.File +} + +func (p *pipe) Close() error { + err := p.r.Close() + if werr := p.w.Close(); err == nil { + err = werr + } + return err +} + +type pipeIO struct { + in *pipe + out *pipe + err *pipe +} + +func (i *pipeIO) Stdin() io.WriteCloser { + return i.in.w +} + +func (i *pipeIO) Stdout() io.ReadCloser { + return i.in.r +} + +func (i *pipeIO) Stderr() io.ReadCloser { + return i.in.r +} + +func (i *pipeIO) Close() error { + var err error + for _, v := range []*pipe{ + i.in, + i.out, + i.err, + } { + if cerr := v.Close(); err == nil { + err = cerr + } + } + return err +} + +// Set sets the io to the exec.Cmd +func (i *pipeIO) Set(cmd *exec.Cmd) { + cmd.Stdin = i.in.r + cmd.Stdout = i.out.w + cmd.Stderr = i.err.w +} diff --git a/vendor/github.com/crosbymichael/go-runc/runc.go b/vendor/github.com/crosbymichael/go-runc/runc.go index bb551f4..9ba661c 100644 --- a/vendor/github.com/crosbymichael/go-runc/runc.go +++ b/vendor/github.com/crosbymichael/go-runc/runc.go @@ -73,36 +73,6 @@ type CreateOpts struct { NoNewKeyring bool } -type IO struct { - Stdin io.Reader - Stdout io.Writer - Stderr io.Writer -} - -func (i *IO) Close() error { - var err error - for _, v := range []interface{}{ - i.Stdin, - i.Stderr, - i.Stdout, - } { - if v != nil { - if c, ok := v.(io.Closer); ok { - if cerr := c.Close(); err == nil { - err = cerr - } - } - } - } - return err -} - -func (o IO) setSTDIO(cmd *exec.Cmd) { - cmd.Stdin = o.Stdin - cmd.Stdout = o.Stdout - cmd.Stderr = o.Stderr -} - func (o *CreateOpts) args() (out []string) { if o.PidFile != "" { out = append(out, "--pid-file", o.PidFile) @@ -130,7 +100,7 @@ func (r *Runc) Create(context context.Context, id, bundle string, opts *CreateOp } cmd := r.command(context, append(args, id)...) if opts != nil { - opts.setSTDIO(cmd) + opts.Set(cmd) } return runOrError(cmd) } @@ -190,7 +160,7 @@ func (r *Runc) Exec(context context.Context, id string, spec specs.Process, opts } cmd := r.command(context, append(args, id)...) if opts != nil { - opts.setSTDIO(cmd) + opts.Set(cmd) } return runOrError(cmd) } @@ -204,7 +174,7 @@ func (r *Runc) Run(context context.Context, id, bundle string, opts *CreateOpts) } cmd := r.command(context, append(args, id)...) if opts != nil { - opts.setSTDIO(cmd) + opts.Set(cmd) } if err := cmd.Start(); err != nil { return -1, err