2006-08-15  Paul Eggert  <eggert@cs.ucla.edu>

	Port recent fixes for symbolic modes involving X from gnulib,
	and clarify the documentation in this area.
	* doc/find.texi: Use "file mode bits" when talking about
	all the file mode bits (including setuid, setgid, and sticky),
	and "permissions" when talking only about permissions bits
	(read, write, execute/search).  Use "execute/search" to
	talk about the x bit, since it means both.  You do not need
	permission to the linked-to file to follow a symlink for
	syscalls like "stat", but you do need search permission for
	the directories you traverse.  Clarify the explanation of
	-perm.  Use "that" instead of "which" when "which" isn't
	quite correct English.
	(Mode Bits): Renamed from Permissions.  All uses changed.
	* doc/perm.texi: Sync from coreutils 6.0.
	* find/defs.h (struct perm_val.val): Now an array of two items,
	one for non-directories, and one for directories.  This is
	to handle symbolic modes like +X correctly.
	* find/parser.c (parse_perm): Likewise.  Also, adjust to
	latest gnulib interface for mode_adjust.
	* find/pred.c (pred_perm): Likewise.
	* find/testsuite/Makefile.am (EXTRA_DIST_XO): Add find.posix/perm-X.xo.
	(EXTRA_DIST_EXP): Add find.posix/perm-X.exp.
	* find/testsuite/find.posix/perm-X.exp: New file.
	* find/testsuite/find.posix/perm-X.so: New file.

Index: doc/find.texi
===================================================================
RCS file: /cvsroot/findutils/findutils/doc/find.texi,v
retrieving revision 1.119
diff -p -u -b -w -r1.119 find.texi
--- doc/find.texi	7 Aug 2006 10:12:51 -0000	1.119
+++ doc/find.texi	15 Aug 2006 21:12:41 -0000
@@ -188,7 +188,7 @@ are of a certain type (regular file, dir
 @item
 are owned by a certain user or group;
 @item
-have certain access permissions;
+have certain access permissions or special mode bits;
 @item
 contain text that matches a certain pattern;
 @item
@@ -346,7 +346,7 @@ more information about the matching file
 * Size::
 * Type::
 * Owner::
-* Permissions::
+* Mode Bits::
 * Contents::
 * Directories::
 * Filesystems::
@@ -620,11 +620,12 @@ links listed on the command line are der
 links are not.
 
 Symbolic links are different to ``hard links'' in the sense that you
-need permissions upon the linked-to file in order to be able to
+need permission to search the directories
+in the the linked-to file name to
 dereference the link.  This can mean that even if you specify the
 @samp{-L} option, @code{find} may not be able to determine the
 properties of the file that the link points to (because you don't have
-sufficient permissions).  In this situation, @code{find} uses the
+sufficient permission).  In this situation, @code{find} uses the
 properties of the link itself.  This also occurs if a symbolic link
 exists but points to a file that is missing.
 
