github.com/dolotech/hongbao@v0.0.0-20191130105438-fd59d7a5dda5/src/golang.org/x/sys/unix/syscall_unix.go (about) 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 dragonfly freebsd linux netbsd openbsd solaris 6 7 package unix 8 9 import ( 10 "runtime" 11 "sync" 12 "syscall" 13 "unsafe" 14 ) 15 16 var ( 17 Stdin = 0 18 Stdout = 1 19 Stderr = 2 20 ) 21 22 const ( 23 darwin64Bit = runtime.GOOS == "darwin" && sizeofPtr == 8 24 dragonfly64Bit = runtime.GOOS == "dragonfly" && sizeofPtr == 8 25 netbsd32Bit = runtime.GOOS == "netbsd" && sizeofPtr == 4 26 solaris64Bit = runtime.GOOS == "solaris" && sizeofPtr == 8 27 ) 28 29 // Do the interface allocations only once for common 30 // Errno values. 31 var ( 32 errEAGAIN error = syscall.EAGAIN 33 errEINVAL error = syscall.EINVAL 34 errENOENT error = syscall.ENOENT 35 ) 36 37 // errnoErr returns common boxed Errno values, to prevent 38 // allocations at runtime. 39 func errnoErr(e syscall.Errno) error { 40 switch e { 41 case 0: 42 return nil 43 case EAGAIN: 44 return errEAGAIN 45 case EINVAL: 46 return errEINVAL 47 case ENOENT: 48 return errENOENT 49 } 50 return e 51 } 52 53 // Mmap manager, for use by operating system-specific implementations. 54 55 type mmapper struct { 56 sync.Mutex 57 active map[*byte][]byte // active mappings; key is last byte in mapping 58 mmap func(addr, length uintptr, prot, flags, fd int, offset int64) (uintptr, error) 59 munmap func(addr uintptr, length uintptr) error 60 } 61 62 func (m *mmapper) Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) { 63 if length <= 0 { 64 return nil, EINVAL 65 } 66 67 // Map the requested memory. 68 addr, errno := m.mmap(0, uintptr(length), prot, flags, fd, offset) 69 if errno != nil { 70 return nil, errno 71 } 72 73 // Slice memory layout 74 var sl = struct { 75 addr uintptr 76 len int 77 cap int 78 }{addr, length, length} 79 80 // Use unsafe to turn sl into a []byte. 81 b := *(*[]byte)(unsafe.Pointer(&sl)) 82 83 // Register mapping in m and return it. 84 p := &b[cap(b)-1] 85 m.Lock() 86 defer m.Unlock() 87 m.active[p] = b 88 return b, nil 89 } 90 91 func (m *mmapper) Munmap(data []byte) (err error) { 92 if len(data) == 0 || len(data) != cap(data) { 93 return EINVAL 94 } 95 96 // Find the base of the mapping. 97 p := &data[cap(data)-1] 98 m.Lock() 99 defer m.Unlock() 100 b := m.active[p] 101 if b == nil || &b[0] != &data[0] { 102 return EINVAL 103 } 104 105 // Unmap the memory and update m. 106 if errno := m.munmap(uintptr(unsafe.Pointer(&b[0])), uintptr(len(b))); errno != nil { 107 return errno 108 } 109 delete(m.active, p) 110 return nil 111 } 112 113 func Read(fd int, p []byte) (n int, err error) { 114 n, err = read(fd, p) 115 if raceenabled { 116 if n > 0 { 117 raceWriteRange(unsafe.Pointer(&p[0]), n) 118 } 119 if err == nil { 120 raceAcquire(unsafe.Pointer(&ioSync)) 121 } 122 } 123 return 124 } 125 126 func Write(fd int, p []byte) (n int, err error) { 127 if raceenabled { 128 raceReleaseMerge(unsafe.Pointer(&ioSync)) 129 } 130 n, err = write(fd, p) 131 if raceenabled && n > 0 { 132 raceReadRange(unsafe.Pointer(&p[0]), n) 133 } 134 return 135 } 136 137 // For testing: clients can set this flag to force 138 // creation of IPv6 sockets to return EAFNOSUPPORT. 139 var SocketDisableIPv6 bool 140 141 type Sockaddr interface { 142 sockaddr() (ptr unsafe.Pointer, len _Socklen, err error) // lowercase; only we can define Sockaddrs 143 } 144 145 type SockaddrInet4 struct { 146 Port int 147 Addr [4]byte 148 raw RawSockaddrInet4 149 } 150 151 type SockaddrInet6 struct { 152 Port int 153 ZoneId uint32 154 Addr [16]byte 155 raw RawSockaddrInet6 156 } 157 158 type SockaddrUnix struct { 159 Name string 160 raw RawSockaddrUnix 161 } 162 163 func Bind(fd int, sa Sockaddr) (err error) { 164 ptr, n, err := sa.sockaddr() 165 if err != nil { 166 return err 167 } 168 return bind(fd, ptr, n) 169 } 170 171 func Connect(fd int, sa Sockaddr) (err error) { 172 ptr, n, err := sa.sockaddr() 173 if err != nil { 174 return err 175 } 176 return connect(fd, ptr, n) 177 } 178 179 func Getpeername(fd int) (sa Sockaddr, err error) { 180 var rsa RawSockaddrAny 181 var len _Socklen = SizeofSockaddrAny 182 if err = getpeername(fd, &rsa, &len); err != nil { 183 return 184 } 185 return anyToSockaddr(&rsa) 186 } 187 188 func GetsockoptInt(fd, level, opt int) (value int, err error) { 189 var n int32 190 vallen := _Socklen(4) 191 err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen) 192 return int(n), err 193 } 194 195 func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) { 196 var rsa RawSockaddrAny 197 var len _Socklen = SizeofSockaddrAny 198 if n, err = recvfrom(fd, p, flags, &rsa, &len); err != nil { 199 return 200 } 201 if rsa.Addr.Family != AF_UNSPEC { 202 from, err = anyToSockaddr(&rsa) 203 } 204 return 205 } 206 207 func Sendto(fd int, p []byte, flags int, to Sockaddr) (err error) { 208 ptr, n, err := to.sockaddr() 209 if err != nil { 210 return err 211 } 212 return sendto(fd, p, flags, ptr, n) 213 } 214 215 func SetsockoptByte(fd, level, opt int, value byte) (err error) { 216 return setsockopt(fd, level, opt, unsafe.Pointer(&value), 1) 217 } 218 219 func SetsockoptInt(fd, level, opt int, value int) (err error) { 220 var n = int32(value) 221 return setsockopt(fd, level, opt, unsafe.Pointer(&n), 4) 222 } 223 224 func SetsockoptInet4Addr(fd, level, opt int, value [4]byte) (err error) { 225 return setsockopt(fd, level, opt, unsafe.Pointer(&value[0]), 4) 226 } 227 228 func SetsockoptIPMreq(fd, level, opt int, mreq *IPMreq) (err error) { 229 return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPMreq) 230 } 231 232 func SetsockoptIPv6Mreq(fd, level, opt int, mreq *IPv6Mreq) (err error) { 233 return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPv6Mreq) 234 } 235 236 func SetsockoptICMPv6Filter(fd, level, opt int, filter *ICMPv6Filter) error { 237 return setsockopt(fd, level, opt, unsafe.Pointer(filter), SizeofICMPv6Filter) 238 } 239 240 func SetsockoptLinger(fd, level, opt int, l *Linger) (err error) { 241 return setsockopt(fd, level, opt, unsafe.Pointer(l), SizeofLinger) 242 } 243 244 func SetsockoptString(fd, level, opt int, s string) (err error) { 245 return setsockopt(fd, level, opt, unsafe.Pointer(&[]byte(s)[0]), uintptr(len(s))) 246 } 247 248 func SetsockoptTimeval(fd, level, opt int, tv *Timeval) (err error) { 249 return setsockopt(fd, level, opt, unsafe.Pointer(tv), unsafe.Sizeof(*tv)) 250 } 251 252 func Socket(domain, typ, proto int) (fd int, err error) { 253 if domain == AF_INET6 && SocketDisableIPv6 { 254 return -1, EAFNOSUPPORT 255 } 256 fd, err = socket(domain, typ, proto) 257 return 258 } 259 260 func Socketpair(domain, typ, proto int) (fd [2]int, err error) { 261 var fdx [2]int32 262 err = socketpair(domain, typ, proto, &fdx) 263 if err == nil { 264 fd[0] = int(fdx[0]) 265 fd[1] = int(fdx[1]) 266 } 267 return 268 } 269 270 func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { 271 if raceenabled { 272 raceReleaseMerge(unsafe.Pointer(&ioSync)) 273 } 274 return sendfile(outfd, infd, offset, count) 275 } 276 277 var ioSync int64 278 279 func CloseOnExec(fd int) { fcntl(fd, F_SETFD, FD_CLOEXEC) } 280 281 func SetNonblock(fd int, nonblocking bool) (err error) { 282 flag, err := fcntl(fd, F_GETFL, 0) 283 if err != nil { 284 return err 285 } 286 if nonblocking { 287 flag |= O_NONBLOCK 288 } else { 289 flag &= ^O_NONBLOCK 290 } 291 _, err = fcntl(fd, F_SETFL, flag) 292 return err 293 }