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.
27 darwin64Bit = (runtime.GOOS == "darwin" || runtime.GOOS == "ios") && sizeofPtr == 8
28 netbsd32Bit = runtime.GOOS == "netbsd" && sizeofPtr == 4
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 {
39 // Mmap manager, for use by operating system-specific implementations.
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
48 func (m *mmapper) Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
53 // Map the requested memory.
54 addr, errno := m.mmap(0, uintptr(length), prot, flags, fd, offset)
59 // Use unsafe to turn addr into a []byte.
60 b := unsafe.Slice((*byte)(unsafe.Pointer(addr)), length)
62 // Register mapping in m and return it.
70 func (m *mmapper) Munmap(data []byte) (err error) {
71 if len(data) == 0 || len(data) != cap(data) {
75 // Find the base of the mapping.
76 p := &data[cap(data)-1]
80 if b == nil || &b[0] != &data[0] {
84 // Unmap the memory and update m.
85 if errno := m.munmap(uintptr(unsafe.Pointer(&b[0])), uintptr(len(b))); errno != nil {
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:
101 // Errno values can be tested against error values using errors.Is.
104 // _, _, err := syscall.Syscall(...)
105 // if errors.Is(err, fs.ErrNotExist) ...
108 func (e Errno) Error() string {
109 if 0 <= int(e) && int(e) < len(errors) {
115 return "errno " + itoa.Itoa(int(e))
118 func (e Errno) Is(target error) bool {
120 case oserror.ErrPermission:
121 return e == EACCES || e == EPERM
122 case oserror.ErrExist:
123 return e == EEXIST || e == ENOTEMPTY
124 case oserror.ErrNotExist:
126 case errorspkg.ErrUnsupported:
127 return e == ENOSYS || e == ENOTSUP || e == EOPNOTSUPP
132 func (e Errno) Temporary() bool {
133 return e == EINTR || e == EMFILE || e == ENFILE || e.Timeout()
136 func (e Errno) Timeout() bool {
137 return e == EAGAIN || e == EWOULDBLOCK || e == ETIMEDOUT
140 // Do the interface allocations only once for common
143 errEAGAIN error = EAGAIN
144 errEINVAL error = EINVAL
145 errENOENT error = ENOENT
148 // errnoErr returns common boxed Errno values, to prevent
149 // allocations at runtime.
150 func errnoErr(e Errno) error {
164 // A Signal is a number describing a process signal.
165 // It implements the os.Signal interface.
168 func (s Signal) Signal() {}
170 func (s Signal) String() string {
171 if 0 <= s && int(s) < len(signals) {
177 return "signal " + itoa.Itoa(int(s))
180 func Read(fd int, p []byte) (n int, err error) {
184 race.WriteRange(unsafe.Pointer(&p[0]), n)
187 race.Acquire(unsafe.Pointer(&ioSync))
190 if msanenabled && n > 0 {
191 msanWrite(unsafe.Pointer(&p[0]), n)
193 if asanenabled && n > 0 {
194 asanWrite(unsafe.Pointer(&p[0]), n)
199 func Write(fd int, p []byte) (n int, err error) {
201 race.ReleaseMerge(unsafe.Pointer(&ioSync))
203 if faketime && (fd == 1 || fd == 2) {
204 n = faketimeWrite(fd, p)
206 n, err = 0, errnoErr(Errno(-n))
209 n, err = write(fd, p)
211 if race.Enabled && n > 0 {
212 race.ReadRange(unsafe.Pointer(&p[0]), n)
214 if msanenabled && n > 0 {
215 msanRead(unsafe.Pointer(&p[0]), n)
217 if asanenabled && n > 0 {
218 asanRead(unsafe.Pointer(&p[0]), n)
223 func Pread(fd int, p []byte, offset int64) (n int, err error) {
224 n, err = pread(fd, p, offset)
227 race.WriteRange(unsafe.Pointer(&p[0]), n)
230 race.Acquire(unsafe.Pointer(&ioSync))
233 if msanenabled && n > 0 {
234 msanWrite(unsafe.Pointer(&p[0]), n)
236 if asanenabled && n > 0 {
237 asanWrite(unsafe.Pointer(&p[0]), n)
242 func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
244 race.ReleaseMerge(unsafe.Pointer(&ioSync))
246 n, err = pwrite(fd, p, offset)
247 if race.Enabled && n > 0 {
248 race.ReadRange(unsafe.Pointer(&p[0]), n)
250 if msanenabled && n > 0 {
251 msanRead(unsafe.Pointer(&p[0]), n)
253 if asanenabled && n > 0 {
254 asanRead(unsafe.Pointer(&p[0]), n)
259 // For testing: clients can set this flag to force
260 // creation of IPv6 sockets to return EAFNOSUPPORT.
261 var SocketDisableIPv6 bool
263 type Sockaddr interface {
264 sockaddr() (ptr unsafe.Pointer, len _Socklen, err error) // lowercase; only we can define Sockaddrs
267 type SockaddrInet4 struct {
273 type SockaddrInet6 struct {
280 type SockaddrUnix struct {
285 func Bind(fd int, sa Sockaddr) (err error) {
286 ptr, n, err := sa.sockaddr()
290 return bind(fd, ptr, n)
293 func Connect(fd int, sa Sockaddr) (err error) {
294 ptr, n, err := sa.sockaddr()
298 return connect(fd, ptr, n)
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 {
307 return anyToSockaddr(&rsa)
310 func GetsockoptInt(fd, level, opt int) (value int, err error) {
312 vallen := _Socklen(4)
313 err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen)
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 {
323 if rsa.Addr.Family != AF_UNSPEC {
324 from, err = anyToSockaddr(&rsa)
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 {
335 pp := (*RawSockaddrInet4)(unsafe.Pointer(&rsa))
336 port := (*[2]byte)(unsafe.Pointer(&pp.Port))
337 from.Port = int(port[0])<<8 + int(port[1])
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 {
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
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)
362 pp := (*RawSockaddrInet4)(unsafe.Pointer(&rsa))
363 port := (*[2]byte)(unsafe.Pointer(&pp.Port))
364 from.Port = int(port[0])<<8 + int(port[1])
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)
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
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)
393 func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) {
394 _, err = SendmsgN(fd, p, oob, to, flags)
398 func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) {
399 var ptr unsafe.Pointer
402 ptr, salen, err = to.sockaddr()
407 return sendmsgN(fd, p, oob, ptr, salen, flags)
410 func sendmsgNInet4(fd int, p, oob []byte, to *SockaddrInet4, flags int) (n int, err error) {
411 ptr, salen, err := to.sockaddr()
415 return sendmsgN(fd, p, oob, ptr, salen, flags)
418 func sendmsgNInet6(fd int, p, oob []byte, to *SockaddrInet6, flags int) (n int, err error) {
419 ptr, salen, err := to.sockaddr()
423 return sendmsgN(fd, p, oob, ptr, salen, flags)
426 func sendtoInet4(fd int, p []byte, flags int, to *SockaddrInet4) (err error) {
427 ptr, n, err := to.sockaddr()
431 return sendto(fd, p, flags, ptr, n)
434 func sendtoInet6(fd int, p []byte, flags int, to *SockaddrInet6) (err error) {
435 ptr, n, err := to.sockaddr()
439 return sendto(fd, p, flags, ptr, n)
442 func Sendto(fd int, p []byte, flags int, to Sockaddr) (err error) {
448 ptr, salen, err = to.sockaddr()
453 return sendto(fd, p, flags, ptr, salen)
456 func SetsockoptByte(fd, level, opt int, value byte) (err error) {
457 return setsockopt(fd, level, opt, unsafe.Pointer(&value), 1)
460 func SetsockoptInt(fd, level, opt int, value int) (err error) {
462 return setsockopt(fd, level, opt, unsafe.Pointer(&n), 4)
465 func SetsockoptInet4Addr(fd, level, opt int, value [4]byte) (err error) {
466 return setsockopt(fd, level, opt, unsafe.Pointer(&value[0]), 4)
469 func SetsockoptIPMreq(fd, level, opt int, mreq *IPMreq) (err error) {
470 return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPMreq)
473 func SetsockoptIPv6Mreq(fd, level, opt int, mreq *IPv6Mreq) (err error) {
474 return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPv6Mreq)
477 func SetsockoptICMPv6Filter(fd, level, opt int, filter *ICMPv6Filter) error {
478 return setsockopt(fd, level, opt, unsafe.Pointer(filter), SizeofICMPv6Filter)
481 func SetsockoptLinger(fd, level, opt int, l *Linger) (err error) {
482 return setsockopt(fd, level, opt, unsafe.Pointer(l), SizeofLinger)
485 func SetsockoptString(fd, level, opt int, s string) (err error) {
488 p = unsafe.Pointer(&[]byte(s)[0])
490 return setsockopt(fd, level, opt, p, uintptr(len(s)))
493 func SetsockoptTimeval(fd, level, opt int, tv *Timeval) (err error) {
494 return setsockopt(fd, level, opt, unsafe.Pointer(tv), unsafe.Sizeof(*tv))
497 func Socket(domain, typ, proto int) (fd int, err error) {
498 if domain == AF_INET6 && SocketDisableIPv6 {
499 return -1, EAFNOSUPPORT
501 fd, err = socket(domain, typ, proto)
505 func Socketpair(domain, typ, proto int) (fd [2]int, err error) {
507 err = socketpair(domain, typ, proto, &fdx)
515 func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
517 race.ReleaseMerge(unsafe.Pointer(&ioSync))
519 return sendfile(outfd, infd, offset, count)