X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fsd-daemon.c;h=a2ec74cceb59a744f9bec7486972832896cdb2ff;hb=b8590c197deceab623d37dbb95e30eec9cf47d14;hp=ec436bf724458ae359be9648dd1d1a4bd5abef08;hpb=b136daf5ca9d1c446a3e36a1019940496f522b98;p=elogind.git diff --git a/src/sd-daemon.c b/src/sd-daemon.c index ec436bf72..a2ec74cce 100644 --- a/src/sd-daemon.c +++ b/src/sd-daemon.c @@ -169,7 +169,43 @@ _sd_hidden_ int sd_is_fifo(int fd, const char *path) { return 1; } -_sd_hidden_ static int sd_is_socket_internal(int fd, int type, int listening) { +_sd_hidden_ int sd_is_special(int fd, const char *path) { + struct stat st_fd; + + if (fd < 0) + return -EINVAL; + + if (fstat(fd, &st_fd) < 0) + return -errno; + + if (!S_ISREG(st_fd.st_mode) && !S_ISCHR(st_fd.st_mode)) + return 0; + + if (path) { + struct stat st_path; + + if (stat(path, &st_path) < 0) { + + if (errno == ENOENT || errno == ENOTDIR) + return 0; + + return -errno; + } + + if (S_ISREG(st_fd.st_mode) && S_ISREG(st_path.st_mode)) + return + st_path.st_dev == st_fd.st_dev && + st_path.st_ino == st_fd.st_ino; + else if (S_ISCHR(st_fd.st_mode) && S_ISCHR(st_path.st_mode)) + return st_path.st_rdev == st_fd.st_rdev; + else + return 0; + } + + return 1; +} + +static int sd_is_socket_internal(int fd, int type, int listening) { struct stat st_fd; if (fd < 0 || type < 0)