Source file src/pkg/syscall/syscall_unix.go
1
2
3
4
5
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
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
44
45 type mmapper struct {
46 sync.Mutex
47 active map[*byte][]byte
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
58 addr, errno := m.mmap(0, uintptr(length), prot, flags, fd, offset)
59 if errno != nil {
60 return nil, errno
61 }
62
63
64 var sl = struct {
65 addr uintptr
66 len int
67 cap int
68 }{addr, length, length}
69
70
71 b := *(*[]byte)(unsafe.Pointer(&sl))
72
73
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
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
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
104
105
106
107
108
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
143
144 var (
145 errEAGAIN error = EAGAIN
146 errEINVAL error = EINVAL
147 errENOENT error = ENOENT
148 )
149
150
151
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
167
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
213
214 var SocketDisableIPv6 bool
215
216 type Sockaddr interface {
217 sockaddr() (ptr unsafe.Pointer, len _Socklen, err error)
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