]> git.cworth.org Git - tar/blobdiff - lib/fchdir.c
Imported Upstream version 1.21
[tar] / lib / fchdir.c
index 246987c8860289e1c908f5c42eba00de64c71d7a..969e984c9555b11a95f3e411f15a0ff6bdc581bd 100644 (file)
@@ -1,5 +1,5 @@
 /* fchdir replacement.
-   Copyright (C) 2006, 2007 Free Software Foundation, Inc.
+   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
@@ -19,6 +19,7 @@
 /* Specification.  */
 #include <unistd.h>
 
+#include <dirent.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <stdarg.h>
 #include <string.h>
 #include <sys/types.h>
 #include <sys/stat.h>
-#include <dirent.h>
 
 #include "canonicalize.h"
-#include "dirfd.h"
 
 /* This replacement assumes that a directory is not renamed while opened
    through a file descriptor.  */
@@ -75,64 +74,34 @@ ensure_dirs_slot (size_t fd)
     }
 }
 
-/* Override open() and close(), to keep track of the open file descriptors.  */
+/* Hook into the gnulib replacements for open() and close() to keep track
+   of the open file descriptors.  */
 
-int
-rpl_close (int fd)
-#undef close
+void
+_gl_unregister_fd (int fd)
 {
-  int retval = close (fd);
-
-  if (retval >= 0 && fd >= 0 && fd < dirs_allocated)
+  if (fd >= 0 && fd < dirs_allocated)
     {
       if (dirs[fd].name != NULL)
        free (dirs[fd].name);
       dirs[fd].name = NULL;
       dirs[fd].saved_errno = ENOTDIR;
     }
-  return retval;
 }
 
-int
-rpl_open (const char *filename, int flags, ...)
-#undef open
+void
+_gl_register_fd (int fd, const char *filename)
 {
-  mode_t mode;
-  int fd;
   struct stat statbuf;
 
-  mode = 0;
-  if (flags & O_CREAT)
+  ensure_dirs_slot (fd);
+  if (fd < dirs_allocated
+      && fstat (fd, &statbuf) >= 0 && S_ISDIR (statbuf.st_mode))
     {
-      va_list arg;
-      va_start (arg, flags);
-
-      /* If mode_t is narrower than int, use the promoted type (int),
-        not mode_t.  Use sizeof to guess whether mode_t is narrower;
-        we don't know of any practical counterexamples.  */
-      mode = (sizeof (mode_t) < sizeof (int)
-             ? va_arg (arg, int)
-             : va_arg (arg, mode_t));
-
-      va_end (arg);
+      dirs[fd].name = canonicalize_file_name (filename);
+      if (dirs[fd].name == NULL)
+       dirs[fd].saved_errno = errno;
     }
-#if defined GNULIB_OPEN && ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__)
-  if (strcmp (filename, "/dev/null") == 0)
-    filename = "NUL";
-#endif
-  fd = open (filename, flags, mode);
-  if (fd >= 0)
-    {
-      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;
-       }
-    }
-  return fd;
 }
 
 /* Override opendir() and closedir(), to keep track of the open file
@@ -145,13 +114,8 @@ rpl_closedir (DIR *dp)
   int fd = dirfd (dp);
   int retval = closedir (dp);
 
-  if (retval >= 0 && fd >= 0 && fd < dirs_allocated)
-    {
-      if (dirs[fd].name != NULL)
-       free (dirs[fd].name);
-      dirs[fd].name = NULL;
-      dirs[fd].saved_errno = ENOTDIR;
-    }
+  if (retval >= 0)
+    _gl_unregister_fd (fd);
   return retval;
 }
 
@@ -166,15 +130,7 @@ rpl_opendir (const char *filename)
     {
       int fd = dirfd (dp);
       if (fd >= 0)
-       {
-         ensure_dirs_slot (fd);
-         if (fd < dirs_allocated)
-           {
-             dirs[fd].name = canonicalize_file_name (filename);
-             if (dirs[fd].name == NULL)
-               dirs[fd].saved_errno = errno;
-           }
-       }
+       _gl_register_fd (fd, filename);
     }
   return dp;
 }