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