[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH] test: Add unary operator -E: test that a file is an empty direct
From: |
maandree |
Subject: |
[PATCH] test: Add unary operator -E: test that a file is an empty directory |
Date: |
Wed, 6 Apr 2016 19:09:32 +0200 |
From: Mattias Andrée <address@hidden>
---
doc/coreutils.texi | 7 ++++++-
src/test.c | 44 +++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 49 insertions(+), 2 deletions(-)
diff --git a/doc/coreutils.texi b/doc/coreutils.texi
index 45706bd..e399986 100644
--- a/doc/coreutils.texi
+++ b/doc/coreutils.texi
@@ -12420,7 +12420,7 @@ Exit status:
@end display
@menu
-* File type tests:: -[bcdfhLpSt]
+* File type tests:: -[bcEdfhLpSt]
* Access permission tests:: -[gkruwxOG]
* File characteristic tests:: -e -s -nt -ot -ef
* String tests:: -z -n = == !=
@@ -12449,6 +12449,11 @@ True if @var{file} exists and is a block special
device.
@cindex character special check
True if @var{file} exists and is a character special device.
+@item -E @var{file}
+@opindex -E
+@cindex empty directory check
+True if @var{file} exists, is a directory, and is empty.
+
@item -d @var{file}
@opindex -d
@cindex directory check
diff --git a/src/test.c b/src/test.c
index 8ac7467..eb9c43a 100644
--- a/src/test.c
+++ b/src/test.c
@@ -27,6 +27,7 @@
#endif
#include <config.h>
+#include <dirent.h>
#include <stdio.h>
#include <sys/types.h>
@@ -179,6 +180,39 @@ get_mtime (char const *filename, struct timespec *mtime)
return ok;
}
+/* Return true iff DIR is empty. DIR must be a directory. */
+static bool
+empty_p (char const *dirname)
+{
+ DIR *dir;
+ struct dirent *de;
+
+ dir = opendir (dirname);
+ if (!dir)
+ {
+ error (0, errno, "%s", dirname);
+ test_exit (TEST_FAILURE);
+ }
+
+ while (errno = 0, (de = readdir (dir)))
+ {
+ if (de->d_name[0] == '.')
+ if (de->d_name[1 + (de->d_name[1] == '.')] == '\0')
+ continue;
+ closedir (dir);
+ return 0;
+ }
+
+ if (errno)
+ {
+ error (0, errno, "%s", dirname);
+ closedir (dir);
+ test_exit (TEST_FAILURE);
+ }
+ closedir (dir);
+ return 1;
+}
+
/* Return true if S is one of the test command's binary operators. */
static bool
binop (char const *s)
@@ -457,6 +491,12 @@ unary_operator (void)
return (stat (argv[pos - 1], &stat_buf) == 0
&& S_ISDIR (stat_buf.st_mode));
+ case 'E': /* File is an empty directory? */
+ unary_advance ();
+ return (stat (argv[pos - 1], &stat_buf) == 0
+ && S_ISDIR (stat_buf.st_mode)
+ && empty_p (argv[pos - 1]));
+
case 's': /* File has something in it? */
unary_advance ();
return (stat (argv[pos - 1], &stat_buf) == 0
@@ -590,7 +630,8 @@ test_unop (char const *op)
case 'f': case 'g': case 'h': case 'k': case 'n':
case 'o': case 'p': case 'r': case 's': case 't':
case 'u': case 'w': case 'x': case 'z':
- case 'G': case 'L': case 'O': case 'S': case 'N':
+ case 'E': case 'G': case 'L': case 'O': case 'S':
+ case 'N':
return true;
default:
return false;
@@ -760,6 +801,7 @@ EXPRESSION is true or false and sets exit status. It is
one of:\n\
-c FILE FILE exists and is character special\n\
-d FILE FILE exists and is a directory\n\
-e FILE FILE exists\n\
+ -E FILE FILE exists and is an empty directory\n\
"), stdout);
fputs (_("\
-f FILE FILE exists and is a regular file\n\
--
2.8.0