...
Run Format

Source file src/syscall/syscall_unix.go

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

View as plain text