// +build !windows package containerd import ( "context" "io" "io/ioutil" "os" "path/filepath" "sync" "syscall" "github.com/containerd/fifo" ) // NewFifos returns a new set of fifos for the task func NewFifos(id string) (*FIFOSet, error) { root := filepath.Join(os.TempDir(), "containerd") if err := os.MkdirAll(root, 0700); err != nil { return nil, err } dir, err := ioutil.TempDir(root, "") if err != nil { return nil, err } return &FIFOSet{ Dir: dir, In: filepath.Join(dir, id+"-stdin"), Out: filepath.Join(dir, id+"-stdout"), Err: filepath.Join(dir, id+"-stderr"), }, nil } func copyIO(fifos *FIFOSet, ioset *ioSet, tty bool) (_ *wgCloser, err error) { var ( f io.ReadWriteCloser set []io.Closer ctx, cancel = context.WithCancel(context.Background()) wg = &sync.WaitGroup{} ) defer func() { if err != nil { for _, f := range set { f.Close() } cancel() } }() if f, err = fifo.OpenFifo(ctx, fifos.In, syscall.O_WRONLY|syscall.O_CREAT|syscall.O_NONBLOCK, 0700); err != nil { return nil, err } set = append(set, f) go func(w io.WriteCloser) { io.Copy(w, ioset.in) w.Close() }(f) if f, err = fifo.OpenFifo(ctx, fifos.Out, syscall.O_RDONLY|syscall.O_CREAT|syscall.O_NONBLOCK, 0700); err != nil { return nil, err } set = append(set, f) wg.Add(1) go func(r io.ReadCloser) { io.Copy(ioset.out, r) r.Close() wg.Done() }(f) if f, err = fifo.OpenFifo(ctx, fifos.Err, syscall.O_RDONLY|syscall.O_CREAT|syscall.O_NONBLOCK, 0700); err != nil { return nil, err } set = append(set, f) if !tty { wg.Add(1) go func(r io.ReadCloser) { io.Copy(ioset.err, r) r.Close() wg.Done() }(f) } return &wgCloser{ wg: wg, dir: fifos.Dir, set: set, cancel: cancel, }, nil }