X-Git-Url: https://git.sur5r.net/?p=i3%2Fi3;a=blobdiff_plain;f=src%2Fsd-daemon.c;h=dc33b2e9a5e38e8841708724977f99a2c319dfe3;hp=6d1eebff07c68a977abc325a3c9c3592839a24ee;hb=HEAD;hpb=a4804a53b8ecf5e5f7d6ee9266cd8d9501e090df diff --git a/src/sd-daemon.c b/src/sd-daemon.c index 6d1eebff..dc33b2e9 100644 --- a/src/sd-daemon.c +++ b/src/sd-daemon.c @@ -45,392 +45,383 @@ #include "sd-daemon.h" int sd_listen_fds(int unset_environment) { - -#if defined(DISABLE_SYSTEMD) || !defined(__linux__) - return 0; -#else - int r, fd; - const char *e; - char *p = NULL; - unsigned long l; - - if (!(e = getenv("LISTEN_PID"))) { - r = 0; - goto finish; - } - - errno = 0; - l = strtoul(e, &p, 10); - - if (errno != 0) { - r = -errno; - goto finish; - } - - if (!p || *p || l <= 0) { - r = -EINVAL; - goto finish; - } - - /* Is this for us? */ - if (getpid() != (pid_t) l) { - r = 0; - goto finish; + int r, fd; + const char *e; + char *p = NULL; + unsigned long l; + + if (!(e = getenv("LISTEN_PID"))) { + r = 0; + goto finish; + } + + errno = 0; + l = strtoul(e, &p, 10); + + if (errno != 0) { + r = -errno; + goto finish; + } + + if (!p || *p || l <= 0) { + r = -EINVAL; + goto finish; + } + + /* Is this for us? */ + if (getpid() != (pid_t)l) { + r = 0; + goto finish; + } + + if (!(e = getenv("LISTEN_FDS"))) { + r = 0; + goto finish; + } + + errno = 0; + l = strtoul(e, &p, 10); + + if (errno != 0) { + r = -errno; + goto finish; + } + + if (!p || *p) { + r = -EINVAL; + goto finish; + } + + for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + (int)l; fd++) { + int flags; + + if ((flags = fcntl(fd, F_GETFD)) < 0) { + r = -errno; + goto finish; } - if (!(e = getenv("LISTEN_FDS"))) { - r = 0; - goto finish; - } - - errno = 0; - l = strtoul(e, &p, 10); - - if (errno != 0) { - r = -errno; - goto finish; - } + if (flags & FD_CLOEXEC) + continue; - if (!p || *p) { - r = -EINVAL; - goto finish; + if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) < 0) { + r = -errno; + goto finish; } + } - for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + (int) l; fd ++) { - int flags; - - if ((flags = fcntl(fd, F_GETFD)) < 0) { - r = -errno; - goto finish; - } - - if (flags & FD_CLOEXEC) - continue; - - if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) < 0) { - r = -errno; - goto finish; - } - } - - r = (int) l; + r = (int)l; finish: - if (unset_environment) { - unsetenv("LISTEN_PID"); - unsetenv("LISTEN_FDS"); - } + if (unset_environment) { + unsetenv("LISTEN_PID"); + unsetenv("LISTEN_FDS"); + } - return r; -#endif + return r; } int sd_is_fifo(int fd, const char *path) { - struct stat st_fd; - - if (fd < 0) - return -EINVAL; + struct stat st_fd; - memset(&st_fd, 0, sizeof(st_fd)); - if (fstat(fd, &st_fd) < 0) - return -errno; + if (fd < 0) + return -EINVAL; - if (!S_ISFIFO(st_fd.st_mode)) - return 0; - - if (path) { - struct stat st_path; + memset(&st_fd, 0, sizeof(st_fd)); + if (fstat(fd, &st_fd) < 0) + return -errno; - memset(&st_path, 0, sizeof(st_path)); - if (stat(path, &st_path) < 0) { + if (!S_ISFIFO(st_fd.st_mode)) + return 0; - if (errno == ENOENT || errno == ENOTDIR) - return 0; + if (path) { + struct stat st_path; - return -errno; - } + memset(&st_path, 0, sizeof(st_path)); + if (stat(path, &st_path) < 0) { + if (errno == ENOENT || errno == ENOTDIR) + return 0; - return - st_path.st_dev == st_fd.st_dev && - st_path.st_ino == st_fd.st_ino; + return -errno; } - return 1; + return st_path.st_dev == st_fd.st_dev && + st_path.st_ino == st_fd.st_ino; + } + + return 1; } static int sd_is_socket_internal(int fd, int type, int listening) { - struct stat st_fd; + struct stat st_fd; - if (fd < 0 || type < 0) - return -EINVAL; + if (fd < 0 || type < 0) + return -EINVAL; - if (fstat(fd, &st_fd) < 0) - return -errno; + if (fstat(fd, &st_fd) < 0) + return -errno; - if (!S_ISSOCK(st_fd.st_mode)) - return 0; + if (!S_ISSOCK(st_fd.st_mode)) + return 0; - if (type != 0) { - int other_type = 0; - socklen_t l = sizeof(other_type); + if (type != 0) { + int other_type = 0; + socklen_t l = sizeof(other_type); - if (getsockopt(fd, SOL_SOCKET, SO_TYPE, &other_type, &l) < 0) - return -errno; + if (getsockopt(fd, SOL_SOCKET, SO_TYPE, &other_type, &l) < 0) + return -errno; - if (l != sizeof(other_type)) - return -EINVAL; + if (l != sizeof(other_type)) + return -EINVAL; - if (other_type != type) - return 0; - } + if (other_type != type) + return 0; + } - if (listening >= 0) { - int accepting = 0; - socklen_t l = sizeof(accepting); + if (listening >= 0) { + int accepting = 0; + socklen_t l = sizeof(accepting); - if (getsockopt(fd, SOL_SOCKET, SO_ACCEPTCONN, &accepting, &l) < 0) - return -errno; + if (getsockopt(fd, SOL_SOCKET, SO_ACCEPTCONN, &accepting, &l) < 0) + return -errno; - if (l != sizeof(accepting)) - return -EINVAL; + if (l != sizeof(accepting)) + return -EINVAL; - if (!accepting != !listening) - return 0; - } + if (!accepting != !listening) + return 0; + } - return 1; + return 1; } union sockaddr_union { - struct sockaddr sa; - struct sockaddr_in in4; - struct sockaddr_in6 in6; - struct sockaddr_un un; - struct sockaddr_storage storage; + struct sockaddr sa; + struct sockaddr_in in4; + struct sockaddr_in6 in6; + struct sockaddr_un un; + struct sockaddr_storage storage; }; int sd_is_socket(int fd, int family, int type, int listening) { - int r; + int r; - if (family < 0) - return -EINVAL; + if (family < 0) + return -EINVAL; - if ((r = sd_is_socket_internal(fd, type, listening)) <= 0) - return r; + if ((r = sd_is_socket_internal(fd, type, listening)) <= 0) + return r; - if (family > 0) { - union sockaddr_union sockaddr; - socklen_t l; + if (family > 0) { + union sockaddr_union sockaddr; + socklen_t l; - memset(&sockaddr, 0, sizeof(sockaddr)); - l = sizeof(sockaddr); + memset(&sockaddr, 0, sizeof(sockaddr)); + l = sizeof(sockaddr); - if (getsockname(fd, &sockaddr.sa, &l) < 0) - return -errno; + if (getsockname(fd, &sockaddr.sa, &l) < 0) + return -errno; - if (l < sizeof(sa_family_t)) - return -EINVAL; + if (l < sizeof(sa_family_t)) + return -EINVAL; - return sockaddr.sa.sa_family == family; - } + return sockaddr.sa.sa_family == family; + } - return 1; + return 1; } int sd_is_socket_inet(int fd, int family, int type, int listening, uint16_t port) { - union sockaddr_union sockaddr; - socklen_t l; - int r; + union sockaddr_union sockaddr; + socklen_t l; + int r; - if (family != 0 && family != AF_INET && family != AF_INET6) - return -EINVAL; + if (family != 0 && family != AF_INET && family != AF_INET6) + return -EINVAL; - if ((r = sd_is_socket_internal(fd, type, listening)) <= 0) - return r; + if ((r = sd_is_socket_internal(fd, type, listening)) <= 0) + return r; - memset(&sockaddr, 0, sizeof(sockaddr)); - l = sizeof(sockaddr); + memset(&sockaddr, 0, sizeof(sockaddr)); + l = sizeof(sockaddr); - if (getsockname(fd, &sockaddr.sa, &l) < 0) - return -errno; + if (getsockname(fd, &sockaddr.sa, &l) < 0) + return -errno; - if (l < sizeof(sa_family_t)) - return -EINVAL; + if (l < sizeof(sa_family_t)) + return -EINVAL; - if (sockaddr.sa.sa_family != AF_INET && - sockaddr.sa.sa_family != AF_INET6) - return 0; + if (sockaddr.sa.sa_family != AF_INET && + sockaddr.sa.sa_family != AF_INET6) + return 0; - if (family > 0) - if (sockaddr.sa.sa_family != family) - return 0; + if (family > 0) + if (sockaddr.sa.sa_family != family) + return 0; - if (port > 0) { - if (sockaddr.sa.sa_family == AF_INET) { - if (l < sizeof(struct sockaddr_in)) - return -EINVAL; + if (port > 0) { + if (sockaddr.sa.sa_family == AF_INET) { + if (l < sizeof(struct sockaddr_in)) + return -EINVAL; - return htons(port) == sockaddr.in4.sin_port; - } else { - if (l < sizeof(struct sockaddr_in6)) - return -EINVAL; + return htons(port) == sockaddr.in4.sin_port; + } else { + if (l < sizeof(struct sockaddr_in6)) + return -EINVAL; - return htons(port) == sockaddr.in6.sin6_port; - } + return htons(port) == sockaddr.in6.sin6_port; } + } - return 1; + return 1; } int sd_is_socket_unix(int fd, int type, int listening, const char *path, size_t length) { - union sockaddr_union sockaddr; - socklen_t l; - int r; - - if ((r = sd_is_socket_internal(fd, type, listening)) <= 0) - return r; + union sockaddr_union sockaddr; + socklen_t l; + int r; - memset(&sockaddr, 0, sizeof(sockaddr)); - l = sizeof(sockaddr); + if ((r = sd_is_socket_internal(fd, type, listening)) <= 0) + return r; - if (getsockname(fd, &sockaddr.sa, &l) < 0) - return -errno; + memset(&sockaddr, 0, sizeof(sockaddr)); + l = sizeof(sockaddr); - if (l < sizeof(sa_family_t)) - return -EINVAL; + if (getsockname(fd, &sockaddr.sa, &l) < 0) + return -errno; - if (sockaddr.sa.sa_family != AF_UNIX) - return 0; + if (l < sizeof(sa_family_t)) + return -EINVAL; - if (path) { - if (length <= 0) - length = strlen(path); - - if (length <= 0) - /* Unnamed socket */ - return l == offsetof(struct sockaddr_un, sun_path); - - if (path[0]) - /* Normal path socket */ - return - (l >= offsetof(struct sockaddr_un, sun_path) + length + 1) && - memcmp(path, sockaddr.un.sun_path, length+1) == 0; - else - /* Abstract namespace socket */ - return - (l == offsetof(struct sockaddr_un, sun_path) + length) && - memcmp(path, sockaddr.un.sun_path, length) == 0; - } + if (sockaddr.sa.sa_family != AF_UNIX) + return 0; - return 1; + if (path) { + if (length <= 0) + length = strlen(path); + + if (length <= 0) + /* Unnamed socket */ + return l == offsetof(struct sockaddr_un, sun_path); + + if (path[0]) + /* Normal path socket */ + return (l >= offsetof(struct sockaddr_un, sun_path) + length + 1) && + memcmp(path, sockaddr.un.sun_path, length + 1) == 0; + else + /* Abstract namespace socket */ + return (l == offsetof(struct sockaddr_un, sun_path) + length) && + memcmp(path, sockaddr.un.sun_path, length) == 0; + } + + return 1; } int sd_notify(int unset_environment, const char *state) { #if defined(DISABLE_SYSTEMD) || !defined(__linux__) || !defined(SOCK_CLOEXEC) - return 0; + return 0; #else - int fd = -1, r; - struct msghdr msghdr; - struct iovec iovec; - union sockaddr_union sockaddr; - const char *e; - - if (!state) { - r = -EINVAL; - goto finish; - } - - if (!(e = getenv("NOTIFY_SOCKET"))) - return 0; + int fd = -1, r; + struct msghdr msghdr; + struct iovec iovec; + union sockaddr_union sockaddr; + const char *e; + + if (!state) { + r = -EINVAL; + goto finish; + } + + if (!(e = getenv("NOTIFY_SOCKET"))) + return 0; - /* Must be an abstract socket, or an absolute path */ - if ((e[0] != '@' && e[0] != '/') || e[1] == 0) { - r = -EINVAL; - goto finish; - } + /* Must be an abstract socket, or an absolute path */ + if ((e[0] != '@' && e[0] != '/') || e[1] == 0) { + r = -EINVAL; + goto finish; + } - if ((fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0)) < 0) { - r = -errno; - goto finish; - } + if ((fd = socket(AF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0)) < 0) { + r = -errno; + goto finish; + } - memset(&sockaddr, 0, sizeof(sockaddr)); - sockaddr.sa.sa_family = AF_UNIX; - strncpy(sockaddr.un.sun_path, e, sizeof(sockaddr.un.sun_path)); + memset(&sockaddr, 0, sizeof(sockaddr)); + sockaddr.sa.sa_family = AF_UNIX; + strncpy(sockaddr.un.sun_path, e, sizeof(sockaddr.un.sun_path)); - if (sockaddr.un.sun_path[0] == '@') - sockaddr.un.sun_path[0] = 0; + if (sockaddr.un.sun_path[0] == '@') + sockaddr.un.sun_path[0] = 0; - memset(&iovec, 0, sizeof(iovec)); - iovec.iov_base = (char*) state; - iovec.iov_len = strlen(state); + memset(&iovec, 0, sizeof(iovec)); + iovec.iov_base = (char *)state; + iovec.iov_len = strlen(state); - memset(&msghdr, 0, sizeof(msghdr)); - msghdr.msg_name = &sockaddr; - msghdr.msg_namelen = offsetof(struct sockaddr_un, sun_path) + strlen(e); + memset(&msghdr, 0, sizeof(msghdr)); + msghdr.msg_name = &sockaddr; + msghdr.msg_namelen = offsetof(struct sockaddr_un, sun_path) + strlen(e); - if (msghdr.msg_namelen > sizeof(struct sockaddr_un)) - msghdr.msg_namelen = sizeof(struct sockaddr_un); + if (msghdr.msg_namelen > sizeof(struct sockaddr_un)) + msghdr.msg_namelen = sizeof(struct sockaddr_un); - msghdr.msg_iov = &iovec; - msghdr.msg_iovlen = 1; + msghdr.msg_iov = &iovec; + msghdr.msg_iovlen = 1; - if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0) { - r = -errno; - goto finish; - } + if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0) { + r = -errno; + goto finish; + } - r = 1; + r = 1; finish: - if (unset_environment) - unsetenv("NOTIFY_SOCKET"); + if (unset_environment) + unsetenv("NOTIFY_SOCKET"); - if (fd >= 0) - close(fd); + if (fd >= 0) + close(fd); - return r; + return r; #endif } int sd_notifyf(int unset_environment, const char *format, ...) { #if defined(DISABLE_SYSTEMD) || !defined(__linux__) - return 0; + return 0; #else - va_list ap; - char *p = NULL; - int r; + va_list ap; + char *p = NULL; + int r; - va_start(ap, format); - r = vasprintf(&p, format, ap); - va_end(ap); + va_start(ap, format); + r = vasprintf(&p, format, ap); + va_end(ap); - if (r < 0 || !p) - return -ENOMEM; + if (r < 0 || !p) + return -ENOMEM; - r = sd_notify(unset_environment, p); - free(p); + r = sd_notify(unset_environment, p); + free(p); - return r; + return r; #endif } int sd_booted(void) { #if defined(DISABLE_SYSTEMD) || !defined(__linux__) - return 0; + return 0; #else - struct stat a, b; + struct stat a, b; - /* We simply test whether the systemd cgroup hierarchy is + /* We simply test whether the systemd cgroup hierarchy is * mounted */ - if (lstat("/sys/fs/cgroup", &a) < 0) - return 0; + if (lstat("/sys/fs/cgroup", &a) < 0) + return 0; - if (lstat("/sys/fs/cgroup/systemd", &b) < 0) - return 0; + if (lstat("/sys/fs/cgroup/systemd", &b) < 0) + return 0; - return a.st_dev != b.st_dev; + return a.st_dev != b.st_dev; #endif }