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 <der...@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

_______________________________________________
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to