summaryrefslogtreecommitdiffstats
path: root/usr.bin/find
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>2001-01-23 11:16:50 +0000
committerpeter <peter@FreeBSD.org>2001-01-23 11:16:50 +0000
commit7eafba69d54138a0429c71ddd6080ad718f3527c (patch)
tree9fd9977704c86e786a10c71f41130e4113c603ba /usr.bin/find
parent3bdade41c9a9713ee00256d16b86b65b74fc8f7e (diff)
downloadFreeBSD-src-7eafba69d54138a0429c71ddd6080ad718f3527c.zip
FreeBSD-src-7eafba69d54138a0429c71ddd6080ad718f3527c.tar.gz
Add the -empty flag, from OpenBSD. It returns true if the directory
is empty. There doesn't appear to be another easy way to do this. mobile# mkdir foo mobile# mkdir foo/bar mobile# mkdir bar mobile# find . -empty ./foo/bar ./bar
Diffstat (limited to 'usr.bin/find')
-rw-r--r--usr.bin/find/extern.h1
-rw-r--r--usr.bin/find/find.12
-rw-r--r--usr.bin/find/find.h4
-rw-r--r--usr.bin/find/function.c43
-rw-r--r--usr.bin/find/option.c1
5 files changed, 49 insertions, 2 deletions
diff --git a/usr.bin/find/extern.h b/usr.bin/find/extern.h
index 16832d4..00c8db2 100644
--- a/usr.bin/find/extern.h
+++ b/usr.bin/find/extern.h
@@ -54,6 +54,7 @@ PLAN *c_cmin __P((char *));
PLAN *c_ctime __P((char *));
PLAN *c_delete __P((void));
PLAN *c_depth __P((void));
+PLAN *c_empty __P((void));
PLAN *c_exec __P((char ***, int));
PLAN *c_flags __P((char *));
PLAN *c_execdir __P((char ***));
diff --git a/usr.bin/find/find.1 b/usr.bin/find/find.1
index 44338fa..78ddcf5 100644
--- a/usr.bin/find/find.1
+++ b/usr.bin/find/find.1
@@ -181,6 +181,8 @@ recurses down the tree.
It will not attempt to delete a filename with a ``/''
character in its pathname relative to "." for security reasons.
Depth\-first traversal processing is implied by this option.
+.It Ic -empty
+True if the current file or directory is empty.
.It Ic -exec Ar utility Op argument ... ;
True if the program named
.Ar utility
diff --git a/usr.bin/find/find.h b/usr.bin/find/find.h
index 35aadac..e126086 100644
--- a/usr.bin/find/find.h
+++ b/usr.bin/find/find.h
@@ -41,9 +41,9 @@
enum ntype {
N_AND = 1, /* must start > 0 */
N_AMIN, N_ATIME, N_CLOSEPAREN, N_CMIN, N_CTIME, N_DEPTH,
- N_EXEC, N_EXECDIR, N_EXPR, N_FLAGS,
+ N_EMPTY, N_EXEC, N_EXECDIR, N_EXPR, N_FLAGS,
N_FOLLOW, N_FSTYPE, N_GROUP, N_INUM, N_LINKS, N_LS, N_MMIN,
- N_MTIME, N_NAME,
+ N_MTIME, N_NAME,
N_NEWER, N_NOGROUP, N_NOT, N_NOUSER, N_OK, N_OPENPAREN, N_OR, N_PATH,
N_PERM, N_PRINT, N_PRUNE, N_SIZE, N_TYPE, N_USER, N_XDEV,
N_PRINT0, N_DELETE, N_MAXDEPTH, N_MINDEPTH
diff --git a/usr.bin/find/function.c b/usr.bin/find/function.c
index 670d102..18cd83c 100644
--- a/usr.bin/find/function.c
+++ b/usr.bin/find/function.c
@@ -49,6 +49,7 @@ static const char rcsid[] =
#include <sys/wait.h>
#include <sys/mount.h>
+#include <dirent.h>
#include <err.h>
#include <errno.h>
#include <fnmatch.h>
@@ -385,6 +386,48 @@ c_exec(argvp, isok)
}
/*
+ * -empty functions --
+ *
+ * True if the file or directory is empty
+ */
+int
+f_empty(plan, entry)
+ PLAN *plan;
+ FTSENT *entry;
+{
+ if (S_ISREG(entry->fts_statp->st_mode) && entry->fts_statp->st_size == 0)
+ return (1);
+ if (S_ISDIR(entry->fts_statp->st_mode)) {
+ struct dirent *dp;
+ int empty;
+ DIR *dir;
+
+ empty = 1;
+ dir = opendir(entry->fts_accpath);
+ if (dir == NULL)
+ err(1, "%s", entry->fts_accpath);
+ for (dp = readdir(dir); dp; dp = readdir(dir))
+ if (dp->d_name[0] != '.' ||
+ (dp->d_name[1] != '\0' &&
+ (dp->d_name[1] != '.' || dp->d_name[2] != '\0'))) {
+ empty = 0;
+ break;
+ }
+ closedir(dir);
+ return (empty);
+ }
+ return (0);
+}
+
+PLAN *
+c_empty()
+{
+ ftsoptions &= ~FTS_NOSTAT;
+
+ return (palloc(N_EMPTY, f_empty));
+}
+
+/*
* -execdir utility [arg ... ] ; functions --
*
* True if the executed utility returns a zero value as exit status.
diff --git a/usr.bin/find/option.c b/usr.bin/find/option.c
index 6ae15d3..3bb6226 100644
--- a/usr.bin/find/option.c
+++ b/usr.bin/find/option.c
@@ -68,6 +68,7 @@ static OPTION const options[] = {
{ "-ctime", N_CTIME, c_ctime, O_ARGV },
{ "-delete", N_DELETE, c_delete, O_ZERO },
{ "-depth", N_DEPTH, c_depth, O_ZERO },
+ { "-empty", N_EMPTY, c_empty, O_ZERO },
{ "-exec", N_EXEC, c_exec, O_ARGVP },
{ "-execdir", N_EXECDIR, c_execdir, O_ARGVP },
{ "-flags", N_FLAGS, c_flags, O_ARGV },
OpenPOWER on IntegriCloud