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  	"internal/unsafeheader"
    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  	var b []byte
    61  	hdr := (*unsafeheader.Slice)(unsafe.Pointer(&b))
    62  	hdr.Data = unsafe.Pointer(addr)
    63  	hdr.Cap = length
    64  	hdr.Len = length
    65  
    66  	// Register mapping in m and return it.
    67  	p := &b[cap(b)-1]
    68  	m.Lock()
    69  	defer m.Unlock()
    70  	m.active[p] = b
    71  	return b, nil
    72  }
    73  
    74  func (m *mmapper) Munmap(data []byte) (err error) {
    75  	if len(data) == 0 || len(data) != cap(data) {
    76  		return EINVAL
    77  	}
    78  
    79  	// Find the base of the mapping.
    80  	p := &data[cap(data)-1]
    81  	m.Lock()
    82  	defer m.Unlock()
    83  	b := m.active[p]
    84  	if b == nil || &b[0] != &data[0] {
    85  		return EINVAL
    86  	}
    87  
    88  	// Unmap the memory and update m.
    89  	if errno := m.munmap(uintptr(unsafe.Pointer(&b[0])), uintptr(len(b))); errno != nil {
    90  		return errno
    91  	}
    92  	delete(m.active, p)
    93  	return nil
    94  }
    95  
    96  // An Errno is an unsigned number describing an error condition.
    97  // It implements the error interface. The zero Errno is by convention
    98  // a non-error, so code to convert from Errno to error should use:
    99  //
   100  //	err = nil
   101  //	if errno != 0 {
   102  //		err = errno
   103  //	}
   104  //
   105  // Errno values can be tested against error values from the os package
   106  // using errors.Is. For example:
   107  //
   108  //	_, _, err := syscall.Syscall(...)
   109  //	if errors.Is(err, fs.ErrNotExist) ...
   110  type Errno uintptr
   111  
   112  func (e Errno) Error() string {
   113  	if 0 <= int(e) && int(e) < len(errors) {
   114  		s := errors[e]
   115  		if s != "" {
   116  			return s
   117  		}
   118  	}
   119  	return "errno " + itoa.Itoa(int(e))
   120  }
   121  
   122  func (e Errno) Is(target error) bool {
   123  	switch target {
   124  	case oserror.ErrPermission:
   125  		return e == EACCES || e == EPERM
   126  	case oserror.ErrExist:
   127  		return e == EEXIST || e == ENOTEMPTY
   128  	case oserror.ErrNotExist:
   129  		return e == ENOENT
   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 msanenabled && n > 0 {
   193  		msanWrite(unsafe.Pointer(&p[0]), n)
   194  	}
   195  	if asanenabled && n > 0 {
   196  		asanWrite(unsafe.Pointer(&p[0]), 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 msanenabled && n > 0 {
   217  		msanRead(unsafe.Pointer(&p[0]), n)
   218  	}
   219  	if asanenabled && n > 0 {
   220  		asanRead(unsafe.Pointer(&p[0]), 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 msanenabled && n > 0 {
   236  		msanWrite(unsafe.Pointer(&p[0]), n)
   237  	}
   238  	if asanenabled && n > 0 {
   239  		asanWrite(unsafe.Pointer(&p[0]), 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 msanenabled && n > 0 {
   253  		msanRead(unsafe.Pointer(&p[0]), n)
   254  	}
   255  	if asanenabled && n > 0 {
   256  		asanRead(unsafe.Pointer(&p[0]), 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  	ptr, n, err := to.sockaddr()
   446  	if err != nil {
   447  		return err
   448  	}
   449  	return sendto(fd, p, flags, ptr, n)
   450  }
   451  
   452  func SetsockoptByte(fd, level, opt int, value byte) (err error) {
   453  	return setsockopt(fd, level, opt, unsafe.Pointer(&value), 1)
   454  }
   455  
   456  func SetsockoptInt(fd, level, opt int, value int) (err error) {
   457  	var n = int32(value)
   458  	return setsockopt(fd, level, opt, unsafe.Pointer(&n), 4)
   459  }
   460  
   461  func SetsockoptInet4Addr(fd, level, opt int, value [4]byte) (err error) {
   462  	return setsockopt(fd, level, opt, unsafe.Pointer(&value[0]), 4)
   463  }
   464  
   465  func SetsockoptIPMreq(fd, level, opt int, mreq *IPMreq) (err error) {
   466  	return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPMreq)
   467  }
   468  
   469  func SetsockoptIPv6Mreq(fd, level, opt int, mreq *IPv6Mreq) (err error) {
   470  	return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPv6Mreq)
   471  }
   472  
   473  func SetsockoptICMPv6Filter(fd, level, opt int, filter *ICMPv6Filter) error {
   474  	return setsockopt(fd, level, opt, unsafe.Pointer(filter), SizeofICMPv6Filter)
   475  }
   476  
   477  func SetsockoptLinger(fd, level, opt int, l *Linger) (err error) {
   478  	return setsockopt(fd, level, opt, unsafe.Pointer(l), SizeofLinger)
   479  }
   480  
   481  func SetsockoptString(fd, level, opt int, s string) (err error) {
   482  	var p unsafe.Pointer
   483  	if len(s) > 0 {
   484  		p = unsafe.Pointer(&[]byte(s)[0])
   485  	}
   486  	return setsockopt(fd, level, opt, p, uintptr(len(s)))
   487  }
   488  
   489  func SetsockoptTimeval(fd, level, opt int, tv *Timeval) (err error) {
   490  	return setsockopt(fd, level, opt, unsafe.Pointer(tv), unsafe.Sizeof(*tv))
   491  }
   492  
   493  func Socket(domain, typ, proto int) (fd int, err error) {
   494  	if domain == AF_INET6 && SocketDisableIPv6 {
   495  		return -1, EAFNOSUPPORT
   496  	}
   497  	fd, err = socket(domain, typ, proto)
   498  	return
   499  }
   500  
   501  func Socketpair(domain, typ, proto int) (fd [2]int, err error) {
   502  	var fdx [2]int32
   503  	err = socketpair(domain, typ, proto, &fdx)
   504  	if err == nil {
   505  		fd[0] = int(fdx[0])
   506  		fd[1] = int(fdx[1])
   507  	}
   508  	return
   509  }
   510  
   511  func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
   512  	if race.Enabled {
   513  		race.ReleaseMerge(unsafe.Pointer(&ioSync))
   514  	}
   515  	return sendfile(outfd, infd, offset, count)
   516  }
   517  
   518  var ioSync int64
   519  

View as plain text