2017-08-31 Paul Eggert <eggert@cs.ucla.edu>
+ glob, backupfile: inode 0 is a valid inode number
+ * doc/posix-functions/readdir.texi (readdir):
+ * doc/posix-headers/dirent.texi (dirent.h):
+ Document more readdir portability issues.
+ * lib/backupfile.c (REAL_DIR_ENTRY): Remove.
+ (numbered_backup): Don’t treat inode 0 any differently from
+ other inode values.
+ * lib/glob.c (struct readdir_result): Remove skip_entry member.
+ (readdir_result_skip_entry, D_INO_TO_RESULT): Remove.
+ All uses removed.
+ * modules/glob (Depends-on): Remove d-ino.
+
glob: simplify symlink detection
* lib/glob.c (dirent_type): New type. Use uint_fast8_t not
uint8_t, as C99 does not require uint8_t.
Portability problems not fixed by Gnulib:
@itemize
+@item
+Although POSIX places no restrictions on @code{d_ino} values, some
+older systems are rumored to return @code{d_ino} values equal to zero
+for directory entries that do not really exist. Although Gnulib
+formerly attempted to cater to these older systems, this caused
+misbehavior on standard systems and so Gnulib does not attempt to
+cater to them any more. If you know of any problems caused by this,
+please send a bug report.
@end itemize
@item
This header file is missing on some platforms:
MSVC 14.
+
+@item
+Although many systems define a @code{struct dirent} member named
+@code{d_type} and directory entry type macros like @code{DT_DIR} and
+@code{DT_LINK}, some do not:
+AIX 7.2, HP-UX 11, Solaris 11, probably others.
+
+@item
+On systems with @code{d_type}, not every filesystem supports
+@code{d_type}, and those lacking support will set it to @code{DT_UNKNOWN}.
+
+@item
+Some systems define a @code{struct dirent} member named @code{d_namlen}
+containing the string length of @code{d_name}, but others do not.
+
+@item
+Some systems define a @code{struct dirent} member named @code{d_off}
+containing a magic cookie suitable as an argument to @code{seekdir},
+but others do not.
+
+@item
+Some systems define a @code{struct dirent} member named
+@code{d_reclen} containing the number of bytes in the directory entry
+record, but others do not. This member has limited utility, as it is
+an implementation detail.
@end itemize
#ifndef _D_EXACT_NAMLEN
# define _D_EXACT_NAMLEN(dp) strlen ((dp)->d_name)
#endif
-#if D_INO_IN_DIRENT
-# define REAL_DIR_ENTRY(dp) ((dp)->d_ino != 0)
-#else
-# define REAL_DIR_ENTRY(dp) 1
-#endif
#if ! (HAVE_PATHCONF && defined _PC_NAME_MAX)
# define pathconf(file, option) (errno = -1)
bool all_9s;
size_t versionlen;
- if (! REAL_DIR_ENTRY (dp) || _D_EXACT_NAMLEN (dp) < baselen + 4)
+ if (_D_EXACT_NAMLEN (dp) < baselen + 4)
continue;
if (memcmp (buf + base_offset, dp->d_name, baselen + 2) != 0)
#if defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE
dirent_type type;
#endif
-#if defined _LIBC || defined D_INO_IN_DIRENT
- bool skip_entry;
-#endif
};
/* Initialize and return type member of struct readdir_result. */
#endif
}
-/* Initialize and return skip_entry member of struct readdir_result. */
-static bool
-readdir_result_skip_entry (struct readdir_result d)
-{
-/* Initializer for skip_entry. POSIX does not require that the d_ino
- field be present, and some systems do not provide it. */
-#if defined _LIBC || defined D_INO_IN_DIRENT
-# define D_INO_TO_RESULT(source) (source)->d_ino == 0,
- return d.skip_entry;
-#else
-# define D_INO_TO_RESULT(source)
- return false;
-#endif
-}
-
/* Construct an initializer for a struct readdir_result object from a
struct dirent *. No copy of the name is made. */
#define READDIR_RESULT_INITIALIZER(source) \
{ \
source->d_name, \
D_TYPE_TO_RESULT (source) \
- D_INO_TO_RESULT (source) \
}
/* Call gl_readdir on STREAM. This macro can be overridden to reduce
}
if (d.name == NULL)
break;
- if (readdir_result_skip_entry (d))
- continue;
/* If we shall match only directories use the information
provided by the dirent call if possible. */
alloca [test -n "$GLOB_H"]
builtin-expect [test -n "$GLOB_H"]
closedir [test -n "$GLOB_H"]
-d-ino [test -n "$GLOB_H"]
d-type [test -n "$GLOB_H"]
dirfd [test -n "$GLOB_H"]
flexmember [test -n "$GLOB_H"]