mirror of
https://github.com/zrepl/zrepl.git
synced 2024-11-25 09:54:47 +01:00
socketpair: directly export *net.UnixConn (and add test for that behavior)
This commit is contained in:
parent
76a6c623f3
commit
d281fb00e3
@ -1,42 +1,32 @@
|
|||||||
package socketpair
|
package socketpair
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"golang.org/x/sys/unix"
|
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
"golang.org/x/sys/unix"
|
||||||
)
|
)
|
||||||
type fileConn struct {
|
|
||||||
net.Conn // net.FileConn
|
|
||||||
f *os.File
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c fileConn) Close() error {
|
func SocketPair() (a, b *net.UnixConn, err error) {
|
||||||
if err := c.Conn.Close(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := c.f.Close(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func SocketPair() (a, b net.Conn, err error) {
|
|
||||||
// don't use net.Pipe, as it doesn't implement things like lingering, which our code relies on
|
// don't use net.Pipe, as it doesn't implement things like lingering, which our code relies on
|
||||||
sockpair, err := unix.Socketpair(unix.AF_UNIX, unix.SOCK_STREAM, 0)
|
sockpair, err := unix.Socketpair(unix.AF_UNIX, unix.SOCK_STREAM, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
toConn := func(fd int) (net.Conn, error) {
|
toConn := func(fd int) (*net.UnixConn, error) {
|
||||||
f := os.NewFile(uintptr(fd), "fileconn")
|
f := os.NewFile(uintptr(fd), "fileconn")
|
||||||
if f == nil {
|
if f == nil {
|
||||||
panic(fd)
|
panic(fd)
|
||||||
}
|
}
|
||||||
c, err := net.FileConn(f)
|
c, err := net.FileConn(f)
|
||||||
|
f.Close() // net.FileConn uses dup under the hood
|
||||||
if err != nil {
|
if err != nil {
|
||||||
f.Close()
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return fileConn{Conn: c, f: f}, nil
|
// strictly, the following type assertion is an implementation detail
|
||||||
|
// however, will be caught by test TestSocketPairWorks
|
||||||
|
fileConnIsUnixConn := c.(*net.UnixConn)
|
||||||
|
return fileConnIsUnixConn, nil
|
||||||
}
|
}
|
||||||
if a, err = toConn(sockpair[0]); err != nil { // shadowing
|
if a, err = toConn(sockpair[0]); err != nil { // shadowing
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
|
18
util/socketpair/socketpair_test.go
Normal file
18
util/socketpair/socketpair_test.go
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
package socketpair
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
// This is test is mostly to verify that the assumption about
|
||||||
|
// net.FileConn returning *net.UnixConn for AF_UNIX FDs works.
|
||||||
|
func TestSocketPairWorks(t *testing.T) {
|
||||||
|
assert.NotPanics(t, func() {
|
||||||
|
a, b, err := SocketPair()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
a.Close()
|
||||||
|
b.Close()
|
||||||
|
})
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user