[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
portability patch for io/ftw.c
From: |
Jim Meyering |
Subject: |
portability patch for io/ftw.c |
Date: |
Fri, 07 Feb 2003 10:59:58 +0100 |
Hi,
ftw.c is now being used in the GNU coreutils.
Here are the portability-related changes I've
made in order to use it outside of glibc.
This does introduce reliance on wrapper code outside of libc
(in particular, a wrapper for lstat that properly handles
trailing slashes and a wrapper for getcwd that works like
glibc's extended one). Without such wrapper code, the function
silently misbehaves when used on non-glibc systems.
If you don't like relying on such wrapper functions, then please
at least add cpp directives that will cause the function not to
compile on non-glibc systems, so others don't end up debugging the
same problems this patch fixes.
At worst, let me know and I'll rework the patch not to
mention rpl_lstat or xgetcwd.
* io/ftw.c: Add autoconf-recommended block of alloca-related code.
Include autoconf-recommended block of dirent/NAMELEN-related
definitions and includes. Use NAMELEN throughout, rather than
_D_EXACT_NAMLEN.
[_LIBC]: Define NAMELEN to _D_EXACT_NAMLEN.
[!_LIBC] (__getcwd): Define to xgetcwd and declare xgetcwd.
(stpcpy): Declare, if necessary.
(mempcpy): Define, if necessary.
[!_LIBC] (__stpcpy, __mempcpy): Define.
[!_LIBC] (LXSTAT, XSTAT): Define.
(lstat) [!LIBC && !LSTAT_FOLLOWS_SLASHED_SYMLINK]: Define to rpl_lstat.
(find_object): Don't use c99-style struct initializer.
Tweak wording in a couple comments.
Index: io/ftw.c
===================================================================
RCS file: /cvs/glibc/libc/io/ftw.c,v
retrieving revision 1.40
diff -u -p -u -p -r1.40 ftw.c
--- io/ftw.c 5 Feb 2003 17:46:12 -0000 1.40
+++ io/ftw.c 7 Feb 2003 09:50:22 -0000
@@ -22,7 +22,42 @@
# include <config.h>
#endif
-#include <dirent.h>
+#if __GNUC__
+# define alloca __builtin_alloca
+#else
+# if HAVE_ALLOCA_H
+# include <alloca.h>
+# else
+# ifdef _AIX
+ # pragma alloca
+# else
+char *alloca ();
+# endif
+# endif
+#endif
+
+#if defined _LIBC
+# include <dirent.h>
+# define NAMLEN(dirent) _D_EXACT_NAMLEN(dirent)
+#else
+# if HAVE_DIRENT_H || defined _LIBC
+# include <dirent.h>
+# define NAMLEN(dirent) strlen ((dirent)->d_name)
+# else
+# define dirent direct
+# define NAMLEN(dirent) (dirent)->d_namlen
+# if HAVE_SYS_NDIR_H
+# include <sys/ndir.h>
+# endif
+# if HAVE_SYS_DIR_H
+# include <sys/dir.h>
+# endif
+# if HAVE_NDIR_H
+# include <ndir.h>
+# endif
+# endif
+#endif
+
#include <errno.h>
#include <ftw.h>
#include <limits.h>
@@ -39,6 +74,15 @@
# include <sys/stat.h>
#endif
+#if ! _LIBC && !HAVE_DECL_STPCPY && !defined stpcpy
+char *stpcpy ();
+#endif
+
+#if ! _LIBC && ! defined HAVE_MEMPCPY && ! defined mempcpy
+/* Be CAREFUL that there are no side effects in N. */
+# define mempcpy(D, S, N) ((void *) ((char *) memcpy (D, S, N) + (N)))
+#endif
+
/* #define NDEBUG 1 */
#include <assert.h>
@@ -49,8 +93,6 @@
# define __closedir closedir
# undef __fchdir
# define __fchdir fchdir
-# undef __getcwd
-# define __getcwd getcwd
# undef __opendir
# define __opendir opendir
# undef __readdir64
@@ -61,6 +103,10 @@
# define __tfind tfind
# undef __tsearch
# define __tsearch tsearch
+# undef __stpcpy
+# define __stpcpy stpcpy
+# undef __mempcpy
+# define __mempcpy mempcpy
# undef internal_function
# define internal_function /* empty */
# undef dirent64
@@ -69,6 +115,21 @@
# define MAX(a, b) ((a) > (b) ? (a) : (b))
#endif
+#ifndef _LIBC
+# undef __getcwd
+# define __getcwd(P, N) xgetcwd ()
+extern char *xgetcwd (void);
+#endif
+
+/* Arrange to make lstat calls go through the wrapper function
+ on systems with an lstat function that does not dereference symlinks
+ that are specified with a trailing slash. */
+#if ! _LIBC && ! LSTAT_FOLLOWS_SLASHED_SYMLINK
+int rpl_lstat (const char *, struct stat *);
+# undef lstat
+# define lstat(Name, Stat_buf) rpl_lstat(Name, Stat_buf)
+#endif
+
#ifndef __set_errno
# define __set_errno(Val) errno = (Val)
#endif
@@ -79,8 +140,13 @@
# define NFTW_NAME nftw
# define INO_T ino_t
# define STAT stat
-# define LXSTAT __lxstat
-# define XSTAT __xstat
+# ifdef _LIBC
+# define LXSTAT __lxstat
+# define XSTAT __xstat
+# else
+# define LXSTAT(V,f,sb) lstat (f,sb)
+# define XSTAT(V,f,sb) stat (f,sb)
+# endif
# define FTW_FUNC_T __ftw_func_t
# define NFTW_FUNC_T __nftw_func_t
#endif
@@ -124,7 +190,7 @@ struct ftw_data
int flags;
/* Conversion array for flag values. It is the identity mapping for
- `nftw' calls, otherwise it maps the values to those know by
+ `nftw' calls, otherwise it maps the values to those known by
`ftw'. */
const int *cvt_arr;
@@ -140,9 +206,8 @@ struct ftw_data
};
-/* Internally we use the FTW_* constants used for `nftw'. When the
- process called `ftw' we must reduce the flag to the known flags
- for `ftw'. */
+/* Internally we use the FTW_* constants used for `nftw'. When invoked
+ as `ftw', map each flag to the subset of values used by `ftw'. */
static const int nftw_arr[] =
{
FTW_F, FTW_D, FTW_DNR, FTW_NS, FTW_SL, FTW_DP, FTW_SLN
@@ -188,7 +253,9 @@ add_object (struct ftw_data *data, struc
static inline int
find_object (struct ftw_data *data, struct STAT *st)
{
- struct known_object obj = { .dev = st->st_dev, .ino = st->st_ino };
+ struct known_object obj;
+ obj.dev = st->st_dev;
+ obj.ino = st->st_ino;
return __tfind (&obj, &data->known_objects, object_compare) != NULL;
}
@@ -216,7 +283,7 @@ open_dir_stream (struct ftw_data *data,
while ((d = __readdir64 (st)) != NULL)
{
- size_t this_len = _D_EXACT_NAMLEN (d);
+ size_t this_len = NAMLEN (d);
if (actsize + this_len + 2 >= bufsize)
{
char *newp;
@@ -354,7 +421,7 @@ process_entry (struct ftw_data *data, st
if (result == 0 && (data->flags & FTW_CHDIR))
{
- /* Change back to current directory. */
+ /* Change back to parent directory. */
int done = 0;
if (dir->stream != NULL)
if (__fchdir (dirfd (dir->stream)) == 0)
@@ -452,7 +519,7 @@ ftw_dir (struct ftw_data *data, struct S
while (dir.stream != NULL && (d = __readdir64 (dir.stream)) != NULL)
{
- result = process_entry (data, &dir, d->d_name, _D_EXACT_NAMLEN (d));
+ result = process_entry (data, &dir, d->d_name, NAMLEN (d));
if (result != 0)
break;
}
pgpFUzGjLybIL.pgp
Description: PGP signature
- portability patch for io/ftw.c,
Jim Meyering <=