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

Method SendMsg

pkg/sentry/socket/unix/unix.go:647–717  ·  view source on GitHub ↗

SendMsg implements the linux syscall sendmsg(2) for unix sockets backed by a transport.Endpoint.

(t *kernel.Task, src usermem.IOSequence, to []byte, flags int, haveDeadline bool, deadline ktime.Time, controlMessages socket.ControlMessages)

Source from the content-addressed store, hash-verified

645// SendMsg implements the linux syscall sendmsg(2) for unix sockets backed by
646// a transport.Endpoint.
647func (s *Socket) SendMsg(t *kernel.Task, src usermem.IOSequence, to []byte, flags int, haveDeadline bool, deadline ktime.Time, controlMessages socket.ControlMessages) (int, *syserr.Error) {
648 w := EndpointWriter{
649 Ctx: t,
650 Endpoint: s.ep,
651 Control: controlMessages.Unix,
652 To: nil,
653 }
654 if len(to) > 0 {
655 switch s.stype {
656 case linux.SOCK_SEQPACKET:
657 // to is ignored.
658 case linux.SOCK_STREAM:
659 if s.State() == linux.SS_CONNECTED {
660 return 0, syserr.ErrAlreadyConnected
661 }
662 return 0, syserr.ErrNotSupported
663 default:
664 ep, err := s.extractEndpoint(t, to)
665 if err != nil {
666 return 0, err
667 }
668 defer ep.Release(t)
669 w.To = ep
670
671 if ep.Passcred() && w.Control.Credentials == nil {
672 w.Control.Credentials = control.MakeCreds(t)
673 }
674 }
675 }
676
677 n, err := src.CopyInTo(t, &w)
678 if w.Notify != nil {
679 w.Notify()
680 }
681 if err != linuxerr.ErrWouldBlock || flags&linux.MSG_DONTWAIT != 0 {
682 return int(n), syserr.FromError(err)
683 }
684
685 // Only send SCM Rights once (see net/unix/af_unix.c:unix_stream_sendmsg).
686 w.Control.Rights = nil
687
688 // We'll have to block. Register for notification and keep trying to
689 // send all the data.
690 e, ch := waiter.NewChannelEntry(waiter.WritableEvents)
691 s.EventRegister(&e)
692 defer s.EventUnregister(&e)
693
694 total := n
695 for {
696 // Shorten src to reflect bytes previously written.
697 src = src.DropFirst64(n)
698
699 n, err = src.CopyInTo(t, &w)
700 if w.Notify != nil {
701 w.Notify()
702 }
703 total += n
704 if err != linuxerr.ErrWouldBlock {

Callers

nothing calls this directly

Calls 14

StateMethod · 0.95
extractEndpointMethod · 0.95
EventRegisterMethod · 0.95
EventUnregisterMethod · 0.95
MakeCredsFunction · 0.92
FromErrorFunction · 0.92
NewChannelEntryFunction · 0.92
EqualsFunction · 0.92
BlockWithDeadlineMethod · 0.80
ReleaseMethod · 0.65
PasscredMethod · 0.65
CopyInToMethod · 0.65

Tested by

no test coverage detected