Ejemplo n.º 1
0
        private static int SendMessageAndFileDescriptor(
            this Socket socket,
            ReadOnlySpan <byte> messageData,
            IntPtr fileDescriptor)
        {
            if (socket == null)
            {
                throw new ArgumentNullException(nameof(socket));
            }

            if (fileDescriptor == null)
            {
                throw new ArgumentNullException(nameof(fileDescriptor));
            }

            unsafe
            {
                fixed(byte *pinnedData = &messageData.GetPinnableReference())
                {
                    // Message data.
                    //
                    IoVec ioVec = default;

                    ioVec.IovBase   = new IntPtr(pinnedData);
                    ioVec.IovLength = (ulong)messageData.Length;

                    // #define SOL_SOCKET 1
                    ControlMessage <int> controlMessage = default;

                    controlMessage.Header.ControlMessageLength = (ulong)sizeof(ControlMessage <int>);
                    controlMessage.Header.ControlMessageLevel  = 1;
                    controlMessage.Header.ControlMessageType   = SocketLevelMessageType.ScmRights;
                    controlMessage.Value = fileDescriptor.ToInt32();

                    // Construct the message.
                    //
                    MessageHeader message = default;

                    message.MessageName       = IntPtr.Zero;
                    message.MessageNameLength = 0;

                    message.MessageIoVec       = &ioVec;
                    message.MessageIoVecLength = 1;

                    message.MessageControl       = &controlMessage.Header;
                    message.MessageControlLength = controlMessage.Header.ControlMessageLength;

                    // Send the message.
                    //
                    ulong bytesSent = Native.SendMessage(socket.Handle, ref message, 0);

                    if ((long)bytesSent == -1)
                    {
                        throw new SocketException(Marshal.GetLastWin32Error());
                    }

                    int sent = checked ((int)bytesSent);

                    return(sent);
                }
            }
        }