Description: Implement service activation via systemd socket.
From: Nathan Pratta Teodosio <nathan.teodosio@canonical.com>
Date: 10 May 2023 08:55:45 +0200
Applied-Upstream: commit:f55ea76 (and onwards) and commit:4fc86d7

---
 Makefile.am                        | 10 +++++++---
 configure.ac                       | 13 +++++++++++++
 speech-dispatcher.service.in (new) | 23 +++++++++++++++++++++++
 speech-dispatcher.socket (new)     |  8 ++++++++
 src/server/Makefile.am             |  6 ++++--
 src/server/speechd.c               |  9 +++++++++
 6 files changed, 64 insertions(+), 5 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index 3a6009a9..6dbb8828 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -24,18 +24,22 @@ BUILT_SOURCES = $(top_srcdir)/.version
 
 SUBDIRS= include locale src config doc po
 
-EXTRA_DIST= config.rpath COPYING.LGPL COPYING.GPL-2 COPYING.GPL-3 ANNOUNCE BUGS FAQ README.md README.packagers README.translators README.overview.md README.style.md build.sh git-version-gen split-version.sh speech-dispatcherd.service.in po/Makevars.in po/README
+EXTRA_DIST= config.rpath COPYING.LGPL COPYING.GPL-2 COPYING.GPL-3 ANNOUNCE BUGS FAQ README.md README.packagers README.translators README.overview.md README.style.md build.sh git-version-gen split-version.sh speech-dispatcherd.service.in speech-dispatcher.socket speech-dispatcher.service.in po/Makevars.in po/README
 
 CLEANFILES=
 
 MAINTAINERCLEANFILES=configure
 
-AM_DISTCHECK_CONFIGURE_FLAGS=--without-systemdsystemunitdir
+AM_DISTCHECK_CONFIGURE_FLAGS=--without-systemdsystemunitdir --without-systemduserunitdir
 
 nodist_systemdsystemunit_DATA = \
 	speech-dispatcherd.service
+if HAVE_SYSTEMD
+nodist_systemduserunit_DATA = \
+	speech-dispatcher.service speech-dispatcher.socket
+endif
 CLEANFILES += \
-	speech-dispatcherd.service
+	speech-dispatcherd.service speech-dispatcher.service
 %.service: %.service.in
 	$(AM_V_GEN)sed -e 's,@bindir\@,$(bindir),g' $< > $@
 
diff --git a/configure.ac b/configure.ac
index 13a21c8e..5d51750a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -118,6 +118,12 @@ PKG_CHECK_MODULES([SNDFILE], [sndfile >= 1.0.2])
 AC_SUBST([SNDFILE_CFLAGS])
 AC_SUBST([SNDFILE_LIBS])
 
+PKG_CHECK_MODULES([LIBSYSTEMD], [libsystemd], [have_systemd="yes"], [have_systemd="no"])
+if test x$have_systemd = xyes; then
+    AC_DEFINE([HAVE_SYSTEMD], [1], [Define to 1 if you have the systemd library])
+fi
+AM_CONDITIONAL(HAVE_SYSTEMD, [test x$have_systemd = xyes])
+
 # Checks for header files.
 AC_CHECK_HEADERS([arpa/inet.h fcntl.h langinfo.h limits.h netdb.h])
 AC_CHECK_HEADERS([netinet/in.h stddef.h stdlib.h string.h sys/filio.h])
@@ -542,6 +548,13 @@ if test "x$with_systemdsystemunitdir" != xno; then
         AC_SUBST([systemdsystemunitdir], [$with_systemdsystemunitdir])
 fi
 AM_CONDITIONAL(HAVE_SYSTEMD, [test -n "$with_systemdsystemunitdir" -a "x$with_systemdsystemunitdir" != xno ])
