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/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  

View as plain text