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

Method RecvMsg

pkg/sentry/socket/unix/unix.go:758–900  ·  view source on GitHub ↗

RecvMsg implements the linux syscall recvmsg(2) for sockets backed by a transport.Endpoint.

(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

756// RecvMsg implements the linux syscall recvmsg(2) for sockets backed by
757// a transport.Endpoint.
758func (s *Socket) RecvMsg(t *kernel.Task, dst usermem.IOSequence, flags int, haveDeadline bool, deadline ktime.Time, senderRequested bool, controlDataLen uint64) (n int, msgFlags int, senderAddr linux.SockAddr, senderAddrLen uint32, controlMessages socket.ControlMessages, err *syserr.Error) {
759 trunc := flags&linux.MSG_TRUNC != 0
760 peek := flags&linux.MSG_PEEK != 0
761 dontWait := flags&linux.MSG_DONTWAIT != 0
762 waitAll := flags&linux.MSG_WAITALL != 0
763 isPacket := s.isPacket()
764
765 // Calculate the number of FDs for which we have space and if we are
766 // requesting credentials.
767 var wantCreds bool
768 rightsLen := int(controlDataLen) - unix.SizeofCmsghdr
769 if s.Passcred() {
770 // Credentials take priority if they are enabled and there is space.
771 wantCreds = rightsLen > 0
772 if !wantCreds {
773 msgFlags |= linux.MSG_CTRUNC
774 }
775 credLen := unix.CmsgSpace(unix.SizeofUcred)
776 rightsLen -= credLen
777 }
778 // FDs are 32 bit (4 byte) ints.
779 numRights := rightsLen / 4
780 if numRights < 0 {
781 numRights = 0
782 }
783
784 r := EndpointReader{
785 Ctx: t,
786 Endpoint: s.ep,
787 Creds: wantCreds,
788 NumRights: numRights,
789 Peek: peek,
790 }
791
792 doRead := func() (int64, error) {
793 n, err := dst.CopyOutFrom(t, &r)
794 if r.Notify != nil {
795 r.Notify()
796 }
797 return n, err
798 }
799
800 // Drop any unused rights messages after reading.
801 defer func() {
802 for _, rm := range r.UnusedRights {
803 rm.Release(t)
804 }
805 }()
806
807 // If MSG_TRUNC is set with a zero byte destination then we still need
808 // to read the message and discard it, or in the case where MSG_PEEK is
809 // set, leave it be. In both cases the full message length must be
810 // returned.
811 if trunc && dst.Addrs.NumBytes() == 0 {
812 doRead = func() (int64, error) {
813 err := r.Truncate()
814 // Always return zero for bytes read since the destination size is
815 // zero.

Callers

nothing calls this directly

Calls 15

isPacketMethod · 0.95
PasscredMethod · 0.95
TruncateMethod · 0.95
EventRegisterMethod · 0.95
EventUnregisterMethod · 0.95
FromErrorFunction · 0.92
NewChannelEntryFunction · 0.92
EqualsFunction · 0.92
convertAddressFunction · 0.85
BlockWithDeadlineMethod · 0.80
CopyOutFromMethod · 0.65
ReleaseMethod · 0.65

Tested by

no test coverage detected