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 }