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