github.com/epfl-dcsl/gotee@v0.0.0-20200909122901-014b35f5e5e9/src/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  // +build darwin dragonfly freebsd linux netbsd openbsd solaris
     6  
     7  package syscall
     8  
     9  import (
    10  	"internal/race"
    11  	"runtime"
    12  	"sync"
    13  	"unsafe"
    14  )
    15  
    16  var (
    17  	Stdin  = 0
    18  	Stdout = 1
    19  	Stderr = 2
    20  )
    21  
    22  const (
    23  	darwin64Bit    = runtime.GOOS == "darwin" && sizeofPtr == 8
    24  	dragonfly64Bit = runtime.GOOS == "dragonfly" && sizeofPtr == 8
    25  	netbsd32Bit    = runtime.GOOS == "netbsd" && sizeofPtr == 4
    26  	solaris64Bit   = runtime.GOOS == "solaris" && sizeofPtr == 8
    27  )
    28  
    29  func SSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
    30  func SSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
    31  func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
    32  func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
    33  
    34  // Mmap manager, for use by operating system-specific implementations.
    35  
    36  type mmapper struct {
    37  	sync.Mutex
    38  	active map[*byte][]byte // active mappings; key is last byte in mapping
    39  	mmap   func(addr, length uintptr, prot, flags, fd int, offset int64) (uintptr, error)
    40  	munmap func(addr uintptr, length uintptr) error
    41  }
    42  
    43  func (m *mmapper) Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
    44  	if length <= 0 {
    45  		return nil, EINVAL
    46  	}
    47  
    48  	// Map the requested memory.
    49  	addr, errno := m.mmap(0, uintptr(length), prot, flags, fd, offset)
    50  	if errno != nil {
    51  		return nil, errno
    52  	}
    53  
    54  	// Slice memory layout
    55  	var sl = struct {
    56  		addr uintptr
    57  		len  int
    58  		cap  int
    59  	}{addr, length, length}
    60  
    61  	// Use unsafe to turn sl into a []byte.
    62  	b := *(*[]byte)(unsafe.Pointer(&sl))
    63  
    64  	// Register mapping in m and return it.
    65  	p := &b[cap(b)-1]
    66  	m.Lock()
    67  	defer m.Unlock()
    68  	m.active[p] = b
    69  	return b, nil
    70  }
    71  
    72  func (m *mmapper) RMmap(ptr uintptr, length, prot, flags, fd int, offset int64) (data []byte, err error) {
    73  	if length <= 0 {
    74  		return nil, EINVAL
    75  	}
    76  
    77  	// Map the requested memory.
    78  	addr, errno := m.mmap(ptr, uintptr(length), prot, flags, fd, offset)
    79  	if errno != nil {
    80  		return nil, errno
    81  	}
    82  
    83  	// Slice memory layout
    84  	var sl = struct {
    85  		addr uintptr
    86  		len  int
    87  		cap  int
    88  	}{addr, length, length}
    89  
    90  	// Use unsafe to turn sl into a []byte.
    91  	b := *(*[]byte)(unsafe.Pointer(&sl))
    92  
    93  	// Register mapping in m and return it.
    94  	p := &b[cap(b)-1]
    95  	m.Lock()
    96  	defer m.Unlock()
    97  	m.active[p] = b
    98  	return b, nil
    99  }
   100  
   101  func (m *mmapper) Munmap(data []byte) (err error) {
   102  	if len(data) == 0 || len(data) != cap(data) {
   103  		return EINVAL
   104  	}
   105  
   106  	// Find the base of the mapping.
   107  	p := &data[cap(data)-1]
   108  	m.Lock()
   109  	defer m.Unlock()
   110  	b := m.active[p]
   111  	if b == nil || &b[0] != &data[0] {
   112  		return EINVAL
   113  	}
   114  
   115  	// Unmap the memory and update m.
   116  	if errno := m.munmap(uintptr(unsafe.Pointer(&b[0])), uintptr(len(b))); errno != nil {
   117  		return errno
   118  	}
   119  	delete(m.active, p)
   120  	return nil
   121  }
   122  
   123  // An Errno is an unsigned number describing an error condition.
   124  // It implements the error interface. The zero Errno is by convention
   125  // a non-error, so code to convert from Errno to error should use:
   126  //	err = nil
   127  //	if errno != 0 {
   128  //		err = errno
   129  //	}
   130  type Errno uintptr
   131  
   132  func (e Errno) Error() string {
   133  	if 0 <= int(e) && int(e) < len(errors) {
   134  		s := errors[e]
   135  		if s != "" {
   136  			return s
   137  		}
   138  	}
   139  	return "errno " + itoa(int(e))
   140  }
   141  
   142  func (e Errno) Temporary() bool {
   143  	return e == EINTR || e == EMFILE || e == ECONNRESET || e == ECONNABORTED || e.Timeout()
   144  }
   145  
   146  func (e Errno) Timeout() bool {
   147  	return e == EAGAIN || e == EWOULDBLOCK || e == ETIMEDOUT
   148  }
   149  
   150  // Do the interface allocations only once for common
   151  // Errno values.
   152  var (
   153  	errEAGAIN error = EAGAIN
   154  	errEINVAL error = EINVAL
   155  	errENOENT error = ENOENT
   156  )
   157  
   158  // errnoErr returns common boxed Errno values, to prevent
   159  // allocations at runtime.
   160  func errnoErr(e Errno) error {
   161  	switch e {
   162  	case 0:
   163  		return nil
   164  	case EAGAIN:
   165  		return errEAGAIN
   166  	case EINVAL:
   167  		return errEINVAL
   168  	case ENOENT:
   169  		return errENOENT
   170  	}
   171  	return e
   172  }
   173  
   174  // A Signal is a number describing a process signal.
   175  // It implements the os.Signal interface.
   176  type Signal int
   177  
   178  func (s Signal) Signal() {}
   179  
   180  func (s Signal) String() string {
   181  	if 0 <= s && int(s) < len(signals) {
   182  		str := signals[s]
   183  		if str != "" {
   184  			return str
   185  		}
   186  	}
   187  	return "signal " + itoa(int(s))
   188  }
   189  
   190  func Read(fd int, p []byte) (n int, err error) {
   191  	n, err = read(fd, p)
   192  	if race.Enabled {
   193  		if n > 0 {
   194  			race.WriteRange(unsafe.Pointer(&p[0]), n)
   195  		}
   196  		if err == nil {
   197  			race.Acquire(unsafe.Pointer(&ioSync))
   198  		}
   199  	}
   200  	if msanenabled && n > 0 {
   201  		msanWrite(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  	n, err = write(fd, p)
   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  	return
   218  }
   219  
   220  // For testing: clients can set this flag to force
   221  // creation of IPv6 sockets to return EAFNOSUPPORT.
   222  var SocketDisableIPv6 bool
   223  
   224  type Sockaddr interface {
   225  	sockaddr() (ptr unsafe.Pointer, len _Socklen, err error) // lowercase; only we can define Sockaddrs
   226  }
   227  
   228  type SockaddrInet4 struct {
   229  	Port int
   230  	Addr [4]byte
   231  	raw  RawSockaddrInet4
   232  }
   233  
   234  type SockaddrInet6 struct {
   235  	Port   int
   236  	ZoneId uint32
   237  	Addr   [16]byte
   238  	raw    RawSockaddrInet6
   239  }
   240  
   241  type SockaddrUnix struct {
   242  	Name string
   243  	raw  RawSockaddrUnix
   244  }
   245  
   246  func Bind(fd int, sa Sockaddr) (err error) {
   247  	ptr, n, err := sa.sockaddr()
   248  	if err != nil {
   249  		return err
   250  	}
   251  	return bind(fd, ptr, n)
   252  }
   253  
   254  func Connect(fd int, sa Sockaddr) (err error) {
   255  	ptr, n, err := sa.sockaddr()
   256  	if err != nil {
   257  		return err
   258  	}
   259  	return connect(fd, ptr, n)
   260  }
   261  
   262  func Getpeername(fd int) (sa Sockaddr, err error) {
   263  	var rsa RawSockaddrAny
   264  	var len _Socklen = SizeofSockaddrAny
   265  	if err = getpeername(fd, &rsa, &len); err != nil {
   266  		return
   267  	}
   268  	return anyToSockaddr(&rsa)
   269  }
   270  
   271  func GetsockoptInt(fd, level, opt int) (value int, err error) {
   272  	var n int32
   273  	vallen := _Socklen(4)
   274  	err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen)
   275  	return int(n), err
   276  }
   277  
   278  func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) {
   279  	var rsa RawSockaddrAny
   280  	var len _Socklen = SizeofSockaddrAny
   281  	if n, err = recvfrom(fd, p, flags, &rsa, &len); err != nil {
   282  		return
   283  	}
   284  	if rsa.Addr.Family != AF_UNSPEC {
   285  		from, err = anyToSockaddr(&rsa)
   286  	}
   287  	return
   288  }
   289  
   290  func Sendto(fd int, p []byte, flags int, to Sockaddr) (err error) {
   291  	ptr, n, err := to.sockaddr()
   292  	if err != nil {
   293  		return err
   294  	}
   295  	return sendto(fd, p, flags, ptr, n)
   296  }
   297  
   298  func SetsockoptByte(fd, level, opt int, value byte) (err error) {
   299  	return setsockopt(fd, level, opt, unsafe.Pointer(&value), 1)
   300  }
   301  
   302  func SetsockoptInt(fd, level, opt int, value int) (err error) {
   303  	var n = int32(value)
   304  	return setsockopt(fd, level, opt, unsafe.Pointer(&n), 4)
   305  }
   306  
   307  func SetsockoptInet4Addr(fd, level, opt int, value [4]byte) (err error) {
   308  	return setsockopt(fd, level, opt, unsafe.Pointer(&value[0]), 4)
   309  }
   310  
   311  func SetsockoptIPMreq(fd, level, opt int, mreq *IPMreq) (err error) {
   312  	return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPMreq)
   313  }
   314  
   315  func SetsockoptIPv6Mreq(fd, level, opt int, mreq *IPv6Mreq) (err error) {
   316  	return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPv6Mreq)
   317  }
   318  
   319  func SetsockoptICMPv6Filter(fd, level, opt int, filter *ICMPv6Filter) error {
   320  	return setsockopt(fd, level, opt, unsafe.Pointer(filter), SizeofICMPv6Filter)
   321  }
   322  
   323  func SetsockoptLinger(fd, level, opt int, l *Linger) (err error) {
   324  	return setsockopt(fd, level, opt, unsafe.Pointer(l), SizeofLinger)
   325  }
   326  
   327  func SetsockoptString(fd, level, opt int, s string) (err error) {
   328  	return setsockopt(fd, level, opt, unsafe.Pointer(&[]byte(s)[0]), uintptr(len(s)))
   329  }
   330  
   331  func SetsockoptTimeval(fd, level, opt int, tv *Timeval) (err error) {
   332  	return setsockopt(fd, level, opt, unsafe.Pointer(tv), unsafe.Sizeof(*tv))
   333  }
   334  
   335  func Socket(domain, typ, proto int) (fd int, err error) {
   336  	if domain == AF_INET6 && SocketDisableIPv6 {
   337  		return -1, EAFNOSUPPORT
   338  	}
   339  	fd, err = socket(domain, typ, proto)
   340  	return
   341  }
   342  
   343  func Socketpair(domain, typ, proto int) (fd [2]int, err error) {
   344  	var fdx [2]int32
   345  	err = socketpair(domain, typ, proto, &fdx)
   346  	if err == nil {
   347  		fd[0] = int(fdx[0])
   348  		fd[1] = int(fdx[1])
   349  	}
   350  	return
   351  }
   352  
   353  func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
   354  	if race.Enabled {
   355  		race.ReleaseMerge(unsafe.Pointer(&ioSync))
   356  	}
   357  	return sendfile(outfd, infd, offset, count)
   358  }
   359  
   360  var ioSync int64