/* Traverse a file hierarchy.
- Copyright (C) 2004-2011 Free Software Foundation, Inc.
+ Copyright (C) 2004-2012 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
#define ISSET(opt) (sp->fts_options & (opt))
#define SET(opt) (sp->fts_options |= (opt))
-/* FIXME: make this a function */
-#define RESTORE_INITIAL_CWD(sp) \
- (fd_ring_clear (&((sp)->fts_fd_ring)), \
- FCHDIR ((sp), (ISSET (FTS_CWDFD) ? AT_FDCWD : (sp)->fts_rfd)))
-
/* FIXME: FTS_NOCHDIR is now misnamed.
Call it FTS_USE_FULL_RELATIVE_FILE_NAMES instead. */
#define FCHDIR(sp, fd) \
sp->fts_cwd_fd = fd;
}
+/* Restore the initial, pre-traversal, "working directory".
+ In FTS_CWDFD mode, we merely call cwd_advance_fd, otherwise,
+ we may actually change the working directory.
+ Return 0 upon success. Upon failure, set errno and return nonzero. */
+static int
+restore_initial_cwd (FTS *sp)
+{
+ int fail = FCHDIR (sp, ISSET (FTS_CWDFD) ? AT_FDCWD : sp->fts_rfd);
+ fd_ring_clear (&(sp->fts_fd_ring));
+ return fail;
+}
+
/* Open the directory DIR if possible, and return a file
descriptor. Return -1 and set errno on failure. It doesn't matter
whether the file descriptor has read or write access. */
O_SEARCH | (ISSET (FTS_NOATIME) ? O_NOATIME : 0));
if (fd < 0)
{
- /* Even if `.' is unreadable, don't revert to FTS_NOCHDIR mode
+ /* Even if "." is unreadable, don't revert to FTS_NOCHDIR mode
on systems like Linux+PROC_FS, where our openat emulation
is good enough. Note: on a system that emulates
openat via /proc, this technique can still fail, but
switch (fs_buf.f_type)
{
- /* List here the file system types that lack useable dirent.d_type
+ /* List here the file system types that lack usable dirent.d_type
info, yet for which the optimization does apply. */
case S_MAGIC_REISERFS:
return true;
* root.
*/
if (p->fts_level == FTS_ROOTLEVEL) {
- if (RESTORE_INITIAL_CWD(sp)) {
+ if (restore_initial_cwd(sp)) {
SET(FTS_STOP);
return (NULL);
}
* one level, via "..".
*/
if (p->fts_level == FTS_ROOTLEVEL) {
- if (RESTORE_INITIAL_CWD(sp)) {
+ if (restore_initial_cwd(sp)) {
p->fts_errno = errno;
SET(FTS_STOP);
}
level = cur->fts_level + 1;
- /* Read the directory, attaching each entry to the `link' pointer. */
+ /* Read the directory, attaching each entry to the "link" pointer. */
doadjust = false;
head = NULL;
tail = NULL;
*/
if (!continue_readdir && descend && (type == BCHILD || !nitems) &&
(cur->fts_level == FTS_ROOTLEVEL
- ? RESTORE_INITIAL_CWD(sp)
+ ? restore_initial_cwd(sp)
: fts_safe_changedir(sp, cur->fts_parent, -1, ".."))) {
cur->fts_info = FTS_ERR;
SET(FTS_STOP);
}
static size_t
-internal_function
+internal_function _GL_ATTRIBUTE_PURE
fts_maxarglen (char * const *argv)
{
size_t len, max;
* tricked by someone changing the world out from underneath us.
* Assumes p->fts_statp->st_dev and p->fts_statp->st_ino are filled in.
* If FD is non-negative, expect it to be used after this function returns,
- * and to be closed eventually. So don't pass e.g., `dirfd(dirp)' and then
+ * and to be closed eventually. So don't pass e.g., 'dirfd(dirp)' and then
* do closedir(dirp), because that would invalidate the saved FD.
* Upon failure, close FD immediately and return nonzero.
*/
return -1;
/* The following dev/inode check is necessary if we're doing a
- `logical' traversal (through symlinks, a la chown -L), if the
+ "logical" traversal (through symlinks, a la chown -L), if the
system lacks O_NOFOLLOW support, or if we're changing to ".."
(but not via a popped file descriptor). When changing to the
name "..", O_NOFOLLOW can't help. In general, when the target is