//send peer credentials null byte //different platforms do this in different ways #if HAVE_CMSGCRED unsafe void WriteBsdCred() { //null credentials byte byte buf = 0; IOVector iov = new IOVector(); //iov.Base = (IntPtr)(&buf); iov.Base = &buf; iov.Length = 1; msghdr msg = new msghdr(); msg.msg_iov = &iov; msg.msg_iovlen = 1; cmsg cm = new cmsg(); msg.msg_control = (IntPtr)(&cm); msg.msg_controllen = (uint)sizeof(cmsg); cm.hdr.cmsg_len = (uint)sizeof(cmsg); cm.hdr.cmsg_level = 0xffff; //SOL_SOCKET cm.hdr.cmsg_type = 0x03; //SCM_CREDS int written = socket.SendMsg(&msg, 0); if (written != 1) { throw new Exception("Failed to write credentials"); } }
// Send the two buffers and the FDs using sendmsg(), don't handle short writes // length1 + length2 must not be 0 public unsafe long SendmsgShort(byte[] buffer1, long offset1, long length1, byte[] buffer2, long offset2, long length2, DBus.Protocol.UnixFDArray fds) { //Console.WriteLine ("SendmsgShort (X, {0}, {1}, {2}, {3}, {4}, {5})", offset1, length1, buffer2 == null ? "-" : "Y", offset2, length2, fds == null ? "-" : "" + fds.FDs.Count); AssertValidBuffer(buffer1, offset1, length1); if (buffer2 == null) { if (length2 != 0) { throw new ArgumentOutOfRangeException("length2", "!= 0 while buffer2 == null"); } offset2 = 0; } else { AssertValidBuffer(buffer2, offset2, length2); } fixed(byte *ptr1 = buffer1, ptr2 = buffer2) { var iovecs = new IOVector[] { new IOVector { Base = (ptr1 + offset1), Length = (int)length1, }, new IOVector { Base = (ptr2 + offset2), Length = (int)length2, }, }; /* Simulate short writes * if (iovecs[0].iov_len == 0) { * iovecs[1].iov_len = Math.Min (iovecs[1].iov_len, 5); * } else { * iovecs[0].iov_len = Math.Min (iovecs[0].iov_len, 5); * iovecs[1].iov_len = 0; * } */ byte[] cmsg = null; // Create copy of FDs to prevent the user from Dispose()ing the // FDs in another thread between writing the FDs into the cmsg // buffer and calling sendmsg() fixed(IOVector *iovecPtr = iovecs) { using (var fds2 = fds == null ? null : fds.Clone()) { int fdCount = fds2 == null ? 0 : fds2.FDs.Count; if (fdCount != 0) { // Create one SCM_RIGHTS control message cmsg = new byte[CMSG_SPACE((uint)fdCount * sizeof(int))]; } fixed(byte *cmsgPtr = cmsg) { var msghdr = new msghdr { msg_iov = iovecPtr, msg_iovlen = length2 == 0 ? 1 : 2, msg_control = (IntPtr)cmsgPtr, msg_controllen = cmsg == null ? 0 : (uint)cmsg.Length, }; if (fdCount != 0) { var hdr = new cmsghdr { cmsg_len = (UIntPtr)CMSG_LEN((uint)fdCount * sizeof(int)), cmsg_level = 1, // SOL_SOCKET cmsg_type = 1, // SCM_RIGHTS }; *((cmsghdr *)cmsgPtr) = hdr; var data = CMSG_DATA((cmsghdr *)cmsgPtr); fixed(byte *ptr = cmsg) { for (int i = 0; i < fdCount; i++) { ((int *)data)[i] = fds2.FDs[i].Handle; } } } long r = socket.SendMsg(&msghdr, 0); if (r == 0) { throw new Exception("sendmsg() returned 0"); } return(r); } } } } }