]> Cypherpunks.ru repositories - gostls13.git/blob - src/syscall/syscall_unix.go
cmd/compile/internal/inline: score call sites exposed by inlines
[gostls13.git] / src / syscall / syscall_unix.go
1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 //go:build unix
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 // clen returns the index of the first NULL byte in n or len(n) if n contains no NULL byte.
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 // Mmap manager, for use by operating system-specific implementations.
40
41 type mmapper struct {
42         sync.Mutex
43         active map[*byte][]byte // active mappings; key is last byte in mapping
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         // Map the requested memory.
54         addr, errno := m.mmap(0, uintptr(length), prot, flags, fd, offset)
55         if errno != nil {
56                 return nil, errno
57         }
58
59         // Use unsafe to turn addr into a []byte.
60         b := unsafe.Slice((*byte)(unsafe.Pointer(addr)), length)
61
62         // Register mapping in m and return it.
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         // Find the base of the mapping.
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         // Unmap the memory and update m.
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 // An Errno is an unsigned number describing an error condition.
93 // It implements the error interface. The zero Errno is by convention
94 // a non-error, so code to convert from Errno to error should use:
95 //
96 //      err = nil
97 //      if errno != 0 {
98 //              err = errno
99 //      }
100 //
101 // Errno values can be tested against error values using errors.Is.
102 // For example:
103 //
104 //      _, _, err := syscall.Syscall(...)
105 //      if errors.Is(err, fs.ErrNotExist) ...
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 // Do the interface allocations only once for common
141 // Errno values.
142 var (
143         errEAGAIN error = EAGAIN
144         errEINVAL error = EINVAL
145         errENOENT error = ENOENT
146 )
147
148 // errnoErr returns common boxed Errno values, to prevent
149 // allocations at runtime.
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 // A Signal is a number describing a process signal.
165 // It implements the os.Signal interface.
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 // For testing: clients can set this flag to force
260 // creation of IPv6 sockets to return EAFNOSUPPORT.
261 var SocketDisableIPv6 bool
262
263 type Sockaddr interface {
264         sockaddr() (ptr unsafe.Pointer, len _Socklen, err error) // lowercase; only we can define Sockaddrs
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         // source address is only specified if the socket is unconnected
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