1/* $OpenBSD$ */
2
3/*
4 * Copyright (c) 2022 Nicholas Marriott <nicholas.marriott@gmail.com>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
15 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19#include <sys/types.h>
20#include <sys/un.h>
21
22#include <systemd/sd-daemon.h>
23
24#include "tmux.h"
25
26int
27systemd_create_socket(int flags, char **cause)
28{
29	int			fds;
30	int			fd;
31	struct sockaddr_un	sa;
32	int			addrlen = sizeof sa;
33
34	fds = sd_listen_fds(0);
35	if (fds > 1) { /* too many file descriptors */
36		errno = E2BIG;
37		goto fail;
38	}
39
40	if (fds == 1) { /* socket-activated */
41		fd = SD_LISTEN_FDS_START;
42		if (!sd_is_socket_unix(fd, SOCK_STREAM, 1, NULL, 0)) {
43			errno = EPFNOSUPPORT;
44			goto fail;
45		}
46		if (getsockname(fd, (struct sockaddr *)&sa, &addrlen) == -1)
47			goto fail;
48		socket_path = xstrdup(sa.sun_path);
49		return (fd);
50	}
51
52	return (server_create_socket(flags, cause));
53
54fail:
55	if (cause != NULL)
56		xasprintf(cause, "systemd socket error (%s)", strerror(errno));
57	return (-1);
58}
59