X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=lib%2Ffchdir.c;fp=lib%2Ffchdir.c;h=969e984c9555b11a95f3e411f15a0ff6bdc581bd;hb=cf7169a2ede9bb08b71de68fe0c8bbecf827abe6;hp=246987c8860289e1c908f5c42eba00de64c71d7a;hpb=138fc7e67e3d9845cd7d81aad0e9c7724784f9b9;p=tar diff --git a/lib/fchdir.c b/lib/fchdir.c index 246987c..969e984 100644 --- a/lib/fchdir.c +++ b/lib/fchdir.c @@ -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 +#include #include #include #include @@ -26,10 +27,8 @@ #include #include #include -#include #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; }