From 43eed091129212dd29996838cf1d76af0f8fc135 Mon Sep 17 00:00:00 2001 From: Richard Jones Date: Thu, 9 Sep 2010 22:43:32 +0100 Subject: [PATCH] New APIs: is-chardev, is-blockdev, is-fifo, is-symlink, is-socket These complement the existing is-file and is-dir APIs. --- daemon/is.c | 78 ++++++++++++++++++++++++++++++++++++++++++++------------ src/MAX_PROC_NR | 2 +- src/generator.ml | 62 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 124 insertions(+), 18 deletions(-) diff --git a/daemon/is.c b/daemon/is.c index a16596b..4a834f4 100644 --- a/daemon/is.c +++ b/daemon/is.c @@ -41,30 +41,73 @@ do_exists (const char *path) return r == 0; } +static int get_mode (const char *path, mode_t *mode); + int do_is_file (const char *path) { - int r; - struct stat buf; + mode_t mode; + int r = get_mode (path, &mode); + if (r <= 0) return r; + return S_ISREG (mode); +} - CHROOT_IN; - r = lstat (path, &buf); - CHROOT_OUT; +int +do_is_dir (const char *path) +{ + mode_t mode; + int r = get_mode (path, &mode); + if (r <= 0) return r; + return S_ISDIR (mode); +} - if (r == -1) { - if (errno != ENOENT && errno != ENOTDIR) { - reply_with_perror ("stat: %s", path); - return -1; - } - else - return 0; /* Not a file. */ - } +int +do_is_chardev (const char *path) +{ + mode_t mode; + int r = get_mode (path, &mode); + if (r <= 0) return r; + return S_ISCHR (mode); +} - return S_ISREG (buf.st_mode); +int +do_is_blockdev (const char *path) +{ + mode_t mode; + int r = get_mode (path, &mode); + if (r <= 0) return r; + return S_ISBLK (mode); } int -do_is_dir (const char *path) +do_is_fifo (const char *path) +{ + mode_t mode; + int r = get_mode (path, &mode); + if (r <= 0) return r; + return S_ISFIFO (mode); +} + +int +do_is_symlink (const char *path) +{ + mode_t mode; + int r = get_mode (path, &mode); + if (r <= 0) return r; + return S_ISLNK (mode); +} + +int +do_is_socket (const char *path) +{ + mode_t mode; + int r = get_mode (path, &mode); + if (r <= 0) return r; + return S_ISSOCK (mode); +} + +static int +get_mode (const char *path, mode_t *mode) { int r; struct stat buf; @@ -79,8 +122,9 @@ do_is_dir (const char *path) return -1; } else - return 0; /* Not a directory. */ + return 0; /* Doesn't exist, means return false. */ } - return S_ISDIR (buf.st_mode); + *mode = buf.st_mode; + return 1; } diff --git a/src/MAX_PROC_NR b/src/MAX_PROC_NR index c1d1ffb..e6a4f00 100644 --- a/src/MAX_PROC_NR +++ b/src/MAX_PROC_NR @@ -1 +1 @@ -266 +271 diff --git a/src/generator.ml b/src/generator.ml index e2b96c8..da01f12 100755 --- a/src/generator.ml +++ b/src/generator.ml @@ -5356,6 +5356,68 @@ filesystem can be found. To find the label of a filesystem, use C."); + ("is_chardev", (RBool "flag", [Pathname "path"]), 267, [], + [InitISOFS, Always, TestOutputFalse ( + [["is_chardev"; "/directory"]]); + InitBasicFS, Always, TestOutputTrue ( + [["mknod_c"; "0o777"; "99"; "66"; "/test"]; + ["is_chardev"; "/test"]])], + "test if character device", + "\ +This returns C if and only if there is a character device +with the given C name. + +See also C."); + + ("is_blockdev", (RBool "flag", [Pathname "path"]), 268, [], + [InitISOFS, Always, TestOutputFalse ( + [["is_blockdev"; "/directory"]]); + InitBasicFS, Always, TestOutputTrue ( + [["mknod_b"; "0o777"; "99"; "66"; "/test"]; + ["is_blockdev"; "/test"]])], + "test if block device", + "\ +This returns C if and only if there is a block device +with the given C name. + +See also C."); + + ("is_fifo", (RBool "flag", [Pathname "path"]), 269, [], + [InitISOFS, Always, TestOutputFalse ( + [["is_fifo"; "/directory"]]); + InitBasicFS, Always, TestOutputTrue ( + [["mkfifo"; "0o777"; "/test"]; + ["is_fifo"; "/test"]])], + "test if FIFO (named pipe)", + "\ +This returns C if and only if there is a FIFO (named pipe) +with the given C name. + +See also C."); + + ("is_symlink", (RBool "flag", [Pathname "path"]), 270, [], + [InitISOFS, Always, TestOutputFalse ( + [["is_symlink"; "/directory"]]); + InitISOFS, Always, TestOutputTrue ( + [["is_symlink"; "/abssymlink"]])], + "test if symbolic link", + "\ +This returns C if and only if there is a symbolic link +with the given C name. + +See also C."); + + ("is_socket", (RBool "flag", [Pathname "path"]), 271, [], + (* XXX Need a positive test for sockets. *) + [InitISOFS, Always, TestOutputFalse ( + [["is_socket"; "/directory"]])], + "test if socket", + "\ +This returns C if and only if there is a Unix domain socket +with the given C name. + +See also C."); + ] let all_functions = non_daemon_functions @ daemon_functions -- 1.8.3.1