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