OSDN Git Service

e3c6629ed077e6b3f0373c8720f977a81ff2090d
[pf3gnuchains/gcc-fork.git] / libgo / go / 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 //extern syscall
22 func c_syscall32(trap int32, a1, a2, a3, a4, a5, a6 int32) int32
23
24 //extern syscall
25 func c_syscall64(trap int64, a1, a2, a3, a4, a5, a6 int64) int64
26
27 const darwinAMD64 = runtime.GOOS == "darwin" && runtime.GOARCH == "amd64"
28
29 // Do a system call.  We look at the size of uintptr to see how to pass
30 // the arguments, so that we don't pass a 64-bit value when the function
31 // expects a 32-bit one.
32 func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) {
33         Entersyscall()
34         var r uintptr
35         if unsafe.Sizeof(r) == 4 {
36                 r1 := c_syscall32(int32(trap), int32(a1), int32(a2), int32(a3), 0, 0, 0)
37                 r = uintptr(r1)
38         } else {
39                 r1 := c_syscall64(int64(trap), int64(a1), int64(a2), int64(a3), 0, 0, 0)
40                 r = uintptr(r1)
41         }
42         err = GetErrno()
43         Exitsyscall()
44         return r, 0, err
45 }
46
47 func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) {
48         Entersyscall()
49         var r uintptr
50         if unsafe.Sizeof(r) == 4 {
51                 r1 := c_syscall32(int32(trap), int32(a1), int32(a2), int32(a3),
52                         int32(a4), int32(a5), int32(a6))
53                 r = uintptr(r1)
54         } else {
55                 r1 := c_syscall64(int64(trap), int64(a1), int64(a2), int64(a3),
56                         int64(a4), int64(a5), int64(a6))
57                 r = uintptr(r1)
58         }
59         err = GetErrno()
60         Exitsyscall()
61         return r, 0, err
62 }
63
64 func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) {
65         var r uintptr
66         if unsafe.Sizeof(r) == 4 {
67                 r1 := c_syscall32(int32(trap), int32(a1), int32(a2), int32(a3), 0, 0, 0)
68                 r = uintptr(r1)
69         } else {
70                 r1 := c_syscall64(int64(trap), int64(a1), int64(a2), int64(a3), 0, 0, 0)
71                 r = uintptr(r1)
72         }
73         err = GetErrno()
74         return r, 0, err
75 }
76
77 func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) {
78         var r uintptr
79         if unsafe.Sizeof(r) == 4 {
80                 r1 := c_syscall32(int32(trap), int32(a1), int32(a2), int32(a3),
81                         int32(a4), int32(a5), int32(a6))
82                 r = uintptr(r1)
83         } else {
84                 r1 := c_syscall64(int64(trap), int64(a1), int64(a2), int64(a3),
85                         int64(a4), int64(a5), int64(a6))
86                 r = uintptr(r1)
87         }
88         err = GetErrno()
89         return r, 0, err
90 }
91
92 // Mmap manager, for use by operating system-specific implementations.
93 // Gccgo only has one implementation but we do this to correspond to gc.
94
95 type mmapper struct {
96         sync.Mutex
97         active map[*byte][]byte // active mappings; key is last byte in mapping
98         mmap   func(addr, length uintptr, prot, flags, fd int, offset int64) (uintptr, error)
99         munmap func(addr uintptr, length uintptr) error
100 }
101
102 func (m *mmapper) Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
103         if length <= 0 {
104                 return nil, EINVAL
105         }
106
107         // Map the requested memory.
108         addr, errno := m.mmap(0, uintptr(length), prot, flags, fd, offset)
109         if errno != nil {
110                 return nil, errno
111         }
112
113         // Slice memory layout
114         var sl = struct {
115                 addr uintptr
116                 len  int
117                 cap  int
118         }{addr, length, length}
119
120         // Use unsafe to turn sl into a []byte.
121         b := *(*[]byte)(unsafe.Pointer(&sl))
122
123         // Register mapping in m and return it.
124         p := &b[cap(b)-1]
125         m.Lock()
126         defer m.Unlock()
127         m.active[p] = b
128         return b, nil
129 }
130
131 func (m *mmapper) Munmap(data []byte) (err error) {
132         if len(data) == 0 || len(data) != cap(data) {
133                 return EINVAL
134         }
135
136         // Find the base of the mapping.
137         p := &data[cap(data)-1]
138         m.Lock()
139         defer m.Unlock()
140         b := m.active[p]
141         if b == nil || &b[0] != &data[0] {
142                 return EINVAL
143         }
144
145         // Unmap the memory and update m.
146         if errno := m.munmap(uintptr(unsafe.Pointer(&b[0])), uintptr(len(b))); errno != nil {
147                 return errno
148         }
149         m.active[p] = nil, false
150         return nil
151 }
152
153 var mapper = &mmapper{
154         active: make(map[*byte][]byte),
155         mmap:   mmap,
156         munmap: munmap,
157 }
158
159 func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
160         return mapper.Mmap(fd, offset, length, prot, flags)
161 }
162
163 func Munmap(b []byte) (err error) {
164         return mapper.Munmap(b)
165 }
166
167 // A Signal is a number describing a process signal.
168 // It implements the os.Signal interface.
169 type Signal int
170
171 func (s Signal) Signal() {}
172
173 func Signame(s Signal) string
174
175 func (s Signal) String() string {
176         return Signame(s)
177 }