coreutils
[Top][All Lists]
Advanced

[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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]