Lennart Poettering <lenn...@poettering.net> writes: > On Wed, 15.06.11 11:25, William Douglas (william.r.doug...@gmail.com) wrote: > >> >From 85f51557a62be9224ed475047aff503bece342b4 Mon Sep 17 00:00:00 2001 >> From: William Douglas <william.doug...@intel.com> >> Date: Wed, 15 Jun 2011 11:08:17 -0700 >> >> With the addition of ListenSpecial as a socket option we need the >> the usual sd_is_ functions for special files. This patch does >> that. > > ListenSpecial= in systemd is designed so that we can use it to do > socket-style activation both on files in /proc that have "special" > behaviour (and are 'regular' files), i.e. /proc/kmsg, as well as device > nodes in /dev. For example, people could use this to listen on > /dev/input/event0 and activate a service whenever somebody presses a key > or so. > > sd_is_special() hence should be able to check for both kinds of files, > too. That means, S_ISCHR needs to be accepted as well as S_ISREG, and in > the former case we should compare st_rdev, and only in the latter > st_dev+st_ino. > > Otherwise looks fine. > > Lennart
Ah right, I was only thinking of getting /proc/kmsg working =P. I have updated accordingly below. >From 0f18a84ed77b9cb84d5c43281551c2d2898b2874 Mon Sep 17 00:00:00 2001 From: William Douglas <william.doug...@intel.com> Date: Wed, 15 Jun 2011 11:08:17 -0700 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 | 34 ++++++++++++++++++++++++++++++++++ src/sd-daemon.h | 12 ++++++++++++ 2 files changed, 46 insertions(+), 0 deletions(-) diff --git a/src/sd-daemon.c b/src/sd-daemon.c index d9f23d6..c73a714 100644 --- a/src/sd-daemon.c +++ b/src/sd-daemon.c @@ -169,6 +169,40 @@ _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)) + 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; + } + + 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