bug-findutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[bug #14619] find -perm +... broken in 4.2.25


From: Eric Blake
Subject: [bug #14619] find -perm +... broken in 4.2.25
Date: Thu, 6 Oct 2005 08:54:35 -0600
User-agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; .NET CLR 1.1.4322)

Follow-up Comment #3, bug #14619 (project findutils):

The POSIX rules are that -perm mode only returns true on files that exactly
match mode, if mode is a valid POSIX mode without a leading -; and the POSIX
grammar for valid modes includes leading +.  The old findutils behavior were
often incompatible with POSIX (find ignored the leading plus, then parsed the
remaining mode, then returned true if any of the specified bits in the
remaining mode were set on a file).  The new behavior is that the leading
plus is part of the mode, then find returns true only on an EXACT match.

The POSIX rules are found in
http://www.opengroup.org/onlinepubs/009695399/utilities/find.html and
http://www.opengroup.org/onlinepubs/009695399/utilities/chmod.html

Now, for your example: the old behavior of -perm +x is to treat mode as "x",
which maps to 0111, then return true if any of the three execute bits are set
on the file without regard to the read or write bits.  This is now provided by
-perm /x.  The new behavior of -perm +x is to treat mode as "+x", which maps
to 0111 & ~umask during chmod, but which maps to 0111 & 07777 in find [see
note 1 below], then to return true on files that are EXACTLY that mode (ie a
file that has NO read or write permissions, but all three execute
permissions).  Some modes, like "+x", are extremely rare in file systems,
explaining why your output has dramatically decreased.

Another example: -perm +u+x used to be (and -perm /u+x still should be)
treated as the mode "u+x", which maps to 0100, then returning true for ALL
files that have the u+x bit set regardless of the state of their other bits. 
Now, per POSIX, +u+x is treated as the valid mode "+u+x" (which is identical
to "+u,+x", and again maps to 0111 & 07777).

The only case where the 4.2.25 behavior is retained is where the mode given
to perm is not a valid POSIX mode, but when stripping the leading plus, a
valid mode results.  An example of this would be -perm +a+x.  "+a+x" is not a
valid mode, but "a+x" is, and maps to 0111.  So, findutils invokes the old
behavior of selecting all files that have any one of their three execute bits
set, regardless of the state of the read or write bits.

Unfortunately, the grammar for modes permitted by POSIX state that a leading
+ can be followed by: , + - = u g o r w x X s t.  The ONLY character that can
appear in a valid mode but which cannot directly follow '+' is 'a'.  So in
terms of backwards compatibility, EVERY symbolic mode, except for those
starting with a leading 'a', are affected by the change in findutils
semantics to be POSIX compliant, from the old behavior of returning true if
any bit in the specified mode is set regardless of unspecified bits, to the
new behavior of returning true if there is an exact match (all bits
specified, and no other bits, are set).  Thus, you should get used to -perm
/mode instead of -perm +mode.

[note 1] One of the POSIX requirements is ambiguous when read in English - it
states: "An op symbol of '+' shall set the appropriate mode bits in the
template; '-' shall clear the appropriate bits; '=' shall set the appropriate
mode bits, without regard to the contents of process' file mode creation
mask."  One parse is roughly "('+' shall set); ('-' shall clear); ('=' shall
set, and ignore umask)",  the other parse is roughly "('+' shall set; '-'
shall clear; '=' shall set), all while ignoring umask".  But it looks like
findutils 4.2.25 chose the second parse (ignore the umask for all three ops,
and not just =), as evidenced by this trace:

$ touch 100 111
$ chmod 100 100
$ chmod 111 111
$ umask 011
$ find . -perm +x
./111
$

If the umask mattered, then +x maps to 0111 & ~umask, which would then find
only ./100.  But since findutils is ignoring umask, then +x maps to 0111 &
07777, which finds only ./111.


    _______________________________________________________

Reply to this item at:

  <http://savannah.gnu.org/bugs/?func=detailitem&item_id=14619>

_______________________________________________
  Message sent via/by Savannah
  http://savannah.gnu.org/





reply via email to

[Prev in Thread] Current Thread [Next in Thread]