/* 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
/* 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. */
}
}
-/* 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
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;
}
{
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;
}