The branch main has been updated by imp:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=486cae8f06b1956b5b6f6b9b89c175aa02d56dda

commit 486cae8f06b1956b5b6f6b9b89c175aa02d56dda
Author:     Warner Losh <i...@freebsd.org>
AuthorDate: 2025-07-25 16:30:10 +0000
Commit:     Warner Losh <i...@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:            paua...@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 },

Reply via email to