diff --git a/0001-add-systemd-socket-activation.patch b/0001-add-systemd-socket-activation.patch new file mode 100644 index 0000000..5b5a4ee --- /dev/null +++ b/0001-add-systemd-socket-activation.patch @@ -0,0 +1,194 @@ +From e5dcacdefbdf50f23b51d3cb172a398aa5e9309f Mon Sep 17 00:00:00 2001 +From: Wim Taymans +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 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 ', 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 ++#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 + diff --git a/pipewire.spec b/pipewire.spec index dd3d481..99d4bcb 100644 --- a/pipewire.spec +++ b/pipewire.spec @@ -15,7 +15,7 @@ Name: pipewire Summary: Media Sharing Server Version: 0.2.3 -Release: 1%{?snap:.%{snap}git%{shortcommit}}%{?dist} +Release: 2%{?snap:.%{snap}git%{shortcommit}}%{?dist} License: LGPLv2+ URL: https://pipewire.org/ %if 0%{?gitrel} @@ -27,6 +27,7 @@ Source0: https://github.com/PipeWire/pipewire/archive/%{version}.tar.gz %endif ## upstream patches +Patch0: 0001-add-systemd-socket-activation.patch ## upstreamable patches @@ -100,6 +101,8 @@ This package contains command line utilities for the PipeWire media server. %prep %setup -q -T -b0 -n %{name}-%{version}%{?gitrel:-%{gitrel}-g%{shortcommit}} +%patch0 -p1 -b .0000 + %build %meson -D docs=true -D man=true -D gstreamer=true -D systemd=true %meson_build @@ -107,13 +110,16 @@ This package contains command line utilities for the PipeWire media server. %install %meson_install +mkdir %{buildroot}%{_userunitdir}/sockets.target.wants +ln -s ../pipewire.socket %{buildroot}%{_userunitdir}/sockets.target.wants/pipewire.socket + %check %meson_test %pre getent group pipewire >/dev/null || groupadd -r pipewire getent passwd pipewire >/dev/null || \ - useradd -r -g pipewire -d /var/run/pipewire -s /sbin/nologin -c "PipeWire System Daemon" pipewire + useradd -r -g pipewire -d %{_localstatedir}/run/pipewire -s /sbin/nologin -c "PipeWire System Daemon" pipewire exit 0 %ldconfig_scriptlets @@ -123,6 +129,7 @@ exit 0 %doc README %if 0%{?systemd} %{_userunitdir}/pipewire.* +%{_userunitdir}/sockets.target.wants/pipewire.socket %endif %{_bindir}/pipewire %{_libdir}/libpipewire-%{apiversion}.so.* @@ -158,6 +165,9 @@ exit 0 %{_bindir}/spa-inspect %changelog +* Wed Oct 18 2018 Wim Taymans - 0.2.3-2 +- Add systemd socket activation + * Thu Aug 30 2018 Wim Taymans - 0.2.3-1 - Update to 0.2.3