Skip to content

Commit 05e2da1

Browse files
committed
implement pipe to conn adapter
1 parent 242380c commit 05e2da1

File tree

1 file changed

+121
-0
lines changed

1 file changed

+121
-0
lines changed

dialer/pipewrap.go

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
package dialer
2+
3+
import (
4+
"fmt"
5+
"io"
6+
"net"
7+
"sync"
8+
"time"
9+
10+
"github.com/hashicorp/go-multierror"
11+
)
12+
13+
type ReadPipe interface {
14+
io.Reader
15+
io.WriterTo
16+
io.Closer
17+
Fd() uintptr
18+
SetReadDeadline(t time.Time) error
19+
}
20+
21+
type WritePipe interface {
22+
io.Writer
23+
io.ReaderFrom
24+
io.Closer
25+
Fd() uintptr
26+
SetWriteDeadline(t time.Time) error
27+
}
28+
29+
type PipeAddr struct {
30+
rfd uintptr
31+
wfd uintptr
32+
}
33+
34+
func (_ PipeAddr) Network() string {
35+
return "pipe"
36+
}
37+
38+
func (a PipeAddr) String() string {
39+
return fmt.Sprintf("<read fd: %d, write rd: %d>", a.rfd, a.wfd)
40+
}
41+
42+
type PipeConn struct {
43+
r ReadPipe
44+
w WritePipe
45+
rc sync.Once
46+
wc sync.Once
47+
}
48+
49+
func NewPipeConn(r ReadPipe, w WritePipe) *PipeConn {
50+
return &PipeConn{
51+
r: r,
52+
w: w,
53+
}
54+
}
55+
56+
func (c *PipeConn) Read(p []byte) (n int, err error) {
57+
return c.r.Read(p)
58+
}
59+
60+
func (c *PipeConn) Write(p []byte) (n int, err error) {
61+
return c.w.Write(p)
62+
}
63+
64+
func (c *PipeConn) Close() error {
65+
var err error
66+
if closeErr := c.CloseWrite(); closeErr != nil {
67+
err = multierror.Append(err, closeErr)
68+
}
69+
if closeErr := c.CloseRead(); closeErr != nil {
70+
err = multierror.Append(err, closeErr)
71+
}
72+
return err
73+
}
74+
75+
func (c *PipeConn) CloseWrite() error {
76+
var err error
77+
c.wc.Do(func() {
78+
err = c.w.Close()
79+
})
80+
return err
81+
}
82+
83+
func (c *PipeConn) CloseRead() error {
84+
var err error
85+
c.wc.Do(func() {
86+
err = c.r.Close()
87+
})
88+
return err
89+
}
90+
91+
func (c *PipeConn) LocalAddr() net.Addr {
92+
return PipeAddr{
93+
rfd: c.r.Fd(),
94+
wfd: c.w.Fd(),
95+
}
96+
}
97+
98+
func (c *PipeConn) RemoteAddr() net.Addr {
99+
return c.LocalAddr()
100+
}
101+
102+
func (c *PipeConn) SetReadDeadline(t time.Time) error {
103+
return c.r.SetReadDeadline(t)
104+
}
105+
106+
func (c *PipeConn) SetWriteDeadline(t time.Time) error {
107+
return c.w.SetWriteDeadline(t)
108+
}
109+
110+
func (c *PipeConn) SetDeadline(t time.Time) error {
111+
var err error
112+
if cErr := c.SetReadDeadline(t); err != nil {
113+
err = multierror.Append(err, cErr)
114+
}
115+
if cErr := c.SetWriteDeadline(t); err != nil {
116+
err = multierror.Append(err, cErr)
117+
}
118+
return err
119+
}
120+
121+
var _ net.Conn = new(PipeConn)

0 commit comments

Comments
 (0)