/* File tree walker functions.
- Copyright (C) 1996-2003, 2004, 2006 Free Software Foundation, Inc.
+ Copyright (C) 1996-2014 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
#ifdef HAVE_CONFIG_H
# include <config.h>
}
-static inline int
+static int
add_object (struct ftw_data *data, struct STAT *st)
{
struct known_object *newp = malloc (sizeof (struct known_object));
int save_err = errno;
free (buf);
__set_errno (save_err);
- result = -1;
- break;
+ return -1;
}
buf = newp;
}
}
else
{
- const char *name = ((data->flags & FTW_CHDIR)
- ? data->dirbuf + data->ftw.base: data->dirbuf);
+ const char *name;
+
+ if (data->flags & FTW_CHDIR)
+ {
+ name = data->dirbuf + data->ftw.base;
+ if (name[0] == '\0')
+ name = ".";
+ }
+ else
+ name = data->dirbuf;
+
dirp->stream = __opendir (name);
}
{
if (errno != EACCES && errno != ENOENT)
result = -1;
- else if (!(data->flags & FTW_PHYS)
- && (d_type == DT_LNK
- || (LXSTAT (_STAT_VER, name, &st) == 0
- && S_ISLNK (st.st_mode))))
+ else if (data->flags & FTW_PHYS)
+ flag = FTW_NS;
+ else if (d_type == DT_LNK)
flag = FTW_SLN;
else
- flag = FTW_NS;
+ {
+ if (dir->streamfd != -1)
+ statres = FXSTATAT (_STAT_VER, dir->streamfd, name, &st,
+ AT_SYMLINK_NOFOLLOW);
+ else
+ statres = LXSTAT (_STAT_VER, name, &st);
+ if (statres == 0 && S_ISLNK (st.st_mode))
+ flag = FTW_SLN;
+ else
+ flag = FTW_NS;
+ }
}
else
{
/* Next, update the `struct FTW' information. */
++data->ftw.level;
- startp = strchr (data->dirbuf, '\0');
+ startp = __rawmemchr (data->dirbuf, '\0');
/* There always must be a directory name. */
assert (startp != data->dirbuf);
if (startp[-1] != '/')
while (dir.stream != NULL && (d = __readdir64 (dir.stream)) != NULL)
{
- result = process_entry (data, &dir, d->d_name, NAMLEN (d), d->d_type);
+ int d_type = DT_UNKNOWN;
+#ifdef _DIRENT_HAVE_D_TYPE
+ d_type = d->d_type;
+#endif
+ result = process_entry (data, &dir, d->d_name, NAMLEN (d), d_type);
if (result != 0)
break;
}
/* Get stat info for start directory. */
if (result == 0)
{
- const char *name = ((data.flags & FTW_CHDIR)
- ? data.dirbuf + data.ftw.base
- : data.dirbuf);
+ const char *name;
+
+ if (data.flags & FTW_CHDIR)
+ {
+ name = data.dirbuf + data.ftw.base;
+ if (name[0] == '\0')
+ name = ".";
+ }
+ else
+ name = data.dirbuf;
if (((flags & FTW_PHYS)
? LXSTAT (_STAT_VER, name, &st)
{
int save_err = errno;
__fchdir (cwdfd);
+ close_not_cancel_no_status (cwdfd);
__set_errno (save_err);
}
else if (cwd != NULL)