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