gitee.com/bomy/docker.git@v1.13.1/libcontainerd/process_unix.go (about) 1 // +build linux solaris 2 3 package libcontainerd 4 5 import ( 6 "io" 7 "io/ioutil" 8 "os" 9 "path/filepath" 10 goruntime "runtime" 11 "strings" 12 13 containerd "github.com/docker/containerd/api/grpc/types" 14 "github.com/tonistiigi/fifo" 15 "golang.org/x/net/context" 16 "golang.org/x/sys/unix" 17 ) 18 19 var fdNames = map[int]string{ 20 unix.Stdin: "stdin", 21 unix.Stdout: "stdout", 22 unix.Stderr: "stderr", 23 } 24 25 // process keeps the state for both main container process and exec process. 26 type process struct { 27 processCommon 28 29 // Platform specific fields are below here. 30 dir string 31 } 32 33 func (p *process) openFifos(ctx context.Context, terminal bool) (pipe *IOPipe, err error) { 34 if err := os.MkdirAll(p.dir, 0700); err != nil { 35 return nil, err 36 } 37 38 io := &IOPipe{} 39 40 io.Stdin, err = fifo.OpenFifo(ctx, p.fifo(unix.Stdin), unix.O_WRONLY|unix.O_CREAT|unix.O_NONBLOCK, 0700) 41 if err != nil { 42 return nil, err 43 } 44 45 defer func() { 46 if err != nil { 47 io.Stdin.Close() 48 } 49 }() 50 51 io.Stdout, err = fifo.OpenFifo(ctx, p.fifo(unix.Stdout), unix.O_RDONLY|unix.O_CREAT|unix.O_NONBLOCK, 0700) 52 if err != nil { 53 return nil, err 54 } 55 56 defer func() { 57 if err != nil { 58 io.Stdout.Close() 59 } 60 }() 61 62 if goruntime.GOOS == "solaris" || !terminal { 63 // For Solaris terminal handling is done exclusively by the runtime therefore we make no distinction 64 // in the processing for terminal and !terminal cases. 65 io.Stderr, err = fifo.OpenFifo(ctx, p.fifo(unix.Stderr), unix.O_RDONLY|unix.O_CREAT|unix.O_NONBLOCK, 0700) 66 if err != nil { 67 return nil, err 68 } 69 defer func() { 70 if err != nil { 71 io.Stderr.Close() 72 } 73 }() 74 } else { 75 io.Stderr = ioutil.NopCloser(emptyReader{}) 76 } 77 78 return io, nil 79 } 80 81 func (p *process) sendCloseStdin() error { 82 _, err := p.client.remote.apiClient.UpdateProcess(context.Background(), &containerd.UpdateProcessRequest{ 83 Id: p.containerID, 84 Pid: p.friendlyName, 85 CloseStdin: true, 86 }) 87 if err != nil && (strings.Contains(err.Error(), "container not found") || strings.Contains(err.Error(), "process not found")) { 88 return nil 89 } 90 return err 91 } 92 93 func (p *process) closeFifos(io *IOPipe) { 94 io.Stdin.Close() 95 io.Stdout.Close() 96 io.Stderr.Close() 97 } 98 99 type emptyReader struct{} 100 101 func (r emptyReader) Read(b []byte) (int, error) { 102 return 0, io.EOF 103 } 104 105 func (p *process) fifo(index int) string { 106 return filepath.Join(p.dir, p.friendlyName+"-"+fdNames[index]) 107 }