[PATCH 4/5] server: Add support for systemd socket activation
Benjamin Franzke
benjaminfranzke at googlemail.com
Wed Feb 27 03:10:19 PST 2013
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
More information about the wayland-devel
mailing list