Compare commits

...

129 Commits

Author SHA1 Message Date
Bernhard Voelker
6b49775f9d maint: update gnulib to latest
Run 'make update-gnulib-to-latest'; there have been 58 commits on gnulib
since the last update.

* gnulib: Update to latest.
2026-01-25 19:40:23 +01:00
Bernhard Voelker
6cf0fe34d7 maint: simplify updating 'bootstrap' and adjust target 'gnulib-sync'
Copy the 'bootstrap' script from the 'build-aux' directory in gnulib
instead of from the 'top' directory.  The former one already contains
the 'bootstrap-funclib.sh' code which can then be removed as well here.
Finally, remove the obsolete 'autogen.sh' and 'autopull.sh' scripts.

* autogen.sh: Remove.
* autopull.sh: Remove.
* bootstrap-funclib.sh: Remove.
* bootstrap: Update from 'gnulib/build-aux/bootstrap'.
* Makefile.am (gnulib-sync): Change the source dirsctory of 'bootstrap'
from 'top' to 'build-aux', and remove the copying of above obsolete
files.
2026-01-25 19:18:23 +01:00
Bernhard Voelker
c56b96a54f maint: prefer NULL to nullptr
NULL is best for C as discussed - for coreutils - at:
  https://bugs.gnu.org/66221#53

* bootstrap.conf: Remove dependency on nullptr.
* s/nullptr/NULL/.

This effectively reverts 93ce19f0d5a1.
2026-01-20 23:03:54 +01:00
Bernhard Voelker
99b3365ec3 tests: avoid unportable 'sed -i'
The sed(1) implementations at least on Solaris and the BSD familiy OSes do
not support the -i flag, and latest POSIX 2024 still does not specify it.

* tests/find/user-group-max.sh: Avoid 'sed -i' by redirecting to
another file ERR2.
2026-01-06 10:34:37 +01:00
Bernhard Voelker
ebea22e88b tests: make new -mount test more robust
This test failed on non-Linux systems:
- On Solaris 11, the output of the native df(1) tool has a different order,
  and hence the detection of a usable mount point for the test fails.
  Verify that df(1) is from GNU coreutils, or fall back to 'gdf',
  else skip the test.
- On a FreeBSD system where /home was a symlink to /usr/home, the code
  for finding a usable mount point failed, because the symlink itself
  is on the '/' file system.
  Ensure that the found mount point is identical to the original test
  directory like /home etc.

* tests/find/mount-vs-xdev.sh: Try harder to use a GNU df(1) tool.
Check whether the found mount point is identical to the original
directory name, thus avoiding symlinks.
2026-01-06 10:33:59 +01:00
Bernhard Voelker
3c2af8a185 doc: avoid man-lint errors due to deprecated .HP macro
The .HP macro introduced only recently triggers a 'make check' errors:

   env GROFF=groff ../build-aux/man-lint.sh . find.1
   check_manpages_format_without_error_messages  (         find.1): OK
   check_manpages_with_groff_checkstyle_2        (         find.1): FAILED
   an.tmac:./find.1:23: style: use of deprecated macro: .HP
   make[3]: *** [Makefile:3112: findutils-check-manpages] Error 1

and

   env GROFF=groff ../build-aux/man-lint.sh . locate.1 updatedb.1 locatedb.5
   check_manpages_format_without_error_messages  (       locate.1): OK
   check_manpages_format_without_error_messages  (     updatedb.1): OK
   check_manpages_format_without_error_messages  (     locatedb.5): OK
   check_manpages_with_groff_checkstyle_2        (       locate.1): FAILED
   an.tmac:./locate.1:18: style: use of deprecated macro: .HP
   make[3]: *** [Makefile:3287: findutils-check-manpages] Error 1
   make[3]: Target 'check-local' not remade because of errors.

The HP hanging paragraph would work nicely, but is marked as deprecated
in groff-1.23; the deprecations warning will disappear in groff-1.24.
Until then, use .TP instead to avoid the check errors.

* find/find.1: Change '.HP' to the '.TP' tagged paragraph macro.
Add a FIXME for 2027 to switch to .HP when groff-1.24 is more commonly
available.
* locate/locate.1: Likewise.
2026-01-05 16:52:58 +01:00
G. Branden Robinson
09a4602970 xargs.1: revise option formatting
* xargs/xargs.1:

- Migrate from comma-separated to "stacked tag" formatting for command
  options.  This is easier to read and understand when option syntax is
  complex, and eliminates the problem of the comma being misinterpreted.
  Setting the comma in bold, not roman, might have increased this risk.

  Stacking tags--without direct recourse to formatter requests--however
  requires the use of a groff man(7) extension macro, `TQ` (from groff
  1.20, 2009).  Because this page needs to be portable to non-groff
  formatters, define a page-local version after testing for its
  nonexistence using other GNU troff extensions (the `do` request and
  the `d` conditional expression operator).  (Actually, the method here
  is to test for `TQ`'s existence and then ignore the macro definition
  if the test succeeds; the token `..` terminates whichever eventuates.)

- Use the `TQ` macro to stack paragraph tags presenting synonymous
  options to xargs(1).

- Use the page-local `~~` string to put unbreakable spaces (where
  supported) between short options and their arguments.  (On the other
  hand, if a paragraph tag breaks across lines, the document likely
  requires revision.)

Discussed at:
https://lists.gnu.org/r/bug-findutils/2025-11/msg00094.html

Copyright-paperwork-exempt: Yes
2026-01-05 16:52:58 +01:00
G. Branden Robinson
b698bc19a1 xargs.1: fix markup nit
* xargs/xargs.1: Consistently use empty request before paragraphing macros
to aid document maintainers.  This was already done, inconsistently.

Discussed at:
https://lists.gnu.org/r/bug-findutils/2025-11/msg00094.html

Copyright-paperwork-exempt: Yes
2026-01-05 16:52:58 +01:00
G. Branden Robinson
a86cd78912 xargs.1: fix markup nit
groff_man(7):
   History
     M. Douglas McIlroy ⟨m.douglas.mcilroy@dartmouth.edu⟩ designed,
     implemented, and documented the AT&T man macros for Unix Version 7
     (1979) and employed them to edit Volume 1 of its Programmer’s
     Manual, a compilation of all man pages supplied by the system.  The
     package supported the macros listed in this page not described as
     extensions, except P and the deprecated AT and UC.  It documented
     no registers and defined only R and S strings.

     UC appeared in 3BSD (1980).  Unix System III (1980) introduced P
     and exposed the registers IN and LL, which had been internal to
     Seventh Edition Unix man.  PWB/Unix 2.0 (1980) added the Tm string.
     4BSD (1980) added lq and rq strings.  SunOS 2.0 (1985) recognized
     C, D, P, and X registers.  4.3BSD (1986) added AT and P.  Ninth
     Edition Unix (1986) introduced EX and EE.  SunOS 4.0 (1988) added
     SB.  Unix System V (1988) incorporated BSD’s lq and rq strings.

     Except for EX/EE, James Clark implemented the foregoing features in
     early versions of groff.  Later, groff 1.20 (2009) resurrected
     EX/EE and originated SY/YS, TQ, MT/ME, and UR/UE.  Plan 9 from User
     Space’s troff introduced MR in 2020.

* xargs/xargs.1: Favor `P` macro, which the page predominantly uses, over
`PP` (`LP` is not observed).  `P` has been universally portable since 1986.

Discussed at:
https://lists.gnu.org/r/bug-findutils/2025-11/msg00094.html

Copyright-paperwork-exempt: Yes
2026-01-05 16:52:58 +01:00
G. Branden Robinson
8d74646de9 xargs.1: fix markup nit
* xargs/xargs.1:
Drop unnecessary quotes around single-word macro arguments.

Discussed at:
https://lists.gnu.org/r/bug-findutils/2025-11/msg00094.html

Copyright-paperwork-exempt: Yes
2026-01-05 16:52:58 +01:00
G. Branden Robinson
214285e6f2 xargs.1: fix unescaped hyphens
* xargs/xargs.1: Do the above.

Discussed at:
https://lists.gnu.org/r/bug-findutils/2025-11/msg00094.html

Copyright-paperwork-exempt: Yes
2026-01-05 16:52:58 +01:00
G. Branden Robinson
341ba019f4 xargs.1: clarify --max-args value "1" better
* xargs/xargs.1: Do the above.

Discussed at:
https://lists.gnu.org/r/bug-findutils/2025-11/msg00094.html

Copyright-paperwork-exempt: Yes
2026-01-05 16:52:58 +01:00
G. Branden Robinson
289eaa25dc xargs.1: hyphenate attributive phrase
* xargs/xargs.1 (OPTIONS): Use hyphen in "POSIX-compliant".

Discussed at:
https://lists.gnu.org/r/bug-findutils/2025-11/msg00094.html

Copyright-paperwork-exempt: Yes
2026-01-05 16:52:58 +01:00
G. Branden Robinson
ab387c1cdc xargs.1: fix font markup nit
* xargs/xargs.1:
Favor man(7) font macros over *roff font selection escape sequences.
Macros are (a) visually less cluttered, (b) interfere less with spell
checking, and (c), in groff man(7), automatically apply italic
corrections, which otherwise requires explicit use of GNU troff
extension escape sequences (`\/` and `\,`).

Discussed at:
https://lists.gnu.org/r/bug-findutils/2025-11/msg00094.html

Copyright-paperwork-exempt: Yes
2026-01-05 16:52:58 +01:00
G. Branden Robinson
2b9f253b15 xargs.1: use ellipses in synopsis
...rather than pluralization.

* xargs/xargs.1 (SYNOPSIS): Do the above.

Discussed at:
https://lists.gnu.org/r/bug-findutils/2025-11/msg00094.html

Copyright-paperwork-exempt: Yes
2026-01-05 16:52:58 +01:00
G. Branden Robinson
c5dfe4c378 xargs.1: set file names in italics
...not roman.

groff_man_style(7):
   Font style macros
...
     .I [text]
            Set text in an italic or oblique face.  Given no argument, I
            plants a one‐line input trap; text on the next line, which
            can be further formatted with a macro, is set in an italic
            or oblique face.

            Use italics for file and path names, for environment
            variables, for C data types, for enumeration or preprocessor
            constants in C, for variant (user‐replaceable) portions of
            syntax synopses, for the first occurrence (only) of a
            technical concept being introduced, for names of journals
            and of literary works longer than an article, and anywhere a
            parameter requiring replacement by the user is encountered.
            An exception involves variant text in a context already
            typeset in italics, such as file or path names with
            replaceable components; in such cases, follow the convention
            of mathematical typography: set the file or path name in
            italics as usual but use roman for the variant part (see IR
            and RI below), and italics again in running roman text when
            referring to the variant material.

* xargs/xargs.1: Do the above.

Discussed at:
https://lists.gnu.org/r/bug-findutils/2025-11/msg00094.html

Copyright-paperwork-exempt: Yes
2026-01-05 16:52:58 +01:00
G. Branden Robinson
6d695cc480 xargs.1: use quotation marks
* xargs/xargs.1: Also set the braces in `-I{}` in bold, not roman,
since they are literal.

The `lq` and `rq` strings are widely portable.

