* io/ftw.c (ftw_startup): Use fchdir to return to original

directory for FTW_CHDIR.
This commit is contained in:
Ulrich Drepper 2006-02-05 21:19:53 +00:00
parent df6871cb7e
commit becac6c5b1
2 changed files with 35 additions and 21 deletions

View File

@ -1,3 +1,8 @@
2006-02-05 Ulrich Drepper <drepper@redhat.com>
* io/ftw.c (ftw_startup): Use fchdir to return to original
directory for FTW_CHDIR.
2006-02-03 Ulrich Drepper <drepper@redhat.com> 2006-02-03 Ulrich Drepper <drepper@redhat.com>
* manual/stdio.texi (Formatted Output Functions): Fix make_message * manual/stdio.texi (Formatted Output Functions): Fix make_message

View File

@ -1,5 +1,5 @@
/* File tree walker functions. /* File tree walker functions.
Copyright (C) 1996-2003, 2004 Free Software Foundation, Inc. Copyright (C) 1996-2003, 2004, 2006 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
@ -36,7 +36,7 @@ char *alloca ();
# endif # endif
#endif #endif
#if defined _LIBC #ifdef _LIBC
# include <dirent.h> # include <dirent.h>
# define NAMLEN(dirent) _D_EXACT_NAMLEN (dirent) # define NAMLEN(dirent) _D_EXACT_NAMLEN (dirent)
#else #else
@ -59,6 +59,7 @@ char *alloca ();
#endif #endif
#include <errno.h> #include <errno.h>
#include <fcntl.h>
#include <ftw.h> #include <ftw.h>
#include <limits.h> #include <limits.h>
#include <search.h> #include <search.h>
@ -585,7 +586,7 @@ ftw_startup (const char *dir, int is_nftw, void *func, int descriptors,
struct STAT st; struct STAT st;
int result = 0; int result = 0;
int save_err; int save_err;
char *cwd = NULL; int cwdfd = -1;
char *cp; char *cp;
/* First make sure the parameters are reasonable. */ /* First make sure the parameters are reasonable. */
@ -639,24 +640,33 @@ ftw_startup (const char *dir, int is_nftw, void *func, int descriptors,
/* Now go to the directory containing the initial file/directory. */ /* Now go to the directory containing the initial file/directory. */
if (flags & FTW_CHDIR) if (flags & FTW_CHDIR)
{ {
/* GNU extension ahead. */ /* We have to be able to go back to the current working
cwd = __getcwd (NULL, 0); directory. The best way to do this is to use a file
if (cwd == NULL) descriptor. */
cwdfd = __open (".", O_RDONLY | O_DIRECTORY);
if (cwdfd == -1)
result = -1; result = -1;
else if (data.ftw.base > 0) else
{ {
/* Change to the directory the file is in. In data.dirbuf if (data.maxdir > 1)
we have a writable copy of the file name. Just NUL /* Account for the file descriptor we use here. */
terminate it for now and change the directory. */ --data.maxdir;
if (data.ftw.base == 1)
/* I.e., the file is in the root directory. */ if (data.ftw.base > 0)
result = __chdir ("/");
else
{ {
char ch = data.dirbuf[data.ftw.base - 1]; /* Change to the directory the file is in. In data.dirbuf
data.dirbuf[data.ftw.base - 1] = '\0'; we have a writable copy of the file name. Just NUL
result = __chdir (data.dirbuf); terminate it for now and change the directory. */
data.dirbuf[data.ftw.base - 1] = ch; if (data.ftw.base == 1)
/* I.e., the file is in the root directory. */
result = __chdir ("/");
else
{
char ch = data.dirbuf[data.ftw.base - 1];
data.dirbuf[data.ftw.base - 1] = '\0';
result = __chdir (data.dirbuf);
data.dirbuf[data.ftw.base - 1] = ch;
}
} }
} }
} }
@ -713,11 +723,10 @@ ftw_startup (const char *dir, int is_nftw, void *func, int descriptors,
} }
/* Return to the start directory (if necessary). */ /* Return to the start directory (if necessary). */
if (cwd != NULL) if (cwdfd != -1)
{ {
int save_err = errno; int save_err = errno;
__chdir (cwd); __fchdir (cwdfd);
free (cwd);
__set_errno (save_err); __set_errno (save_err);
} }