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 }