Lennart Poettering <lenn...@poettering.net> writes:

> On Wed, 15.06.11 13:20, William Douglas (william.r.doug...@gmail.com) wrote:
>
>> Ah right, I was only thinking of getting /proc/kmsg working =P.
>> I have updated accordingly below.
>
> Almost there now:
>
>> +_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))
>> +                        return
>> +                                st_path.st_dev == st_fd.st_dev &&
>> +                                st_path.st_ino == st_fd.st_ino;
>> +                else
>> +                        return st_path.st_rdev == st_fd.st_rdev;
>
> if st_path refers to a normal file, but st_fd to a device node, then
> you are accessing st_path.st_rdev which might not be initialized. Since
> st_rdev is specific to device nodes you need to verify the type of
> st_path, too.
>
> Lennart

Awww I suck.

So I just went ahead and verified that st_fd and st_path
are the same type before doing the return comparison and if they aren't
the same type return false.

>From a6fcc6368af5cdae3ff57373dcf14c4e0e3b5d44 Mon Sep 17 00:00:00 2001
From: William Douglas <william.doug...@intel.com>
Date: Wed, 15 Jun 2011 11:08:17 -0700
Subject: [PATCH] Add sd_is_special for special file descriptors

With the addition of ListenSpecial as a socket option we need the
the usual sd_is_ functions for special files.  This patch does
that.
---
 src/sd-daemon.c |   36 ++++++++++++++++++++++++++++++++++++
 src/sd-daemon.h |   12 ++++++++++++
 2 files changed, 48 insertions(+), 0 deletions(-)

diff --git a/src/sd-daemon.c b/src/sd-daemon.c
index d9f23d6..d39a353 100644
--- a/src/sd-daemon.c
+++ b/src/sd-daemon.c
@@ -169,6 +169,42 @@ _sd_hidden_ int sd_is_fifo(int fd, const char *path) {
         return 1;
 }
 
+_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;
 
diff --git a/src/sd-daemon.h b/src/sd-daemon.h
index 884c361..46dc7fd 100644
--- a/src/sd-daemon.h
+++ b/src/sd-daemon.h
@@ -125,6 +125,18 @@ int sd_is_fifo(int fd, const char *path);
 
 /*
   Helper call for identifying a passed file descriptor. Returns 1 if
+  the file descriptor is a special character device on the file
+  system stored under the specified path, 0 otherwise.
+  If path is NULL a path name check will not be done and the call
+  only verifies if the file descriptor refers to a special character.
+  Returns a negative errno style error code on failure.
+
+  See sd_is_special(3) for more information.
+*/
+int sd_is_special(int fd, const char *path);
+
+/*
+  Helper call for identifying a passed file descriptor. Returns 1 if
   the file descriptor is a socket of the specified family (AF_INET,
   ...) and type (SOCK_DGRAM, SOCK_STREAM, ...), 0 otherwise. If
   family is 0 a socket family check will not be done. If type is 0 a
-- 
1.7.2.3
_______________________________________________
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel

Reply via email to