github.com/epfl-dcsl/gotee@v0.0.0-20200909122901-014b35f5e5e9/src/syscall/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 syscall 8 9 import ( 10 "internal/race" 11 "runtime" 12 "sync" 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 func SSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) 30 func SSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) 31 func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) 32 func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) 33 34 // Mmap manager, for use by operating system-specific implementations. 35 36 type mmapper struct { 37 sync.Mutex 38 active map[*byte][]byte // active mappings; key is last byte in mapping 39 mmap func(addr, length uintptr, prot, flags, fd int, offset int64) (uintptr, error) 40 munmap func(addr uintptr, length uintptr) error 41 } 42 43 func (m *mmapper) Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) { 44 if length <= 0 { 45 return nil, EINVAL 46 } 47 48 // Map the requested memory. 49 addr, errno := m.mmap(0, uintptr(length), prot, flags, fd, offset) 50 if errno != nil { 51 return nil, errno 52 } 53 54 // Slice memory layout 55 var sl = struct { 56 addr uintptr 57 len int 58 cap int 59 }{addr, length, length} 60 61 // Use unsafe to turn sl into a []byte. 62 b := *(*[]byte)(unsafe.Pointer(&sl)) 63 64 // Register mapping in m and return it. 65 p := &b[cap(b)-1] 66 m.Lock() 67 defer m.Unlock() 68 m.active[p] = b 69 return b, nil 70 } 71 72 func (m *mmapper) RMmap(ptr uintptr, length, prot, flags, fd int, offset int64) (data []byte, err error) { 73 if length <= 0 { 74 return nil, EINVAL 75 } 76 77 // Map the requested memory. 78 addr, errno := m.mmap(ptr, uintptr(length), prot, flags, fd, offset) 79 if errno != nil { 80 return nil, errno 81 } 82 83 // Slice memory layout 84 var sl = struct { 85 addr uintptr 86 len int 87 cap int 88 }{addr, length, length} 89 90 // Use unsafe to turn sl into a []byte. 91 b := *(*[]byte)(unsafe.Pointer(&sl)) 92 93 // Register mapping in m and return it. 94 p := &b[cap(b)-1] 95 m.Lock() 96 defer m.Unlock() 97 m.active[p] = b 98 return b, nil 99 } 100 101 func (m *mmapper) Munmap(data []byte) (err error) { 102 if len(data) == 0 || len(data) != cap(data) { 103 return EINVAL 104 } 105 106 // Find the base of the mapping. 107 p := &data[cap(data)-1] 108 m.Lock() 109 defer m.Unlock() 110 b := m.active[p] 111 if b == nil || &b[0] != &data[0] { 112 return EINVAL 113 } 114 115 // Unmap the memory and update m. 116 if errno := m.munmap(uintptr(unsafe.Pointer(&b[0])), uintptr(len(b))); errno != nil { 117 return errno 118 } 119 delete(m.active, p) 120 return nil 121 } 122 123 // An Errno is an unsigned number describing an error condition. 124 // It implements the error interface. The zero Errno is by convention 125 // a non-error, so code to convert from Errno to error should use: 126 // err = nil 127 // if errno != 0 { 128 // err = errno 129 // } 130 type Errno uintptr 131 132 func (e Errno) Error() string { 133 if 0 <= int(e) && int(e) < len(errors) { 134 s := errors[e] 135 if s != "" { 136 return s 137 } 138 } 139 return "errno " + itoa(int(e)) 140 } 141 142 func (e Errno) Temporary() bool { 143 return e == EINTR || e == EMFILE || e == ECONNRESET || e == ECONNABORTED || e.Timeout() 144 } 145 146 func (e Errno) Timeout() bool { 147 return e == EAGAIN || e == EWOULDBLOCK || e == ETIMEDOUT 148 } 149 150 // Do the interface allocations only once for common 151 // Errno values. 152 var ( 153 errEAGAIN error = EAGAIN 154 errEINVAL error = EINVAL 155 errENOENT error = ENOENT 156 ) 157 158 // errnoErr returns common boxed Errno values, to prevent 159 // allocations at runtime. 160 func errnoErr(e Errno) error { 161 switch e { 162 case 0: 163 return nil 164 case EAGAIN: 165 return errEAGAIN 166 case EINVAL: 167 return errEINVAL 168 case ENOENT: 169 return errENOENT 170 } 171 return e 172 } 173 174 // A Signal is a number describing a process signal. 175 // It implements the os.Signal interface. 176 type Signal int 177 178 func (s Signal) Signal() {} 179 180 func (s Signal) String() string { 181 if 0 <= s && int(s) < len(signals) { 182 str := signals[s] 183 if str != "" { 184 return str 185 } 186 } 187 return "signal " + itoa(int(s)) 188 } 189 190 func Read(fd int, p []byte) (n int, err error) { 191 n, err = read(fd, p) 192 if race.Enabled { 193 if n > 0 { 194 race.WriteRange(unsafe.Pointer(&p[0]), n) 195 } 196 if err == nil { 197 race.Acquire(unsafe.Pointer(&ioSync)) 198 } 199 } 200 if msanenabled && n > 0 { 201 msanWrite(unsafe.Pointer(&p[0]), n) 202 } 203 return 204 } 205 206 func Write(fd int, p []byte) (n int, err error) { 207 if race.Enabled { 208 race.ReleaseMerge(unsafe.Pointer(&ioSync)) 209 } 210 n, err = write(fd, p) 211 if race.Enabled && n > 0 { 212 race.ReadRange(unsafe.Pointer(&p[0]), n) 213 } 214 if msanenabled && n > 0 { 215 msanRead(unsafe.Pointer(&p[0]), n) 216 } 217 return 218 } 219 220 // For testing: clients can set this flag to force 221 // creation of IPv6 sockets to return EAFNOSUPPORT. 222 var SocketDisableIPv6 bool 223 224 type Sockaddr interface { 225 sockaddr() (ptr unsafe.Pointer, len _Socklen, err error) // lowercase; only we can define Sockaddrs 226 } 227 228 type SockaddrInet4 struct { 229 Port int 230 Addr [4]byte 231 raw RawSockaddrInet4 232 } 233 234 type SockaddrInet6 struct { 235 Port int 236 ZoneId uint32 237 Addr [16]byte 238 raw RawSockaddrInet6 239 } 240 241 type SockaddrUnix struct { 242 Name string 243 raw RawSockaddrUnix 244 } 245 246 func Bind(fd int, sa Sockaddr) (err error) { 247 ptr, n, err := sa.sockaddr() 248 if err != nil { 249 return err 250 } 251 return bind(fd, ptr, n) 252 } 253 254 func Connect(fd int, sa Sockaddr) (err error) { 255 ptr, n, err := sa.sockaddr() 256 if err != nil { 257 return err 258 } 259 return connect(fd, ptr, n) 260 } 261 262 func Getpeername(fd int) (sa Sockaddr, err error) { 263 var rsa RawSockaddrAny 264 var len _Socklen = SizeofSockaddrAny 265 if err = getpeername(fd, &rsa, &len); err != nil { 266 return 267 } 268 return anyToSockaddr(&rsa) 269 } 270 271 func GetsockoptInt(fd, level, opt int) (value int, err error) { 272 var n int32 273 vallen := _Socklen(4) 274 err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen) 275 return int(n), err 276 } 277 278 func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) { 279 var rsa RawSockaddrAny 280 var len _Socklen = SizeofSockaddrAny 281 if n, err = recvfrom(fd, p, flags, &rsa, &len); err != nil { 282 return 283 } 284 if rsa.Addr.Family != AF_UNSPEC { 285 from, err = anyToSockaddr(&rsa) 286 } 287 return 288 } 289 290 func Sendto(fd int, p []byte, flags int, to Sockaddr) (err error) { 291 ptr, n, err := to.sockaddr() 292 if err != nil { 293 return err 294 } 295 return sendto(fd, p, flags, ptr, n) 296 } 297 298 func SetsockoptByte(fd, level, opt int, value byte) (err error) { 299 return setsockopt(fd, level, opt, unsafe.Pointer(&value), 1) 300 } 301 302 func SetsockoptInt(fd, level, opt int, value int) (err error) { 303 var n = int32(value) 304 return setsockopt(fd, level, opt, unsafe.Pointer(&n), 4) 305 } 306 307 func SetsockoptInet4Addr(fd, level, opt int, value [4]byte) (err error) { 308 return setsockopt(fd, level, opt, unsafe.Pointer(&value[0]), 4) 309 } 310 311 func SetsockoptIPMreq(fd, level, opt int, mreq *IPMreq) (err error) { 312 return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPMreq) 313 } 314 315 func SetsockoptIPv6Mreq(fd, level, opt int, mreq *IPv6Mreq) (err error) { 316 return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPv6Mreq) 317 } 318 319 func SetsockoptICMPv6Filter(fd, level, opt int, filter *ICMPv6Filter) error { 320 return setsockopt(fd, level, opt, unsafe.Pointer(filter), SizeofICMPv6Filter) 321 } 322 323 func SetsockoptLinger(fd, level, opt int, l *Linger) (err error) { 324 return setsockopt(fd, level, opt, unsafe.Pointer(l), SizeofLinger) 325 } 326 327 func SetsockoptString(fd, level, opt int, s string) (err error) { 328 return setsockopt(fd, level, opt, unsafe.Pointer(&[]byte(s)[0]), uintptr(len(s))) 329 } 330 331 func SetsockoptTimeval(fd, level, opt int, tv *Timeval) (err error) { 332 return setsockopt(fd, level, opt, unsafe.Pointer(tv), unsafe.Sizeof(*tv)) 333 } 334 335 func Socket(domain, typ, proto int) (fd int, err error) { 336 if domain == AF_INET6 && SocketDisableIPv6 { 337 return -1, EAFNOSUPPORT 338 } 339 fd, err = socket(domain, typ, proto) 340 return 341 } 342 343 func Socketpair(domain, typ, proto int) (fd [2]int, err error) { 344 var fdx [2]int32 345 err = socketpair(domain, typ, proto, &fdx) 346 if err == nil { 347 fd[0] = int(fdx[0]) 348 fd[1] = int(fdx[1]) 349 } 350 return 351 } 352 353 func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { 354 if race.Enabled { 355 race.ReleaseMerge(unsafe.Pointer(&ioSync)) 356 } 357 return sendfile(outfd, infd, offset, count) 358 } 359 360 var ioSync int64