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

View as plain text