github.com/gidoBOSSftw5731/go/src@v0.0.0-20210226122457-d24b0edbf019/syscall/syscall_unix.go (about)

     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  // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
     7  
     8  package syscall
     9  
    10  import (
    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(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(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  	return
   201  }
   202  
   203  func Write(fd int, p []byte) (n int, err error) {
   204  	if race.Enabled {
   205  		race.ReleaseMerge(unsafe.Pointer(&ioSync))
   206  	}
   207  	if faketime && (fd == 1 || fd == 2) {
   208  		n = faketimeWrite(fd, p)
   209  		if n < 0 {
   210  			n, err = 0, errnoErr(Errno(-n))
   211  		}
   212  	} else {
   213  		n, err = write(fd, p)
   214  	}
   215  	if race.Enabled && n > 0 {
   216  		race.ReadRange(unsafe.Pointer(&p[0]), n)
   217  	}
   218  	if msanenabled && n > 0 {
   219  		msanRead(unsafe.Pointer(&p[0]), n)
   220  	}
   221  	return
   222  }
   223  
   224  // For testing: clients can set this flag to force
   225  // creation of IPv6 sockets to return EAFNOSUPPORT.
   226  var SocketDisableIPv6 bool
   227  
   228  type Sockaddr interface {
   229  	sockaddr() (ptr unsafe.Pointer, len _Socklen, err error) // lowercase; only we can define Sockaddrs
   230  }
   231  
   232  type SockaddrInet4 struct {
   233  	Port int
   234  	Addr [4]byte
   235  	raw  RawSockaddrInet4
   236  }
   237  
   238  type SockaddrInet6 struct {
   239  	Port   int
   240  	ZoneId uint32
   241  	Addr   [16]byte
   242  	raw    RawSockaddrInet6
   243  }
   244  
   245  type SockaddrUnix struct {
   246  	Name string
   247  	raw  RawSockaddrUnix
   248  }
   249  
   250  func Bind(fd int, sa Sockaddr) (err error) {
   251  	ptr, n, err := sa.sockaddr()
   252  	if err != nil {
   253  		return err
   254  	}
   255  	return bind(fd, ptr, n)
   256  }
   257  
   258  func Connect(fd int, sa Sockaddr) (err error) {
   259  	ptr, n, err := sa.sockaddr()
   260  	if err != nil {
   261  		return err
   262  	}
   263  	return connect(fd, ptr, n)
   264  }
   265  
   266  func Getpeername(fd int) (sa Sockaddr, err error) {
   267  	var rsa RawSockaddrAny
   268  	var len _Socklen = SizeofSockaddrAny
   269  	if err = getpeername(fd, &rsa, &len); err != nil {
   270  		return
   271  	}
   272  	return anyToSockaddr(&rsa)
   273  }
   274  
   275  func GetsockoptInt(fd, level, opt int) (value int, err error) {
   276  	var n int32
   277  	vallen := _Socklen(4)
   278  	err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen)
   279  	return int(n), err
   280  }
   281  
   282  func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) {
   283  	var rsa RawSockaddrAny
   284  	var len _Socklen = SizeofSockaddrAny
   285  	if n, err = recvfrom(fd, p, flags, &rsa, &len); err != nil {
   286  		return
   287  	}
   288  	if rsa.Addr.Family != AF_UNSPEC {
   289  		from, err = anyToSockaddr(&rsa)
   290  	}
   291  	return
   292  }
   293  
   294  func Sendto(fd int, p []byte, flags int, to Sockaddr) (err error) {
   295  	ptr, n, err := to.sockaddr()
   296  	if err != nil {
   297  		return err
   298  	}
   299  	return sendto(fd, p, flags, ptr, n)
   300  }
   301  
   302  func SetsockoptByte(fd, level, opt int, value byte) (err error) {
   303  	return setsockopt(fd, level, opt, unsafe.Pointer(&value), 1)
   304  }
   305  
   306  func SetsockoptInt(fd, level, opt int, value int) (err error) {
   307  	var n = int32(value)
   308  	return setsockopt(fd, level, opt, unsafe.Pointer(&n), 4)
   309  }
   310  
   311  func SetsockoptInet4Addr(fd, level, opt int, value [4]byte) (err error) {
   312  	return setsockopt(fd, level, opt, unsafe.Pointer(&value[0]), 4)
   313  }
   314  
   315  func SetsockoptIPMreq(fd, level, opt int, mreq *IPMreq) (err error) {
   316  	return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPMreq)
   317  }
   318  
   319  func SetsockoptIPv6Mreq(fd, level, opt int, mreq *IPv6Mreq) (err error) {
   320  	return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPv6Mreq)
   321  }
   322  
   323  func SetsockoptICMPv6Filter(fd, level, opt int, filter *ICMPv6Filter) error {
   324  	return setsockopt(fd, level, opt, unsafe.Pointer(filter), SizeofICMPv6Filter)
   325  }
   326  
   327  func SetsockoptLinger(fd, level, opt int, l *Linger) (err error) {
   328  	return setsockopt(fd, level, opt, unsafe.Pointer(l), SizeofLinger)
   329  }
   330  
   331  func SetsockoptString(fd, level, opt int, s string) (err error) {
   332  	var p unsafe.Pointer
   333  	if len(s) > 0 {
   334  		p = unsafe.Pointer(&[]byte(s)[0])
   335  	}
   336  	return setsockopt(fd, level, opt, p, uintptr(len(s)))
   337  }
   338  
   339  func SetsockoptTimeval(fd, level, opt int, tv *Timeval) (err error) {
   340  	return setsockopt(fd, level, opt, unsafe.Pointer(tv), unsafe.Sizeof(*tv))
   341  }
   342  
   343  func Socket(domain, typ, proto int) (fd int, err error) {
   344  	if domain == AF_INET6 && SocketDisableIPv6 {
   345  		return -1, EAFNOSUPPORT
   346  	}
   347  	fd, err = socket(domain, typ, proto)
   348  	return
   349  }
   350  
   351  func Socketpair(domain, typ, proto int) (fd [2]int, err error) {
   352  	var fdx [2]int32
   353  	err = socketpair(domain, typ, proto, &fdx)
   354  	if err == nil {
   355  		fd[0] = int(fdx[0])
   356  		fd[1] = int(fdx[1])
   357  	}
   358  	return
   359  }
   360  
   361  func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
   362  	if race.Enabled {
   363  		race.ReleaseMerge(unsafe.Pointer(&ioSync))
   364  	}
   365  	return sendfile(outfd, infd, offset, count)
   366  }
   367  
   368  var ioSync int64