+AC_ARG_WITH([systemduserunitdir],
+        AS_HELP_STRING([--with-systemduserunitdir=DIR], [Directory for systemd user service files]),
+        [], [with_systemduserunitdir=$($PKG_CONFIG --variable=systemduserunitdir systemd)])
+if test "x$with_systemduserunitdir" != xno; then
+        AC_SUBST([systemduserunitdir], [$with_systemduserunitdir])
+fi
+AM_CONDITIONAL(HAVE_SYSTEMD, [test -n "$with_systemduserunitdir" -a "x$with_systemduserunitdir" != xno ])
 
 AC_CONFIG_FILES([Makefile
 		 run-speechd
diff --git a/speech-dispatcher.service.in b/speech-dispatcher.service.in
new file mode 100644
index 00000000..4d257121
--- /dev/null
+++ b/speech-dispatcher.service.in
@@ -0,0 +1,23 @@
+# Copyright (C) 2018 Samuel Thibault <samuel.thibault@ens-lyon.org>
+#
+# This program is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any later
+# version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.  See the GNU General Public License for more details (file
+# COPYING in the root directory).
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+[Unit]
+Description=Common interface to speech synthesizers
+Requires=speech-dispatcher.socket
+
+[Service]
+Type=simple
+ExecStart=@bindir@/speech-dispatcher -s -t 0
+ExecReload=/bin/kill -HUP $MAINPID
diff --git a/speech-dispatcher.socket b/speech-dispatcher.socket
new file mode 100644
index 00000000..a9475e76
--- /dev/null
+++ b/speech-dispatcher.socket
@@ -0,0 +1,8 @@
+[Unit]
+Description=Speech Dispatcher Socket
+
+[Socket]
+ListenStream=%t/speech-dispatcher/speechd.sock
+
+[Install]
+WantedBy=sockets.target
diff --git a/src/server/Makefile.am b/src/server/Makefile.am
index 03235369..5acc59dd 100644
--- a/src/server/Makefile.am
+++ b/src/server/Makefile.am
@@ -29,7 +29,8 @@ speech_dispatcher_SOURCES = speechd.c speechd.h server.c server.h \
 	index_marking.c index_marking.h symbols.c symbols.h
 speech_dispatcher_CFLAGS = $(ERROR_CFLAGS)
 speech_dispatcher_CPPFLAGS = $(inc_local) $(DOTCONF_CFLAGS) $(GLIB_CFLAGS) \
-	$(GMODULE_CFLAGS) $(GTHREAD_CFLAGS) -DSYS_CONF=\"$(spdconfdir)\" \
+	$(GMODULE_CFLAGS) $(GTHREAD_CFLAGS) $(LIBSYSTEMD_CFLAGS) \
+	-DSYS_CONF=\"$(spdconfdir)\" \
 	-DSND_DATA=\"$(snddatadir)\" \
 	-DMODULEBINDIR=\"$(modulebindir)\" \
 	-DOLDMODULEBINDIR=\"$(oldmodulebindir)\" \
@@ -37,7 +38,8 @@ speech_dispatcher_CPPFLAGS = $(inc_local) $(DOTCONF_CFLAGS) $(GLIB_CFLAGS) \
 	-D_GNU_SOURCE -DDEFAULT_AUDIO_METHOD=\"$(default_audio_method)\"
 speech_dispatcher_LDFLAGS = $(RDYNAMIC)
 speech_dispatcher_LDADD = $(lib_common) $(DOTCONF_LIBS) $(GLIB_LIBS) \
-	$(SNDFILE_LIBS) $(GMODULE_LIBS) $(GTHREAD_LIBS) $(EXTRA_SOCKET_LIBS)
+	$(SNDFILE_LIBS) $(GMODULE_LIBS) $(GTHREAD_LIBS) $(EXTRA_SOCKET_LIBS) \
+	$(LIBSYSTEMD_LIBS)
 
 if HAVE_HELP2MAN
 speech-dispatcher.1: speech-dispatcher$(EXEEXT)
diff --git a/src/server/speechd.c b/src/server/speechd.c
index 742b7f6f..c7a51bff 100644
--- a/src/server/speechd.c
+++ b/src/server/speechd.c
@@ -29,6 +29,9 @@
 #include <sys/stat.h>
 #include <sys/socket.h>
 #include <sys/un.h>
+#ifdef HAVE_SYSTEMD
+#include <systemd/sd-daemon.h>
+#endif
 
 #ifdef HAVE_SYS_FILIO_H
 #include <sys/filio.h>	/* Needed for FIONREAD on Solaris */
@@ -1283,6 +1286,12 @@ int main(int argc, char *argv[])
 		g_free(spawn_socket_path);
 	}
 
+#ifdef HAVE_SYSTEMD
+	if (sd_listen_fds(0) >= 1) {
+		/* Daemon launched via Systemd socket activation */
+		server_socket = SD_LISTEN_FDS_START;
+	} else
+#endif
 	if (!strcmp(SpeechdOptions.communication_method, "inet_socket")) {
 		MSG(4, "Speech Dispatcher will use inet port %d",
 		    SpeechdOptions.port);
-- 
2.37.2