@@ -1008,10 +1009,10 @@ existing user or group, using the @code{
 program.
 @end deffn
 
-@node Permissions
-@section Permissions
+@node Mode Bits
+@section File Mode Bits
 
-@xref{File Permissions}, for information on how file permissions are
+@xref{File Permissions}, for information on how file mode bits are
 structured and how to specify them.
 
 Four tests determine what users can do with files.  These are
@@ -1052,27 +1053,31 @@ operation; for example, the filesystem m
 @end deffn
 
 @deffn Test -executable
-True if the file can be executed by the invoking user.
+True if the file can be executed/searched by the invoking user.
 @end deffn
 
-@deffn Test -perm mode
+@deffn Test -perm pmode
 
-True if the file's permissions are exactly @var{mode}, which can be
-numeric or symbolic.
+True if the file's mode bits match @var{pmode}, which can be
+either a symbolic or numeric @var{mode} (@pxref{File Permissions})
+optionally prefixed by @samp{-} or @samp{/}.
 
-If @var{mode} starts with @samp{-}, true if
-@emph{all} of the permissions set in @var{mode} are set for the file;
-permissions not set in @var{mode} are ignored.
+A @var{pmode} that starts with neither @samp{-} nor @samp{/} matches
+if @var{mode} exactly matches the file mode bits.
 
-If @var{mode} starts with @samp{/}, true if
-@emph{any} of the permissions set in @var{mode} are set for the file;
-permissions not set in @var{mode} are ignored.
+A @var{pmode} that starts with @samp{-} matches if
+@emph{all} the file mode bits set in @var{mode} are set for the file;
+bits not set in @var{mode} are ignored.
+
+A @var{pmode} that starts with @samp{/} matches if
+@emph{any} of the file mode bits set in @var{mode} are set for the file;
+bits not set in @var{mode} are ignored.
 This is a GNU extension.
 
 If you don't use the @samp{/} or @samp{-} form with a symbolic mode
 string, you may have to specify a rather complex mode string.  For
-example @samp{-perm g=w} will only match files which have mode 0020
-(that is, ones for which group write permission is the only permission
+example @samp{-perm g=w} will only match files that have mode 0020
+(that is, ones for which group write permission is the only file mode bit
 set).  It is more likely that you will want to use the @samp{/} or
 @samp{-} forms, for example @samp{-perm -g=w}, which matches any file
 with group write permission.
@@ -1080,24 +1085,24 @@ with group write permission.
 
 @table @samp
 @item -perm 664
-Match files which have read and write permission for their owner,
-and group, but which the rest of the world can read but not write to.
-Files which meet these criteria but have other permissions bits set
-(for example if someone can execute the file) will not be matched.
+Match files that have read and write permission for their owner,
+and group, but that the rest of the world can read but not write to.
+Do not match files that meet these criteria but have other file mode
+bits set (for example if someone can execute/search the file).
 
 @item -perm -664
-Match files which have read and write permission for their owner,
-and group, but which the rest of the world can read but not write to,
-without regard to the presence of any extra permission bits (for
-example the executable bit).  This will match a file which has mode
+Match files that have read and write permission for their owner,
+and group, but that the rest of the world can read but not write to,
+without regard to the presence of any extra file mode bits (for
+example the executable bit).  This matchs a file with mode
 0777, for example.
 
 @item -perm /222
-Match files which are writable by somebody (their owner, or
+Match files that are writable by somebody (their owner, or
 their group, or anybody else).
 
 @item -perm /022
-Match files which are writable by either their owner or their
+Match files that are writable by either their owner or their
 group.  The files don't have to be writable by both the owner and
 group to be matched; either will do.
 
@@ -1105,16 +1110,16 @@ group to be matched; either will do.
 As above.
 
 @item -perm /g=w,o=w
-As above
+As above.
 
 @item -perm -022
-Search for files which are writable by both their owner and their
+Match files that are writable by both their owner and their
 group.
 
 @item -perm -444 -perm /222 ! -perm /111
-Search for files which are readable for everybody, have at least one
-write bit set (i.e. somebody can write to them), but which cannot be
-executed by anybody.  Note that in some shells the @samp{!} must be
+Match files that are readable for everybody, have at least one
+write bit set (i.e. somebody can write to them), but that cannot be
+executed/searched by anybody.  Note that in some shells the @samp{!} must be
 escaped;.
 
 @item -perm -a+r -perm /a+w ! -perm /a+x
@@ -1491,13 +1496,13 @@ which case 512-byte blocks are used.  @x
 files based on their size.
 
 @item
-The file's type and permissions.  The type is shown as a dash for a
+The file's type and file mode bits.  The type is shown as a dash for a
 regular file; for other file types, a letter like for @samp{-type} is
-used (@pxref{Type}).  The permissions are read, write, and execute for
+used (@pxref{Type}).  The file mode bits are read, write, and execute/search for
 the file's owner, its group, and other users, respectively; a dash
 means the permission is not granted.  @xref{File Permissions}, for
-more details about file permissions.  @xref{Permissions}, for how to
-find files based on their permissions.
+more details about file permissions.  @xref{Mode Bits}, for how to
+find files based on their file mode bits.
 
 @item
 The number of hard links to the file.
@@ -1666,17 +1671,17 @@ File's user name, or numeric user ID if 
 File's numeric user ID.
 @item %m
 @c full support, including # and 0.
-File's permissions (in octal).  If you always want to have a leading
+File's mode bits (in octal).  If you always want to have a leading
 zero on the number, use the '#' format flag, for example '%#m'.  
 
-The permission numbers used are the traditional Unix permission
+The file mode bit numbers used are the traditional Unix
 numbers, which will be as expected on most systems, but if your
-system's permission bit layout differs from the traditional Unix
+system's file mode bit layout differs from the traditional Unix
 semantics, you will see a difference between the mode as printed by
 @samp{%m} and the mode as it appears in @code{struct stat}.
 
 @item %M
-File's permissions (in symbolic form, as for @code{ls}).  This
+File's type and mode bits (in symbolic form, as for @code{ls}).  This
 directive is supported in findutils 4.2.5 and later.
 @end table
 
@@ -4746,4 +4751,3 @@ Expressions}, for more information on ex
 @comment LocalWords: su Timar ubins ug unstripped vf VM Weitzel
 @comment LocalWords: wildcard zlogout basename execdir wholename iwholename
 @comment LocalWords: timestamp timestamps Solaris FreeBSD OpenBSD POSIX
-
Index: doc/perm.texi
===================================================================
RCS file: /cvsroot/findutils/findutils/doc/perm.texi,v
retrieving revision 1.3
diff -p -u -b -w -r1.3 perm.texi
--- doc/perm.texi	12 Dec 2005 08:11:48 -0000	1.3
+++ doc/perm.texi	15 Aug 2006 21:12:41 -0000
@@ -1,16 +1,20 @@
-Each file has a set of @dfn{permissions} that control the kinds of
-access that users have to that file.  The permissions for a file are
-also called its @dfn{access mode}.  They can be represented either in
+Each file has a set of @dfn{file mode bits} that control the kinds of
+access that users have to that file.  They can be represented either in
 symbolic form or as an octal number.
 
 @menu
-* Mode Structure::              Structure of file permissions.
-* Symbolic Modes::              Mnemonic permissions representation.
-* Numeric Modes::               Permissions as octal numbers.
+* Mode Structure::              Structure of file mode bits.
+* Symbolic Modes::              Mnemonic representation of file mode bits.
+* Numeric Modes::               File mode bits as octal numbers.
+* Directory Setuid and Setgid:: Set-user-ID and set-group-ID on directories.
 @end menu
 
 @node Mode Structure
-@section Structure of File Permissions
+@section Structure of File Mode Bits
+
+The file mode bits have two parts: the @dfn{file permission bits},
+which control ordinary access to the file, and @dfn{special mode
+bits}, which affect only some files.
 
 There are three kinds of permissions that a user can have for a file:
 
@@ -24,7 +28,7 @@ list the contents of the directory.
 permission to write to (change) the file.  For directories, this means
 permission to create and remove files in the directory.
 @item
-@cindex execute permission
+@cindex execute/search permission
 permission to execute the file (run it as a program).  For directories,
 this means permission to access files in the directory.
 @end enumerate
@@ -50,58 +54,66 @@ file system the file is created on, and 
 can change the owner and group of a file by using the @command{chown} and
 @command{chgrp} commands.
 
-In addition to the three sets of three permissions listed above, a
-file's permissions have three special components, which affect only
-executable files (programs) and, on some systems, directories:
+In addition to the three sets of three permissions listed above, the
+file mode bits have three special components, which affect only
+executable files (programs) and, on most systems, directories:
 
 @enumerate
 @item
+@cindex set-user-ID
 @cindex setuid
 Set the process's effective user ID to that of the file upon execution
-(called the @dfn{setuid bit}).  No effect on directories.
+(called the @dfn{set-user-ID bit}, or sometimes the @dfn{setgid bit}).
+For directories on a few systems, give files created in the directory
+the same owner as the directory, no matter who creates them, and set
+the set-user-ID bit of newly-created subdirectories.
 @item
+@cindex set-group-ID
 @cindex setgid
 Set the process's effective group ID to that of the file upon execution
-(called the @dfn{setgid bit}).  For directories on some systems, put
-files created in the directory into the same group as the directory, no
-matter what group the user who creates them is in.
+(called the @dfn{set-group-ID bit}, or sometimes the @dfn{setgid bit}).
+For directories on most systems, give files created in the directory
+the same group as the directory, no matter what group the user who
+creates them is in, and set the set-group-ID bit of newly-created
+subdirectories.
 @item
 @cindex sticky
 @cindex swap space, saving text image in
 @cindex text image, saving in swap space
 @cindex restricted deletion flag
-prevent users from removing or renaming a file in a directory
+Prevent unprivileged users from removing or renaming a file in a directory
 unless they own the file or the directory; this is called the
-@dfn{restricted deletion flag} for the directory.
-For regular files on some systems, save the program's text image on the
+@dfn{restricted deletion flag} for the directory, and is commonly
+found on world-writable directories like @file{/tmp}.
+
+For regular files on some older systems, save the program's text image on the
 swap device so it will load more quickly when run; this is called the
 @dfn{sticky bit}.
 @end enumerate
 
-In addition to the permissions listed above, there may be file attributes
-specific to the file system, e.g: access control lists (ACLs), whether a
-file is compressed, whether a file can be modified (immutability), whether
+In addition to the file mode bits listed above, there may be file attributes
+specific to the file system, e.g., access control lists (ACLs), whether a
+file is compressed, whether a file can be modified (immutability), and whether
 a file can be dumped.  These are usually set using programs
 specific to the file system.  For example:
 @c should probably say a lot more about ACLs... someday
 
 @table @asis
 @item ext2
-On @acronym{GNU} and @acronym{GNU}/Linux the file permissions
-(``attributes'') specific to
+On @acronym{GNU} and @acronym{GNU}/Linux the file attributes specific to
 the ext2 file system are set using @command{chattr}.
 
 @item FFS
-On FreeBSD the file permissions (``flags'') specific to the FFS
-file system are set using @command{chrflags}.
+On FreeBSD the file flags specific to the FFS
+file system are set using @command{chflags}.
 @end table
 
-Although a file's permission ``bits'' allow an operation on that file,
+Even if a file's mode bits allow an operation on that file,
 that operation may still fail, because:
 
 @itemize
 @item
-the file-system-specific permissions do not permit it;
+the file-system-specific attributes or flags do not permit it; or
 
 @item
 the file system is mounted as read-only.
@@ -115,9 +127,9 @@ may have just run @code{chmod a+w FILE}.
 @section Symbolic Modes
 
 @cindex symbolic modes
-@dfn{Symbolic modes} represent changes to files' permissions as
+@dfn{Symbolic modes} represent changes to files' mode bits as
 operations on single-character symbols.  They allow you to modify either
-all or selected parts of files' permissions, optionally based on
+all or selected parts of files' mode bits, optionally based on
 their previous values, and perhaps on the current @code{umask} as well
 (@pxref{Umask and Protection}).
 
@@ -137,7 +149,7 @@ symbolic modes.
 @menu
 * Setting Permissions::          Basic operations on permissions.
 * Copying Permissions::          Copying existing permissions.
-* Changing Special Permissions:: Special permissions.
+* Changing Special Mode Bits::   Special mode bits.
 * Conditional Executability::    Conditionally affecting executability.
 * Multiple Changes::             Making multiple changes.
 * Umask and Protection::              The effect of the umask.
@@ -148,7 +160,7 @@ symbolic modes.
 
 The basic symbolic operations on a file's permissions are adding,
 removing, and setting the permission that certain users have to read,
-write, and execute the file.  These operations have the following
+write, and execute or search the file.  These operations have the following
 format:
 
 @example
@@ -213,11 +225,12 @@ the permission the @var{users} have to r
 @cindex write permission, symbolic
 the permission the @var{users} have to write to the file;
 @item x
-@cindex execute permission, symbolic
-the permission the @var{users} have to execute the file.
+@cindex execute/search permission, symbolic
+the permission the @var{users} have to execute the file,
+or search it if it is a directory.
 @end table
 
-For example, to give everyone permission to read and write a file,
+For example, to give everyone permission to read and write a regular file,
 but not to execute it, use:
 
 @example
@@ -275,38 +288,42 @@ it to mode 666 (@samp{rw-rw-rw-}).  If t
 (@samp{rwxr--r-x}).  The @samp{-} and @samp{=} operations work
 analogously.
 
-@node Changing Special Permissions
-@subsection Changing Special Permissions
+@node Changing Special Mode Bits
+@subsection Changing Special Mode Bits
 
-@cindex changing special permissions
-In addition to changing a file's read, write, and execute permissions,
-you can change its special permissions.  @xref{Mode Structure}, for a
-summary of these permissions.
+@cindex changing special mode bits
+In addition to changing a file's read, write, and execute/search permissions,
+you can change its special mode bits.  @xref{Mode Structure}, for a
+summary of these special mode bits.
 
-To change a file's permission to set the user ID on execution, use
+To change the file mode bits to set the user ID on execution, use
 @samp{u} in the @var{users} part of the symbolic mode and
 @samp{s} in the @var{permissions} part.
 
-To change a file's permission to set the group ID on execution, use
+To change the file mode bits to set the group ID on execution, use
 @samp{g} in the @var{users} part of the symbolic mode and
 @samp{s} in the @var{permissions} part.
 
-To change a file's permission to set the restricted deletion flag or sticky bit,
-omit the @var{users} part of the symbolic mode (or use @samp{a}) and put
+To set both user and group ID on execution, omit the @var{users} part
+of the symbolic mode (or use @samp{a}) and use @samp{s} in the
+@var{permissions} part.
+
+To change the file mode bits to set the restricted deletion flag or sticky bit,
+omit the @var{users} part of the symbolic mode (or use @samp{a}) and use
 @samp{t} in the @var{permissions} part.
 
-For example, to add set-user-ID permission to a program,
+For example, to set the set-user-ID mode bit of a program,
 you can use the mode:
 
 @example
 u+s
 @end example
 
-To remove both set-user-ID and set-group-ID permission from
+To remove both set-user-ID and set-group-ID mode bits from
 it, you can use the mode:
 
 @example
-ug-s
+a-s
 @end example
 
 To set the restricted deletion flag or sticky bit, you can use
@@ -320,8 +337,8 @@ The combination @samp{o+s} has no effect
 the combinations @samp{u+t} and @samp{g+t} have no effect, and
 @samp{o+t} acts like plain @samp{+t}.
 
-The @samp{=} operator is not very useful with special permissions; for
-example, the mode:
+The @samp{=} operator is not very useful with special mode bits.
+For example, the mode:
 
 @example
 o=t
@@ -329,15 +346,18 @@ o=t
 
 @noindent
 does set the restricted deletion flag or sticky bit, but it also
-removes all read, write, and execute permissions that users not in the
+removes all read, write, and execute/search permissions that users not in the
 file's group might have had for it.
 
+@xref{Directory Setuid and Setgid}, for additional rules concerning
+set-user-ID and set-group-ID bits and directories.
+
 @node Conditional Executability
 @subsection Conditional Executability
 
 @cindex conditional executability
 There is one more special type of symbolic permission: if you use
-@samp{X} instead of @samp{x}, execute permission is affected only if the
+@samp{X} instead of @samp{x}, execute/search permission is affected only if the
 file is a directory or already had execute permission.
 
 For example, this mode:
@@ -356,7 +376,7 @@ anyone could execute them before.
 @cindex multiple changes to permissions
 The format of symbolic modes is actually more complex than described
 above (@pxref{Setting Permissions}).  It provides two ways to make
-multiple changes to files' permissions.
+multiple changes to files' mode bits.
 
 The first way is to specify multiple @var{operation} and
 @var{permissions} parts after a @var{users} part in the symbolic mode.
@@ -370,7 +390,7 @@ og+rX-w
 @noindent
 gives users other than the owner of the file read permission and, if
 it is a directory or if someone already had execute permission
-to it, gives them execute permission; and it also denies them write
+to it, gives them execute/search permission; and it also denies them write
 permission to the file.  It does not affect the permission that the
 owner of the file has for it.  The above mode is equivalent to
 the two modes:
@@ -396,7 +416,7 @@ u=rwx,g=rx,o=
 @end example
 
 @noindent
-sets all of the non-special permissions for the file explicitly.  (It
+sets all of the permission bits for the file explicitly.  (It
 gives users who are not in the file's group no permission at all for
 it.)
 
@@ -408,7 +428,7 @@ a+r,g+x-w
 
 @noindent
 gives all users permission to read the file, and gives users who are in
-the file's group permission to execute it, as well, but not permission
+the file's group permission to execute/search it as well, but not permission
 to write to it.  The above mode could be written in several different
 ways; another is:
 
@@ -457,52 +477,116 @@ the file to all users.
 @section Numeric Modes
 
 @cindex numeric modes
-@cindex file permissions, numeric
+@cindex file mode bits, numeric
 @cindex octal numbers for file modes
 As an
 alternative to giving a symbolic mode, you can give an octal (base 8)
-number that represents the new mode.
+number that represents the mode.
 This number is always interpreted in octal; you do not have to add a
-leading 0, as you do in C.  Mode 0055 is the same as mode 55.
+leading @samp{0}, as you do in C.  Mode @samp{0055} is the same as
+mode @samp{55}.
 
 A numeric mode is usually shorter than the corresponding symbolic
-mode, but it is limited in that it cannot take into account a file's
-previous permissions; it can only set them absolutely.
+mode, but it is limited in that normally it cannot take into account the
+previous file mode bits; it can only set them absolutely.
+(As discussed in the next section, the set-user-ID and set-group-ID
+bits of directories are an exception to this general limitation.)
 
 The permissions granted to the user,
 to other users in the file's group,
 and to other users not in the file's group each require three
 bits, which are represented as one octal digit.  The three special
-permissions also require one bit each, and they are as a group
+mode bits also require one bit each, and they are as a group
 represented as another octal digit.  Here is how the bits are arranged,
 starting with the lowest valued bit:
 
 @example
 Value in  Corresponding
-Mode      Permission
+Mode      Mode Bit
 
           Other users not in the file's group:
-   1      Execute
+   1      Execute/search
    2      Write
    4      Read
 
           Other users in the file's group:
-  10      Execute
+  10      Execute/search
   20      Write
   40      Read
 
           The file's owner:
- 100      Execute
+ 100      Execute/search
  200      Write
  400      Read
 
-          Special permissions:
+          Special mode bits:
 1000      Restricted deletion flag or sticky bit
 2000      Set group ID on execution
 4000      Set user ID on execution
 @end example
 
-For example, numeric mode 4755 corresponds to symbolic mode
-@samp{u=rwxs,go=rx}, and numeric mode 664 corresponds to symbolic mode
-@samp{ug=rw,o=r}.  Numeric mode 0 corresponds to symbolic mode
+For example, numeric mode @samp{4755} corresponds to symbolic mode
+@samp{u=rwxs,go=rx}, and numeric mode @samp{664} corresponds to symbolic mode
+@samp{ug=rw,o=r}.  Numeric mode @samp{0} corresponds to symbolic mode
 @samp{a=}.
+
+@node Directory Setuid and Setgid
+@section Directories and the Set-User-ID and Set-Group-ID Bits
+
+On most systems, if a directory's set-group-ID bit is set, newly
+created subfiles inherit the same group as the directory, and newly
+created subdirectories inherit the set-group-ID bit of the parent
+directory.  On a few systems, a directory's set-user-ID bit has a
+similar effect on the ownership of new subfiles and the set-user-ID
+bits of new subdirectories.  These mechanisms let users share files
+more easily, by lessening the need to use @command{chmod} or
+@command{chown} to share new files.
+
+These convenience mechanisms rely on the set-user-ID and set-group-ID
+bits of directories.  If commands like @command{chmod} and
+@command{mkdir} routinely cleared these bits on directories, the
+mechanisms would be less convenient and it would be harder to share
+files.  Therefore, a command like @command{chmod} does not affect the
+set-user-ID or set-group-ID bits of a directory unless the user
+specifically mentions them in a symbolic mode, or sets them in
+a numeric mode.  For example, on systems that support
+set-group-ID inheritance:
+
+@example
+# These commands leave the set-user-ID and
+# set-group-ID bits of the subdirectories alone,
+# so that they retain their default values.
+mkdir A B C
+chmod 755 A
+chmod 0755 B
+chmod u=rwx,go=rx C
+mkdir -m 755 D
+mkdir -m 0755 E
+mkdir -m u=rwx,go=rx F
+@end example
+
+If you want to try to set these bits, you must mention them
+explicitly in the symbolic or numeric modes, e.g.:
+
+@example
+# These commands try to set the set-user-ID
+# and set-group-ID bits of the subdirectories.
+mkdir G H
+chmod 6755 G
+chmod u=rwx,go=rx,a+s H
+mkdir -m 6755 I
+mkdir -m u=rwx,go=rx,a+s J
+@end example
+
+If you want to try to clear these bits, you must mention them
+explicitly in a symbolic mode, e.g.:
+
+@example
+# This command tries to clear the set-user-ID
+# and set-group-ID bits of the directory D.
+chmod a-s D
+@end example
+
+This behavior is a @acronym{GNU} extension.  Portable scripts should
+not rely on requests to set or clear these bits on directories, as
+@acronym{POSIX} allows implementations to ignore these requests.
Index: find/defs.h
===================================================================
RCS file: /cvsroot/findutils/findutils/find/defs.h,v
retrieving revision 1.59
diff -p -u -b -w -r1.59 defs.h
--- find/defs.h	6 Aug 2006 17:34:45 -0000	1.59
+++ find/defs.h	15 Aug 2006 21:12:41 -0000
@@ -1,5 +1,5 @@
 /* defs.h -- data types and declarations.
-   Copyright (C) 1990, 91, 92, 93, 94, 2000, 2004, 2005 Free Software Foundation, Inc.
+   Copyright (C) 1990, 91, 92, 93, 94, 2000, 2004, 2005, 2006 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
@@ -201,7 +201,7 @@ struct long_val
 struct perm_val
 {
   enum permissions_type kind;
-  mode_t val;
+  mode_t val[2];
 };
 
 /* dir_id is used to support loop detection in find.c and 
Index: find/parser.c
===================================================================
RCS file: /cvsroot/findutils/findutils/find/parser.c,v
retrieving revision 1.90
diff -p -u -b -w -r1.90 parser.c
--- find/parser.c	5 Aug 2006 18:02:54 -0000	1.90
+++ find/parser.c	15 Aug 2006 21:12:41 -0000
@@ -1,6 +1,6 @@
 /* parser.c -- convert the command line args into an expression tree.
    Copyright (C) 1990, 1991, 1992, 1993, 1994, 2000, 2001, 2003, 
-                 2004, 2005 Free Software Foundation, Inc.
+                 2004, 2005, 2006 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
@@ -1403,7 +1403,7 @@ parse_wholename (const struct parser_tab
 static boolean
 parse_perm (const struct parser_table* entry, char **argv, int *arg_ptr)
 {
-  mode_t perm_val;
+  mode_t perm_val[2];
   float rate;
   int mode_start = 0;
   boolean havekind = false;
@@ -1472,7 +1472,8 @@ parse_perm (const struct parser_table* e
       if (NULL == change)
 	error (1, 0, _("invalid mode `%s'"), argv[*arg_ptr]);
     }
-  perm_val = mode_adjust (0, change, 0);
+  perm_val[0] = mode_adjust (0, false, 0, change, NULL);
+  perm_val[1] = mode_adjust (0, true, 0, change, NULL);
   free (change);
   
   our_pred = insert_primary (entry);
@@ -1497,7 +1498,7 @@ parse_perm (const struct parser_table* e
 	  break;
 	}
     }
-  if (('/' == argv[*arg_ptr][0]) && (0 == perm_val))
+  if (('/' == argv[*arg_ptr][0]) && (0 == perm_val[0]) && (0 == perm_val[1]))
     {
       /* The meaning of -perm /000 will change in the future.
        * It currently matches no files, but like -perm -000 it
@@ -1512,7 +1513,7 @@ parse_perm (const struct parser_table* e
 	     argv[*arg_ptr]);
     }
 
-  our_pred->args.perm.val = perm_val & MODE_ALL;
+  memcpy (our_pred->args.perm.val, perm_val, sizeof perm_val);
   (*arg_ptr)++;
   return true;
 }
Index: find/pred.c
===================================================================
RCS file: /cvsroot/findutils/findutils/find/pred.c,v
retrieving revision 1.74
diff -p -u -b -w -r1.74 pred.c
--- find/pred.c	10 Aug 2006 19:36:09 -0000	1.74
+++ find/pred.c	15 Aug 2006 21:12:41 -0000
@@ -1195,11 +1195,13 @@ pred_path (char *pathname, struct stat *
 boolean
 pred_perm (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
 {
+  mode_t mode = stat_buf->st_mode;
+  mode_t perm_val = pred_ptr->args.perm.val[S_ISDIR (mode) != 0];
   (void) pathname;
   switch (pred_ptr->args.perm.kind)
     {
     case PERM_AT_LEAST:
-      return (stat_buf->st_mode & pred_ptr->args.perm.val) == pred_ptr->args.perm.val;
+      return (mode & perm_val) == perm_val;
       break;
 
     case PERM_ANY:
@@ -1213,14 +1215,14 @@ pred_perm (char *pathname, struct stat *
        * Eric Blake's interpretation is that the mode argument is zero, 
        
        */
-      if (0 == pred_ptr->args.perm.val)
+      if (0 == perm_val)
 	return true;		/* Savannah bug 14748; we used to return false */
       else
-	return (stat_buf->st_mode & pred_ptr->args.perm.val) != 0;
+	return (mode & perm_val) != 0;
       break;
 
     case PERM_EXACT:
-      return (stat_buf->st_mode & MODE_ALL) == pred_ptr->args.perm.val;
+      return (mode & MODE_ALL) == perm_val;
       break;
 
     default:
Index: find/testsuite/Makefile.am
===================================================================
RCS file: /cvsroot/findutils/findutils/find/testsuite/Makefile.am,v
retrieving revision 1.30
diff -p -u -b -w -r1.30 Makefile.am
--- find/testsuite/Makefile.am	4 Jan 2006 19:22:38 -0000	1.30
+++ find/testsuite/Makefile.am	15 Aug 2006 21:12:41 -0000
@@ -63,6 +63,7 @@ find.posix/files-not-expressions3.xo \
 find.posix/grouping.xo \
 find.posix/links.xo \
 find.posix/name.xo \
+find.posix/perm-X.xo \
 find.posix/perm-vanilla.xo \
 find.posix/posixnot.xo \
 find.posix/prune.xo \
@@ -136,6 +137,7 @@ find.posix/files-not-expressions3.exp \
 find.posix/grouping.exp \
 find.posix/links.exp \
 find.posix/name.exp \
+find.posix/perm-X.exp \
 find.posix/perm-vanilla.exp \
 find.posix/posixnot.exp \
 find.posix/prune.exp \
--- /dev/null	2005-09-24 22:00:15.000000000 -0700
+++ find/testsuite/find.posix/perm-X.exp	2006-08-15 13:12:10.000000000 -0700
@@ -0,0 +1,12 @@
+# tests for -perm with X
+exec rm -rf tmp
+exec mkdir tmp
+exec chmod 755 tmp
+exec true > tmp/empty
+exec true > tmp/empty-xxx
+exec chmod 711 tmp/empty-xxx
+exec mkdir tmp/sub
+exec chmod 300 tmp/sub
+find_start p { tmp \( ! -name sub -o -prune \) -perm -u+w,a+X -print }
+exec chmod 700 tmp/sub
+exec rm -rf tmp
--- /dev/null	2005-09-24 22:00:15.000000000 -0700
+++ find/testsuite/find.posix/perm-X.xo	2006-08-15 13:11:00.000000000 -0700
@@ -0,0 +1,3 @@
+tmp
+tmp/empty
+tmp/empty-xxx