groff_man_style(7):
   Strings
     \*(lq
     \*(rq   interpolate special character escape sequences for left and
             right double‐quotation marks, \(lq and \(rq, respectively.
...
     A contemporary man page needs none of the above.  \*S is
     superfluous; type size changes are invisible on terminals, and
     macros that change it restore its original value afterward.  Better
     alternatives exist for the rest; simply use the \[rg], \[lq],
     \[rq], and \[tm] special character escape sequences directly.
     Unless you are aiming for a pathological level of portability——
     perhaps composing a man page for consumption on simulators of 1980s
     Unix systems (or Solaris 10 troff, though even it supports
     “\(rg”)——avoid using the above strings.
...
Notes
     Some tips on composing and troubleshooting your man pages follow.
...
     • When and how should I use quotation marks?

       As noted above in subsection “Font style macros”, apply quotation
       marks to “brief specimens of literal text, such as article
       titles, inline examples, mentions of individual characters or
       short strings, and (sub)section headings in man pages”.  Multi‐
       word literals, such as Unix commands with arguments, when set
       inline (as opposed to displayed between EX and EE), should be
       quoted to ensure that the boundaries of the literal are clear
       even when the material is stripped of font styling by, for
       example, copy‐and‐paste operations.  groff, Heirloom Doctools
       troff, neatroff, and mandoc support all of the special characters
       \[oq], \[cq], \[lq], \[rq], \[aq], and \[dq] described in
       subsection “Portability” above.  DWB, Plan 9, and Solaris 10
       troffs do not.  Interpolating the strings \*(lq and \*(rq
       portably yields directional double quotation marks, if available,
       in all these formatters (though neatroff does not supply a man
       macro package), but they cannot reliably be used in macro
       arguments.

Discussed at:
https://lists.gnu.org/r/bug-findutils/2025-11/msg00094.html

Copyright-paperwork-exempt: Yes
2026-01-05 16:52:58 +01:00
G. Branden Robinson
34142ca063 xargs.1: set "findutils" in italics
...not roman.

* xargs/xargs.1 (STANDARDS CONFORMANCE): Do the above.

Discussed at:
https://lists.gnu.org/r/bug-findutils/2025-11/msg00094.html

Copyright-paperwork-exempt: Yes
2026-01-05 16:52:58 +01:00
G. Branden Robinson
4055cf7bbc xargs.1: fix truncated examples on old troff
Seventh Edition Unix man(7)[1] and its descendants handle at most six
arguments to macros.  Excess arguments are ignored and not formatted.

[1] https://minnie.tuhs.org/cgi-bin/utree.pl?file=V7/usr/lib/tmac/tmac.an

* xargs/xargs.1 (EXAMPLES): Add quotes.

Discussed at:
https://lists.gnu.org/r/bug-findutils/2025-11/msg00094.html

Copyright-paperwork-exempt: Yes
2026-01-05 16:52:58 +01:00
G. Branden Robinson
5c31ac2aeb xargs.1: add styling to text
...for consistency with existing practice in findutils man pages.

* xargs/xargs.1: Set "find" (the command) and "-print0" in bold, not roman.

Discussed at:
https://lists.gnu.org/r/bug-findutils/2025-11/msg00094.html

Copyright-paperwork-exempt: Yes
2026-01-05 16:52:58 +01:00
G. Branden Robinson
4e562ab11f xargs.1: access ' character portably
* xargs/xargs.1: Do the above.

Discussed at:
https://lists.gnu.org/r/bug-findutils/2025-11/msg00094.html

Copyright-paperwork-exempt: Yes
2026-01-05 16:52:58 +01:00
G. Branden Robinson
cd4977172c xargs.1: overcome limited portability of \~
Warnings from `groff -C -ww -man` in the forthcoming groff 1.24:
troff:xargs/xargs.1:295: warning: an escaped '~' is not portable to AT&T troff
troff:xargs/xargs.1:296: warning: an escaped '~' is not portable to AT&T troff
troff:xargs/xargs.1:296: warning: an escaped '~' is not portable to AT&T troff
troff:xargs/xargs.1:298: warning: an escaped '~' is not portable to AT&T troff

groff_man_style(1):
   Portability
...
     \~        Adjustable non‐breaking space.  Use this escape sequence
               to prevent a break inside a short phrase or between a
               numerical quantity and its corresponding unit(s).

                      Before starting the motor,
                      set the output speed to\~1.
                      There are 1,024\~bytes in 1\~KiB.
                      CSTR\~#8 documents the B\~language.

               \~ is a GNU extension also supported by Heirloom Doctools
               troff 050915 (September 2005), mandoc 1.9.14
               (2009‐11‐16), neatroff (commit 1c6ab0f6e, 2016‐09‐13),
               and Plan 9 from User Space troff (commit 93f8143600,
               2022‐08‐12), but not by DWB or Solaris 10 troffs.

* xargs/xargs.1:
Define a string to indirect use of `\~` escape sequence.  On formatters
that don't support groff extensions, use the AT&T troff `\ `
(backslash-space) escape sequence, which isn't quite as good because it
is a space that is not only unbreakable, but unadjustable--which,
however, doesn't matter when formatting man pages with adjustment
disabled, as some implementations do (and which groff makes
configurable).

Discussed at:
https://lists.gnu.org/r/bug-findutils/2025-11/msg00094.html

Copyright-paperwork-exempt: Yes
2026-01-05 16:52:58 +01:00
G. Branden Robinson
5a000f9a50 locate.1: access ^ character portably
The `\(ha` special character escape sequence is not universally
portable.  Indirect it through a string definition.  (GNU Bash also uses
this technique.[1])

* locate/locate.1: Do the above.

[1] a8a1c2fac0/doc/bash.1 (L26)

Discussed at:
https://lists.gnu.org/r/bug-findutils/2025-11/msg00094.html

Copyright-paperwork-exempt: Yes
2026-01-05 16:52:58 +01:00
G. Branden Robinson
a64197a3d8 locatedb.5: fix unescaped hyphens
These instances represent hyphen-minus characters, so should be spelled
in man(7) source as `\-`.

* locate/locatedb.5: Do the above.

Discussed at:
https://lists.gnu.org/r/bug-findutils/2025-11/msg00094.html

Copyright-paperwork-exempt: Yes
2026-01-05 16:52:58 +01:00
G. Branden Robinson
236a3c8647 xargs.1: use portable typographer's quotes
* xargs/xargs.1: Do the above.

Discussed at:
https://lists.gnu.org/r/bug-findutils/2025-11/msg00094.html

Copyright-paperwork-exempt: Yes
2026-01-05 16:52:58 +01:00
G. Branden Robinson
755d9fbf38 find.1: set file name literals in italics
...not roman, and protect them from hyphenation.

GNU troff, Heirloom Doctools troff, and mandoc all support use of the
`\%` hyphenation control escape sequence at the _beginning_ of a word
suppress its hyphenation.  Other troffs do not.  Indirect this
application of the escape sequence through a string, interpolating
nothing on formatters that don't advertise GNU compatibility via the
`.g` register.  (This means that literals can hyphenate undesirably on
DWB, Solaris, and Plan 9 troffs.)

GNU troff, Heirloom Doctools troff, and mandoc all also support the GNU
`\:` extension to mark break points that should not produce hyphens.
Apply the same technique to avoid undesired formatting of a ':'
character on DWB, Solaris, and Plan 9 troffs.

* find/find.1: Do the above.

Discussed at:
https://lists.gnu.org/r/bug-findutils/2025-11/msg00094.html

Copyright-paperwork-exempt: Yes
2026-01-05 16:52:58 +01:00
G. Branden Robinson
30f820abf7 find.1: access “ and ” portably
The `\(lq` and `\(rq` and special character escape sequences are not
universally portable.

Traditionally, AT&T troff did not bother to identify these special
characters at all; it was apparently felt that adjacently setting
directional single quotes sufficed.  You can discern this fact in
materials typeset by AT&T troff by observing what one might call
generous kerning of these glyphs when used as "double" quotes.

However, someone at the Berkeley CSRG had a brainwave, and for 4BSD in
1980, added strings named `lq` and `rq` to the man(7) package so that
man pages could access double quotes by whatever means the underlying
implementation had for realizing them.  This excellent idea made it into
Unix System V (1988/9), so that every surviving troff implementation
known to me, including DWB and Solaris 10, supports them--save one.  The
exception is Plan 9.  Fortunately, the Plan 9 from User Space
("plan9port") project accepted a patch from me on 10 October to add
support there as well.[1]

Like the \*" string, \*(lq and \*(rq should not be used in quoted macro
arguments if one desires portability to AT&T troff-descended formatters
(other than Heirloom Doctools troff); if the implementation defines
these strings such that their interpolations contain `"`, undesired
output is the likely result.

[1] https://github.com/9fans/plan9port/pull/735

* find/find.1: Do the above.

Discussed at:
https://lists.gnu.org/r/bug-findutils/2025-11/msg00094.html

Copyright-paperwork-exempt: Yes
2026-01-05 16:52:58 +01:00
G. Branden Robinson
897264c8e8 find.1: use new ~ string for pastable tilde
* find/find.1: Do the above.

Discussed at:
https://lists.gnu.org/r/bug-findutils/2025-11/msg00094.html

Copyright-paperwork-exempt: Yes
2026-01-05 16:52:58 +01:00
G. Branden Robinson
c4f03874ac find.1: access ~ character portably
* find/find.1:
The `\(ti` special character escape sequence is not universally
portable.  Indirect it through a string definition.  (GNU Bash also uses
this technique.[1])

[1] a8a1c2fac0/doc/bash.1 (L26)

Discussed at:
https://lists.gnu.org/r/bug-findutils/2025-11/msg00094.html

Copyright-paperwork-exempt: Yes
2026-01-05 16:52:58 +01:00
G. Branden Robinson
bbce846161 find.1: improve cosmetics of *roff logic
* find/find.1: Do the above.

Discussed at:
https://lists.gnu.org/r/bug-findutils/2025-11/msg00094.html

Copyright-paperwork-exempt: Yes
2026-01-05 16:52:58 +01:00
G. Branden Robinson
2923a0d78f doc: access en dash character portably
The `\(en` special character escape sequence is not universally
portable.  Indirect it through a string definition.

* find/find.1:
* locate/locate.1:
* locate/locatedb.5:
* locate/updatedb.1:
* xargs/xargs.1: Do the above.

Discussed at:
https://lists.gnu.org/r/bug-findutils/2025-11/msg00094.html

Copyright-paperwork-exempt: Yes
2026-01-05 16:52:58 +01:00
G. Branden Robinson
7cb135d5fb find.1: use em dash for linguistic pausa
An em dash is the more orthographically correct dash for a couple of
contexts where the page had been using an en dash (which denotes a
range), and its special character escape sequence is universally
portable to boot.

* find/find.1: \Replace "(en" by "\(em".

Discussed at:
https://lists.gnu.org/r/bug-findutils/2025-11/msg00094.html

Copyright-paperwork-exempt: Yes
2026-01-05 16:52:58 +01:00
G. Branden Robinson
f0e2bbe45b find.1: set quotation marks as such in roman
* find/find.1: ...not bold.

Discussed at:
https://lists.gnu.org/r/bug-findutils/2025-11/msg00094.html

Copyright-paperwork-exempt: Yes
2026-01-05 16:52:58 +01:00
G. Branden Robinson
e0d0dab353 find.1: access ` character portably
When using ` as the Unix shell's command output substitution operator,
use the portable *roff `\(ga` special character escape sequence to
ensure that we really format a grave accent rather than a typographer's
single quotation mark (‘).

* find/find.1: Do the above.

Discussed at:
https://lists.gnu.org/r/bug-findutils/2025-11/msg00094.html

Copyright-paperwork-exempt: Yes
2026-01-05 16:52:58 +01:00
G. Branden Robinson
a81c9c431d find.1: access ' character portably
The `\(aq` special character escape sequence is not universally
portable.  Indirect it through a string definition.  (GNU Bash also uses
this technique.[1])

[1] a8a1c2fac0/doc/bash.1 (L26)

* find/find.1: Do the above.

Discussed at:
https://lists.gnu.org/r/bug-findutils/2025-11/msg00094.html

Copyright-paperwork-exempt: Yes
2026-01-05 16:52:58 +01:00
G. Branden Robinson
ba94c5423e find.1: access " character somewhat portably
The `\(dq` special character escape sequence is not universally
portable.  Indirect it through a string definition.  (GNU Bash also uses
this technique.[1])

Unfortunately, `"` is one of the worst-behaved and least-accessible
characters in AT&T troff; a pleasant Dr. Jekyll when used on text lines,
its Mr. Hyde persona erupts when used in macro calls, and is wholly
unpredictable to non-experts when appearing in request arguments.[2]
_Some_ AT&T troffs offer `\(dq` on _some_ output devices.  AT&T troff
also has no mechanism for a document to define its own special character
escape sequences.  GNU troff offers `\(dq` on all output devices.

[1] a8a1c2fac0/doc/bash.1 (L26)

[2] "For the (neutral) double quote, you have recourse to an obscure
    syntactical feature of AT&T troff.  Because a double quote can begin
    a macro argument, the formatter keeps track of whether the current
    argument was started thus, and doesn’t require a space after the
    double quote that ends it.  In the argument list to a macro, a
    double quote that isn’t preceded by a space doesn’t start a macro
    argument.  If not preceded by a double quote that began an argument,
    this double quote becomes part of the argument.  Furthermore, within
    a quoted argument, a pair of adjacent double quotes becomes a
    literal double quote."

    https://www.gnu.org/software/groff/manual/groff.html.node/Calling-Macros.html

* find/find.1: Do the above.

Discussed at:
https://lists.gnu.org/r/bug-findutils/2025-11/msg00094.html

Copyright-paperwork-exempt: Yes
2026-01-05 16:52:58 +01:00
G. Branden Robinson
700e8cae79 find.1: improve table formatting
* find/find.1:
- Use paragraphing macros to put vertical space above and below the
  tables (where not already present) so that they looks more like
  typographical "displays".[1]
- Simplify "XY" table definition (see groff's tbl(1) man page).  This
  simpler definition has the same result (and is more adaptable in the
  event the text of the table is revised).
- Put horizontal rule below column headings in table that uses them.
- Use thin space escape sequences `\|` between the dots of an ellipsis;
  the effect is visible only on typesetting devices.[2]  I left the
  dummy character escape sequence `\&` trailing it intact, but observe
  for the edification of nit-pickers that it has no effect in this
  context.[3]

[1] man(7) implementations are historically inconsistent with respect to
    whether a `TS` macro call should put any vertical space on the
    output, and compositional practices on the part of man page authors
    have thus been, to quote Ingo Schwarze, "wildly inconsistent".

    https://savannah.gnu.org/bugs/?62841

[2] groff_man_style(7):

       Examples of ellipsis usage are shown above, in subsection
       “Synopsis macros”.  The idiomatic roff ellipsis is three dots
       (periods) with thin space escape sequences \| internally
       separating them.

[3] tbl(1):

     Ordinarily, a table entry is typeset rigidly.  It is not filled,
     broken, hyphenated, adjusted, or populated with supplemental inter‐
     sentence space.

Discussed at:
https://lists.gnu.org/r/bug-findutils/2025-11/msg00094.html

Copyright-paperwork-exempt: Yes
2026-01-05 16:52:58 +01:00
G. Branden Robinson
1520e3d307 find.1: quote multi-word SH, SS call arguments
The man(7) macro package from AT&T troff and most of its descendants,
including those in DWB, Plan 9, and Solaris troffs, support at most six
arguments to any macro call.

* find/find.1: Quote all multi-word arguments to these macros, not just those
in excess of six arguments, as a reminder of defensive practice to document
maintainers.

Before and after on Plan 9 from User Space troff:

  $ diff -b -U0 find-plan9port-[12].txt
  --- find-plan9port-1.txt        2025-11-18 20:20:08.388887375 -0600
  +++ find-plan9port-2.txt        2025-11-18 20:20:14.712881949 -0600
  @@ -2068 +2068 @@
  -       Safer `find -print0 | xargs -0`
  +       Safer `find -print0 | xargs -0` approach
  @@ -2129 +2129,2 @@
  -       Traversing the filesystem just once en
  +       Traversing the filesystem just once en for 2 different actions

Discussed at:
https://lists.gnu.org/r/bug-findutils/2025-11/msg00094.html

Copyright-paperwork-exempt: Yes
2026-01-05 16:52:58 +01:00
G. Branden Robinson
10235e591a locate.1: improve table formatting
* locate/locate.1 (HISTORY):
- Use paragraphing macro to put vertical space above the table so that
  it looks more like a typographical "display".[1]
- Set table cells that overset the line on AT&T nroff (where the line
  length is 65n) using text blocks.
- Issue `na` request in these text blocks to prevent the cell contents
  from adjusting in the event the formatter/package/user has configured
  man pages to employ adjustment by default.  (Practices vary; it's a
  long story.[2])
- Remove spaces around the configured tbl(1) tab character of `|`.  This
  certainly does make the table uglier in source form.  Unfortunately,
  AT&T tbl(1) takes those spaces deadly seriously and they impact the
  computed cell (and therefore column) widths.  GNU tbl has for decades
  supported a "nospaces" region option to address precisely this
  problem; unfortunately it is not portable to DWB 3.3, Plan 9, or
  Solaris 10 troffs, and I suspect not to _any_ surviving System V
  troff.

Fixes warning from tbl(1) in groff 1.23.0:

locate/locate.1:289: warning: table wider than line length minus indentation

[1] man(7) implementations are historically inconsistent with respect to
    whether a `TS` macro call should put any vertical space on the
    output, and compositional practices on the part of man page authors
    have thus been, to quote Ingo Schwarze, "wildly inconsistent".

    https://savannah.gnu.org/bugs/?62841

[2] "Some people do hate adjustment of nroff output, though, which is
    why I added a feature to groff man(7) to support disabling it.

    The history of this practice is inconsistent.  Seventh Edition Unix
    (1979) disabled adjustment of man pages when rendering in nroff
    mode,[3] and BSD retained that disablement until death.  SunOS
    commented it as early as SunOS 2.0 (1985), thus restoring adjustment
    in nroff mode, and retained that all the way through Solaris 10
    (2005).  When James Clark wrote groff starting in about 1989, his
    man(7) implementation closely emulated SunOS.  With the Solaris 11
    release in 2010, Oracle discarded its AT&T-descended troff in favor
    of the then-current groff release.  [That's not quite true--see
    below.]  They're still on groff 1.22.2 (2013) today, and so they've
    been adjusting their man pages in nroff mode for at least 40 years,
    as has groff for about 35[].  I don't know what other System V
    Unices did."

    https://lists.gnu.org/archive/html/groff/2025-05/msg00001.html

    (I made an incorrect claim in the foregoing; Solaris 11 still has
    its AT&T troff around, but its man page rendering is now performed
    by [an old version of] groff.)

Discussed at:
https://lists.gnu.org/r/bug-findutils/2025-11/msg00094.html

Copyright-paperwork-exempt: Yes
2026-01-05 16:52:58 +01:00
G. Branden Robinson
c2b67c7c92 doc: improve formatting of command synopses (2/2)
* find/find.1:
* locate/locate.1: Use unbreakable spaces between options and their
  arguments, potentially improving legibility.

The existing synopses are short enough that they don't break in such a
way as to promote confusion even on old-fashioned AT&T troffs that use a
line length of 65n in nroff mode (vs. groff man(7)'s historical 78n and
present-day 80n).  Thus this change merely makes the synopses robust to
future changes.

Discussed at:
https://lists.gnu.org/r/bug-findutils/2025-11/msg00094.html

Copyright-paperwork-exempt: Yes
2026-01-05 16:52:58 +01:00
G. Branden Robinson
d9cef9e7da doc: improve formatting of command synopses (1/2)
* find/find.1:
* locate/locate.1: Use `HP` hanging paragraph macro to indent
  non-initial lines of synopsis.  Temporarily disable adjustment.

An alternative approach would be to use groff man(7)'s `SY` and `YS`
extension macros; each man page would then need to define local versions
for portability to DWB 3.3, Plan 9, and Solaris 10 troffs.

Discussed at:
https://lists.gnu.org/r/bug-findutils/2025-11/msg00094.html

Copyright-paperwork-exempt: Yes
2026-01-05 16:52:58 +01:00
G. Branden Robinson
3d398b07cd doc: improve typography of synopses
* find/find.1:
* locate/locate.1: Place thin space escape sequences between ellipsis
  dots for more pleasant output when typesetting.

Discussed at:
https://lists.gnu.org/r/bug-findutils/2025-11/msg00094.html

Copyright-paperwork-exempt: Yes
2026-01-05 16:52:58 +01:00
G. Branden Robinson
7e8712f0ca doc: use man(7) macros to style command synopses
* find/find.1:
* locate/locate.1:
* locate/updatedb.1:
* xargs/xargs.1: Favor man(7) font alternation macros over *roff font
  escape sequences.  When typesetting with groff(1), the macros
  automatically apply italic corrections.

* locate/locate.1: Protect long option name literals from hyphenation.
  GNU troff, Heirloom Doctools troff, and mandoc all support use of the
  `\%` hyphenation control escape sequence at the _beginning_ of a word
  suppress its hyphenation.  Other troffs do not.  Indirect this
  application of the escape sequence through a string, interpolating
  nothing on formatters that don't advertise GNU compatibility via the
  `.g` register.  (This means that literals can hyphenate undesirably on
  DWB, Solaris, and Plan 9 troffs.)

Discussed at:
https://lists.gnu.org/r/bug-findutils/2025-11/msg00094.html

Copyright-paperwork-exempt: Yes
2026-01-05 16:52:58 +01:00
G. Branden Robinson
fe5b98b247 find.1: use AT&T troff-compatible syntax
Before and after, using DWB 3.3 troff (Plan 9 and Solaris 10 troffs are
similar):

  $ diff -U0 find.1.dwb-[12].txt|head -n 19
  --- find.1.dwb-1.txt    2025-10-13 10:09:17.024054824 -0500
  +++ find.1.dwb-2.txt    2025-10-13 10:09:24.764012282 -0500
  @@ -2039 +2039 @@
  -            [bu]
  +            o   Find files named core in or below the directory /tmp and
  @@ -2054 +2053,0 @@
  -                Find files named core in or below the directory /tmp and
  @@ -2064,2 +2063 @@
  -            [bu]
  -                Find files named core in or below the directory /tmp and
  +            o   Find files named core in or below the directory /tmp and
  @@ -2080,2 +2078 @@
  -            [bu]
  -                Given that another program proggy pre-filters and cre-
  +            o   Given that another program proggy pre-filters and cre-
  @@ -2097,2 +2094 @@
  -            [bu]
  -                Run file on every file in or below the current direc-
  +            o   Run file on every file in or below the current direc-

Further changes in the diff appear because the document now paginates
differently with these troffs.  That's because a one-en-wide mark 'o'
(the ASCII representation of a bullet) fits within the 4n space allotted
by the document's `IP` calls, whereas "[bu]" does not.

Fixes warnings from "nroff -C -ww -man" in the forthcoming groff 1.24:
troff:./find/find.1:2260: warning: an escaped '[' is not portable to AT&T troff
troff:./find/find.1:2277: warning: an escaped '[' is not portable to AT&T troff
troff:./find/find.1:2305: warning: an escaped '[' is not portable to AT&T troff
troff:./find/find.1:2326: warning: an escaped '[' is not portable to AT&T troff
troff:./find/find.1:2349: warning: an escaped '[' is not portable to AT&T troff
troff:./find/find.1:2372: warning: an escaped '[' is not portable to AT&T troff
troff:./find/find.1:2392: warning: an escaped '[' is not portable to AT&T troff
troff:./find/find.1:2402: warning: an escaped '[' is not portable to AT&T troff
troff:./find/find.1:2415: warning: an escaped '[' is not portable to AT&T troff
troff:./find/find.1:2431: warning: an escaped '[' is not portable to AT&T troff
troff:./find/find.1:2442: warning: an escaped '[' is not portable to AT&T troff
troff:./find/find.1:2459: warning: an escaped '[' is not portable to AT&T troff
troff:./find/find.1:2471: warning: an escaped '[' is not portable to AT&T troff
troff:./find/find.1:2498: warning: an escaped '[' is not portable to AT&T troff
troff:./find/find.1:2542: warning: an escaped '[' is not portable to AT&T troff
troff:./find/find.1:2597: warning: an escaped '[' is not portable to AT&T troff
troff:./find/find.1:2618: warning: an escaped '[' is not portable to AT&T troff
troff:./find/find.1:2630: warning: an escaped '[' is not portable to AT&T troff

* find/find.1: Replace '\[bu]' by '\(bu'.

Discussed at:
https://lists.gnu.org/r/bug-findutils/2025-11/msg00094.html

Copyright-paperwork-exempt: Yes
2026-01-05 16:52:58 +01:00
G. Branden Robinson
ad7e34650a doc: delete blank lines from man page sources
* find/find.1:
* xargs/xargs.1: Replace blank lines with empty requests or paragraphing
  macro calls as seems to be intended.
* find/find.1: Delete blank lines preceding paragraphing or sectioning
  macros that serve only to put excess vertical space in the output.
* locate/locatedb.5: Replace blank lines with a dummy character
  producing a blank output line as _might_ be intended.

groff_man_style(7):
     ?  The empty request (.), which does nothing, vertically spaces the
        input file for readability by the document maintainer.  Do not
        put blank (empty) lines in a man page source document.  Some
        man(1) programs ?squeeze? multiple blank output lines into one.

Fixes style warnings from `groff -rCHECKSTYLE=3 -man`:
an.tmac:/.../share/man/man1/find.1:87: style: blank line in input
...
an.tmac:/.../share/man/man1/xargs.1:231: style: blank line in input
...
an.tmac:/.../share/man/man5/locatedb.5:118: style: blank line in input
...

Discussed at:
https://lists.gnu.org/r/bug-findutils/2025-11/msg00094.html

Copyright-paperwork-exempt: Yes
2026-01-05 16:52:37 +01:00
G. Branden Robinson
d1edc59b19 find.1: fix typo in *roff syntax
Style warning from `groff -rCHECKSTYLE=3 -man`:
an.tmac:/.../share/man/man1/find.1:9: style: 1 leading space(s) on input line

* find/find.1 (SYNOPSIS): Make an intended empty request work that way.

Discussed at:
https://lists.gnu.org/r/bug-findutils/2025-11/msg00094.html

Copyright-paperwork-exempt: Yes
2026-01-02 22:48:58 +01:00
G. Branden Robinson
627072f022 doc: populate man pages' headers and footers more
Style warnings from `groff -rCHECKSTYLE=3 -man`.
an.tmac:/.../share/man/man1/locate.1:1: style: .TH missing third argument; \
  consider document modification date in ISO 8601 format (YYYY-MM-DD)
an.tmac:/.../share/man/man1/locate.1:1: style: .TH missing fourth argument; \
  consider package/project name and version (e.g., "groff 1.23.0")
...and similar.

groff_man_style(7):
     .TH identifier section [footer‐middle [footer‐inside [header‐
     middle]]]
...
            By convention, footer‐middle is the date of the most recent
            modification to the man page source document, and footer‐
            inside is the name and version or release of the project
            providing it.

* find/find.1:
* locate/locate.1:
* locate/locatedb.5:
* locate/updatedb.1:
* xargs/xargs.1: Add appropriate third and fourth arguments to `TH` macro calls.

To determine the revision date to include in the page, I used the Git
"AuthorDate" of the last commit consituting anything but a "bump" to the
copyright notice.

Discussed at:
https://lists.gnu.org/r/bug-findutils/2025-11/msg00094.html

Copyright-paperwork-exempt: Yes
2026-01-02 22:48:58 +01:00
G. Branden Robinson
2749632838 find.1: drop unportable tbl(1) 'x' modifier
Plan 9 and Solaris tbl, like Seventh Edition Unix tbl, do not support
the 'x' column modifier.  This extension appeared in DWB tbl by version
3.3 and early in GNU troff development (both circa 1990).  I suspect,
but do not know, that other System V Unix tbl programs don't support it
either.

These old tbl programs are brutal when they encounter an unsupported
column modifier--they abort the preprocessor altogether ("tbl quits")
without attempting recovery.[1]  Because tbl works as a filter, like
eqn, pic, soelim, or more familiar Unix tools (cat, sed, nl), this means
that tbl truncated the entire remainder of the input at that point.  GNU
tbl is more robust, and discards input only until the next `.TE` token.

Due to this rudeness it's impossible to portably use 'x' without
rewriting the page text, and I know of no good way to parameterize a
table format.  (tbl(1) doesn't have variables or anything like a macro
preprocessor.  *roff strings are no use because tbl is a _pre_processor
for troff.)

To portably use 'x' requires a man page to test the underlying
implementation and potentially rewrite the page prior to installing it.

See a recent patch of mine to ncurses (merged in its 20251115 release)
for an approach potentially adaptable to findutils.

https://lists.gnu.org/archive/html/bug-ncurses/2025-11/msg00035.html

[1] I've proposed a merge request to Plan 9 from User Space to make its
    tbl less intolerant.  Even if accepted, that won't help anyone who
    uses other "legacy" troffs.

    https://github.com/9fans/plan9port/pull/739

* find/find.1 (Functional Changes): Drop 'x' table modifier.

Discussed at:
https://lists.gnu.org/r/bug-findutils/2025-11/msg00094.html

Copyright-paperwork-exempt: Yes
2026-01-02 22:48:58 +01:00
Bernhard Voelker
04738593b4 find: add more -mount tests (check-root)
Add some more tests exercising bind mounts on the same device which
should not be affected by -mount or -xdev, and tests with a loopback
file system and a bind mount from there.

* tests/find/mount-vs-xdev-bind.sh: Add test.
* tests/find/mount-vs-xdev-other-fs.sh: Likewise.
* tests/local.mk (all_root_tests): Reference them.
2026-01-02 22:36:44 +01:00
Bernhard Voelker
0d8de87299 find: add -mount tests
* tests/find/mount-vs-xdev.sh: Add test.
* tests/local.mk (sh_tests): Reference it.
2026-01-02 22:36:42 +01:00
Bernhard Voelker
6da3a73f73 NEWS: enhance description about the -mount change
* NEWS (Changes in find): Clarify better what is the difference between
the -mount and -xdev options including an example.  Also move the
topic to the top of the section due to its importance.
2026-01-02 22:35:49 +01:00
Lukáš Zaoral
cd8568758a find: make -mount POSIX 2024 compliant
* find/defs.h (struct options): Add mount member and rename
stay_on_filesystem to xdev.
* find/ftsfind.c (find): Set FTS_MOUNT flag when -mount is enabled.
* find/parser.c (parse_table): Use a separate parser for -mount.
(parse_mount): Declare and define function.
(parse_xdev): Use xdev option flag.
* find/util.c (set_option_defaults): Initialize new struct members.
* doc/find.texi (node Filesystems): Add new section describing the new
behaviour of -mount and specify the current behaviour of -xdev.
* find/find.1: Document the new -mount behaviour and specify current
behaviour of -xdev.
* NEWS (Changes in find): Mention the -mount behaviour change.
2026-01-02 11:48:31 +01:00
Bernhard Voelker
733bb9a054 maint: update copyright year number ranges
Run 'make update-copyright'.

* lib/regexprops.c (copying): Update the year number manually.
* tests/sample-test: Adjust to use the single most recent year.
* All other files: Update copyright years via the above make run.
2026-01-02 11:46:15 +01:00
Bernhard Voelker
e69e78fb1d maint: update gnulib to latest
Run 'make update-gnulib-to-latest'; there have been 135 commits on gnulib
since the last update.
This is mainly for the following change making sc_copyright_check pass
again, but there are also other useful fixes and improvements:
  > maint: run 'make update-copyright'

* gnulib: Update to latest.
* autogen.sh: Likewise.
* autopull.sh: Likewise.
* bootstrap: Likewise.
* bootstrap-funclib.sh: Likewise.
2026-01-02 11:45:58 +01:00
James Youngman
580be65e25 [find] Format findutils changes as reverse-time-ordered tables.
* find/find.1 (COMPATIBILITY): Add release-year information to the
feature addition table.  Format the functional changes as a table,
too.
2025-11-18 09:49:21 +00:00
James Youngman
99cfb6cf42 [maint] Stricter manpage checks.
From a suggestion by G. Branden Robinson to use `groff -t -z -ww
-rCHECKSTYLE=2 -man`, by pointing to and example in
https://lists.gnu.org/archive/html/bug-findutils/2025-11/msg00004.html.

* configure.ac: discover the location of the groff binary.
* build-aux/man-lint.sh: also run groff with -rCHECKSTYLE=2.   Use
  groff at the path discovered during configuration.
* find/Makefile.am: Lint-check manpages during "make check",
  not "make dist". Set the environment variable GROFF to the
  location of the groff binary.
* locate/Makefile.am: Likewise.
* xargs/Makefile.am: Likewise.
2025-11-17 10:08:13 +00:00
James Youngman
c9a2aaa354 [find] Fix a lint problem in the find manual page.
Without this fix, we get this error from `groff -C -t -z -ww
-rCHECKSTYLE=2 -man find/find.1`:

troff: find/find.1:2255: warning: macro '."' not defined
troff: find/find.1:2255: warning: number register '[' not defined

* find/find.1: revert a change which caused a lint warning from
  troff.
2025-11-17 10:08:13 +00:00
James Youngman
8821923b49 [find] Use ASCII apostrophe in find.1 (instead of U+2019).
* find/find.1: Use ASCII apostrophe U+0027 instead of U+2019.
2025-11-17 10:08:13 +00:00
Bernhard Voelker
7156420fab maint: switch from gnulib ctype to ctype-h module
Prompted by the following bootstrap notice:
  Notice from module ctype:
    This module is deprecated. Use the module 'ctype-h' instead.

* bootstrap.conf (gnulib_modules): ctype -> ctype-h
2025-11-15 19:44:18 +01:00
Bernhard Voelker
bccc4f8a28 maint: update gnulib to latest
Run 'make update-gnulib-to-latest'; there have been 450 commits on gnulib
since the last update.

This pulls in the new FTS_MOUNT flag needed for the upcoming changes
to -mount vs. -xdev mandated by POSIX Issue 8 (IEEE Std 1003.1-2024),
thanks to Lukáš Zaoral <lzaoral@redhat.com>:
> fts: Introduce the FTS_MOUNT flag.

* gnulib: Update to latest.
* bootstrap-funclib.sh: Likewise.
2025-11-15 19:44:13 +01:00
Bernhard Voelker
c78d103e81 parser.c: simplify parse_table
Avoid macro preprocessing when filling the parse_table for better
readability.

* find/parser.c (PASTE, PARSE_OPTION, PARSE_POSOPT, PARSE_TEST,
PARSE_TEST_NP, PARSE_ACTION, PARSE_PUNCTUATION): Remove macros.
(parse_table): Replace macro-based filling with regular structure entries.
Group entries by types: regular options, positional options, punctuation,
tests and actions; loosely sort within each group.
Remove duplicate "atime" entry introduced in commit 7102a229fa.
While at it, change -help and -version from ARG_TEST to ARG_OPTION.
2025-11-15 19:43:35 +01:00
Bernhard Voelker
aa292af4c1 maint: help translators to disambiguate -0 as --null, not option "o"
As reported in <https://savannah.gnu.org/bugs/?67432>, it is easy to
confuse -0 with -O.  Give a hint to translators.

* xargs/xargs.c (main): Add TRANSLATORS hints.
2025-11-15 19:39:43 +01:00
Bernhard Voelker
9e505ec52f maint: add entry to .gitignore file
* po/.gitignore (/insert-header.sed): Add.
2025-11-15 19:39:43 +01:00
Bernhard Voelker
93ce19f0d5 maint: prefer C23-style nullptr
* bootstrap.conf (gnulib_modules): Add nullptr.
In code, prefer nullptr to NULL where either will do.
* cfg.mk (sc_prohibit_NULL): Direct to use nullptr instead.
(begword, endword): Add regex helper macros.
2025-11-15 19:39:43 +01:00
Bernhard Voelker
499e792fc0 maint: do not produce DVI-format manual anymore
The GNU standards don't require DVI-format documentation anymore:
https://lists.gnu.org/archive/html/bug-standards/2025-07/msg00011.html

* build-aux/update-online-manual.sh: Remove DVI format.
* doc/.gitignore: Remove ignore entries for DVI files.
2025-11-15 19:39:43 +01:00
Bernhard Voelker
deb3f7066d maint: use consistent references to standard files in messages
Use standard input instead of stdin, standard output instead of stdout,
and standard error instead of stderr in messages and documentation.
Inspired by coreutils commit:
https://cgit.git.sv.gnu.org/cgit/coreutils.git/commit/?id=c9a30d6781

* cfg.mk (sc_standard_outputs): Add syntax-check rule.
* doc/find.texi: Do the above.
* find/find.1: Likewise.
* locate/locate.1: Likewise.
* locate/locate.c: Likewise.
* xargs/xargs.1: Likewise.
* xargs/xargs.c: Likewise.
2025-11-15 19:39:43 +01:00
Bernhard Voelker
c41a617953 doc: clarify that POSIX Issue 8 is "IEEE Std 1003.1-2024"
* doc/find.texi: Do the above in various places.
* find/find.1:  Likewise.
* xargs/xargs.1: Likewise.
2025-11-15 19:39:43 +01:00
Bernhard Voelker
56a376a26d doc: state that POSIX from Issue 8 specifies 'find -iname'
* doc/find.texi (-iname): Document POSIX compliance.
* find/find.1 (COMPATIBILITY): Mark POSIX compliance of -iname.
2025-11-15 19:39:43 +01:00
Collin Funk
c18bba5c59 maint: ensure that new "make syntax-check"-run sc_codespell passes
* cfg.mk (codespell_ignore_words_list): Ignore false-positives.
(exclude_file_name_regexp--sc_codespell): Skip some file names.
* NEWS: Fix typos.
* README-hacking: Likewise.
* doc/find-maint.texi: Likewise.
* doc/find.texi: Likewise.
* bootstrap.conf: Fix typos in comments.
* find/ftsfind.c: Likewise.
* find/parser.c: Likewise.
* find/print.c: Likewise.
* find/testsuite/find.gnu/exec-one-rtn-fail.exp: Likewise.
* find/testsuite/find.posix/bracket-depth.exp: Likewise.
* find/testsuite/find.posix/exec-nogaps.exp: Likewise.
* find/testsuite/find.posix/files-not-expressions1.exp: Likewise.
* find/testsuite/find.posix/files-not-expressions2.exp: Likewise.
* find/testsuite/find.posix/files-not-expressions3.exp: Likewise.
* find/util.c: Likewise.
* init.cfg: Likewise.
* lib/regextype.h: Likewise.
* lib/splitstring.h: Likewise.
* locate/locate.c: Likewise.
* locate/updatedb.sh: Likewise.
* tests/find/exec-plus-last-file.sh: Likewise.
* tests/find/files0-from.sh: Likewise.
* tests/xargs/test-sigusr.c: Likewise.
* tests/xargs/verbose-quote.sh: Likewise.
* xargs/xargs.c: Likewise.
2025-11-15 19:39:02 +01:00
James Youngman
0cac25f6e7 doc: minor shell coding improvements in examples.
- Use -type f so that the timestamp of `subdir` is not relevant.
- Use LC_ALL=C with sort, tail, cut (as file names are not text).
- Use "$(...)" instead of just $(...).

Also mention that Issue 8 of the POSIX standard has been published
now.
2025-10-15 05:55:05 +01:00
James Youngman
cabfc3b184 find: point out that -newer is false when timestamps are equal. 2025-10-15 05:55:05 +01:00
Bernhard Voelker
74d25ac58d find: document -newerXY in --help output
* find/util.c (usage): Add above find(1) option, and briefly explain
that XY stands for the combination [aBcm][aBcmt].
2025-10-13 22:15:09 +02:00
Bernhard Voelker
1c39dc6055 find: fix minor typo in --help output
* find/util.c (usage): Terminate sentence about -D with a dot.
(show_valid_debug_options): While at it, add indentation for -D values.
2025-10-13 22:12:01 +02:00
danny mcClanahan
fbbda507c6 doc: fix typo in symbolics links node
* doc/find.texi (node Symbolic Links): s/directoires/directories/
* find/testsuite/find.gnu/execdir-hier.exp: Likewise here in a comment.

Copyright-paperwork-exempt: Yes
2025-08-24 14:19:50 +02:00
Bernhard Voelker
facc27e180 doc: regenerate regexprops.texi
* doc/regexprops.texi: Regenerate due to recent changes in gnulib regex.h
to align with current Emacs behavior (gnulib commit efd5c380ff), and also
due to the change of the node sort order in regextype.c in the previous
commit.

Reported by Collin Funk in
  https://lists.gnu.org/r/bug-gnulib/2025-07/msg00037.html
2025-07-09 20:53:21 +02:00
Bernhard Voelker
c9c2c51175 regexprops: sort regex_map alphabetically
Commit '1b53838ddf' has changed the order of the nodes, yet not
quite well.  Let's use alphabetical sort order.

* lib/regextype.c (regex_map): Move 'awk' and 'egrep' entries up.
2025-07-09 20:49:51 +02:00
Bernhard Voelker
c7f5ff1ed8 maint: update gnulib to latest
Run 'make update-gnulib-to-latest'; there have been 645 commits on gnulib
since the last update.

* gnulib: Update to latest.
* bootstrap: Likewise.
* bootstrap-funclib.sh: Likewise.
2025-07-09 08:55:51 +02:00
Bernhard Voelker
acd4564eda doc: reference -newer for -anewer,-cnewer in find.1
* find/find.1 (-anewer): Reference the similarity to -newer.
(-cnewer): Likewise.

Discussed at:
  https://sv.gnu.org/bugs/?67220
2025-07-01 19:38:20 +02:00
raf
1ef8d7c2cf doc: supplement list of actions that suppress default -print
* find/find.1 (EXPRESSION): Add missing -print0 and -fprint0 to
the list of actions that suppress the default -print action.
Sort items.
* doc/find.texi (find Expressions): Likewise.
* NEWS: Mention the fix.
2025-04-18 13:01:22 +02:00
Bernhard Voelker
bad1de52aa NEWS: mention the previous doc fixes
* NEWS (Documentation Changes): Describe the fix done by the two
previous commits.
2025-04-18 13:01:08 +02:00
Bernhard Voelker
97b8920482 doc: fix the "Finding the Shallowest Instance" example in find.1
* find/find.1 (EXAMPLES): Fix the Pruning SCM example by changing the
attribution of the list from "Sample output" to "Sample directories".
The wrong attribution was made in commit v4.7.0-76-g9302afb9.
Then, add the output for clarity.

Fixes https://sv.gnu.org/bugs/?62259
2025-04-18 13:00:07 +02:00
raf
45530ee875 doc: fix the "Finding the Shallowest Instance" example in Texinfo manual
* doc/find.texi (Finding the Shallowest Instance): Add surrounding \(
and \) around the 3x -exec actions to correctly group them with higher
priority than the implicit '-a' for the following '-print'.  Otherwise,
only the SCM roots matching the last test, "CVS", would be printed.
Improve indentation of the multi-line command.
Add sample output for clarity.
While at it, fix a minor typo.

This bug was present since adding that example in 2008.
The very same issue was already fixed for the man page in commit
v4.6.0-55-g47d8fd38.

Fixes https://sv.gnu.org/bugs/?62259
2025-04-18 12:56:23 +02:00
Bernhard Voelker
ee500667d4 tests: add case for passing -files0-from multiple times
Passing -files0-from several times silently overrides the previously given
file names, and only takes the last one.  This behavior is quite common
and has precedence e.g. in 'du --files0-from ...'.
Add a test to document the current behavior.

* tests/find/files0-from.sh: Add a test passing -files0-from 3 times.

Discussed at:
  https://sv.gnu.org/bugs/?66965
2025-04-06 16:49:12 +02:00
Bernhard Voelker
8e1331d8a7 NEWS: document the previous fixes in find.1
* NEWS (Documentation Changes): Mention the change of the previous commit.
2025-03-25 22:40:37 +01:00
Bjarni Ingi Gislason
2be6812e01 find.1: some remarks and editing fixes in the man page
Reported at:
  https://lists.gnu.org/r/bug-findutils/2025-03/msg00002.html

Output from "mandoc -T lint  find.1": (shortened list)

      1 input text line longer than 80 bytes: Some of the conversi...
      1 missing date, using "": TH
      1 unterminated quoted argument

-.-.

Output from "test-nroff -mandoc -t -ww -z find.1": (shortened list)

      1 	Use macro '.B' for one argument or split argument.
      1 	Use macro '.I' for one argument or split argument.
      1 .BR is for at least 2 arguments, got 1
      1 .IR is for at least 2 arguments, got 1

-.-.

Change a HYPHEN-MINUS (code 0x2D) to a minus(-dash) (\-),
if it
is in front of a name for an option,
is a symbol for standard input,
is a single character used to indicate an option,
or is in the NAME section (man-pages(7)).
N.B. - (0x2D), processed as a UTF-8 file, is changed to a hyphen
(0x2010, groff \[u2010] or \[hy]) in the output.

73:until an expression argument comes (which also starts with a `-').
74:Now, if a path argument would start with a `-', then
875:An exception to this is when using only a slash as \fIpattern\fR (`-name /'),
878:A warning is issued if you try to pass a pattern containing a - but not
879:consisting solely of one - slash, unless the environment variable
1095:The + and - prefixes signify greater than and less than, as usual;
1832:find / -name needle -print -quit
2252:.SS Safer `find -print0 | xargs -0` approach
2324:.SS Traversing the filesystem just once - for 2 different actions
2473:Pruning - omitting files and subdirectories
2590:.B $ find / -name needle -print -quit
2607:.B $ find . .. / /tmp /tmp/TRACE compile compile/64/tests/find -maxdepth 0 -printf '[%h][%f]\en'
2654:.B find -print0
2656:.B xargs -0
2743:find: possible unquoted pattern after predicate `-name'?

-.-.

Add a "\&" (or a comma (Oxford comma)) after "e.g." and "i.e.",
or use English words
(man-pages(7)).
Abbreviation points should be marked as such and protected against being
interpreted as an end of sentence, if they are not, and that independent
of the current place on the line.

546:and e.g. from a pipe.
565:The processing of the starting points is otherwise as usual, e.g.

-.-.

Wrong distance (not two spaces) between sentences in the input file.

  Separate the sentences and subordinate clauses; each begins on a new
line.  See man-pages(7) ("Conventions for source file layout") and
"info groff" ("Input Conventions").

  The best procedure is to always start a new sentence on a new line,
at least, if you are typing on a computer.

Remember coding: Only one command ("sentence") on each (logical) line.

E-mail: Easier to quote exactly the relevant lines.

Generally: Easier to edit the sentence.

Patches: Less unaffected text.

Search for two adjacent words is easier, when they belong to the same line,
and the same phrase.

  The amount of space between sentences in the output can then be
controlled with the ".ss" request.

Mark a final abbreviation point as such by suffixing it with "\&".

Some sentences (etc.) do not begin on a new line.

Split (sometimes) lines after a punctuation mark; before a conjunction.

  Lines with only one (or two) space(s) between sentences could be split,
so latter sentences begin on a new line.

Use

sed -e '/^\./n' \
-e 's/\([[:alpha:]]\)\.  */\1.\n/g' $1

to split lines after a sentence period.
Check result with the difference between the formatted outputs.
See also the attachment "general.bugs"

[List of affected lines removed.]

-.-.

Split lines longer than 80 characters into two or more lines.
Appropriate break points are the end of a sentence and a subordinate
clause; after punctuation marks.
Add "\:" to split the string for the output, "\<newline>" in the source.

Line 1546, length 86

Some of the conversion specification characters might not be available on all systems,

Line 2487, length 82

.B $ find . \-name .snapshot \-prune \-o \e( \e! \-name \(aq*~\(aq \-print0 \e) \e

Line 2607, length 96

.B $ find . .. / /tmp /tmp/TRACE compile compile/64/tests/find -maxdepth 0 -printf '[%h][%f]\en'

Line 2645, length 87

.I A Research UNIX Reader: Annotated Excerpts from the Programmer’s Manual, 1971-1986

-.-.

Use \(en (en-dash) for a dash at the beginning (end) of a line,
or between space characters,
not a minus (\-) or a hyphen (-), except in the NAME section.

find.1:2324:.SS Traversing the filesystem just once - for 2 different actions
find.1:2473:Pruning - omitting files and subdirectories

-.-.

Remove reverse slash (\) in front of a period (.) that is to be printed
as such, and can not come a control character in the first column of a line.
Use "\&" to protect the period to avoid that.
This is a sign, that the man page was transformed from another source
file with a program, whose name is NOT mentioned in a comment.

2715:\.B \-perm +MODE
2717:\.B \-perm

-.-.

Split a punctuation mark from a single argument for a two-font macro

1048:.IR ./fubar3,

-.-.

Put a parenthetical sentence, phrase on a separate line,
if not part of a code.
See man-pages(7), item "semantic newline".

[List of affected lines removed.]

-.-.

One space only after an end of sentence.

find.1:339:no error message will be issued. This is the reason why such operation
find.1:546:and e.g. from a pipe.
find.1:960:find . \-path \(dq./sr*sc\(dq
find.1:1797:find . \-path ./src/emacs \-prune \-o \-print
find.1:1896:.B find . \-name afile \-o \-name bfile \-print
find.1:2309:.B $ find . \-type f \-exec file \(aq{}\(aq \e;
find.1:2384:.B $ find . \-perm 664
find.1:2399:.B $ find . \-perm \-664
find.1:2413:.B $ find . \-perm /222
find.1:2423:.B $ find . \-perm /220
find.1:2424:.B $ find . \-perm /u+w,g+w
find.1:2425:.B $ find . \-perm /u=w,g=w
find.1:2440:.B $ find . \-perm \-220
find.1:2441:.B $ find . \-perm \-g+w,u+w
find.1:2452:.B $ find . \-perm \-444 \-perm /222 \e! \-perm /111
find.1:2453:.B $ find . \-perm \-a+r \-perm /a+w \e! \-perm /a+x
find.1:2467:.RB ( "! \-perm /111"
find.1:2469:.B ! \-perm /a+x
find.1:2487:.B $ find . \-name .snapshot \-prune \-o \e( \e! \-name \(aq*~\(aq \-print0 \e) \e
find.1:2607:.B $ find . .. / /tmp /tmp/TRACE compile compile/64/tests/find -maxdepth 0 -printf '[%h][%f]\en'
find.1:2727:.B find . \-name afile \-o \-name bfile \-print
find.1:2731:.BR "find . \-name afile \-o \e( \-name bfile \-a \-print \e)" .
find.1:2741:.B $ find . \-name *.c \-print
find.1:2754:.B find . \-name frcode.c locate.c word_io.c \-print
find.1:2766:.B $ find . \-name \(aq*.c\(aq \-print
find.1:2767:.B $ find . \-name \e*.c \-print

-.-.

Put a subordinate sentence (after a comma) on a new line.

[List of affected lines removed.]

-.-.

Remove quotes when there is a printable
but no space character between them
and the quotes are not for emphasis (markup),
for example as an argument to a macro.

find.1:638:.IP "\-noleaf"
find.1:1154:.IP "\-writable"
find.1:1196:.IP "\-delete\fR"
find.1:1802:.IP "\-quit"
find.1:2233:.SH "EXAMPLES"
find.1:2638:.SH "HISTORY"
find.1:2659:.SH "COMPATIBILITY"
find.1:2724:.SH "NON-BUGS"
find.1:2770:.SH "BUGS"

-.-.

Section headings (.SH and .SS) do not need quoting their arguments.

1968:.SH "STANDARDS CONFORMANCE"
2120:.SH "ENVIRONMENT VARIABLES"
2233:.SH "EXAMPLES"
2638:.SH "HISTORY"
2659:.SH "COMPATIBILITY"
2724:.SH "NON-BUGS"
2770:.SH "BUGS"
2788:.SH "REPORTING BUGS"
2811:.SH "SEE ALSO"

-.-.

Space after an end of sentence.

temp.table:25:\-exec ... +	4.2.12	POSIX

-.-.

Output from "test-groff  -mandoc -t -K utf8 -rF0 -rHY=0 -rCHECKSTYLE=10 -ww -z ":

an.tmac:<stdin>:2: style: .TH missing third argument; consider document modification date in ISO 8601 format (YYYY-MM-DD)
an.tmac:<stdin>:2: style: .TH missing fourth argument; consider package/project name and version (e.g., "groff 1.23.0")
an.tmac:<stdin>:690: misuse, warning: .BR is for at least 2 arguments, got 1
	Use macro '.B' for one argument or split argument.
an.tmac:<stdin>:1048: misuse, warning: .IR is for at least 2 arguments, got 1
	Use macro '.I' for one argument or split argument.

-.-.

Additionally:

  Change "1\ KB" to "1\ KiB"

  Change indent "4m" to "4n".  "4m" is too wide in troff-mode.

  Inhibit hyphenation of "strftime" once (based on an A4 page size).

  Create a "space" between some tags and the its following text by adding
" \&" to the tag.

  Decrease indent after a bullet in lists.

Generally:

Split (sometimes) lines after a punctuation mark; before a conjunction.

* find/find.1: Change as described above.
2025-03-25 21:57:29 +01:00
Bernhard Voelker
f3a3833320 maint: remove declared-only find_pred_name
Only user was inside a an #ifdef DEBUG / #endif block.
Introduced with -context in commit v4.5.5-42-g1a05af6a.

* find/parser.c (parse_context): Remove #ifdef/#endif block.
* find/defs.h (find_pred_name): Remove declaration.
2025-03-25 20:12:40 +01:00
Bernhard Voelker
dc3365628e find: issue a warning for wrongly accepted operators like '-!'
In the current implementation, GNU find accepts the operators '!', ',',
'(' and ')' with a leading dash, e.g. '-!'.
Let's issue a warning to see if anyone relies on that odd behavior.
With a later release, let's fix the parser, and not accept these anymore.

* find/parser.c (find_parser): Issue a warning in the case one of the
above operators has been passed with a leading '-'.
* tests/find/operators-wrong-with-dash.sh: Add test.
* tests/local.mk (sh_tests): Reference it.
* NEWS (Changes in find): Mention the change in behavior.

Discussed at:
https://lists.gnu.org/r/bug-findutils/2025-03/msg00005.html
2025-03-23 23:47:15 +01:00
Collin Funk
faa1301368 tests: adjust shell syntax that breaks AIX /bin/sh
* find/testsuite/find.gnu/execdir-multiple.exp: Move the 'do' of a for
loop to the same line so AIX doesn't fail.
2025-01-26 18:18:57 +01:00
Bernhard Voelker
e5d6eb919b find: avoid crash when diagnosing a file system loop
When gnulib's FTS returns FTS_DC indicating a directory cycle, then the
struct member 'fts_cycle' is not guaranteed to contain valid data.
Avoid dereferencing it when diagnosing the file system loop.

* find/ftsfind.c (issue_loop_warning): Change the error message to avoid
mentioning the other entry involved in the loop anymore.
(partial_quotearg_n): Remove now-unused function.
* NEWS (Bug Fixes): Mention the fix.

Reported by Dietmar Hahn in
<https://lists.gnu.org/r/bug-findutils/2025-01/msg00013.html>
2025-01-26 18:17:10 +01:00
Bernhard Voelker
d44172075a pred.c: consolidate numerical comparisons
Several predicate tests perform a numerical comparison based on the
comparison_type (COMP_GT, COMP_LT, COMP_EQ).
Factor that out into a utility function.

* find/pred.c (compare_num): Add static function.
(pred_gid, pred_inum, pred_links, pred_size, pred_uid): Use it.
2025-01-06 21:43:57 +01:00
Bernhard Voelker
0c20228608 xargs: clarify command as optional in --help output
* xargs/xargs.c (usage): Fix synopsis by wrapping COMMAND in '[...]',
because it is in fact optional.  Also add a sentence that the default
COMMAND is 'echo'.
2025-01-05 22:32:46 +01:00
Bernhard Voelker
85c67e9c3c doc: mention default command of xargs in 'Invoking xargs'
* doc/find.texi (node Invoking xargs): Add sentence about default
command 'echo'.

Reported by <toomas@rosin.ee> in
https://savannah.gnu.org/bugs/?66591
2025-01-05 22:00:00 +01:00
Bernhard Voelker
a465fc58bc maint: silence GCC-14 on utility source getlimits.c
Seen on GCC 14:
  getlimits.c:73:3: warning: stack-based buffer overflow [CWE-121] \
     [-Wanalyzer-out-of-bounds]
     73 |   sprintf (limit + 1, "%" "ju", (uintmax_t) TYPE##_MAX);     \
        |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
... while limit is defined more than large enough.

* find/getlimits.c: Add pragma for GCC version >= 14.
2025-01-05 21:23:25 +01:00
Bernhard Voelker
b52c6688ff maint: adjust to gnulib module renaming
Since previous gnulib update, './bootstrap' shows deprecation warnings
like the following for several modules:
  Notice from module errno:
    This module is deprecated. Use the module 'errno-h' instead.
Use the newer names instead:
- errno -> errno-h
- inttypes -> inttypes-h
- locale -> locale-h
- math -> math-h
- realloc-gnu -> realloc-posix
- stdarg -> stdarg-h
- stdbool -> bool
- stddef -> stddef-h
- stdint -> stdint-h
- stdio -> stdio-h
- stdlib -> stdlib-h
- string -> string-h
- sys_stat -> sys_stat-h
- sys_time -> sys_time-h
- sys_types -> sys_types-h
- sys_wait -> sys_wait-h
- wchar -> wchar-h

* bootstrap.conf (gnulib_modules): Do the above replacements.
2025-01-05 00:58:10 +01:00
Bernhard Voelker
7752c3da26 xargs: simplify error handling for gnulib's safe_read function
The gnulib/NEWS file states:
  SAFE_READ_ERROR and SAFE_WRITE_ERROR are now
  obsolescent; callers can just check for < 0.

* xargs/xargs.c (xargs_do_exec): Adjust error handling of safe_read
accordingly.
2025-01-04 20:04:15 +01:00
Bernhard Voelker
00e698e1b2 maint: update gnulib to latest
Run 'make update-gnulib-to-latest'; there have been 1127 commits on gnulib
since the last update.

* gnulib: Update to latest.
* bootstrap: Likewise.
* bootstrap-funclib.sh: Likewise.
* cfg.mk (exclude_file_name_regexp--sc_fsf_postal): Add to exempt the
script build-aux/src-sniff.py from this syntax-check.
2025-01-04 19:59:41 +01:00
Bernhard Voelker
f1f6471ae8 maint: update copyright year number ranges
Run 'make update-copyright'.

* lib/regexprops.c (copying): Update the year number manually.
* tests/sample-test: Adjust to use the single most recent year.
* All other files: Update copyright years via the above make run.
2025-01-04 11:43:53 +01:00
Christoph Anton Mitterer
a78812c62e doc: state that -execdir prepends the base names with "./"
The '{}' replacement done by the -execdir action prepends each entry,
i.e., the base names, with "./" unless for the root directory "/".

* doc/find.texi (-execdir): Document that behavior.
* find/find.1: Likewise.

Discussed at: https://sv.gnu.org/bugs/?66568

Copyright-paperwork-exempt: Yes
2024-12-24 14:07:30 +01:00
Bernhard Voelker
1da19bdba7 doc: maint: break lines at sentences in a paragraph to change
As the texinfo renderer is caring about proper layout, we can let sentences
start at the beginning of the line, thus making further changes easier
to review.

* doc/find.texi (-execdir): Break lines at the end of sentences.
2024-12-24 13:35:10 +01:00
Bernhard Voelker
00e82f2c15 maint: fix typo in comment
* find/exec.c (impl_pred_exec): Add '-' to 'execdir' example in comment.
2024-12-24 10:30:08 +01:00
Bernhard Voelker
324b5dddc2 maint: pull in gnulib module basename-lgpl
* bootstrap.conf (gnulib_modules): Add 'basename-lgpl', because we're
using the gnulib 'base_name' function.
2024-12-23 21:00:51 +01:00
Bernhard Voelker
aff4e48c11 find: ignore more vanished subdirectories with -ignore_readdir_race
Similar to commit 889d001ab750 which handles vanished files better,
also fix the race for subdirectories (FTS_DNR).

Reproducer:
In average, the following produced 6-10 failures out of 1000 runs:
  $ mkdir testdir
  $ while :; do mkdir testdir/foo; rmdir testdir/foo; done &
  $ for f in $(seq 1000); do \
      find testdir -ignore_readdir_race -ls ; done >/dev/null
  find: 'testdir/foo': No such file or directory
  find: 'testdir/foo': No such file or directory

* find/ftsfind.c (consider_visiting): Return when FTS returned ENOENT
for FTS_DNR, i.e., unreadable directory, with -ignore_readdir_race.
* tests/find/readdir_race.sh: Add test.
* tests/local.mk (sh_tests): Reference it.
* NEWS (Bug Fixes): Amend and improve description of the previous fix.

See also https://savannah.gnu.org/bugs/?45930
2024-12-23 12:59:24 +01:00
Bernhard Voelker
eac8aecaad maint: update further Makefile variables used by Gnulib
Like in the recent commit, also change the following variables to follow
the renaming done in gnulib:
- LIB_SETLOCALE_NULL -> SETLOCALE_NULL_LIB,
- LIB_MBRTOWC -> MBRTOWC_LIB,
- LIB_EACCESS -> EUIDACCESS_LIBGEN.

* find/Makefile.am (LDADD): Change as described above.
* lib/Makefile.am: Likewise.
* locate/Makefile.am: Likewise.
* xargs/Makefile.am: Likewise.
2024-12-02 19:54:19 +01:00
Collin Funk
e65a91d2fb maint: update Makefile variables used by Gnulib
* locate/Makefile.am (LDADD): Remove $(LIB_CLOSE) as it is no longer
required per Gnulib NEWS 2009-03-20.
* xargs/Makefile.am (LADD): Likewise.
* find/Makefile.am (LDADD): Likewise. Change $(LIB_EACCESS) to
$(EUIDACCESS_LIBGEN) per Gnulib NEWS 2023-01-07.
2024-12-02 19:54:19 +01:00
Collin Funk
5db475b306 maint: don't use gettimeofday
POSIX marked gettimeofday obsolete in POSIX.1-2017 and removed it in
POSIX.1-2024. Prefer Gnulib functions which use nanosecond resolution if
supported by the operating system.

* bootstrap.conf (gnulib_extra_files): Remove gettimeofday. Add gettime.
* find/util.c (now): Remove function.
(set_option_defaults): Use current_timespec.
* find/Makefile.am (LDADD): Rename $(LIB_CLOCK_GETTIME) to
$(CLOCK_TIME_LIB) per Gnulib NEWS 2023-01-07.
2024-12-02 19:54:19 +01:00
Bernhard Voelker
ea9288c6be doc: fix typo in Texinfo manual
* doc/find.texi (node Leaf Optimisation): s/filssytems/filesystems/
Bug introduced in v4.5.10-9-gb28cc8c4 in 2011.

Reported by <firasuke@gmail.com> in
https://savannah.gnu.org/bugs/?66418
2024-11-10 16:35:17 +01:00
Bernhard Voelker
baab958700 maint: remove unused include from fstype.c
With newer gnulib, the sc_prohibit_always_true_header_tests check
fails with:
  find/fstype.c:30:#if HAVE_MNTENT_H
  maint.mk: do not test the above HAVE_<header>_H symbol(s);
    with the corresponding gnulib module, they are always true
  make: *** [maint.mk:969: sc_prohibit_always_true_header_tests] Error 1

* find/fstype.c (#include <mntent.h>): Remove as it is not actually used.
2024-11-03 21:32:35 +01:00
Bernhard Voelker
744da6ddcc maint: prefer endian.h for byte order conversions
Now that <endian.h> is a part of POSIX 2024 it should become more
portable than <byteswap.h>.

* bootstrap.conf (gnulib_modules): Remove byteswap; add endian.
* locate/word_io.c: Include endian.h instead of byteswap.h.
(decode_value): Use htobe32 instead of bswap_32.
2024-11-03 21:32:30 +01:00
Bernhard Voelker
f4ec39eee0 maint: import tests/init.sh from Gnulib during bootstrap
* bootstrap.conf (bootstrap_post_import_hook): Use gnulib-tool
--copy-file to import tests/init.sh.
* tests/init.sh: Remove file.
* tests/.gitignore (/init.sh): Add entry.
* Makefile.am (update-gnulib-to-latest): Remove handling tests/init.sh.
2024-11-03 21:32:17 +01:00
Bernhard Voelker
d0187016e1 maint: list Gnulib sys_types directly
* bootstrap.conf (gnulib_modules): Add sys_types.
Although it’s already brought in indirectly, findutils code
includes <sys/types.h> directly.
2024-11-03 21:32:08 +01:00
Bernhard Voelker
57fb016b73 maint: add NEWS entry for recent 'find -execdir/-okdir' change
* NEWS (Changes in find): Reflect the change in behavir in recent
commit v4.10.0-15-g1dcdf3de.
2024-11-03 21:14:37 +01:00
Bernhard Voelker
2ef0b4ce38 maint: fix indentation in NEWS
* NEWS: Use 2 char indentation.
2024-11-03 21:09:51 +01:00
Bernhard Voelker
128c5b18c9 maint: make tests/sample-test executable
To avoid that new tests copied from the template sample-test lack the
executable bit, add the executable bit to that file.

* tests/sample-test: Set executable permission bit.
2024-11-03 20:04:48 +01:00
Bernhard Voelker
727d261bb8 maint: make new tests/find/sv-bug-66365-exec.sh executable
'make syntax-check' fails with:
  tests_executable
  maint.mk: Please make test executable: tests/find/sv-bug-66365-exec.sh
  make: *** [cfg.mk:129: sc_tests_executable] Error 1

* tests/find/sv-bug-66365-exec.sh: Set executable permission bit.
2024-11-03 20:04:42 +01:00
James Youngman
1dcdf3de8e find: -exec is terminated by + only if the prior arg is exactly '{}'
A "+" only terminates -exec when it immediately follows an argument
which is exactly "{}" (and not, for example, "{}x").  This fixes
Savannah bug 66365.

* NEWS: explain this change.
* doc/find.texi: update one place which omitted the '{}' before '+'.
* find/parser.c (insert_exec_ok): consider + to be special ony if it
  follows an argument which is exactly '{}'.
* tests/find/sv-bug-66365-exec.sh: test for this bug.
* tests/local.mk: add the new test file.
2024-11-02 18:42:35 +00:00
James Youngman
457acfa06b Fix VPATH compilation failure for 'make check'
The libgnulib.a library isn't (necessarily) below $(top_srcdir), it's
below $(top_builddir).  This fixes a bug introduced in commit
85fc8966e5912390ad220d03b188dd319c85ed1e.
2024-10-31 15:29:07 +00:00
Bernhard Voelker
e38e2f8a36 tests: avoid -Wshadow warning
Seen on GCC 14.2.0:

tests/xargs/test-sigusr.c: In function 'run_xargs':
tests/xargs/test-sigusr.c:159:43: warning: declaration of 'optarg' \
  shadows a global declaration [-Wshadow]
  159 | run_xargs(const char *option, const char *optarg, int send_signal)
      |                               ~~~~~~~~~~~~^~~~~~
  ...
  /usr/include/bits/getopt_core.h:36:14: note: shadowed declaration is here
   36 | extern char *optarg;
      |              ^~~~~~

* tests/xargs/test-sigusr.c (run_xargs): Rename 'optarg' parameter
to 'opt_arg'.
2024-09-17 22:46:58 +02:00
Bernhard Voelker
523043b313 maint: avoid using FSF postal address
The postal address of the FSF has changed from Franklin Street to
Milk Street in Boston, yet according to RMS we shall better avoid
the postal address.

* build-aux/update-online-manual.sh (Copyright): Change from postal
address to the FSF URL.
2024-09-17 21:50:11 +02:00
Bernhard Voelker
f65a2a960f maint: adjust to Gnulib -Wsystem-headers change
* configure.ac: Don’t suppress -Wsystem-headers since Gnulib no
longer enables it.

Borrowed from
  https://git.sv.gnu.org/cgit/coreutils.git/commit/?id=94e8f2b012eb
2024-09-17 21:49:56 +02:00
Bernhard Voelker
4a719e65d2 maint: pacify GCC 14.2
Avoid the following warnings:
tree.c:1573:19: warning: no previous declaration for 'cost_table' [-Wmissing-variable-declarations]
 1573 | struct cost_assoc cost_table[] =
      |                   ^~~~~~~~~~
findutils-version.c:37:13: warning: no previous declaration for 'version_string' [-Wmissing-variable-declarations]
   37 | const char *version_string = VERSION;
      |             ^~~~~~~~~~~~~~

* find/tree.c (cost_table): Declare static.
* lib/findutils-version.c (version_string): Likewise.
* locate/frcode.c (version_string): Remove extern declaration.
* locate/locate.c: Likewise.
* xargs/xargs.c: Likewise.
2024-09-17 21:49:18 +02:00
Bernhard Voelker
889d001ab7 find: ignore more vanished entries with -ignore_readdir_race
Reproducer:
  # Spin up lots of short-living processes.
  $ while env true; do sleep .001; done &

  # Invoke 'find' on the /proc file system;
  # this pretty reliably gives the following error:
  $ find /proc -ignore_readdir_race -maxdepth 3 > /dev/null
  find: '/proc/845078': No such file or directory

* find/ftsfind.c (consider_visiting): Return when FTS returned ENOENT
with the option -ignore_readdir_race.
* NEWS (Bug Fixes): Mention the fix.

Fixes https://savannah.gnu.org/bugs/?45930
2024-09-17 21:49:00 +02:00
Dave
07bd7fa675 build: add bison as requirement
Building from git without bison available would result in
  cc1: fatal error: ./parse-datetime.c: No such file or directory
which is not a very helpful error message.
Let gnulib bootstrap check for bison much earlier.

* README-hacking (Prerequisites): Add Bison explicitly.
* bootstrap.conf (buildreq): Add bison.
* cfg.mk (bootstrap-tools): Add gnulib variable with tools including
bison.

Co-authored-by: Bernhard Voelker <mail@bernhard-voelker.de>
Copyright-paperwork-exempt: Yes
2024-09-17 21:44:33 +02:00
Collin Funk
85fc8966e5 tests: link binaries to gnulib
* tests/local.mk (AM_CPPFLAGS): Include gnulib headers.
(LDADD): Link to gnulib.

Copyright-paperwork-exempt: Yes
2024-06-24 14:35:55 +02:00
Bernhard Voelker
b94986a897 doc: avoid sc_prohibit_unhyphenated_eof failure
'make syntax-check' complains:
  maint.mk: use "end-of-file", not "end of file"
  make: *** [cfg.mk:273: sc_prohibit_unhyphenated_eof] Error 1

* doc/find.texi (xargs options): Change as suggested by the SC rule.
2024-06-24 14:33:09 +02:00
James Youngman
76ddbb913e doc: State that find -print0 and xargs -0 are in POSIX from Issue 8.
The forthcoming Issue 8 of the POSIX standard includes find -print0
and xargs -0.
* doc/find.texi: find -print0 is no longer GNU-specific.  Similarly
for xargs -0.
* xargs/xargs.1: Likewise.
* NEWS: mention these changes.
2024-06-03 12:40:42 +01:00
James Youngman
bb13ef8f93 find: mention when -print0 was introduced.
* find/find.1(COMPATIBILITY): mention that -print0 was introduced in
release 2.0 and is planned for inclusion in POSIX Issue 8.
2024-06-03 12:16:55 +01:00
James Youngman
1c8f85de97 maint: prohibit the use of tabs in Findutils C sources.
This check does not apply to gnulib code.
* cfg.mk (sc_spaces_not_tabs): add syntax check prohibiting
the use of tabs in Findutils code.
* build-aux/tabs-to-spaces.sh: Add small tool for converting
source file tabs to spaces.
2024-06-01 21:41:11 +01:00
James Youngman
e178314ae3 maint: convert tabs to spaces in C source files. 2024-06-01 21:41:05 +01:00
Bernhard Voelker
c8fd333368 maint: post-release administrivia
* NEWS: Add new dummy release header.
2024-06-01 19:19:31 +02:00
139 changed files with 6795 additions and 6685 deletions

View File

@ -1,6 +1,6 @@
# Make findutils.
# Copyright (C) 1996-2024 Free Software Foundation, Inc.
# Copyright (C) 1996-2026 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -111,14 +111,8 @@ gnulib-sync update-gnulib-to-latest:
&& git submodule foreach git pull origin master \
&& cp -v gnulib/doc/COPYINGv3 COPYING \
&& cp -v gnulib/doc/fdl.texi doc/fdl.texi \
&& cp -v gnulib/top/autogen.sh autogen.sh \
&& cp -v gnulib/top/autopull.sh autopull.sh \
&& cp -v gnulib/top/bootstrap bootstrap \
&& cp -v gnulib/top/bootstrap-funclib.sh bootstrap-funclib.sh \
&& cp -v gnulib/tests/init.sh tests/init.sh \
&& git status --short -- gnulib COPYING doc/fdl.texi autogen.sh \
autopull.sh bootstrap bootstrap-funclib.sh tests/init.sh \
tests/init.sh \
&& cp -v gnulib/build-aux/bootstrap bootstrap \
&& git status --short -- gnulib COPYING doc/fdl.texi bootstrap \
)
# Clean coverage files generated by running binaries built with gcc

86
NEWS
View File

@ -1,5 +1,59 @@
GNU findutils NEWS - User visible changes. -*- outline -*- (allout)
* Noteworthy changes in release ?.? (????-??-??) [?]
** Bug Fixes
find no longer crashes when diagnosing a directory cycle (without a symlink
being involved pointing to a parent directory).
[Bug present since the FTS implementation.]
'find -ignore_readdir_race' now better handles races between FTS reading a
directory and visiting its entries when the file or directory was meanwhile
removed. [#45930]
To fix a POSIX compatibility bug, -exec foo Z{} + is no longer a
complete predicate, because '+' is only a terminator when it follows
an argument which is exactly '{}'. The findutils documentation
already states this, and now find's behaviour matches the
documentation.
** Changes in find
As announced since the release of 4.7.0 (2019) and mandated by POSIX 2024,
the behaviour of the -mount option changed: while it was a mere alias for
the -xdev option to prevent descending into directories of another device,
the -mount option now makes find(1) ignore files on another device, i.e.,
'find -mount' will skip the entry of active mount points already.
Example, assuming the PROC filesystem is mounted on '/proc':
$ find / -mount -path /proc -print
$ find / -xdev -path /proc -print
/proc
[#54745]
The actions -execdir and -okdir now refuse the '{}' replacement in the zeroth
argument of the command to be run. While POSIX allows this for -exec, this is
deemed insecure as an attacker could influence which files could be found.
find now issues a warning when the punctuation operators '(', ')', '!' and ','
are passed with a leading dash, e.g. '-!'. Future releases will not accept
that any more. Accepting that was rather a bug "since the beginning".
** Documentation Changes
The forthcoming Issue 8 of the POSIX standard will standardise "find
-print0" and "xargs -0". Our documentation now points this out.
The code example for "Finding the Shallowest Instance" in the Texinfo manual
and the corresponding one in the EXAMPLES section in the find.1 man page have
been fixed. [#62259]
Translators contributed numerous fixes for issues in the find.1 man page.
The list of actions that suppress the default -print action has been
supplemented with the missing '-print0' and '-fprint0' actions.
* Noteworthy changes in release 4.10.0 (2024-06-01) [stable]
** Bug Fixes
@ -472,7 +526,7 @@ posix-egrep. This is the result of a change to gnulib to bring it
into line with GNU grep (see https://debbugs.gnu.org/20974#22).
** Translations
Updated translations: Estonian, Swedish, Polish, Vietnamese, Ukranian,
Updated translations: Estonian, Swedish, Polish, Vietnamese, Ukrainian,
Norwegian Bokmaal, Czech, Russian, French, Hungarian.
** Bug Fixes:
@ -501,7 +555,7 @@ Norwegian Bokmaal, Czech, Russian, French, Hungarian.
#45062: Enabling CACHE_IDS causes segfaults (this bug affects many
historic releases, probably since release 3.0 in 1991). You
would not have been affected by this problem unless you used
the option --enable-id-cache when invoking confgure.
the option --enable-id-cache when invoking configure.
#42903: checklists.py now supports Python 3.
@ -549,7 +603,7 @@ Some minor documentation improvements are listed in "Bug Fixes" below.
** Translations
Updated translations: Estonian, Polish, Ukranian.
Updated translations: Estonian, Polish, Ukrainian.
* Major changes in release 4.5.12, 2013-09-22
@ -648,7 +702,7 @@ For example use "xargs /bin/echo < foo" rather than "xargs < foo".
A new option is provided, --process-slot-var. If you set this, xargs
will set the indicated environment variable in each child. The values
are re-used, but no executing child process will have the same value
are reused, but no executing child process will have the same value
as another executing child process. This wishlist item was Savannah
bug #29512.
@ -678,7 +732,7 @@ expression types selected by the -regextype option have slightly
changed, to bring them into line with the behaviour of the GNU C
library. For "awk", character classes (such as [[:digit:]]) are now
supported. For "gnu-awk" and "posix-awk", intervals are supported and
invalid interval specifcations are treated as literals (for example
invalid interval specifications are treated as literals (for example
'a{1' is treated as 'a\{1').
@ -761,7 +815,7 @@ Updated Vietnamese, Czech, Dutch, Polish, Russian translations.
** Performance changes
If you use the -fstype FOO predicate and specify a filsystem type FOO
If you use the -fstype FOO predicate and specify a filesystem type FOO
which is not known (e.g. present in /etc/mtab) at the time find
starts, that predicate is now equivalent to -false. This substitution
currently occurs at optimisation level 2 and above.
@ -837,7 +891,7 @@ in the text).
#22708: Exit status 126 and 127 from the utility invoked from xargs
now makes xargs return 123, meaning that exit status values 126 and
127 now unambigously mean that the utility could not be run or could
127 now unambiguously mean that the utility could not be run or could
not be found, respectively.
** Documentation Changes
@ -877,13 +931,13 @@ unknown user or is missing.
#25154: Allow compilation with C compilers that don't allow
declarations to follow statements.
#24342: -inum predicate shoud use dirent.d_ino instead of stat.st_ino
#24342: -inum predicate should use dirent.d_ino instead of stat.st_ino
(this is a performance bug).
** Translations
Updated translations for Bulgarian, German, Irish, Hungarian,
Lithuanian, Dutch, Polish, Slovenian, Swedish, Turkish, Ukranian,
Lithuanian, Dutch, Polish, Slovenian, Swedish, Turkish, Ukrainian,
Vietnamese.
** Documentation Changes
@ -901,7 +955,7 @@ The file README-CVS has been renamed to README-hacking and improved.
Changes to gnulib's fts code should provide performance improvements
in find when processing very large directories (for example
directories containing significantly more than 10000 filenames).
Performance imporvements may only exist for some find command lines
Performance improvements may only exist for some find command lines
(performance testing was done for the fts implementation itself but
we haven't done the analogous performance tests in find).
@ -1364,7 +1418,7 @@ servers.
#11668: FreeBSD extensions for time specification are now
implemented. In fact, these were included in findutils-4.3.3. The
change was listed as a functional change (whcih it is) and this bug
change was listed as a functional change (which it is) and this bug
report was not mentioned.
** Documentation Fixes
@ -1589,7 +1643,7 @@ problem was worse for -exec.
Savannah bug #16579: Updatedb now works if it is running as a user
whose login shell is not actually a shell.
There have also been a number of documentation improvements (includng
There have also been a number of documentation improvements (including
Savannah bug #16269).
** Functional changes
@ -1909,7 +1963,7 @@ Some typos in the manual pages have been fixed. Various parts of the
manual now point out that it is good practice to quote the argument of
"-name". The manpage now has a "NON-BUGS" section which explains some
symptoms that look like bugs but aren't. The explanations of the "%k"
and "%b" directives to "find -printf" have been imrpoved.
and "%b" directives to "find -printf" have been improved.
* Major changes in release 4.2.21, 2005-06-07
@ -2125,7 +2179,7 @@ New Vietnamese message translation.
have it.
*** Bugfix to the findutils 4.2.6 automount handling (which hadn't been enabled
on Solaris).
*** Reenabled internationalisation support (which had been accidentally
*** Re-enabled internationalisation support (which had been accidentally
disabled in findutils-4.2.5).
* Major changes in release 4.2.6, 2004-11-21
@ -2163,7 +2217,7 @@ New Vietnamese message translation.
*** If you specify a 'find' option after non-option, a warning message
is now issued. Options should be specified immediately after the
list of paths to search. These warnings are enabled if you
specify the -warn option, or if stdin is a tty. They are diabled
specify the -warn option, or if stdin is a tty. They are disabled
by the use of the -nowarn option.
*** Like find, the locate program now supports an option --null (short form -0)
which changes the result separator from newline to NULL.
@ -2396,7 +2450,7 @@ LocalWords: strncasecmp strcasecmp LIBOBJS FUNC prunefs allout libexec
LocalWords: testsuite Texinfo chdir inode fstype afs fls ls EOF lname
LocalWords: regex ilname iname ipath iregex printf fprintf
Copyright (C) 1996-2024 Free Software Foundation, Inc.
Copyright (C) 1996-2026 Free Software Foundation, Inc.
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or

2
README
View File

@ -100,7 +100,7 @@ We are looking forward to hacking with you!
========================================================================
Copyright (C) 1996-2024 Free Software Foundation, Inc.
Copyright (C) 1996-2026 Free Software Foundation, Inc.
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or

View File

@ -14,6 +14,7 @@ Prerequisites
on a POSIX system should work.
* GNU Autoconf
* GNU Automake
* GNU Bison
* GNU m4
* GNU gettext
* GNU Dejagnu
@ -105,7 +106,7 @@ proc_max.
MAX_PROC_MAX.
--- example ends ---
There are several things to notice about this checkin message. Most
There are several things to notice about this check-in message. Most
importantly, it begins with a single line summary of the whole change.
This needs to be short. It would be used as the subject line of
patches mailed by "git send-email". Some people begin that line with
@ -248,7 +249,7 @@ In case you're wondering why we bother with all of this, read this:
========================================================================
Copyright (C) 2009-2024 Free Software Foundation, Inc.
Copyright (C) 2009-2026 Free Software Foundation, Inc.
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or

2
TODO
View File

@ -86,7 +86,7 @@ LocalWords: findutils Debian cron
-----
Copyright (C) 1996-2024 Free Software Foundation, Inc.
Copyright (C) 1996-2026 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@ -1,39 +0,0 @@
#!/bin/sh
# Convenience script for regenerating all autogeneratable files that are
# omitted from the version control repository. In particular, this script
# also regenerates all aclocal.m4, config.h.in, Makefile.in, configure files
# with new versions of autoconf or automake.
# Copyright (C) 2003-2024 Free Software Foundation, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
# Originally written by Paul Eggert. The canonical version of this
# script is maintained as top/autogen.sh in gnulib. However, to be
# useful to your package, you should place a copy of it under version
# control in the top-level directory of your package. The intent is
# that all customization can be done with a bootstrap.conf file also
# maintained in your version control; gnulib comes with a template
# build-aux/bootstrap.conf to get you started.
#
# Alternatively, you can use an autogen.sh script that is specific
# to your package.
me="$0"
medir=`dirname "$me"`
# Read the function library and the configuration.
. "$medir"/bootstrap-funclib.sh
autogen "$@"

View File

@ -1,37 +0,0 @@
#!/bin/sh
# Convenience script for fetching auxiliary files that are omitted from
# the version control repository of this package.
# Copyright (C) 2003-2024 Free Software Foundation, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
# Originally written by Paul Eggert. The canonical version of this
# script is maintained as top/autopull.sh in gnulib. However, to be
# useful to your package, you should place a copy of it under version
# control in the top-level directory of your package. The intent is
# that all customization can be done with a bootstrap.conf file also
# maintained in your version control; gnulib comes with a template
# build-aux/bootstrap.conf to get you started.
#
# Alternatively, you can use an autopull.sh script that is specific
# to your package.
me="$0"
medir=`dirname "$me"`
# Read the function library and the configuration.
. "$medir"/bootstrap-funclib.sh
autopull "$@"

1398
bootstrap

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
# Bootstrap configuration.
# Copyright (C) 2006-2024 Free Software Foundation, Inc.
# Copyright (C) 2006-2026 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -55,7 +55,7 @@ gendocs
# consider using gendocs
# consider using sig2str in xargs
# consider using signal (why not: maybe we don't need those features)
# consider using the dev-ino moduile to support -samefile.
# consider using the dev-ino module to support -samefile.
# consider removing stpcpy
# We have rpmatch, either use it for -ok and xargs or remove the dependency
@ -76,20 +76,22 @@ gnulib_modules="
argmatch
argv-iter
assert
byteswap
basename-lgpl
bool
c-strcasestr
c-strstr
canonicalize
cloexec
closein
closeout
ctype
ctype-h
d-ino
d-type
dirent-safer
dirname
dup2
errno
endian
errno-h
error
faccessat
fchdir
@ -107,7 +109,7 @@ gnulib_modules="
getline
getopt-gnu
gettext-h
gettimeofday
gettime
git-version-gen
gnupload
gpl-3.0
@ -116,13 +118,13 @@ gnulib_modules="
idcache
inline
intprops
inttypes
inttypes-h
isblank
locale
locale-h
lstat
malloc-gnu
manywarnings
math
math-h
mbrtowc
mbscasestr
mbswidth
@ -140,7 +142,7 @@ gnulib_modules="
progname
quotearg
readlink
realloc-gnu
realloc-posix
regex
rpmatch
safe-read
@ -153,22 +155,22 @@ gnulib_modules="
stat-macros
stat-size
stat-time
stdarg
stdbool
stddef
stdio
stdint
stdlib
stdarg-h
stddef-h
stdio-h
stdint-h
stdlib-h
stpcpy
strcasestr
strdup-posix
string
string-h
strndup
strtoull
strtoumax
sys_stat
sys_time
sys_wait
sys_stat-h
sys_time-h
sys_types-h
sys_wait-h
timespec
uname
unistd-safer
@ -177,7 +179,7 @@ gnulib_modules="
version-etc
version-etc-fsf
warnings
wchar
wchar-h
wcwidth
xalloc
xalloc-die
@ -203,7 +205,7 @@ gnulib_name=libgnulib
# Create 'gl/Makefile.am' which is mentioned in 'configure.ac'.
hack_gnulib_tool_makefile() {
cat > gl/Makefile.am <<EOF
# Copyright (C) 2006-2024 Free Software Foundation, Inc.
# Copyright (C) 2006-2026 Free Software Foundation, Inc.
#
# This file is free software, distributed under the terms of the GNU
# General Public License. As a special exception to the GNU General
@ -221,7 +223,10 @@ EOF
# after 'gnulib-tool' is done, create the 'gl/Makefile.am' to be backward
# compatible with 'import-gnulib.sh'.
bootstrap_post_import_hook() {
hack_gnulib_tool_makefile
hack_gnulib_tool_makefile
# Copy tests/init.sh from Gnulib.
$gnulib_tool --copy-file tests/init.sh
}
# For compatibility with 'import-gnulib.sh', add gnulib's test directory.
@ -273,6 +278,7 @@ buildreq="\
autoconf 2.64
automake 1.11.2
autopoint 0.19.2
bison -
gettext 0.19.2
git 1.5.5
m4 -

View File

@ -1,4 +1,4 @@
# Copyright (C) 2007-2024 Free Software Foundation, Inc.
# Copyright (C) 2007-2026 Free Software Foundation, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by

View File

@ -1,6 +1,6 @@
#! /bin/sh
# check-testfiles.sh -- Check we distributed all the test files we need
# Copyright (C) 2007-2024 Free Software Foundation, Inc.
# Copyright (C) 2007-2026 Free Software Foundation, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by

View File

@ -1,7 +1,7 @@
#! /bin/sh
# Generate the ChangeLog for findutils.
# Copyright (C) 2015-2024 Free Software Foundation, Inc.
# Copyright (C) 2015-2026 Free Software Foundation, Inc.
# Written by James Youngman.
#
# This program is free software: you can redistribute it and/or modify

View File

@ -1,5 +1,5 @@
#! /bin/sh
# Copyright (C) 2007-2024 Free Software Foundation, Inc.
# Copyright (C) 2007-2026 Free Software Foundation, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -14,20 +14,60 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
rv=0
case "${GROFF}" in
:)
echo "groff is not installed, so we cannot check manual pages. Continuing without checking them." >&2
exit 0
;;
"")
echo "The GROFF environment is not set; this is normally set when invoking this command from the Makefile; assuming GNU groff is at 'groff'." >&2
GROFF=groff
;;
*)
;;
esac
srcdir="$1" ; shift
for manpage
do
what="lint check on manpage $manpage"
echo -n "$what: "
messages="$( groff -t -man ${srcdir}/${manpage} 2>&1 >/dev/null )"
if test -z "$messages" ; then
echo "passed"
else
echo "FAILED:" >&2
echo "$messages" >&2
rv=1
fi
done
exit $rv
fixed_width_context_message_without_newline() {
printf '%-45s (%15s): ' "$1" "$2"
}
check_manpages_format_without_error_messages() {
for manpage
do
fixed_width_context_message_without_newline \
'check_manpages_format_without_error_messages' "${manpage}"
messages="$( ${GROFF} -t -man ${srcdir}/${manpage} 2>&1 >/dev/null )"
if test -z "$messages"
then
printf 'OK\n'
else
printf 'FAILED\n%s\n' "$messages" >&2
return 1
fi
done
return 0
}
check_manpages_with_groff_checkstyle_2() {
for manpage
do
fixed_width_context_message_without_newline \
'check_manpages_with_groff_checkstyle_2' "${manpage}"
messages="$( ${GROFF} -t -z -ww -rCHECKSTYLE=2 -man ${srcdir}/${manpage} 2>&1 )"
if test -z "$messages"
then
printf 'OK\n'
else
printf 'FAILED\n%s\n' "$messages" >&2
return 1
fi
done
return 0
}
rv=0
check_manpages_format_without_error_messages "$@" &&
check_manpages_with_groff_checkstyle_2 "$@"

View File

@ -1,7 +1,7 @@
#! /usr/bin/env python
# src-sniff.py: checks source code for patterns that look like common errors.
# Copyright (C) 2007-2024 Free Software Foundation, Inc.
# Copyright (C) 2007-2026 Free Software Foundation, Inc.
#
#
# This program is free software: you can redistribute it and/or modify

108
build-aux/tabs-to-spaces.sh Normal file
View File

@ -0,0 +1,108 @@
#! /bin/sh
# You might use this tool like this:
#
# sh build-aux/tabs-to-spaces.sh check $( find find lib locate tests xargs -regextype posix-extended -regex '.*[.]([ch]|cc)$' )
set -u
error() {
echo "$@" >&2
exit 1
}
cleanup() {
if ! rm -f "$@"
then
error "failed to delete temporary file(s) $@"
return 1
fi
}
usage_error() {
error "Please specify a sub-command (either 'check' or 'fix')."
}
make_expanded_file() {
if output="$(mktemp)"
then
expand -- "$1" > "${output}" && echo "${output}"
else
error 'failed to create temporary file'
fi
}
check() {
result=0
for input
do
if expanded="$(make_expanded_file ${input})"
then
cmp -s -- "${input}" "${expanded}"
rv="$?"
if ! cleanup "${expanded}"
then
return 1
fi
case "$rv" in
0) ;;
1) echo "${input} is incorrectly formatted (it contains tabs)"
result=1
;;
*) error "failed to compare ${input} with ${expanded}"
;;
esac
else
exit 1
fi
done
return $result
}
fix() {
for input
do
if expanded="$(make_expanded_file ${input})"
then
cmp -s -- "${input}" "${expanded}"
rv="$?"
case "$rv" in
0) if ! cleanup "${expanded}"
then
return 1
fi
# Otherwise, continue with next file.
;;
1) if ! mv "${expanded}" "${input}"
then
cleanup "${expanded}"
error "failed to replace ${input} with tab-expanded version ${expanded}"
else
unset expanded
fi
# Otherwise, continue with next file.
;;
*) error "failed to compare ${input} with ${expanded}"
;;
esac
else
exit 1
fi
done
}
main() {
if [ $# -eq 0 ]
then
usage_error
fi
case "$1" in
check) shift; check "$@" ;;
fix) shift; fix "$@" ;;
*) usage_error ;;
esac
}
main "$@"

View File

@ -1,5 +1,5 @@
#! /bin/sh
# Copyright (C) 2019-2024 Free Software Foundation, Inc.
# Copyright (C) 2019-2026 Free Software Foundation, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -30,7 +30,7 @@ usage: $0 location-of-${PACKAGE}-build-directory
EOF
}
checkfiles="CVS dvi ${TEXIBASE}.html html_node html_mono info ps texi text ${TEXIBASE}.pdf"
checkfiles="CVS ${TEXIBASE}.html html_node html_mono info ps texi text ${TEXIBASE}.pdf"
if [ $# -ne 1 ]; then
usage >&2
@ -99,9 +99,6 @@ then
cp ${BUILDDIR}/doc/manual/${TEXIBASE}.texi.tar.gz texi/${TEXIBASE}.texi.tar.gz
cp ${BUILDDIR}/doc/manual/${TEXIBASE}.info.tar.gz info/${TEXIBASE}-info.tar.gz
echo Collecting the DVI file...
cp $BUILDDIR/doc/manual/${TEXIBASE}.dvi.gz dvi/${TEXIBASE}.dvi.gz
echo Collecting the PDF file...
cp $BUILDDIR/doc/manual/${TEXIBASE}.pdf .
@ -178,9 +175,6 @@ This manual is available in the following formats:
<LI>
$(linkfor "text/${TEXIBASE}.txt.gz" "gzipped characters" "ASCII text")
</LI>
<LI>
$(linkfor "dvi/${TEXIBASE}.dvi.gz" "gzipped" "a TeX dvi file")
</LI>
<LI>
$(linkfor "${TEXIBASE}.pdf" "PDF file" PDF)
</LI>
@ -208,8 +202,8 @@ send other questions to
<A HREF="mailto:gnu@gnu.org"><EM>gnu@gnu.org</EM></A>.
<P>
Copyright &copy; 1997, 1998, 2003, 2005, 2006, 2008 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
Copyright &copy; 1997-2026 Free Software Foundation, Inc.,
&lt;<A HREF="https://fsf.org/">https://fsf.org/</A>&gt;
<P>
Verbatim copying and distribution of this entire article is

39
cfg.mk
View File

@ -1,5 +1,5 @@
# cfg.mk -- configuration file for the maintainer makefile provided by gnulib.
# Copyright (C) 2010-2024 Free Software Foundation, Inc.
# Copyright (C) 2010-2026 Free Software Foundation, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -21,11 +21,15 @@ gendocs_options_ = -s find.texi -I $(abs_builddir)/doc
local-checks-to-skip :=
# Tools used to bootstrap this package, used for "announcement".
bootstrap-tools = autoconf,automake,gnulib,bison
# Errors I think are too picky anyway.
local-checks-to-skip += sc_error_message_period sc_error_message_uppercase \
sc_file_system sc_indent
exclude_file_name_regexp--sc_obsolete_symbols = build-aux/src-sniff\.py
exclude_file_name_regexp--sc_fsf_postal = build-aux/src-sniff\.py
exclude_file_name_regexp--sc_space_tab = \
xargs/testsuite/(inputs/.*\.xi|xargs.(gnu|posix|sysv)/.*\.xo)|find/testsuite/test_escapechars\.golden$$
@ -92,6 +96,13 @@ exclude_file_name_regexp--sc_bindtextdomain = \
exclude_file_name_regexp--sc_unmarked_diagnostics = \
^(tests/xargs/test-sigusr)\.c$$
# Things that 'codespell' mistakenly flags as typos.
codespell_ignore_words_list = afile,bu,debbugs,filll,fo,hel,ois,siz,ublic,TE,
# Files to exclude from sc_codespell
exclude_file_name_regexp--sc_codespell = \
^(THANKS|build-aux/git-log-fix)$$
# sc_prohibit_strcmp is broken because it gives false positives for
# cases where neither argument is a string literal.
local-checks-to-skip += sc_prohibit_strcmp
@ -274,6 +285,32 @@ sc_prohibit_unhyphenated_eof:
halt='use "end-of-file", not "e''nd of file"' \
$(_sc_search_regexp)
# Prohibit the use of tabs in findutils C source files (but not
# gnulib). This is not the same as sc_space_tab which prohibits only
# tabs which follow spaces.
sc_spaces_not_tabs:
@cd $(srcdir) \
&& GIT_PAGER= git grep -n ' ' -- \
"find/*.[ch]" \
"lib/*.[ch]" \
"locate/*.[ch]" \
"tests/*.[ch]" \
"xargs/*.[ch]" \
&& { echo '$(ME): Indent C sources with spaces, not tabs (fix with build-aux/tabs-to-spaces.sh)' 1>&2; exit 1; } \
|| :
# Enforce standard references "standard input/output/error".
sc_standard_outputs:
@cd $(srcdir) || exit 1; \
GIT_PAGER= git grep -En '_\("[^"]*std(in|out|err)' -- '*/*.c' \
&& { echo '$@: use "standard ....." in translated strings' 1>&2; \
fail=1; } || :; \
GIT_PAGER= git grep -En '[^/]std(in|out|err)' -- \
'*/*.1' '*/*.5' 'doc/*.texi' \
&& { echo '$@: use "standard ....." in user docs' 1>&2; \
fail=1; } || :; \
exit $$fail
# Now that we have better tests, make this the default.
export VERBOSE = yes

View File

@ -1,7 +1,7 @@
# -*- autoconf -*-
# Process this file with autoconf to produce a configure script.
# Copyright (C) 1996-2024 Free Software Foundation, Inc.
# Copyright (C) 1996-2026 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -101,7 +101,6 @@ dnl AC_PROG_LIBTOOL
AC_PROG_MAKE_SET
AC_SYS_LARGEFILE
gl_INIT
AC_ARG_ENABLE(compiler-warnings,
@ -116,7 +115,6 @@ AC_ARG_ENABLE(compiler-warnings,
# Set up the list of the pointless, undesired warnings.
findutils_nw=
findutils_nw="$findutils_nw -Wsystem-headers" # Don't let system headers trigger warnings
findutils_nw="$findutils_nw -Wundef" # All compiler preprocessors support #if UNDEF
findutils_nw="$findutils_nw -Wtraditional" # All compilers nowadays support ANSI C
findutils_nw="$findutils_nw -Wconversion" # These warnings usually don't point to mistakes.
@ -298,6 +296,11 @@ AM_CONDITIONAL([HAVE_PYTHON], [test "$PYTHON" != :])
AC_CHECK_PROGS([FAKETIME],[faketime],[:])
AM_CONDITIONAL([HAVE_FAKETIME], [test "$FAKETIME" != :])
dnl Manpage linting.
AC_ARG_VAR(GROFF,[Location of GNU groff])
AC_CHECK_PROGS([GROFF], [groff],[:])
# This is necessary so that .o files in LIBOBJS are also built via
# the ANSI2KNR-filtering rules.
#LIBOBJS=`echo $LIBOBJS|sed 's/\.o /\$U.o /g;s/\.o$/\$U.o/'`

2
doc/.gitignore vendored
View File

@ -4,7 +4,6 @@
/find.aux
/find.cp
/find.cps
/find.dvi
/find.fn
/find.fns
/find.html/
@ -17,7 +16,6 @@
/find.toc
/find.tp
/find.vr
/find-maint.dvi
/find-maint.html/
/find-maint.pdf
/find-maint.ps

View File

@ -1,4 +1,4 @@
# Copyright (C) 1996-2024 Free Software Foundation, Inc.
# Copyright (C) 1996-2026 Free Software Foundation, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by

View File

@ -23,7 +23,7 @@ be made and tested, and what resources exist to help developers.
This document corresponds to version @value{VERSION} of the GNU findutils.
Copyright @copyright{} 2007--2024 Free Software Foundation, Inc.
Copyright @copyright{} 2007--2026 Free Software Foundation, Inc.
@quotation
Permission is granted to copy, distribute and/or modify this document
@ -87,7 +87,7 @@ This manual aims to be useful without necessarily being verbose. It's
also a recent document, so there will be a many areas in which
improvements can be made. If you find that the document misses out
important information or any part of the document is be so terse as to
be unuseful, please ask for help on the @email{bug-findutils@@gnu.org}
be useless, please ask for help on the @email{bug-findutils@@gnu.org}
mailing list. We'll try to improve this document too.
@ -537,7 +537,7 @@ Make sure your editor follows symbolic links so that your changes to
directory you checked out earlier. Observe that your test now passes.
@item Prepare a Gnulib patch
In the gnulib subdirectory, use @code{git format-patch} to prepare the
patch. Follow the normal usage for checkin comments (take a look at
patch. Follow the normal usage for check-in comments (take a look at
the output of @code{git log}). Check that the patch conforms with the
GNU coding standards, and email it to the Gnulib mailing list.
@item Wait for the patch to be applied
@ -674,7 +674,7 @@ changes). The level of detail used for this file should be sufficient
to answer the questions ``what changed?'' and ``why was it changed?''.
The file is generated from the git commit messages during @code{make dist}.
If a change fixes a bug, always give the bug reference number in the
@file{NEWS} file and of course also in the checkin message.
@file{NEWS} file and of course also in the check-in message.
In general, it should be possible to enumerate all
material changes to a function by searching for its name in
@file{ChangeLog}. Mention when each release is made.
@ -947,7 +947,7 @@ VI. VENDOR RESPONSE
The GNU project discovered the problem while 'locate' was being worked
on; this is the first public announcement of the problem.
The GNU findutils mantainer has issued a patch as part of this
The GNU findutils maintainer has issued a patch as part of this
announcement. The patch appears below.
A source release of findutils-4.2.31 will be issued on 2007-05-30.

View File

@ -30,7 +30,7 @@
This manual documents version @value{VERSION} of the GNU utilities for finding
files that match certain criteria and performing various operations on them.
Copyright @copyright{} 1994--2024 Free Software Foundation, Inc.
Copyright @copyright{} 1994--2026 Free Software Foundation, Inc.
@quotation
Permission is granted to copy, distribute and/or modify this document
@ -328,10 +328,21 @@ connect primaries into more complex expressions.
The @samp{-print} action is performed on all files for which the
entire expression is true (@pxref{Print File Name}), unless the
expression contains an action other than @samp{-prune} or
@samp{-quit}. Actions which inhibit the default @samp{-print} are
@samp{-delete}, @samp{-exec}, @samp{-execdir}, @samp{-ok},
@samp{-okdir}, @samp{-fls}, @samp{-fprint}, @samp{-fprintf},
@samp{-ls}, @samp{-print} and @samp{-printf}.
@samp{-quit}.
Actions which inhibit the default @samp{-print} are
@samp{-delete},
@samp{-execdir},
@samp{-exec},
@samp{-fls},
@samp{-fprint0},
@samp{-fprintf},
@samp{-fprint},
@samp{-ls},
@samp{-okdir},
@samp{-ok},
@samp{-print0},
@samp{-printf}
and @samp{-print}.
Options take effect immediately, rather than being evaluated for each
file when their place in the expression is reached. Therefore, for
@ -497,6 +508,9 @@ Because the leading directories are removed, the file names considered
for a match with @samp{-name} will never include a slash, so
@samp{-name a/b} will never match anything (you probably need to use
@samp{-path} instead).
The @samp{-iname} option appeared first in POSIX Issue 8 (IEEE Std 1003.1-2024)
while GNU @code{find} supports it since version 3.8 (1993).
@end deffn
@ -521,8 +535,8 @@ arguments ending in @samp{/} will match nothing (except perhaps a
start point specified on the command line).
The name @samp{-wholename} is GNU-specific, but @samp{-path} is more
portable; it is supported by HP-UX @code{find} and is part of the
POSIX 2008 standard.
portable: the latter is supported by HP-UX @code{find} and is part of the
POSIX standard (since IEEE Std 1003.1-2008).
@end deffn
@ -808,7 +822,7 @@ Actions that can cause symbolic links to become broken while
confusing behaviour. Take for example the command line
@samp{find -L . -type d -delete}. This will delete empty
directories. If a subtree includes only directories and symbolic
links to directoires, this command may still not successfully delete
links to directories, this command may still not successfully delete
it, since deletion of the target of the symbolic link will cause the
symbolic link to become broken and @samp{-type d} is false for broken
symbolic links.
@ -1025,8 +1039,9 @@ command line.
@deffn Test -newerXY reference
Succeeds if timestamp @samp{X} of the file being considered is newer
than timestamp @samp{Y} of the file @file{reference}. The letters
@samp{X} and @samp{Y} can be any of the following letters:
than timestamp @samp{Y} of the file @file{reference}.
Fails if the timestamps are @emph{equal}.
The letters @samp{X} and @samp{Y} can be any of the following letters:
@table @samp
@item a
@ -1066,7 +1081,8 @@ not UFS1 file systems.
There are two ways to list files in @file{/usr} modified after
February 1 of the current year. One uses @samp{-newermt}:
@emph{the start} of February 1 of the current year. One uses
@samp{-newermt}:
@example
find /usr -newermt "Feb 1"
@ -1087,6 +1103,7 @@ rm -f /tmp/stamp$$
True if the time of the last access (or status change or data modification)
of the current file is more recent than that of the last data modification
of the @var{reference} file.
False if the timestamps are equal.
As such, @samp{-anewer} is equivalent to @samp{-neweram},
@samp{-cnewer} to @samp{-newercm}, and @samp{-newer} to @samp{-newermm}.
@ -1536,7 +1553,7 @@ This is different to @samp{-prune} because @samp{-prune} only applies
to the contents of pruned directories, while @samp{-quit} simply makes
@code{find} stop immediately. No child processes will be left
running. Any command lines which have been built by @samp{-exec
... \+} or @samp{-execdir ... \+} are invoked before the program is
... @{@} +} or @samp{-execdir ... \+} are invoked before the program is
exited. After @samp{-quit} is executed, no more files specified on
the command line will be processed. For example, @samp{find /tmp/foo
/tmp/bar -print -quit} will print only @samp{/tmp/foo}. One common
@ -1607,10 +1624,12 @@ them.
There are two ways to avoid searching certain filesystems. One way is
to tell @code{find} to only search one filesystem:
@deffn Option -mount
Ignore files on other devices.
@end deffn
@deffn Option -xdev
@deffnx Option -mount
Don't descend directories on other filesystems. These options are
synonyms.
Don't descend into directories on other devices.
@end deffn
The other way is to check the type of filesystem each file is on, and
@ -1752,7 +1771,7 @@ you are searching might contain a newline, you should use
@c @item -fls
@c Escaped if @samp{how} is @samp{safe}
@c @item -print
@c Always quoted if stdout is a tty,
@c Always quoted if standard output is a tty,
@c @samp{-show-control-chars} is ignored
@c @item -print0
@c Always literal, never escaped
@ -1765,7 +1784,7 @@ you are searching might contain a newline, you should use
@c If the destination is a tty, the @samp{%f},
@c @samp{%F}, @samp{%h}, @samp{%l}, @samp{%p},
@c and @samp{%P} directives produce quoted
@c strings if stdout is a tty and are treated
@c strings if standard output is a tty and are treated
@c literally otherwise.
@c @item -printf
@c As for @code{-fprintf}.
@ -2318,13 +2337,16 @@ Here is how to run a command on one file at a time.
@deffn Action -execdir command ;
Execute @var{command}; true if @var{command} returns zero. @code{find}
takes all arguments after @samp{-execdir} to be part of the command until
an argument consisting of @samp{;} is reached. It replaces the string
@samp{@{@}} by the current file name being processed everywhere it
occurs in the command. Both of these constructions need to be escaped
(with a @samp{\}) or quoted to protect them from expansion by the
shell. The command is executed in the directory which @code{find}
was searching at the time the action was executed (that is, @{@} will
expand to a file in the local directory).
an argument consisting of @samp{;} is reached.
It replaces the string @samp{@{@}} by the current file name being processed
everywhere it occurs in the command.
Each file name except for the root directory @samp{/} is prepended with
@samp{./}.
Both of these constructions need to be escaped (with a @samp{\}) or quoted to
protect them from expansion by the shell.
The command is executed in the directory which @code{find} was searching at the
time the action was executed (that is, @{@} will expand to a file in the local
directory).
For example, to compare each C header file in or below the current
directory with the file @file{/tmp/master}:
@ -2388,15 +2410,17 @@ The @samp{-execdir} and @samp{-exec} actions have variants that build
command lines containing as many matched files as possible.
@deffn Action -execdir command @{@} +
This works as for @samp{-execdir command ;}, except that the result is
always true, and the @samp{@{@}} at the end of the command is expanded
to a list of names of matching files. This expansion is done in such
a way as to avoid exceeding the maximum command line length available
on the system. Only one @samp{@{@}} is allowed within the command,
and it must appear at the end, immediately before the @samp{+}. A
@samp{+} appearing in any position other than immediately after
@samp{@{@}} is not considered to be special (that is, it does not
terminate the command).
This works as for @samp{-execdir command ;}, except that the result is always
true, and the @samp{@{@}} at the end of the command is expanded to a list of
names of matching files.
Each file name except for the root directory @samp{/} is prepended with
@samp{./}.
This expansion is done in such a way as to avoid exceeding the maximum command
line length available on the system.
Only one @samp{@{@}} is allowed within the command, and it must appear at the
end, immediately before the @samp{+}.
A @samp{+} appearing in any position other than immediately after @samp{@{@}}
is not considered to be special (that is, it does not terminate the command).
@end deffn
@ -2453,7 +2477,7 @@ should consider the following line to be part of this one.
Instead of blank-delimited names, it is safer to use @samp{find
-print0} or @samp{find -fprint0} and process the output by giving the
@samp{-0} or @samp{--null} option to GNU @code{xargs}, GNU @code{tar},
@samp{-0} or @samp{--null} option to @code{xargs}, GNU @code{tar},
GNU @code{cpio}, or @code{perl}. The @code{locate} command also has a
@samp{-0} or @samp{--null} option which does the same thing.
@ -2566,6 +2590,9 @@ can process file names generated this way by giving the @samp{-0} or
@samp{--null} option to GNU @code{xargs}, GNU @code{tar}, GNU
@code{cpio}, or @code{perl}.
Both @code{find . -print0} and @code{xargs -0} are
POSIX-conforming since Issue 8 (IEEE Std 1003.1-2024).
@deffn Action -print0
True; print the entire file name on the standard output, followed by a
null character.
@ -2786,16 +2813,17 @@ if @code{xargs} is running commands that are waiting for a response from a
distant network connection, running a few in parallel may reduce the
overall latency by overlapping their waiting time.
If you are running commands in parallel, you need to think about how
they should arbitrate access to any resources that they share. For
example, if more than one of them tries to print to stdout, the output
will be produced in an indeterminate order (and very likely mixed up)
unless the processes collaborate in some way to prevent this. Using
some kind of locking scheme is one way to prevent such problems. In
general, using a locking scheme will help ensure correct output but
reduce performance. If you don't want to tolerate the performance
difference, simply arrange for each process to produce a separate output
file (or otherwise use separate resources).
If you are running commands in parallel, you need to think about how they should
arbitrate access to any resources that they share.
For example, if more than one of them tries to print to standard output, the
output will be produced in an indeterminate order (and very likely mixed up)
unless the processes collaborate in some way to prevent this.
Using some kind of locking scheme is one way to prevent such problems.
In general, using a locking scheme will help ensure correct output but reduce
performance.
If you don't want to tolerate the performance difference, simply arrange for
each process to produce a separate output file (or otherwise use separate
resources).
@code{xargs} also allows ``turning up'' or ``turning down'' its parallelism
in the middle of a run. Suppose you are keeping your four-processor
@ -2853,7 +2881,7 @@ delaying for a few seconds between signals (unless your system is very
heavily loaded).
Whether or not parallel execution will work well for you depends on
the nature of the commmand you are running in parallel, on the
the nature of the command you are running in parallel, on the
configuration of the system on which you are running the command, and
on the other work being done on the system at the time.
@ -3348,7 +3376,7 @@ useful or which are not obvious are explained here.
@section Leaf Optimisation
Files in Unix file systems have a link count which indicates how many
names point to the same inode. Directories in Unix filssytems have a
names point to the same inode. Directories in Unix filesystems have a
@file{..} entry which functions as a hard link to the parent directory
and a @file{.} entry which functions as a link to the directory itself.
The @file{..} entry of the root directory also points to the root.
@ -3549,7 +3577,7 @@ information from the inode. On many modern versions of Unix, file
types are returned by @code{readdir()} and so these predicates are
faster to evaluate than predicates which need to stat the file first.
If you use the @samp{-fstype FOO} predicate and specify a filsystem
If you use the @samp{-fstype FOO} predicate and specify a filesystem
type @samp{FOO} which is not known (that is, present in
@file{/etc/mtab}) at the time @code{find} starts, that predicate is
equivalent to @samp{-false}.
@ -3655,7 +3683,7 @@ database file names. You can also use the environment variable
option overrides the environment variable if both are used. Empty
elements in @var{path} (that is, a leading or trailing colon, or two
colons in a row) are taken to stand for the default database.
A database can be supplied on stdin, using @samp{-} as an element
A database can be supplied on standard input, using @samp{-} as an element
of @samp{path}. If more than one element of @samp{path} is @samp{-},
later instances are ignored (but a warning message is printed).
@ -3856,6 +3884,10 @@ Print the version number of @code{updatedb} and exit.
xargs @r{[}@var{option}@dots{}@r{]} @r{[}@var{command} @r{[}@var{initial-arguments}@r{]}@r{]}
@end example
@code{xargs} executes the @var{command} - the default is @file{echo} - one or
more times with any @var{initial-arguments} followed by arguments read from
standard input.
@code{xargs} exits with the following status:
@table @asis
@ -3901,15 +3933,15 @@ rejecting this as unrecognized option.
@itemx -a @r{@var{inputfile}}
Read names from the file @var{inputfile} instead of standard input.
If you use this option, the standard input stream remains unchanged
when commands are run. Otherwise, stdin is redirected from
@file{/dev/null}.
when commands are run.
Otherwise, standard input is redirected from @file{/dev/null}.
@item --null
@itemx -0
Input file names are terminated by a null character instead of by
whitespace, and any quotes and backslash characters are not considered
special (every character is taken literally). Disables the end of
file string, which is treated like any other argument.
special (every character is taken literally).
Disables the end-of-file string, which is treated like any other argument.
@item --delimiter @var{delim}
@itemx -d @var{delim}
@ -3979,7 +4011,7 @@ case @code{xargs} will exit.
@item --open-tty
@itemx -o
Reopen stdin as @file{/dev/tty} in the child process before executing
Reopen standard input as @file{/dev/tty} in the child process before executing
the command, thus allowing that command to be associated to the terminal
while @code{xargs} reads from a different stream, e.g. from a pipe.
This is useful if you want @code{xargs} to run an interactive application.
@ -4048,7 +4080,7 @@ The options @samp{--max-lines} (@samp{-L}, @samp{-l}), @samp{--replace}
If some of them are specified at the same time, then @code{xargs} will
generally use the option specified last on the command line, i.e., it will
reset the value of the offending option (given before) to its default value.
Additionally, @code{xargs} will issue a warning diagnostic on @file{stderr}.
Additionally, @code{xargs} will issue a warning diagnostic on standard error.
@example
$ seq 4 | xargs -L2 -n3
@ -4148,7 +4180,7 @@ process creation.
Although GNU @code{xargs} and the implementations on some other platforms
like BSD support the @samp{-o} option to achieve the same, the above is
the portable way to redirect stdin to @file{/dev/tty}.
the portable way to redirect standard input to @file{/dev/tty}.
Sometimes, though, it can be helpful to keep the shell process around:
@ -4247,7 +4279,7 @@ they are units of 1024 bytes.
Setting this variable also turns off warning messages (that is, implies
@samp{-nowarn}) by default, because POSIX requires that apart from
the output for @samp{-ok}, all messages printed on stderr are
the output for @samp{-ok}, all messages printed on standard error are
diagnostics and must result in a non-zero exit status.
When @env{POSIXLY_CORRECT} is set, the response to the prompt made by the
@ -4328,7 +4360,7 @@ nothing). The capitalised @samp{Emacs} on the command line is used as
Please note that the implementations in GNU @code{xargs} and at least BSD
support the @samp{-o} option as extension to achieve the same, while the
above is the portable way to redirect stdin to @file{/dev/tty}.
above is the portable way to redirect standard input to @file{/dev/tty}.
@node Archiving
@section Archiving
@ -4654,6 +4686,9 @@ there are lots of files to delete. Since the task is to delete
unwanted files, this is precisely the time we don't want things to go
wrong.
There is also a second problem with this method. We will discuss that
below.
@subsection Making Use of @code{xargs}
So, is there a way to be more efficient in the use of @code{fork()}
@ -4719,13 +4754,15 @@ this command:
find /var/tmp/stuff -mtime +90 -print0 | xargs -0 /bin/rm
@end smallexample
The result is an efficient way of proceeding that
correctly handles all the possible characters that could appear in the
list of files to delete. This is good news. However, there is, as
I'm sure you're expecting, also more bad news. The problem is that
this is not a portable construct; although other versions of Unix
(notably BSD-derived ones) support @samp{-print0}, it's not
universal. So, is there a more universal mechanism?
The result is an efficient way of proceeding that correctly handles
all the possible characters that could appear in the list of files to
delete. This is good news. However, there is, as I'm sure you're
expecting, also more bad news. The problem is that this is not a
portable construct. Support for @samp{-print0} is not universal.
Although some other versions of Unix (notably BSD-derived ones)
support @samp{-print0}, this is only required in POSIX from Issue 8
(IEEE Std 1003.1-2024). So, is there a more universal mechanism?
@subsection Going back to @code{-exec}
@ -4992,7 +5029,7 @@ different ways to do it.
The obvious but wrong answer is just to use @samp{-newer}:
@smallexample
find subdir -newer timestamp -exec touch -r @{@} timestamp \;
find subdir -type f -newer timestamp -exec touch -r @{@} timestamp \;
@end smallexample
This does the right sort of thing but has a bug. Suppose that two
@ -5013,7 +5050,7 @@ compared against it, but that will reduce the performance of
The @code{test} command can be used to compare timestamps:
@smallexample
find subdir -exec test @{@} -nt timestamp \; -exec touch -r @{@} timestamp \;
find subdir -type f -exec test @{@} -nt timestamp \; -exec touch -r @{@} timestamp \;
@end smallexample
This will ensure that any changes made to the modification time of
@ -5027,13 +5064,14 @@ We can of course still use @samp{-newer} to cut down on the number of
calls to @code{test}:
@smallexample
find subdir -newer timestamp -and \
find subdir -type f -newer timestamp -and \
-exec test @{@} -nt timestamp \; -and \
-exec touch -r @{@} timestamp \;
@end smallexample
Here, the @samp{-newer} test excludes all the files which are
definitely older than the timestamp, but all the files which are newer
definitely older than or the same age as
the timestamp, but all the files which are newer
than the old value of the timestamp are compared against the current
updated timestamp.
@ -5046,10 +5084,8 @@ It is possible to use the @samp{-printf} action to abandon the use of
@code{test} entirely:
@smallexample
newest=$(find subdir -newer timestamp -printf "%A@@:%p\n" |
sort -n |
tail -n1 |
cut -d: -f2- )
newest="$(find subdir -type f -newer timestamp -printf "%A@@:%p\n" |
env LC_ALL=C sh -c 'sort -n | tail -n1 | cut -d: -f2-' )"
touch -r "$@{newest:-timestamp@}" timestamp
@end smallexample
@ -5057,19 +5093,20 @@ The command above works by generating a list of the timestamps and
names of all the files which are newer than the timestamp. The
@code{sort}, @code{tail} and @code{cut} commands simply pull out the
name of the file with the largest timestamp value (that is, the latest
file). The @code{touch} command is then used to update the timestamp,
file). We run those programs (which normally read and write text)
with with the @env{LC_ALL} environment variable set to @samp{C} in
order to avoid character encoding problems; file names are not
guaranteed to have a valid (or consistent) character encoding. The
@code{touch} command is then used to update the timestamp,
The @code{"$@{newest:-timestamp@}"} expression simply expands to the
value of @code{$newest} if that variable is set, but to
@file{timestamp} otherwise. This ensures that an argument is always
given to the @samp{-r} option of the @code{touch} command.
This approach seems quite efficient, but unfortunately it has a
problem. Many operating systems now keep file modification time
information at a granularity which is finer than one second.
Findutils version 4.3.3 and later will print a fractional part with
%A@@, but older versions will not.
@c We used to warn the reader about older versions of Find where %A@
@c didn't include a fractional part, but since Findutils 4.3.3 was
@c released in 2007, people are unlikely to have a problem today.
@subsection Solving the problem with @code{make}
@ -5078,8 +5115,9 @@ use @code{find} to generate a @file{Makefile} file on the fly and then
use @code{make} to update the timestamps:
@smallexample
makefile=$(mktemp)
makefile="$(mktemp)"
find subdir \
-type f \
\( \! -xtype l \) \
-newer timestamp \
-printf "timestamp:: %p\n\ttouch -r %p timestamp\n\n" > "$makefile"
@ -5099,14 +5137,15 @@ space), and do things more efficiently too. The following command
works with newlines and doesn't need to sort the list of filenames.
@smallexample
find subdir -newer timestamp -printf "%A@@:%p\0" |
find subdir -type f -newer timestamp -printf "%A@@:%p\0" |
perl -0 newest.pl |
xargs --no-run-if-empty --null --replace \
find @{@} -maxdepth 0 -newer timestamp -exec touch -r @{@} timestamp \;
@end smallexample
The first @code{find} command generates a list of files which are
newer than the original timestamp file, and prints a list of them with
newer than (and not the same age as) the original timestamp file,
and prints a list of them with
their timestamps. The @file{newest.pl} script simply filters out all
the filenames which have timestamps which are older than whatever the
newest file is:
@ -5168,13 +5207,24 @@ already found.
@smallexample
find repo/ \
-exec test -d @{@}/.svn \; -or \
-exec test -d @{@}/.git \; -or \
-exec test -d @{@}/CVS \; -print -prune
\( \
-exec test -d @{@}/.svn \; -or \
-exec test -d @{@}/.git \; -or \
-exec test -d @{@}/CVS \; \
\) -print -prune
@end smallexample
Output:
@smallexample
repo/project1
repo/gnu/project2
repo/gnu/project3
repo/project4
@end smallexample
In this example, @command{test} is used to tell if we are currently
examining a directory which appears to the a project's root directory
examining a directory which appears to be a project's root directory
(because it has an SCM subdirectory). When we find a project root,
there is no need to search inside it, and @code{-prune} makes sure
that we descend no further.
@ -5600,9 +5650,10 @@ The only ways to avoid this problem are either to avoid all use of
available) @samp{find -execdir}, or to use the @samp{-0} option, which
ensures that @code{xargs} considers file names to be separated by
ASCII NUL characters rather than whitespace. However, useful as this
option is, the POSIX standard does not make it mandatory.
option is, the POSIX standard did not make it mandatory prior to
Issue 8 (IEEE Std 1003.1-2024).
POSIX also specifies that @code{xargs} interprets quoting and trailing
POSIX also specifies that @code{xargs} without @code{-0} interprets quoting and trailing
whitespace specially in filenames, too. This means that using
@code{find ... -print | xargs ...} can cause the commands run by
@code{xargs} to receive a list of file names which is not the same as
@ -5840,8 +5891,8 @@ If you don't plan to send it those signals, this warning can be ignored
why @code{xargs} is confused by your operating system).
@item failed to redirect standard input of the child process
@code{xargs} redirects the stdin stream of the command to be run to either
@file{/dev/null} or to @file{/dev/tty} for the @samp{-o} option.
@code{xargs} redirects the standard input stream of the command to be run to
either @file{/dev/null} or to @file{/dev/tty} for the @samp{-o} option.
See the manual of the system call @code{dup2(2)}.
@end table

View File

@ -1,6 +1,6 @@
@c File mode bits
@c Copyright (C) 1994--2024 Free Software Foundation, Inc.
@c Copyright (C) 1994--2026 Free Software Foundation, Inc.
@c Permission is granted to copy, distribute and/or modify this document
@c under the terms of the GNU Free Documentation License, Version 1.3 or

View File

@ -1,4 +1,4 @@
@c Copyright (C) 1994--2024 Free Software Foundation, Inc.
@c Copyright (C) 1994--2026 Free Software Foundation, Inc.
@c
@c Permission is granted to copy, distribute and/or modify this document
@c under the terms of the GNU Free Documentation License, Version 1.3 or
@ -11,14 +11,14 @@
@menu
* findutils-default regular expression syntax::
* awk regular expression syntax::
* egrep regular expression syntax::
* emacs regular expression syntax::
* gnu-awk regular expression syntax::
* grep regular expression syntax::
* posix-awk regular expression syntax::
* awk regular expression syntax::
* posix-basic regular expression syntax::
* posix-egrep regular expression syntax::
* egrep regular expression syntax::
* posix-extended regular expression syntax::
@end menu
@ -42,7 +42,7 @@ matches a @samp{?}.
@end table
Bracket expressions are used to match ranges of characters. Bracket expressions where the range is backward, for example @samp{[z-a]}, are ignored. Within square brackets, @samp{\} is taken literally. Character classes are not supported, so for example you would need to use @samp{[0-9]} instead of @samp{[[:digit:]]}.
Bracket expressions are used to match ranges of characters. Bracket expressions where the range is backward, for example @samp{[z-a]}, are ignored. Within square brackets, @samp{\} is taken literally. Character classes are supported; for example @samp{[[:digit:]]} will match a single decimal digit.
GNU extensions are supported:
@ -108,11 +108,124 @@ The character @samp{$} only represents the end of a string when it appears:
@end enumerate
Intervals are specified by @samp{\@{} and @samp{\@}}.
Invalid intervals such as @samp{a\@{1z} are not accepted.
The longest possible match is returned; this applies to the regular expression as a whole and (subject to this constraint) to subexpressions within groups.
@node awk regular expression syntax
@subsection @samp{awk} regular expression syntax
The character @samp{.} matches any single character except the null character.
@table @samp
@item +
indicates that the regular expression should match one or more occurrences of the previous atom or regexp.
@item ?
indicates that the regular expression should match zero or one occurrence of the previous atom or regexp.
@item \+
matches a @samp{+}
@item \?
matches a @samp{?}.
@end table
Bracket expressions are used to match ranges of characters. Bracket expressions where the range is backward, for example @samp{[z-a]}, are invalid. Within square brackets, @samp{\} can be used to quote the following character. Character classes are supported; for example @samp{[[:digit:]]} will match a single decimal digit.
GNU extensions are not supported and so @samp{\w}, @samp{\W}, @samp{\<}, @samp{\>}, @samp{\b}, @samp{\B}, @samp{\`}, and @samp{\'} match @samp{w}, @samp{W}, @samp{<}, @samp{>}, @samp{b}, @samp{B}, @samp{`}, and @samp{'} respectively.
Grouping is performed with parentheses @samp{()}. An unmatched @samp{)} matches just itself. A backslash followed by a digit matches that digit.
The alternation operator is @samp{|}.
The characters @samp{^} and @samp{$} always represent the beginning and end of a string respectively, except within square brackets. Within brackets, @samp{^} can be used to invert the membership of the character class being specified.
@samp{*}, @samp{+} and @samp{?} are special at any point in a regular expression except:
@enumerate
@item At the beginning of a regular expression
@item After an open-group, signified by @samp{(}
@item After the alternation operator @samp{|}
@end enumerate
The longest possible match is returned; this applies to the regular expression as a whole and (subject to this constraint) to subexpressions within groups.
@node egrep regular expression syntax
@subsection @samp{egrep} regular expression syntax
The character @samp{.} matches any single character.
@table @samp
@item +
indicates that the regular expression should match one or more occurrences of the previous atom or regexp.
@item ?
indicates that the regular expression should match zero or one occurrence of the previous atom or regexp.
@item \+
matches a @samp{+}
@item \?
matches a @samp{?}.
@end table
Bracket expressions are used to match ranges of characters. Bracket expressions where the range is backward, for example @samp{[z-a]}, are invalid. Within square brackets, @samp{\} is taken literally. Character classes are supported; for example @samp{[[:digit:]]} will match a single decimal digit.
GNU extensions are supported:
@enumerate
@item @samp{\w} matches a character within a word
@item @samp{\W} matches a character which is not within a word
@item @samp{\<} matches the beginning of a word
@item @samp{\>} matches the end of a word
@item @samp{\b} matches a word boundary
@item @samp{\B} matches characters which are not a word boundary
@item @samp{\`} matches the beginning of the whole input
@item @samp{\'} matches the end of the whole input
@end enumerate
Grouping is performed with parentheses @samp{()}. An unmatched @samp{)} matches just itself. A backslash followed by a digit acts as a back-reference and matches the same thing as the previous grouped expression indicated by that number. For example @samp{\2} matches the second group expression. The order of group expressions is determined by the position of their opening parenthesis @samp{(}.
The alternation operator is @samp{|}.
The characters @samp{^} and @samp{$} always represent the beginning and end of a string respectively, except within square brackets. Within brackets, @samp{^} can be used to invert the membership of the character class being specified.
The characters @samp{*}, @samp{+} and @samp{?} are special anywhere in a regular expression.
Intervals are specified by @samp{@{} and @samp{@}}.
Invalid intervals are treated as literals, for example @samp{a@{1} is treated as @samp{a\@{1}
The longest possible match is returned; this applies to the regular expression as a whole and (subject to this constraint) to subexpressions within groups.
@node emacs regular expression syntax
@subsection @samp{emacs} regular expression syntax
@ -133,7 +246,7 @@ matches a @samp{?}.
@end table
Bracket expressions are used to match ranges of characters. Bracket expressions where the range is backward, for example @samp{[z-a]}, are ignored. Within square brackets, @samp{\} is taken literally. Character classes are not supported, so for example you would need to use @samp{[0-9]} instead of @samp{[[:digit:]]}.
Bracket expressions are used to match ranges of characters. Bracket expressions where the range is backward, for example @samp{[z-a]}, are ignored. Within square brackets, @samp{\} is taken literally. Character classes are supported; for example @samp{[[:digit:]]} will match a single decimal digit.
GNU extensions are supported:
@ -199,6 +312,8 @@ The character @samp{$} only represents the end of a string when it appears:
@end enumerate
Intervals are specified by @samp{\@{} and @samp{\@}}.
Invalid intervals such as @samp{a\@{1z} are not accepted.
The longest possible match is returned; this applies to the regular expression as a whole and (subject to this constraint) to subexpressions within groups.
@ -420,56 +535,6 @@ The characters @samp{^} and @samp{$} always represent the beginning and end of a
Intervals are specified by @samp{@{} and @samp{@}}.
Invalid intervals are treated as literals, for example @samp{a@{1} is treated as @samp{a\@{1}
The longest possible match is returned; this applies to the regular expression as a whole and (subject to this constraint) to subexpressions within groups.
@node awk regular expression syntax
@subsection @samp{awk} regular expression syntax
The character @samp{.} matches any single character except the null character.
@table @samp
@item +
indicates that the regular expression should match one or more occurrences of the previous atom or regexp.
@item ?
indicates that the regular expression should match zero or one occurrence of the previous atom or regexp.
@item \+
matches a @samp{+}
@item \?
matches a @samp{?}.
@end table
Bracket expressions are used to match ranges of characters. Bracket expressions where the range is backward, for example @samp{[z-a]}, are invalid. Within square brackets, @samp{\} can be used to quote the following character. Character classes are supported; for example @samp{[[:digit:]]} will match a single decimal digit.
GNU extensions are not supported and so @samp{\w}, @samp{\W}, @samp{\<}, @samp{\>}, @samp{\b}, @samp{\B}, @samp{\`}, and @samp{\'} match @samp{w}, @samp{W}, @samp{<}, @samp{>}, @samp{b}, @samp{B}, @samp{`}, and @samp{'} respectively.
Grouping is performed with parentheses @samp{()}. An unmatched @samp{)} matches just itself. A backslash followed by a digit matches that digit.
The alternation operator is @samp{|}.
The characters @samp{^} and @samp{$} always represent the beginning and end of a string respectively, except within square brackets. Within brackets, @samp{^} can be used to invert the membership of the character class being specified.
@samp{*}, @samp{+} and @samp{?} are special at any point in a regular expression except:
@enumerate
@item At the beginning of a regular expression
@item After an open-group, signified by @samp{(}
@item After the alternation operator @samp{|}
@end enumerate
The longest possible match is returned; this applies to the regular expression as a whole and (subject to this constraint) to subexpressions within groups.
@ -567,68 +632,7 @@ The longest possible match is returned; this applies to the regular expression a
@node posix-egrep regular expression syntax
@subsection @samp{posix-egrep} regular expression syntax
The character @samp{.} matches any single character.
@table @samp
@item +
indicates that the regular expression should match one or more occurrences of the previous atom or regexp.
@item ?
indicates that the regular expression should match zero or one occurrence of the previous atom or regexp.
@item \+
matches a @samp{+}
@item \?
matches a @samp{?}.
@end table
Bracket expressions are used to match ranges of characters. Bracket expressions where the range is backward, for example @samp{[z-a]}, are invalid. Within square brackets, @samp{\} is taken literally. Character classes are supported; for example @samp{[[:digit:]]} will match a single decimal digit.
GNU extensions are supported:
@enumerate
@item @samp{\w} matches a character within a word
@item @samp{\W} matches a character which is not within a word
@item @samp{\<} matches the beginning of a word
@item @samp{\>} matches the end of a word
@item @samp{\b} matches a word boundary
@item @samp{\B} matches characters which are not a word boundary
@item @samp{\`} matches the beginning of the whole input
@item @samp{\'} matches the end of the whole input
@end enumerate
Grouping is performed with parentheses @samp{()}. An unmatched @samp{)} matches just itself. A backslash followed by a digit acts as a back-reference and matches the same thing as the previous grouped expression indicated by that number. For example @samp{\2} matches the second group expression. The order of group expressions is determined by the position of their opening parenthesis @samp{(}.
The alternation operator is @samp{|}.
The characters @samp{^} and @samp{$} always represent the beginning and end of a string respectively, except within square brackets. Within brackets, @samp{^} can be used to invert the membership of the character class being specified.
The characters @samp{*}, @samp{+} and @samp{?} are special anywhere in a regular expression.
Intervals are specified by @samp{@{} and @samp{@}}.
Invalid intervals are treated as literals, for example @samp{a@{1} is treated as @samp{a\@{1}
The longest possible match is returned; this applies to the regular expression as a whole and (subject to this constraint) to subexpressions within groups.
@node egrep regular expression syntax
@subsection @samp{egrep} regular expression syntax
This is a synonym for posix-egrep.
This is a synonym for egrep.
@node posix-extended regular expression syntax
@subsection @samp{posix-extended} regular expression syntax

View File

@ -1,4 +1,4 @@
## Copyright (C) 1996-2024 Free Software Foundation, Inc.
## Copyright (C) 1996-2026 Free Software Foundation, Inc.
## This program is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
@ -28,11 +28,11 @@ man_MANS = find.1
EXTRA_DIST = defs.h sharefile.h print.h $(man_MANS)
AM_CPPFLAGS = -I../gl/lib -I$(top_srcdir)/lib -I$(top_srcdir)/gl/lib -DLOCALEDIR=\"$(localedir)\"
LDADD = libfindtools.a ../lib/libfind.a ../gl/lib/libgnulib.a $(LIBINTL) $(LIB_CLOCK_GETTIME) $(LIB_EACCESS) $(LIB_SELINUX) $(LIB_CLOSE) $(MODF_LIBM) $(FINDLIBS) $(GETHOSTNAME_LIB) $(LIB_EACCESS) $(LIB_SETLOCALE_NULL) $(LIB_MBRTOWC)
LDADD = libfindtools.a ../lib/libfind.a ../gl/lib/libgnulib.a $(LIBINTL) $(CLOCK_TIME_LIB) $(EUIDACCESS_LIBGEN) $(LIB_SELINUX) $(MODF_LIBM) $(FINDLIBS) $(GETHOSTNAME_LIB) $(EUIDACCESS_LIBGEN) $(SETLOCALE_NULL_LIB) $(MBRTOWC_LIB)
# gnulib advises we link against <first> because we use <second>:
# $(GETHOSTNAME_LIB) uname
# $(LIB_CLOCK_GETTIME) (some indirect dependency)
# $(LIB_EACCESS) faccessat
# $(CLOCK_TIME_LIB) gettime
# $(EUIDACCESS_LIBGEN) faccessat
# $(LIB_SELINUX) selinux-h
# $(MODF_LIBM) modf
@ -40,7 +40,7 @@ SUBDIRS = . testsuite
noinst_PROGRAMS = getlimits
dist-hook: findutils-check-manpages
check-local: findutils-check-manpages
# Clean coverage files generated by running binaries built with
# gcc -fprofile-arcs -ftest-coverage
@ -50,4 +50,4 @@ coverage-clean:
clean-local: coverage-clean
findutils-check-manpages:
$(top_srcdir)/build-aux/man-lint.sh $(srcdir) $(man_MANS)
env GROFF=$(GROFF) $(top_srcdir)/build-aux/man-lint.sh $(srcdir) $(man_MANS)

View File

@ -1,5 +1,5 @@
/* defs.h -- data types and declarations.
Copyright (C) 1990-2024 Free Software Foundation, Inc.
Copyright (C) 1990-2026 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -38,14 +38,14 @@ Please stop compiling the program now
/* XXX: some of these includes probably don't belong in a common header file */
# include <sys/stat.h>
# include <stdio.h> /* for FILE* */
# include <stdio.h> /* for FILE* */
# include <string.h>
# include <stdlib.h>
# include <unistd.h>
# include <time.h>
# include <limits.h> /* for CHAR_BIT */
# include <stdbool.h> /* for bool */
# include <stdint.h> /* for uintmax_t */
# include <limits.h> /* for CHAR_BIT */
# include <stdbool.h> /* for bool */
# include <stdint.h> /* for uintmax_t */
# include <sys/stat.h> /* S_ISUID etc. */
# include <selinux/selinux.h>
@ -73,11 +73,11 @@ void set_stat_placeholders (struct stat *p);
int get_statinfo (const char *pathname, const char *name, struct stat *p);
# define MODE_WXUSR (S_IWUSR | S_IXUSR)
# define MODE_R (S_IRUSR | S_IRGRP | S_IROTH)
# define MODE_RW (S_IWUSR | S_IWGRP | S_IWOTH | MODE_R)
# define MODE_RWX (S_IXUSR | S_IXGRP | S_IXOTH | MODE_RW)
# define MODE_ALL (S_ISUID | S_ISGID | S_ISVTX | MODE_RWX)
# define MODE_WXUSR (S_IWUSR | S_IXUSR)
# define MODE_R (S_IRUSR | S_IRGRP | S_IROTH)
# define MODE_RW (S_IWUSR | S_IWGRP | S_IWOTH | MODE_R)
# define MODE_RWX (S_IXUSR | S_IXGRP | S_IXOTH | MODE_RW)
# define MODE_ALL (S_ISUID | S_ISGID | S_ISVTX | MODE_RWX)
struct predicate;
@ -87,7 +87,7 @@ struct options;
typedef bool (*PRED_FUNC)(const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr);
/* The number of seconds in a day. */
# define DAYSECS 86400
# define DAYSECS 86400
/* Argument structures for predicates. */
@ -128,7 +128,7 @@ enum predicate_precedence
struct long_val
{
enum comparison_type kind;
bool negative; /* Defined only when representing time_t. */
bool negative; /* Defined only when representing time_t. */
uintmax_t l_val;
};
@ -191,14 +191,14 @@ struct time_val
struct exec_val
{
bool multiple; /* -exec {} \+ denotes multiple argument. */
bool multiple; /* -exec {} \+ denotes multiple argument. */
struct buildcmd_control ctl;
struct buildcmd_state state;
char **replace_vec; /* Command arguments (for ";" style) */
char **replace_vec; /* Command arguments (for ";" style) */
int num_args;
bool close_stdin; /* If true, close stdin in the child. */
bool close_stdin; /* If true, close stdin in the child. */
struct saved_cwd *wd_for_exec; /* What directory to perform the exec in. */
int last_child_status; /* Status of the most recent child. */
int last_child_status; /* Status of the most recent child. */
};
/* The format string for a -printf or -fprintf is chopped into one or
@ -209,26 +209,26 @@ struct exec_val
/* Special values for the `kind' field of `struct segment'. */
enum SegmentKind
{
KIND_PLAIN=0, /* Segment containing just plain text. */
KIND_STOP=1, /* \c -- stop printing and flush output. */
KIND_FORMAT, /* Regular format */
KIND_PLAIN=0, /* Segment containing just plain text. */
KIND_STOP=1, /* \c -- stop printing and flush output. */
KIND_FORMAT, /* Regular format */
};
struct segment
{
enum SegmentKind segkind; /* KIND_FORMAT, KIND_PLAIN, KIND_STOP */
char format_char[2]; /* Format chars if kind is KIND_FORMAT */
char *text; /* Plain text or `%' format string. */
int text_len; /* Length of `text'. */
struct segment *next; /* Next segment for this predicate. */
char format_char[2]; /* Format chars if kind is KIND_FORMAT */
char *text; /* Plain text or `%' format string. */
int text_len; /* Length of `text'. */
struct segment *next; /* Next segment for this predicate. */
};
struct format_val
{
struct segment *segment; /* Linked list of segments. */
FILE *stream; /* Output stream to print on. */
const char *filename; /* We need the filename for error messages. */
bool dest_is_tty; /* True if the destination is a terminal. */
struct segment *segment; /* Linked list of segments. */
FILE *stream; /* Output stream to print on. */
const char *filename; /* We need the filename for error messages. */
bool dest_is_tty; /* True if the destination is a terminal. */
struct quoting_options *quote_opts;
};
@ -304,17 +304,17 @@ struct predicate
Next to each member are listed the predicates that use it. */
union
{
const char *str; /* fstype [i]lname [i]name [i]path */
const char *str; /* fstype [i]lname [i]name [i]path */
struct re_pattern_buffer *regex; /* regex */
struct exec_val exec_vec; /* exec ok */
struct long_val numinfo; /* gid inum links uid */
struct size_val size; /* size */
uid_t uid; /* user */
gid_t gid; /* group */
struct time_val reftime; /* newer newerXY anewer cnewer mtime atime ctime mmin amin cmin */
struct perm_val perm; /* perm */
struct exec_val exec_vec; /* exec ok */
struct long_val numinfo; /* gid inum links uid */
struct size_val size; /* size */
uid_t uid; /* user */
gid_t gid; /* group */
struct time_val reftime; /* newer newerXY anewer cnewer mtime atime ctime mmin amin cmin */
struct perm_val perm; /* perm */
struct samefile_file_id samefileid; /* samefile */
bool types[FTYPE_COUNT]; /* file type(s) */
bool types[FTYPE_COUNT]; /* file type(s) */
struct format_val printf_vec; /* printf fprintf fprint ls fls print0 fprint0 print */
char *scontext; /* security context */
} args;
@ -347,9 +347,9 @@ bool is_fts_cwdfd_enabled(void);
*/
enum SymlinkOption
{
SYMLINK_NEVER_DEREF, /* Option -P */
SYMLINK_ALWAYS_DEREF, /* Option -L */
SYMLINK_DEREF_ARGSONLY /* Option -H */
SYMLINK_NEVER_DEREF, /* Option -P */
SYMLINK_ALWAYS_DEREF, /* Option -L */
SYMLINK_DEREF_ARGSONLY /* Option -H */
};
void set_follow_state (enum SymlinkOption opt);
@ -364,20 +364,20 @@ dev_t * get_mounted_devices (size_t *);
enum arg_type
{
ARG_OPTION, /* regular options like -maxdepth */
ARG_NOOP, /* does nothing, returns true, internal use only */
ARG_POSITIONAL_OPTION, /* options whose position is important (-follow) */
ARG_TEST, /* a like -name */
ARG_SPECIAL_PARSE, /* complex to parse, don't eat the test name before calling parse_xx(). */
ARG_PUNCTUATION, /* like -o or ( */
ARG_ACTION /* like -print */
ARG_OPTION, /* regular options like -maxdepth */
ARG_NOOP, /* does nothing, returns true, internal use only */
ARG_POSITIONAL_OPTION, /* options whose position is important (-follow) */
ARG_TEST, /* a like -name */
ARG_SPECIAL_PARSE, /* complex to parse, don't eat the test name before calling parse_xx(). */
ARG_PUNCTUATION, /* like -o or ( */
ARG_ACTION /* like -print */
};
struct parser_table;
/* Pointer to a parser function. */
typedef bool (*PARSE_FUNC)(const struct parser_table *p,
char *argv[], int *arg_ptr);
char *argv[], int *arg_ptr);
struct parser_table
{
enum arg_type type;
@ -462,11 +462,6 @@ PREDICATEFUNCTION pred_context;
bool pred_quit (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
_GL_ATTRIBUTE_NORETURN;
char *find_pred_name (PRED_FUNC pred_func);
void print_predicate (FILE *fp, const struct predicate *p);
void print_tree (FILE*, struct predicate *node, int indent);
void print_list (FILE*, struct predicate *node);
@ -482,7 +477,7 @@ struct predicate * get_eval_tree (void);
struct predicate *get_new_pred_noarg (const struct parser_table *entry);
struct predicate *get_new_pred (const struct parser_table *entry);
struct predicate *get_new_pred_chk_op (const struct parser_table *entry,
const char *arg);
const char *arg);
float calculate_derived_rates (struct predicate *p);
/* util.c */
@ -507,7 +502,7 @@ int process_leading_options (int argc, char *argv[]);
void set_option_defaults (struct options *p);
# if 0
# define apply_predicate(pathname, stat_buf_ptr, node) \
# define apply_predicate(pathname, stat_buf_ptr, node) \
(*(node)->pred_func)((pathname), (stat_buf_ptr), (node))
# else
bool apply_predicate(const char *pathname, struct stat *stat_buf, struct predicate *p);
@ -554,8 +549,11 @@ struct options
are non-directories. */
bool no_leaf_check;
/* If true, skip files on other devices. */
bool mount;
/* If true, don't cross filesystem boundaries. */
bool stay_on_filesystem;
bool xdev;
/* If true, we ignore the problem where we find that a directory entry
* no longer exists by the time we get around to processing it.
@ -577,7 +575,7 @@ struct options
*/
bool posixly_correct;
struct timespec start_time; /* Time at start of execution. */
struct timespec start_time; /* Time at start of execution. */
/* Either one day before now (the default), or the start of today (if -daystart is given). */
struct timespec cur_day_start;
@ -585,7 +583,7 @@ struct options
/* If true, cur_day_start has been adjusted to the start of the day. */
bool full_days;
int output_block_size; /* Output block size. */
int output_block_size; /* Output block size. */
/* bitmask for debug options */
unsigned long debug_options;
@ -638,7 +636,7 @@ struct state
/* If true, we know the type of the current path. */
bool have_type;
mode_t type; /* this is the actual type */
mode_t type; /* this is the actual type */
/* The file being operated on, relative to the current directory.
Used for stat, readlink, remove, and opendir. */
@ -653,7 +651,7 @@ struct state
int starting_path_length;
/* If true, don't descend past current directory.
Can be set by -prune, -maxdepth, and -xdev/-mount. */
Can be set by -prune, -maxdepth, -mount and -xdev. */
bool stop_at_current_level;
/* Status value to return to system. */

View File

@ -1,5 +1,5 @@
/* exec.c -- Implementation of -exec, -execdir, -ok, -okdir.
Copyright (C) 1990-2024 Free Software Foundation, Inc.
Copyright (C) 1990-2026 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -64,30 +64,30 @@ record_exec_dir (struct exec_val *execp)
if (!execp->state.todo)
{
/* working directory not already known, so must be a *dir variant,
and this must be the first arg we added. However, this may
be -execdir foo {} \; (i.e. not multiple). */
and this must be the first arg we added. However, this may
be -execdir foo {} \; (i.e. not multiple). */
assert (!execp->state.todo);
/* Record the WD. If we're using -L or fts chooses to do so for
any other reason, state.cwd_dir_fd may in fact not be the
directory containing the target file. When this happens,
rel_path will contain directory components (since it is the
path from state.cwd_dir_fd to the target file).
any other reason, state.cwd_dir_fd may in fact not be the
directory containing the target file. When this happens,
rel_path will contain directory components (since it is the
path from state.cwd_dir_fd to the target file).
We deal with this by extracting any directory part and using
that to adjust what goes into execp->wd_for_exec.
We deal with this by extracting any directory part and using
that to adjust what goes into execp->wd_for_exec.
*/
if (strchr (state.rel_pathname, '/'))
{
char *dir = mdir_name (state.rel_pathname);
bool result = initialize_wd_for_exec (execp, state.cwd_dir_fd, dir);
free (dir);
return result;
}
{
char *dir = mdir_name (state.rel_pathname);
bool result = initialize_wd_for_exec (execp, state.cwd_dir_fd, dir);
free (dir);
return result;
}
else
{
return initialize_wd_for_exec (execp, state.cwd_dir_fd, ".");
}
{
return initialize_wd_for_exec (execp, state.cwd_dir_fd, ".");
}
}
return true;
}
@ -126,7 +126,7 @@ impl_pred_exec (const char *pathname,
target = buf = base_name (state.rel_pathname);
if ('/' == target[0])
{
/* find / execdir ls -d {} \; */
/* find / -execdir ls -d {} \; */
prefix = NULL;
pfxlen = 0;
}
@ -217,13 +217,13 @@ impl_pred_exec (const char *pathname,
Possible returns:
ret errno status(h) status(l)
ret errno status(h) status(l)
pid x signal# 0177 stopped
pid x exit arg 0 term by _exit
pid x 0 signal # term by signal
-1 EINTR parent got signal
-1 other some other kind of error
pid x signal# 0177 stopped
pid x exit arg 0 term by _exit
pid x 0 signal # term by signal
-1 EINTR parent got signal
-1 other some other kind of error
Return true only if the pid matches, status(l) is
zero, and the exit arg (status high) is 0.
@ -237,27 +237,27 @@ prep_child_for_exec (bool close_stdin, const struct saved_cwd *wd)
const char inputfile[] = "/dev/null";
if (close (0) < 0)
{
error (0, errno, _("Cannot close standard input"));
ok = false;
}
{
error (0, errno, _("Cannot close standard input"));
ok = false;
}
else
{
if (open (inputfile, O_RDONLY
{
if (open (inputfile, O_RDONLY
#if defined O_LARGEFILE
|O_LARGEFILE
|O_LARGEFILE
#endif
) < 0)
{
/* This is not entirely fatal, since
* executing the child with a closed
* stdin is almost as good as executing it
* with its stdin attached to /dev/null.
*/
error (0, errno, "%s", safely_quote_err_filename (0, inputfile));
/* do not set ok=false, it is OK to continue anyway. */
}
}
) < 0)
{
/* This is not entirely fatal, since
* executing the child with a closed
* stdin is almost as good as executing it
* with its stdin attached to /dev/null.
*/
error (0, errno, "%s", safely_quote_err_filename (0, inputfile));
/* do not set ok=false, it is OK to continue anyway. */
}
}
}
/* Even if DebugSearch is set, don't announce our change of
@ -268,8 +268,8 @@ prep_child_for_exec (bool close_stdin, const struct saved_cwd *wd)
if (0 != restore_cwd (wd))
{
error (0, errno, _("Failed to change directory%s%s"),
(wd->desc < 0 && wd->name) ? ": " : "",
(wd->desc < 0 && wd->name) ? wd->name : "");
(wd->desc < 0 && wd->name) ? ": " : "",
(wd->desc < 0 && wd->name) ? wd->name : "");
ok = false;
}
return ok;
@ -283,8 +283,8 @@ launch (struct buildcmd_control *ctl, void *usercontext, int argc, char **argv)
static int first_time = 1;
struct exec_val *execp = usercontext;
(void) ctl; /* silence compiler warning */
(void) argc; /* silence compiler warning */
(void) ctl; /* silence compiler warning */
(void) argc; /* silence compiler warning */
if (options.debug_options & DebugExec)
{
@ -292,10 +292,10 @@ launch (struct buildcmd_control *ctl, void *usercontext, int argc, char **argv)
fprintf (stderr, "DebugExec: launching process (argc=%" PRIuMAX "):",
(uintmax_t) execp->state.cmd_argc - 1);
for (i=0; i<execp->state.cmd_argc -1; ++i)
{
fprintf (stderr, " %s",
safely_quote_err_filename (0, execp->state.cmd_argv[i]));
}
{
fprintf (stderr, " %s",
safely_quote_err_filename (0, execp->state.cmd_argv[i]));
}
fprintf (stderr, "\n");
}
@ -318,54 +318,54 @@ launch (struct buildcmd_control *ctl, void *usercontext, int argc, char **argv)
/* We are the child. */
assert (NULL != execp->wd_for_exec);
if (!prep_child_for_exec (execp->close_stdin, execp->wd_for_exec))
{
_exit (1);
}
{
_exit (1);
}
else
{
if (fd_leak_check_is_enabled ())
{
complain_about_leaky_fds ();
}
}
{
if (fd_leak_check_is_enabled ())
{
complain_about_leaky_fds ();
}
}
if (bc_args_exceed_testing_limit (argv))
errno = E2BIG;
errno = E2BIG;
else
execvp (argv[0], argv);
execvp (argv[0], argv);
/* TODO: use a pipe to pass back the errno value, like xargs does */
error (0, errno, "%s",
safely_quote_err_filename (0, argv[0]));
safely_quote_err_filename (0, argv[0]));
_exit (1);
}
while (waitpid (child_pid, &(execp->last_child_status), 0) == (pid_t) -1)
{
if (errno != EINTR)
{
error (0, errno, _("error waiting for %s"),
safely_quote_err_filename (0, argv[0]));
state.exit_status = EXIT_FAILURE;
return 0; /* FAIL */
}
{
error (0, errno, _("error waiting for %s"),
safely_quote_err_filename (0, argv[0]));
state.exit_status = EXIT_FAILURE;
return 0; /* FAIL */
}
}
if (WIFSIGNALED (execp->last_child_status))
{
error (0, 0, _("%s terminated by signal %d"),
quotearg_n_style (0, options.err_quoting_style, argv[0]),
WTERMSIG (execp->last_child_status));
quotearg_n_style (0, options.err_quoting_style, argv[0]),
WTERMSIG (execp->last_child_status));
if (execp->multiple)
{
/* -exec \; just returns false if the invoked command fails.
* -exec {} + returns true if the invoked command fails, but
* sets the program exit status.
*/
state.exit_status = EXIT_FAILURE;
}
{
/* -exec \; just returns false if the invoked command fails.
* -exec {} + returns true if the invoked command fails, but
* sets the program exit status.
*/
state.exit_status = EXIT_FAILURE;
}
return 1; /* OK */
return 1; /* OK */
}
int ex = WEXITSTATUS (execp->last_child_status);
@ -380,22 +380,22 @@ launch (struct buildcmd_control *ctl, void *usercontext, int argc, char **argv)
if (0 == ex)
{
return 1; /* OK */
return 1; /* OK */
}
else
{
if (execp->multiple)
{
/* -exec \; just returns false if the invoked command fails.
* -exec {} + returns true if the invoked command fails, but
* sets the program exit status.
*/
state.exit_status = EXIT_FAILURE;
}
{
/* -exec \; just returns false if the invoked command fails.
* -exec {} + returns true if the invoked command fails, but
* sets the program exit status.
*/
state.exit_status = EXIT_FAILURE;
}
/* The child failed, but this is the exec callback. We
* don't want to run the child again in this case anwyay.
*/
return 1; /* FAIL (but don't try again) */
return 1; /* FAIL (but don't try again) */
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/* finddata.c -- global data for "find".
Copyright (C) 1990-2024 Free Software Foundation, Inc.
Copyright (C) 1990-2026 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@ -1,5 +1,5 @@
/* fstype.c -- determine type of file systems that files are on
Copyright (C) 1990-2024 Free Software Foundation, Inc.
Copyright (C) 1990-2026 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
@ -27,9 +27,6 @@
/* system headers. */
#include <errno.h>
#include <fcntl.h>
#if HAVE_MNTENT_H
# include <mntent.h>
#endif
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
@ -101,7 +98,7 @@ in_afs (char *path)
if (pioctl (path, VIOC_FILE_CELL_NAME, &vi, 1)
&& (errno == EINVAL || errno == ENOENT))
return 0;
return 0;
return 1;
}
#endif /* AFS */
@ -148,7 +145,7 @@ filesystem_type (const struct stat *statp, const char *path)
if (current_fstype != NULL)
{
if (fstype_known && statp->st_dev == current_dev)
return current_fstype; /* Cached value. */
return current_fstype; /* Cached value. */
free (current_fstype);
}
current_dev = statp->st_dev;
@ -162,25 +159,25 @@ is_used_fs_type(const char *name)
if (0 == strcmp("afs", name))
{
/* I guess AFS may not appear in /etc/mtab (or equivalent) but still be in use,
so assume we always need to check for AFS. */
so assume we always need to check for AFS. */
return true;
}
else
{
const struct mount_entry *entries = get_file_system_list(false);
if (entries)
{
const struct mount_entry *entry;
for (entry = entries; entry; entry = entry->me_next)
{
if (0 == strcmp(name, entry->me_type))
return true;
}
}
{
const struct mount_entry *entry;
for (entry = entries; entry; entry = entry->me_next)
{
if (0 == strcmp(name, entry->me_type))
return true;
}
}
else
{
return true;
}
{
return true;
}
}
return false;
}
@ -194,16 +191,16 @@ set_fstype_devno (struct mount_entry *p)
{
set_stat_placeholders (&stbuf);
if (0 == (options.xstat)(p->me_mountdir, &stbuf))
{
p->me_dev = stbuf.st_dev;
return 0;
}
{
p->me_dev = stbuf.st_dev;
return 0;
}
else
{
return -1;
}
{
return -1;
}
}
return 0; /* not needed */
return 0; /* not needed */
}
/* Return a newly allocated string naming the type of file system that the
@ -242,21 +239,21 @@ file_system_type_uncached (const struct stat *statp, const char *path,
{
#ifdef MNTTYPE_IGNORE
if (!strcmp (entry->me_type, MNTTYPE_IGNORE))
continue;
continue;
#endif
if (0 == set_fstype_devno (entry))
{
if (entry->me_dev == statp->st_dev)
{
best = entry;
/* Don't exit the loop, because some systems (for
example Linux-based systems in which /etc/mtab is a
symlink to /proc/mounts) can have duplicate entries
in the filesystem list. This happens most frequently
for /.
*/
}
}
{
if (entry->me_dev == statp->st_dev)
{
best = entry;
/* Don't exit the loop, because some systems (for
example Linux-based systems in which /etc/mtab is a
symlink to /proc/mounts) can have duplicate entries
in the filesystem list. This happens most frequently
for /.
*/
}
}
}
if (best)
{
@ -290,19 +287,19 @@ get_mounted_devices (size_t *n)
{
void *p = extendbuf (result, sizeof(dev_t)*(used+1), &alloc_size);
if (p)
{
result = p;
if (0 == set_fstype_devno (entry))
{
result[used] = entry->me_dev;
++used;
}
}
{
result = p;
if (0 == set_fstype_devno (entry))
{
result[used] = entry->me_dev;
++used;
}
}
else
{
free (result);
result = NULL;
}
{
free (result);
result = NULL;
}
}
free_file_system_list (entries);
if (result)

View File

@ -1,5 +1,5 @@
/* find -- search for files in a directory hierarchy (fts version)
Copyright (C) 1990-2024 Free Software Foundation, Inc.
Copyright (C) 1990-2026 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -81,10 +81,10 @@ left_dir (void)
if (ftsoptions & FTS_CWDFD)
{
if (curr_fd >= 0)
{
close (curr_fd);
curr_fd = -1;
}
{
close (curr_fd);
curr_fd = -1;
}
}
else
{
@ -106,23 +106,23 @@ inside_dir (int dir_fd)
state.cwd_dir_fd = dir_fd;
if (curr_fd < 0)
{
if (AT_FDCWD == dir_fd)
{
curr_fd = AT_FDCWD;
}
else if (dir_fd >= 0)
{
curr_fd = dup_cloexec (dir_fd);
}
else
{
/* curr_fd is invalid, but dir_fd is also invalid.
* This should not have happened.
*/
assert (curr_fd >= 0 || dir_fd >= 0);
}
}
{
if (AT_FDCWD == dir_fd)
{
curr_fd = AT_FDCWD;
}
else if (dir_fd >= 0)
{
curr_fd = dup_cloexec (dir_fd);
}
else
{
/* curr_fd is invalid, but dir_fd is also invalid.
* This should not have happened.
*/
assert (curr_fd >= 0 || dir_fd >= 0);
}
}
}
else
{
@ -188,27 +188,6 @@ visit (FTS *p, FTSENT *ent, struct stat *pstat)
}
}
static const char*
partial_quotearg_n (int n, char *s, size_t len, enum quoting_style style)
{
if (0 == len)
{
return quotearg_n_style (n, style, "");
}
else
{
char saved;
const char *result;
saved = s[len];
s[len] = 0;
result = quotearg_n_style (n, style, s);
s[len] = saved;
return result;
}
}
/* We've detected a file system loop. This is caused by one of
* two things:
*
@ -218,7 +197,7 @@ partial_quotearg_n (int n, char *s, size_t len, enum quoting_style style)
*
* 2. We have hit a real cycle in the directory hierarchy. In this
* case, we issue a diagnostic message (POSIX requires this) and we
* skip that directory entry.
* will skip that directory entry.
*/
static void
issue_loop_warning (FTSENT * ent)
@ -226,8 +205,8 @@ issue_loop_warning (FTSENT * ent)
if (S_ISLNK(ent->fts_statp->st_mode))
{
error (0, 0,
_("Symbolic link %s is part of a loop in the directory hierarchy; we have already visited the directory to which it points."),
safely_quote_err_filename (0, ent->fts_path));
_("Symbolic link %s is part of a loop in the directory hierarchy; we have already visited the directory to which it points."),
safely_quote_err_filename (0, ent->fts_path));
}
else
{
@ -240,13 +219,9 @@ issue_loop_warning (FTSENT * ent)
* to /a/b/c.
*/
error (0, 0,
_("File system loop detected; "
"%s is part of the same file system loop as %s."),
safely_quote_err_filename (0, ent->fts_path),
partial_quotearg_n (1,
ent->fts_cycle->fts_path,
ent->fts_cycle->fts_pathlen,
options.err_quoting_style));
_("File system loop detected; "
"the following directory is part of the cycle: %s"),
safely_quote_err_filename (0, ent->fts_path));
}
}
@ -274,14 +249,14 @@ consider_visiting (FTS *p, FTSENT *ent)
if (options.debug_options & DebugSearch)
fprintf (stderr,
"consider_visiting (early): %s: "
"fts_info=%-6s, fts_level=%2d, prev_depth=%d "
"fts_path=%s, fts_accpath=%s\n",
quotearg_n_style (0, options.err_quoting_style, ent->fts_path),
get_fts_info_name (ent->fts_info),
(int)ent->fts_level, prev_depth,
quotearg_n_style (1, options.err_quoting_style, ent->fts_path),
quotearg_n_style (2, options.err_quoting_style, ent->fts_accpath));
"consider_visiting (early): %s: "
"fts_info=%-6s, fts_level=%2d, prev_depth=%d "
"fts_path=%s, fts_accpath=%s\n",
quotearg_n_style (0, options.err_quoting_style, ent->fts_path),
get_fts_info_name (ent->fts_info),
(int)ent->fts_level, prev_depth,
quotearg_n_style (1, options.err_quoting_style, ent->fts_path),
quotearg_n_style (2, options.err_quoting_style, ent->fts_accpath));
if (ent->fts_info == FTS_DP)
{
@ -304,15 +279,18 @@ consider_visiting (FTS *p, FTSENT *ent)
}
if (ent->fts_info == FTS_DNR)
{
/* Ignore ENOENT error for vanished directories. */
if (ENOENT == ent->fts_errno && options.ignore_readdir_race)
return;
nonfatal_target_file_error (ent->fts_errno, ent->fts_path);
if (options.do_dir_first)
{
/* Return for unreadable directories without -depth.
* With -depth, the directory itself has to be processed, yet the
* error message above has to be output.
*/
return;
}
{
/* Return for unreadable directories without -depth.
* With -depth, the directory itself has to be processed, yet the
* error message above has to be output.
*/
return;
}
}
else if (ent->fts_info == FTS_DC)
{
@ -330,45 +308,49 @@ consider_visiting (FTS *p, FTSENT *ent)
* of the file (fts_path) in the error message.
*/
if (symlink_loop (ent->fts_accpath))
{
nonfatal_target_file_error (ELOOP, ent->fts_path);
return;
}
{
nonfatal_target_file_error (ELOOP, ent->fts_path);
return;
}
}
else if (ent->fts_info == FTS_NS)
{
if (ent->fts_level == 0)
{
/* e.g., nonexistent starting point */
nonfatal_target_file_error (ent->fts_errno, ent->fts_path);
return;
}
{
/* e.g., nonexistent starting point */
nonfatal_target_file_error (ent->fts_errno, ent->fts_path);
return;
}
else
{
/* The following if statement fixes Savannah bug #19605
* (failure to diagnose a symbolic link loop)
*/
if (symlink_loop (ent->fts_accpath))
{
nonfatal_target_file_error (ELOOP, ent->fts_path);
return;
}
else
{
nonfatal_target_file_error (ent->fts_errno, ent->fts_path);
/* Continue despite the error, as file name without stat info
* might be better than not even processing the file name. This
* can lead to repeated error messages later on, though, if a
* predicate requires stat information.
*
* Not printing an error message here would be even more wrong,
* though, as this could cause the contents of a directory to be
* silently ignored, as the directory wouldn't be identified as
* such.
*/
}
{
/* The following if statement fixes Savannah bug #19605
* (failure to diagnose a symbolic link loop)
*/
if (symlink_loop (ent->fts_accpath))
{
nonfatal_target_file_error (ELOOP, ent->fts_path);
return;
}
else
{
/* Ignore ENOENT error for vanished files. */
if (ENOENT == ent->fts_errno && options.ignore_readdir_race)
return;
}
nonfatal_target_file_error (ent->fts_errno, ent->fts_path);
/* Continue despite the error, as file name without stat info
* might be better than not even processing the file name. This
* can lead to repeated error messages later on, though, if a
* predicate requires stat information.
*
* Not printing an error message here would be even more wrong,
* though, as this could cause the contents of a directory to be
* silently ignored, as the directory wouldn't be identified as
* such.
*/
}
}
}
/* Cope with the usual cases. */
@ -387,11 +369,11 @@ consider_visiting (FTS *p, FTSENT *ent)
state.type = mode = statbuf.st_mode;
if (00000 == mode)
{
/* Savannah bug #16378. */
error (0, 0, _("WARNING: file %s appears to have mode 0000"),
quotearg_n_style (0, options.err_quoting_style, ent->fts_path));
}
{
/* Savannah bug #16378. */
error (0, 0, _("WARNING: file %s appears to have mode 0000"),
quotearg_n_style (0, options.err_quoting_style, ent->fts_path));
}
}
/* update state.curdepth before calling digest_mode(), because digest_mode
@ -401,7 +383,7 @@ consider_visiting (FTS *p, FTSENT *ent)
if (mode)
{
if (!digest_mode (&mode, ent->fts_path, ent->fts_name, &statbuf, 0))
return;
return;
}
/* examine this item. */
@ -425,12 +407,12 @@ consider_visiting (FTS *p, FTSENT *ent)
if (options.maxdepth >= 0)
{
if (ent->fts_level >= options.maxdepth)
{
fts_set (p, ent, FTS_SKIP); /* descend no further */
{
fts_set (p, ent, FTS_SKIP); /* descend no further */
if (ent->fts_level > options.maxdepth)
ignore = 1; /* don't even look at this one */
}
if (ent->fts_level > options.maxdepth)
ignore = 1; /* don't even look at this one */
}
}
if ( (ent->fts_info == FTS_D) && !options.do_dir_first )
@ -450,11 +432,11 @@ consider_visiting (FTS *p, FTSENT *ent)
if (options.debug_options & DebugSearch)
fprintf (stderr,
"consider_visiting (late): %s: "
"fts_info=%-6s, isdir=%d ignore=%d have_stat=%d have_type=%d \n",
quotearg_n_style (0, options.err_quoting_style, ent->fts_path),
get_fts_info_name (ent->fts_info),
isdir, ignore, state.have_stat, state.have_type);
"consider_visiting (late): %s: "
"fts_info=%-6s, isdir=%d ignore=%d have_stat=%d have_type=%d \n",
quotearg_n_style (0, options.err_quoting_style, ent->fts_path),
get_fts_info_name (ent->fts_info),
isdir, ignore, state.have_stat, state.have_type);
if (!ignore)
{
@ -498,14 +480,17 @@ find (char *arg)
break;
}
if (options.stay_on_filesystem)
if (options.mount)
ftsoptions |= FTS_MOUNT;
if (options.xdev)
ftsoptions |= FTS_XDEV;
p = fts_open (arglist, ftsoptions, NULL);
if (NULL == p)
{
error (0, errno, _("cannot search %s"),
safely_quote_err_filename (0, arg));
safely_quote_err_filename (0, arg));
state.exit_status = EXIT_FAILURE;
}
else
@ -513,48 +498,48 @@ find (char *arg)
int level = INT_MIN;
while ( (errno=0, ent=fts_read (p)) != NULL )
{
if (state.execdirs_outstanding && ((int)ent->fts_level != level))
{
/* If we changed level, perform any outstanding
* execdirs. If we see a sequence of directory entries
* like this: fffdfffdfff, we could build a command line
* of 9 files, but this simple-minded implementation
* builds a command line for only 3 files at a time
* (since fts descends into the directories).
*/
complete_pending_execdirs ();
}
level = (int)ent->fts_level;
{
if (state.execdirs_outstanding && ((int)ent->fts_level != level))
{
/* If we changed level, perform any outstanding
* execdirs. If we see a sequence of directory entries
* like this: fffdfffdfff, we could build a command line
* of 9 files, but this simple-minded implementation
* builds a command line for only 3 files at a time
* (since fts descends into the directories).
*/
complete_pending_execdirs ();
}
level = (int)ent->fts_level;
state.already_issued_stat_error_msg = false;
state.have_stat = false;
state.have_type = !!ent->fts_statp->st_mode;
state.type = state.have_type ? ent->fts_statp->st_mode : 0;
consider_visiting (p, ent);
}
state.already_issued_stat_error_msg = false;
state.have_stat = false;
state.have_type = !!ent->fts_statp->st_mode;
state.type = state.have_type ? ent->fts_statp->st_mode : 0;
consider_visiting (p, ent);
}
/* fts_read returned NULL; distinguish between "finished" and "error". */
if (errno)
{
error (0, errno,
"failed to read file names from file system at or below %s",
safely_quote_err_filename (0, arg));
state.exit_status = EXIT_FAILURE;
return false;
}
{
error (0, errno,
"failed to read file names from file system at or below %s",
safely_quote_err_filename (0, arg));
state.exit_status = EXIT_FAILURE;
return false;
}
if (0 != fts_close (p))
{
/* Here we break the abstraction of fts_close a bit, because we
* are going to skip the rest of the start points, and return with
* nonzero exit status. Hence we need to issue a diagnostic on
* stderr. */
error (0, errno,
_("failed to restore working directory after searching %s"),
arg);
state.exit_status = EXIT_FAILURE;
return false;
}
{
/* Here we break the abstraction of fts_close a bit, because we
* are going to skip the rest of the start points, and return with
* nonzero exit status. Hence we need to issue a diagnostic on
* stderr. */
error (0, errno,
_("failed to restore working directory after searching %s"),
arg);
state.exit_status = EXIT_FAILURE;
return false;
}
p = NULL;
}
return true;
@ -636,7 +621,7 @@ process_all_startpoints (int argc, char *argv[])
{
if (!argv_starting_points)
{
/* If no starting points are given on the comman line, then
/* If no starting points are given on the command line, then
* fall back to processing the current directory, i.e., ".".
* We use a temporary variable here because some actions modify
* the path temporarily. Hence if we use a string constant,
@ -752,7 +737,7 @@ main (int argc, char **argv)
if (NULL == state.shared_files)
{
error (EXIT_FAILURE, errno,
_("Failed to initialize shared-file hash table"));
_("Failed to initialize shared-file hash table"));
}
/* Set the option defaults before we do the locale initialisation as
@ -812,7 +797,7 @@ main (int argc, char **argv)
* the wrong directory for example.
*/
if (process_all_startpoints (argc-end_of_leading_options,
argv+end_of_leading_options))
argv+end_of_leading_options))
{
/* If "-exec ... {} +" has been used, there may be some
* partially-full command lines which have been built,

View File

@ -1,5 +1,5 @@
/* getlimits - print various platform dependent limits.
Copyright (C) 2023-2024 Free Software Foundation, Inc.
Copyright (C) 2023-2026 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -38,6 +38,11 @@
# define MIN(a,b) (a<b?a:b)
#endif
/* Silence GCC 14. */
#if 14 <= __GNUC__
# pragma GCC diagnostic ignored "-Wanalyzer-out-of-bounds"
#endif
/* Add one to the absolute value of the number whose textual
representation is BUF + 1. Do this in-place, in the buffer.
Return a pointer to the result, which is normally BUF + 1, but is

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/* pred.c -- execute the expression tree.
Copyright (C) 1990-2024 Free Software Foundation, Inc.
Copyright (C) 1990-2026 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -63,7 +63,7 @@ static bool match_lname (const char *pathname, struct stat *stat_buf, struct pre
/* Returns ts1 - ts2 */
static double ts_difference (struct timespec ts1,
struct timespec ts2)
struct timespec ts2)
{
double d = difftime (ts1.tv_sec, ts2.tv_sec)
+ (1.0e-9 * (ts1.tv_nsec - ts2.tv_nsec));
@ -73,7 +73,7 @@ static double ts_difference (struct timespec ts1,
static int
compare_ts (struct timespec ts1,
struct timespec ts2)
struct timespec ts2)
{
if ((ts1.tv_sec == ts2.tv_sec) &&
(ts1.tv_nsec == ts2.tv_nsec))
@ -116,21 +116,21 @@ pred_timewindow (struct timespec ts, struct predicate const *pred_ptr, int windo
case COMP_EQ:
{
/* consider "find . -mtime 0".
*
* Here, the origin is exactly 86400 seconds before the start
* of the program (since -daystart was not specified). This
* function will be called with window=86400 and
* pred_ptr->args.reftime.ts as the origin. Hence a file
* created the instant the program starts will show a time
* difference (value of delta) of 86400. Similarly, a file
* created exactly 24h ago would be the newest file which was
* _not_ created today. So, if delta is 0.0, the file
* was not created today. If the delta is 86400, the file
* was created this instant.
*/
double delta = ts_difference (ts, pred_ptr->args.reftime.ts);
return (delta > 0.0 && delta <= window);
/* consider "find . -mtime 0".
*
* Here, the origin is exactly 86400 seconds before the start
* of the program (since -daystart was not specified). This
* function will be called with window=86400 and
* pred_ptr->args.reftime.ts as the origin. Hence a file
* created the instant the program starts will show a time
* difference (value of delta) of 86400. Similarly, a file
* created exactly 24h ago would be the newest file which was
* _not_ created today. So, if delta is 0.0, the file
* was not created today. If the delta is 86400, the file
* was created this instant.
*/
double delta = ts_difference (ts, pred_ptr->args.reftime.ts);
return (delta > 0.0 && delta <= window);
}
}
assert (0);
@ -231,32 +231,32 @@ pred_delete (const char *pathname, struct stat *stat_buf, struct predicate *pred
{
int flags=0;
if (state.have_stat && S_ISDIR(stat_buf->st_mode))
flags |= AT_REMOVEDIR;
flags |= AT_REMOVEDIR;
if (perform_delete (flags))
{
return true;
}
{
return true;
}
else
{
if (ENOENT == errno && options.ignore_readdir_race)
{
/* Ignore unlink() error for vanished files. */
errno = 0;
return true;
}
if (EISDIR == errno)
{
if ((flags & AT_REMOVEDIR) == 0)
{
/* unlink() operation failed because we should have done rmdir(). */
flags |= AT_REMOVEDIR;
if (perform_delete (flags))
return true;
}
}
}
{
if (ENOENT == errno && options.ignore_readdir_race)
{
/* Ignore unlink() error for vanished files. */
errno = 0;
return true;
}
if (EISDIR == errno)
{
if ((flags & AT_REMOVEDIR) == 0)
{
/* unlink() operation failed because we should have done rmdir(). */
flags |= AT_REMOVEDIR;
if (perform_delete (flags))
return true;
}
}
}
error (0, errno, _("cannot delete %s"),
safely_quote_err_filename (0, pathname));
safely_quote_err_filename (0, pathname));
/* Previously I had believed that having the -delete action
* return false provided the user with control over whether an
* error message is issued. While this is true, the policy of
@ -277,6 +277,27 @@ pred_delete (const char *pathname, struct stat *stat_buf, struct predicate *pred
}
}
static bool
compare_num (enum comparison_type kind, uintmax_t l_val, uintmax_t val)
{
switch (kind)
{
case COMP_GT:
if (val > l_val)
return true;
break;
case COMP_LT:
if (val < l_val)
return true;
break;
case COMP_EQ:
if (val == l_val)
return true;
break;
}
return false;
}
bool
pred_empty (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
{
@ -293,49 +314,49 @@ pred_empty (const char *pathname, struct stat *stat_buf, struct predicate *pred_
errno = 0;
if ((fd = openat (state.cwd_dir_fd, state.rel_pathname, O_RDONLY
#if defined O_LARGEFILE
| O_LARGEFILE
| O_LARGEFILE
#endif
| O_CLOEXEC | O_DIRECTORY | O_NOCTTY | O_NONBLOCK)) < 0)
{
error (0, errno, "%s", safely_quote_err_filename (0, pathname));
state.exit_status = EXIT_FAILURE;
return false;
}
| O_CLOEXEC | O_DIRECTORY | O_NOCTTY | O_NONBLOCK)) < 0)
{
error (0, errno, "%s", safely_quote_err_filename (0, pathname));
state.exit_status = EXIT_FAILURE;
return false;
}
d = fdopendir (fd);
if (d == NULL)
{
error (0, errno, "%s", safely_quote_err_filename (0, pathname));
state.exit_status = EXIT_FAILURE;
close (fd);
return false;
}
{
error (0, errno, "%s", safely_quote_err_filename (0, pathname));
state.exit_status = EXIT_FAILURE;
close (fd);
return false;
}
/* errno is not touched in the loop body, so initializing it here
* once before the loop is enough to detect readdir(3) errors. */
errno = 0;
for (dp = readdir (d); dp; dp = readdir (d))
{
if (dp->d_name[0] != '.'
|| (dp->d_name[1] != '\0'
&& (dp->d_name[1] != '.' || dp->d_name[2] != '\0')))
{
empty = false;
break;
}
}
{
if (dp->d_name[0] != '.'
|| (dp->d_name[1] != '\0'
&& (dp->d_name[1] != '.' || dp->d_name[2] != '\0')))
{
empty = false;
break;
}
}
if (errno)
{
/* Handle errors from readdir(3). */
error (0, errno, "%s", safely_quote_err_filename (0, pathname));
state.exit_status = EXIT_FAILURE;
CLOSEDIR (d);
return false;
}
{
/* Handle errors from readdir(3). */
error (0, errno, "%s", safely_quote_err_filename (0, pathname));
state.exit_status = EXIT_FAILURE;
CLOSEDIR (d);
return false;
}
if (CLOSEDIR (d))
{
error (0, errno, "%s", safely_quote_err_filename (0, pathname));
state.exit_status = EXIT_FAILURE;
return false;
}
{
error (0, errno, "%s", safely_quote_err_filename (0, pathname));
state.exit_status = EXIT_FAILURE;
return false;
}
return (empty);
}
else if (S_ISREG (stat_buf->st_mode))
@ -374,9 +395,9 @@ pred_fls (const char *pathname, struct stat *stat_buf, struct predicate *pred_pt
{
FILE * stream = pred_ptr->args.printf_vec.stream;
list_file (pathname, state.cwd_dir_fd, state.rel_pathname, stat_buf,
options.start_time.tv_sec,
options.output_block_size,
options.literal_control_chars, stream);
options.start_time.tv_sec,
options.output_block_size,
options.literal_control_chars, stream);
return true;
}
@ -387,10 +408,10 @@ pred_fprint (const char *pathname, struct stat *stat_buf, struct predicate *pred
(void) &stat_buf;
print_quoted (pred_ptr->args.printf_vec.stream,
pred_ptr->args.printf_vec.quote_opts,
pred_ptr->args.printf_vec.dest_is_tty,
"%s\n",
pathname);
pred_ptr->args.printf_vec.quote_opts,
pred_ptr->args.printf_vec.dest_is_tty,
"%s\n",
pathname);
return true;
}
@ -424,22 +445,9 @@ pred_gid (const char *pathname, struct stat *stat_buf, struct predicate *pred_pt
{
(void) pathname;
switch (pred_ptr->args.numinfo.kind)
{
case COMP_GT:
if (stat_buf->st_gid > pred_ptr->args.numinfo.l_val)
return (true);
break;
case COMP_LT:
if (stat_buf->st_gid < pred_ptr->args.numinfo.l_val)
return (true);
break;
case COMP_EQ:
if (stat_buf->st_gid == pred_ptr->args.numinfo.l_val)
return (true);
break;
}
return (false);
return compare_num (pred_ptr->args.numinfo.kind,
pred_ptr->args.numinfo.l_val,
stat_buf->st_gid);
}
bool
@ -496,22 +504,9 @@ pred_inum (const char *pathname, struct stat *stat_buf, struct predicate *pred_p
{
(void) pathname;
switch (pred_ptr->args.numinfo.kind)
{
case COMP_GT:
if (stat_buf->st_ino > pred_ptr->args.numinfo.l_val)
return (true);
break;
case COMP_LT:
if (stat_buf->st_ino < pred_ptr->args.numinfo.l_val)
return (true);
break;
case COMP_EQ:
if (stat_buf->st_ino == pred_ptr->args.numinfo.l_val)
return (true);
break;
}
return (false);
return compare_num (pred_ptr->args.numinfo.kind,
pred_ptr->args.numinfo.l_val,
stat_buf->st_ino);
}
bool
@ -529,22 +524,9 @@ pred_links (const char *pathname, struct stat *stat_buf, struct predicate *pred_
{
(void) pathname;
switch (pred_ptr->args.numinfo.kind)
{
case COMP_GT:
if (stat_buf->st_nlink > pred_ptr->args.numinfo.l_val)
return (true);
break;
case COMP_LT:
if (stat_buf->st_nlink < pred_ptr->args.numinfo.l_val)
return (true);
break;
case COMP_EQ:
if (stat_buf->st_nlink == pred_ptr->args.numinfo.l_val)
return (true);
break;
}
return (false);
return compare_num (pred_ptr->args.numinfo.kind,
pred_ptr->args.numinfo.l_val,
stat_buf->st_nlink);
}
bool
@ -562,16 +544,16 @@ match_lname (const char *pathname, struct stat *stat_buf, struct predicate *pred
{
char *linkname = areadlinkat (state.cwd_dir_fd, state.rel_pathname);
if (linkname)
{
if (fnmatch (pred_ptr->args.str, linkname,
ignore_case ? FNM_CASEFOLD : 0) == 0)
ret = true;
}
{
if (fnmatch (pred_ptr->args.str, linkname,
ignore_case ? FNM_CASEFOLD : 0) == 0)
ret = true;
}
else
{
nonfatal_target_file_error (errno, pathname);
state.exit_status = EXIT_FAILURE;
}
{
nonfatal_target_file_error (errno, pathname);
state.exit_status = EXIT_FAILURE;
}
free (linkname);
}
#endif /* S_ISLNK */
@ -643,12 +625,12 @@ pred_newerXY (const char *pathname, struct stat *stat_buf, struct predicate *pre
ts = get_stat_birthtime (stat_buf);
collected = true;
if (ts.tv_nsec < 0)
{
/* XXX: Cannot determine birth time. Warn once. */
error (0, 0, _("WARNING: cannot determine birth time of file %s"),
safely_quote_err_filename (0, pathname));
return false;
}
{
/* XXX: Cannot determine birth time. Warn once. */
error (0, 0, _("WARNING: cannot determine birth time of file %s"),
safely_quote_err_filename (0, pathname));
return false;
}
break;
case XVAL_CTIME:
@ -783,9 +765,9 @@ pred_perm (const char *pathname, struct stat *stat_buf, struct predicate *pred_p
*/
if (0 == perm_val)
return true; /* Savannah bug 14748; we used to return false */
return true; /* Savannah bug 14748; we used to return false */
else
return (mode & perm_val) != 0;
return (mode & perm_val) != 0;
break;
case PERM_EXACT:
@ -839,9 +821,9 @@ pred_print (const char *pathname, struct stat *stat_buf, struct predicate *pred_
(void) pred_ptr;
print_quoted (pred_ptr->args.printf_vec.stream,
pred_ptr->args.printf_vec.quote_opts,
pred_ptr->args.printf_vec.dest_is_tty,
"%s\n", pathname);
pred_ptr->args.printf_vec.quote_opts,
pred_ptr->args.printf_vec.dest_is_tty,
"%s\n", pathname);
return true;
}
@ -860,7 +842,7 @@ pred_prune (const char *pathname, struct stat *stat_buf, struct predicate *pred_
if (options.do_dir_first == true) { /* no effect with -depth */
assert (state.have_stat);
if (stat_buf != NULL &&
S_ISDIR(stat_buf->st_mode))
S_ISDIR(stat_buf->st_mode))
state.stop_at_current_level = true;
}
@ -886,7 +868,7 @@ pred_quit (const char *pathname, struct stat *stat_buf, struct predicate *pred_p
/* Since -exec and friends don't leave child processes running in the
* background, there is no need to wait for them here.
*/
exit (state.exit_status); /* 0 for success, etc. */
exit (state.exit_status); /* 0 for success, etc. */
}
bool
@ -895,7 +877,7 @@ pred_regex (const char *pathname, struct stat *stat_buf, struct predicate *pred_
int len = strlen (pathname);
(void) stat_buf;
if (re_match (pred_ptr->args.regex, pathname, len, 0,
(struct re_registers *) NULL) == len)
(struct re_registers *) NULL) == len)
return (true);
return (false);
}
@ -907,23 +889,11 @@ pred_size (const char *pathname, struct stat *stat_buf, struct predicate *pred_p
(void) pathname;
f_val = ((stat_buf->st_size / pred_ptr->args.size.blocksize)
+ (stat_buf->st_size % pred_ptr->args.size.blocksize != 0));
switch (pred_ptr->args.size.kind)
{
case COMP_GT:
if (f_val > pred_ptr->args.size.size)
return (true);
break;
case COMP_LT:
if (f_val < pred_ptr->args.size.size)
return (true);
break;
case COMP_EQ:
if (f_val == pred_ptr->args.size.size)
return (true);
break;
}
return (false);
+ (stat_buf->st_size % pred_ptr->args.size.blocksize != 0));
return compare_num (pred_ptr->args.size.kind,
pred_ptr->args.size.size,
f_val);
}
bool
@ -951,14 +921,14 @@ pred_samefile (const char *pathname, struct stat *stat_buf, struct predicate *pr
if (stat_buf->st_ino)
{
if (stat_buf->st_ino != pred_ptr->args.samefileid.ino)
return false;
return false;
}
/* Now stat the file to check the device number. */
if (0 == get_statinfo (pathname, state.rel_pathname, stat_buf))
{
/* the repeated test here is necessary in case stat_buf.st_ino had been zero. */
return stat_buf->st_ino == pred_ptr->args.samefileid.ino
&& stat_buf->st_dev == pred_ptr->args.samefileid.dev;
&& stat_buf->st_dev == pred_ptr->args.samefileid.dev;
}
else
{
@ -1076,22 +1046,9 @@ bool
pred_uid (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
{
(void) pathname;
switch (pred_ptr->args.numinfo.kind)
{
case COMP_GT:
if (stat_buf->st_uid > pred_ptr->args.numinfo.l_val)
return (true);
break;
case COMP_LT:
if (stat_buf->st_uid < pred_ptr->args.numinfo.l_val)
return (true);
break;
case COMP_EQ:
if (stat_buf->st_uid == pred_ptr->args.numinfo.l_val)
return (true);
break;
}
return (false);
return compare_num (pred_ptr->args.numinfo.kind,
pred_ptr->args.numinfo.l_val,
stat_buf->st_uid);
}
bool
@ -1146,7 +1103,7 @@ err_signals_broken_link(int errno_value)
bool
pred_xtype (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
{
struct stat sbuf; /* local copy, not stat_buf because we're using a different stat method */
struct stat sbuf; /* local copy, not stat_buf because we're using a different stat method */
int (*ystat) (const char*, struct stat *p);
@ -1163,18 +1120,18 @@ pred_xtype (const char *pathname, struct stat *stat_buf, struct predicate *pred_
if ((*ystat) (state.rel_pathname, &sbuf) != 0)
{
if (ystat_follows_links && err_signals_broken_link (errno))
{
/* If we failed to follow the symlink,
* fall back on looking at the symlink itself.
*/
/* Mimic behavior of ls -lL. */
return pred_type (pathname, stat_buf, pred_ptr);
}
{
/* If we failed to follow the symlink,
* fall back on looking at the symlink itself.
*/
/* Mimic behavior of ls -lL. */
return pred_type (pathname, stat_buf, pred_ptr);
}
else
{
error (0, errno, "%s", safely_quote_err_filename (0, pathname));
state.exit_status = EXIT_FAILURE;
}
{
error (0, errno, "%s", safely_quote_err_filename (0, pathname));
state.exit_status = EXIT_FAILURE;
}
return false;
}
/* Now that we have our stat() information, query it in the same
@ -1186,17 +1143,17 @@ pred_xtype (const char *pathname, struct stat *stat_buf, struct predicate *pred_
bool
pred_context (const char *pathname, struct stat *stat_buf,
struct predicate *pred_ptr)
struct predicate *pred_ptr)
{
char *scontext;
int rv = (*options.x_getfilecon) (state.cwd_dir_fd, state.rel_pathname,
&scontext);
&scontext);
(void) stat_buf;
if (rv < 0)
{
error (0, errno, _("getfilecon failed: %s"),
safely_quote_err_filename (0, pathname));
safely_quote_err_filename (0, pathname));
return false;
}
@ -1248,24 +1205,24 @@ print_parenthesised (FILE *fp, struct predicate *node)
if (node)
{
if ((pred_is (node, pred_or) || pred_is (node, pred_and))
&& node->pred_left == NULL)
{
/* We print "<nothing> or X" as just "X"
* We print "<nothing> and X" as just "X"
*/
print_parenthesised(fp, node->pred_right);
}
&& node->pred_left == NULL)
{
/* We print "<nothing> or X" as just "X"
* We print "<nothing> and X" as just "X"
*/
print_parenthesised(fp, node->pred_right);
}
else
{
if (node->pred_left || node->pred_right)
parens = 1;
{
if (node->pred_left || node->pred_right)
parens = 1;
if (parens)
fprintf (fp, "%s", " ( ");
print_optlist (fp, node);
if (parens)
fprintf (fp, "%s", " ) ");
}
if (parens)
fprintf (fp, "%s", " ( ");
print_optlist (fp, node);
if (parens)
fprintf (fp, "%s", " ) ");
}
}
}
@ -1343,52 +1300,52 @@ pred_sanity_check (const struct predicate *predicates)
* the parse_xxx function fills it in, so we can't check it.
*/
if (p->parser_entry->pred_func)
{
assert (p->parser_entry->pred_func == p->pred_func);
}
{
assert (p->parser_entry->pred_func == p->pred_func);
}
switch (p->parser_entry->type)
{
/* Options all take effect during parsing, so there should
* be no predicate entries corresponding to them. Hence we
* should not see any ARG_OPTION or ARG_POSITIONAL_OPTION
* items.
*
* This is a silly way of coding this test, but it prevents
* a compiler warning (i.e. otherwise it would think that
* there would be case statements missing).
*/
case ARG_OPTION:
case ARG_POSITIONAL_OPTION:
assert (p->parser_entry->type != ARG_OPTION);
assert (p->parser_entry->type != ARG_POSITIONAL_OPTION);
break;
{
/* Options all take effect during parsing, so there should
* be no predicate entries corresponding to them. Hence we
* should not see any ARG_OPTION or ARG_POSITIONAL_OPTION
* items.
*
* This is a silly way of coding this test, but it prevents
* a compiler warning (i.e. otherwise it would think that
* there would be case statements missing).
*/
case ARG_OPTION:
case ARG_POSITIONAL_OPTION:
assert (p->parser_entry->type != ARG_OPTION);
assert (p->parser_entry->type != ARG_POSITIONAL_OPTION);
break;
case ARG_ACTION:
assert (p->side_effects); /* actions have side effects. */
if (!pred_is (p, pred_prune) && !pred_is(p, pred_quit))
{
/* actions other than -prune and -quit should
* inhibit the default -print
*/
assert (p->no_default_print);
}
break;
case ARG_ACTION:
assert (p->side_effects); /* actions have side effects. */
if (!pred_is (p, pred_prune) && !pred_is(p, pred_quit))
{
/* actions other than -prune and -quit should
* inhibit the default -print
*/
assert (p->no_default_print);
}
break;
/* We happen to know that the only user of ARG_SPECIAL_PARSE
* is a test, so handle it like ARG_TEST.
*/
case ARG_SPECIAL_PARSE:
case ARG_TEST:
case ARG_PUNCTUATION:
case ARG_NOOP:
/* Punctuation and tests should have no side
* effects and not inhibit default print.
*/
assert (!p->no_default_print);
assert (!p->side_effects);
break;
}
/* We happen to know that the only user of ARG_SPECIAL_PARSE
* is a test, so handle it like ARG_TEST.
*/
case ARG_SPECIAL_PARSE:
case ARG_TEST:
case ARG_PUNCTUATION:
case ARG_NOOP:
/* Punctuation and tests should have no side
* effects and not inhibit default print.
*/
assert (!p->no_default_print);
assert (!p->side_effects);
break;
}
}
}
#endif

View File

@ -1,5 +1,5 @@
/* print.c -- print/printf-related code.
Copyright (C) 1990-2024 Free Software Foundation, Inc.
Copyright (C) 1990-2026 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -588,7 +588,7 @@ format_date (struct timespec ts, int kind)
* For example, some systems return junk in the tv_nsec part of
* st_birthtime. An example of this is the NetBSD-4.0-RELENG kernel
* (at Sat Mar 24 18:46:46 2007) running a NetBSD-3.1-RELEASE
* runtime and examining files on an msdos filesytem. So for that
* runtime and examining files on an msdos filesystem. So for that
* reason we set NS_BUF_LEN to 32, which is simply "long enough" as
* opposed to "exactly the right size". Note that the behaviour of
* NetBSD appears to be a result of the use of uninitialized data,
@ -698,7 +698,7 @@ format_date (struct timespec ts, int kind)
*--p = '-'; /* XXX: Ugh, relying on internal details of human_readable(). */
/* Add the nanoseconds part. Because we cannot enforce a
* particlar implementation of human_readable, we cannot assume
* particular implementation of human_readable, we cannot assume
* any particular value for (p-buf). So we need to be careful
* that there is enough space remaining in the buffer.
*/
@ -1250,14 +1250,14 @@ do_fprintf (struct format_val *dest,
break;
case 0:
/* Trailing single %. This should have been rejected by
insert_fprintf. We use %s here in the error message
simply to ensure that the error message matches the one
in insert_fprintf, easing the translation burden.
*/
error (EXIT_FAILURE, 0, _("error: %s at end of format string"), "%");
/*NOTREACHED*/
break;
/* Trailing single %. This should have been rejected by
insert_fprintf. We use %s here in the error message
simply to ensure that the error message matches the one
in insert_fprintf, easing the translation burden.
*/
error (EXIT_FAILURE, 0, _("error: %s at end of format string"), "%");
/*NOTREACHED*/
break;
}
/* end of KIND_FORMAT case */
break;

View File

@ -1,5 +1,5 @@
/* print.h -- declarations for symbols in print.c.
Copyright (C) 2011-2024 Free Software Foundation, Inc.
Copyright (C) 2011-2026 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -25,13 +25,13 @@ struct predicate;
struct segment;
struct segment **make_segment (struct segment **segment,
char *format, int len,
int kind, char format_char,
char aux_format_char,
struct predicate *pred);
char *format, int len,
int kind, char format_char,
char aux_format_char,
struct predicate *pred);
bool
insert_fprintf (struct format_val *vec,
const struct parser_table *entry,
char *format);
const struct parser_table *entry,
char *format);
#endif /* PRINT_H */

View File

@ -1,5 +1,5 @@
/* sharefile.c -- open files just once.
Copyright (C) 2008-2024 Free Software Foundation, Inc.
Copyright (C) 2008-2026 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -80,7 +80,7 @@ entry_free (void *pv)
if (p->fp)
{
if (0 != fclose (p->fp))
fatal_nontarget_file_error (errno, p->name);
fatal_nontarget_file_error (errno, p->name);
}
free (p->name);
free (p);
@ -105,25 +105,25 @@ sharefile_init (const char *mode)
{
p->mode = strdup (mode);
if (p->mode)
{
p->table = hash_initialize (DefaultHashTableSize, NULL,
entry_hashfunc,
entry_comparator,
entry_free);
if (p->table)
{
return p;
}
else
{
free (p->mode);
free (p);
}
}
{
p->table = hash_initialize (DefaultHashTableSize, NULL,
entry_hashfunc,
entry_comparator,
entry_free);
if (p->table)
{
return p;
}
else
{
free (p->mode);
free (p);
}
}
else
{
free (p);
}
{
free (p);
}
}
return NULL;
}
@ -168,36 +168,36 @@ sharefile_fopen (sharefile_handle h, const char *filename)
set_cloexec_flag (fd, true);
if (fstat (fd, &st) < 0)
{
entry_free (new_entry);
entry_free (new_entry);
return NULL;
}
else
{
void *existing;
void *existing;
new_entry->device = st.st_dev;
new_entry->inode = st.st_ino;
existing = hash_lookup (p->table, new_entry);
if (existing) /* We have previously opened that file. */
{
entry_free (new_entry); /* don't need new_entry. */
return ((const struct SharefileEntry*)existing)->fp;
}
if (existing) /* We have previously opened that file. */
{
entry_free (new_entry); /* don't need new_entry. */
return ((const struct SharefileEntry*)existing)->fp;
}
else /* We didn't open it already */
{
if (hash_insert (p->table, new_entry))
{
return new_entry->fp;
}
else /* failed to insert in hashtable. */
{
const int save_errno = errno;
entry_free (new_entry);
errno = save_errno;
return NULL;
}
}
{
if (hash_insert (p->table, new_entry))
{
return new_entry->fp;
}
else /* failed to insert in hashtable. */
{
const int save_errno = errno;
entry_free (new_entry);
errno = save_errno;
return NULL;
}
}
}
}
}

