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

View as plain text