From: Eric Blake Date: Thu, 24 Sep 2009 02:33:40 +0000 (-0600) Subject: fchdir: another mingw fix X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=657fb89d3276465fcf756392f10aa268ca451136;p=pspp fchdir: another mingw fix canonicalize_file_name does not understand drive letters or backslash. The only reason openat required it was to make fchdir get the canonical name of a directory. But we can do the same trick with chdir and getcwd. With this fix, fchdir(open("..",O_RDONLY)) finally does the right thing on mingw. * modules/fchdir (Depends-on): Drop canonicalize-lgpl. * lib/fchdir.c (get_name): New helper method; skips canonicalize on mingw (where it has not yet been ported), and make it optional elsewhere. (_gl_register_fd): Use it. Signed-off-by: Eric Blake --- diff --git a/ChangeLog b/ChangeLog index bed42c53ff..ee180ac44e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,12 @@ 2009-09-23 Eric Blake + fchdir: another mingw fix + * modules/fchdir (Depends-on): Drop canonicalize-lgpl. + * lib/fchdir.c (get_name): New helper method; skips canonicalize + on mingw (where it has not yet been ported), and make it optional + elsewhere. + (_gl_register_fd): Use it. + same-inode: make SAME_INODE tri-state, to port to mingw * NEWS: Mention this change. * lib/same-inode.h (same-inode.h): Recognize mingw limitation of diff --git a/lib/fchdir.c b/lib/fchdir.c index 677d4422e8..54bbc623db 100644 --- a/lib/fchdir.c +++ b/lib/fchdir.c @@ -33,6 +33,14 @@ # define REPLACE_OPEN_DIRECTORY 0 #endif +#ifndef HAVE_CANONICALIZE_FILE_NAME +# if GNULIB_CANONICALIZE || GNULIB_CANONICALIZE_LGPL +# define HAVE_CANONICALIZE_FILE_NAME 1 +# else +# define HAVE_CANONICALIZE_FILE_NAME 0 +# endif +#endif + /* This replacement assumes that a directory is not renamed while opened through a file descriptor. @@ -78,6 +86,38 @@ ensure_dirs_slot (size_t fd) return true; } +/* Return the canonical name of DIR in malloc'd storage. */ +static char * +get_name (char const *dir) +{ + char *result; + if (REPLACE_OPEN_DIRECTORY || !HAVE_CANONICALIZE_FILE_NAME) + { + /* The function canonicalize_file_name has not yet been ported + to mingw, with all its drive letter and backslash quirks. + Fortunately, getcwd is reliable in this case, but we ensure + we can get back to where we started before using it. Treat + "." as a special case, as it is frequently encountered. */ + char *cwd = getcwd (NULL, 0); + int saved_errno; + if (dir[0] == '.' && dir[1] == '\0') + return cwd; + if (chdir (cwd)) + return NULL; + result = chdir (dir) ? NULL : getcwd (NULL, 0); + saved_errno = errno; + chdir (cwd); + free (cwd); + errno = saved_errno; + } + else + { + /* Avoid changing the directory. */ + result = canonicalize_file_name (dir); + } + return result; +} + /* Hook into the gnulib replacements for open() and close() to keep track of the open file descriptors. */ @@ -108,7 +148,7 @@ _gl_register_fd (int fd, const char *filename) || (fstat (fd, &statbuf) == 0 && S_ISDIR (statbuf.st_mode))) { if (!ensure_dirs_slot (fd) - || (dirs[fd].name = canonicalize_file_name (filename)) == NULL) + || (dirs[fd].name = get_name (filename)) == NULL) { int saved_errno = errno; close (fd); diff --git a/modules/fchdir b/modules/fchdir index 69ac3c308a..5bae7d611c 100644 --- a/modules/fchdir +++ b/modules/fchdir @@ -6,7 +6,6 @@ lib/fchdir.c m4/fchdir.m4 Depends-on: -canonicalize-lgpl close dirent dirfd