Mercurial > hg > octave-lyh > gnulib-hg
changeset 12066:5e590c10bc80
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 <ebb9@byu.net>
author | Eric Blake <ebb9@byu.net> |
---|---|
date | Wed, 23 Sep 2009 20:33:40 -0600 |
parents | fbde8fb7f644 |
children | c1ef4ce880fc |
files | ChangeLog lib/fchdir.c modules/fchdir |
diffstat | 3 files changed, 48 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,12 @@ 2009-09-23 Eric Blake <ebb9@byu.net> + 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
--- 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 @@ 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 @@ || (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);