View File

@ -1,5 +1,5 @@
/* sharefile.h -- open files just once.
Copyright (C) 2008-2024 Free Software Foundation, Inc.
Copyright (C) 2008-2026 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@ -1,4 +1,4 @@
# Copyright (C) 2001-2024 Free Software Foundation, Inc.
# Copyright (C) 2001-2026 Free Software Foundation, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by

View File

@ -1,4 +1,4 @@
# Copyright (C) 2014-2024 Free Software Foundation, Inc.
# Copyright (C) 2014-2026 Free Software Foundation, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by

View File

@ -1,6 +1,6 @@
# -*- TCL -*-
# Test-specific TCL procedures required by DejaGNU.
# Copyright (C) 2000-2024 Free Software Foundation, Inc.
# Copyright (C) 2000-2026 Free Software Foundation, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by

View File

@ -1,4 +1,4 @@
# If -exec \; fails, it should return false. The return
# value of find should stil; be 0, unless another error has
# value of find should still be 0, unless another error has
# happened.
find_start p { /tmp -exec false \; -o \( -printf "yep\n" -quit \) }

View File

@ -1,5 +1,5 @@
# tests for -execdir ... \+
# Specifically, ensure that output for separate directoires is not mixed.
# Specifically, ensure that output for separate directories is not mixed.
if { [ safe_path ] } {
exec rm -rf tmp
exec mkdir tmp tmp/two

View File

@ -22,8 +22,7 @@ set -e
here=`pwd`
d=`basename $here`
for arg;
do
for arg; do
echo "$d" "$arg"
done | LC_ALL=C sort
}

View File

@ -1,4 +1,4 @@
exec rm -rf tmp
exec mkdir tmp
# shoud not result in a fatal error.
# should not result in a fatal error.
find_start p { tmp \( -depth \) -false -print }

View File

@ -21,7 +21,7 @@ for f; do echo "$f"; done
close $script
exec chmod 0500 tmp/list.sh
send_log "creeating files $file_list\n"
send_log "creating files $file_list\n"
foreach filename $file_list {
}

View File

@ -2,7 +2,7 @@ set files "\(1 "
foreach file $files { touch $file }
# shoud not result in a fatal error.
# should not result in a fatal error.
find_start p { \(1 }
foreach file $files { file delete -- $file }

View File

@ -2,7 +2,7 @@ set files "!2"
foreach file $files { touch $file }
# shoud not result in a fatal error.
# should not result in a fatal error.
find_start p { !2 }
foreach file $files { file delete -- $file }

View File

@ -2,7 +2,7 @@ set files "\)"
foreach file $files { touch $file }
# shoud not result in a fatal error.
# should not result in a fatal error.
find_start p { \) }
foreach file $files { file delete -- $file }

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/* util.c -- functions for initializing new tree elements, and other things.
Copyright (C) 1990-2024 Free Software Foundation, Inc.
Copyright (C) 1990-2026 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -74,10 +74,10 @@ static struct debug_option_assoc debugassoc[] =
Fills in the following cells of the new predicate node:
pred_func PRED_FUNC
args(.str) NULL
p_type PRIMARY_TYPE
p_prec NO_PREC
pred_func PRED_FUNC
args(.str) NULL
p_type PRIMARY_TYPE
p_prec NO_PREC
Other cells that need to be filled in are defaulted by
get_new_pred_chk_op, which is used to ensure that the prior node is
@ -86,8 +86,8 @@ static struct debug_option_assoc debugassoc[] =
struct predicate *
insert_primary_withpred (const struct parser_table *entry,
PRED_FUNC pred_func,
const char *arg)
PRED_FUNC pred_func,
const char *arg)
{
struct predicate *new_pred;
@ -106,10 +106,10 @@ insert_primary_withpred (const struct parser_table *entry,
Fills in the following cells of the new predicate node:
pred_func PRED_FUNC
args(.str) NULL
p_type PRIMARY_TYPE
p_prec NO_PREC
pred_func PRED_FUNC
args(.str) NULL
p_type PRIMARY_TYPE
p_prec NO_PREC
Other cells that need to be filled in are defaulted by
get_new_pred_chk_op, which is used to ensure that the prior node is
@ -138,18 +138,18 @@ show_valid_debug_options (int full)
if (full)
{
for (i=0; i<N_DEBUGASSOC; ++i)
{
fprintf (stdout, "%-10s %s\n",
debugassoc[i].name,
debugassoc[i].docstring);
}
{
fprintf (stdout, "%-10s %s\n",
debugassoc[i].name,
debugassoc[i].docstring);
}
}
else
{
for (i=0; i<N_DEBUGASSOC; ++i)
{
fprintf (stdout, "%s%s", (i>0 ? ", " : ""), debugassoc[i].name);
}
{
fprintf (stdout, "%s%s", (i>0 ? ", " : " "), debugassoc[i].name);
}
}
}
@ -188,8 +188,8 @@ Tests (N can be +N or -N or N):\n\
-ctime N -empty -false -fstype TYPE -gid N -group NAME -ilname PATTERN\n\
-iname PATTERN -inum N -iwholename PATTERN -iregex PATTERN\n\
-links N -lname PATTERN -mmin N -mtime N -name PATTERN -newer FILE\n\
-nouser -nogroup -path PATTERN -perm [-/]MODE -regex PATTERN\n\
-readable -writable -executable\n\
-newerXY REFERENCE -nouser -nogroup -path PATTERN -perm [-/]MODE\n\
-regex PATTERN -readable -writable -executable\n\
-wholename PATTERN -size N[bcwkMG] -true -type [bcdpflsD] -uid N\n\
-used N -user NAME -xtype [bcdpfls]\n"));
HTL (_("\n\
@ -204,9 +204,13 @@ Other common options:\n"));
HTL (_(" --help display this help and exit\n"));
HTL (_(" --version output version information and exit\n\n"));
HTL (_("\n\
In -newerXY, XY stands for the combination [aBcm][aBcmt]; see find(1).\n\
\n"));
show_valid_debug_options (0);
HTL (_("\n\
Use '-D help' for a description of the options, or see find(1)\n\
Use '-D help' for a description of the options, or see find(1).\n\
\n"));
explain_how_to_report_bugs (stdout, program_name);
@ -250,23 +254,23 @@ get_statinfo (const char *pathname, const char *name, struct stat *p)
{
set_stat_placeholders (p);
if (0 == (*options.xstat) (name, p))
{
if (00000 == p->st_mode)
{
/* Savannah bug #16378. */
error (0, 0, _("WARNING: file %s appears to have mode 0000"),
quotearg_n_style (0, options.err_quoting_style, name));
state.exit_status = EXIT_FAILURE;
}
}
{
if (00000 == p->st_mode)
{
/* Savannah bug #16378. */
error (0, 0, _("WARNING: file %s appears to have mode 0000"),
quotearg_n_style (0, options.err_quoting_style, name));
state.exit_status = EXIT_FAILURE;
}
}
else
{
if (!options.ignore_readdir_race || (errno != ENOENT) )
{
nonfatal_target_file_error (errno, pathname);
}
return -1;
}
{
if (!options.ignore_readdir_race || (errno != ENOENT) )
{
nonfatal_target_file_error (errno, pathname);
}
return -1;
}
}
state.have_stat = true;
state.have_type = true;
@ -280,8 +284,8 @@ get_statinfo (const char *pathname, const char *name, struct stat *p)
*/
static int
get_info (const char *pathname,
struct stat *p,
struct predicate *pred_ptr)
struct stat *p,
struct predicate *pred_ptr)
{
bool todo = false;
@ -290,34 +294,34 @@ get_info (const char *pathname,
*/
if (pred_ptr->need_stat && !state.have_stat)
{
todo = true; /* need full stat info */
todo = true; /* need full stat info */
}
else if (pred_ptr->need_type && !state.have_type)
{
todo = true; /* need to stat to get the type */
todo = true; /* need to stat to get the type */
}
else if (pred_ptr->need_inum)
{
if (!p->st_ino)
{
todo = true; /* need to stat to get the inode number */
}
{
todo = true; /* need to stat to get the inode number */
}
else if ((!state.have_type) || S_ISDIR(p->st_mode))
{
/* For now we decide not to trust struct dirent.d_ino for
* directory entries that are subdirectories, in case this
* subdirectory is a mount point. We also need to call a
* stat function if we don't have st_ino (i.e. it is zero).
*/
todo = true;
}
{
/* For now we decide not to trust struct dirent.d_ino for
* directory entries that are subdirectories, in case this
* subdirectory is a mount point. We also need to call a
* stat function if we don't have st_ino (i.e. it is zero).
*/
todo = true;
}
}
if (todo)
{
if (get_statinfo (pathname, state.rel_pathname, p) != 0)
return -1; /* failure. */
return -1; /* failure. */
}
return 0; /* success, or nothing to do. */
return 0; /* success, or nothing to do. */
}
/* Determine if we can use O_NOFOLLOW.
@ -342,15 +346,15 @@ check_nofollow (void)
release = conversion (uts.release);
if (0 == strcmp ("Linux", uts.sysname))
{
/* Linux kernels 2.1.126 and earlier ignore the O_NOFOLLOW flag. */
return release >= 2.2f; /* close enough */
}
{
/* Linux kernels 2.1.126 and earlier ignore the O_NOFOLLOW flag. */
return release >= 2.2f; /* close enough */
}
else if (0 == strcmp ("FreeBSD", uts.sysname))
{
/* FreeBSD 3.0-CURRENT and later support it */
return release >= 3.1f;
}
{
/* FreeBSD 3.0-CURRENT and later support it */
return release >= 3.1f;
}
}
/* Well, O_NOFOLLOW was defined, so we'll try to use it. */
@ -404,18 +408,18 @@ do_complete_pending_execdirs (struct predicate *p)
/* It's an exec-family predicate. p->args.exec_val is valid. */
assert(predicate_uses_exec(p));
if (p->args.exec_vec.multiple)
{
struct exec_val *execp = &p->args.exec_vec;
{
struct exec_val *execp = &p->args.exec_vec;
/* This one was terminated by '+' and so might have some
* left... Run it if necessary.
*/
if (execp->state.todo)
{
/* There are not-yet-executed arguments. */
do_exec (execp);
}
}
/* This one was terminated by '+' and so might have some
* left... Run it if necessary.
*/
if (execp->state.todo)
{
/* There are not-yet-executed arguments. */
do_exec (execp);
}
}
}
do_complete_pending_execdirs (p->pred_right);
@ -455,10 +459,10 @@ complete_pending_execs (struct predicate *p)
* there are any problems.
*/
if (execp->state.todo)
{
/* There are not-yet-executed arguments. */
bc_do_exec (&execp->ctl, &execp->state);
}
{
/* There are not-yet-executed arguments. */
bc_do_exec (&execp->ctl, &execp->state);
}
}
complete_pending_execs (p->pred_right);
@ -471,9 +475,9 @@ record_initial_cwd (void)
if (0 != save_cwd (initial_wd))
{
error (EXIT_FAILURE, errno,
_("Failed to save initial working directory%s%s"),
(initial_wd->desc < 0 && initial_wd->name) ? ": " : "",
(initial_wd->desc < 0 && initial_wd->name) ? initial_wd->name : "");
_("Failed to save initial working directory%s%s"),
(initial_wd->desc < 0 && initial_wd->name) ? ": " : "",
(initial_wd->desc < 0 && initial_wd->name) ? initial_wd->name : "");
}
}
@ -490,9 +494,9 @@ cleanup_initial_cwd (void)
{
/* since we may already be in atexit, die with _exit(). */
error (0, errno,
_("Failed to restore initial working directory%s%s"),
(initial_wd->desc < 0 && initial_wd->name) ? ": " : "",
(initial_wd->desc < 0 && initial_wd->name) ? initial_wd->name : "");
_("Failed to restore initial working directory%s%s"),
(initial_wd->desc < 0 && initial_wd->name) ? ": " : "",
(initial_wd->desc < 0 && initial_wd->name) ? initial_wd->name : "");
_exit (EXIT_FAILURE);
}
}
@ -500,7 +504,7 @@ cleanup_initial_cwd (void)
static void
traverse_tree (struct predicate *tree,
void (*callback)(struct predicate*))
void (*callback)(struct predicate*))
{
if (tree->pred_left)
traverse_tree (tree->pred_left, callback);
@ -571,7 +575,7 @@ fallback_stat (const char *name, struct stat *p, int prev_rv)
case ENOENT:
case ENOTDIR:
if (options.debug_options & DebugStat)
fprintf(stderr, "fallback_stat(): stat(%s) failed; falling back on lstat()\n", name);
fprintf(stderr, "fallback_stat(): stat(%s) failed; falling back on lstat()\n", name);
return fstatat(state.cwd_dir_fd, name, p, AT_SYMLINK_NOFOLLOW);
case EACCES:
@ -579,7 +583,7 @@ fallback_stat (const char *name, struct stat *p, int prev_rv)
case ELOOP:
case ENAMETOOLONG:
#ifdef EOVERFLOW
case EOVERFLOW: /* EOVERFLOW is not #defined on UNICOS. */
case EOVERFLOW: /* EOVERFLOW is not #defined on UNICOS. */
#endif
default:
return prev_rv;
@ -611,9 +615,9 @@ optionh_stat (const char *name, struct stat *p)
int rv;
rv = fstatat (state.cwd_dir_fd, name, p, 0);
if (0 == rv)
return 0; /* success */
return 0; /* success */
else
return fallback_stat (name, p, rv);
return fallback_stat (name, p, rv);
}
else
{
@ -637,7 +641,7 @@ optionl_stat(const char *name, struct stat *p)
set_stat_placeholders (p);
rv = fstatat (state.cwd_dir_fd, name, p, 0);
if (0 == rv)
return 0; /* normal case. */
return 0; /* normal case. */
else
return fallback_stat (name, p, rv);
}
@ -698,10 +702,10 @@ following_links(void)
*/
bool
digest_mode (mode_t *mode,
const char *pathname,
const char *name,
struct stat *pstat,
bool leaf)
const char *pathname,
const char *name,
struct stat *pstat,
bool leaf)
{
/* If we know the type of the directory entry, and it is not a
* symbolic link, we may be able to avoid a stat() or lstat() call.
@ -709,18 +713,18 @@ digest_mode (mode_t *mode,
if (*mode)
{
if (S_ISLNK(*mode) && following_links())
{
/* mode is wrong because we should have followed the symlink. */
if (get_statinfo (pathname, name, pstat) != 0)
return false;
*mode = state.type = pstat->st_mode;
state.have_type = true;
}
{
/* mode is wrong because we should have followed the symlink. */
if (get_statinfo (pathname, name, pstat) != 0)
return false;
*mode = state.type = pstat->st_mode;
state.have_type = true;
}
else
{
state.have_type = true;
pstat->st_mode = state.type = *mode;
}
{
state.have_type = true;
pstat->st_mode = state.type = *mode;
}
}
else
{
@ -729,24 +733,24 @@ digest_mode (mode_t *mode,
* know at this stage)
*/
if (leaf)
{
state.have_stat = false;
state.have_type = false;
state.type = 0;
}
{
state.have_stat = false;
state.have_type = false;
state.type = 0;
}
else
{
if (get_statinfo (pathname, name, pstat) != 0)
return false;
{
if (get_statinfo (pathname, name, pstat) != 0)
return false;
/* If -L is in effect and we are dealing with a symlink,
* st_mode is the mode of the pointed-to file, while mode is
* the mode of the directory entry (S_IFLNK). Hence now
* that we have the stat information, override "mode".
*/
state.type = *mode = pstat->st_mode;
state.have_type = true;
}
/* If -L is in effect and we are dealing with a symlink,
* st_mode is the mode of the pointed-to file, while mode is
* the mode of the directory entry (S_IFLNK). Hence now
* that we have the stat information, override "mode".
*/
state.type = *mode = pstat->st_mode;
state.have_type = true;
}
}
/* success. */
@ -764,7 +768,7 @@ default_prints (struct predicate *pred)
while (pred != NULL)
{
if (pred->no_default_print)
return (false);
return (false);
pred = pred->pred_next;
}
return (true);
@ -776,18 +780,18 @@ looks_like_expression (const char *arg, bool leading)
switch (arg[0])
{
case '-':
if (arg[1]) /* "-foo" is an expression. */
return true;
if (arg[1]) /* "-foo" is an expression. */
return true;
else
return false; /* Just "-" is a filename. */
return false; /* Just "-" is a filename. */
break;
case ')':
case ',':
if (arg[1])
return false; /* )x and ,z are not expressions */
return false; /* )x and ,z are not expressions */
else
return !leading; /* A leading ) or , is not either */
return !leading; /* A leading ) or , is not either */
/* ( and ! are part of an expression, but (2 and !foo are
* filenames.
@ -795,9 +799,9 @@ looks_like_expression (const char *arg, bool leading)
case '!':
case '(':
if (arg[1])
return false;
return false;
else
return true;
return true;
default:
return false;
@ -819,18 +823,18 @@ process_debug_options (char *arg)
empty = false;
for (i=0; i<N_DEBUGASSOC; ++i)
{
if (0 == strcmp (debugassoc[i].name, p))
{
options.debug_options |= debugassoc[i].val;
break;
}
}
{
if (0 == strcmp (debugassoc[i].name, p))
{
options.debug_options |= debugassoc[i].val;
break;
}
}
if (i >= N_DEBUGASSOC)
{
error (0, 0, _("Ignoring unrecognised debug flag %s"),
quotearg_n_style (0, options.err_quoting_style, arg));
}
{
error (0, 0, _("Ignoring unrecognised debug flag %s"),
quotearg_n_style (0, options.err_quoting_style, arg));
}
p = strtok_r (NULL, delimiters, &token_context);
}
if (empty)
@ -852,7 +856,7 @@ process_optimisation_option (const char *arg)
if (0 == arg[0])
{
error (EXIT_FAILURE, 0,
_("The -O option must be immediately followed by a decimal integer"));
_("The -O option must be immediately followed by a decimal integer"));
}
else
{
@ -860,48 +864,48 @@ process_optimisation_option (const char *arg)
char *end;
if (!isdigit ( (unsigned char) arg[0] ))
{
error (EXIT_FAILURE, 0,
_("Please specify a decimal number immediately after -O"));
}
{
error (EXIT_FAILURE, 0,
_("Please specify a decimal number immediately after -O"));
}
else
{
int prev_errno = errno;
errno = 0;
{
int prev_errno = errno;
errno = 0;
opt_level = strtoul (arg, &end, 10);
if ( (0==opt_level) && (end==arg) )
{
error (EXIT_FAILURE, 0,
_("Please specify a decimal number immediately after -O"));
}
else if (*end)
{
/* unwanted trailing characters. */
error (EXIT_FAILURE, 0, _("Invalid optimisation level %s"), arg);
}
else if ( (ULONG_MAX==opt_level) && errno)
{
error (EXIT_FAILURE, errno,
_("Invalid optimisation level %s"), arg);
}
else if (opt_level > USHRT_MAX)
{
/* tricky to test, as on some platforms USHORT_MAX and ULONG_MAX
* can have the same value, though this is unusual.
*/
error (EXIT_FAILURE, 0,
_("Optimisation level %lu is too high. "
"If you want to find files very quickly, "
"consider using GNU locate."),
opt_level);
}
else
{
options.optimisation_level = opt_level;
errno = prev_errno;
}
}
opt_level = strtoul (arg, &end, 10);
if ( (0==opt_level) && (end==arg) )
{
error (EXIT_FAILURE, 0,
_("Please specify a decimal number immediately after -O"));
}
else if (*end)
{
/* unwanted trailing characters. */
error (EXIT_FAILURE, 0, _("Invalid optimisation level %s"), arg);
}
else if ( (ULONG_MAX==opt_level) && errno)
{
error (EXIT_FAILURE, errno,
_("Invalid optimisation level %s"), arg);
}
else if (opt_level > USHRT_MAX)
{
/* tricky to test, as on some platforms USHORT_MAX and ULONG_MAX
* can have the same value, though this is unusual.
*/
error (EXIT_FAILURE, 0,
_("Optimisation level %lu is too high. "
"If you want to find files very quickly, "
"consider using GNU locate."),
opt_level);
}
else
{
options.optimisation_level = opt_level;
errno = prev_errno;
}
}
}
}
@ -913,73 +917,53 @@ process_leading_options (int argc, char *argv[])
for (i=1; (end_of_leading_options = i) < argc; ++i)
{
if (0 == strcmp ("-H", argv[i]))
{
/* Meaning: dereference symbolic links on command line, but nowhere else. */
set_follow_state (SYMLINK_DEREF_ARGSONLY);
}
{
/* Meaning: dereference symbolic links on command line, but nowhere else. */
set_follow_state (SYMLINK_DEREF_ARGSONLY);
}
else if (0 == strcmp ("-L", argv[i]))
{
/* Meaning: dereference all symbolic links. */
set_follow_state (SYMLINK_ALWAYS_DEREF);
}
{
/* Meaning: dereference all symbolic links. */
set_follow_state (SYMLINK_ALWAYS_DEREF);
}
else if (0 == strcmp ("-P", argv[i]))
{
/* Meaning: never dereference symbolic links (default). */
set_follow_state (SYMLINK_NEVER_DEREF);
}
{
/* Meaning: never dereference symbolic links (default). */
set_follow_state (SYMLINK_NEVER_DEREF);
}
else if (0 == strcmp ("--", argv[i]))
{
/* -- signifies the end of options. */
end_of_leading_options = i+1; /* Next time start with the next option */
break;
}
{
/* -- signifies the end of options. */
end_of_leading_options = i+1; /* Next time start with the next option */
break;
}
else if (0 == strcmp ("-D", argv[i]))
{
if (argc <= i+1)
{
error (0, 0, _("Missing argument after the -D option."));
usage (EXIT_FAILURE);
}
process_debug_options (argv[i+1]);
++i; /* skip the argument too. */
}
{
if (argc <= i+1)
{
error (0, 0, _("Missing argument after the -D option."));
usage (EXIT_FAILURE);
}
process_debug_options (argv[i+1]);
++i; /* skip the argument too. */
}
else if (0 == strncmp ("-O", argv[i], 2))
{
process_optimisation_option (argv[i]+2);
}
{
process_optimisation_option (argv[i]+2);
}
else
{
/* Hmm, must be one of
* (a) A path name
* (b) A predicate
*/
end_of_leading_options = i; /* Next time start with this option */
break;
}
{
/* Hmm, must be one of
* (a) A path name
* (b) A predicate
*/
end_of_leading_options = i; /* Next time start with this option */
break;
}
}
return end_of_leading_options;
}
static struct timespec
now(void)
{
struct timespec retval;
struct timeval tv;
time_t t;
if (0 == gettimeofday (&tv, NULL))
{
retval.tv_sec = tv.tv_sec;
retval.tv_nsec = tv.tv_usec * 1000; /* convert unit from microseconds to nanoseconds */
return retval;
}
t = time (NULL);
assert (t != (time_t)-1);
retval.tv_sec = t;
retval.tv_nsec = 0;
return retval;
}
void
set_option_defaults (struct options *p)
{
@ -989,7 +973,7 @@ set_option_defaults (struct options *p)
p->posixly_correct = false;
/* We call check_nofollow() before setlocale() because the numbers
* for which we check (in the results of uname) definitiely have "."
* for which we check (in the results of uname) definitely have "."
* as the decimal point indicator even under locales for which that
* is not normally true. Hence atof would do the wrong thing
* if we call it after setlocale().
@ -1021,12 +1005,12 @@ set_option_defaults (struct options *p)
p->explicit_depth = false;
p->maxdepth = p->mindepth = -1;
p->start_time = now ();
p->start_time = current_timespec ();
p->cur_day_start.tv_sec = p->start_time.tv_sec - DAYSECS;
p->cur_day_start.tv_nsec = p->start_time.tv_nsec;
p->full_days = false;
p->stay_on_filesystem = false;
p->mount = p->xdev = false;
p->ignore_readdir_race = false;
if (p->posixly_correct)
@ -1040,9 +1024,9 @@ set_option_defaults (struct options *p)
if (getenv ("FIND_BLOCK_SIZE"))
{
error (EXIT_FAILURE, 0,
_("The environment variable FIND_BLOCK_SIZE is not supported, "
"the only thing that affects the block size is the "
"POSIXLY_CORRECT environment variable"));
_("The environment variable FIND_BLOCK_SIZE is not supported, "
"the only thing that affects the block size is the "
"POSIXLY_CORRECT environment variable"));
}
#if LEAF_OPTIMISATION
@ -1074,7 +1058,7 @@ apply_predicate(const char *pathname, struct stat *stat_buf, struct predicate *p
{
/* We may need a stat here. */
if (get_info(pathname, stat_buf, p) != 0)
return false;
return false;
}
if ((p->pred_func)(pathname, stat_buf, p))
{
@ -1110,7 +1094,7 @@ safely_quote_err_filename (int n, char const *arg)
*/
static void
report_file_err(int exitval, int errno_value,
bool is_target_file, const char *name)
bool is_target_file, const char *name)
{
/* It is important that the errno value is passed in as a function
* argument before we call safely_quote_err_filename(), because otherwise

2
gnulib

@ -1 +1 @@
Subproject commit 623bcc22f4744b409ac5e1c00c3b6fd6494b49ce
Subproject commit 43d801a0234994cf97f5d7c34a5fb9b23b9be55a

View File

@ -1,6 +1,6 @@
/* gcc-function-attribtues.h -- GCC-specific function attributes
Copyright (C) 2016-2024 Free Software Foundation, Inc.
Copyright (C) 2016-2026 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@ -1,6 +1,6 @@
# This file is sourced by init.sh, *before* its initialization.
# Copyright (C) 2010-2024 Free Software Foundation, Inc.
# Copyright (C) 2010-2026 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -560,7 +560,7 @@ require_sparse_support_()
# Compile a shared lib using the GCC options for doing so.
# Pass input and output file as parameters respectively.
# Any other optional parmeters are passed to $CC.
# Any other optional parameters are passed to $CC.
gcc_shared_()
{
local in=$1

View File

@ -1,6 +1,6 @@
## Process this file with automake to produce Makefile.in.
## Copyright (C) 1996-2024 Free Software Foundation, Inc.
## Copyright (C) 1996-2026 Free Software Foundation, Inc.
## This program is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
@ -24,7 +24,7 @@ noinst_LIBRARIES = libfind.a
check_PROGRAMS = regexprops test_splitstring
check_SCRIPTS = check-regexprops
regexprops_SOURCES = regexprops.c regextype.c
regexprops_LDADD = $(LDADD) $(LIB_SETLOCALE_NULL) $(LIB_MBRTOWC)
regexprops_LDADD = $(LDADD) $(SETLOCALE_NULL_LIB) $(MBRTOWC_LIB)
TESTS =
if CROSS_COMPILING

View File

@ -1,5 +1,5 @@
/* bugreports.h -- explain how to report bugs
Copyright (C) 2016-2024 Free Software Foundation, Inc.
Copyright (C) 2016-2026 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -31,9 +31,9 @@ explain_how_to_report_bugs (FILE *f, const char *program_name)
"program via the %s bug-reporting page at\n"
"%s or, if\n"
"you have no web access, by sending email to <%s>.\n"),
PACKAGE_URL,
program_name,
PACKAGE_NAME,
PACKAGE_BUGREPORT_URL,
PACKAGE_BUGREPORT);
PACKAGE_URL,
program_name,
PACKAGE_NAME,
PACKAGE_BUGREPORT_URL,
PACKAGE_BUGREPORT);
}

View File

@ -1,5 +1,5 @@
/* bugreports.h -- explain how to report bugs
Copyright (C) 2016-2024 Free Software Foundation, Inc.
Copyright (C) 2016-2026 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@ -1,5 +1,5 @@
/* buildcmd.c -- build command lines from a list of arguments.
Copyright (C) 1990-2024 Free Software Foundation, Inc.
Copyright (C) 1990-2026 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -55,7 +55,7 @@ static const char *special_terminating_arg = "do_not_care";
/* Add a terminator to the argument list. */
static void
bc_args_complete (struct buildcmd_control *ctl,
struct buildcmd_state *state)
struct buildcmd_state *state)
{
bc_push_arg (ctl, state, special_terminating_arg, 0, NULL, 0, 0);
}
@ -112,7 +112,7 @@ bc_do_insert (struct buildcmd_control *ctl,
if (bytes_left <= len)
break;
else
bytes_left -= len;
bytes_left -= len;
strncpy (p, arg, len);
p += len;
@ -121,16 +121,16 @@ bc_do_insert (struct buildcmd_control *ctl,
if (s)
{
if (bytes_left <= (lblen + pfxlen))
break;
else
bytes_left -= (lblen + pfxlen);
if (bytes_left <= (lblen + pfxlen))
break;
else
bytes_left -= (lblen + pfxlen);
if (prefix)
{
strcpy (p, prefix);
p += pfxlen;
}
if (prefix)
{
strcpy (p, prefix);
p += pfxlen;
}
strcpy (p, linebuf);
p += lblen;
@ -144,7 +144,7 @@ bc_do_insert (struct buildcmd_control *ctl,
*p++ = '\0';
bc_push_arg (ctl, state,
insertbuf, p - insertbuf,
insertbuf, p - insertbuf,
NULL, 0,
initial_args);
}
@ -155,55 +155,55 @@ bc_do_insert (struct buildcmd_control *ctl,
*/
static size_t
update_limit (struct buildcmd_control *ctl,
struct buildcmd_state *state,
bool success,
size_t limit)
struct buildcmd_state *state,
bool success,
size_t limit)
{
if (success)
{
if (limit > state->largest_successful_arg_count)
state->largest_successful_arg_count = limit;
state->largest_successful_arg_count = limit;
}
else
{
if (limit < state->smallest_failed_arg_count
|| (0 == state->smallest_failed_arg_count))
state->smallest_failed_arg_count = limit;
|| (0 == state->smallest_failed_arg_count))
state->smallest_failed_arg_count = limit;
}
if (0 == (state->largest_successful_arg_count)
|| (state->smallest_failed_arg_count <= state->largest_successful_arg_count))
{
/* No success yet, or running on a system which has
limits on total argv length, but not arg count. */
limits on total argv length, but not arg count. */
if (success)
{
if (limit < SIZE_MAX)
++limit;
}
{
if (limit < SIZE_MAX)
++limit;
}
else
{
limit /= 2;
}
{
limit /= 2;
}
}
else /* We can use bisection. */
{
const size_t shift = (state->smallest_failed_arg_count
- state->largest_successful_arg_count) / 2;
- state->largest_successful_arg_count) / 2;
if (success)
{
if (shift)
limit += shift;
else
++limit;
}
{
if (shift)
limit += shift;
else
++limit;
}
else
{
if (shift)
limit -= shift;
else
--limit;
}
{
if (shift)
limit -= shift;
else
--limit;
}
}
/* Make sure the returned value is such that progress is
@ -223,8 +223,8 @@ update_limit (struct buildcmd_control *ctl,
*/
static size_t
copy_args (struct buildcmd_control *ctl,
struct buildcmd_state *state,
char** working_args, size_t limit, size_t done)
struct buildcmd_state *state,
char** working_args, size_t limit, size_t done)
{
size_t dst_pos = 0;
size_t src_pos = 0;
@ -249,7 +249,7 @@ copy_args (struct buildcmd_control *ctl,
/* Execute the program with the currently-built list of arguments. */
void
bc_do_exec (struct buildcmd_control *ctl,
struct buildcmd_state *state)
struct buildcmd_state *state)
{
char** working_args;
size_t limit, done;
@ -266,28 +266,28 @@ bc_do_exec (struct buildcmd_control *ctl,
do
{
const size_t dst_pos = copy_args (ctl, state, working_args,
limit, done);
if (ctl->exec_callback (ctl, state->usercontext, dst_pos, working_args))
{
limit = update_limit (ctl, state, true, limit);
done += (dst_pos - ctl->initial_argc);
}
else /* got E2BIG, adjust arguments */
{
if (limit <= ctl->initial_argc + 1)
{
/* No room to reduce the length of the argument list.
Issue an error message and give up. */
error (EXIT_FAILURE, 0,
_("can't call exec() due to argument size restrictions"));
}
else
{
/* Try fewer arguments. */
limit = update_limit (ctl, state, false, limit);
}
}
const size_t dst_pos = copy_args (ctl, state, working_args,
limit, done);
if (ctl->exec_callback (ctl, state->usercontext, dst_pos, working_args))
{
limit = update_limit (ctl, state, true, limit);
done += (dst_pos - ctl->initial_argc);
}
else /* got E2BIG, adjust arguments */
{
if (limit <= ctl->initial_argc + 1)
{
/* No room to reduce the length of the argument list.
Issue an error message and give up. */
error (EXIT_FAILURE, 0,
_("can't call exec() due to argument size restrictions"));
}
else
{
/* Try fewer arguments. */
limit = update_limit (ctl, state, false, limit);
}
}
}
while ((done + 1) < (state->cmd_argc - ctl->initial_argc));
/* (state->cmd_argc - ctl->initial_argc) includes the terminating NULL,
@ -307,8 +307,8 @@ bc_do_exec (struct buildcmd_control *ctl,
*/
static int
bc_argc_limit_reached (int initial_args,
const struct buildcmd_control *ctl,
struct buildcmd_state *state)
const struct buildcmd_control *ctl,
struct buildcmd_state *state)
{
/* Check to see if we about to exceed a limit set by xargs' -n option */
if (!initial_args && ctl->args_per_exec &&
@ -379,7 +379,7 @@ bc_push_arg (struct buildcmd_control *ctl,
{
state->cmd_argv_alloc *= 2;
state->cmd_argv = xrealloc (state->cmd_argv,
sizeof (char *) * state->cmd_argv_alloc);
sizeof (char *) * state->cmd_argv_alloc);
}
}
@ -401,9 +401,9 @@ bc_push_arg (struct buildcmd_control *ctl,
* do the exec immediately.
*/
if (bc_argc_limit_reached (initial_args, ctl, state))
{
bc_do_exec (ctl, state);
}
{
bc_do_exec (ctl, state);
}
}
/* If this is an initial argument, set the high-water mark. */
@ -453,9 +453,9 @@ bc_get_arg_max (void)
static int
cb_exec_noop (struct buildcmd_control * ctl,
void *usercontext,
int argc,
char **argv)
void *usercontext,
int argc,
char **argv)
{
/* does nothing. */
(void) ctl;
@ -483,7 +483,7 @@ bc_size_of_environment (void)
enum BC_INIT_STATUS
bc_init_controlinfo (struct buildcmd_control *ctl,
size_t headroom)
size_t headroom)
{
size_t size_of_environment = bc_size_of_environment ();
@ -557,8 +557,8 @@ bc_use_sensible_arg_max (struct buildcmd_control *ctl)
void
bc_init_state (const struct buildcmd_control *ctl,
struct buildcmd_state *state,
void *context)
struct buildcmd_state *state,
void *context)
{
state->cmd_argc = 0;
state->cmd_argv_chars = 0;
@ -583,7 +583,7 @@ bc_init_state (const struct buildcmd_control *ctl,
void
bc_clear_args (const struct buildcmd_control *ctl,
struct buildcmd_state *state)
struct buildcmd_state *state)
{
state->cmd_argc = ctl->initial_argc;
state->cmd_argv_chars = state->cmd_initial_argv_chars;
@ -605,18 +605,18 @@ exceeds (const char *env_var_name, size_t quantity)
unsigned long limit;
if (xstrtoul (val, &tmp, 10, &limit, NULL) == LONGINT_OK)
{
if (quantity > limit)
return 1;
}
{
if (quantity > limit)
return 1;
}
else
{
error (EXIT_FAILURE, errno,
_("Environment variable %s is not set to a "
"valid decimal number"),
env_var_name);
return 0;
}
{
error (EXIT_FAILURE, errno,
_("Environment variable %s is not set to a "
"valid decimal number"),
env_var_name);
return 0;
}
}
return 0;
}
@ -637,5 +637,5 @@ bc_args_exceed_testing_limit (char **argv)
}
return (exceeds ("__GNU_FINDUTILS_EXEC_ARG_COUNT_LIMIT", args) ||
exceeds ("__GNU_FINDUTILS_EXEC_ARG_LENGTH_LIMIT", chars));
exceeds ("__GNU_FINDUTILS_EXEC_ARG_LENGTH_LIMIT", chars));
}

