]> Git — Sourcephile - julm/julm-nix.git/blob - nixpkgs/overlays/tmux/0001-Add-support-for-systemd-socket-activation.patch
tmux: enable socket activation
[julm/julm-nix.git] / nixpkgs / overlays / tmux / 0001-Add-support-for-systemd-socket-activation.patch
1 From 1775d9857a7ac60578f3560613ead7c189d8b756 Mon Sep 17 00:00:00 2001
2 From: Julien Moutinho <julm+tmux@sourcephile.fr>
3 Date: Wed, 16 Mar 2022 02:43:18 +0100
4 Subject: [PATCH] Add support for systemd socket activation
5
6 See http://0pointer.de/blog/projects/socket-activation.html
7 and https://www.freedesktop.org/software/systemd/man/sd_listen_fds.html
8
9 Fixes #3117
10 ---
11 Makefile.am | 5 ++++
12 compat.h | 5 ++++
13 compat/systemd.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++
14 configure.ac | 24 +++++++++++++++++++
15 server.c | 22 +++++++++++-------
16 tmux.c | 1 +
17 tmux.h | 2 ++
18 7 files changed, 111 insertions(+), 8 deletions(-)
19 create mode 100644 compat/systemd.c
20
21 diff --git a/Makefile.am b/Makefile.am
22 index 68494932..5bdd9d5f 100644
23 --- a/Makefile.am
24 +++ b/Makefile.am
25 @@ -204,6 +204,11 @@ if NEED_FORKPTY
26 nodist_tmux_SOURCES += compat/forkpty-@PLATFORM@.c
27 endif
28
29 +# Add compat file for systemd.
30 +if HAVE_SYSTEMD
31 +nodist_tmux_SOURCES += compat/systemd.c
32 +endif
33 +
34 # Add compat file for utf8proc.
35 if HAVE_UTF8PROC
36 nodist_tmux_SOURCES += compat/utf8proc.c
37 diff --git a/compat.h b/compat.h
38 index be726831..6eb97619 100644
39 --- a/compat.h
40 +++ b/compat.h
41 @@ -421,6 +421,11 @@ void *reallocarray(void *, size_t, size_t);
42 void *recallocarray(void *, size_t, size_t, size_t);
43 #endif
44
45 +#ifdef HAVE_SYSTEMD
46 +/* systemd.c */
47 +int systemd_create_socket(int, char **);
48 +#endif
49 +
50 #ifdef HAVE_UTF8PROC
51 /* utf8proc.c */
52 int utf8proc_wcwidth(wchar_t);
53 diff --git a/compat/systemd.c b/compat/systemd.c
54 new file mode 100644
55 index 00000000..8e34c007
56 --- /dev/null
57 +++ b/compat/systemd.c
58 @@ -0,0 +1,60 @@
59 +/* $OpenBSD$ */
60 +
61 +/*
62 + * Copyright (c) 2022 Nicholas Marriott <nicholas.marriott@gmail.com>
63 + * Copyright (c) 2022 Julien Moutinho <julm+tmux@sourcephile.fr>
64 + *
65 + * Permission to use, copy, modify, and distribute this software for any
66 + * purpose with or without fee is hereby granted, provided that the above
67 + * copyright notice and this permission notice appear in all copies.
68 + *
69 + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
70 + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
71 + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
72 + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
73 + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
74 + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
75 + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
76 + */
77 +
78 +#include <sys/types.h>
79 +#include <sys/un.h>
80 +
81 +#include <systemd/sd-daemon.h>
82 +
83 +#include "tmux.h"
84 +
85 +int
86 +systemd_create_socket(int flags, char **cause)
87 +{
88 + int fds;
89 + int fd;
90 + struct sockaddr_un sa;
91 + int addrlen = sizeof sa;
92 +
93 + fds = sd_listen_fds(0);
94 + if (fds > 1) { /* too many file descriptors */
95 + errno = E2BIG;
96 + goto fail;
97 + }
98 +
99 + if (fds == 1) { /* socket-activated */
100 + fd = SD_LISTEN_FDS_START;
101 + if (!sd_is_socket_unix(fd, SOCK_STREAM, 1, NULL, 0)) {
102 + errno = EPFNOSUPPORT;
103 + goto fail;
104 + }
105 + if (getsockname(fd, (struct sockaddr *)&sa, &addrlen) == -1)
106 + goto fail;
107 + socket_path = xstrdup(sa.sun_path);
108 + socket_can_be_created_again = 0;
109 + return (fd);
110 + }
111 +
112 + return (server_create_socket(flags, cause));
113 +
114 +fail:
115 + if (cause != NULL)
116 + xasprintf(cause, "systemd socket error (%s)", strerror(errno));
117 + return (-1);
118 +}
119 diff --git a/configure.ac b/configure.ac
120 index e473f141..f90d9f05 100644
121 --- a/configure.ac
122 +++ b/configure.ac
123 @@ -390,6 +390,30 @@ if test "x$enable_utf8proc" = xyes; then
124 fi
125 AM_CONDITIONAL(HAVE_UTF8PROC, [test "x$enable_utf8proc" = xyes])
126
127 +# Check for systemd support.
128 +AC_ARG_ENABLE(
129 + systemd,
130 + AS_HELP_STRING(--enable-systemd, enable systemd integration)
131 +)
132 +if test x"$enable_systemd" = xyes; then
133 + PKG_CHECK_MODULES(
134 + SYSTEMD,
135 + libsystemd,
136 + [
137 + AM_CPPFLAGS="$SYSTEMD_CFLAGS $AM_CPPFLAGS"
138 + CPPFLAGS="$AM_CPPFLAGS $SAVED_CPPFLAGS"
139 + LIBS="$SYSTEMD_LIBS $LIBS"
140 + AC_DEFINE(HAVE_SYSTEMD)
141 + found_systemd=yes
142 + ],
143 + found_systemd=no
144 + )
145 + if test "x$found_systemd" = xno; then
146 + AC_MSG_ERROR("systemd not found")
147 + fi
148 +fi
149 +AM_CONDITIONAL(HAVE_SYSTEMD, [test "x$found_systemd" = xyes])
150 +
151 # Check for b64_ntop. If we have b64_ntop, we assume b64_pton as well.
152 AC_MSG_CHECKING(for b64_ntop)
153 AC_LINK_IFELSE([AC_LANG_PROGRAM(
154 diff --git a/server.c b/server.c
155 index 2db5a8d8..5acddb10 100644
156 --- a/server.c
157 +++ b/server.c
158 @@ -100,7 +100,7 @@ server_check_marked(void)
159 }
160
161 /* Create server socket. */
162 -static int
163 +int
164 server_create_socket(int flags, char **cause)
165 {
166 struct sockaddr_un sa;
167 @@ -214,7 +214,11 @@ server_start(struct tmuxproc *client, int flags, struct event_base *base,
168
169 gettimeofday(&start_time, NULL);
170
171 +#ifdef HAVE_SYSTEMD
172 + server_fd = systemd_create_socket(flags, &cause);
173 +#else
174 server_fd = server_create_socket(flags, &cause);
175 +#endif
176 if (server_fd != -1)
177 server_update_socket();
178 if (~flags & CLIENT_NOFORK)
179 @@ -424,14 +428,16 @@ server_signal(int sig)
180 server_child_signal();
181 break;
182 case SIGUSR1:
183 - event_del(&server_ev_accept);
184 - fd = server_create_socket(server_client_flags, NULL);
185 - if (fd != -1) {
186 - close(server_fd);
187 - server_fd = fd;
188 - server_update_socket();
189 + if (socket_can_be_created_again) {
190 + event_del(&server_ev_accept);
191 + fd = server_create_socket(server_client_flags, NULL);
192 + if (fd != -1) {
193 + close(server_fd);
194 + server_fd = fd;
195 + server_update_socket();
196 + }
197 + server_add_accept(0);
198 }
199 - server_add_accept(0);
200 break;
201 case SIGUSR2:
202 proc_toggle_log(server_proc);
203 diff --git a/tmux.c b/tmux.c
204 index 11c368ff..187a7429 100644
205 --- a/tmux.c
206 +++ b/tmux.c
207 @@ -40,6 +40,7 @@ struct environ *global_environ;
208
209 struct timeval start_time;
210 const char *socket_path;
211 +int socket_can_be_created_again = 1;
212 int ptm_fd = -1;
213 const char *shell_command;
214
215 diff --git a/tmux.h b/tmux.h
216 index 370c7773..d5c63390 100644
217 --- a/tmux.h
218 +++ b/tmux.h
219 @@ -2001,6 +2001,7 @@ extern struct options *global_s_options;
220 extern struct options *global_w_options;
221 extern struct environ *global_environ;
222 extern struct timeval start_time;
223 +extern int socket_can_be_created_again;
224 extern const char *socket_path;
225 extern const char *shell_command;
226 extern int ptm_fd;
227 @@ -2583,6 +2584,7 @@ int server_start(struct tmuxproc *, int, struct event_base *, int, char *);
228 void server_update_socket(void);
229 void server_add_accept(int);
230 void printflike(1, 2) server_add_message(const char *, ...);
231 +int server_create_socket(int, char **);
232
233 /* server-client.c */
234 RB_PROTOTYPE(client_windows, client_window, entry, server_client_window_cmp);
235 --
236 2.34.1
237