github.com/jshiv/can-go@v0.2.1-0.20210224011015-069e90e90bdf/pkg/socketcan/fileconn.go (about) 1 package socketcan 2 3 import ( 4 "errors" 5 "net" 6 "os" 7 "time" 8 ) 9 10 // file is an interface for mocking file operations performed by fileConn. 11 type file interface { 12 Read([]byte) (int, error) 13 Write([]byte) (int, error) 14 SetDeadline(time.Time) error 15 SetReadDeadline(time.Time) error 16 SetWriteDeadline(time.Time) error 17 Close() error 18 } 19 20 // fileConn provides a net.Conn API for file-like types. 21 type fileConn struct { 22 // f is the file to provide a net.Conn API for. 23 f file 24 // net is the connection's network. 25 net string 26 // la is the connection's local address, if any. 27 la net.Addr 28 // ra is the connection's remote address, if any. 29 ra net.Addr 30 } 31 32 var _ net.Conn = &fileConn{} 33 34 func (c *fileConn) Read(b []byte) (int, error) { 35 n, err := c.f.Read(b) 36 if err != nil { 37 return n, &net.OpError{Op: "read", Net: c.net, Source: c.la, Addr: c.ra, Err: unwrapPathError(err)} 38 } 39 return n, nil 40 } 41 42 func (c *fileConn) Write(b []byte) (int, error) { 43 n, err := c.f.Write(b) 44 if err != nil { 45 return n, &net.OpError{Op: "write", Net: c.net, Source: c.la, Addr: c.ra, Err: unwrapPathError(err)} 46 } 47 return n, nil 48 } 49 50 func (c *fileConn) LocalAddr() net.Addr { 51 return c.la 52 } 53 54 func (c *fileConn) RemoteAddr() net.Addr { 55 return c.ra 56 } 57 58 func (c *fileConn) SetDeadline(t time.Time) error { 59 if err := c.f.SetDeadline(t); err != nil { 60 return &net.OpError{Op: "set deadline", Net: c.net, Source: c.la, Addr: c.ra, Err: unwrapPathError(err)} 61 } 62 return nil 63 } 64 65 func (c *fileConn) SetReadDeadline(t time.Time) error { 66 if err := c.f.SetReadDeadline(t); err != nil { 67 return &net.OpError{Op: "set read deadline", Net: c.net, Source: c.la, Addr: c.ra, Err: unwrapPathError(err)} 68 } 69 return nil 70 } 71 72 func (c *fileConn) SetWriteDeadline(t time.Time) error { 73 if err := c.f.SetWriteDeadline(t); err != nil { 74 return &net.OpError{Op: "set write deadline", Net: c.net, Source: c.la, Addr: c.ra, Err: unwrapPathError(err)} 75 } 76 return nil 77 } 78 79 func (c *fileConn) Close() error { 80 if err := c.f.Close(); err != nil { 81 return &net.OpError{Op: "close", Net: c.net, Source: c.la, Addr: c.ra, Err: unwrapPathError(err)} 82 } 83 return nil 84 } 85 86 // unwrapPathError unwraps one level of *os.PathError from the provided error. 87 func unwrapPathError(err error) error { 88 var pe *os.PathError 89 if errors.As(err, &pe) { 90 return pe.Err 91 } 92 return err 93 }