...

Source file src/pkg/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 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