On Linux, with a forced ac_cv_func_fchdir=no, the test failed because dup2 was not replaced, all because the shell variable ac_cv_func_dup2 had not been set yet.
Meanwhile, computing the canonical pathname of a directory on mingw was rather expensive -- multiple chdir()! -- but nothing cared whether the name was canonical, just that it was absolute. * modules/fchdir (Depends-on): Add dosname, filenamecat-lgpl, getcwd-lgpl. * lib/fchdir.c (get_name): Any absolute name will do; it does not have to be canonical. * m4/dup2.m4 (gl_REPLACE_DUP2): Ensure dup2 is replaced. Signed-off-by: Eric Blake <ebl...@redhat.com> --- ChangeLog | 7 +++++++ lib/fchdir.c | 45 +++++++++++++++++++-------------------------- m4/dup2.m4 | 1 + modules/fchdir | 3 +++ 4 files changed, 30 insertions(+), 26 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7383f23..9f05815 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,12 @@ 2011-04-26 Eric Blake <ebl...@redhat.com> + fchdir: avoid extra chdir and fix test + * modules/fchdir (Depends-on): Add dosname, filenamecat-lgpl, + getcwd-lgpl. + * lib/fchdir.c (get_name): Any absolute name will do; it does not + have to be canonical. + * m4/dup2.m4 (gl_REPLACE_DUP2): Ensure dup2 is replaced. + filenamecat-lgpl: fix licence * modules/filenamecat-lgpl (License): Mark as LGPLv2+, as intended when it was first created. diff --git a/lib/fchdir.c b/lib/fchdir.c index 94c4e71..2a70132 100644 --- a/lib/fchdir.c +++ b/lib/fchdir.c @@ -29,6 +29,9 @@ #include <sys/types.h> #include <sys/stat.h> +#include "dosname.h" +#include "filenamecat.h" + #ifndef REPLACE_OPEN_DIRECTORY # define REPLACE_OPEN_DIRECTORY 0 #endif @@ -90,36 +93,26 @@ ensure_dirs_slot (size_t fd) return true; } -/* Return the canonical name of DIR in malloc'd storage. */ +/* Return an absolute name of DIR in malloc'd storage. */ static char * get_name (char const *dir) { + char *cwd; 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; - if (chdir (cwd)) - abort (); - free (cwd); - errno = saved_errno; - } - else - { - /* Avoid changing the directory. */ - result = canonicalize_file_name (dir); - } + int saved_errno; + + if (IS_ABSOLUTE_FILE_NAME (dir)) + return strdup (dir); + + /* We often encounter "."; treat it as a special case. */ + cwd = getcwd (NULL, 0); + if (!cwd || (dir[0] == '.' && dir[1] == '\0')) + return cwd; + + result = mfile_name_concat (cwd, dir, NULL); + saved_errno = errno; + free (cwd); + errno = saved_errno; return result; } diff --git a/m4/dup2.m4 b/m4/dup2.m4 index b8794c2..62e31a8 100644 --- a/m4/dup2.m4 +++ b/m4/dup2.m4 @@ -69,6 +69,7 @@ AC_DEFUN([gl_FUNC_DUP2], AC_DEFUN([gl_REPLACE_DUP2], [ AC_REQUIRE([gl_UNISTD_H_DEFAULTS]) + AC_CHECK_FUNCS_ONCE([dup2]) if test $ac_cv_func_dup2 = yes; then REPLACE_DUP2=1 fi diff --git a/modules/fchdir b/modules/fchdir index 46b481f..0a3ab99 100644 --- a/modules/fchdir +++ b/modules/fchdir @@ -9,9 +9,12 @@ Depends-on: close dirent dirfd +dosname dup2 fcntl fcntl-h +filenamecat-lgpl +getcwd-lgpl include_next malloc-posix open -- 1.7.4.4