...
Run Format

Source file src/syscall/syscall_unix.go

Documentation: syscall

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

View as plain text