summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Gruenbacher <agruen@gnu.org>2015-02-21 03:39:17 +0100
committerAndreas Gruenbacher <agruen@gnu.org>2015-02-28 21:10:34 +0100
commite1f0aa0a9d3249fbf9578423a05db59b8ba8fd45 (patch)
treec75d5ddbf6a3764e626363417836ed8c40bacf5f
parentc5da382c0baa822606236fe65527c027c1250822 (diff)
downloadpatch-e1f0aa0a9d3249fbf9578423a05db59b8ba8fd45.tar.gz
Refactor traverse_another_path() and helpers
Prepare for keeping track of the directory hierarchy: * src/safe.c (traverse_another_path): Pass struct cached_dirfd to traverse_next(). (traverse_next, openat_cached): Pass through struct cached_dirfd.
-rw-r--r--src/safe.c42
1 files changed, 23 insertions, 19 deletions
diff --git a/src/safe.c b/src/safe.c
index 00e5903..9448614 100644
--- a/src/safe.c
+++ b/src/safe.c
@@ -190,35 +190,35 @@ static void invalidate_cached_dirfd (int dirfd, const char *name)
remove_cached_dirfd (entry);
}
-static int openat_cached (int dirfd, const char *name, int keepfd)
+static struct cached_dirfd *openat_cached (struct cached_dirfd *dir, const char *name, int keepfd)
{
int fd;
- struct cached_dirfd *entry = lookup_cached_dirfd (dirfd, name);
+ struct cached_dirfd *entry = lookup_cached_dirfd (dir->fd, name);
if (entry)
- return entry->fd;
+ return entry;
dirfd_cache_misses++;
/* Actually get the new directory file descriptor. Don't follow
symbolic links. */
- fd = openat (dirfd, name, O_DIRECTORY | O_NOFOLLOW);
+ fd = openat (dir->fd, name, O_DIRECTORY | O_NOFOLLOW);
/* Don't cache errors. */
if (fd < 0)
- return fd;
+ return NULL;
/* Store new cache entry */
entry = xmalloc (sizeof (struct cached_dirfd));
- entry->dirfd = dirfd;
+ entry->dirfd = dir->fd;
entry->name = xstrdup (name);
entry->fd = fd;
insert_cached_dirfd (entry, keepfd);
- return fd;
+ return entry;
}
/* Resolve the next path component in PATH inside DIRFD. */
-static int traverse_next (int dirfd, const char **path, int keepfd)
+static struct cached_dirfd *traverse_next (struct cached_dirfd *dir, const char **path, int keepfd)
{
const char *p = *path;
char *name;
@@ -231,17 +231,17 @@ static int traverse_next (int dirfd, const char **path, int keepfd)
memcpy(name, *path, p - *path);
name[p - *path] = 0;
- dirfd = openat_cached (dirfd, name, keepfd);
- if (dirfd < 0 && dirfd != AT_FDCWD)
+ dir = openat_cached (dir, name, keepfd);
+ if (! dir)
{
*path = p;
- return -1;
+ return NULL;
}
skip:
while (ISSLASH (*p))
p++;
*path = p;
- return dirfd;
+ return dir;
}
/* Traverse PATHNAME. Updates PATHNAME to point to the last path component and
@@ -251,12 +251,16 @@ skip:
beyond MAX_CACHED_FDS entries. */
static int traverse_another_path (const char **pathname, int keepfd)
{
+ static struct cached_dirfd cwd = {
+ .fd = AT_FDCWD,
+ };
+
unsigned long misses = dirfd_cache_misses;
const char *path = *pathname, *last;
- int dirfd = AT_FDCWD;
+ struct cached_dirfd *dir = &cwd;
if (! *path || IS_ABSOLUTE_FILE_NAME (path))
- return dirfd;
+ return dir->fd;
/* Find the last pathname component */
last = strrchr (path, 0) - 1;
@@ -269,15 +273,15 @@ static int traverse_another_path (const char **pathname, int keepfd)
while (last != path && ! ISSLASH (*(last - 1)))
last--;
if (last == path)
- return dirfd;
+ return dir->fd;
if (debug & 32)
printf ("Resolving path \"%.*s\"", (int) (last - path), path);
while (path != last)
{
- dirfd = traverse_next (dirfd, &path, keepfd);
- if (dirfd < 0 && dirfd != AT_FDCWD)
+ dir = traverse_next (dir, &path, keepfd);
+ if (! dir)
{
if (debug & 32)
{
@@ -293,7 +297,7 @@ static int traverse_another_path (const char **pathname, int keepfd)
(int) (path - *pathname), *pathname);
skip_rest_of_patch = true;
}
- return dirfd;
+ return -1;
}
}
*pathname = last;
@@ -306,7 +310,7 @@ static int traverse_another_path (const char **pathname, int keepfd)
printf (" (%lu miss%s)\n", misses, misses == 1 ? "" : "es");
fflush (stdout);
}
- return dirfd;
+ return dir->fd;
}
/* Just traverse PATHNAME; see traverse_another_path(). */