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