qemu
1/*
2* systemd socket activation support
3*
4* Copyright 2017 Red Hat, Inc. and/or its affiliates
5*
6* Authors:
7* Richard W.M. Jones <rjones@redhat.com>
8*
9* This work is licensed under the terms of the GNU GPL, version 2 or later.
10* See the COPYING file in the top-level directory.
11*/
12
13#include "qemu/osdep.h"14#include "qemu/systemd.h"15#include "qemu/cutils.h"16#include "qemu/error-report.h"17
18#ifndef _WIN3219unsigned int check_socket_activation(void)20{
21const char *s;22unsigned long pid;23unsigned long nr_fds;24unsigned int i;25int fd;26int f;27int err;28
29s = getenv("LISTEN_PID");30if (s == NULL) {31return 0;32}33err = qemu_strtoul(s, NULL, 10, &pid);34if (err) {35return 0;36}37if (pid != getpid()) {38return 0;39}40
41s = getenv("LISTEN_FDS");42if (s == NULL) {43return 0;44}45err = qemu_strtoul(s, NULL, 10, &nr_fds);46if (err) {47return 0;48}49assert(nr_fds <= UINT_MAX);50
51/* So these are not passed to any child processes we might start. */52unsetenv("LISTEN_FDS");53unsetenv("LISTEN_PID");54unsetenv("LISTEN_FDNAMES");55
56/* So the file descriptors don't leak into child processes. */57for (i = 0; i < nr_fds; ++i) {58fd = FIRST_SOCKET_ACTIVATION_FD + i;59f = fcntl(fd, F_GETFD);60if (f == -1 || fcntl(fd, F_SETFD, f | FD_CLOEXEC) == -1) {61/* If we cannot set FD_CLOEXEC then it probably means the file62* descriptor is invalid, so socket activation has gone wrong
63* and we should exit.
64*/
65error_report("Socket activation failed: "66"invalid file descriptor fd = %d: %s",67fd, g_strerror(errno));68exit(EXIT_FAILURE);69}70}71
72return (unsigned int) nr_fds;73}
74
75#else /* !_WIN32 */76unsigned int check_socket_activation(void)77{
78return 0;79}
80#endif81