mirror of
https://sourceware.org/git/glibc.git
synced 2025-07-28 00:21:52 +03:00
Update.
2003-11-07 Jakub Jelinek <jakub@redhat.com> * io/ftw.c (NFTW_OLD_NAME, NFTW_NEW_NAME): Define. (ftw_dir, ftw_startup): Add __attribute ((noinline)). (NFTW_OLD_NAME, NFTW_NEW_NAME): New functions. (NFTW_NAME): Only define if !_LIBC, add versioned_symbol and compat_symbol. * io/ftw64.c (NFTW_OLD_NAME, NFTW_NEW_NAME): Define. * io/Versions (libc): Export nftw@@GLIBC_2.3.3 and nftw64@@GLIBC_2.3.3. * io/ftw.h (FTW_ACTIONRETVAL): New flag. (FTW_CONTINUE, FTW_STOP, FTW_SKIP_SUBTREE, FTW_SKIP_SIBLINGS): New. * io/ftw.c (ftw_dir): Add old_dir argument. Clear result if it was FTW_SKIP_SIBLINGS after processing all dir entries. Change cwd back if old_dir != NULL. (process_entry): Adjust caller. Don't change cwd back here. Change FTW_SKIP_SUBTREE result to 0. (ftw_startup): Adjust ftw_dir caller. Clear result if it was FTW_SKIP_SUBTREE or FTW_SKIP_SIBLINGS. * io/ftwtest.c (skip_subtree, skip_siblings): New variables. (options, main): Add --skip-subtree and --skip-siblings options. (cb): Use return FTW_CONTINUE instead of return 0. Handle --skip-subtree and --skip-siblings. * io/ftwtest-sh: Add tests for FTW_ACTIONRETVAL. * manual/filesys.texi: Document FTW_ACTIONRETVAL.
This commit is contained in:
112
io/ftw.c
112
io/ftw.c
@ -135,6 +135,8 @@ int rpl_lstat (const char *, struct stat *);
|
||||
#ifndef FTW_NAME
|
||||
# define FTW_NAME ftw
|
||||
# define NFTW_NAME nftw
|
||||
# define NFTW_OLD_NAME __old_nftw
|
||||
# define NFTW_NEW_NAME __new_nftw
|
||||
# define INO_T ino_t
|
||||
# define STAT stat
|
||||
# ifdef _LIBC
|
||||
@ -217,7 +219,8 @@ static const int ftw_arr[] =
|
||||
|
||||
|
||||
/* Forward declarations of local functions. */
|
||||
static int ftw_dir (struct ftw_data *data, struct STAT *st) internal_function;
|
||||
static int ftw_dir (struct ftw_data *data, struct STAT *st,
|
||||
struct dir_data *old_dir) internal_function;
|
||||
|
||||
|
||||
static int
|
||||
@ -415,43 +418,24 @@ process_entry (struct ftw_data *data, struct dir_data *dir, const char *name,
|
||||
|| (!find_object (data, &st)
|
||||
/* Remember the object. */
|
||||
&& (result = add_object (data, &st)) == 0))
|
||||
{
|
||||
result = ftw_dir (data, &st);
|
||||
|
||||
if (result == 0 && (data->flags & FTW_CHDIR))
|
||||
{
|
||||
/* Change back to the parent directory. */
|
||||
int done = 0;
|
||||
if (dir->stream != NULL)
|
||||
if (__fchdir (dirfd (dir->stream)) == 0)
|
||||
done = 1;
|
||||
|
||||
if (!done)
|
||||
{
|
||||
if (data->ftw.base == 1)
|
||||
{
|
||||
if (__chdir ("/") < 0)
|
||||
result = -1;
|
||||
}
|
||||
else
|
||||
if (__chdir ("..") < 0)
|
||||
result = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
result = ftw_dir (data, &st, dir);
|
||||
}
|
||||
else
|
||||
result = (*data->func) (data->dirbuf, &st, data->cvt_arr[flag],
|
||||
&data->ftw);
|
||||
}
|
||||
|
||||
if ((data->flags & FTW_ACTIONRETVAL) && result == FTW_SKIP_SUBTREE)
|
||||
result = 0;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
__attribute ((noinline))
|
||||
internal_function
|
||||
ftw_dir (struct ftw_data *data, struct STAT *st)
|
||||
ftw_dir (struct ftw_data *data, struct STAT *st, struct dir_data *old_dir)
|
||||
{
|
||||
struct dir_data dir;
|
||||
struct dirent64 *d;
|
||||
@ -550,6 +534,9 @@ fail:
|
||||
__set_errno (save_err);
|
||||
}
|
||||
|
||||
if ((data->flags & FTW_ACTIONRETVAL) && result == FTW_SKIP_SIBLINGS)
|
||||
result = 0;
|
||||
|
||||
/* Prepare the return, revert the `struct FTW' information. */
|
||||
data->dirbuf[data->ftw.base - 1] = '\0';
|
||||
--data->ftw.level;
|
||||
@ -559,11 +546,37 @@ fail:
|
||||
if (result == 0 && (data->flags & FTW_DEPTH))
|
||||
result = (*data->func) (data->dirbuf, st, FTW_DP, &data->ftw);
|
||||
|
||||
if (old_dir
|
||||
&& (data->flags & FTW_CHDIR)
|
||||
&& (result == 0
|
||||
|| ((data->flags & FTW_ACTIONRETVAL)
|
||||
&& (result != -1 && result != FTW_STOP))))
|
||||
{
|
||||
/* Change back to the parent directory. */
|
||||
int done = 0;
|
||||
if (old_dir->stream != NULL)
|
||||
if (__fchdir (dirfd (old_dir->stream)) == 0)
|
||||
done = 1;
|
||||
|
||||
if (!done)
|
||||
{
|
||||
if (data->ftw.base == 1)
|
||||
{
|
||||
if (__chdir ("/") < 0)
|
||||
result = -1;
|
||||
}
|
||||
else
|
||||
if (__chdir ("..") < 0)
|
||||
result = -1;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
__attribute ((noinline))
|
||||
internal_function
|
||||
ftw_startup (const char *dir, int is_nftw, void *func, int descriptors,
|
||||
int flags)
|
||||
@ -683,7 +696,7 @@ ftw_startup (const char *dir, int is_nftw, void *func, int descriptors,
|
||||
result = add_object (&data, &st);
|
||||
|
||||
if (result == 0)
|
||||
result = ftw_dir (&data, &st);
|
||||
result = ftw_dir (&data, &st, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -693,6 +706,10 @@ ftw_startup (const char *dir, int is_nftw, void *func, int descriptors,
|
||||
&data.ftw);
|
||||
}
|
||||
}
|
||||
|
||||
if ((flags & FTW_ACTIONRETVAL)
|
||||
&& (result == FTW_SKIP_SUBTREE || result == FTW_SKIP_SIBLINGS))
|
||||
result = 0;
|
||||
}
|
||||
|
||||
/* Return to the start directory (if necessary). */
|
||||
@ -726,6 +743,7 @@ FTW_NAME (path, func, descriptors)
|
||||
return ftw_startup (path, 0, func, descriptors, 0);
|
||||
}
|
||||
|
||||
#ifndef _LIBC
|
||||
int
|
||||
NFTW_NAME (path, func, descriptors, flags)
|
||||
const char *path;
|
||||
@ -735,3 +753,43 @@ NFTW_NAME (path, func, descriptors, flags)
|
||||
{
|
||||
return ftw_startup (path, 1, func, descriptors, flags);
|
||||
}
|
||||
#else
|
||||
|
||||
#include <shlib-compat.h>
|
||||
|
||||
int
|
||||
NFTW_NEW_NAME (path, func, descriptors, flags)
|
||||
const char *path;
|
||||
NFTW_FUNC_T func;
|
||||
int descriptors;
|
||||
int flags;
|
||||
{
|
||||
if (flags
|
||||
& ~(FTW_PHYS | FTW_MOUNT | FTW_CHDIR | FTW_DEPTH | FTW_ACTIONRETVAL))
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
return ftw_startup (path, 1, func, descriptors, flags);
|
||||
}
|
||||
|
||||
versioned_symbol (libc, NFTW_NEW_NAME, NFTW_NAME, GLIBC_2_3_3);
|
||||
|
||||
#if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_3_3)
|
||||
|
||||
/* Older nftw* version just ignored all unknown flags. */
|
||||
|
||||
int
|
||||
NFTW_OLD_NAME (path, func, descriptors, flags)
|
||||
const char *path;
|
||||
NFTW_FUNC_T func;
|
||||
int descriptors;
|
||||
int flags;
|
||||
{
|
||||
flags &= (FTW_PHYS | FTW_MOUNT | FTW_CHDIR | FTW_DEPTH);
|
||||
return ftw_startup (path, 1, func, descriptors, flags);
|
||||
}
|
||||
|
||||
compat_symbol (libc, NFTW_OLD_NAME, NFTW_NAME, GLIBC_2_1);
|
||||
#endif
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user