[RFC wayland 15/18] connection: support sending the contents of fds as bulk data

Derek Foreman derekf at osg.samsung.com
Tue Feb 9 16:56:02 UTC 2016


For network transparent operation we need to send fd contents over the
wire for some fds (for example, keymaps).

This adds functions to copy fd data into the network pipe without
feeding it through the 4k ring buffer by writing it directly into the
socket (after flushing ring buffer contents first)

Signed-off-by: Derek Foreman <derekf at osg.samsung.com>
---
 src/connection.c      | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++
 src/wayland-private.h |  6 +++++
 2 files changed, 73 insertions(+)

diff --git a/src/connection.c b/src/connection.c
index 5fd085f..8a44806 100644
--- a/src/connection.c
+++ b/src/connection.c
@@ -40,6 +40,8 @@
 #include <time.h>
 #include <ffi.h>
 #include <stdbool.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
 
 #include "wayland-util.h"
 #include "wayland-private.h"
@@ -1142,6 +1144,71 @@ overflow:
 }
 
 int
+wl_connection_put_bulk_data(struct wl_connection *connection, int fd)
+{
+	char *map;
+	struct stat sb;
+	uint32_t p;
+	int ret = -1;
+
+	if (fstat(fd, &sb) < 0)
+		return -1;
+
+	map = mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED, fd, 0);
+	if (map == MAP_FAILED)
+		return -1;
+
+	p = sb.st_size;
+	if (wl_os_write(connection->fd, &p, sizeof(p)) < 0)
+		goto out;
+
+	if (wl_os_write(connection->fd, map, sb.st_size) < 0)
+		goto out;
+
+	ret = 0;
+
+out:
+	munmap(map, sb.st_size);
+	return ret;
+}
+
+int
+wl_connection_get_bulk_data(struct wl_connection *connection, int fd)
+{
+	int ret = -1;
+	uint32_t need;
+	uint32_t have;
+	char *dump = NULL;
+	int total;
+
+	have = wl_buffer_size(&connection->in);
+	if (!have) {
+		if (wl_os_read(connection->fd, &need, sizeof need) < 0)
+			goto out;
+	} else {
+		wl_connection_copy(connection, &need, sizeof need);
+		wl_connection_consume(connection, sizeof need);
+	}
+	total = need;
+	dump = malloc(need);
+	have = wl_buffer_size(&connection->in);
+	wl_connection_copy(connection, dump, have);
+	wl_connection_consume(connection, have);
+	need -= have;
+	if (wl_os_read(connection->fd, dump + have, need) < 0)
+		goto out;
+
+	if (write(fd, dump, total) < total)
+		goto out;
+
+	ret = 0;
+
+out:
+	free(dump);
+	return ret;
+}
+
+int
 wl_closure_send(struct wl_closure *closure, struct wl_connection *connection)
 {
 	int size;
diff --git a/src/wayland-private.h b/src/wayland-private.h
index 67de269..be41e83 100644
--- a/src/wayland-private.h
+++ b/src/wayland-private.h
@@ -206,6 +206,12 @@ wl_closure_dispatch(struct wl_closure *closure, wl_dispatcher_func_t dispatcher,
 		    struct wl_object *target, uint32_t opcode);
 
 int
+wl_connection_get_bulk_data(struct wl_connection *connection, int fd);
+
+int
+wl_connection_put_bulk_data(struct wl_connection *connection, int fd);
+
+int
 wl_closure_send(struct wl_closure *closure, struct wl_connection *connection);
 
 int
-- 
2.7.0



More information about the wayland-devel mailing list