github.com/puellanivis/breton@v0.2.16/lib/files/socketfiles/unixsock.go (about) 1 package socketfiles 2 3 import ( 4 "context" 5 "errors" 6 "net" 7 "net/url" 8 "os" 9 10 "github.com/puellanivis/breton/lib/files" 11 ) 12 13 type unixHandler struct{} 14 15 func init() { 16 files.RegisterScheme(&unixHandler{}, "unix", "unixgram") 17 } 18 19 func (h *unixHandler) Open(ctx context.Context, uri *url.URL) (files.Reader, error) { 20 path := uri.Path 21 if path == "" { 22 path = uri.Opaque 23 } 24 network := uri.Scheme 25 26 laddr, err := net.ResolveUnixAddr(network, path) 27 if err != nil { 28 return nil, files.PathError("open", uri.String(), err) 29 } 30 31 switch laddr.Network() { 32 case "unixgram": 33 conn, err := net.ListenUnixgram(network, laddr) 34 if err != nil { 35 return nil, files.PathError("open", uri.String(), err) 36 } 37 38 sock, err := sockReader(conn, uri.Query()) 39 if err != nil { 40 conn.Close() 41 return nil, files.PathError("open", uri.String(), err) 42 } 43 44 return newDatagramReader(ctx, sock), nil 45 46 case "unix": 47 l, err := net.ListenUnix(network, laddr) 48 if err != nil { 49 return nil, files.PathError("open", uri.String(), err) 50 } 51 52 return newStreamReader(ctx, l) 53 } 54 55 return nil, files.PathError("create", uri.String(), errors.New("unknown unix socket type")) 56 } 57 58 func (h *unixHandler) Create(ctx context.Context, uri *url.URL) (files.Writer, error) { 59 path := uri.Path 60 if path == "" { 61 path = uri.Opaque 62 } 63 network := uri.Scheme 64 65 raddr, err := net.ResolveUnixAddr(network, path) 66 if err != nil { 67 return nil, err 68 } 69 70 q := uri.Query() 71 72 var laddr *net.UnixAddr 73 74 addr := q.Get(FieldLocalAddress) 75 if addr != "" { 76 laddr, err = net.ResolveUnixAddr(network, addr) 77 if err != nil { 78 return nil, files.PathError("create", uri.String(), err) 79 } 80 } 81 82 var conn *net.UnixConn 83 dial := func() error { 84 var err error 85 86 conn, err = net.DialUnix(network, laddr, raddr) 87 88 return err 89 } 90 91 if err := do(ctx, dial); err != nil { 92 return nil, files.PathError("create", uri.String(), err) 93 } 94 95 sock, err := sockWriter(conn, laddr != nil, q) 96 if err != nil { 97 conn.Close() 98 return nil, files.PathError("create", uri.String(), err) 99 } 100 101 switch network { 102 case "unix": 103 return newStreamWriter(ctx, sock), nil 104 105 case "unixgram", "unixpacket": 106 return newDatagramWriter(ctx, sock), nil 107 } 108 109 conn.Close() 110 return nil, files.PathError("create", uri.String(), errors.New("unknown unix socket type")) 111 } 112 113 func (h *unixHandler) List(ctx context.Context, uri *url.URL) ([]os.FileInfo, error) { 114 return nil, files.PathError("readdir", uri.String(), os.ErrInvalid) 115 }