2011-03-25 14:42:25 -04:00
|
|
|
// Copyright 2011 The Go Authors. All rights reserved.
|
|
|
|
|
// Use of this source code is governed by a BSD-style
|
|
|
|
|
// license that can be found in the LICENSE file.
|
|
|
|
|
|
2014-09-18 19:17:55 +09:00
|
|
|
// +build darwin dragonfly freebsd linux netbsd openbsd solaris
|
build: add build comments to core packages
The go/build package already recognizes
system-specific file names like
mycode_darwin.go
mycode_darwin_386.go
mycode_386.s
However, it is also common to write files that
apply to multiple architectures, so a recent CL added
to go/build the ability to process comments
listing a set of conditions for building. For example:
// +build darwin freebsd openbsd/386
says that this file should be compiled only on
OS X, FreeBSD, or 32-bit x86 OpenBSD systems.
These conventions are not yet documented
(hence this long CL description).
This CL adds build comments to the multi-system
files in the core library, a step toward making it
possible to use go/build to build them.
With this change go/build can handle crypto/rand,
exec, net, path/filepath, os/user, and time.
os and syscall need additional adjustments.
R=golang-dev, r, gri, r, gustavo
CC=golang-dev
https://golang.org/cl/5011046
2011-09-15 16:48:57 -04:00
|
|
|
|
2011-03-25 14:42:25 -04:00
|
|
|
package net
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"os"
|
|
|
|
|
"syscall"
|
|
|
|
|
)
|
|
|
|
|
|
net, internal/syscall/unix: add SocketConn, SocketPacketConn
FileConn and FilePacketConn APIs accept user-configured socket
descriptors to make them work together with runtime-integrated network
poller, but there's a limitation. The APIs reject protocol sockets that
are not supported by standard library. It's very hard for the net,
syscall packages to look after all platform, feature-specific sockets.
This change allows various platform, feature-specific socket descriptors
to use runtime-integrated network poller by using SocketConn,
SocketPacketConn APIs that bridge between the net, syscall packages and
platforms.
New exposed APIs:
pkg net, func SocketConn(*os.File, SocketAddr) (Conn, error)
pkg net, func SocketPacketConn(*os.File, SocketAddr) (PacketConn, error)
pkg net, type SocketAddr interface { Addr, Raw }
pkg net, type SocketAddr interface, Addr([]uint8) Addr
pkg net, type SocketAddr interface, Raw(Addr) []uint8
Fixes #10565.
Change-Id: Iec57499b3d84bb5cb0bcf3f664330c535eec11e3
Reviewed-on: https://go-review.googlesource.com/9275
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2015-04-23 23:57:00 +09:00
|
|
|
func dupSocket(f *os.File) (int, error) {
|
|
|
|
|
s, err := dupCloseOnExec(int(f.Fd()))
|
2012-02-01 00:36:45 +09:00
|
|
|
if err != nil {
|
net, internal/syscall/unix: add SocketConn, SocketPacketConn
FileConn and FilePacketConn APIs accept user-configured socket
descriptors to make them work together with runtime-integrated network
poller, but there's a limitation. The APIs reject protocol sockets that
are not supported by standard library. It's very hard for the net,
syscall packages to look after all platform, feature-specific sockets.
This change allows various platform, feature-specific socket descriptors
to use runtime-integrated network poller by using SocketConn,
SocketPacketConn APIs that bridge between the net, syscall packages and
platforms.
New exposed APIs:
pkg net, func SocketConn(*os.File, SocketAddr) (Conn, error)
pkg net, func SocketPacketConn(*os.File, SocketAddr) (PacketConn, error)
pkg net, type SocketAddr interface { Addr, Raw }
pkg net, type SocketAddr interface, Addr([]uint8) Addr
pkg net, type SocketAddr interface, Raw(Addr) []uint8
Fixes #10565.
Change-Id: Iec57499b3d84bb5cb0bcf3f664330c535eec11e3
Reviewed-on: https://go-review.googlesource.com/9275
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2015-04-23 23:57:00 +09:00
|
|
|
return -1, err
|
2011-03-25 14:42:25 -04:00
|
|
|
}
|
net, internal/syscall/unix: add SocketConn, SocketPacketConn
FileConn and FilePacketConn APIs accept user-configured socket
descriptors to make them work together with runtime-integrated network
poller, but there's a limitation. The APIs reject protocol sockets that
are not supported by standard library. It's very hard for the net,
syscall packages to look after all platform, feature-specific sockets.
This change allows various platform, feature-specific socket descriptors
to use runtime-integrated network poller by using SocketConn,
SocketPacketConn APIs that bridge between the net, syscall packages and
platforms.
New exposed APIs:
pkg net, func SocketConn(*os.File, SocketAddr) (Conn, error)
pkg net, func SocketPacketConn(*os.File, SocketAddr) (PacketConn, error)
pkg net, type SocketAddr interface { Addr, Raw }
pkg net, type SocketAddr interface, Addr([]uint8) Addr
pkg net, type SocketAddr interface, Raw(Addr) []uint8
Fixes #10565.
Change-Id: Iec57499b3d84bb5cb0bcf3f664330c535eec11e3
Reviewed-on: https://go-review.googlesource.com/9275
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2015-04-23 23:57:00 +09:00
|
|
|
if err := syscall.SetNonblock(s, true); err != nil {
|
|
|
|
|
closeFunc(s)
|
|
|
|
|
return -1, os.NewSyscallError("setnonblock", err)
|
2013-01-28 08:54:15 -08:00
|
|
|
}
|
net, internal/syscall/unix: add SocketConn, SocketPacketConn
FileConn and FilePacketConn APIs accept user-configured socket
descriptors to make them work together with runtime-integrated network
poller, but there's a limitation. The APIs reject protocol sockets that
are not supported by standard library. It's very hard for the net,
syscall packages to look after all platform, feature-specific sockets.
This change allows various platform, feature-specific socket descriptors
to use runtime-integrated network poller by using SocketConn,
SocketPacketConn APIs that bridge between the net, syscall packages and
platforms.
New exposed APIs:
pkg net, func SocketConn(*os.File, SocketAddr) (Conn, error)
pkg net, func SocketPacketConn(*os.File, SocketAddr) (PacketConn, error)
pkg net, type SocketAddr interface { Addr, Raw }
pkg net, type SocketAddr interface, Addr([]uint8) Addr
pkg net, type SocketAddr interface, Raw(Addr) []uint8
Fixes #10565.
Change-Id: Iec57499b3d84bb5cb0bcf3f664330c535eec11e3
Reviewed-on: https://go-review.googlesource.com/9275
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2015-04-23 23:57:00 +09:00
|
|
|
return s, nil
|
|
|
|
|
}
|
2011-03-25 14:42:25 -04:00
|
|
|
|
2015-07-02 15:02:03 +09:00
|
|
|
func newFileFD(f *os.File) (*netFD, error) {
|
net, internal/syscall/unix: add SocketConn, SocketPacketConn
FileConn and FilePacketConn APIs accept user-configured socket
descriptors to make them work together with runtime-integrated network
poller, but there's a limitation. The APIs reject protocol sockets that
are not supported by standard library. It's very hard for the net,
syscall packages to look after all platform, feature-specific sockets.
This change allows various platform, feature-specific socket descriptors
to use runtime-integrated network poller by using SocketConn,
SocketPacketConn APIs that bridge between the net, syscall packages and
platforms.
New exposed APIs:
pkg net, func SocketConn(*os.File, SocketAddr) (Conn, error)
pkg net, func SocketPacketConn(*os.File, SocketAddr) (PacketConn, error)
pkg net, type SocketAddr interface { Addr, Raw }
pkg net, type SocketAddr interface, Addr([]uint8) Addr
pkg net, type SocketAddr interface, Raw(Addr) []uint8
Fixes #10565.
Change-Id: Iec57499b3d84bb5cb0bcf3f664330c535eec11e3
Reviewed-on: https://go-review.googlesource.com/9275
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2015-04-23 23:57:00 +09:00
|
|
|
s, err := dupSocket(f)
|
2012-02-01 00:36:45 +09:00
|
|
|
if err != nil {
|
net, internal/syscall/unix: add SocketConn, SocketPacketConn
FileConn and FilePacketConn APIs accept user-configured socket
descriptors to make them work together with runtime-integrated network
poller, but there's a limitation. The APIs reject protocol sockets that
are not supported by standard library. It's very hard for the net,
syscall packages to look after all platform, feature-specific sockets.
This change allows various platform, feature-specific socket descriptors
to use runtime-integrated network poller by using SocketConn,
SocketPacketConn APIs that bridge between the net, syscall packages and
platforms.
New exposed APIs:
pkg net, func SocketConn(*os.File, SocketAddr) (Conn, error)
pkg net, func SocketPacketConn(*os.File, SocketAddr) (PacketConn, error)
pkg net, type SocketAddr interface { Addr, Raw }
pkg net, type SocketAddr interface, Addr([]uint8) Addr
pkg net, type SocketAddr interface, Raw(Addr) []uint8
Fixes #10565.
Change-Id: Iec57499b3d84bb5cb0bcf3f664330c535eec11e3
Reviewed-on: https://go-review.googlesource.com/9275
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2015-04-23 23:57:00 +09:00
|
|
|
return nil, err
|
2011-03-25 14:42:25 -04:00
|
|
|
}
|
2015-07-02 15:02:03 +09:00
|
|
|
family := syscall.AF_UNSPEC
|
|
|
|
|
sotype, err := syscall.GetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_TYPE)
|
|
|
|
|
if err != nil {
|
|
|
|
|
closeFunc(s)
|
|
|
|
|
return nil, os.NewSyscallError("getsockopt", err)
|
|
|
|
|
}
|
|
|
|
|
lsa, _ := syscall.Getsockname(s)
|
|
|
|
|
rsa, _ := syscall.Getpeername(s)
|
|
|
|
|
switch lsa.(type) {
|
|
|
|
|
case *syscall.SockaddrInet4:
|
|
|
|
|
family = syscall.AF_INET
|
|
|
|
|
case *syscall.SockaddrInet6:
|
|
|
|
|
family = syscall.AF_INET6
|
|
|
|
|
case *syscall.SockaddrUnix:
|
|
|
|
|
family = syscall.AF_UNIX
|
|
|
|
|
default:
|
|
|
|
|
closeFunc(s)
|
|
|
|
|
return nil, syscall.EPROTONOSUPPORT
|
2011-03-25 14:42:25 -04:00
|
|
|
}
|
2015-07-02 15:02:03 +09:00
|
|
|
fd, err := newFD(s, family, sotype, "")
|
2012-02-01 00:36:45 +09:00
|
|
|
if err != nil {
|
net, internal/syscall/unix: add SocketConn, SocketPacketConn
FileConn and FilePacketConn APIs accept user-configured socket
descriptors to make them work together with runtime-integrated network
poller, but there's a limitation. The APIs reject protocol sockets that
are not supported by standard library. It's very hard for the net,
syscall packages to look after all platform, feature-specific sockets.
This change allows various platform, feature-specific socket descriptors
to use runtime-integrated network poller by using SocketConn,
SocketPacketConn APIs that bridge between the net, syscall packages and
platforms.
New exposed APIs:
pkg net, func SocketConn(*os.File, SocketAddr) (Conn, error)
pkg net, func SocketPacketConn(*os.File, SocketAddr) (PacketConn, error)
pkg net, type SocketAddr interface { Addr, Raw }
pkg net, type SocketAddr interface, Addr([]uint8) Addr
pkg net, type SocketAddr interface, Raw(Addr) []uint8
Fixes #10565.
Change-Id: Iec57499b3d84bb5cb0bcf3f664330c535eec11e3
Reviewed-on: https://go-review.googlesource.com/9275
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2015-04-23 23:57:00 +09:00
|
|
|
closeFunc(s)
|
2011-03-28 23:40:01 -04:00
|
|
|
return nil, err
|
|
|
|
|
}
|
2015-07-02 15:02:03 +09:00
|
|
|
laddr := fd.addrFunc()(lsa)
|
|
|
|
|
raddr := fd.addrFunc()(rsa)
|
|
|
|
|
fd.net = laddr.Network()
|
net, internal/syscall/unix: add SocketConn, SocketPacketConn
FileConn and FilePacketConn APIs accept user-configured socket
descriptors to make them work together with runtime-integrated network
poller, but there's a limitation. The APIs reject protocol sockets that
are not supported by standard library. It's very hard for the net,
syscall packages to look after all platform, feature-specific sockets.
This change allows various platform, feature-specific socket descriptors
to use runtime-integrated network poller by using SocketConn,
SocketPacketConn APIs that bridge between the net, syscall packages and
platforms.
New exposed APIs:
pkg net, func SocketConn(*os.File, SocketAddr) (Conn, error)
pkg net, func SocketPacketConn(*os.File, SocketAddr) (PacketConn, error)
pkg net, type SocketAddr interface { Addr, Raw }
pkg net, type SocketAddr interface, Addr([]uint8) Addr
pkg net, type SocketAddr interface, Raw(Addr) []uint8
Fixes #10565.
Change-Id: Iec57499b3d84bb5cb0bcf3f664330c535eec11e3
Reviewed-on: https://go-review.googlesource.com/9275
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2015-04-23 23:57:00 +09:00
|
|
|
if err := fd.init(); err != nil {
|
|
|
|
|
fd.Close()
|
2013-08-06 23:42:33 +09:00
|
|
|
return nil, err
|
|
|
|
|
}
|
net, internal/syscall/unix: add SocketConn, SocketPacketConn
FileConn and FilePacketConn APIs accept user-configured socket
descriptors to make them work together with runtime-integrated network
poller, but there's a limitation. The APIs reject protocol sockets that
are not supported by standard library. It's very hard for the net,
syscall packages to look after all platform, feature-specific sockets.
This change allows various platform, feature-specific socket descriptors
to use runtime-integrated network poller by using SocketConn,
SocketPacketConn APIs that bridge between the net, syscall packages and
platforms.
New exposed APIs:
pkg net, func SocketConn(*os.File, SocketAddr) (Conn, error)
pkg net, func SocketPacketConn(*os.File, SocketAddr) (PacketConn, error)
pkg net, type SocketAddr interface { Addr, Raw }
pkg net, type SocketAddr interface, Addr([]uint8) Addr
pkg net, type SocketAddr interface, Raw(Addr) []uint8
Fixes #10565.
Change-Id: Iec57499b3d84bb5cb0bcf3f664330c535eec11e3
Reviewed-on: https://go-review.googlesource.com/9275
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2015-04-23 23:57:00 +09:00
|
|
|
fd.setAddr(laddr, raddr)
|
|
|
|
|
return fd, nil
|
2011-03-25 14:42:25 -04:00
|
|
|
}
|
|
|
|
|
|
2015-04-18 16:53:55 +09:00
|
|
|
func fileConn(f *os.File) (Conn, error) {
|
2015-07-02 15:02:03 +09:00
|
|
|
fd, err := newFileFD(f)
|
2011-03-25 14:42:25 -04:00
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
switch fd.laddr.(type) {
|
|
|
|
|
case *TCPAddr:
|
|
|
|
|
return newTCPConn(fd), nil
|
|
|
|
|
case *UDPAddr:
|
|
|
|
|
return newUDPConn(fd), nil
|
|
|
|
|
case *IPAddr:
|
|
|
|
|
return newIPConn(fd), nil
|
2012-08-23 20:54:00 +09:00
|
|
|
case *UnixAddr:
|
|
|
|
|
return newUnixConn(fd), nil
|
2011-03-25 14:42:25 -04:00
|
|
|
}
|
|
|
|
|
fd.Close()
|
2012-02-17 10:04:29 +11:00
|
|
|
return nil, syscall.EINVAL
|
2011-03-25 14:42:25 -04:00
|
|
|
}
|
|
|
|
|
|
2015-04-18 16:53:55 +09:00
|
|
|
func fileListener(f *os.File) (Listener, error) {
|
2015-07-02 15:02:03 +09:00
|
|
|
fd, err := newFileFD(f)
|
2011-03-25 14:42:25 -04:00
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
switch laddr := fd.laddr.(type) {
|
|
|
|
|
case *TCPAddr:
|
|
|
|
|
return &TCPListener{fd}, nil
|
|
|
|
|
case *UnixAddr:
|
2015-12-05 01:15:26 -05:00
|
|
|
return &UnixListener{fd: fd, path: laddr.Name, unlink: false}, nil
|
2011-03-25 14:42:25 -04:00
|
|
|
}
|
|
|
|
|
fd.Close()
|
2012-02-17 10:04:29 +11:00
|
|
|
return nil, syscall.EINVAL
|
2011-03-25 14:42:25 -04:00
|
|
|
}
|
|
|
|
|
|
2015-04-18 16:53:55 +09:00
|
|
|
func filePacketConn(f *os.File) (PacketConn, error) {
|
2015-07-02 15:02:03 +09:00
|
|
|
fd, err := newFileFD(f)
|
2011-03-25 14:42:25 -04:00
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
switch fd.laddr.(type) {
|
|
|
|
|
case *UDPAddr:
|
|
|
|
|
return newUDPConn(fd), nil
|
2014-01-28 03:18:27 -08:00
|
|
|
case *IPAddr:
|
|
|
|
|
return newIPConn(fd), nil
|
2011-03-25 14:42:25 -04:00
|
|
|
case *UnixAddr:
|
|
|
|
|
return newUnixConn(fd), nil
|
|
|
|
|
}
|
|
|
|
|
fd.Close()
|
2012-02-17 10:04:29 +11:00
|
|
|
return nil, syscall.EINVAL
|
2011-03-25 14:42:25 -04:00
|
|
|
}
|