View File

@ -1,5 +1,5 @@
/* buildcmd.[ch] -- build command lines from a stream of arguments
Copyright (C) 2005-2024 Free Software Foundation, Inc.
Copyright (C) 2005-2026 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -25,7 +25,7 @@
struct buildcmd_state
{
/* Number of valid elements in `cmd_argv', including terminating NULL. */
size_t cmd_argc; /* 0 */
size_t cmd_argc; /* 0 */
/* The list of args being built. */
char **cmd_argv; /* NULL */
@ -90,14 +90,14 @@ struct buildcmd_control
const char *replace_pat;
/* Number of initial arguments given on the command line. */
size_t initial_argc; /* 0 */
size_t initial_argc; /* 0 */
/* exec callback. */
int (*exec_callback)(struct buildcmd_control *, void *usercontext, int argc, char **argv);
/* If nonzero, the maximum number of nonblank lines from stdin to use
per command line. */
unsigned long lines_per_exec; /* 0 */
unsigned long lines_per_exec; /* 0 */
/* The maximum number of arguments to use per command line. */
size_t args_per_exec;
@ -114,30 +114,30 @@ extern size_t bc_size_of_environment (void);
extern void bc_do_insert (struct buildcmd_control *ctl,
struct buildcmd_state *state,
char *arg, size_t arglen,
const char *prefix, size_t pfxlen,
const char *linebuf, size_t lblen,
int initial_args);
struct buildcmd_state *state,
char *arg, size_t arglen,
const char *prefix, size_t pfxlen,
const char *linebuf, size_t lblen,
int initial_args);
extern void bc_do_exec (struct buildcmd_control *ctl,
struct buildcmd_state *state);
struct buildcmd_state *state);
extern void bc_push_arg (struct buildcmd_control *ctl,
struct buildcmd_state *state,
const char *arg, size_t len,
const char *prefix, size_t pfxlen,
int initial_args);
struct buildcmd_state *state,
const char *arg, size_t len,
const char *prefix, size_t pfxlen,
int initial_args);
extern void bc_init_state(const struct buildcmd_control *ctl,
struct buildcmd_state *state,
void *usercontext);
struct buildcmd_state *state,
void *usercontext);
extern enum BC_INIT_STATUS bc_init_controlinfo(struct buildcmd_control *ctl,
size_t arglen_headroom);
size_t arglen_headroom);
extern size_t bc_get_arg_max(void);
extern void bc_use_sensible_arg_max(struct buildcmd_control *ctl);
extern void bc_clear_args(const struct buildcmd_control *ctl,
struct buildcmd_state *state);
struct buildcmd_state *state);
bool bc_args_exceed_testing_limit(char **argv);

