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