Source file
src/syscall/syscall_unix.go
Documentation: syscall
1
2
3
4
5
6
7 package syscall
8
9 import (
10 "internal/bytealg"
11 "internal/itoa"
12 "internal/oserror"
13 "internal/race"
14 "internal/unsafeheader"
15 "runtime"
16 "sync"
17 "unsafe"
18 )
19
20 var (
21 Stdin = 0
22 Stdout = 1
23 Stderr = 2
24 )
25
26 const (
27 darwin64Bit = (runtime.GOOS == "darwin" || runtime.GOOS == "ios") && sizeofPtr == 8
28 netbsd32Bit = runtime.GOOS == "netbsd" && sizeofPtr == 4
29 )
30
31
32 func clen(n []byte) int {
33 if i := bytealg.IndexByte(n, 0); i != -1 {
34 return i
35 }
36 return len(n)
37 }
38
39
40
41 type mmapper struct {
42 sync.Mutex
43 active map[*byte][]byte
44 mmap func(addr, length uintptr, prot, flags, fd int, offset int64) (uintptr, error)
45 munmap func(addr uintptr, length uintptr) error
46 }
47
48 func (m *mmapper) Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
49 if length <= 0 {
50 return nil, EINVAL
51 }
52
53
54 addr, errno := m.mmap(0, uintptr(length), prot, flags, fd, offset)
55 if errno != nil {
56 return nil, errno
57 }
58
59
60 var b []byte
61 hdr := (*unsafeheader.Slice)(unsafe.Pointer(&b))
62 hdr.Data = unsafe.Pointer(addr)
63 hdr.Cap = length
64 hdr.Len = length
65
66
67 p := &b[cap(b)-1]
68 m.Lock()
69 defer m.Unlock()
70 m.active[p] = b
71 return b, nil
72 }
73
74 func (m *mmapper) Munmap(data []byte) (err error) {
75 if len(data) == 0 || len(data) != cap(data) {
76 return EINVAL
77 }
78
79
80 p := &data[cap(data)-1]
81 m.Lock()
82 defer m.Unlock()
83 b := m.active[p]
84 if b == nil || &b[0] != &data[0] {
85 return EINVAL
86 }
87
88
89 if errno := m.munmap(uintptr(unsafe.Pointer(&b[0])), uintptr(len(b))); errno != nil {
90 return errno
91 }
92 delete(m.active, p)
93 return nil
94 }
95
96
97
98
99
100
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.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 == ENFILE || 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.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 if asanenabled && n > 0 {
196 asanWrite(unsafe.Pointer(&p[0]), n)
197 }
198 return
199 }
200
201 func Write(fd int, p []byte) (n int, err error) {
202 if race.Enabled {
203 race.ReleaseMerge(unsafe.Pointer(&ioSync))
204 }
205 if faketime && (fd == 1 || fd == 2) {
206 n = faketimeWrite(fd, p)
207 if n < 0 {
208 n, err = 0, errnoErr(Errno(-n))
209 }
210 } else {
211 n, err = write(fd, p)
212 }
213 if race.Enabled && n > 0 {
214 race.ReadRange(unsafe.Pointer(&p[0]), n)
215 }
216 if msanenabled && n > 0 {
217 msanRead(unsafe.Pointer(&p[0]), n)
218 }
219 if asanenabled && n > 0 {
220 asanRead(unsafe.Pointer(&p[0]), n)
221 }
222 return
223 }
224
225 func Pread(fd int, p []byte, offset int64) (n int, err error) {
226 n, err = pread(fd, p, offset)
227 if race.Enabled {
228 if n > 0 {
229 race.WriteRange(unsafe.Pointer(&p[0]), n)
230 }
231 if err == nil {
232 race.Acquire(unsafe.Pointer(&ioSync))
233 }
234 }
235 if msanenabled && n > 0 {
236 msanWrite(unsafe.Pointer(&p[0]), n)
237 }
238 if asanenabled && n > 0 {
239 asanWrite(unsafe.Pointer(&p[0]), n)
240 }
241 return
242 }
243
244 func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
245 if race.Enabled {
246 race.ReleaseMerge(unsafe.Pointer(&ioSync))
247 }
248 n, err = pwrite(fd, p, offset)
249 if race.Enabled && n > 0 {
250 race.ReadRange(unsafe.Pointer(&p[0]), n)
251 }
252 if msanenabled && n > 0 {
253 msanRead(unsafe.Pointer(&p[0]), n)
254 }
255 if asanenabled && n > 0 {
256 asanRead(unsafe.Pointer(&p[0]), n)
257 }
258 return
259 }
260
261
262
263 var SocketDisableIPv6 bool
264
265 type Sockaddr interface {
266 sockaddr() (ptr unsafe.Pointer, len _Socklen, err error)
267 }
268
269 type SockaddrInet4 struct {
270 Port int
271 Addr [4]byte
272 raw RawSockaddrInet4
273 }
274
275 type SockaddrInet6 struct {
276 Port int
277 ZoneId uint32
278 Addr [16]byte
279 raw RawSockaddrInet6
280 }
281
282 type SockaddrUnix struct {
283 Name string
284 raw RawSockaddrUnix
285 }
286
287 func Bind(fd int, sa Sockaddr) (err error) {
288 ptr, n, err := sa.sockaddr()
289 if err != nil {
290 return err
291 }
292 return bind(fd, ptr, n)
293 }
294
295 func Connect(fd int, sa Sockaddr) (err error) {
296 ptr, n, err := sa.sockaddr()
297 if err != nil {
298 return err
299 }
300 return connect(fd, ptr, n)
301 }
302
303 func Getpeername(fd int) (sa Sockaddr, err error) {
304 var rsa RawSockaddrAny
305 var len _Socklen = SizeofSockaddrAny
306 if err = getpeername(fd, &rsa, &len); err != nil {
307 return
308 }
309 return anyToSockaddr(&rsa)
310 }
311
312 func GetsockoptInt(fd, level, opt int) (value int, err error) {
313 var n int32
314 vallen := _Socklen(4)
315 err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen)
316 return int(n), err
317 }
318
319 func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) {
320 var rsa RawSockaddrAny
321 var len _Socklen = SizeofSockaddrAny
322 if n, err = recvfrom(fd, p, flags, &rsa, &len); err != nil {
323 return
324 }
325 if rsa.Addr.Family != AF_UNSPEC {
326 from, err = anyToSockaddr(&rsa)
327 }
328 return
329 }
330
331 func recvfromInet4(fd int, p []byte, flags int, from *SockaddrInet4) (n int, err error) {
332 var rsa RawSockaddrAny
333 var socklen _Socklen = SizeofSockaddrAny
334 if n, err = recvfrom(fd, p, flags, &rsa, &socklen); err != nil {
335 return
336 }
337 pp := (*RawSockaddrInet4)(unsafe.Pointer(&rsa))
338 port := (*[2]byte)(unsafe.Pointer(&pp.Port))
339 from.Port = int(port[0])<<8 + int(port[1])
340 from.Addr = pp.Addr
341 return
342 }
343
344 func recvfromInet6(fd int, p []byte, flags int, from *SockaddrInet6) (n int, err error) {
345 var rsa RawSockaddrAny
346 var socklen _Socklen = SizeofSockaddrAny
347 if n, err = recvfrom(fd, p, flags, &rsa, &socklen); err != nil {
348 return
349 }
350 pp := (*RawSockaddrInet6)(unsafe.Pointer(&rsa))
351 port := (*[2]byte)(unsafe.Pointer(&pp.Port))
352 from.Port = int(port[0])<<8 + int(port[1])
353 from.ZoneId = pp.Scope_id
354 from.Addr = pp.Addr
355 return
356 }
357
358 func recvmsgInet4(fd int, p, oob []byte, flags int, from *SockaddrInet4) (n, oobn int, recvflags int, err error) {
359 var rsa RawSockaddrAny
360 n, oobn, recvflags, err = recvmsgRaw(fd, p, oob, flags, &rsa)
361 if err != nil {
362 return
363 }
364 pp := (*RawSockaddrInet4)(unsafe.Pointer(&rsa))
365 port := (*[2]byte)(unsafe.Pointer(&pp.Port))
366 from.Port = int(port[0])<<8 + int(port[1])
367 from.Addr = pp.Addr
368 return
369 }
370
371 func recvmsgInet6(fd int, p, oob []byte, flags int, from *SockaddrInet6) (n, oobn int, recvflags int, err error) {
372 var rsa RawSockaddrAny
373 n, oobn, recvflags, err = recvmsgRaw(fd, p, oob, flags, &rsa)
374 if err != nil {
375 return
376 }
377 pp := (*RawSockaddrInet6)(unsafe.Pointer(&rsa))
378 port := (*[2]byte)(unsafe.Pointer(&pp.Port))
379 from.Port = int(port[0])<<8 + int(port[1])
380 from.ZoneId = pp.Scope_id
381 from.Addr = pp.Addr
382 return
383 }
384
385 func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) {
386 var rsa RawSockaddrAny
387 n, oobn, recvflags, err = recvmsgRaw(fd, p, oob, flags, &rsa)
388
389 if rsa.Addr.Family != AF_UNSPEC {
390 from, err = anyToSockaddr(&rsa)
391 }
392 return
393 }
394
395 func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) {
396 _, err = SendmsgN(fd, p, oob, to, flags)
397 return
398 }
399
400 func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) {
401 var ptr unsafe.Pointer
402 var salen _Socklen
403 if to != nil {
404 ptr, salen, err = to.sockaddr()
405 if err != nil {
406 return 0, err
407 }
408 }
409 return sendmsgN(fd, p, oob, ptr, salen, flags)
410 }
411
412 func sendmsgNInet4(fd int, p, oob []byte, to *SockaddrInet4, flags int) (n int, err error) {
413 ptr, salen, err := to.sockaddr()
414 if err != nil {
415 return 0, err
416 }
417 return sendmsgN(fd, p, oob, ptr, salen, flags)
418 }
419
420 func sendmsgNInet6(fd int, p, oob []byte, to *SockaddrInet6, flags int) (n int, err error) {
421 ptr, salen, err := to.sockaddr()
422 if err != nil {
423 return 0, err
424 }
425 return sendmsgN(fd, p, oob, ptr, salen, flags)
426 }
427
428 func sendtoInet4(fd int, p []byte, flags int, to *SockaddrInet4) (err error) {
429 ptr, n, err := to.sockaddr()
430 if err != nil {
431 return err
432 }
433 return sendto(fd, p, flags, ptr, n)
434 }
435
436 func sendtoInet6(fd int, p []byte, flags int, to *SockaddrInet6) (err error) {
437 ptr, n, err := to.sockaddr()
438 if err != nil {
439 return err
440 }
441 return sendto(fd, p, flags, ptr, n)
442 }
443
444 func Sendto(fd int, p []byte, flags int, to Sockaddr) (err error) {
445 ptr, n, err := to.sockaddr()
446 if err != nil {
447 return err
448 }
449 return sendto(fd, p, flags, ptr, n)
450 }
451
452 func SetsockoptByte(fd, level, opt int, value byte) (err error) {
453 return setsockopt(fd, level, opt, unsafe.Pointer(&value), 1)
454 }
455
456 func SetsockoptInt(fd, level, opt int, value int) (err error) {
457 var n = int32(value)
458 return setsockopt(fd, level, opt, unsafe.Pointer(&n), 4)
459 }
460
461 func SetsockoptInet4Addr(fd, level, opt int, value [4]byte) (err error) {
462 return setsockopt(fd, level, opt, unsafe.Pointer(&value[0]), 4)
463 }
464
465 func SetsockoptIPMreq(fd, level, opt int, mreq *IPMreq) (err error) {
466 return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPMreq)
467 }
468
469 func SetsockoptIPv6Mreq(fd, level, opt int, mreq *IPv6Mreq) (err error) {
470 return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPv6Mreq)
471 }
472
473 func SetsockoptICMPv6Filter(fd, level, opt int, filter *ICMPv6Filter) error {
474 return setsockopt(fd, level, opt, unsafe.Pointer(filter), SizeofICMPv6Filter)
475 }
476
477 func SetsockoptLinger(fd, level, opt int, l *Linger) (err error) {
478 return setsockopt(fd, level, opt, unsafe.Pointer(l), SizeofLinger)
479 }
480
481 func SetsockoptString(fd, level, opt int, s string) (err error) {
482 var p unsafe.Pointer
483 if len(s) > 0 {
484 p = unsafe.Pointer(&[]byte(s)[0])
485 }
486 return setsockopt(fd, level, opt, p, uintptr(len(s)))
487 }
488
489 func SetsockoptTimeval(fd, level, opt int, tv *Timeval) (err error) {
490 return setsockopt(fd, level, opt, unsafe.Pointer(tv), unsafe.Sizeof(*tv))
491 }
492
493 func Socket(domain, typ, proto int) (fd int, err error) {
494 if domain == AF_INET6 && SocketDisableIPv6 {
495 return -1, EAFNOSUPPORT
496 }
497 fd, err = socket(domain, typ, proto)
498 return
499 }
500
501 func Socketpair(domain, typ, proto int) (fd [2]int, err error) {
502 var fdx [2]int32
503 err = socketpair(domain, typ, proto, &fdx)
504 if err == nil {
505 fd[0] = int(fdx[0])
506 fd[1] = int(fdx[1])
507 }
508 return
509 }
510
511 func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
512 if race.Enabled {
513 race.ReleaseMerge(unsafe.Pointer(&ioSync))
514 }
515 return sendfile(outfd, infd, offset, count)
516 }
517
518 var ioSync int64
519
View as plain text