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