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

View as plain text