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//go:build unix 6 7package syscall 8 9import ( 10 errorspkg "errors" 11 "internal/asan" 12 "internal/bytealg" 13 "internal/itoa" 14 "internal/msan" 15 "internal/oserror" 16 "internal/race" 17 "runtime" 18 "sync" 19 "unsafe" 20) 21 22var ( 23 Stdin = 0 24 Stdout = 1 25 Stderr = 2 26) 27 28const ( 29 darwin64Bit = (runtime.GOOS == "darwin" || runtime.GOOS == "ios") && sizeofPtr == 8 30 netbsd32Bit = runtime.GOOS == "netbsd" && sizeofPtr == 4 31) 32 33// clen returns the index of the first NULL byte in n or len(n) if n contains no NULL byte. 34func clen(n []byte) int { 35 if i := bytealg.IndexByte(n, 0); i != -1 { 36 return i 37 } 38 return len(n) 39} 40 41// Mmap manager, for use by operating system-specific implementations. 42 43type mmapper struct { 44 sync.Mutex 45 active map[*byte][]byte // active mappings; key is last byte in mapping 46 mmap func(addr, length uintptr, prot, flags, fd int, offset int64) (uintptr, error) 47 munmap func(addr uintptr, length uintptr) error 48} 49 50func (m *mmapper) Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) { 51 if length <= 0 { 52 return nil, EINVAL 53 } 54 55 // Map the requested memory. 56 addr, errno := m.mmap(0, uintptr(length), prot, flags, fd, offset) 57 if errno != nil { 58 return nil, errno 59 } 60 61 // Use unsafe to turn addr into a []byte. 62 b := unsafe.Slice((*byte)(unsafe.Pointer(addr)), length) 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 72func (m *mmapper) Munmap(data []byte) (err error) { 73 if len(data) == 0 || len(data) != cap(data) { 74 return EINVAL 75 } 76 77 // Find the base of the mapping. 78 p := &data[cap(data)-1] 79 m.Lock() 80 defer m.Unlock() 81 b := m.active[p] 82 if b == nil || &b[0] != &data[0] { 83 return EINVAL 84 } 85 86 // Unmap the memory and update m. 87 if errno := m.munmap(uintptr(unsafe.Pointer(&b[0])), uintptr(len(b))); errno != nil { 88 return errno 89 } 90 delete(m.active, p) 91 return nil 92} 93 94// An Errno is an unsigned number describing an error condition. 95// It implements the error interface. The zero Errno is by convention 96// a non-error, so code to convert from Errno to error should use: 97// 98// err = nil 99// if errno != 0 { 100// err = errno 101// } 102// 103// Errno values can be tested against error values using [errors.Is]. 104// For example: 105// 106// _, _, err := syscall.Syscall(...) 107// if errors.Is(err, fs.ErrNotExist) ... 108type Errno uintptr 109 110func (e Errno) Error() string { 111 if 0 <= int(e) && int(e) < len(errors) { 112 s := errors[e] 113 if s != "" { 114 return s 115 } 116 } 117 return "errno " + itoa.Itoa(int(e)) 118} 119 120func (e Errno) Is(target error) bool { 121 switch target { 122 case oserror.ErrPermission: 123 return e == EACCES || e == EPERM 124 case oserror.ErrExist: 125 return e == EEXIST || e == ENOTEMPTY 126 case oserror.ErrNotExist: 127 return e == ENOENT 128 case errorspkg.ErrUnsupported: 129 return e == ENOSYS || e == ENOTSUP || e == EOPNOTSUPP 130 } 131 return false 132} 133 134func (e Errno) Temporary() bool { 135 return e == EINTR || e == EMFILE || e == ENFILE || e.Timeout() 136} 137 138func (e Errno) Timeout() bool { 139 return e == EAGAIN || e == EWOULDBLOCK || e == ETIMEDOUT 140} 141 142// Do the interface allocations only once for common 143// Errno values. 144var ( 145 errEAGAIN error = EAGAIN 146 errEINVAL error = EINVAL 147 errENOENT error = ENOENT 148) 149 150// errnoErr returns common boxed Errno values, to prevent 151// allocations at runtime. 152func errnoErr(e Errno) error { 153 switch e { 154 case 0: 155 return nil 156 case EAGAIN: 157 return errEAGAIN 158 case EINVAL: 159 return errEINVAL 160 case ENOENT: 161 return errENOENT 162 } 163 return e 164} 165 166// A Signal is a number describing a process signal. 167// It implements the [os.Signal] interface. 168type Signal int 169 170func (s Signal) Signal() {} 171 172func (s Signal) String() string { 173 if 0 <= s && int(s) < len(signals) { 174 str := signals[s] 175 if str != "" { 176 return str 177 } 178 } 179 return "signal " + itoa.Itoa(int(s)) 180} 181 182func Read(fd int, p []byte) (n int, err error) { 183 n, err = read(fd, p) 184 if race.Enabled { 185 if n > 0 { 186 race.WriteRange(unsafe.Pointer(&p[0]), n) 187 } 188 if err == nil { 189 race.Acquire(unsafe.Pointer(&ioSync)) 190 } 191 } 192 if msan.Enabled && n > 0 { 193 msan.Write(unsafe.Pointer(&p[0]), uintptr(n)) 194 } 195 if asan.Enabled && n > 0 { 196 asan.Write(unsafe.Pointer(&p[0]), uintptr(n)) 197 } 198 return 199} 200 201func Write(fd int, p []byte) (n int, err error) { 202 if race.Enabled { 203 race.ReleaseMerge(unsafe.Pointer(&ioSync)) 204 } 205 if faketime && (fd == 1 || fd == 2) { 206 n = faketimeWrite(fd, p) 207 if n < 0 { 208 n, err = 0, errnoErr(Errno(-n)) 209 } 210 } else { 211 n, err = write(fd, p) 212 } 213 if race.Enabled && n > 0 { 214 race.ReadRange(unsafe.Pointer(&p[0]), n) 215 } 216 if msan.Enabled && n > 0 { 217 msan.Read(unsafe.Pointer(&p[0]), uintptr(n)) 218 } 219 if asan.Enabled && n > 0 { 220 asan.Read(unsafe.Pointer(&p[0]), uintptr(n)) 221 } 222 return 223} 224 225func Pread(fd int, p []byte, offset int64) (n int, err error) { 226 n, err = pread(fd, p, offset) 227 if race.Enabled { 228 if n > 0 { 229 race.WriteRange(unsafe.Pointer(&p[0]), n) 230 } 231 if err == nil { 232 race.Acquire(unsafe.Pointer(&ioSync)) 233 } 234 } 235 if msan.Enabled && n > 0 { 236 msan.Write(unsafe.Pointer(&p[0]), uintptr(n)) 237 } 238 if asan.Enabled && n > 0 { 239 asan.Write(unsafe.Pointer(&p[0]), uintptr(n)) 240 } 241 return 242} 243 244func Pwrite(fd int, p []byte, offset int64) (n int, err error) { 245 if race.Enabled { 246 race.ReleaseMerge(unsafe.Pointer(&ioSync)) 247 } 248 n, err = pwrite(fd, p, offset) 249 if race.Enabled && n > 0 { 250 race.ReadRange(unsafe.Pointer(&p[0]), n) 251 } 252 if msan.Enabled && n > 0 { 253 msan.Read(unsafe.Pointer(&p[0]), uintptr(n)) 254 } 255 if asan.Enabled && n > 0 { 256 asan.Read(unsafe.Pointer(&p[0]), uintptr(n)) 257 } 258 return 259} 260 261// For testing: clients can set this flag to force 262// creation of IPv6 sockets to return [EAFNOSUPPORT]. 263var SocketDisableIPv6 bool 264 265type Sockaddr interface { 266 sockaddr() (ptr unsafe.Pointer, len _Socklen, err error) // lowercase; only we can define Sockaddrs 267} 268 269type SockaddrInet4 struct { 270 Port int 271 Addr [4]byte 272 raw RawSockaddrInet4 273} 274 275type SockaddrInet6 struct { 276 Port int 277 ZoneId uint32 278 Addr [16]byte 279 raw RawSockaddrInet6 280} 281 282type SockaddrUnix struct { 283 Name string 284 raw RawSockaddrUnix 285} 286 287func Bind(fd int, sa Sockaddr) (err error) { 288 ptr, n, err := sa.sockaddr() 289 if err != nil { 290 return err 291 } 292 return bind(fd, ptr, n) 293} 294 295func Connect(fd int, sa Sockaddr) (err error) { 296 ptr, n, err := sa.sockaddr() 297 if err != nil { 298 return err 299 } 300 return connect(fd, ptr, n) 301} 302 303func Getpeername(fd int) (sa Sockaddr, err error) { 304 var rsa RawSockaddrAny 305 var len _Socklen = SizeofSockaddrAny 306 if err = getpeername(fd, &rsa, &len); err != nil { 307 return 308 } 309 return anyToSockaddr(&rsa) 310} 311 312func GetsockoptInt(fd, level, opt int) (value int, err error) { 313 var n int32 314 vallen := _Socklen(4) 315 err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen) 316 return int(n), err 317} 318 319func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) { 320 var rsa RawSockaddrAny 321 var len _Socklen = SizeofSockaddrAny 322 if n, err = recvfrom(fd, p, flags, &rsa, &len); err != nil { 323 return 324 } 325 if rsa.Addr.Family != AF_UNSPEC { 326 from, err = anyToSockaddr(&rsa) 327 } 328 return 329} 330 331func recvfromInet4(fd int, p []byte, flags int, from *SockaddrInet4) (n int, err error) { 332 var rsa RawSockaddrAny 333 var socklen _Socklen = SizeofSockaddrAny 334 if n, err = recvfrom(fd, p, flags, &rsa, &socklen); err != nil { 335 return 336 } 337 pp := (*RawSockaddrInet4)(unsafe.Pointer(&rsa)) 338 port := (*[2]byte)(unsafe.Pointer(&pp.Port)) 339 from.Port = int(port[0])<<8 + int(port[1]) 340 from.Addr = pp.Addr 341 return 342} 343 344func recvfromInet6(fd int, p []byte, flags int, from *SockaddrInet6) (n int, err error) { 345 var rsa RawSockaddrAny 346 var socklen _Socklen = SizeofSockaddrAny 347 if n, err = recvfrom(fd, p, flags, &rsa, &socklen); err != nil { 348 return 349 } 350 pp := (*RawSockaddrInet6)(unsafe.Pointer(&rsa)) 351 port := (*[2]byte)(unsafe.Pointer(&pp.Port)) 352 from.Port = int(port[0])<<8 + int(port[1]) 353 from.ZoneId = pp.Scope_id 354 from.Addr = pp.Addr 355 return 356} 357 358func recvmsgInet4(fd int, p, oob []byte, flags int, from *SockaddrInet4) (n, oobn int, recvflags int, err error) { 359 var rsa RawSockaddrAny 360 n, oobn, recvflags, err = recvmsgRaw(fd, p, oob, flags, &rsa) 361 if err != nil { 362 return 363 } 364 pp := (*RawSockaddrInet4)(unsafe.Pointer(&rsa)) 365 port := (*[2]byte)(unsafe.Pointer(&pp.Port)) 366 from.Port = int(port[0])<<8 + int(port[1]) 367 from.Addr = pp.Addr 368 return 369} 370 371func recvmsgInet6(fd int, p, oob []byte, flags int, from *SockaddrInet6) (n, oobn int, recvflags int, err error) { 372 var rsa RawSockaddrAny 373 n, oobn, recvflags, err = recvmsgRaw(fd, p, oob, flags, &rsa) 374 if err != nil { 375 return 376 } 377 pp := (*RawSockaddrInet6)(unsafe.Pointer(&rsa)) 378 port := (*[2]byte)(unsafe.Pointer(&pp.Port)) 379 from.Port = int(port[0])<<8 + int(port[1]) 380 from.ZoneId = pp.Scope_id 381 from.Addr = pp.Addr 382 return 383} 384 385func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) { 386 var rsa RawSockaddrAny 387 n, oobn, recvflags, err = recvmsgRaw(fd, p, oob, flags, &rsa) 388 // source address is only specified if the socket is unconnected 389 if rsa.Addr.Family != AF_UNSPEC { 390 from, err = anyToSockaddr(&rsa) 391 } 392 return 393} 394 395func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) { 396 _, err = SendmsgN(fd, p, oob, to, flags) 397 return 398} 399 400func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) { 401 var ptr unsafe.Pointer 402 var salen _Socklen 403 if to != nil { 404 ptr, salen, err = to.sockaddr() 405 if err != nil { 406 return 0, err 407 } 408 } 409 return sendmsgN(fd, p, oob, ptr, salen, flags) 410} 411 412func sendmsgNInet4(fd int, p, oob []byte, to *SockaddrInet4, flags int) (n int, err error) { 413 ptr, salen, err := to.sockaddr() 414 if err != nil { 415 return 0, err 416 } 417 return sendmsgN(fd, p, oob, ptr, salen, flags) 418} 419 420func sendmsgNInet6(fd int, p, oob []byte, to *SockaddrInet6, flags int) (n int, err error) { 421 ptr, salen, err := to.sockaddr() 422 if err != nil { 423 return 0, err 424 } 425 return sendmsgN(fd, p, oob, ptr, salen, flags) 426} 427 428func sendtoInet4(fd int, p []byte, flags int, to *SockaddrInet4) (err error) { 429 ptr, n, err := to.sockaddr() 430 if err != nil { 431 return err 432 } 433 return sendto(fd, p, flags, ptr, n) 434} 435 436func sendtoInet6(fd int, p []byte, flags int, to *SockaddrInet6) (err error) { 437 ptr, n, err := to.sockaddr() 438 if err != nil { 439 return err 440 } 441 return sendto(fd, p, flags, ptr, n) 442} 443 444func Sendto(fd int, p []byte, flags int, to Sockaddr) (err error) { 445 var ( 446 ptr unsafe.Pointer 447 salen _Socklen 448 ) 449 if to != nil { 450 ptr, salen, err = to.sockaddr() 451 if err != nil { 452 return err 453 } 454 } 455 return sendto(fd, p, flags, ptr, salen) 456} 457 458func SetsockoptByte(fd, level, opt int, value byte) (err error) { 459 return setsockopt(fd, level, opt, unsafe.Pointer(&value), 1) 460} 461 462func SetsockoptInt(fd, level, opt int, value int) (err error) { 463 var n = int32(value) 464 return setsockopt(fd, level, opt, unsafe.Pointer(&n), 4) 465} 466 467func SetsockoptInet4Addr(fd, level, opt int, value [4]byte) (err error) { 468 return setsockopt(fd, level, opt, unsafe.Pointer(&value[0]), 4) 469} 470 471func SetsockoptIPMreq(fd, level, opt int, mreq *IPMreq) (err error) { 472 return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPMreq) 473} 474 475func SetsockoptIPv6Mreq(fd, level, opt int, mreq *IPv6Mreq) (err error) { 476 return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPv6Mreq) 477} 478 479func SetsockoptICMPv6Filter(fd, level, opt int, filter *ICMPv6Filter) error { 480 return setsockopt(fd, level, opt, unsafe.Pointer(filter), SizeofICMPv6Filter) 481} 482 483func SetsockoptLinger(fd, level, opt int, l *Linger) (err error) { 484 return setsockopt(fd, level, opt, unsafe.Pointer(l), SizeofLinger) 485} 486 487func SetsockoptString(fd, level, opt int, s string) (err error) { 488 var p unsafe.Pointer 489 if len(s) > 0 { 490 p = unsafe.Pointer(&[]byte(s)[0]) 491 } 492 return setsockopt(fd, level, opt, p, uintptr(len(s))) 493} 494 495func SetsockoptTimeval(fd, level, opt int, tv *Timeval) (err error) { 496 return setsockopt(fd, level, opt, unsafe.Pointer(tv), unsafe.Sizeof(*tv)) 497} 498 499func Socket(domain, typ, proto int) (fd int, err error) { 500 if domain == AF_INET6 && SocketDisableIPv6 { 501 return -1, EAFNOSUPPORT 502 } 503 fd, err = socket(domain, typ, proto) 504 return 505} 506 507func Socketpair(domain, typ, proto int) (fd [2]int, err error) { 508 var fdx [2]int32 509 err = socketpair(domain, typ, proto, &fdx) 510 if err == nil { 511 fd[0] = int(fdx[0]) 512 fd[1] = int(fdx[1]) 513 } 514 return 515} 516 517func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { 518 if race.Enabled { 519 race.ReleaseMerge(unsafe.Pointer(&ioSync)) 520 } 521 return sendfile(outfd, infd, offset, count) 522} 523 524var ioSync int64 525