[gtk+/wip/alexl/broadway4: 68/96] broadway: Support fd passing in protocol
- From: Alexander Larsson <alexl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/alexl/broadway4: 68/96] broadway: Support fd passing in protocol
- Date: Thu, 23 Nov 2017 09:51:59 +0000 (UTC)
commit f31d7e1f9114d9d39229d827d564e54120598013
Author: Alexander Larsson <alexl redhat com>
Date: Fri Nov 17 15:57:28 2017 +0100
broadway: Support fd passing in protocol
This will be used to pass buffers
gdk/broadway/broadwayd.c | 38 +++++++++++++++++++++--
gdk/broadway/gdkbroadway-server.c | 60 +++++++++++++++++++++++++++++++-----
2 files changed, 86 insertions(+), 12 deletions(-)
---
diff --git a/gdk/broadway/broadwayd.c b/gdk/broadway/broadwayd.c
index e36c8fc..f29eb77 100644
--- a/gdk/broadway/broadwayd.c
+++ b/gdk/broadway/broadwayd.c
@@ -13,6 +13,7 @@
#include <gio/gio.h>
#ifdef G_OS_UNIX
#include <gio/gunixsocketaddress.h>
+#include <gio/gunixfdmessage.h>
#endif
#include "broadway-server.h"
@@ -54,9 +55,16 @@ typedef struct {
GSList *serial_mappings;
GList *windows;
guint disconnect_idle;
+ GList *fds;
} BroadwayClient;
static void
+close_fd (void *data)
+{
+ close (GPOINTER_TO_INT (data));
+}
+
+static void
client_free (BroadwayClient *client)
{
g_assert (client->windows == NULL);
@@ -66,6 +74,7 @@ client_free (BroadwayClient *client)
g_object_unref (client->in);
g_string_free (client->buffer, TRUE);
g_slist_free_full (client->serial_mappings, g_free);
+ g_list_free_full (client->fds, close_fd);
g_free (client);
}
@@ -341,6 +350,9 @@ client_input_cb (GPollableInputStream *stream,
gsize old_len;
guchar *buffer;
gsize buffer_len;
+ GInputVector input_vector;
+ GSocketControlMessage **messages = NULL;
+ int i, num_messages;
old_len = client->buffer->len;
@@ -348,10 +360,13 @@ client_input_cb (GPollableInputStream *stream,
g_string_set_size (client->buffer, old_len + INPUT_BUFFER_SIZE);
g_string_set_size (client->buffer, old_len);
- res = g_socket_receive_with_blocking (socket, client->buffer->str + old_len,
- client->buffer->allocated_len - client->buffer->len -1,
- FALSE, NULL, NULL);
+ input_vector.buffer = client->buffer->str + old_len;
+ input_vector.size = client->buffer->allocated_len - client->buffer->len -1;
+ res = g_socket_receive_message (socket, NULL,
+ &input_vector, 1,
+ &messages, &num_messages,
+ NULL, NULL, NULL);
if (res <= 0)
{
client->source = NULL;
@@ -359,6 +374,23 @@ client_input_cb (GPollableInputStream *stream,
return G_SOURCE_REMOVE;
}
+ for (i = 0; i < num_messages; i++)
+ {
+ if (G_IS_UNIX_FD_MESSAGE (messages[i]))
+ {
+ int j, n_fds;
+ int *fds = g_unix_fd_message_steal_fds (G_UNIX_FD_MESSAGE (messages[i]), &n_fds);
+ for (j = 0; j < n_fds; j++)
+ {
+ int fd = fds[i];
+ client->fds = g_list_append (client->fds, GINT_TO_POINTER (fd));
+ }
+ g_free (fds);
+ }
+ g_object_unref (messages[i]);
+ }
+ g_free (messages);
+
g_string_set_size (client->buffer, old_len + res);
buffer = (guchar *)client->buffer->str;
diff --git a/gdk/broadway/gdkbroadway-server.c b/gdk/broadway/gdkbroadway-server.c
index d81690e..57cb48d 100644
--- a/gdk/broadway/gdkbroadway-server.c
+++ b/gdk/broadway/gdkbroadway-server.c
@@ -12,9 +12,8 @@
#include <glib.h>
#include <glib/gprintf.h>
-#ifdef G_OS_UNIX
#include <gio/gunixsocketaddress.h>
-#endif
+#include <gio/gunixfdmessage.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
@@ -160,30 +159,73 @@ _gdk_broadway_server_get_last_seen_time (GdkBroadwayServer *server)
static guint32
gdk_broadway_server_send_message_with_size (GdkBroadwayServer *server, BroadwayRequestBase *base,
- gsize size, guint32 type)
+ gsize size, guint32 type, int fd)
{
GOutputStream *out;
gsize written;
+ guchar *buf;
base->size = size;
base->type = type;
base->serial = server->next_serial++;
- out = g_io_stream_get_output_stream (G_IO_STREAM (server->connection));
+ buf = (guchar *)base;
- if (!g_output_stream_write_all (out, base, size, &written, NULL, NULL))
+ if (fd != -1)
{
- g_printerr ("Unable to write to server\n");
- exit (1);
+ GUnixFDList *fd_list = g_unix_fd_list_new_from_array (&fd, 1);
+ GSocketControlMessage *control_message = g_unix_fd_message_new_with_fd_list (fd_list);
+ GSocket *socket = g_socket_connection_get_socket (server->connection);
+ GOutputVector vector;
+ gssize bytes_written;
+
+ vector.buffer = buf;
+ vector.size = size;
+
+ bytes_written = g_socket_send_message (socket,
+ NULL, /* address */
+ &vector,
+ 1,
+ &control_message, 1,
+ G_SOCKET_MSG_NONE,
+ NULL,
+ NULL);
+
+ if (bytes_written <= 0)
+ {
+ g_printerr ("Unable to write to server\n");
+ exit (1);
+ }
+
+ g_print ("socket send message wrote %d of %d\n", (int)bytes_written, (int)size);
+ buf += bytes_written;
+ size -= bytes_written;
+
+ g_object_unref (control_message);
+ g_object_unref (fd_list);
+ }
+
+ if (size > 0)
+ {
+ out = g_io_stream_get_output_stream (G_IO_STREAM (server->connection));
+ if (!g_output_stream_write_all (out, buf, size, &written, NULL, NULL))
+ {
+ g_printerr ("Unable to write to server\n");
+ exit (1);
+ }
+
+ g_assert (written == size);
}
- g_assert (written == size);
return base->serial;
}
#define gdk_broadway_server_send_message(_server, _msg, _type) \
- gdk_broadway_server_send_message_with_size(_server, (BroadwayRequestBase *)&_msg, sizeof (_msg), _type)
+ gdk_broadway_server_send_message_with_size(_server, (BroadwayRequestBase *)&_msg, sizeof (_msg), _type, -1)
+
+#define gdk_broadway_server_send_fd_message(_server, _msg, _type, _fd) \
+ gdk_broadway_server_send_message_with_size(_server, (BroadwayRequestBase *)&_msg, sizeof (_msg), _type,
_fd)
static void
parse_all_input (GdkBroadwayServer *server)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]