Source file src/pkg/net/sock.go
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. 4 5 // +build darwin freebsd linux netbsd openbsd windows 6 7 // Sockets 8 9 package net 10 11 import ( 12 "io" 13 "syscall" 14 ) 15 16 var listenerBacklog = maxListenerBacklog() 17 18 // Generic socket creation. 19 func socket(net string, f, t, p int, ipv6only bool, la, ra syscall.Sockaddr, toAddr func(syscall.Sockaddr) Addr) (fd *netFD, err error) { 20 // See ../syscall/exec.go for description of ForkLock. 21 syscall.ForkLock.RLock() 22 s, err := syscall.Socket(f, t, p) 23 if err != nil { 24 syscall.ForkLock.RUnlock() 25 return nil, err 26 } 27 syscall.CloseOnExec(s) 28 syscall.ForkLock.RUnlock() 29 30 err = setDefaultSockopts(s, f, t, ipv6only) 31 if err != nil { 32 closesocket(s) 33 return nil, err 34 } 35 36 var bla syscall.Sockaddr 37 if la != nil { 38 bla, err = listenerSockaddr(s, f, la, toAddr) 39 if err != nil { 40 closesocket(s) 41 return nil, err 42 } 43 err = syscall.Bind(s, bla) 44 if err != nil { 45 closesocket(s) 46 return nil, err 47 } 48 } 49 50 if fd, err = newFD(s, f, t, net); err != nil { 51 closesocket(s) 52 return nil, err 53 } 54 55 if ra != nil { 56 if err = fd.connect(ra); err != nil { 57 closesocket(s) 58 fd.Close() 59 return nil, err 60 } 61 fd.isConnected = true 62 } 63 64 sa, _ := syscall.Getsockname(s) 65 var laddr Addr 66 if la != nil && bla != la { 67 laddr = toAddr(la) 68 } else { 69 laddr = toAddr(sa) 70 } 71 sa, _ = syscall.Getpeername(s) 72 raddr := toAddr(sa) 73 74 fd.setAddr(laddr, raddr) 75 return fd, nil 76 } 77 78 type writerOnly struct { 79 io.Writer 80 } 81 82 // Fallback implementation of io.ReaderFrom's ReadFrom, when sendfile isn't 83 // applicable. 84 func genericReadFrom(w io.Writer, r io.Reader) (n int64, err error) { 85 // Use wrapper to hide existing r.ReadFrom from io.Copy. 86 return io.Copy(writerOnly{w}, r) 87 }