View File

@ -1,7 +1,7 @@
#! /bin/sh
# Generate regexprops.texi and compare it against the checked-in version.
#
# Copyright (C) 2009-2024 Free Software Foundation, Inc.
# Copyright (C) 2009-2026 Free Software Foundation, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by

View File

@ -1,5 +1,5 @@
/* listfile.c -- run a function in a specific directory
Copyright (C) 2007-2024 Free Software Foundation, Inc.
Copyright (C) 2007-2026 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -36,7 +36,7 @@
int
run_in_dir (const struct saved_cwd *there,
int (*callback)(void*), void *usercontext)
int (*callback)(void*), void *usercontext)
{
int err = -1;
int saved_errno = 0;
@ -44,17 +44,17 @@ run_in_dir (const struct saved_cwd *there,
if (0 == save_cwd (&here))
{
if (0 == restore_cwd (there))
{
err = callback(usercontext);
saved_errno = (err < 0 ? errno : 0);
}
{
err = callback(usercontext);
saved_errno = (err < 0 ? errno : 0);
}
else
{
openat_restore_fail (errno);
}
{
openat_restore_fail (errno);
}
if (restore_cwd (&here) != 0)
openat_restore_fail (errno);
openat_restore_fail (errno);
free_cwd (&here);
}
@ -82,26 +82,26 @@ run_in_dirfd (int dir_fd, int (*callback)(void*), void *usercontext)
int err;
if (save_cwd (&saved_cwd) != 0)
openat_save_fail (errno);
openat_save_fail (errno);
if (fchdir (dir_fd) != 0)
{
saved_errno = errno;
free_cwd (&saved_cwd);
errno = saved_errno;
return -1;
}
{
saved_errno = errno;
free_cwd (&saved_cwd);
errno = saved_errno;
return -1;
}
err = (*callback)(usercontext);
saved_errno = (err < 0 ? errno : 0);
if (restore_cwd (&saved_cwd) != 0)
openat_restore_fail (errno);
openat_restore_fail (errno);
free_cwd (&saved_cwd);
if (saved_errno)
errno = saved_errno;
errno = saved_errno;
return err;
}
}

View File

@ -1,5 +1,5 @@
/* listfile.h -- display a long listing of a file
Copyright (C) 2007-2024 Free Software Foundation, Inc.
Copyright (C) 2007-2026 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@ -1,6 +1,6 @@
/* extendbuf.c -- manage a dynamically-allocated buffer
Copyright (C) 2004-2024 Free Software Foundation, Inc.
Copyright (C) 2004-2026 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -52,7 +52,7 @@ decide_size (size_t current, size_t wanted)
while (newsize < wanted)
{
if (2 * newsize < newsize)
return wanted;
return wanted;
newsize *= 2;
}
return newsize;
@ -84,24 +84,24 @@ extendbuf (void* existing, size_t wanted, size_t *allocated)
else
{
if (newsize != (*allocated) )
{
(*allocated) = newsize;
result = realloc (existing, newsize);
if (NULL == result)
{
saved_errno = errno;
}
}
{
(*allocated) = newsize;
result = realloc (existing, newsize);
if (NULL == result)
{
saved_errno = errno;
}
}
else
{
result = existing;
}
{
result = existing;
}
}
if (result)
{
/* malloc () or realloc () may have changed errno, but in the
success case we want to preserve the previous value.
success case we want to preserve the previous value.
*/
errno = saved_errno;
}

