···3535find_package(Threads)
3636find_package(ZLIB)
3737find_package(cJSON)
3838+find_package(Systemd)
38393940# @TODO Turn into a find_package LIBUVC file.
4041pkg_check_modules(LIBUVC libuvc)
···7273cmake_dependent_option(BUILD_WITH_DBUS "Enable dbus support (for BLE support)" ON "DBUS_FOUND" OFF)
7374cmake_dependent_option(BUILD_COMPOSITOR_MAIN "Build main compositor host" ON "BUILD_WITH_WAYLAND OR BUILD_WITH_XCB" OFF)
7475cmake_dependent_option(XRT_BUILD_IPC "Build OpenXR runtime target" ON "BUILD_COMPOSITOR_MAIN" OFF)
7676+cmake_dependent_option(XRT_HAVE_SYSTEMD "Enable systemd support (for socket activation of service)" ON "Systemd_FOUND AND XRT_BUILD_IPC" OFF)
7577cmake_dependent_option(BUILD_TARGET_OPENXR "Build OpenXR runtime target" ON "BUILD_COMPOSITOR_MAIN OR XRT_BUILD_IPC" OFF)
76787779# Most users won't touch these.
···156156 // Should we exit when a client disconnects.
157157 bool exit_on_disconnect;
158158159159+ //! Were we launched by socket activation, instead of explicitly?
160160+ bool launched_by_socket;
161161+159162 bool print_debug;
160163 bool print_spew;
161164
+59-7
src/xrt/ipc/ipc_server_process.c
···1212#include "xrt/xrt_device.h"
1313#include "xrt/xrt_instance.h"
1414#include "xrt/xrt_compositor.h"
1515+#include "xrt/xrt_config_have.h"
15161617#include "util/u_var.h"
1718#include "util/u_misc.h"
···3637#include <errno.h>
3738#include <stdio.h>
38394040+#ifdef XRT_HAVE_SYSTEMD
4141+#include <systemd/sd-daemon.h>
4242+#endif
39434044/*
4145 *
···6872 xrt_instance_destroy(&s->xinst);
69737074 if (s->listen_socket > 0) {
7575+ // Close socket on exit
7176 close(s->listen_socket);
7277 s->listen_socket = -1;
7378 }
···174179}
175180176181static int
177177-init_listen_socket(struct ipc_server *s)
182182+get_systemd_socket(struct ipc_server *s, int *out_fd)
183183+{
184184+#ifdef XRT_HAVE_SYSTEMD
185185+ // We may have been launched with socket activation
186186+ int num_fds = sd_listen_fds(0);
187187+ if (num_fds > 1) {
188188+ fprintf(stderr,
189189+ "Too many file descriptors passed by systemd.\n");
190190+ return -1;
191191+ }
192192+ if (num_fds == 1) {
193193+ *out_fd = SD_LISTEN_FDS_START + 0;
194194+ s->launched_by_socket = true;
195195+ printf("Got existing socket from systemd.\n");
196196+ }
197197+#endif
198198+ return 0;
199199+}
200200+static int
201201+create_listen_socket(struct ipc_server *s, int *out_fd)
178202{
203203+ // no fd provided
179204 struct sockaddr_un addr;
180205 int fd, ret;
181206···202227 close(fd);
203228 return ret;
204229 }
230230+ printf("Created listening socket.\n");
231231+ *out_fd = fd;
232232+ return 0;
233233+}
205234235235+static int
236236+init_listen_socket(struct ipc_server *s)
237237+{
238238+ int fd = -1, ret;
239239+ s->listen_socket = -1;
240240+241241+ ret = get_systemd_socket(s, &fd);
242242+ if (ret < 0) {
243243+ return ret;
244244+ }
245245+246246+ if (fd == -1) {
247247+ ret = create_listen_socket(s, &fd);
248248+ if (ret < 0) {
249249+ return ret;
250250+ }
251251+ }
206252 // All ok!
207253 s->listen_socket = fd;
254254+ printf("Listening socket is fd %d\n", s->listen_socket);
208255209256 return fd;
210257}
···221268222269 struct epoll_event ev = {0};
223270224224- ev.events = EPOLLIN;
225225- ev.data.fd = 0; // stdin
226226- ret = epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, 0, &ev);
227227- if (ret < 0) {
228228- fprintf(stderr, "ERROR: epoll_ctl(stdin) failed '%i'\n", ret);
229229- return ret;
271271+ if (!s->launched_by_socket) {
272272+ // Can't do this when launched by systemd socket activation by
273273+ // default
274274+ ev.events = EPOLLIN;
275275+ ev.data.fd = 0; // stdin
276276+ ret = epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, 0, &ev);
277277+ if (ret < 0) {
278278+ fprintf(stderr, "ERROR: epoll_ctl(stdin) failed '%i'\n",
279279+ ret);
280280+ return ret;
281281+ }
230282 }
231283232284 ev.events = EPOLLIN;