process_linux.go 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. package libcontainerd
  2. import (
  3. "io"
  4. "io/ioutil"
  5. "os"
  6. "path/filepath"
  7. "syscall"
  8. "time"
  9. containerd "github.com/docker/containerd/api/grpc/types"
  10. "github.com/tonistiigi/fifo"
  11. "golang.org/x/net/context"
  12. )
  13. var fdNames = map[int]string{
  14. syscall.Stdin: "stdin",
  15. syscall.Stdout: "stdout",
  16. syscall.Stderr: "stderr",
  17. }
  18. // process keeps the state for both main container process and exec process.
  19. type process struct {
  20. processCommon
  21. // Platform specific fields are below here.
  22. dir string
  23. }
  24. func (p *process) openFifos(terminal bool) (pipe *IOPipe, err error) {
  25. if err := os.MkdirAll(p.dir, 0700); err != nil {
  26. return nil, err
  27. }
  28. ctx, _ := context.WithTimeout(context.Background(), 15*time.Second)
  29. io := &IOPipe{}
  30. io.Stdin, err = fifo.OpenFifo(ctx, p.fifo(syscall.Stdin), syscall.O_WRONLY|syscall.O_CREAT|syscall.O_NONBLOCK, 0700)
  31. if err != nil {
  32. return nil, err
  33. }
  34. defer func() {
  35. if err != nil {
  36. io.Stdin.Close()
  37. }
  38. }()
  39. io.Stdout, err = fifo.OpenFifo(ctx, p.fifo(syscall.Stdout), syscall.O_RDONLY|syscall.O_CREAT|syscall.O_NONBLOCK, 0700)
  40. if err != nil {
  41. return nil, err
  42. }
  43. defer func() {
  44. if err != nil {
  45. io.Stdout.Close()
  46. }
  47. }()
  48. if !terminal {
  49. io.Stderr, err = fifo.OpenFifo(ctx, p.fifo(syscall.Stderr), syscall.O_RDONLY|syscall.O_CREAT|syscall.O_NONBLOCK, 0700)
  50. if err != nil {
  51. return nil, err
  52. }
  53. defer func() {
  54. if err != nil {
  55. io.Stderr.Close()
  56. }
  57. }()
  58. } else {
  59. io.Stderr = ioutil.NopCloser(emptyReader{})
  60. }
  61. return io, nil
  62. }
  63. func (p *process) sendCloseStdin() error {
  64. _, err := p.client.remote.apiClient.UpdateProcess(context.Background(), &containerd.UpdateProcessRequest{
  65. Id: p.containerID,
  66. Pid: p.friendlyName,
  67. CloseStdin: true,
  68. })
  69. return err
  70. }
  71. func (p *process) closeFifos(io *IOPipe) {
  72. io.Stdin.Close()
  73. io.Stdout.Close()
  74. io.Stderr.Close()
  75. }
  76. type emptyReader struct{}
  77. func (r emptyReader) Read(b []byte) (int, error) {
  78. return 0, io.EOF
  79. }
  80. func (p *process) fifo(index int) string {
  81. return filepath.Join(p.dir, p.friendlyName+"-"+fdNames[index])
  82. }