This is acquring the socket, omit bind and listen,
and not touching (e.g. removing) the socket path
since thats managed by systemd.
---
 src/wayland-server.c | 42 +++++++++++++++++++++++++++++++++++++++---
 1 file changed, 39 insertions(+), 3 deletions(-)

diff --git a/src/wayland-server.c b/src/wayland-server.c
index 9ac0a71..c61291e 100644
--- a/src/wayland-server.c
+++ b/src/wayland-server.c
@@ -45,6 +45,7 @@
 #include "wayland-server.h"
 #include "wayland-server-protocol.h"
 #include "wayland-os.h"
+#include "sd-daemon.h"
 
 /* This is the size of the char array in struct sock_addr_un.
    No Wayland socket can be created with a path longer than this,
@@ -59,6 +60,7 @@
 struct wl_socket {
        int fd;
        int fd_lock;
+       int is_systemd;
        struct sockaddr_un addr;
        char lock_addr[UNIX_PATH_MAX + LOCK_SUFFIXLEN];
        struct wl_list link;
@@ -1123,7 +1125,8 @@ wl_display_destroy(struct wl_display *display)
 
        wl_list_for_each_safe(s, next, &display->socket_list, link) {
                wl_event_source_remove(s->source);
-               unlink(s->addr.sun_path);
+               if (!s->is_systemd)
+                       unlink(s->addr.sun_path);
                close(s->fd);
                unlink(s->lock_addr);
                close(s->fd_lock);
@@ -1277,6 +1280,9 @@ get_socket_lock(struct wl_socket *socket)
                return -1;
        }
 
+       if (socket->is_systemd)
+               return fd_lock;
+
        if (stat(socket->addr.sun_path, &socket_stat) < 0 ) {
                if (errno != ENOENT) {
                        wl_log("did not manage to stat file %s\n",
@@ -1297,6 +1303,9 @@ init_socket(struct wl_socket *s, int name_size)
 {
        socklen_t size;
 
+       if (s->is_systemd)
+               return 0;
+
        size = offsetof (struct sockaddr_un, sun_path) + name_size;
        if (bind(s->fd, (struct sockaddr *) &s->addr, size) < 0) {
                wl_log("bind() failed with error: %m\n");
@@ -1312,6 +1321,30 @@ init_socket(struct wl_socket *s, int name_size)
        return 0;
 }
 
+static int
+acquire_systemd_socket(struct wl_socket *s, int type)
+{
+       int n, fd;
+
+       s->is_systemd = 0;
+       n = sd_listen_fds(0);
+       if (n <= 0) {
+               if (n < 0)
+                       wl_log("failed to acquire socket from systemd: %m\n");
+               return -1;
+       }
+
+       for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd++) {
+               if (sd_is_socket_unix(fd, type, 1, s->addr.sun_path, 0) == 1) {
+                       s->is_systemd = 1;
+                       s->fd = fd;
+                       return 0;
+               }
+       }
+
+       return -1;
+}
+
 WL_EXPORT int
 wl_display_add_socket(struct wl_display *display, const char *name)
 {
@@ -1354,7 +1387,9 @@ wl_display_add_socket(struct wl_display *display, const 
char *name)
                return -1;
        };
 
-       s->fd = wl_os_socket_cloexec(PF_LOCAL, SOCK_STREAM, 0);
+       if (acquire_systemd_socket(s, SOCK_STREAM) < 0)
+               s->fd = wl_os_socket_cloexec(PF_LOCAL, SOCK_STREAM, 0);
+
        if (s->fd < 0) {
                free(s);
                return -1;
@@ -1380,7 +1415,8 @@ wl_display_add_socket(struct wl_display *display, const 
char *name)
                                         WL_EVENT_READABLE,
                                         socket_data, display);
        if (s->source == NULL) {
-               unlink(s->addr.sun_path);
+               if (!s->is_systemd)
+                       unlink(s->addr.sun_path);
                close(s->fd);
                unlink(s->lock_addr);
                close(s->fd_lock);
-- 
1.7.12.4

_______________________________________________
wayland-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to