1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 // +build darwin dragonfly freebsd linux netbsd openbsd solaris
23 darwin64Bit = runtime.GOOS == "darwin" && sizeofPtr == 8
24 dragonfly64Bit = runtime.GOOS == "dragonfly" && sizeofPtr == 8
25 netbsd32Bit = runtime.GOOS == "netbsd" && sizeofPtr == 4
28 // Do the interface allocations only once for common
31 errEAGAIN error = syscall.EAGAIN
32 errEINVAL error = syscall.EINVAL
33 errENOENT error = syscall.ENOENT
36 // errnoErr returns common boxed Errno values, to prevent
37 // allocations at runtime.
38 func errnoErr(e syscall.Errno) error {
52 func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno)
53 func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno)
54 func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno)
55 func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno)
57 // Mmap manager, for use by operating system-specific implementations.
61 active map[*byte][]byte // active mappings; key is last byte in mapping
62 mmap func(addr, length uintptr, prot, flags, fd int, offset int64) (uintptr, error)
63 munmap func(addr uintptr, length uintptr) error
66 func (m *mmapper) Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
71 // Map the requested memory.
72 addr, errno := m.mmap(0, uintptr(length), prot, flags, fd, offset)
77 // Slice memory layout
82 }{addr, length, length}
84 // Use unsafe to turn sl into a []byte.
85 b := *(*[]byte)(unsafe.Pointer(&sl))
87 // Register mapping in m and return it.
95 func (m *mmapper) Munmap(data []byte) (err error) {
96 if len(data) == 0 || len(data) != cap(data) {
100 // Find the base of the mapping.
101 p := &data[cap(data)-1]
105 if b == nil || &b[0] != &data[0] {
109 // Unmap the memory and update m.
110 if errno := m.munmap(uintptr(unsafe.Pointer(&b[0])), uintptr(len(b))); errno != nil {
117 func Read(fd int, p []byte) (n int, err error) {
121 raceWriteRange(unsafe.Pointer(&p[0]), n)
124 raceAcquire(unsafe.Pointer(&ioSync))
130 func Write(fd int, p []byte) (n int, err error) {
132 raceReleaseMerge(unsafe.Pointer(&ioSync))
134 n, err = write(fd, p)
135 if raceenabled && n > 0 {
136 raceReadRange(unsafe.Pointer(&p[0]), n)
141 // For testing: clients can set this flag to force
142 // creation of IPv6 sockets to return EAFNOSUPPORT.
143 var SocketDisableIPv6 bool
145 type Sockaddr interface {
146 sockaddr() (ptr unsafe.Pointer, len _Socklen, err error) // lowercase; only we can define Sockaddrs
149 type SockaddrInet4 struct {
155 type SockaddrInet6 struct {
162 type SockaddrUnix struct {
167 func Bind(fd int, sa Sockaddr) (err error) {
168 ptr, n, err := sa.sockaddr()
172 return bind(fd, ptr, n)
175 func Connect(fd int, sa Sockaddr) (err error) {
176 ptr, n, err := sa.sockaddr()
180 return connect(fd, ptr, n)
183 func Getpeername(fd int) (sa Sockaddr, err error) {
184 var rsa RawSockaddrAny
185 var len _Socklen = SizeofSockaddrAny
186 if err = getpeername(fd, &rsa, &len); err != nil {
189 return anyToSockaddr(&rsa)
192 func GetsockoptInt(fd, level, opt int) (value int, err error) {
194 vallen := _Socklen(4)
195 err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen)
199 func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) {
200 var rsa RawSockaddrAny
201 var len _Socklen = SizeofSockaddrAny
202 if n, err = recvfrom(fd, p, flags, &rsa, &len); err != nil {
205 if rsa.Addr.Family != AF_UNSPEC {
206 from, err = anyToSockaddr(&rsa)
211 func Sendto(fd int, p []byte, flags int, to Sockaddr) (err error) {
212 ptr, n, err := to.sockaddr()
216 return sendto(fd, p, flags, ptr, n)
219 func SetsockoptByte(fd, level, opt int, value byte) (err error) {
220 return setsockopt(fd, level, opt, unsafe.Pointer(&value), 1)
223 func SetsockoptInt(fd, level, opt int, value int) (err error) {
225 return setsockopt(fd, level, opt, unsafe.Pointer(&n), 4)
228 func SetsockoptInet4Addr(fd, level, opt int, value [4]byte) (err error) {
229 return setsockopt(fd, level, opt, unsafe.Pointer(&value[0]), 4)
232 func SetsockoptIPMreq(fd, level, opt int, mreq *IPMreq) (err error) {
233 return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPMreq)
236 func SetsockoptIPv6Mreq(fd, level, opt int, mreq *IPv6Mreq) (err error) {
237 return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPv6Mreq)
240 func SetsockoptICMPv6Filter(fd, level, opt int, filter *ICMPv6Filter) error {
241 return setsockopt(fd, level, opt, unsafe.Pointer(filter), SizeofICMPv6Filter)
244 func SetsockoptLinger(fd, level, opt int, l *Linger) (err error) {
245 return setsockopt(fd, level, opt, unsafe.Pointer(l), SizeofLinger)
248 func SetsockoptString(fd, level, opt int, s string) (err error) {
249 return setsockopt(fd, level, opt, unsafe.Pointer(&[]byte(s)[0]), uintptr(len(s)))
252 func SetsockoptTimeval(fd, level, opt int, tv *Timeval) (err error) {
253 return setsockopt(fd, level, opt, unsafe.Pointer(tv), unsafe.Sizeof(*tv))
256 func Socket(domain, typ, proto int) (fd int, err error) {
257 if domain == AF_INET6 && SocketDisableIPv6 {
258 return -1, EAFNOSUPPORT
260 fd, err = socket(domain, typ, proto)
264 func Socketpair(domain, typ, proto int) (fd [2]int, err error) {
266 err = socketpair(domain, typ, proto, &fdx)
274 func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
276 raceReleaseMerge(unsafe.Pointer(&ioSync))
278 return sendfile(outfd, infd, offset, count)
283 func CloseOnExec(fd int) { fcntl(fd, F_SETFD, FD_CLOEXEC) }
285 func SetNonblock(fd int, nonblocking bool) (err error) {
286 flag, err := fcntl(fd, F_GETFL, 0)
295 _, err = fcntl(fd, F_SETFL, flag)