195 lines
5.7 KiB
Diff
195 lines
5.7 KiB
Diff
From e5dcacdefbdf50f23b51d3cb172a398aa5e9309f Mon Sep 17 00:00:00 2001
|
|
From: Wim Taymans <wtaymans@redhat.com>
|
|
Date: Thu, 18 Oct 2018 09:50:43 +0200
|
|
Subject: [PATCH] add systemd socket activation
|
|
|
|
---
|
|
config.h.meson | 3 ++
|
|
meson.build | 10 +++++
|
|
src/daemon/meson.build | 9 +----
|
|
src/modules/meson.build | 2 +-
|
|
src/modules/module-protocol-native.c | 59 +++++++++++++++++-----------
|
|
5 files changed, 52 insertions(+), 31 deletions(-)
|
|
|
|
diff --git a/config.h.meson b/config.h.meson
|
|
index 335f3de5..ad0b79d0 100644
|
|
--- a/config.h.meson
|
|
+++ b/config.h.meson
|
|
@@ -317,6 +317,9 @@
|
|
/* Define to 1 if you have the <winsock2.h> header file. */
|
|
#mesondefine HAVE_WINSOCK2_H
|
|
|
|
+/* for the systemd header files */
|
|
+#mesondefine HAVE_SYSTEMD_DAEMON
|
|
+
|
|
/* the host CPU */
|
|
#mesondefine HOST_CPU
|
|
|
|
diff --git a/meson.build b/meson.build
|
|
index 8e440fe5..dde1f22b 100644
|
|
--- a/meson.build
|
|
+++ b/meson.build
|
|
@@ -125,6 +125,16 @@ if cc.has_function('memfd_create', prefix : '#include <sys/mman.h>', args : [ '-
|
|
cdata.set('HAVE_MEMFD_CREATE', 1)
|
|
endif
|
|
|
|
+if get_option('systemd')
|
|
+ systemd = dependency('systemd', required: false)
|
|
+ systemd_dep = dependency('libsystemd', required: false)
|
|
+ if systemd.found()
|
|
+ cdata.set('HAVE_SYSTEMD_DAEMON', 1)
|
|
+ else
|
|
+ warning('Systemd integration was enabled, but systemd is not available')
|
|
+ endif
|
|
+endif
|
|
+
|
|
configure_file(input : 'config.h.meson',
|
|
output : 'config.h',
|
|
configuration : cdata)
|
|
diff --git a/src/daemon/meson.build b/src/daemon/meson.build
|
|
index 0761224d..8b4f5205 100644
|
|
--- a/src/daemon/meson.build
|
|
+++ b/src/daemon/meson.build
|
|
@@ -30,11 +30,6 @@ executable('pipewire',
|
|
dependencies : [pipewire_dep],
|
|
)
|
|
|
|
-if get_option('systemd')
|
|
- systemd = dependency('systemd', required: false)
|
|
- if systemd.found()
|
|
- subdir('systemd')
|
|
- else
|
|
- warning('Systemd integration was enabled, but systemd is not available')
|
|
- endif
|
|
+if systemd.found()
|
|
+ subdir('systemd')
|
|
endif
|
|
diff --git a/src/modules/meson.build b/src/modules/meson.build
|
|
index 2c5092df..4dcb6e59 100644
|
|
--- a/src/modules/meson.build
|
|
+++ b/src/modules/meson.build
|
|
@@ -81,7 +81,7 @@ pipewire_module_protocol_native = shared_library('pipewire-module-protocol-nativ
|
|
include_directories : [configinc, spa_inc],
|
|
install : true,
|
|
install_dir : modules_install_dir,
|
|
- dependencies : [mathlib, dl_lib, pipewire_dep],
|
|
+ dependencies : [mathlib, dl_lib, pipewire_dep, systemd_dep],
|
|
)
|
|
|
|
pipewire_module_audio_dsp = shared_library('pipewire-module-audio-dsp',
|
|
diff --git a/src/modules/module-protocol-native.c b/src/modules/module-protocol-native.c
|
|
index 7417aa4f..84ebb5c1 100644
|
|
--- a/src/modules/module-protocol-native.c
|
|
+++ b/src/modules/module-protocol-native.c
|
|
@@ -32,6 +32,10 @@
|
|
|
|
#include "config.h"
|
|
|
|
+#ifdef HAVE_SYSTEMD_DAEMON
|
|
+#include <systemd/sd-daemon.h>
|
|
+#endif
|
|
+
|
|
#include "pipewire/pipewire.h"
|
|
#include "pipewire/private.h"
|
|
#include "pipewire/log.h"
|
|
@@ -88,6 +92,7 @@ struct server {
|
|
int fd_lock;
|
|
struct sockaddr_un addr;
|
|
char lock_addr[UNIX_PATH_MAX + LOCK_SUFFIXLEN];
|
|
+ bool activated;
|
|
|
|
struct pw_loop *loop;
|
|
struct spa_source *source;
|
|
@@ -386,8 +391,6 @@ static bool init_socket_name(struct server *s, const char *name)
|
|
|
|
static bool lock_socket(struct server *s)
|
|
{
|
|
- struct stat socket_stat;
|
|
-
|
|
snprintf(s->lock_addr, sizeof(s->lock_addr), "%s%s", s->addr.sun_path, LOCK_SUFFIX);
|
|
|
|
s->fd_lock = open(s->lock_addr, O_CREAT | O_CLOEXEC,
|
|
@@ -403,15 +406,6 @@ static bool lock_socket(struct server *s)
|
|
s->lock_addr);
|
|
goto err_fd;
|
|
}
|
|
-
|
|
- if (stat(s->addr.sun_path, &socket_stat) < 0) {
|
|
- if (errno != ENOENT) {
|
|
- pw_log_error("did not manage to stat file %s\n", s->addr.sun_path);
|
|
- goto err_fd;
|
|
- }
|
|
- } else if (socket_stat.st_mode & S_IWUSR || socket_stat.st_mode & S_IWGRP) {
|
|
- unlink(s->addr.sun_path);
|
|
- }
|
|
return true;
|
|
|
|
err_fd:
|
|
@@ -455,24 +449,43 @@ socket_data(void *data, int fd, enum spa_io mask)
|
|
static bool add_socket(struct pw_protocol *protocol, struct server *s)
|
|
{
|
|
socklen_t size;
|
|
- int fd;
|
|
-
|
|
- if ((fd = socket(PF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0)) < 0)
|
|
- goto error;
|
|
+ int fd = -1;
|
|
+ bool activated = false;
|
|
|
|
- size = offsetof(struct sockaddr_un, sun_path) + strlen(s->addr.sun_path);
|
|
- if (bind(fd, (struct sockaddr *) &s->addr, size) < 0) {
|
|
- pw_log_error("bind() failed with error: %m");
|
|
- goto error_close;
|
|
+#ifdef HAVE_SYSTEMD_DAEMON
|
|
+ {
|
|
+ int i, n = sd_listen_fds(0);
|
|
+ for (i = 0; i < n; ++i) {
|
|
+ if (sd_is_socket_unix(SD_LISTEN_FDS_START + i, SOCK_STREAM,
|
|
+ 1, s->addr.sun_path, 0) > 0) {
|
|
+ fd = SD_LISTEN_FDS_START + i;
|
|
+ activated = true;
|
|
+ pw_log_info("Found socket activation socket for '%s'", s->addr.sun_path);
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
}
|
|
+#endif
|
|
|
|
- if (listen(fd, 128) < 0) {
|
|
- pw_log_error("listen() failed with error: %m");
|
|
- goto error_close;
|
|
+ if (fd < 0) {
|
|
+ if ((fd = socket(PF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0)) < 0)
|
|
+ goto error;
|
|
+
|
|
+ size = offsetof(struct sockaddr_un, sun_path) + strlen(s->addr.sun_path);
|
|
+ if (bind(fd, (struct sockaddr *) &s->addr, size) < 0) {
|
|
+ pw_log_error("bind() failed with error: %m");
|
|
+ goto error_close;
|
|
+ }
|
|
+
|
|
+ if (listen(fd, 128) < 0) {
|
|
+ pw_log_error("listen() failed with error: %m");
|
|
+ goto error_close;
|
|
+ }
|
|
}
|
|
|
|
s->loop = pw_core_get_main_loop(protocol->core);
|
|
s->source = pw_loop_add_io(s->loop, fd, SPA_IO_IN, true, socket_data, s);
|
|
+ s->activated = activated;
|
|
if (s->source == NULL)
|
|
goto error_close;
|
|
|
|
@@ -712,7 +725,7 @@ static void destroy_server(struct pw_protocol_server *server)
|
|
|
|
if (s->source)
|
|
pw_loop_destroy_source(s->loop, s->source);
|
|
- if (s->addr.sun_path[0])
|
|
+ if (s->addr.sun_path[0] && !s->activated)
|
|
unlink(s->addr.sun_path);
|
|
if (s->lock_addr[0])
|
|
unlink(s->lock_addr);
|
|
--
|
|
2.17.1
|
|
|