123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107 |
- // +build linux solaris
- package libcontainerd
- import (
- "io"
- "io/ioutil"
- "os"
- "path/filepath"
- goruntime "runtime"
- "strings"
- containerd "github.com/containerd/containerd/api/grpc/types"
- "github.com/tonistiigi/fifo"
- "golang.org/x/net/context"
- "golang.org/x/sys/unix"
- )
- var fdNames = map[int]string{
- unix.Stdin: "stdin",
- unix.Stdout: "stdout",
- unix.Stderr: "stderr",
- }
- // process keeps the state for both main container process and exec process.
- type process struct {
- processCommon
- // Platform specific fields are below here.
- dir string
- }
- func (p *process) openFifos(ctx context.Context, terminal bool) (pipe *IOPipe, err error) {
- if err := os.MkdirAll(p.dir, 0700); err != nil {
- return nil, err
- }
- io := &IOPipe{}
- io.Stdin, err = fifo.OpenFifo(ctx, p.fifo(unix.Stdin), unix.O_WRONLY|unix.O_CREAT|unix.O_NONBLOCK, 0700)
- if err != nil {
- return nil, err
- }
- defer func() {
- if err != nil {
- io.Stdin.Close()
- }
- }()
- io.Stdout, err = fifo.OpenFifo(ctx, p.fifo(unix.Stdout), unix.O_RDONLY|unix.O_CREAT|unix.O_NONBLOCK, 0700)
- if err != nil {
- return nil, err
- }
- defer func() {
- if err != nil {
- io.Stdout.Close()
- }
- }()
- if goruntime.GOOS == "solaris" || !terminal {
- // For Solaris terminal handling is done exclusively by the runtime therefore we make no distinction
- // in the processing for terminal and !terminal cases.
- io.Stderr, err = fifo.OpenFifo(ctx, p.fifo(unix.Stderr), unix.O_RDONLY|unix.O_CREAT|unix.O_NONBLOCK, 0700)
- if err != nil {
- return nil, err
- }
- defer func() {
- if err != nil {
- io.Stderr.Close()
- }
- }()
- } else {
- io.Stderr = ioutil.NopCloser(emptyReader{})
- }
- return io, nil
- }
- func (p *process) sendCloseStdin() error {
- _, err := p.client.remote.apiClient.UpdateProcess(context.Background(), &containerd.UpdateProcessRequest{
- Id: p.containerID,
- Pid: p.friendlyName,
- CloseStdin: true,
- })
- if err != nil && (strings.Contains(err.Error(), "container not found") || strings.Contains(err.Error(), "process not found")) {
- return nil
- }
- return err
- }
- func (p *process) closeFifos(io *IOPipe) {
- io.Stdin.Close()
- io.Stdout.Close()
- io.Stderr.Close()
- }
- type emptyReader struct{}
- func (r emptyReader) Read(b []byte) (int, error) {
- return 0, io.EOF
- }
- func (p *process) fifo(index int) string {
- return filepath.Join(p.dir, p.friendlyName+"-"+fdNames[index])
- }
|