75 lines
		
	
	
		
			1.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			75 lines
		
	
	
		
			1.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
// +build !windows
 | 
						|
 | 
						|
package containerd
 | 
						|
 | 
						|
import (
 | 
						|
	"fmt"
 | 
						|
	"net"
 | 
						|
	"os"
 | 
						|
	"strings"
 | 
						|
	"syscall"
 | 
						|
	"time"
 | 
						|
 | 
						|
	"github.com/pkg/errors"
 | 
						|
)
 | 
						|
 | 
						|
func isNoent(err error) bool {
 | 
						|
	if err != nil {
 | 
						|
		if nerr, ok := err.(*net.OpError); ok {
 | 
						|
			if serr, ok := nerr.Err.(*os.SyscallError); ok {
 | 
						|
				if serr.Err == syscall.ENOENT {
 | 
						|
					return true
 | 
						|
				}
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return false
 | 
						|
}
 | 
						|
 | 
						|
type dialResult struct {
 | 
						|
	c   net.Conn
 | 
						|
	err error
 | 
						|
}
 | 
						|
 | 
						|
func Dialer(address string, timeout time.Duration) (net.Conn, error) {
 | 
						|
	var (
 | 
						|
		stopC = make(chan struct{})
 | 
						|
		synC  = make(chan *dialResult)
 | 
						|
	)
 | 
						|
	address = strings.TrimPrefix(address, "unix://")
 | 
						|
	go func() {
 | 
						|
		defer close(synC)
 | 
						|
		for {
 | 
						|
			select {
 | 
						|
			case <-stopC:
 | 
						|
				return
 | 
						|
			default:
 | 
						|
				c, err := net.DialTimeout("unix", address, timeout)
 | 
						|
				if isNoent(err) {
 | 
						|
					<-time.After(10 * time.Millisecond)
 | 
						|
					continue
 | 
						|
				}
 | 
						|
				synC <- &dialResult{c, err}
 | 
						|
				return
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}()
 | 
						|
	select {
 | 
						|
	case dr := <-synC:
 | 
						|
		return dr.c, dr.err
 | 
						|
	case <-time.After(timeout):
 | 
						|
		close(stopC)
 | 
						|
		go func() {
 | 
						|
			dr := <-synC
 | 
						|
			if dr != nil {
 | 
						|
				dr.c.Close()
 | 
						|
			}
 | 
						|
		}()
 | 
						|
		return nil, errors.Errorf("dial %s: no such file or directory", address)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func DialAddress(address string) string {
 | 
						|
	return fmt.Sprintf("unix://%s", address)
 | 
						|
}
 |