MCPcopy
hub / github.com/google/gvisor / RecvMsg

Method RecvMsg

pkg/sentry/socket/plugin/stack/socket.go:617–708  ·  view source on GitHub ↗

RecvMsg implements socket.Socket.RecvMsg.

(t *kernel.Task, dst usermem.IOSequence, flags int, haveDeadline bool, deadline ktime.Time, senderRequested bool, controlDataLen uint64)

Source from the content-addressed store, hash-verified

615
616// RecvMsg implements socket.Socket.RecvMsg.
617func (s *socketOperations) RecvMsg(t *kernel.Task, dst usermem.IOSequence, flags int, haveDeadline bool, deadline ktime.Time, senderRequested bool, controlDataLen uint64) (int, int, linux.SockAddr, uint32, socket.ControlMessages, *syserr.Error) {
618 var addr, control []byte
619 if senderRequested {
620 if s.skType != linux.SOCK_STREAM {
621 addr = make([]byte, sizeofSockaddr)
622 } else {
623 // According to UNIX98, msg_name/msg_namelen are ignored on connected socket.
624 senderRequested = false
625 }
626 }
627 if controlDataLen > 0 {
628 control = make([]byte, controlDataLen)
629 }
630
631 // Store nonblock info from original flag.
632 nonblock := flags&syscall.MSG_DONTWAIT != 0
633 waitall := !nonblock && flags&syscall.MSG_WAITALL != 0
634
635 var mflag int
636 var n int64
637 var err error
638 // Always set as non-blocking for recv.
639 sysflags := flags | syscall.MSG_DONTWAIT
640 n, addr, control, mflag, err = s.recv(t, dst, sysflags, addr, control)
641
642 var senderAddr linux.SockAddr
643 var addrlen uint32
644 // For non-blocking RecvMsg, we could return after recv once.
645 if nonblock {
646 if err != nil {
647 // Clear controlMessages when error occurs.
648 control = nil
649 } else if senderRequested && len(addr) > 0 {
650 senderAddr = socket.UnmarshalSockAddr(s.family, addr)
651 addrlen = uint32(len(addr))
652 }
653 controlMessages := buildControlMessage(control)
654 // The socket is shutdown, report ErrWouldBlock for non-blocking mode.
655 if err == error(syscall.ESHUTDOWN) {
656 err = linuxerr.ErrWouldBlock
657 }
658 return int(n), mflag, senderAddr, addrlen, *controlMessages, syserr.FromError(err)
659 }
660
661 // For blocking RecvMsg, we need to finish reading all data before return.
662 rn := n
663 for err == linuxerr.ErrWouldBlock || (waitall && err == nil && rn < dst.NumBytes()) {
664 dst = dst.DropFirst(int(rn))
665 // Wait on POLLIN event.
666 if haveDeadline {
667 err = s.waitEventT(t, waiter.EventIn, deadline)
668 } else {
669 err = s.waitEvent(t, waiter.EventIn)
670 }
671 if err != nil {
672 if n == 0 {
673 // There is no POLLIN event reported before timeout.
674 if err == linuxerr.ETIMEDOUT {

Callers

nothing calls this directly

Calls 8

recvMethod · 0.95
waitEventTMethod · 0.95
waitEventMethod · 0.95
UnmarshalSockAddrFunction · 0.92
FromErrorFunction · 0.92
buildControlMessageFunction · 0.85
NumBytesMethod · 0.45
DropFirstMethod · 0.45

Tested by

no test coverage detected