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

View as plain text