aboutsummaryrefslogtreecommitdiff
path: root/compat/systemd.c
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-04-06 14:19:52 +0100
commit1c69a91c25654339a0e670ed5a1495d52b37eb8e (patch)
treea55101c3181c5a776e68833f032d16cd534fe444 /compat/systemd.c
parent98de5784a0a35681b736dc11bb6758a08d428562 (diff)
downloadrtmux-1c69a91c25654339a0e670ed5a1495d52b37eb8e.tar.gz
rtmux-1c69a91c25654339a0e670ed5a1495d52b37eb8e.tar.bz2
rtmux-1c69a91c25654339a0e670ed5a1495d52b37eb8e.zip
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.
Diffstat (limited to 'compat/systemd.c')
-rw-r--r--compat/systemd.c58
1 files changed, 58 insertions, 0 deletions
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);
+}