Source file src/syscall/syscall_unix.go

     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/msan"
    14  	"internal/oserror"
    15  	"internal/race"
    16  	"internal/strconv"
    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 " + strconv.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 " + strconv.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  	if err != nil {
   389  		return
   390  	}
   391  	// source address is only specified if the socket is unconnected
   392  	if rsa.Addr.Family != AF_UNSPEC {
   393  		from, err = anyToSockaddr(&rsa)
   394  	}
   395  	return
   396  }
   397  
   398  func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) {
   399  	_, err = SendmsgN(fd, p, oob, to, flags)
   400  	return
   401  }
   402  
   403  func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) {
   404  	var ptr unsafe.Pointer
   405  	var salen _Socklen
   406  	if to != nil {
   407  		ptr, salen, err = to.sockaddr()
   408  		if err != nil {
   409  			return 0, err
   410  		}
   411  	}
   412  	return sendmsgN(fd, p, oob, ptr, salen, flags)
   413  }
   414  
   415  func sendmsgNInet4(fd int, p, oob []byte, to *SockaddrInet4, flags int) (n int, err error) {
   416  	var ptr unsafe.Pointer
   417  	var salen _Socklen
   418  	if to != nil {
   419  		ptr, salen, err = to.sockaddr()
   420  		if err != nil {
   421  			return 0, err
   422  		}
   423  	}
   424  	return sendmsgN(fd, p, oob, ptr, salen, flags)
   425  }
   426  
   427  func sendmsgNInet6(fd int, p, oob []byte, to *SockaddrInet6, flags int) (n int, err error) {
   428  	var ptr unsafe.Pointer
   429  	var salen _Socklen
   430  	if to != nil {
   431  		ptr, salen, err = to.sockaddr()
   432  		if err != nil {
   433  			return 0, err
   434  		}
   435  	}
   436  	return sendmsgN(fd, p, oob, ptr, salen, flags)
   437  }
   438  
   439  func sendtoInet4(fd int, p []byte, flags int, to *SockaddrInet4) (err error) {
   440  	ptr, n, err := to.sockaddr()
   441  	if err != nil {
   442  		return err
   443  	}
   444  	return sendto(fd, p, flags, ptr, n)
   445  }
   446  
   447  func sendtoInet6(fd int, p []byte, flags int, to *SockaddrInet6) (err error) {
   448  	ptr, n, err := to.sockaddr()
   449  	if err != nil {
   450  		return err
   451  	}
   452  	return sendto(fd, p, flags, ptr, n)
   453  }
   454  
   455  func Sendto(fd int, p []byte, flags int, to Sockaddr) (err error) {
   456  	var (
   457  		ptr   unsafe.Pointer
   458  		salen _Socklen
   459  	)
   460  	if to != nil {
   461  		ptr, salen, err = to.sockaddr()
   462  		if err != nil {
   463  			return err
   464  		}
   465  	}
   466  	return sendto(fd, p, flags, ptr, salen)
   467  }
   468  
   469  func SetsockoptByte(fd, level, opt int, value byte) (err error) {
   470  	return setsockopt(fd, level, opt, unsafe.Pointer(&value), 1)
   471  }
   472  
   473  func SetsockoptInt(fd, level, opt int, value int) (err error) {
   474  	var n = int32(value)
   475  	return setsockopt(fd, level, opt, unsafe.Pointer(&n), 4)
   476  }
   477  
   478  func SetsockoptInet4Addr(fd, level, opt int, value [4]byte) (err error) {
   479  	return setsockopt(fd, level, opt, unsafe.Pointer(&value[0]), 4)
   480  }
   481  
   482  func SetsockoptIPMreq(fd, level, opt int, mreq *IPMreq) (err error) {
   483  	return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPMreq)
   484  }
   485  
   486  func SetsockoptIPv6Mreq(fd, level, opt int, mreq *IPv6Mreq) (err error) {
   487  	return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPv6Mreq)
   488  }
   489  
   490  func SetsockoptICMPv6Filter(fd, level, opt int, filter *ICMPv6Filter) error {
   491  	return setsockopt(fd, level, opt, unsafe.Pointer(filter), SizeofICMPv6Filter)
   492  }
   493  
   494  func SetsockoptLinger(fd, level, opt int, l *Linger) (err error) {
   495  	return setsockopt(fd, level, opt, unsafe.Pointer(l), SizeofLinger)
   496  }
   497  
   498  func SetsockoptString(fd, level, opt int, s string) (err error) {
   499  	var p unsafe.Pointer
   500  	if len(s) > 0 {
   501  		p = unsafe.Pointer(&[]byte(s)[0])
   502  	}
   503  	return setsockopt(fd, level, opt, p, uintptr(len(s)))
   504  }
   505  
   506  func SetsockoptTimeval(fd, level, opt int, tv *Timeval) (err error) {
   507  	return setsockopt(fd, level, opt, unsafe.Pointer(tv), unsafe.Sizeof(*tv))
   508  }
   509  
   510  func Socket(domain, typ, proto int) (fd int, err error) {
   511  	if domain == AF_INET6 && SocketDisableIPv6 {
   512  		return -1, EAFNOSUPPORT
   513  	}
   514  	fd, err = socket(domain, typ, proto)
   515  	return
   516  }
   517  
   518  func Socketpair(domain, typ, proto int) (fd [2]int, err error) {
   519  	var fdx [2]int32
   520  	err = socketpair(domain, typ, proto, &fdx)
   521  	if err == nil {
   522  		fd[0] = int(fdx[0])
   523  		fd[1] = int(fdx[1])
   524  	}
   525  	return
   526  }
   527  
   528  // Sendfile copies up to count bytes from file descriptor infd to file descriptor outfd.
   529  //
   530  // It wraps the sendfile system call. The behavior varies by operating system,
   531  // particularly regarding the offset argument and how partial writes are reported.
   532  //
   533  // On Linux, if offset is nil, Sendfile uses and updates the current file
   534  // position of infd. If offset is non-nil, the current file position is
   535  // unchanged, and the offset pointer is updated to reflect the bytes written.
   536  // A non-nil error typically implies that no bytes were written.
   537  //
   538  // On BSD-derived systems (including macOS), if offset is nil, Sendfile panics.
   539  // The offset argument is not updated by the system call; the caller must manually
   540  // update the offset using the number of bytes written. These systems may
   541  // return a non-zero byte count together with an error (for example, EAGAIN).
   542  //
   543  // For precise semantics, see the system documentation (e.g., man 2 sendfile).
   544  func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
   545  	if race.Enabled {
   546  		race.ReleaseMerge(unsafe.Pointer(&ioSync))
   547  	}
   548  	return sendfile(outfd, infd, offset, count)
   549  }
   550  
   551  var ioSync int64
   552  

View as plain text