Hi, On Fri, Feb 05, 2016 at 12:36:49AM +0100, Marc-André Lureau wrote: > From: Marc-André Lureau <marcandre.lureau@xxxxxxxxxx> > > Utility function used in the messages with socket ancillary fd. > > Signed-off-by: Marc-André Lureau <marcandre.lureau@xxxxxxxxxx> > --- > src/spice-channel-priv.h | 3 +++ > src/spice-channel.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 71 insertions(+) > > diff --git a/src/spice-channel-priv.h b/src/spice-channel-priv.h > index d60ea73..526b661 100644 > --- a/src/spice-channel-priv.h > +++ b/src/spice-channel-priv.h > @@ -205,6 +205,9 @@ void spice_vmc_write_async(SpiceChannel *self, > gpointer user_data); > gssize spice_vmc_write_finish(SpiceChannel *self, > GAsyncResult *result, GError **error); > +#ifdef G_OS_UNIX > +gint spice_channel_unix_read_fd(SpiceChannel *channel); > +#endif > > G_END_DECLS > > diff --git a/src/spice-channel.c b/src/spice-channel.c > index ff85715..db2e5c2 100644 > --- a/src/spice-channel.c > +++ b/src/spice-channel.c > @@ -872,6 +872,74 @@ static void spice_channel_write_msg(SpiceChannel *channel, SpiceMsgOut *out) > spice_msg_out_unref(out); > } > > +#ifdef G_OS_UNIX > +static ssize_t read_fd(int fd, int *msgfd) > +{ > + struct msghdr msg = { NULL, }; > + struct iovec iov[1]; > + union { > + struct cmsghdr cmsg; > + char control[CMSG_SPACE(sizeof(int))]; > + } msg_control; > + struct cmsghdr *cmsg; > + ssize_t ret; > + char c; > + > + iov[0].iov_base = &c; > + iov[0].iov_len = 1; > + > + msg.msg_iov = iov; > + msg.msg_iovlen = 1; > + msg.msg_control = &msg_control; > + msg.msg_controllen = sizeof(msg_control); > + > + ret = recvmsg(fd, &msg, 0); > + if (ret > 0) { > + for (cmsg = CMSG_FIRSTHDR(&msg); > + cmsg; > + cmsg = CMSG_NXTHDR(&msg, cmsg)) { We are trying to keep checks explicit (cmsg != NULL) Patch looks good Acked-by: Victor Toso <victortoso@xxxxxxxxxx> > + if (cmsg->cmsg_len != CMSG_LEN(sizeof(int)) || > + cmsg->cmsg_level != SOL_SOCKET || > + cmsg->cmsg_type != SCM_RIGHTS) { > + continue; > + } > + > + memcpy(msgfd, CMSG_DATA(cmsg), sizeof(int)); > + if (*msgfd < 0) { > + continue; > + } > + } > + } > + return ret; > +} > + > +G_GNUC_INTERNAL > +gint spice_channel_unix_read_fd(SpiceChannel *channel) > +{ > + SpiceChannelPrivate *c = channel->priv; > + gint fd = -1; > + > + g_return_val_if_fail(g_socket_get_family(c->sock) == G_SOCKET_FAMILY_UNIX, -1); > + > + while (1) { > + /* g_socket_receive_message() is not convenient here because it > + * reads all control messages, and overly complicated to deal with */ > + if (read_fd(g_socket_get_fd(c->sock), &fd) > 0) { > + break; > + } > + > + if (errno == EWOULDBLOCK) { > + g_coroutine_socket_wait(&c->coroutine, c->sock, G_IO_IN); > + } else { > + g_warning("failed to get fd: %s", g_strerror(errno)); > + return -1; > + } > + } > + > + return fd; > +} > +#endif > + > /* > * Read at least 1 more byte of data straight off the wire > * into the requested buffer. > -- > 2.5.0 > > _______________________________________________ > Spice-devel mailing list > Spice-devel@xxxxxxxxxxxxxxxxxxxxx > http://lists.freedesktop.org/mailman/listinfo/spice-devel _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel