X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;ds=sidebyside;f=lib%2Ffchdir.c;fp=lib%2Ffchdir.c;h=0000000000000000000000000000000000000000;hb=22f1eb8bc17e5be72dd23d42d6aaa60196ac22e6;hp=969e984c9555b11a95f3e411f15a0ff6bdc581bd;hpb=00fa13ff3f2d5b6e2a94c5e948c38616ff7ad37a;p=tar
diff --git a/lib/fchdir.c b/lib/fchdir.c
deleted file mode 100644
index 969e984..0000000
--- a/lib/fchdir.c
+++ /dev/null
@@ -1,238 +0,0 @@
-/* fchdir replacement.
- Copyright (C) 2006-2008 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
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see . */
-
-#include
-
-/* Specification. */
-#include
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include "canonicalize.h"
-
-/* This replacement assumes that a directory is not renamed while opened
- through a file descriptor. */
-
-/* Array of file descriptors opened. If it points to a directory, it stores
- info about this directory; otherwise it stores an errno value of ENOTDIR. */
-typedef struct
-{
- char *name; /* Absolute name of the directory, or NULL. */
- int saved_errno; /* If name == NULL: The error code describing the failure
- reason. */
-} dir_info_t;
-static dir_info_t *dirs;
-static size_t dirs_allocated;
-
-/* Try to ensure dirs has enough room for a slot at index fd. */
-static void
-ensure_dirs_slot (size_t fd)
-{
- if (fd >= dirs_allocated)
- {
- size_t new_allocated;
- dir_info_t *new_dirs;
- size_t i;
-
- new_allocated = 2 * dirs_allocated + 1;
- if (new_allocated <= fd)
- new_allocated = fd + 1;
- new_dirs =
- (dirs != NULL
- ? (dir_info_t *) realloc (dirs, new_allocated * sizeof (dir_info_t))
- : (dir_info_t *) malloc (new_allocated * sizeof (dir_info_t)));
- if (new_dirs != NULL)
- {
- for (i = dirs_allocated; i < new_allocated; i++)
- {
- new_dirs[i].name = NULL;
- new_dirs[i].saved_errno = ENOTDIR;
- }
- dirs = new_dirs;
- dirs_allocated = new_allocated;
- }
- }
-}
-
-/* Hook into the gnulib replacements for open() and close() to keep track
- of the open file descriptors. */
-
-void
-_gl_unregister_fd (int fd)
-{
- if (fd >= 0 && fd < dirs_allocated)
- {
- if (dirs[fd].name != NULL)
- free (dirs[fd].name);
- dirs[fd].name = NULL;
- dirs[fd].saved_errno = ENOTDIR;
- }
-}
-
-void
-_gl_register_fd (int fd, const char *filename)
-{
- struct stat statbuf;
-
- ensure_dirs_slot (fd);
- if (fd < dirs_allocated
- && fstat (fd, &statbuf) >= 0 && S_ISDIR (statbuf.st_mode))
- {
- dirs[fd].name = canonicalize_file_name (filename);
- if (dirs[fd].name == NULL)
- dirs[fd].saved_errno = errno;
- }
-}
-
-/* Override opendir() and closedir(), to keep track of the open file
- descriptors. Needed because there is a function dirfd(). */
-
-int
-rpl_closedir (DIR *dp)
-#undef closedir
-{
- int fd = dirfd (dp);
- int retval = closedir (dp);
-
- if (retval >= 0)
- _gl_unregister_fd (fd);
- return retval;
-}
-
-DIR *
-rpl_opendir (const char *filename)
-#undef opendir
-{
- DIR *dp;
-
- dp = opendir (filename);
- if (dp != NULL)
- {
- int fd = dirfd (dp);
- if (fd >= 0)
- _gl_register_fd (fd, filename);
- }
- return dp;
-}
-
-/* Override dup() and dup2(), to keep track of open file descriptors. */
-
-int
-rpl_dup (int oldfd)
-#undef dup
-{
- int newfd = dup (oldfd);
-
- if (oldfd >= 0 && newfd >= 0)
- {
- ensure_dirs_slot (newfd);
- if (newfd < dirs_allocated)
- {
- if (oldfd < dirs_allocated)
- {
- if (dirs[oldfd].name != NULL)
- {
- dirs[newfd].name = strdup (dirs[oldfd].name);
- if (dirs[newfd].name == NULL)
- dirs[newfd].saved_errno = ENOMEM;
- }
- else
- {
- dirs[newfd].name = NULL;
- dirs[newfd].saved_errno = dirs[oldfd].saved_errno;
- }
- }
- else
- {
- dirs[newfd].name = NULL;
- dirs[newfd].saved_errno = ENOMEM;
- }
- }
- }
- return newfd;
-}
-
-int
-rpl_dup2 (int oldfd, int newfd)
-#undef dup2
-{
- int retval = dup2 (oldfd, newfd);
-
- if (retval >= 0 && oldfd >= 0 && newfd >= 0 && newfd != oldfd)
- {
- ensure_dirs_slot (newfd);
- if (newfd < dirs_allocated)
- {
- if (oldfd < dirs_allocated)
- {
- if (dirs[oldfd].name != NULL)
- {
- dirs[newfd].name = strdup (dirs[oldfd].name);
- if (dirs[newfd].name == NULL)
- dirs[newfd].saved_errno = ENOMEM;
- }
- else
- {
- dirs[newfd].name = NULL;
- dirs[newfd].saved_errno = dirs[oldfd].saved_errno;
- }
- }
- else
- {
- dirs[newfd].name = NULL;
- dirs[newfd].saved_errno = ENOMEM;
- }
- }
- }
- return retval;
-}
-
-/* Implement fchdir() in terms of chdir(). */
-
-int
-fchdir (int fd)
-{
- if (fd >= 0)
- {
- if (fd < dirs_allocated)
- {
- if (dirs[fd].name != NULL)
- return chdir (dirs[fd].name);
- else
- {
- errno = dirs[fd].saved_errno;
- return -1;
- }
- }
- else
- {
- errno = ENOMEM;
- return -1;
- }
- }
- else
- {
- errno = EBADF;
- return -1;
- }
-}