View File

@ -1,6 +1,6 @@
/* extendbuf.h -- Manage a dynamically-alloicated buffer
Copyright (C) 2004-2024 Free Software Foundation, Inc.
Copyright (C) 2004-2026 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@ -1,5 +1,5 @@
/* fdleak.c -- detect file descriptor leaks
Copyright (C) 2010-2024 Free Software Foundation, Inc.
Copyright (C) 2010-2026 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -73,31 +73,31 @@ get_proc_max_fd (void)
while (1)
{
errno = 0;
dent = readdir (dir);
if (NULL == dent)
{
if (errno)
{
error (0, errno, "%s", quotearg_n_style (0, locale_quoting_style, path));
good = 0;
}
break;
}
errno = 0;
dent = readdir (dir);
if (NULL == dent)
{
if (errno)
{
error (0, errno, "%s", quotearg_n_style (0, locale_quoting_style, path));
good = 0;
}
break;
}
if (dent->d_name[0] != '.'
|| (dent->d_name[1] != 0
&& (dent->d_name[1] != '.' || dent->d_name[2] != 0)))
{
const int fd = safe_atoi (dent->d_name, literal_quoting_style);
if (fd > maxfd)
maxfd = fd;
good = 1;
}
}
if (dent->d_name[0] != '.'
|| (dent->d_name[1] != 0
&& (dent->d_name[1] != '.' || dent->d_name[2] != 0)))
{
const int fd = safe_atoi (dent->d_name, literal_quoting_style);
if (fd > maxfd)
maxfd = fd;
good = 1;
}
}
closedir (dir);
if (good)
return maxfd;
return maxfd;
}
return -1;
}
@ -116,7 +116,7 @@ get_max_fd (void)
open_max = sysconf (_SC_OPEN_MAX);
if (open_max == -1)
open_max = _POSIX_OPEN_MAX; /* underestimate */
open_max = _POSIX_OPEN_MAX; /* underestimate */
/* We assume if RLIMIT_NOFILE is defined, all the related macros are, too. */
#if defined HAVE_GETRLIMIT && defined RLIMIT_NOFILE
@ -124,10 +124,10 @@ get_max_fd (void)
struct rlimit fd_limit;
if (0 == getrlimit (RLIMIT_NOFILE, &fd_limit))
{
if (fd_limit.rlim_cur == RLIM_INFINITY)
return open_max;
else
return (int) fd_limit.rlim_cur;
if (fd_limit.rlim_cur == RLIM_INFINITY)
return open_max;
else
return (int) fd_limit.rlim_cur;
}
}
#endif
@ -138,7 +138,7 @@ get_max_fd (void)
static int
visit_open_fds (int fd_min, int fd_max,
int (*callback)(int, void*), void *cb_context)
int (*callback)(int, void*), void *cb_context)
{
enum { MAX_POLL = 64 };
struct pollfd pf[MAX_POLL];
@ -149,31 +149,31 @@ visit_open_fds (int fd_min, int fd_max,
int i;
int limit = fd_max - fd_min;
if (limit > MAX_POLL)
limit = MAX_POLL;
limit = MAX_POLL;
for (i=0; i<limit; i++)
{
pf[i].events = POLLIN|POLLOUT;
pf[i].revents = 0;
pf[i].fd = fd_min + i;
}
{
pf[i].events = POLLIN|POLLOUT;
pf[i].revents = 0;
pf[i].fd = fd_min + i;
}
rv = poll (pf, limit, 0);
if (-1 == rv)
{
return -1;
}
{
return -1;
}
else
{
int j;
for (j=0; j<limit; j++)
{
if (pf[j].revents != POLLNVAL)
{
if (0 != (rv = callback (pf[j].fd, cb_context)))
return rv;
}
}
}
{
int j;
for (j=0; j<limit; j++)
{
if (pf[j].revents != POLLNVAL)
{
if (0 != (rv = callback (pf[j].fd, cb_context)))
return rv;
}
}
}
fd_min += limit;
}
return 0;
@ -208,19 +208,19 @@ remember_fd_if_non_cloexec (int fd, void *context)
{
struct remember_fd_context * const p = context;
void *newbuf = extendbuf (p->buf,
sizeof (p->buf[0])*(p->used+1),
&(p->allocated));
sizeof (p->buf[0])*(p->used+1),
&(p->allocated));
if (newbuf)
{
p->buf = newbuf;
p->buf[p->used] = fd;
++p->used;
return 0;
}
{
p->buf = newbuf;
p->buf[p->used] = fd;
++p->used;
return 0;
}
else
{
return -1;
}
{
return -1;
}
}
}
@ -259,26 +259,26 @@ find_first_leak_callback (int fd, void *context)
{
struct fd_leak_context *p = context;
while (p->lookup_pos < p->used)
{
if (p->prev_buf[p->lookup_pos] < fd)
{
++p->lookup_pos;
}
else if (p->prev_buf[p->lookup_pos] == fd)
{
/* FD was open and still is, it's not a leak. */
return 0;
}
else
{
break;
}
}
{
if (p->prev_buf[p->lookup_pos] < fd)
{
++p->lookup_pos;
}
else if (p->prev_buf[p->lookup_pos] == fd)
{
/* FD was open and still is, it's not a leak. */
return 0;
}
else
{
break;
}
}
/* We come here if p->prev_buf[p->lookup_pos] > fd, or
if we ran out of items in the lookup table.
Either way, this is a leak. */
if we ran out of items in the lookup table.
Either way, this is a leak. */
p->leaked_fd = fd;
return -1; /* No more callbacks needed. */
return -1; /* No more callbacks needed. */
}
return 0;
}
@ -387,10 +387,10 @@ complain_about_leaky_fds (void)
{
no_leaks = 0;
error (0, 0,
_("File descriptor %d will leak; please report this as a bug, "
"remembering to include a detailed description of the simplest "
"way to reproduce this problem."),
leaking_fd);
_("File descriptor %d will leak; please report this as a bug, "
"remembering to include a detailed description of the simplest "
"way to reproduce this problem."),
leaking_fd);
}
assert (no_leaks);
}

