syscall_unix.mx raw

   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  
   7  package syscall
   8  
   9  import (
  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  
  22  var (
  23  	Stdin  = 0
  24  	Stdout = 1
  25  	Stderr = 2
  26  )
  27  
  28  const (
  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.
  34  func 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  
  43  type 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  
  50  func (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  
  72  func (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) ...
 108  type Errno uintptr
 109  
 110  func (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  
 120  func (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  
 134  func (e Errno) Temporary() bool {
 135  	return e == EINTR || e == EMFILE || e == ENFILE || e.Timeout()
 136  }
 137  
 138  func (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.
 144  var (
 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.
 152  func 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.
 168  type Signal int
 169  
 170  func (s Signal) Signal() {}
 171  
 172  func (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  
 182  func 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  
 201  func 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  
 225  func 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  
 244  func 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].
 263  var SocketDisableIPv6 bool
 264  
 265  type Sockaddr interface {
 266  	sockaddr() (ptr unsafe.Pointer, len _Socklen, err error) // lowercase; only we can define Sockaddrs
 267  }
 268  
 269  type SockaddrInet4 struct {
 270  	Port int
 271  	Addr [4]byte
 272  	raw  RawSockaddrInet4
 273  }
 274  
 275  type SockaddrInet6 struct {
 276  	Port   int
 277  	ZoneId uint32
 278  	Addr   [16]byte
 279  	raw    RawSockaddrInet6
 280  }
 281  
 282  type SockaddrUnix struct {
 283  	Name string
 284  	raw  RawSockaddrUnix
 285  }
 286  
 287  func 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  
 295  func 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  
 303  func 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  
 312  func 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  
 319  func 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  
 331  func 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  
 344  func 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  
 358  func 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  
 371  func 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  
 385  func 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  
 395  func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) {
 396  	_, err = SendmsgN(fd, p, oob, to, flags)
 397  	return
 398  }
 399  
 400  func 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  
 412  func 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  
 420  func 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  
 428  func 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  
 436  func 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  
 444  func 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  
 458  func SetsockoptByte(fd, level, opt int, value byte) (err error) {
 459  	return setsockopt(fd, level, opt, unsafe.Pointer(&value), 1)
 460  }
 461  
 462  func 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  
 467  func SetsockoptInet4Addr(fd, level, opt int, value [4]byte) (err error) {
 468  	return setsockopt(fd, level, opt, unsafe.Pointer(&value[0]), 4)
 469  }
 470  
 471  func SetsockoptIPMreq(fd, level, opt int, mreq *IPMreq) (err error) {
 472  	return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPMreq)
 473  }
 474  
 475  func SetsockoptIPv6Mreq(fd, level, opt int, mreq *IPv6Mreq) (err error) {
 476  	return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPv6Mreq)
 477  }
 478  
 479  func SetsockoptICMPv6Filter(fd, level, opt int, filter *ICMPv6Filter) error {
 480  	return setsockopt(fd, level, opt, unsafe.Pointer(filter), SizeofICMPv6Filter)
 481  }
 482  
 483  func SetsockoptLinger(fd, level, opt int, l *Linger) (err error) {
 484  	return setsockopt(fd, level, opt, unsafe.Pointer(l), SizeofLinger)
 485  }
 486  
 487  func 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  
 495  func SetsockoptTimeval(fd, level, opt int, tv *Timeval) (err error) {
 496  	return setsockopt(fd, level, opt, unsafe.Pointer(tv), unsafe.Sizeof(*tv))
 497  }
 498  
 499  func 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  
 507  func 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  
 517  func 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  
 524  var ioSync int64
 525