[Spice-devel] [PATCH v4 2/5] Add spice_channel_unix_read_fd()

Victor Toso lists at victortoso.com
Sat Feb 13 08:39:01 UTC 2016


Hi,

On Fri, Feb 05, 2016 at 12:36:49AM +0100, Marc-André Lureau wrote:
> From: Marc-André Lureau <marcandre.lureau at redhat.com>
>
> Utility function used in the messages with socket ancillary fd.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau at redhat.com>
> ---
>  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 at redhat.com>

> +            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 at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/spice-devel


More information about the Spice-devel mailing list