View File

@ -1,5 +1,5 @@
/* fdleak.h -- detect file descriptor leaks
Copyright (C) 2010-2024 Free Software Foundation, Inc.
Copyright (C) 2010-2026 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -17,7 +17,7 @@
#ifndef FDLEAK_H
# define FDLEAK_H
# include <stdbool.h> /* for bool */
# include <stdbool.h> /* for bool */
void remember_non_cloexec_fds (void);
void forget_non_cloexec_fds (void);

View File

@ -1,5 +1,5 @@
/* findutils-version.c -- show version information for findutils
Copyright (C) 2007-2024 Free Software Foundation, Inc.
Copyright (C) 2007-2026 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -34,7 +34,7 @@
#endif
extern char *program_name;
const char *version_string = VERSION;
static const char *version_string = VERSION;
void
display_findutils_version (const char *official_name)
@ -45,9 +45,9 @@ display_findutils_version (const char *official_name)
*/
fflush (stderr);
version_etc (stdout,
official_name, PACKAGE_NAME, version_string,
_("Eric B. Decker"),
_("James Youngman"),
_("Kevin Dalley"),
(const char*) NULL);
official_name, PACKAGE_NAME, version_string,
_("Eric B. Decker"),
_("James Youngman"),
_("Kevin Dalley"),
(const char*) NULL);
}

View File

@ -1,5 +1,5 @@
/* findutils-version.h -- show version information for findutils
Copyright (C) 2007-2024 Free Software Foundation, Inc.
Copyright (C) 2007-2026 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@ -1,5 +1,5 @@
/* listfile.c -- display a long listing of a file
Copyright (C) 1991-2024 Free Software Foundation, Inc.
Copyright (C) 1991-2026 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -182,17 +182,17 @@ list_file (const char *name,
so we removed the trailing space. Happily this also makes it
easier to update nlink_width. */
chars_out = fprintf (stream, "%*lu",
nlink_width, (unsigned long) statp->st_nlink);
nlink_width, (unsigned long) statp->st_nlink);
if (chars_out < 0)
{
output_good = false;
failed_at = 300;
}
else
{
if (chars_out > nlink_width)
nlink_width = chars_out;
}
{
if (chars_out > nlink_width)
nlink_width = chars_out;
}
}
if (output_good)

View File

@ -1,5 +1,5 @@
/* listfile.h -- display a long listing of a file
Copyright (C) 1991-2024 Free Software Foundation, Inc.
Copyright (C) 1991-2026 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@ -1,6 +1,6 @@
/* printquoted.c -- print a specified string with any necessary quoting.
Copyright (C) 1990-2024 Free Software Foundation, Inc.
Copyright (C) 1990-2026 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -35,10 +35,10 @@
*/
int
print_quoted (FILE *fp,
const struct quoting_options *qopts,
bool dest_is_tty,
const char *format,
const char *s)
const struct quoting_options *qopts,
bool dest_is_tty,
const char *format,
const char *s)
{
int rv;
@ -48,28 +48,28 @@ print_quoted (FILE *fp,
size_t len = quotearg_buffer (smallbuf, sizeof smallbuf, s, -1, qopts);
char *buf;
if (len < sizeof smallbuf)
buf = smallbuf;
buf = smallbuf;
else
{
/* The original coreutils code uses alloca(), but I don't
* want to take on the anguish of introducing alloca() to
* 'find'.
* XXX: newsflash: we already have alloca().
*/
buf = xmalloc (len + 1);
quotearg_buffer (buf, len + 1, s, -1, qopts);
}
{
/* The original coreutils code uses alloca(), but I don't
* want to take on the anguish of introducing alloca() to
* 'find'.
* XXX: newsflash: we already have alloca().
*/
buf = xmalloc (len + 1);
quotearg_buffer (buf, len + 1, s, -1, qopts);
}
/* Replace any remaining funny characters with '?'. */
len = qmark_chars (buf, len);
buf[len] = 0;
rv = fprintf (fp, format, buf); /* Print the quoted version */
rv = fprintf (fp, format, buf); /* Print the quoted version */
if (buf != smallbuf)
{
free (buf);
buf = NULL;
}
{
free (buf);
buf = NULL;
}
}
else
{

View File

@ -1,6 +1,6 @@
/* Print a string, appropriately quoted.
Copyright (C) 1997-2024 Free Software Foundation, Inc.
Copyright (C) 1997-2026 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@ -1,6 +1,6 @@
/* qmark.c -- quote 'dangerous' filenames
Derived from coreutils' ls.c.
Copyright (C) 1985-2024 Free Software Foundation, Inc.
Copyright (C) 1985-2026 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -93,7 +93,7 @@ unibyte_qmark_chars (char *buf, size_t len)
while (p < plimit)
{
if (! ISPRINT (to_uchar (*p)))
*p = '?';
*p = '?';
p++;
}
return len;
@ -124,91 +124,91 @@ qmark_chars (char *buf, size_t len)
char *q = buf;
while (p < plimit)
switch (*p)
{
case ' ': case '!': case '"': case '#': case '%':
case '&': case '\'': case '(': case ')': case '*':
case '+': case ',': case '-': case '.': case '/':
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
case ':': case ';': case '<': case '=': case '>':
case '?':
case 'A': case 'B': case 'C': case 'D': case 'E':
case 'F': case 'G': case 'H': case 'I': case 'J':
case 'K': case 'L': case 'M': case 'N': case 'O':
case 'P': case 'Q': case 'R': case 'S': case 'T':
case 'U': case 'V': case 'W': case 'X': case 'Y':
case 'Z':
case '[': case '\\': case ']': case '^': case '_':
case 'a': case 'b': case 'c': case 'd': case 'e':
case 'f': case 'g': case 'h': case 'i': case 'j':
case 'k': case 'l': case 'm': case 'n': case 'o':
case 'p': case 'q': case 'r': case 's': case 't':
case 'u': case 'v': case 'w': case 'x': case 'y':
case 'z': case '{': case '|': case '}': case '~':
/* These characters are printable ASCII characters. */
*q++ = *p++;
break;
default:
/* If we have a multibyte sequence, copy it until we
reach its end, replacing each non-printable multibyte
character with a single question mark. */
{
mbstate_t mbstate;
memset (&mbstate, 0, sizeof mbstate);
do
{
wchar_t wc;
size_t bytes;
int w;
switch (*p)
{
case ' ': case '!': case '"': case '#': case '%':
case '&': case '\'': case '(': case ')': case '*':
case '+': case ',': case '-': case '.': case '/':
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
case ':': case ';': case '<': case '=': case '>':
case '?':
case 'A': case 'B': case 'C': case 'D': case 'E':
case 'F': case 'G': case 'H': case 'I': case 'J':
case 'K': case 'L': case 'M': case 'N': case 'O':
case 'P': case 'Q': case 'R': case 'S': case 'T':
case 'U': case 'V': case 'W': case 'X': case 'Y':
case 'Z':
case '[': case '\\': case ']': case '^': case '_':
case 'a': case 'b': case 'c': case 'd': case 'e':
case 'f': case 'g': case 'h': case 'i': case 'j':
case 'k': case 'l': case 'm': case 'n': case 'o':
case 'p': case 'q': case 'r': case 's': case 't':
case 'u': case 'v': case 'w': case 'x': case 'y':
case 'z': case '{': case '|': case '}': case '~':
/* These characters are printable ASCII characters. */
*q++ = *p++;
break;
default:
/* If we have a multibyte sequence, copy it until we
reach its end, replacing each non-printable multibyte
character with a single question mark. */
{
mbstate_t mbstate;
memset (&mbstate, 0, sizeof mbstate);
do
{
wchar_t wc;
size_t bytes;
int w;
bytes = mbrtowc (&wc, p, plimit - p, &mbstate);
bytes = mbrtowc (&wc, p, plimit - p, &mbstate);
if (bytes == (size_t) -1)
{
/* An invalid multibyte sequence was
encountered. Skip one input byte, and
put a question mark. */
p++;
*q++ = '?';
break;
}
if (bytes == (size_t) -1)
{
/* An invalid multibyte sequence was
encountered. Skip one input byte, and
put a question mark. */
p++;
*q++ = '?';
break;
}
if (bytes == (size_t) -2)
{
/* An incomplete multibyte character
at the end. Replace it entirely with
a question mark. */
p = plimit;
*q++ = '?';
break;
}
if (bytes == (size_t) -2)
{
/* An incomplete multibyte character
at the end. Replace it entirely with
a question mark. */
p = plimit;
*q++ = '?';
break;
}
if (bytes == 0)
/* A null wide character was encountered. */
bytes = 1;
if (bytes == 0)
/* A null wide character was encountered. */
bytes = 1;
w = wcwidth (wc);
if (w >= 0)
{
/* A printable multibyte character.
Keep it. */
for (; bytes > 0; --bytes)
*q++ = *p++;
}
else
{
/* An unprintable multibyte character.
Replace it entirely with a question
mark. */
p += bytes;
*q++ = '?';
}
}
while (! mbsinit (&mbstate));
}
break;
}
w = wcwidth (wc);
if (w >= 0)
{
/* A printable multibyte character.
Keep it. */
for (; bytes > 0; --bytes)
*q++ = *p++;
}
else
{
/* An unprintable multibyte character.
Replace it entirely with a question
mark. */
p += bytes;
*q++ = '?';
}
}
while (! mbsinit (&mbstate));
}
break;
}
/* The buffer may have shrunk. */
len = q - buf;

View File

@ -1,7 +1,7 @@
/* regexprops.c -- document the properties of the regular expressions
understood by gnulib.
Copyright (C) 2005-2024 Free Software Foundation, Inc.
Copyright (C) 2005-2026 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -98,9 +98,9 @@ enum_item (const char *s)
static void
begin_subsection (const char *name,
const char *next,
const char *prev,
const char *up)
const char *next,
const char *prev,
const char *up)
{
(void) next;
(void) prev;
@ -173,9 +173,9 @@ describe_regex_syntax (int options)
if (options & RE_DOT_NOT_NULL)
{
if ( (options & RE_DOT_NEWLINE) == 0 )
content (" and");
content (" and");
else
content (" except");
content (" except");
content (" the null character");
}
@ -186,29 +186,29 @@ describe_regex_syntax (int options)
{
begintable_markup ("@samp");
if (options & RE_BK_PLUS_QM)
{
enum_item ("\\+");
content ("indicates that the regular expression should match one"
" or more occurrences of the previous atom or regexp.");
enum_item ("\\?");
content ("indicates that the regular expression should match zero"
" or one occurrence of the previous atom or regexp.");
enum_item ("+ and ?");
content ("match themselves.\n");
}
{
enum_item ("\\+");
content ("indicates that the regular expression should match one"
" or more occurrences of the previous atom or regexp.");
enum_item ("\\?");
content ("indicates that the regular expression should match zero"
" or one occurrence of the previous atom or regexp.");
enum_item ("+ and ?");
content ("match themselves.\n");
}
else
{
enum_item ("+");
content ("indicates that the regular expression should match one"
" or more occurrences of the previous atom or regexp.");
enum_item ("?");
content ("indicates that the regular expression should match zero"
" or one occurrence of the previous atom or regexp.");
enum_item ("\\+");
literal ("matches a @samp{+}");
enum_item ("\\?");
literal ("matches a @samp{?}.");
}
{
enum_item ("+");
content ("indicates that the regular expression should match one"
" or more occurrences of the previous atom or regexp.");
enum_item ("?");
content ("indicates that the regular expression should match zero"
" or one occurrence of the previous atom or regexp.");
enum_item ("\\+");
literal ("matches a @samp{+}");
enum_item ("\\?");
literal ("matches a @samp{?}.");
}
endtable ();
}
@ -224,17 +224,17 @@ describe_regex_syntax (int options)
if (options & RE_BACKSLASH_ESCAPE_IN_LISTS)
literal ("Within square brackets, @samp{\\} can be used to quote "
"the following character. ");
"the following character. ");
else
literal ("Within square brackets, @samp{\\} is taken literally. ");
if (options & RE_CHAR_CLASSES)
content ("Character classes are supported; for example "
"@samp{[[:digit:]]} will match a single decimal digit.\n");
"@samp{[[:digit:]]} will match a single decimal digit.\n");
else
literal ("Character classes are not supported, so for example "
"you would need to use @samp{[0-9]} "
"instead of @samp{[[:digit:]]}.\n");
"you would need to use @samp{[0-9]} "
"instead of @samp{[[:digit:]]}.\n");
if (options & RE_HAT_LISTS_NOT_NEWLINE)
{
@ -244,9 +244,9 @@ describe_regex_syntax (int options)
if (options & RE_NO_GNU_OPS)
{
content ("GNU extensions are not supported and so "
"@samp{\\w}, @samp{\\W}, @samp{\\<}, @samp{\\>}, @samp{\\b}, @samp{\\B}, @samp{\\`}, and @samp{\\'} "
"match "
"@samp{w}, @samp{W}, @samp{<}, @samp{>}, @samp{b}, @samp{B}, @samp{`}, and @samp{'} respectively.\n");
"@samp{\\w}, @samp{\\W}, @samp{\\<}, @samp{\\>}, @samp{\\b}, @samp{\\B}, @samp{\\`}, and @samp{\\'} "
"match "
"@samp{w}, @samp{W}, @samp{<}, @samp{>}, @samp{b}, @samp{B}, @samp{`}, and @samp{'} respectively.\n");
}
else
{
@ -271,7 +271,7 @@ describe_regex_syntax (int options)
literal ("Grouping is performed with parentheses @samp{()}. ");
if (options & RE_UNMATCHED_RIGHT_PAREN_ORD)
literal ("An unmatched @samp{)} matches just itself. ");
literal ("An unmatched @samp{)} matches just itself. ");
}
else
{
@ -286,9 +286,9 @@ describe_regex_syntax (int options)
{
literal ("A backslash followed by a digit acts as a back-reference and matches the same thing as the previous grouped expression indicated by that number. For example @samp{\\2} matches the second group expression. The order of group expressions is determined by the position of their opening parenthesis ");
if (options & RE_NO_BK_PARENS)
literal ("@samp{(}");
literal ("@samp{(}");
else
literal ("@samp{\\(}");
literal ("@samp{\\(}");
content (".");
}
@ -297,9 +297,9 @@ describe_regex_syntax (int options)
if (!(options & RE_LIMITED_OPS))
{
if (options & RE_NO_BK_VBAR)
literal ("The alternation operator is @samp{|}.");
literal ("The alternation operator is @samp{|}.");
else
literal ("The alternation operator is @samp{\\|}.");
literal ("The alternation operator is @samp{\\|}.");
}
newpara ();
@ -313,24 +313,24 @@ describe_regex_syntax (int options)
beginenum ();
enum_item ("At the beginning of a regular expression");
if (options & RE_NO_BK_PARENS)
{
enum_item ("After an open-group, signified by @samp{(}");
}
{
enum_item ("After an open-group, signified by @samp{(}");
}
else
{
enum_item ("After an open-group, signified by @samp{\\(}");
}
{
enum_item ("After an open-group, signified by @samp{\\(}");
}
newline ();
if (!(options & RE_LIMITED_OPS))
{
if (options & RE_NEWLINE_ALT)
enum_item ("After a newline");
{
if (options & RE_NEWLINE_ALT)
enum_item ("After a newline");
if (options & RE_NO_BK_VBAR )
enum_item ("After the alternation operator @samp{|}");
else
enum_item ("After the alternation operator @samp{\\|}");
}
if (options & RE_NO_BK_VBAR )
enum_item ("After the alternation operator @samp{|}");
else
enum_item ("After the alternation operator @samp{\\|}");
}
endenum ();
newpara ();
@ -338,71 +338,71 @@ describe_regex_syntax (int options)
beginenum ();
enum_item ("At the end of a regular expression");
if (options & RE_NO_BK_PARENS)
{
enum_item ("Before a close-group, signified by @samp{)}");
}
{
enum_item ("Before a close-group, signified by @samp{)}");
}
else
{
enum_item ("Before a close-group, signified by @samp{\\)}");
}
{
enum_item ("Before a close-group, signified by @samp{\\)}");
}
if (!(options & RE_LIMITED_OPS))
{
if (options & RE_NEWLINE_ALT)
enum_item ("Before a newline");
{
if (options & RE_NEWLINE_ALT)
enum_item ("Before a newline");
if (options & RE_NO_BK_VBAR)
enum_item ("Before the alternation operator @samp{|}");
else
enum_item ("Before the alternation operator @samp{\\|}");
}
if (options & RE_NO_BK_VBAR)
enum_item ("Before the alternation operator @samp{|}");
else
enum_item ("Before the alternation operator @samp{\\|}");
}
endenum ();
}
newpara ();
if (!(options & RE_LIMITED_OPS) )
{
if ((options & RE_CONTEXT_INDEP_OPS)
&& !(options & RE_CONTEXT_INVALID_OPS))
{
literal ("The characters @samp{*}, @samp{+} and @samp{?} are special anywhere in a regular expression.\n");
}
&& !(options & RE_CONTEXT_INVALID_OPS))
{
literal ("The characters @samp{*}, @samp{+} and @samp{?} are special anywhere in a regular expression.\n");
}
else
{
if (options & RE_BK_PLUS_QM)
literal ("@samp{\\*}, @samp{\\+} and @samp{\\?} ");
else
literal ("@samp{*}, @samp{+} and @samp{?} ");
{
if (options & RE_BK_PLUS_QM)
literal ("@samp{\\*}, @samp{\\+} and @samp{\\?} ");
else
literal ("@samp{*}, @samp{+} and @samp{?} ");
if (options & RE_CONTEXT_INVALID_OPS)
{
content ("are special at any point in a regular expression except the following places, where they are not allowed:");
}
else
{
content ("are special at any point in a regular expression except:");
}
if (options & RE_CONTEXT_INVALID_OPS)
{
content ("are special at any point in a regular expression except the following places, where they are not allowed:");
}
else
{
content ("are special at any point in a regular expression except:");
}
beginenum ();
enum_item ("At the beginning of a regular expression");
if (options & RE_NO_BK_PARENS)
{
enum_item ("After an open-group, signified by @samp{(}");
}
else
{
enum_item ("After an open-group, signified by @samp{\\(}");
}
if (!(options & RE_LIMITED_OPS))
{
if (options & RE_NEWLINE_ALT)
enum_item ("After a newline");
beginenum ();
enum_item ("At the beginning of a regular expression");
if (options & RE_NO_BK_PARENS)
{
enum_item ("After an open-group, signified by @samp{(}");
}
else
{
enum_item ("After an open-group, signified by @samp{\\(}");
}
if (!(options & RE_LIMITED_OPS))
{
if (options & RE_NEWLINE_ALT)
enum_item ("After a newline");
if (options & RE_NO_BK_VBAR)
enum_item ("After the alternation operator @samp{|}");
else
enum_item ("After the alternation operator @samp{\\|}");
}
endenum ();
}
if (options & RE_NO_BK_VBAR)
enum_item ("After the alternation operator @samp{|}");
else
enum_item ("After the alternation operator @samp{\\|}");
}
endenum ();
}
}
@ -410,29 +410,29 @@ describe_regex_syntax (int options)
if (options & RE_INTERVALS)
{
if (options & RE_NO_BK_BRACES)
{
literal ("Intervals are specified by @samp{@{} and @samp{@}}.\n");
if (options & RE_INVALID_INTERVAL_ORD)
{
literal ("Invalid intervals are treated as literals, for example @samp{a@{1} is treated as @samp{a\\@{1}");
}
else
{
literal ("Invalid intervals such as @samp{a@{1z} are not accepted.\n");
}
}
{
literal ("Intervals are specified by @samp{@{} and @samp{@}}.\n");
if (options & RE_INVALID_INTERVAL_ORD)
{
literal ("Invalid intervals are treated as literals, for example @samp{a@{1} is treated as @samp{a\\@{1}");
}
else
{
literal ("Invalid intervals such as @samp{a@{1z} are not accepted.\n");
}
}
else
{
literal ("Intervals are specified by @samp{\\@{} and @samp{\\@}}.\n");
if (options & RE_INVALID_INTERVAL_ORD)
{
literal ("Invalid intervals are treated as literals, for example @samp{a\\@{1} is treated as @samp{a@{1}");
}
else
{
literal ("Invalid intervals such as @samp{a\\@{1z} are not accepted.\n");
}
}
{
literal ("Intervals are specified by @samp{\\@{} and @samp{\\@}}.\n");
if (options & RE_INVALID_INTERVAL_ORD)
{
literal ("Invalid intervals are treated as literals, for example @samp{a\\@{1} is treated as @samp{a@{1}");
}
else
{
literal ("Invalid intervals such as @samp{a\\@{1z} are not accepted.\n");
}
}
}
newpara ();
@ -454,7 +454,7 @@ copying (void)
static const char *copy_para[]=
{
/* The copyright year number range is with "--" in Texinfo files. */
"Copyright (C) 1994--2024 Free Software Foundation, Inc."
"Copyright (C) 1994--2026 Free Software Foundation, Inc."
,""
,"Permission is granted to copy, distribute and/or modify this document"
,"under the terms of the GNU Free Documentation License, Version 1.3 or"
@ -485,17 +485,17 @@ menu (unsigned int context)
output ("@menu\n", 0);
for (i=0;
get_regex_type_flags (i),
name=get_regex_type_name (i);
name=get_regex_type_name (i);
++i)
{
if (!ignore (i, context))
{
output ("* ", 0);
output (name, 0);
content (" regular expression syntax");
output ("::", 0);
newline ();
}
{
output ("* ", 0);
output (name, 0);
content (" regular expression syntax");
output ("::", 0);
newline ();
}
}
output ("@end menu\n", 0);
}
@ -509,13 +509,13 @@ get_next (unsigned int ix, unsigned int context)
while (get_regex_type_name (ix))
{
if (!ignore (ix, context))
{
next = get_regex_type_name (ix);
if (NULL == next)
return "";
else
return next;
}
{
next = get_regex_type_name (ix);
if (NULL == next)
return "";
else
return next;
}
++ix;
}
return "";
@ -524,8 +524,8 @@ get_next (unsigned int ix, unsigned int context)
static void
describe_all (const char *contextname,
unsigned int context,
const char *up)
unsigned int context,
const char *up)
{
const char *name, *next, *previous;
int regopts;
@ -543,33 +543,33 @@ describe_all (const char *contextname,
for (i=0;
regopts = get_regex_type_flags (i),
name=get_regex_type_name (i);
name=get_regex_type_name (i);
++i)
{
if (ignore (i, context))
{
fprintf (stderr,
"Skipping regexp type %s for context %s\n",
name, contextname);
name = previous;
continue;
}
{
fprintf (stderr,
"Skipping regexp type %s for context %s\n",
name, contextname);
name = previous;
continue;
}
next = get_next (i+1, context);
if (NULL == next)
next = "";
next = "";
begin_subsection (name, next, previous, up);
parent = get_regex_type_synonym (i, context);
if (parent >= 0)
{
content ("This is a synonym for ");
content (get_regex_type_name (parent));
content (".");
}
{
content ("This is a synonym for ");
content (get_regex_type_name (parent));
content (".");
}
else
{
describe_regex_syntax (regopts);
}
{
describe_regex_syntax (regopts);
}
previous = name;
}
}
@ -596,17 +596,17 @@ main (int argc, char *argv[])
{
contextname = argv[2];
if (0 == strcmp (contextname, "findutils"))
context = CONTEXT_FINDUTILS;
context = CONTEXT_FINDUTILS;
else if (0 == strcmp (contextname, "generic"))
context = CONTEXT_GENERIC;
context = CONTEXT_GENERIC;
else if (0 == strcmp (contextname, "all"))
context = CONTEXT_ALL;
context = CONTEXT_ALL;
else
{
fprintf (stderr, "Unexpected context %s",
contextname);
return 1;
}
{
fprintf (stderr, "Unexpected context %s",
contextname);
return 1;
}
}
describe_all (contextname, context, up);

View File

@ -2,7 +2,7 @@
/* regextype.c -- Decode the name of a regular expression syntax into am
option name.
Copyright (C) 2005-2024 Free Software Foundation, Inc.
Copyright (C) 2005-2026 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -47,15 +47,15 @@ struct tagRegexTypeMap
static struct tagRegexTypeMap regex_map[] =
{
{ "findutils-default", CONTEXT_FINDUTILS, RE_SYNTAX_EMACS|RE_DOT_NEWLINE },
{ "awk", CONTEXT_ALL, RE_SYNTAX_AWK },
{ "ed", CONTEXT_GENERIC, RE_SYNTAX_ED },
{ "egrep", CONTEXT_ALL, RE_SYNTAX_EGREP },
{ "emacs", CONTEXT_ALL, RE_SYNTAX_EMACS },
{ "gnu-awk", CONTEXT_ALL, RE_SYNTAX_GNU_AWK },
{ "grep", CONTEXT_ALL, RE_SYNTAX_GREP },
{ "posix-awk", CONTEXT_ALL, RE_SYNTAX_POSIX_AWK },
{ "awk", CONTEXT_ALL, RE_SYNTAX_AWK },
{ "posix-basic", CONTEXT_ALL, RE_SYNTAX_POSIX_BASIC },
{ "posix-egrep", CONTEXT_ALL, RE_SYNTAX_POSIX_EGREP },
{ "egrep", CONTEXT_ALL, RE_SYNTAX_EGREP },
{ "posix-extended", CONTEXT_ALL, RE_SYNTAX_POSIX_EXTENDED },
{ "posix-minimal-basic", CONTEXT_GENERIC, RE_SYNTAX_POSIX_MINIMAL_BASIC },
{ "sed", CONTEXT_GENERIC, RE_SYNTAX_SED },
@ -74,9 +74,9 @@ get_regex_type (const char *s)
for (i=0u; i<N_REGEX_MAP_ENTRIES; ++i)
{
if (0 == strcmp (regex_map[i].name, s))
return regex_map[i].option_val;
return regex_map[i].option_val;
else
msglen += strlen (quote (regex_map[i].name)) + 2u;
msglen += strlen (quote (regex_map[i].name)) + 2u;
}
/* We didn't find a match for the type of regular expression that the
@ -86,10 +86,10 @@ get_regex_type (const char *s)
for (i=0u; i<N_REGEX_MAP_ENTRIES; ++i)
{
if (i > 0u)
{
strcpy (p, ", ");
p += 2;
}
{
strcpy (p, ", ");
p += 2;
}
p += sprintf (p, "%s", quote (regex_map[i].name));
}
@ -143,15 +143,15 @@ get_regex_type_synonym (unsigned int ix, unsigned int context)
for (i=0u; i<ix; ++i)
{
if ((regex_map[i].context & context) == 0)
{
/* It is pointless to state that "x is a synonym of y" if we
are not in fact going to include y. */
continue;
}
{
/* It is pointless to state that "x is a synonym of y" if we
are not in fact going to include y. */
continue;
}
else if (flags == regex_map[i].option_val)
{
return i;
}
{
return i;
}
}
return -1;
}

