[Spice-devel] [PATCH spice 05/18] reds-stream: add send_msgfd()

Marc-André Lureau marcandre.lureau at gmail.com
Tue Dec 15 15:49:19 PST 2015


From: Marc-André Lureau <mlureau at redhat.com>

A new function to send fd with unix socket anciliary data.

Signed-off-by: Marc-André Lureau <marcandre.lureau at gmail.com>
---
 server/reds-stream.c | 40 ++++++++++++++++++++++++++++++++++++++++
 server/reds-stream.h |  1 +
 2 files changed, 41 insertions(+)

diff --git a/server/reds-stream.c b/server/reds-stream.c
index d87cb23..fc41f0a 100644
--- a/server/reds-stream.c
+++ b/server/reds-stream.c
@@ -28,6 +28,7 @@
 #include <netdb.h>
 #include <unistd.h>
 #include <sys/socket.h>
+#include <fcntl.h>
 
 #include <glib.h>
 
@@ -254,6 +255,45 @@ int reds_stream_is_plain_unix(const RedsStream *s)
 
 }
 
+int reds_stream_send_msgfd(RedsStream *stream, int fd)
+{
+    struct msghdr msgh = { 0, };
+    struct iovec iov;
+    int r;
+
+    const size_t fd_size = 1 * sizeof(int);
+    struct cmsghdr *cmsg;
+    union {
+        struct cmsghdr hdr;
+        char data[CMSG_SPACE(fd_size)];
+    } control;
+
+    spice_return_val_if_fail(reds_stream_is_plain_unix(stream), -1);
+
+    /* set the payload */
+    iov.iov_base = (char*)"@";
+    iov.iov_len = 1;
+    msgh.msg_iovlen = 1;
+    msgh.msg_iov = &iov;
+
+    if (fd != -1) {
+        msgh.msg_control = control.data;
+        msgh.msg_controllen = sizeof(control.data);
+
+        cmsg = CMSG_FIRSTHDR(&msgh);
+        cmsg->cmsg_len = CMSG_LEN(fd_size);
+        cmsg->cmsg_level = SOL_SOCKET;
+        cmsg->cmsg_type = SCM_RIGHTS;
+        memcpy(CMSG_DATA(cmsg), &fd, fd_size);
+    }
+
+    do {
+        r = sendmsg(stream->socket, &msgh, MSG_NOSIGNAL);
+    } while (r < 0 && (errno == EINTR || errno == EAGAIN));
+
+    return r;
+}
+
 ssize_t reds_stream_writev(RedsStream *s, const struct iovec *iov, int iovcnt)
 {
     int i;
diff --git a/server/reds-stream.h b/server/reds-stream.h
index 9e53b22..72e5dd1 100644
--- a/server/reds-stream.h
+++ b/server/reds-stream.h
@@ -74,6 +74,7 @@ int reds_stream_enable_ssl(RedsStream *stream, SSL_CTX *ctx);
 void reds_stream_set_info_flag(RedsStream *stream, unsigned int flag);
 int reds_stream_get_family(const RedsStream *stream);
 int reds_stream_is_plain_unix(const RedsStream *stream);
+int reds_stream_send_msgfd(RedsStream *stream, int fd);
 
 typedef enum {
     REDS_SASL_ERROR_OK,
-- 
2.5.0



More information about the Spice-devel mailing list