Source file
src/syscall/syscall_unix.go
Documentation: syscall
1
2
3
4
5
6
7 package syscall
8
9 import (
10 errorspkg "errors"
11 "internal/bytealg"
12 "internal/itoa"
13 "internal/oserror"
14 "internal/race"
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 b := unsafe.Slice((*byte)(unsafe.Pointer(addr)), length)
61
62
63 p := &b[cap(b)-1]
64 m.Lock()
65 defer m.Unlock()
66 m.active[p] = b
67 return b, nil
68 }
69
70 func (m *mmapper) Munmap(data []byte) (err error) {
71 if len(data) == 0 || len(data) != cap(data) {
72 return EINVAL
73 }
74
75
76 p := &data[cap(data)-1]
77 m.Lock()
78 defer m.Unlock()
79 b := m.active[p]
80 if b == nil || &b[0] != &data[0] {
81 return EINVAL
82 }
83
84
85 if errno := m.munmap(uintptr(unsafe.Pointer(&b[0])), uintptr(len(b))); errno != nil {
86 return errno
87 }
88 delete(m.active, p)
89 return nil
90 }
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106 type Errno uintptr
107
108 func (e Errno) Error() string {
109 if 0 <= int(e) && int(e) < len(errors) {
110 s := errors[e]
111 if s != "" {
112 return s
113 }
114 }
115 return "errno " + itoa.Itoa(int(e))
116 }
117
118 func (e Errno) Is(target error) bool {
119 switch target {
120 case oserror.ErrPermission:
121 return e == EACCES || e == EPERM
122 case oserror.ErrExist:
123 return e == EEXIST || e == ENOTEMPTY
124 case oserror.ErrNotExist:
125 return e == ENOENT
126 case errorspkg.ErrUnsupported:
127 return e == ENOSYS || e == ENOTSUP || e == EOPNOTSUPP
128 }
129 return false
130 }
131
132 func (e Errno) Temporary() bool {
133 return e == EINTR || e == EMFILE || e == ENFILE || e.Timeout()
134 }
135
136 func (e Errno) Timeout() bool {
137 return e == EAGAIN || e == EWOULDBLOCK || e == ETIMEDOUT
138 }
139
140
141
142 var (
143 errEAGAIN error = EAGAIN
144 errEINVAL error = EINVAL
145 errENOENT error = ENOENT
146 )
147
148
149
150 func errnoErr(e Errno) error {
151 switch e {
152 case 0:
153 return nil
154 case EAGAIN:
155 return errEAGAIN
156 case EINVAL:
157 return errEINVAL
158 case ENOENT:
159 return errENOENT
160 }
161 return e
162 }
163
164
165
166 type Signal int
167
168 func (s Signal) Signal() {}
169
170 func (s Signal) String() string {
171 if 0 <= s && int(s) < len(signals) {
172 str := signals[s]
173 if str != "" {
174 return str
175 }
176 }
177 return "signal " + itoa.Itoa(int(s))
178 }
179
180 func Read(fd int, p []byte) (n int, err error) {
181 n, err = read(fd, p)
182 if race.Enabled {
183 if n > 0 {
184 race.WriteRange(unsafe.Pointer(&p[0]), n)
185 }
186 if err == nil {
187 race.Acquire(unsafe.Pointer(&ioSync))
188 }
189 }
190 if msanenabled && n > 0 {
191 msanWrite(unsafe.Pointer(&p[0]), n)
192 }
193 if asanenabled && n > 0 {
194 asanWrite(unsafe.Pointer(&p[0]), n)
195 }
196 return
197 }
198
199 func Write(fd int, p []byte) (n int, err error) {
200 if race.Enabled {
201 race.ReleaseMerge(unsafe.Pointer(&ioSync))
202 }
203 if faketime && (fd == 1 || fd == 2) {
204 n = faketimeWrite(fd, p)
205 if n < 0 {
206 n, err = 0, errnoErr(Errno(-n))
207 }
208 } else {
209 n, err = write(fd, p)
210 }
211 if race.Enabled && n > 0 {
212 race.ReadRange(unsafe.Pointer(&p[0]), n)
213 }
214 if msanenabled && n > 0 {
215 msanRead(unsafe.Pointer(&p[0]), n)
216 }
217 if asanenabled && n > 0 {
218 asanRead(unsafe.Pointer(&p[0]), n)
219 }
220 return
221 }
222
223 func Pread(fd int, p []byte, offset int64) (n int, err error) {
224 n, err = pread(fd, p, offset)
225 if race.Enabled {
226 if n > 0 {
227 race.WriteRange(unsafe.Pointer(&p[0]), n)
228 }
229 if err == nil {
230 race.Acquire(unsafe.Pointer(&ioSync))
231 }
232 }
233 if msanenabled && n > 0 {
234 msanWrite(unsafe.Pointer(&p[0]), n)
235 }
236 if asanenabled && n > 0 {
237 asanWrite(unsafe.Pointer(&p[0]), n)
238 }
239 return
240 }
241
242 func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
243 if race.Enabled {
244 race.ReleaseMerge(unsafe.Pointer(&ioSync))
245 }
246 n, err = pwrite(fd, p, offset)
247 if race.Enabled && n > 0 {
248 race.ReadRange(unsafe.Pointer(&p[0]), n)
249 }
250 if msanenabled && n > 0 {
251 msanRead(unsafe.Pointer(&p[0]), n)
252 }
253 if asanenabled && n > 0 {
254 asanRead(unsafe.Pointer(&p[0]), n)
255 }
256 return
257 }
258
259
260
261 var SocketDisableIPv6 bool
262
263 type Sockaddr interface {
264 sockaddr() (ptr unsafe.Pointer, len _Socklen, err error)
265 }
266
267 type SockaddrInet4 struct {
268 Port int
269 Addr [4]byte
270 raw RawSockaddrInet4
271 }
272
273 type SockaddrInet6 struct {
274 Port int
275 ZoneId uint32
276 Addr [16]byte
277 raw RawSockaddrInet6
278 }
279
280 type SockaddrUnix struct {
281 Name string
282 raw RawSockaddrUnix
283 }
284
285 func Bind(fd int, sa Sockaddr) (err error) {
286 ptr, n, err := sa.sockaddr()
287 if err != nil {
288 return err
289 }
290 return bind(fd, ptr, n)
291 }
292
293 func Connect(fd int, sa Sockaddr) (err error) {
294 ptr, n, err := sa.sockaddr()
295 if err != nil {
296 return err
297 }
298 return connect(fd, ptr, n)
299 }
300
301 func Getpeername(fd int) (sa Sockaddr, err error) {
302 var rsa RawSockaddrAny
303 var len _Socklen = SizeofSockaddrAny
304 if err = getpeername(fd, &rsa, &len); err != nil {
305 return
306 }
307 return anyToSockaddr(&rsa)
308 }
309
310 func GetsockoptInt(fd, level, opt int) (value int, err error) {
311 var n int32
312 vallen := _Socklen(4)
313 err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen)
314 return int(n), err
315 }
316
317 func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) {
318 var rsa RawSockaddrAny
319 var len _Socklen = SizeofSockaddrAny
320 if n, err = recvfrom(fd, p, flags, &rsa, &len); err != nil {
321 return
322 }
323 if rsa.Addr.Family != AF_UNSPEC {
324 from, err = anyToSockaddr(&rsa)
325 }
326 return
327 }
328
329 func recvfromInet4(fd int, p []byte, flags int, from *SockaddrInet4) (n int, err error) {
330 var rsa RawSockaddrAny
331 var socklen _Socklen = SizeofSockaddrAny
332 if n, err = recvfrom(fd, p, flags, &rsa, &socklen); err != nil {
333 return
334 }
335 pp := (*RawSockaddrInet4)(unsafe.Pointer(&rsa))
336 port := (*[2]byte)(unsafe.Pointer(&pp.Port))
337 from.Port = int(port[0])<<8 + int(port[1])
338 from.Addr = pp.Addr
339 return
340 }
341
342 func recvfromInet6(fd int, p []byte, flags int, from *SockaddrInet6) (n int, err error) {
343 var rsa RawSockaddrAny
344 var socklen _Socklen = SizeofSockaddrAny
345 if n, err = recvfrom(fd, p, flags, &rsa, &socklen); err != nil {
346 return
347 }
348 pp := (*RawSockaddrInet6)(unsafe.Pointer(&rsa))
349 port := (*[2]byte)(unsafe.Pointer(&pp.Port))
350 from.Port = int(port[0])<<8 + int(port[1])
351 from.ZoneId = pp.Scope_id
352 from.Addr = pp.Addr
353 return
354 }
355
356 func recvmsgInet4(fd int, p, oob []byte, flags int, from *SockaddrInet4) (n, oobn int, recvflags int, err error) {
357 var rsa RawSockaddrAny
358 n, oobn, recvflags, err = recvmsgRaw(fd, p, oob, flags, &rsa)
359 if err != nil {
360 return
361 }
362 pp := (*RawSockaddrInet4)(unsafe.Pointer(&rsa))
363 port := (*[2]byte)(unsafe.Pointer(&pp.Port))
364 from.Port = int(port[0])<<8 + int(port[1])
365 from.Addr = pp.Addr
366 return
367 }
368
369 func recvmsgInet6(fd int, p, oob []byte, flags int, from *SockaddrInet6) (n, oobn int, recvflags int, err error) {
370 var rsa RawSockaddrAny
371 n, oobn, recvflags, err = recvmsgRaw(fd, p, oob, flags, &rsa)
372 if err != nil {
373 return
374 }
375 pp := (*RawSockaddrInet6)(unsafe.Pointer(&rsa))
376 port := (*[2]byte)(unsafe.Pointer(&pp.Port))
377 from.Port = int(port[0])<<8 + int(port[1])
378 from.ZoneId = pp.Scope_id
379 from.Addr = pp.Addr
380 return
381 }
382
383 func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) {
384 var rsa RawSockaddrAny
385 n, oobn, recvflags, err = recvmsgRaw(fd, p, oob, flags, &rsa)
386
387 if rsa.Addr.Family != AF_UNSPEC {
388 from, err = anyToSockaddr(&rsa)
389 }
390 return
391 }
392
393 func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) {
394 _, err = SendmsgN(fd, p, oob, to, flags)
395 return
396 }
397
398 func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) {
399 var ptr unsafe.Pointer
400 var salen _Socklen
401 if to != nil {
402 ptr, salen, err = to.sockaddr()
403 if err != nil {
404 return 0, err
405 }
406 }
407 return sendmsgN(fd, p, oob, ptr, salen, flags)
408 }
409
410 func sendmsgNInet4(fd int, p, oob []byte, to *SockaddrInet4, flags int) (n int, err error) {
411 ptr, salen, err := to.sockaddr()
412 if err != nil {
413 return 0, err
414 }
415 return sendmsgN(fd, p, oob, ptr, salen, flags)
416 }
417
418 func sendmsgNInet6(fd int, p, oob []byte, to *SockaddrInet6, flags int) (n int, err error) {
419 ptr, salen, err := to.sockaddr()
420 if err != nil {
421 return 0, err
422 }
423 return sendmsgN(fd, p, oob, ptr, salen, flags)
424 }
425
426 func sendtoInet4(fd int, p []byte, flags int, to *SockaddrInet4) (err error) {
427 ptr, n, err := to.sockaddr()
428 if err != nil {
429 return err
430 }
431 return sendto(fd, p, flags, ptr, n)
432 }
433
434 func sendtoInet6(fd int, p []byte, flags int, to *SockaddrInet6) (err error) {
435 ptr, n, err := to.sockaddr()
436 if err != nil {
437 return err
438 }
439 return sendto(fd, p, flags, ptr, n)
440 }
441
442 func Sendto(fd int, p []byte, flags int, to Sockaddr) (err error) {
443 var (
444 ptr unsafe.Pointer
445 salen _Socklen
446 )
447 if to != nil {
448 ptr, salen, err = to.sockaddr()
449 if err != nil {
450 return err
451 }
452 }
453 return sendto(fd, p, flags, ptr, salen)
454 }
455
456 func SetsockoptByte(fd, level, opt int, value byte) (err error) {
457 return setsockopt(fd, level, opt, unsafe.Pointer(&value), 1)
458 }
459
460 func SetsockoptInt(fd, level, opt int, value int) (err error) {
461 var n = int32(value)
462 return setsockopt(fd, level, opt, unsafe.Pointer(&n), 4)
463 }
464
465 func SetsockoptInet4Addr(fd, level, opt int, value [4]byte) (err error) {
466 return setsockopt(fd, level, opt, unsafe.Pointer(&value[0]), 4)
467 }
468
469 func SetsockoptIPMreq(fd, level, opt int, mreq *IPMreq) (err error) {
470 return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPMreq)
471 }
472
473 func SetsockoptIPv6Mreq(fd, level, opt int, mreq *IPv6Mreq) (err error) {
474 return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPv6Mreq)
475 }
476
477 func SetsockoptICMPv6Filter(fd, level, opt int, filter *ICMPv6Filter) error {
478 return setsockopt(fd, level, opt, unsafe.Pointer(filter), SizeofICMPv6Filter)
479 }
480
481 func SetsockoptLinger(fd, level, opt int, l *Linger) (err error) {
482 return setsockopt(fd, level, opt, unsafe.Pointer(l), SizeofLinger)
483 }
484
485 func SetsockoptString(fd, level, opt int, s string) (err error) {
486 var p unsafe.Pointer
487 if len(s) > 0 {
488 p = unsafe.Pointer(&[]byte(s)[0])
489 }
490 return setsockopt(fd, level, opt, p, uintptr(len(s)))
491 }
492
493 func SetsockoptTimeval(fd, level, opt int, tv *Timeval) (err error) {
494 return setsockopt(fd, level, opt, unsafe.Pointer(tv), unsafe.Sizeof(*tv))
495 }
496
497 func Socket(domain, typ, proto int) (fd int, err error) {
498 if domain == AF_INET6 && SocketDisableIPv6 {
499 return -1, EAFNOSUPPORT
500 }
501 fd, err = socket(domain, typ, proto)
502 return
503 }
504
505 func Socketpair(domain, typ, proto int) (fd [2]int, err error) {
506 var fdx [2]int32
507 err = socketpair(domain, typ, proto, &fdx)
508 if err == nil {
509 fd[0] = int(fdx[0])
510 fd[1] = int(fdx[1])
511 }
512 return
513 }
514
515 func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
516 if race.Enabled {
517 race.ReleaseMerge(unsafe.Pointer(&ioSync))
518 }
519 return sendfile(outfd, infd, offset, count)
520 }
521
522 var ioSync int64
523
View as plain text