Commit cc1d4b7e authored by Russ Cox's avatar Russ Cox

Unix domain socket support, Linux and Darwin.

R=r
DELTA=534  (353 added, 99 deleted, 82 changed)
OCL=28783
CL=28783
parent 533dfd62
This diff is collapsed.
......@@ -43,7 +43,6 @@ func v6ToSockaddr(p IP, port int) (sa1 *syscall.Sockaddr, err os.Error) {
return (*syscall.Sockaddr)(unsafe.Pointer(sa)), nil
}
func sockaddrToIP(sa1 *syscall.Sockaddr) (p IP, port int, err os.Error) {
switch sa1.Family {
case syscall.AF_INET:
......@@ -70,3 +69,32 @@ func listenBacklog() int64 {
return syscall.SOMAXCONN
}
func unixToSockaddr(name string) (sa1 *syscall.Sockaddr, err os.Error) {
sa := new(syscall.SockaddrUnix);
n := len(name);
if n >= len(sa.Path) || n == 0 {
return nil, os.EINVAL;
}
sa.Len = byte(3 + n); // 2 for Family, Len; 1 for NUL
sa.Family = syscall.AF_UNIX;
for i := 0; i < len(name); i++ {
sa.Path[i] = name[i];
}
return (*syscall.Sockaddr)(unsafe.Pointer(sa)), nil;
}
func sockaddrToUnix(sa1 *syscall.Sockaddr) (string, os.Error) {
if sa1.Family != syscall.AF_UNIX || sa1.Len < 3 || sa1.Len > syscall.SizeofSockaddrUnix {
return "", os.EINVAL;
}
sa := (*syscall.SockaddrUnix)(unsafe.Pointer(sa1));
n := int(sa.Len) - 3; // subtract leading Family, Len, terminating NUL
for i := 0; i < n; i++ {
if sa.Path[i] == 0 {
// found early NUL; assume Len is overestimating
n = i;
break;
}
}
return string(sa.Path[0:n]), nil;
}
......@@ -77,3 +77,47 @@ func listenBacklog() int64 {
return syscall.SOMAXCONN
}
func unixToSockaddr(name string) (sa1 *syscall.Sockaddr, err os.Error) {
sa := new(syscall.SockaddrUnix);
n := len(name);
if n >= len(sa.Path) || n == 0 {
return nil, os.EINVAL;
}
sa.Family = syscall.AF_UNIX;
for i := 0; i < len(name); i++ {
sa.Path[i] = name[i];
}
// Special case: @ in first position indicates
// an abstract socket, which has no file system
// representation and starts with a NUL byte
// when talking to the kernel about it.
if sa.Path[0] == '@' {
sa.Path[0] = 0;
}
return (*syscall.Sockaddr)(unsafe.Pointer(sa)), nil;
}
func sockaddrToUnix(sa1 *syscall.Sockaddr) (string, os.Error) {
if sa1.Family != syscall.AF_UNIX {
return "", os.EINVAL;
}
sa := (*syscall.SockaddrUnix)(unsafe.Pointer(sa1));
// @ special case (see comment in unixToSockaddr).
if sa.Path[0] == 0 {
// Not friendly to overwrite in place but
// okay in an internal function.
// The caller doesn't care if we do.
sa.Path[0] = '@';
}
// count length of path
n := 0;
for n < len(sa.Path) && sa.Path[n] != 0 {
n++;
}
return string(sa.Path[0:n]), nil;
}
......@@ -8,6 +8,7 @@ import (
"io";
"net";
"os";
"syscall";
"testing";
)
......@@ -83,3 +84,10 @@ func TestTcpServer(t *testing.T) {
doTest(t, "tcp", "0.0.0.0:9997", "[::ffff:127.0.0.1]:9997");
}
func TestUnixServer(t *testing.T) {
doTest(t, "unix", "/tmp/gotest.net", "/tmp/gotest.net");
if syscall.OS == "linux" {
// Test abstract unix domain socket, a Linux-ism
doTest(t, "unix", "@gotest/net", "@gotest/net");
}
}
......@@ -77,5 +77,7 @@ var (
EAGAIN Error = Errno(syscall.EAGAIN);
EDOM Error = Errno(syscall.EDOM);
ERANGE Error = Errno(syscall.ERANGE);
EADDRINUSE Error = Errno(syscall.EADDRINUSE);
ECONNREFUSED Error = Errno(syscall.ECONNREFUSED);
)
......@@ -16,11 +16,6 @@ import (
// creation of IPv6 sockets to return EAFNOSUPPORT.
var SocketDisableIPv6 bool
func SockaddrToSockaddrInet4(s *Sockaddr) *SockaddrInet4;
func SockaddrToSockaddrInet6(s *Sockaddr) *SockaddrInet6;
func SockaddrInet4ToSockaddr(s *SockaddrInet4) *Sockaddr;
func SockaddrInet6ToSockaddr(s *SockaddrInet6) *Sockaddr;
func Socket(domain, proto, typ int64) (ret int64, err int64) {
if domain == AF_INET6 && SocketDisableIPv6 {
return -1, EAFNOSUPPORT
......
......@@ -16,11 +16,6 @@ import (
// creation of IPv6 sockets to return EAFNOSUPPORT.
var SocketDisableIPv6 bool
func SockaddrToSockaddrInet4(s *Sockaddr) *SockaddrInet4;
func SockaddrToSockaddrInet6(s *Sockaddr) *SockaddrInet6;
func SockaddrInet4ToSockaddr(s *SockaddrInet4) *Sockaddr;
func SockaddrInet6ToSockaddr(s *SockaddrInet6) *Sockaddr;
func saLen(s *Sockaddr) int64 {
switch s.Family {
case AF_UNIX:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment