diff options
author | Peter Wemm <peter@FreeBSD.org> | 2001-01-23 11:16:50 +0000 |
---|---|---|
committer | Peter Wemm <peter@FreeBSD.org> | 2001-01-23 11:16:50 +0000 |
commit | ed1a4621a2ae51371c8e4f181fcb4cdf80d92104 (patch) | |
tree | 5cf799f4f6f8df5445120bd62639abc253a64267 /usr.bin/find | |
parent | 3b9d81dc1acaa3ede3af5a9993b1ee5b2a6cf347 (diff) | |
download | src-ed1a4621a2ae51371c8e4f181fcb4cdf80d92104.tar.gz src-ed1a4621a2ae51371c8e4f181fcb4cdf80d92104.zip |
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
Notes
Notes:
svn path=/head/; revision=71422
Diffstat (limited to 'usr.bin/find')
-rw-r--r-- | usr.bin/find/extern.h | 1 | ||||
-rw-r--r-- | usr.bin/find/find.1 | 2 | ||||
-rw-r--r-- | usr.bin/find/find.h | 4 | ||||
-rw-r--r-- | usr.bin/find/function.c | 43 | ||||
-rw-r--r-- | usr.bin/find/option.c | 1 |
5 files changed, 49 insertions, 2 deletions
diff --git a/usr.bin/find/extern.h b/usr.bin/find/extern.h index 16832d424805..00c8db2b3e92 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 44338fadb437..78ddcf5312e9 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 35aadac69a8a..e12608625f71 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 670d102cc8e0..18cd83cfa3e1 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 6ae15d38e1a6..3bb622625db5 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 }, |