git: 486cae8f06b1 - main - find: implement -fprint and -fprint0
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 25 Jul 2025 16:35:12 UTC
The branch main has been updated by imp:
URL: https://cgit.FreeBSD.org/src/commit/?id=486cae8f06b1956b5b6f6b9b89c175aa02d56dda
commit 486cae8f06b1956b5b6f6b9b89c175aa02d56dda
Author: Warner Losh <imp@FreeBSD.org>
AuthorDate: 2025-07-25 16:30:10 +0000
Commit: Warner Losh <imp@FreeBSD.org>
CommitDate: 2025-07-25 16:34:49 +0000
find: implement -fprint and -fprint0
Implement -fprint fn which will print the matching files to fn, each
followed by a newline ('\n'). And -fprint0 (same, except followed by a
NUL). Both of these are always true. The file is created if it does not
exist, or truncated if it does. This is done first thing
unconditionally, so if there's no output, the file will have zero
length.
Note: GNU Find appears to collect the output for -fprint* to the same
file such that they don't interfere. That detail is unimplemented at
present.
Sponsored by: Netflix
Discussed with: jilles
Reviewed by: pauamma@gundo.com (man)
Differential Revision: https://reviews.freebsd.org/D42667
---
usr.bin/find/extern.h | 3 +++
usr.bin/find/find.1 | 22 ++++++++++++++++++++++
usr.bin/find/find.h | 2 ++
usr.bin/find/function.c | 43 +++++++++++++++++++++++++++++++++++++++++++
usr.bin/find/option.c | 4 ++--
5 files changed, 72 insertions(+), 2 deletions(-)
diff --git a/usr.bin/find/extern.h b/usr.bin/find/extern.h
index 6760ac24fb04..02c85d06a34c 100644
--- a/usr.bin/find/extern.h
+++ b/usr.bin/find/extern.h
@@ -57,6 +57,7 @@ creat_f c_empty;
creat_f c_exec;
creat_f c_flags;
creat_f c_follow;
+creat_f c_fprint;
creat_f c_fstype;
creat_f c_group;
creat_f c_ignore_readdir_race;
@@ -93,6 +94,8 @@ exec_f f_executable;
exec_f f_expr;
exec_f f_false;
exec_f f_flags;
+exec_f f_fprint;
+exec_f f_fprint0;
exec_f f_fstype;
exec_f f_group;
exec_f f_inum;
diff --git a/usr.bin/find/find.1 b/usr.bin/find/find.1
index 1217d9151168..3012ae472015 100644
--- a/usr.bin/find/find.1
+++ b/usr.bin/find/find.1
@@ -515,6 +515,28 @@ and none of the
.Ar flags
bits match those of
.Ar notflags .
+.It Ic -fprint Ar filename
+This primary always evaluates to true.
+This creates
+.Ar filename
+or truncates the file if it already exists.
+The file is created at startup.
+It writes the pathname of the current file to this file, followed
+by a newline character.
+The file will be empty if no files are matched.
+.Pp
+.It Ic -fprint0 Ar filename
+This primary always evaluates to true.
+This creates
+.Ar filename
+or truncates the file if it already exists.
+The file is created at startup.
+It writes the pathname of the current file to this file, followed
+by an ASCII
+.Dv NUL
+character (character code 0).
+The file will be empty if no files are matched.
+.Pp
.It Ic -fstype Ar type
True if the file is contained in a file system of type
.Ar type .
diff --git a/usr.bin/find/find.h b/usr.bin/find/find.h
index 2ddb70fd7bcc..e8bb0ca8c649 100644
--- a/usr.bin/find/find.h
+++ b/usr.bin/find/find.h
@@ -135,6 +135,7 @@ typedef struct _plandata {
char *_a_data[2]; /* array of char pointers */
char *_c_data; /* char pointer */
regex_t *_re_data; /* regex */
+ FILE *_fprint_file; /* file stream for -fprint */
} p_un;
} PLAN;
#define a_data p_un._a_data
@@ -162,6 +163,7 @@ typedef struct _plandata {
#define e_pbsize p_un.ex._e_pbsize
#define e_psizemax p_un.ex._e_psizemax
#define e_next p_un.ex._e_next
+#define fprint_file p_un._fprint_file
typedef struct _option {
const char *name; /* option name */
diff --git a/usr.bin/find/function.c b/usr.bin/find/function.c
index 21dfab8fe408..ac7fe4dd4e98 100644
--- a/usr.bin/find/function.c
+++ b/usr.bin/find/function.c
@@ -866,6 +866,49 @@ c_follow(OPTION *option, char ***argvp __unused)
return palloc(option);
}
+/*
+ * -fprint functions --
+ *
+ * Always true, causes the current pathname to be written to
+ * specified file followed by a newline
+ */
+int
+f_fprint(PLAN *plan, FTSENT *entry)
+{
+ fprintf(plan->fprint_file, "%s\n", entry->fts_path);
+ return 1;
+}
+
+PLAN *
+c_fprint(OPTION *option, char ***argvp)
+{
+ PLAN *new;
+ char *fn;
+
+ isoutput = 1;
+
+ new = palloc(option);
+ fn = nextarg(option, argvp);
+ new->fprint_file = fopen(fn, "w");
+ if (new->fprint_file == NULL)
+ err(1, "fprint: cannot create %s", fn);
+
+ return (new);
+}
+
+/*
+ * -fprint0 functions --
+ *
+ * Always true, causes the current pathname to be written to
+ * specified file followed by a NUL
+ */
+int
+f_fprint0(PLAN *plan, FTSENT *entry)
+{
+ fprintf(plan->fprint_file, "%s%c", entry->fts_path, '\0');
+ return 1;
+}
+
#if HAVE_STRUCT_STATFS_F_FSTYPENAME
/*
* -fstype functions --
diff --git a/usr.bin/find/option.c b/usr.bin/find/option.c
index 79fa581e79f5..fa09231a3152 100644
--- a/usr.bin/find/option.c
+++ b/usr.bin/find/option.c
@@ -83,8 +83,8 @@ static OPTION const options[] = {
#endif
// -fls
{ "-follow", c_follow, f_always_true, 0 },
-// -fprint
-// -fprint0
+ { "-fprint", c_fprint, f_fprint, 0 },
+ { "-fprint0", c_fprint, f_fprint0, 0 },
// -fprintf
#if HAVE_STRUCT_STATFS_F_FSTYPENAME
{ "-fstype", c_fstype, f_fstype, 0 },