/
unix_domain.go
137 lines (120 loc) · 3.53 KB
/
unix_domain.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
package thrift_unix_domain
import (
"net"
"time"
"git.apache.org/thrift.git/lib/go/thrift"
)
type TUnixDomain struct {
conn net.Conn
addr net.Addr
timeout time.Duration
}
// New creates a net.Conn-backed TTransport, given a unix domain file path
//
// Example:
// trans, err := thrift.New("/tmp/thrift.sock")
func NewTUnixDomain(sockFile string) (*TUnixDomain, error) {
return NewTUnixDomainTimeout(sockFile, 0)
}
// NewTSocketTimeout creates a net.Conn-backed TTransport, given a unix domain file path
// it also accepts a timeout as a time.Duration
func NewTUnixDomainTimeout(sockFile string, timeout time.Duration) (*TUnixDomain, error) {
//conn, err := net.DialTimeout(network, address, timeout)
addr, err := net.ResolveUnixAddr("unix", sockFile)
if err != nil {
return nil, err
}
return NewTFromAddrTimeout(addr, timeout), nil
}
// Creates a TUnixDomain from a net.Addr
func NewTFromAddrTimeout(addr net.Addr, timeout time.Duration) *TUnixDomain {
return &TUnixDomain{addr: addr, timeout: timeout}
}
// Sets the socket timeout
func (p *TUnixDomain) SetTimeout(timeout time.Duration) error {
p.timeout = timeout
return nil
}
func (p *TUnixDomain) pushDeadline(read, write bool) {
var t time.Time
if p.timeout > 0 {
t = time.Now().Add(time.Duration(p.timeout))
}
if read && write {
p.conn.SetDeadline(t)
} else if read {
p.conn.SetReadDeadline(t)
} else if write {
p.conn.SetWriteDeadline(t)
}
}
// Connects the socket, creating a new socket object if necessary.
func (p *TUnixDomain) Open() error {
if p.IsOpen() {
return thrift.NewTTransportException(thrift.ALREADY_OPEN, "Socket already connected.")
}
if p.addr == nil {
return thrift.NewTTransportException(thrift.NOT_OPEN, "Cannot open nil address.")
}
if len(p.addr.Network()) == 0 {
return thrift.NewTTransportException(thrift.NOT_OPEN, "Cannot open bad network name.")
}
if len(p.addr.String()) == 0 {
return thrift.NewTTransportException(thrift.NOT_OPEN, "Cannot open bad address.")
}
var err error
if p.conn, err = net.DialTimeout(p.addr.Network(), p.addr.String(), p.timeout); err != nil {
return thrift.NewTTransportException(thrift.NOT_OPEN, err.Error())
}
return nil
}
// Retreive the underlying net.Conn
func (p *TUnixDomain) Conn() net.Conn {
return p.conn
}
// Returns true if the connection is open
func (p *TUnixDomain) IsOpen() bool {
if p.conn == nil {
return false
}
return true
}
// Closes the socket.
func (p *TUnixDomain) Close() error {
// Close the socket
if p.conn != nil {
err := p.conn.Close()
if err != nil {
return err
}
p.conn = nil
}
return nil
}
func (p *TUnixDomain) Read(buf []byte) (int, error) {
if !p.IsOpen() {
return 0, thrift.NewTTransportException(thrift.NOT_OPEN, "Connection not open")
}
p.pushDeadline(true, false)
n, err := p.conn.Read(buf)
return n, thrift.NewTTransportExceptionFromError(err)
}
func (p *TUnixDomain) Write(buf []byte) (int, error) {
if !p.IsOpen() {
return 0, thrift.NewTTransportException(thrift.NOT_OPEN, "Connection not open")
}
p.pushDeadline(false, true)
return p.conn.Write(buf)
}
func (p *TUnixDomain) Peek() bool {
return p.IsOpen()
}
func (p *TUnixDomain) Flush() error {
return nil
}
func (p *TUnixDomain) Interrupt() error {
if !p.IsOpen() {
return nil
}
return p.conn.Close()
}