[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH] find -samedev NAME: true for files on the same device as NAME
From: |
Kamil Dudka |
Subject: |
[PATCH] find -samedev NAME: true for files on the same device as NAME |
Date: |
Thu, 1 Nov 2018 16:56:58 +0100 |
There is no easy way to exclude mount points from the output of `find`.
The options -xdev or -mount prevent `find` from traversing over the
mount points but do not exclude the mount points themselves. It could
be scripted by AWK on Linux as in the following example:
$ find / -xdev -maxdepth 1 $(awk '$2 != "/" { printf("! -path %s ", $2) }'
/proc/mounts)
Would it make sense to introduce a new predicate similar to -samefile
that takes into account device numbers only?
With the proposed predicate implemented in `find`, the above command
could be encoded in a more user-friendly way:
$ find / -xdev -maxdepth 1 -samedev /
Originally reported at: https://bugzilla.redhat.com/1607772
---
find/defs.h | 1 +
find/find.1 | 8 ++++++++
find/parser.c | 23 +++++++++++++++++++++++
find/pred.c | 18 ++++++++++++++++++
find/tree.c | 1 +
5 files changed, 51 insertions(+)
diff --git a/find/defs.h b/find/defs.h
index 63f3b2a3..2d4965e9 100644
--- a/find/defs.h
+++ b/find/defs.h
@@ -461,6 +461,7 @@ PREDICATEFUNCTION pred_print0;
PREDICATEFUNCTION pred_prune;
PREDICATEFUNCTION pred_readable;
PREDICATEFUNCTION pred_regex;
+PREDICATEFUNCTION pred_samedev;
PREDICATEFUNCTION pred_samefile;
PREDICATEFUNCTION pred_size;
PREDICATEFUNCTION pred_true;
diff --git a/find/find.1 b/find/find.1
index 67fdd537..dec78798 100644
--- a/find/find.1
+++ b/find/find.1
@@ -932,6 +932,13 @@ newline), but this can be changed with the
.B \-regextype
option.
+.IP "\-samedev \fIname\fR"
+File is on the same device as
+.IR name .
+When
+.B \-L
+is in effect, this can include symbolic links.
+
.IP "\-samefile \fIname\fR"
File refers to the same inode as
.IR name .
@@ -2282,6 +2289,7 @@ Feature Added in Also occurs in
\-exec ... + 4.2.12 POSIX
\-execdir 4.2.12 BSD
\-okdir 4.2.12
+\-samedev 4.6.1
\-samefile 4.2.11
\-H 4.2.5 POSIX
\-L 4.2.5 POSIX
diff --git a/find/parser.c b/find/parser.c
index d6621506..14279c69 100644
--- a/find/parser.c
+++ b/find/parser.c
@@ -128,6 +128,7 @@ static bool parse_printf (const struct
parser_table*, char *argv[], int *
static bool parse_prune (const struct parser_table*, char *argv[], int
*arg_ptr);
static bool parse_regex (const struct parser_table*, char *argv[], int
*arg_ptr);
static bool parse_regextype (const struct parser_table*, char *argv[], int
*arg_ptr);
+static bool parse_samedev (const struct parser_table*, char *argv[], int
*arg_ptr);
static bool parse_samefile (const struct parser_table*, char *argv[], int
*arg_ptr);
static bool parse_size (const struct parser_table*, char *argv[], int
*arg_ptr);
static bool parse_time (const struct parser_table*, char *argv[], int
*arg_ptr);
@@ -290,6 +291,7 @@ static struct parser_table const parse_table[] =
{ARG_TEST, "readable", parse_accesscheck, pred_readable},
/* GNU, 4.3.0+ */
PARSE_TEST ("regex", regex), /* GNU */
PARSE_POSOPT ("regextype", regextype), /* GNU */
+ PARSE_TEST ("samedev", samedev), /* GNU */
PARSE_TEST ("samefile", samefile), /* GNU */
#if 0
PARSE_OPTION ("show-control-chars", show_control_chars), /* GNU,
4.3.0+ */
@@ -2169,6 +2171,27 @@ parse_size (const struct parser_table* entry, char
**argv, int *arg_ptr)
}
+static bool
+parse_samedev (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+ struct predicate *our_pred;
+ struct stat st;
+ const char *filename;
+
+ set_stat_placeholders (&st);
+ if (!collect_arg_stat_info (argv, arg_ptr, &st, &filename))
+ return false;
+
+ our_pred = insert_primary (entry, filename);
+ our_pred->args.samefileid.ino = (ino_t) -1;
+ our_pred->args.samefileid.dev = st.st_dev;
+ our_pred->args.samefileid.fd = -1;
+ our_pred->need_type = false;
+ our_pred->need_stat = true;
+ our_pred->est_success_rate = 1.0f;
+ return true;
+}
+
static bool
parse_samefile (const struct parser_table* entry, char **argv, int *arg_ptr)
{
diff --git a/find/pred.c b/find/pred.c
index 2014b5ab..f1da8669 100644
--- a/find/pred.c
+++ b/find/pred.c
@@ -118,6 +118,7 @@ struct pred_assoc pred_table[] =
{pred_quit, "quit "},
{pred_readable, "readable "},
{pred_regex, "regex "},
+ {pred_samedev, "samedev "},
{pred_samefile,"samefile "},
{pred_size, "size "},
{pred_true, "true "},
@@ -986,6 +987,23 @@ pred_size (const char *pathname, struct stat *stat_buf,
struct predicate *pred_p
return (false);
}
+bool
+pred_samedev (const char *pathname, struct stat *stat_buf, struct predicate
*pred_ptr)
+{
+ (void) pathname;
+
+ /* Stat the file (if not already statted) to check the device number. */
+ if (0 == get_statinfo (pathname, state.rel_pathname, stat_buf))
+ {
+ return (stat_buf->st_dev == pred_ptr->args.samefileid.dev);
+ }
+ else
+ {
+ /* get_statinfo will already have emitted an error message. */
+ return false;
+ }
+}
+
bool
pred_samefile (const char *pathname, struct stat *stat_buf, struct predicate
*pred_ptr)
{
diff --git a/find/tree.c b/find/tree.c
index 5be88f2e..f5ccc943 100644
--- a/find/tree.c
+++ b/find/tree.c
@@ -972,6 +972,7 @@ static struct pred_cost_lookup costlookup[] =
{ pred_quit , NeedsNothing },
{ pred_readable , NeedsAccessInfo },
{ pred_regex , NeedsNothing },
+ { pred_samedev , NeedsStatInfo },
{ pred_samefile , NeedsStatInfo },
{ pred_size , NeedsStatInfo },
{ pred_true , NeedsNothing },
--
2.17.2
- [PATCH] find -samedev NAME: true for files on the same device as NAME,
Kamil Dudka <=