src/pkg/syscall/syscall_unix.go - The Go Programming Language

Golang

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 darwin 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 darwinAMD64 = runtime.GOOS == "darwin" && runtime.GOARCH == "amd64"
    22	
    23	func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
    24	func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
    25	func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
    26	func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
    27	
    28	// Mmap manager, for use by operating system-specific implementations.
    29	
    30	type mmapper struct {
    31		sync.Mutex
    32		active map[*byte][]byte // active mappings; key is last byte in mapping
    33		mmap   func(addr, length uintptr, prot, flags, fd int, offset int64) (uintptr, error)
    34		munmap func(addr uintptr, length uintptr) error
    35	}
    36	
    37	func (m *mmapper) Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
    38		if length <= 0 {
    39			return nil, EINVAL
    40		}
    41	
    42		// Map the requested memory.
    43		addr, errno := m.mmap(0, uintptr(length), prot, flags, fd, offset)
    44		if errno != nil {
    45			return nil, errno
    46		}
    47	
    48		// Slice memory layout
    49		var sl = struct {
    50			addr uintptr
    51			len  int
    52			cap  int
    53		}{addr, length, length}
    54	
    55		// Use unsafe to turn sl into a []byte.
    56		b := *(*[]byte)(unsafe.Pointer(&sl))
    57	
    58		// Register mapping in m and return it.
    59		p := &b[cap(b)-1]
    60		m.Lock()
    61		defer m.Unlock()
    62		m.active[p] = b
    63		return b, nil
    64	}
    65	
    66	func (m *mmapper) Munmap(data []byte) (err error) {
    67		if len(data) == 0 || len(data) != cap(data) {
    68			return EINVAL
    69		}
    70	
    71		// Find the base of the mapping.
    72		p := &data[cap(data)-1]
    73		m.Lock()
    74		defer m.Unlock()
    75		b := m.active[p]
    76		if b == nil || &b[0] != &data[0] {
    77			return EINVAL
    78		}
    79	
    80		// Unmap the memory and update m.
    81		if errno := m.munmap(uintptr(unsafe.Pointer(&b[0])), uintptr(len(b))); errno != nil {
    82			return errno
    83		}
    84		delete(m.active, p)
    85		return nil
    86	}
    87	
    88	// An Errno is an unsigned number describing an error condition.
    89	// It implements the error interface.  The zero Errno is by convention
    90	// a non-error, so code to convert from Errno to error should use:
    91	//	err = nil
    92	//	if errno != 0 {
    93	//		err = errno
    94	//	}
    95	type Errno uintptr
    96	
    97	func (e Errno) Error() string {
    98		if 0 <= int(e) && int(e) < len(errors) {
    99			s := errors[e]
   100			if s != "" {
   101				return s
   102			}
   103		}
   104		return "errno " + itoa(int(e))
   105	}
   106	
   107	func (e Errno) Temporary() bool {
   108		return e == EINTR || e == EMFILE || e.Timeout()
   109	}
   110	
   111	func (e Errno) Timeout() bool {
   112		return e == EAGAIN || e == EWOULDBLOCK || e == ETIMEDOUT
   113	}
   114	
   115	// A Signal is a number describing a process signal.
   116	// It implements the os.Signal interface.
   117	type Signal int
   118	
   119	func (s Signal) Signal() {}
   120	
   121	func (s Signal) String() string {
   122		if 0 <= s && int(s) < len(signals) {
   123			str := signals[s]
   124			if str != "" {
   125				return str
   126			}
   127		}
   128		return "signal " + itoa(int(s))
   129	}