summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicholas Marriott <nicholas.marriott@gmail.com>2022-03-28 08:42:13 +0100
committerNicholas Marriott <nicholas.marriott@gmail.com>2022-03-28 08:42:13 +0100
commitfc7f1e7acb3539a43df46136e971f770515e0b0d (patch)
treeffe4d697936e4149d955bbfdf3805a9258804dda
parentd26a4ea463b96923bd93d95817f0fe78550c06ca (diff)
Add support for systemd socket activation (where systemd creates the Unix
domain socket for tmux rather than tmux creating it). Build with --enable-systemd. From Julien Moutinho in GitHub issue 3119.
-rw-r--r--Makefile.am5
-rw-r--r--compat.h5
-rw-r--r--compat/systemd.c58
-rw-r--r--configure.ac25
-rw-r--r--server.c6
-rw-r--r--tmux.h1
6 files changed, 99 insertions, 1 deletions
diff --git a/Makefile.am b/Makefile.am
index 68494932..5bdd9d5f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -204,6 +204,11 @@ if NEED_FORKPTY
nodist_tmux_SOURCES += compat/forkpty-@PLATFORM@.c
endif
+# Add compat file for systemd.
+if HAVE_SYSTEMD
+nodist_tmux_SOURCES += compat/systemd.c
+endif
+
# Add compat file for utf8proc.
if HAVE_UTF8PROC
nodist_tmux_SOURCES += compat/utf8proc.c
diff --git a/compat.h b/compat.h
index be726831..6eb97619 100644
--- a/compat.h
+++ b/compat.h
@@ -421,6 +421,11 @@ void *reallocarray(void *, size_t, size_t);
void *recallocarray(void *, size_t, size_t, size_t);
#endif
+#ifdef HAVE_SYSTEMD
+/* systemd.c */
+int systemd_create_socket(int, char **);
+#endif
+
#ifdef HAVE_UTF8PROC
/* utf8proc.c */
int utf8proc_wcwidth(wchar_t);
diff --git a/compat/systemd.c b/compat/systemd.c
new file mode 100644
index 00000000..7317e43a
--- /dev/null
+++ b/compat/systemd.c
@@ -0,0 +1,58 @@
+/* $OpenBSD$ */
+
+/*
+ * Copyright (c) 2022 Nicholas Marriott <nicholas.marriott@gmail.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/types.h>
+#include <sys/un.h>
+
+#include <systemd/sd-daemon.h>
+
+#include "tmux.h"
+
+int
+systemd_create_socket(int flags, char **cause)
+{
+ int fds;
+ int fd;
+ struct sockaddr_un sa;
+ int addrlen = sizeof sa;
+
+ fds = sd_listen_fds(0);
+ if (fds > 1) { /* too many file descriptors */
+ errno = E2BIG;
+ goto fail;
+ }
+
+ if (fds == 1) { /* socket-activated */
+ fd = SD_LISTEN_FDS_START;
+ if (!sd_is_socket_unix(fd, SOCK_STREAM, 1, NULL, 0)) {
+ errno = EPFNOSUPPORT;
+ goto fail;
+ }
+ if (getsockname(fd, (struct sockaddr *)&sa, &addrlen) == -1)
+ goto fail;
+ socket_path = xstrdup(sa.sun_path);
+ return (fd);
+ }
+
+ return (server_create_socket(flags, cause));
+
+fail:
+ if (cause != NULL)
+ xasprintf(cause, "systemd socket error (%s)", strerror(errno));
+ return (-1);
+}
diff --git a/configure.ac b/configure.ac
index e473f141..276f71c8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -390,6 +390,31 @@ if test "x$enable_utf8proc" = xyes; then
fi
AM_CONDITIONAL(HAVE_UTF8PROC, [test "x$enable_utf8proc" = xyes])
+# Check for systemd support.
+AC_ARG_ENABLE(
+ systemd,
+ AS_HELP_STRING(--enable-systemd, enable systemd integration)
+)
+if test x"$enable_systemd" = xyes; then
+ PKG_CHECK_MODULES(
+ SYSTEMD,
+ libsystemd,
+ [
+ AM_CPPFLAGS="$SYSTEMD_CFLAGS $AM_CPPFLAGS"
+ CPPFLAGS="$AM_CPPFLAGS $SAVED_CPPFLAGS"
+ LIBS="$SYSTEMD_LIBS $LIBS"
+ found_systemd=yes
+ ],
+ found_systemd=no
+ )
+ if test "x$found_systemd" = xyes; then
+ AC_DEFINE(HAVE_SYSTEMD)
+ else
+ AC_MSG_ERROR("systemd not found")
+ fi
+fi
+AM_CONDITIONAL(HAVE_SYSTEMD, [test "x$found_systemd" = xyes])
+
# Check for b64_ntop. If we have b64_ntop, we assume b64_pton as well.
AC_MSG_CHECKING(for b64_ntop)
AC_LINK_IFELSE([AC_LANG_PROGRAM(
diff --git a/server.c b/server.c
index 2db5a8d8..bf3a8361 100644
--- a/server.c
+++ b/server.c
@@ -100,7 +100,7 @@ server_check_marked(void)
}
/* Create server socket. */
-static int
+int
server_create_socket(int flags, char **cause)
{
struct sockaddr_un sa;
@@ -214,7 +214,11 @@ server_start(struct tmuxproc *client, int flags, struct event_base *base,
gettimeofday(&start_time, NULL);
+#ifdef HAVE_SYSTEMD
+ server_fd = systemd_create_socket(flags, &cause);
+#else
server_fd = server_create_socket(flags, &cause);
+#endif
if (server_fd != -1)
server_update_socket();
if (~flags & CLIENT_NOFORK)
diff --git a/tmux.h b/tmux.h
index 370c7773..f16b5250 100644
--- a/tmux.h
+++ b/tmux.h
@@ -2583,6 +2583,7 @@ int server_start(struct tmuxproc *, int, struct event_base *, int, char *);
void server_update_socket(void);
void server_add_accept(int);
void printflike(1, 2) server_add_message(const char *, ...);
+int server_create_socket(int, char **);
/* server-client.c */
RB_PROTOTYPE(client_windows, client_window, entry, server_client_window_cmp);