View File

@ -1,6 +1,6 @@
/* regextype.h -- Decode the name of a regular expression syntax.
Copyright (C) 2005-2024 Free Software Foundation, Inc.
Copyright (C) 2005-2026 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -40,7 +40,7 @@ enum {
const char * get_regex_type_name(unsigned int ix);
/* Returns the option mask name corresponding to regular expresion
/* Returns the option mask name corresponding to regular expression
* type index IX. Indexes start at 0. Behaviour is undefined if IX
* has a value which would cause get_regex_type_name to return NULL.
*/

View File

@ -1,5 +1,5 @@
/* safe-atoi.c -- checked string-to-int conversion.
Copyright (C) 2007-2024 Free Software Foundation, Inc.
Copyright (C) 2007-2026 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -42,15 +42,15 @@ safe_atoi (const char *s, enum quoting_style style)
{
/* max/min possible value, or an error. */
if (errno == ERANGE)
{
/* too big, or too small. */
error (EXIT_FAILURE, errno, "%s", s);
}
{
/* too big, or too small. */
error (EXIT_FAILURE, errno, "%s", s);
}
else
{
/* not a valid number */
error (EXIT_FAILURE, errno, "%s", s);
}
{
/* not a valid number */
error (EXIT_FAILURE, errno, "%s", s);
}
/* Otherwise, we do a range check against INT_MAX and INT_MIN
* below.
*/

View File

@ -1,5 +1,5 @@
/* safe-atoi.h -- checked string-to-int conversion.
Copyright (C) 2010-2024 Free Software Foundation, Inc.
Copyright (C) 2010-2026 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@ -1,5 +1,5 @@
/* splitstring.c -- split a const string into fields.
Copyright (C) 2011-2024 Free Software Foundation, Inc.
Copyright (C) 2011-2026 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -37,7 +37,7 @@ field_length (const char *str, const char *separators)
{
const char *end = strpbrk (str, separators);
if (end)
return end - str;
return end - str;
}
return strlen (str);
}
@ -45,7 +45,7 @@ field_length (const char *str, const char *separators)
bool
splitstring(const char *s, const char *separators, bool first,
size_t *pos, size_t *len)
size_t *pos, size_t *len)
{
if (first)
{
@ -54,11 +54,11 @@ splitstring(const char *s, const char *separators, bool first,
}
else
{
*pos += *len; /* advance to the next field. */
*pos += *len; /* advance to the next field. */
if (s[*pos])
++*pos; /* skip the separator */
++*pos; /* skip the separator */
else
return false; /* we reached the end. */
return false; /* we reached the end. */
}
*len = field_length (&s[*pos], separators);
return true;

View File

@ -1,5 +1,5 @@
/* splitstring.h -- split a const string into fields.
Copyright (C) 2011-2024 Free Software Foundation, Inc.
Copyright (C) 2011-2026 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -23,7 +23,7 @@
/* Split a string into fields. The string is never modified.
*
* A false return value indicates that there are no more fields.
* Otherwise the next field is at the poisition indicated by *POS and
* Otherwise the next field is at the position indicated by *POS and
* has length *LEN.
*
* Set FIRST to true only on the first call for any given value of s.
@ -39,6 +39,6 @@
# include <stddef.h>
bool splitstring(const char *s, const char *separators,
bool first, size_t *pos, size_t *len);
bool first, size_t *pos, size_t *len);
#endif

View File

@ -1,6 +1,6 @@
/* system.h -- system-dependent definitions for findutils
Copyright (C) 2017-2024 Free Software Foundation, Inc.
Copyright (C) 2017-2026 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@ -1,5 +1,5 @@
/* test_splitstring.c -- unit test for splitstring()
Copyright (C) 2011-2024 Free Software Foundation, Inc.
Copyright (C) 2011-2026 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -29,11 +29,11 @@
static void
assertEqualFunc(const char *file, int line, const char *label,
size_t expected, size_t got)
size_t expected, size_t got)
{
if (expected != got)
fprintf(stderr, "%s line %d: %s: expected %lu, got %lu\n",
file, line, label, (unsigned long)expected, (unsigned long)got);
file, line, label, (unsigned long)expected, (unsigned long)got);
}
#define ASSERT_EQUAL(expected,got) \
do{ \

View File

@ -1,5 +1,5 @@
/* unused-result.h -- macros for ensuring callers don't ignore return values
Copyright (C) 2010-2024 Free Software Foundation, Inc.
Copyright (C) 2010-2026 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@ -1,6 +1,6 @@
# The default database to build and search.
## Copyright (C) 1996-2024 Free Software Foundation, Inc.
## Copyright (C) 1996-2026 Free Software Foundation, Inc.
## This program is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
@ -35,7 +35,7 @@ nodist_locate_TEXINFOS = dblocation.texi
AM_CPPFLAGS = -I$(top_srcdir)/lib -I../gl/lib -I$(top_srcdir)/gl/lib -DLOCATE_DB=\"$(LOCATE_DB)\" -DLOCALEDIR=\"$(localedir)\"
LDADD = ../lib/libfind.a ../gl/lib/libgnulib.a $(LIB_CLOSE) $(LIBINTL) $(LIB_SETLOCALE_NULL) $(LIB_MBRTOWC)
LDADD = ../lib/libfind.a ../gl/lib/libgnulib.a $(LIBINTL) $(SETLOCALE_NULL_LIB) $(MBRTOWC_LIB)
$(PROGRAMS) $(LIBPROGRAMS): ../lib/libfind.a ../gl/lib/libgnulib.a
@ -79,10 +79,10 @@ dblocation.texi:
SUBDIRS = . testsuite
dist-hook: findutils-check-manpages
check-local: findutils-check-manpages
findutils-check-manpages:
$(top_srcdir)/build-aux/man-lint.sh $(srcdir) $(man_MANS)
env GROFF=$(GROFF) $(top_srcdir)/build-aux/man-lint.sh $(srcdir) $(man_MANS)
# Clean coverage files generated by running binaries built with
# gcc -fprofile-arcs -ftest-coverage

View File

@ -1,5 +1,5 @@
/* frcode -- front-compress a sorted list
Copyright (C) 1994-2024 Free Software Foundation, Inc.
Copyright (C) 1994-2026 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -117,7 +117,7 @@ prefix_length (char *s1, char *s2)
* our return type.
*/
if (0 == --limit)
break;
break;
}
return s1 - start;
}
@ -130,8 +130,6 @@ static struct option const longopts[] =
{NULL, no_argument, NULL, 0}
};
extern char *version_string;
static void _GL_ATTRIBUTE_NORETURN
usage (int status)
{
@ -142,8 +140,8 @@ usage (int status)
}
fprintf (stdout,
_("Usage: %s [-0 | --null] [--version] [--help]\n"),
program_name);
_("Usage: %s [-0 | --null] [--version] [--help]\n"),
program_name);
explain_how_to_report_bugs (stdout, program_name);
exit (status);
@ -164,7 +162,7 @@ get_seclevel (char *s)
if ((0==result) && (p == optarg))
{
error (EXIT_FAILURE, 0,
_("You need to specify a security level as a decimal integer."));
_("You need to specify a security level as a decimal integer."));
/*NOTREACHED*/
return -1;
}
@ -172,7 +170,7 @@ get_seclevel (char *s)
{
error (EXIT_FAILURE, 0,
_("Security level %s is outside the convertible range."), s);
_("Security level %s is outside the convertible range."), s);
/*NOTREACHED*/
return -1;
}
@ -180,7 +178,7 @@ get_seclevel (char *s)
{
/* Some suffix exists */
error (EXIT_FAILURE, 0,
_("Security level %s has unexpected suffix %s."), s, p);
_("Security level %s has unexpected suffix %s."), s, p);
/*NOTREACHED*/
return -1;
}
@ -200,11 +198,11 @@ outerr (void)
int
main (int argc, char **argv)
{
char *path; /* The current input entry. */
char *oldpath; /* The previous input entry. */
size_t pathsize, oldpathsize; /* Amounts allocated for them. */
char *path; /* The current input entry. */
char *oldpath; /* The previous input entry. */
size_t pathsize, oldpathsize; /* Amounts allocated for them. */
int count, oldcount, diffcount; /* Their prefix lengths & the difference. */
int line_len; /* Length of input line. */
int line_len; /* Length of input line. */
int delimiter = '\n';
int optc;
int slocate_compat = 0;
@ -232,29 +230,29 @@ main (int argc, char **argv)
switch (optc)
{
case '0':
delimiter = 0;
break;
delimiter = 0;
break;
case 'S':
slocate_compat = 1;
slocate_seclevel = get_seclevel (optarg);
if (slocate_seclevel < 0 || slocate_seclevel > 1)
{
error (EXIT_FAILURE, 0,
_("slocate security level %ld is unsupported."),
slocate_seclevel);
}
break;
slocate_compat = 1;
slocate_seclevel = get_seclevel (optarg);
if (slocate_seclevel < 0 || slocate_seclevel > 1)
{
error (EXIT_FAILURE, 0,
_("slocate security level %ld is unsupported."),
slocate_seclevel);
}
break;
case 'h':
usage (EXIT_SUCCESS);
usage (EXIT_SUCCESS);
case 'v':
display_findutils_version ("frcode");
return 0;
display_findutils_version ("frcode");
return 0;
default:
usage (EXIT_FAILURE);
usage (EXIT_FAILURE);
}
/* We expect to have no arguments. */
@ -275,76 +273,76 @@ main (int argc, char **argv)
{
/* GNU LOCATE02 format */
if (fwrite (LOCATEDB_MAGIC, 1, sizeof (LOCATEDB_MAGIC), stdout)
!= sizeof (LOCATEDB_MAGIC))
{
error (EXIT_FAILURE, errno, _("Failed to write to standard output"));
}
!= sizeof (LOCATEDB_MAGIC))
{
error (EXIT_FAILURE, errno, _("Failed to write to standard output"));
}
}
while ((line_len = getdelim (&path, &pathsize, delimiter, stdin)) > 0)
{
if (path[line_len - 1] != delimiter)
{
error (0, 0, _("The input file should end with the delimiter"));
}
{
error (0, 0, _("The input file should end with the delimiter"));
}
else
{
path[line_len - 1] = '\0'; /* FIXME temporary: nuke the delimiter. */
}
{
path[line_len - 1] = '\0'; /* FIXME temporary: nuke the delimiter. */
}
count = prefix_length (oldpath, path);
diffcount = count - oldcount;
if ( (diffcount > SHRT_MAX) || (diffcount < SHRT_MIN) )
{
/* We do this to prevent overflow of the value we
* write with put_short ()
*/
count = 0;
diffcount = (-oldcount);
}
{
/* We do this to prevent overflow of the value we
* write with put_short ()
*/
count = 0;
diffcount = (-oldcount);
}
oldcount = count;
if (slocate_compat)
{
/* Emit no count for the first pathname. */
slocate_compat = 0;
}
{
/* Emit no count for the first pathname. */
slocate_compat = 0;
}
else
{
/* If the difference is small, it fits in one byte;
otherwise, two bytes plus a marker noting that fact. */
if (diffcount < LOCATEDB_ONEBYTE_MIN
|| diffcount > LOCATEDB_ONEBYTE_MAX)
{
if (EOF == putc (LOCATEDB_ESCAPE, stdout))
outerr ();
if (!put_short (diffcount, stdout))
outerr ();
}
else
{
if (EOF == putc (diffcount, stdout))
outerr ();
}
}
{
/* If the difference is small, it fits in one byte;
otherwise, two bytes plus a marker noting that fact. */
if (diffcount < LOCATEDB_ONEBYTE_MIN
|| diffcount > LOCATEDB_ONEBYTE_MAX)
{
if (EOF == putc (LOCATEDB_ESCAPE, stdout))
outerr ();
if (!put_short (diffcount, stdout))
outerr ();
}
else
{
if (EOF == putc (diffcount, stdout))
outerr ();
}
}
if ( (EOF == fputs (path + count, stdout))
|| (EOF == putc ('\0', stdout)))
{
outerr ();
}
|| (EOF == putc ('\0', stdout)))
{
outerr ();
}
if (1)
{
/* Swap path and oldpath and their sizes. */
char *tmppath = oldpath;
size_t tmppathsize = oldpathsize;
oldpath = path;
oldpathsize = pathsize;
path = tmppath;
pathsize = tmppathsize;
}
{
/* Swap path and oldpath and their sizes. */
char *tmppath = oldpath;
size_t tmppathsize = oldpathsize;
oldpath = path;
oldpathsize = pathsize;
path = tmppath;
pathsize = tmppathsize;
}
}
free (path);

View File

@ -1,28 +1,83 @@
.TH LOCATE 1 \" -*- nroff -*-
.TH LOCATE 1 2020-12-27 findutils \" -*- nroff -*-
.\" As a GNU troff extension, \% at the beginning of a word suppresses
.\" its hyphenation.
.ie \n(.g \{\
. ds ^ \(ha
. ds en \(en
. ds % \%
.\}
.el \{\
. ds ^ ^
. ds en \-
. ds % \" empty
.\}
.SH NAME
locate \- list files in databases that match a pattern
.
.SH SYNOPSIS
.TP \" FIXME-2027: switch to .HP when groff-1.24 is more commonly available.
.nr sA \n(.j \" Save the adjustment mode.
.na
.B locate
[\-d path | \-\-database=path]
[\-e | \-E | \-\-[non\-]existing]
[\-i | \-\-ignore-case]
[\-0 | \-\-null]
[\-c | \-\-count]
[\-w | \-\-wholename]
[\-b | \-\-basename]
[\-l N | \-\-limit=N]
[\-S | \-\-statistics]
[\-r | \-\-regex ]
[\-\-regextype R]
[\-\-max-database-age D]
[\-P | \-H | \-\-nofollow]
[\-L | \-\-follow]
[\-\-version]
[\-A | \-\-all]
[\-p | \-\-print]
[\-\-help]
pattern...
.RB [ \-d\ \c
.I path
|
.BI \*%\-\-database= path\c
]
.RB [ \-e
|
.B \-E
|
.BR \*%\-\- [ non\- ] existing ]
.RB [ \-i
|
.BR \*%\-\-ignore\-case ]
.RB [ \-0
|
.BR \-\-null ]
.RB [ \-c
|
.BR \*%\-\-count ]
.RB [ \-w
|
.BR \*%\-\-wholename ]
.RB [ \-b
|
.BR \*%\-\-basename ]
.RB [ \-l\ \c
.I N
|
.BI \*%\-\-limit= N\c
]
.RB [ \-S
|
.BR \*%\-\-statistics ]
.RB [ \-r
|
.BR \*%\-\-regex ]
.RB \*%[ \-\-regextype\ \c
.IR R ]
.RB \*%[ \-\-max\-database\-age\ \c
.IR D ]
.RB [ \-P
|
.B \-H
|
.BR \*%\-\-nofollow ]
.RB [ \-L
|
.BR \*%\-\-follow ]
.RB \*%[ \-\-version ]
.RB [ \-A
|
.BR \-\-all ]
.RB [ \-p
|
.BR \*%\-\-print ]
.RB \*%[ \-\-help ]
.IR pattern .\|.\|.
.ad \n(sA \" Restore the adjustment mode.
.rr sA
.
.SH DESCRIPTION
This manual page
@ -91,8 +146,9 @@ to set the list of database files to search.
The option overrides the environment variable if both are used. Empty
elements in the path are taken to be synonyms for the file name of the
default database.
A database can be supplied on stdin, using `\-' as an element
of \fIpath\fP. If more than one element of \fIpath\fP is `\-',
A database can be supplied on standard input, using `\-' as an element
of \fIpath\fP.
If more than one element of \fIpath\fP is `\-',
later instances are ignored (and a warning message is printed).
.IP
The file name database format changed starting with GNU
@ -240,22 +296,32 @@ appears to be derived from the same code.
Significant changes to
.B locate
in reverse order:
.P
.TS
tab(|);
LL.
4.3.7 | Byte-order independent support for old database format
4.3.3 | locate \fI\-i\fR supports multi-byte characters correctly
| Introduced \fI\-\-max_db_age\fR
4.3.2 | Support for the slocate database format
4.2.22| Introduced the \fI\-\-all\fR option
4.2.15| Introduced the \fI\-\-regex\fR option
4.2.14| Introduced options \fI\-L, \-P, \-H\fR
4.2.12| Empty items in \fBLOCATE_PATH\fR now indicate the default database
4.2.11| Introduced the \fI\-\-statistics\fR option
4.2.4 | Introduced \fI\-\-count\fR and \fI\-\-limit\fR
4.2.0 | Glob characters cause matching against the whole file name
4.0 | Introduced the LOCATE02 database format
3.7 | Locate can search multiple databases
4.3.7|T{
.na
Byte-order independent support for old database format
T}
4.3.3|locate \fI\-i\fR supports multi-byte characters correctly
\^|Introduced \fI\-\-max_db_age\fR
4.3.2|Support for the slocate database format
4.2.22|Introduced the \fI\-\-all\fR option
4.2.15|Introduced the \fI\-\-regex\fR option
4.2.14|Introduced options \fI\-L, \-P, \-H\fR
4.2.12|T{
.na
Empty items in \fBLOCATE_PATH\fR now indicate the default database
T}
4.2.11|Introduced the \fI\-\-statistics\fR option
4.2.4|Introduced \fI\-\-count\fR and \fI\-\-limit\fR
4.2.0|T{
.na
Glob characters cause matching against the whole file name
T}
4.0|Introduced the LOCATE02 database format
3.7|Locate can search multiple databases
.TE
.
.SH "BUGS"
@ -287,7 +353,7 @@ mailing list:
.RE
.
.SH COPYRIGHT
Copyright \(co 1994\(en2024 Free Software Foundation, Inc.
Copyright \(co 1994\*(en2026 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.
.br
This is free software: you are free to change and redistribute it.

View File

@ -1,5 +1,5 @@
/* locate -- search databases for filenames that match patterns
Copyright (C) 1994-2024 Free Software Foundation, Inc.
Copyright (C) 1994-2026 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -35,7 +35,7 @@
8, No 1, February/March, 1983, p. 8.
However, latterly code changes to provide additional functionality
became dificult to make with the existing reading scheme, and so
became difficult to make with the existing reading scheme, and so
we no longer perform the matching as efficiently as we used to (that is,
we no longer use the same algorithm).
@ -1033,7 +1033,7 @@ search_one_database (int argc,
* We ensure that we can return to the previous behaviour
* by using two variables, do_check_existence (which we act on)
* and check_existence (which indicates the default before we
* adjust it on the bassis of what kind of database we;re using
* adjust it on the basis of what kind of database we're using
*/
do_check_existence = check_existence;
@ -1353,8 +1353,6 @@ search_one_database (int argc,
}
extern char *version_string;
static void _GL_ATTRIBUTE_NORETURN
usage (int status)
{
@ -1758,7 +1756,7 @@ dolocate (int argc, char **argv, int secure_db_fd)
if (did_stdin)
{
error (0, 0,
_("warning: the locate database can only be read from stdin once."));
_("warning: the locate database can only be read from standard input once."));
return 0;
}
else

View File

@ -1,4 +1,10 @@
.TH LOCATEDB 5 \" -*- nroff -*-
.TH LOCATEDB 5 2020-12-27 findutils \" -*- nroff -*-
.ie \n(.g \{\
. ds en \(en
.\}
.el \{\
. ds en \-
.\}
.SH NAME
locatedb \- front-compressed file name database
.
@ -107,7 +113,7 @@ format starts with a 256 byte table containing the 128 most common
bigrams in the file list. A bigram is a pair of adjacent bytes.
Bytes in the database that have the high bit set are indexes (with the
high bit cleared) into the bigram table. The bigram and
offset-differential count coding makes these databases 20\(en25% smaller
offset-differential count coding makes these databases 20\*(en25% smaller
than the new format, but makes them not 8-bit clean. Any byte in a
file name that is in the ranges used for the special codes is replaced
in the database by a question mark, which not coincidentally is the
@ -115,20 +121,20 @@ shell wildcard to match a single character.
.
.SH EXAMPLE
.nf
\&
Input to \fBfrcode\fP:
.\" with nulls changed to newlines:
/usr/src
/usr/src/cmd/aardvark.c
/usr/src/cmd/armadillo.c
/usr/tmp/zoo
\&
Length of the longest prefix of the preceding entry to share:
0 /usr/src
8 /cmd/aardvark.c
14 rmadillo.c
5 tmp/zoo
\&
.fi
Output from \fBfrcode\fP, with trailing nulls changed to newlines
and count bytes made printable:
@ -138,8 +144,8 @@ and count bytes made printable:
8 /cmd/aardvark.c
6 rmadillo.c
\-9 tmp/zoo
(6 = 14 - 8, and -9 = 5 - 14)
\&
(6 = 14 \- 8, and \-9 = 5 \- 14)
.fi
.
.SH "REPORTING BUGS"
@ -159,7 +165,7 @@ mailing list:
.RE
.
.SH COPYRIGHT
Copyright \(co 1994\(en2024 Free Software Foundation, Inc.
Copyright \(co 1994\*(en2026 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.
.br
This is free software: you are free to change and redistribute it.

View File

@ -1,5 +1,5 @@
/* locatedb.h -- declarations for the locate database
Copyright (C) 1994-2024 Free Software Foundation, Inc.
Copyright (C) 1994-2026 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -47,10 +47,10 @@
/* These are used for old, bigram-encoded databases: */
/* Means the differential count follows in a 2-byte int instead. */
# define LOCATEDB_OLD_ESCAPE 30
# define LOCATEDB_OLD_ESCAPE 30
/* Offset added to differential counts to encode them as positive numbers. */
# define LOCATEDB_OLD_OFFSET 14
# define LOCATEDB_OLD_OFFSET 14
typedef enum
{
@ -60,8 +60,8 @@ typedef enum
} GetwordEndianState;
int getword (FILE *fp, const char *filename,
size_t maxvalue,
GetwordEndianState *endian_state_flag);
size_t maxvalue,
GetwordEndianState *endian_state_flag);
# define SLOCATE_DB_MAGIC_LEN 2

View File

@ -1,4 +1,4 @@
# Copyright (C) 2001-2024 Free Software Foundation, Inc.
# Copyright (C) 2001-2026 Free Software Foundation, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by

View File

@ -1,6 +1,6 @@
# -*- TCL -*-
# Test-specific TCL procedures required by DejaGNU.
# Copyright (C) 1994-2024 Free Software Foundation, Inc.
# Copyright (C) 1994-2026 Free Software Foundation, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by

View File

@ -1,8 +1,15 @@
.TH UPDATEDB 1 \" -*- nroff -*-
.TH UPDATEDB 1 2023-11-10 findutils \" -*- nroff -*-
.ie \n(.g \{\
. ds en \(en
.\}
.el \{\
. ds en \-
.\}
.SH NAME
updatedb \- update a file name database
.SH SYNOPSIS
.B updatedb [\fIoptions\fP]
.B updatedb
.RI [ options ]
.
.SH DESCRIPTION
This manual page
@ -139,7 +146,7 @@ mailing list:
.RE
.
.SH COPYRIGHT
Copyright \(co 1994\(en2024 Free Software Foundation, Inc.
Copyright \(co 1994\*(en2026 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.
.br
This is free software: you are free to change and redistribute it.

View File

@ -1,6 +1,6 @@
#! /bin/sh
# updatedb -- build a locate pathname database
# Copyright (C) 1994-2024 Free Software Foundation, Inc.
# Copyright (C) 1994-2026 Free Software Foundation, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -39,7 +39,7 @@ Written by Eric B. Decker, James Youngman, and Kevin Dalley.
# character encoding errors in text-based tools like "sort". To avoid
# this, we set LC_ALL=C. This will, presumably, not work perfectly on
# systems where LC_ALL is not the way to do locale configuration or
# some other seting can override this.
# some other setting can override this.
LC_ALL=C
export LC_ALL
@ -147,7 +147,7 @@ select_shell() {
# Any global options for find?
: ${FINDOPTIONS=}
# What shell shoud we use? We should use a POSIX-ish sh.
# What shell should we use? We should use a POSIX-ish sh.
: ${SHELL="/bin/sh"}
# Non-network directories to put in the database.

View File

@ -1,5 +1,5 @@
/* word_io.c -- word oriented I/O
Copyright (C) 2007-2024 Free Software Foundation, Inc.
Copyright (C) 2007-2026 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -20,13 +20,13 @@
/* system headers. */
#include <errno.h>
#include <stdbool.h> /* for bool */
#include <stdbool.h> /* for bool */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* gnulib headers. */
#include "byteswap.h"
#include <endian.h>
#include "quotearg.h"
/* find headers. */
@ -38,62 +38,62 @@ enum { WORDBYTES=4 };
static int
decode_value (const unsigned char data[],
int limit,
GetwordEndianState *endian_state_flag,
const char *filename)
int limit,
GetwordEndianState *endian_state_flag,
const char *filename)
{
int swapped;
union
{
int ival; /* native representation */
int ival; /* native representation */
unsigned char data[WORDBYTES];
} u;
u.ival = 0;
memcpy (&u.data, data, WORDBYTES);
swapped = bswap_32(u.ival); /* byteswapped */
swapped = htobe32 (u.ival); /* byteswapped */
if (*endian_state_flag == GetwordEndianStateInitial)
{
if (u.ival <= limit)
{
if (swapped > limit)
{
/* the native value is inside the limit and the
* swapped value is not. We take this as proof
* that we should be using the native byte order.
*/
*endian_state_flag = GetwordEndianStateNative;
}
return u.ival;
}
{
if (swapped > limit)
{
/* the native value is inside the limit and the
* swapped value is not. We take this as proof
* that we should be using the native byte order.
*/
*endian_state_flag = GetwordEndianStateNative;
}
return u.ival;
}
else
{
if (swapped <= limit)
{
/* Aha, now we know we have to byte-swap. */
error (0, 0,
_("WARNING: locate database %s was "
"built with a different byte order"),
quotearg_n_style (0, locale_quoting_style, filename));
*endian_state_flag = GetwordEndianStateSwab;
return swapped;
}
else
{
/* u.ival > limit and swapped > limit. For the moment, assume
* native ordering.
*/
return u.ival;
}
}
{
if (swapped <= limit)
{
/* Aha, now we know we have to byte-swap. */
error (0, 0,
_("WARNING: locate database %s was "
"built with a different byte order"),
quotearg_n_style (0, locale_quoting_style, filename));
*endian_state_flag = GetwordEndianStateSwab;
return swapped;
}
else
{
/* u.ival > limit and swapped > limit. For the moment, assume
* native ordering.
*/
return u.ival;
}
}
}
else
{
/* We already know the byte order. */
if (*endian_state_flag == GetwordEndianStateSwab)
return swapped;
return swapped;
else
return u.ival;
return u.ival;
}
}
@ -101,9 +101,9 @@ decode_value (const unsigned char data[],
int
getword (FILE *fp,
const char *filename,
size_t maxvalue,
GetwordEndianState *endian_state_flag)
const char *filename,
size_t maxvalue,
GetwordEndianState *endian_state_flag)
{
unsigned char data[4];
size_t bytes_read;
@ -113,15 +113,15 @@ getword (FILE *fp,
if (bytes_read != 1)
{
const char * quoted_name = quotearg_n_style (0, locale_quoting_style,
filename);
filename);
/* Distinguish between a truncated database and an I/O error.
* Either condition is fatal.
*/
if (feof (fp))
error (EXIT_FAILURE, 0, _("unexpected EOF in %s"), quoted_name);
error (EXIT_FAILURE, 0, _("unexpected EOF in %s"), quoted_name);
else
error (EXIT_FAILURE, errno,
_("error reading a word from %s"), quoted_name);
error (EXIT_FAILURE, errno,
_("error reading a word from %s"), quoted_name);
abort ();
}
else

View File

@ -1,4 +1,4 @@
dnl Copyright (C) 1995-2024 Free Software Foundation, Inc.
dnl Copyright (C) 1995-2026 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.

View File

@ -1,4 +1,4 @@
dnl Copyright (C) 2007-2024 Free Software Foundation, Inc.
dnl Copyright (C) 2007-2026 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.

1
po/.gitignore vendored
View File

@ -1,3 +1,4 @@
/insert-header.sed
/*.gmo
/*.po
/.reference/

View File

@ -1,5 +1,5 @@
# List of source files containing translatable strings.
# Copyright (C) 2000-2024 Free Software Foundation, Inc.
# Copyright (C) 2000-2026 Free Software Foundation, Inc.
# Copying and distribution of this file, with or without
# modification, are permitted provided the copyright notice

1
tests/.gitignore vendored
View File

@ -1,5 +1,6 @@
/*/*.log
/*/*.trs
/init.sh
/test-suite.log
/xargs/.dirstamp
/xargs/test-sigusr

Some files were not shown because too many files have changed in this diff Show More