11b56dabaaa294349d326b90f86e4bef7c22f1d96Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ 2dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 3dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering/*** 4dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering Copyright 2010 Lennart Poettering 5dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 6dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering Permission is hereby granted, free of charge, to any person 7dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering obtaining a copy of this software and associated documentation files 8dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering (the "Software"), to deal in the Software without restriction, 9dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering including without limitation the rights to use, copy, modify, merge, 10dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering publish, distribute, sublicense, and/or sell copies of the Software, 11dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering and to permit persons to whom the Software is furnished to do so, 12dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering subject to the following conditions: 13dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 14dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering The above copyright notice and this permission notice shall be 15dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering included in all copies or substantial portions of the Software. 16dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 17dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 21dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 22dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 23dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering SOFTWARE. 25dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering***/ 26dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 27dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering#ifndef _GNU_SOURCE 28dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering#define _GNU_SOURCE 29dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering#endif 30dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 31dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering#include <sys/types.h> 32dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering#include <sys/stat.h> 33dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering#include <sys/socket.h> 34dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering#include <sys/un.h> 3528c78cdf3df937d1cd72e3c358f7afa129a8cdabJaikumar Ganesh#include <fcntl.h> 36dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering#include <netinet/in.h> 37dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering#include <stdlib.h> 38dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering#include <errno.h> 39dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering#include <unistd.h> 40dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering#include <string.h> 41dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering#include <stdarg.h> 42dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering#include <stdio.h> 43dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 44dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering#include "sd-daemon.h" 45dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 46dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poetteringint sd_listen_fds(int unset_environment) { 47dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 48dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering#if defined(DISABLE_SYSTEMD) || !defined(__linux__) 49dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering return 0; 50dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering#else 51dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering int r, fd; 52dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering const char *e; 53dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering char *p = NULL; 54dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering unsigned long l; 55dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 56dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering if (!(e = getenv("LISTEN_PID"))) { 57dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering r = 0; 58dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering goto finish; 59dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering } 60dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 61dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering errno = 0; 62dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering l = strtoul(e, &p, 10); 63dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 64dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering if (errno != 0) { 65dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering r = -errno; 66dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering goto finish; 67dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering } 68dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 69dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering if (!p || *p || l <= 0) { 70dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering r = -EINVAL; 71dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering goto finish; 72dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering } 73dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 74dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering /* Is this for us? */ 75dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering if (getpid() != (pid_t) l) { 76dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering r = 0; 77dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering goto finish; 78dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering } 79dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 80dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering if (!(e = getenv("LISTEN_FDS"))) { 81dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering r = 0; 82dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering goto finish; 83dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering } 84dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 85dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering errno = 0; 86dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering l = strtoul(e, &p, 10); 87dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 88dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering if (errno != 0) { 89dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering r = -errno; 90dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering goto finish; 91dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering } 92dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 93dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering if (!p || *p) { 94dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering r = -EINVAL; 95dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering goto finish; 96dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering } 97dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 98dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + (int) l; fd ++) { 99dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering int flags; 100dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 101dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering if ((flags = fcntl(fd, F_GETFD)) < 0) { 102dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering r = -errno; 103dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering goto finish; 104dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering } 105dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 106dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering if (flags & FD_CLOEXEC) 107dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering continue; 108dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 109dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) < 0) { 110dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering r = -errno; 111dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering goto finish; 112dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering } 113dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering } 114dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 115dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering r = (int) l; 116dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 117dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poetteringfinish: 118dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering if (unset_environment) { 119dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering unsetenv("LISTEN_PID"); 120dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering unsetenv("LISTEN_FDS"); 121dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering } 122dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 123dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering return r; 124dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering#endif 125dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering} 126dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 127dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poetteringint sd_is_fifo(int fd, const char *path) { 128dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering struct stat st_fd; 129dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 130dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering if (fd < 0) 131dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering return -EINVAL; 132dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 133dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering memset(&st_fd, 0, sizeof(st_fd)); 134dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering if (fstat(fd, &st_fd) < 0) 135dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering return -errno; 136dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 137dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering if (!S_ISFIFO(st_fd.st_mode)) 138dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering return 0; 139dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 140dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering if (path) { 141dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering struct stat st_path; 142dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 143dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering memset(&st_path, 0, sizeof(st_path)); 144dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering if (stat(path, &st_path) < 0) { 145dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 146dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering if (errno == ENOENT || errno == ENOTDIR) 147dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering return 0; 148dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 149dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering return -errno; 150dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering } 151dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 152dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering return 153dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering st_path.st_dev == st_fd.st_dev && 154dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering st_path.st_ino == st_fd.st_ino; 155dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering } 156dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 157dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering return 1; 158dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering} 159dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 160dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poetteringstatic int sd_is_socket_internal(int fd, int type, int listening) { 161dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering struct stat st_fd; 162dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 163dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering if (fd < 0 || type < 0) 164dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering return -EINVAL; 165dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 166dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering if (fstat(fd, &st_fd) < 0) 167dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering return -errno; 168dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 169dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering if (!S_ISSOCK(st_fd.st_mode)) 170dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering return 0; 171dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 172dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering if (type != 0) { 173dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering int other_type = 0; 174dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering socklen_t l = sizeof(other_type); 175dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 176dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering if (getsockopt(fd, SOL_SOCKET, SO_TYPE, &other_type, &l) < 0) 177dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering return -errno; 178dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 179dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering if (l != sizeof(other_type)) 180dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering return -EINVAL; 181dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 182dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering if (other_type != type) 183dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering return 0; 184dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering } 185dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 186dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering if (listening >= 0) { 187dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering int accepting = 0; 188dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering socklen_t l = sizeof(accepting); 189dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 190dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering if (getsockopt(fd, SOL_SOCKET, SO_ACCEPTCONN, &accepting, &l) < 0) 191dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering return -errno; 192dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 193dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering if (l != sizeof(accepting)) 194dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering return -EINVAL; 195dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 196dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering if (!accepting != !listening) 197dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering return 0; 198dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering } 199dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 200dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering return 1; 201dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering} 202dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 203dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poetteringunion sockaddr_union { 204dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering struct sockaddr sa; 205dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering struct sockaddr_in in4; 206dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering struct sockaddr_in6 in6; 207dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering struct sockaddr_un un; 208dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering struct sockaddr_storage storage; 209dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering}; 210dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 211dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poetteringint sd_is_socket(int fd, int family, int type, int listening) { 212dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering int r; 213dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 214dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering if (family < 0) 215dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering return -EINVAL; 216dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 217dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering if ((r = sd_is_socket_internal(fd, type, listening)) <= 0) 218dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering return r; 219dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 220dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering if (family > 0) { 221dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering union sockaddr_union sockaddr; 222dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering socklen_t l; 223dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 224dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering memset(&sockaddr, 0, sizeof(sockaddr)); 225dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering l = sizeof(sockaddr); 226dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 227dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering if (getsockname(fd, &sockaddr.sa, &l) < 0) 228dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering return -errno; 229dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 230dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering if (l < sizeof(sa_family_t)) 231dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering return -EINVAL; 232dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 233dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering return sockaddr.sa.sa_family == family; 234dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering } 235dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 236dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering return 1; 237dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering} 238dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 239dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poetteringint sd_is_socket_inet(int fd, int family, int type, int listening, uint16_t port) { 240dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering union sockaddr_union sockaddr; 241dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering socklen_t l; 242dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering int r; 243dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 244dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering if (family != 0 && family != AF_INET && family != AF_INET6) 245dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering return -EINVAL; 246dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 247dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering if ((r = sd_is_socket_internal(fd, type, listening)) <= 0) 248dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering return r; 249dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 250dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering memset(&sockaddr, 0, sizeof(sockaddr)); 251dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering l = sizeof(sockaddr); 252dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 253dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering if (getsockname(fd, &sockaddr.sa, &l) < 0) 254dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering return -errno; 255dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 256dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering if (l < sizeof(sa_family_t)) 257dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering return -EINVAL; 258dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 259dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering if (sockaddr.sa.sa_family != AF_INET && 260dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering sockaddr.sa.sa_family != AF_INET6) 261dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering return 0; 262dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 263dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering if (family > 0) 264dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering if (sockaddr.sa.sa_family != family) 265dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering return 0; 266dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 267dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering if (port > 0) { 268dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering if (sockaddr.sa.sa_family == AF_INET) { 269dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering if (l < sizeof(struct sockaddr_in)) 270dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering return -EINVAL; 271dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 272dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering return htons(port) == sockaddr.in4.sin_port; 273dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering } else { 274dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering if (l < sizeof(struct sockaddr_in6)) 275dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering return -EINVAL; 276dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 277dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering return htons(port) == sockaddr.in6.sin6_port; 278dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering } 279dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering } 280dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 281dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering return 1; 282dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering} 283dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 284dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poetteringint sd_is_socket_unix(int fd, int type, int listening, const char *path, size_t length) { 285dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering union sockaddr_union sockaddr; 286dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering socklen_t l; 287dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering int r; 288dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 289dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering if ((r = sd_is_socket_internal(fd, type, listening)) <= 0) 290dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering return r; 291dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 292dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering memset(&sockaddr, 0, sizeof(sockaddr)); 293dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering l = sizeof(sockaddr); 294dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 295dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering if (getsockname(fd, &sockaddr.sa, &l) < 0) 296dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering return -errno; 297dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 298dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering if (l < sizeof(sa_family_t)) 299dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering return -EINVAL; 300dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 301dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering if (sockaddr.sa.sa_family != AF_UNIX) 302dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering return 0; 303dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 304dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering if (path) { 305dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering if (length <= 0) 306dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering length = strlen(path); 307dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 308dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering if (length <= 0) 309dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering /* Unnamed socket */ 310dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering return l == sizeof(sa_family_t); 311dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 312dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering if (path[0]) 313dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering /* Normal path socket */ 314dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering return 315dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering (l >= sizeof(sa_family_t) + length + 1) && 316dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering memcmp(path, sockaddr.un.sun_path, length+1) == 0; 317dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering else 318dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering /* Abstract namespace socket */ 319dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering return 320dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering (l == sizeof(sa_family_t) + length) && 321dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering memcmp(path, sockaddr.un.sun_path, length) == 0; 322dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering } 323dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 324dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering return 1; 325dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering} 326dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 327dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poetteringint sd_notify(int unset_environment, const char *state) { 328ff2325c92c411e6718ae38d6976f54580ed57e86Lennart Poettering#if defined(DISABLE_SYSTEMD) || !defined(__linux__) || !defined(SOCK_CLOEXEC) 329dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering return 0; 330dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering#else 331dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering int fd = -1, r; 332dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering struct msghdr msghdr; 333dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering struct iovec iovec; 334dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering union sockaddr_union sockaddr; 335dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering const char *e; 336dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 337dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering if (!state) { 338dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering r = -EINVAL; 339dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering goto finish; 340dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering } 341dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 342dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering if (!(e = getenv("NOTIFY_SOCKET"))) 343dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering return 0; 344dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 345dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering /* Must be an abstract socket, or an absolute path */ 346dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering if ((e[0] != '@' && e[0] != '/') || e[1] == 0) { 347dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering r = -EINVAL; 348dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering goto finish; 349dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering } 350dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 351dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering if ((fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0)) < 0) { 352dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering r = -errno; 353dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering goto finish; 354dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering } 355dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 356dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering memset(&sockaddr, 0, sizeof(sockaddr)); 357dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering sockaddr.sa.sa_family = AF_UNIX; 358dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering strncpy(sockaddr.un.sun_path, e, sizeof(sockaddr.un.sun_path)); 359dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 360dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering if (sockaddr.un.sun_path[0] == '@') 361dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering sockaddr.un.sun_path[0] = 0; 362dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 363dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering memset(&iovec, 0, sizeof(iovec)); 364dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering iovec.iov_base = (char*) state; 365dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering iovec.iov_len = strlen(state); 366dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 367dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering memset(&msghdr, 0, sizeof(msghdr)); 368dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering msghdr.msg_name = &sockaddr; 369265a3bb04a46d889b89ff0a5f6d4c93df092e0fbLennart Poettering msghdr.msg_namelen = sizeof(sa_family_t) + strlen(e); 370265a3bb04a46d889b89ff0a5f6d4c93df092e0fbLennart Poettering 371265a3bb04a46d889b89ff0a5f6d4c93df092e0fbLennart Poettering if (msghdr.msg_namelen > sizeof(struct sockaddr_un)) 372265a3bb04a46d889b89ff0a5f6d4c93df092e0fbLennart Poettering msghdr.msg_namelen = sizeof(struct sockaddr_un); 373265a3bb04a46d889b89ff0a5f6d4c93df092e0fbLennart Poettering 374dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering msghdr.msg_iov = &iovec; 375dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering msghdr.msg_iovlen = 1; 376dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 377dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0) { 378dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering r = -errno; 379dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering goto finish; 380dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering } 381dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 382dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering r = 1; 383dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 384dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poetteringfinish: 385dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering if (unset_environment) 386dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering unsetenv("NOTIFY_SOCKET"); 387dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 388dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering if (fd >= 0) 389dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering close(fd); 390dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 391dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering return r; 392dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering#endif 393dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering} 394dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 395dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poetteringint sd_notifyf(int unset_environment, const char *format, ...) { 396dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering#if defined(DISABLE_SYSTEMD) || !defined(__linux__) 397dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering return 0; 398dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering#else 399dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering va_list ap; 400dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering char *p = NULL; 401dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering int r; 402dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 403dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering va_start(ap, format); 404dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering r = vasprintf(&p, format, ap); 405dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering va_end(ap); 406dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 407dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering if (r < 0 || !p) 408dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering return -ENOMEM; 409dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 410dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering r = sd_notify(unset_environment, p); 411dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering free(p); 412dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 413dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering return r; 414dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering#endif 415dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering} 416dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 417dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poetteringint sd_booted(void) { 418dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering#if defined(DISABLE_SYSTEMD) || !defined(__linux__) 419dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering return 0; 420dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering#else 421dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 422dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering struct stat a, b; 423dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 424dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering /* We simply test whether the systemd cgroup hierarchy is 425dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering * mounted */ 426dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 4271b56dabaaa294349d326b90f86e4bef7c22f1d96Lennart Poettering if (lstat("/sys/fs/cgroup", &a) < 0) 428dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering return 0; 429dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 4301b56dabaaa294349d326b90f86e4bef7c22f1d96Lennart Poettering if (lstat("/sys/fs/cgroup/systemd", &b) < 0) 431dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering return 0; 432dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering 433dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering return a.st_dev != b.st_dev; 434dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering#endif 435dd31130a971593b5e20a1c4cb04f93c2aae90c84Lennart Poettering} 436