Make sure we wait for the client side copy goroutines to start coping from the fifos before returning from the function. Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
		
			
				
	
	
		
			101 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			101 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
// +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
 | 
						|
		cwg         sync.WaitGroup
 | 
						|
		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)
 | 
						|
	cwg.Add(1)
 | 
						|
	wg.Add(1)
 | 
						|
	go func(w io.WriteCloser) {
 | 
						|
		cwg.Done()
 | 
						|
		io.Copy(w, ioset.in)
 | 
						|
		w.Close()
 | 
						|
		wg.Done()
 | 
						|
	}(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)
 | 
						|
	cwg.Add(1)
 | 
						|
	go func(r io.ReadCloser) {
 | 
						|
		cwg.Done()
 | 
						|
		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)
 | 
						|
		cwg.Add(1)
 | 
						|
		go func(r io.ReadCloser) {
 | 
						|
			cwg.Done()
 | 
						|
			io.Copy(ioset.err, r)
 | 
						|
			r.Close()
 | 
						|
			wg.Done()
 | 
						|
		}(f)
 | 
						|
	}
 | 
						|
	cwg.Wait()
 | 
						|
	return &wgCloser{
 | 
						|
		wg:     wg,
 | 
						|
		dir:    fifos.Dir,
 | 
						|
		set:    set,
 | 
						|
		cancel: cancel,
 | 
						|
	}, nil
 | 
						|
}
 |