mkdir("dir/./",mode) mistakenly succeeded.
* lib/mkdir.c (rpl_mkdir) [FUNC_MKDIR_DOT_BUG]: Work around bug.
* m4/mkdir-slash.m4 (gl_FUNC_MKDIR_TRAILING_SLASH): Move...
* m4/mkdir.m4 (gl_FUNC_MKDIR): ...here, and add check for cygwin
bug.
(gl_PREREQ_MKDIR): Delete unused macro.
* modules/mkdir (Files): Track file rename.
(configure.ac): Update macro name.
* modules/openat (Depends-on): Add mkdir.
* doc/posix-functions/mkdir.texi (mkdir): Document the bug.
Signed-off-by: Eric Blake <ebb9@byu.net>
2009-10-07 Eric Blake <ebb9@byu.net>
+ mkdir, mkdirat: fix cygwin 1.5.x bug
+ * lib/mkdir.c (rpl_mkdir) [FUNC_MKDIR_DOT_BUG]: Work around bug.
+ * m4/mkdir-slash.m4 (gl_FUNC_MKDIR_TRAILING_SLASH): Move...
+ * m4/mkdir.m4 (gl_FUNC_MKDIR): ...here, and add check for cygwin
+ bug.
+ (gl_PREREQ_MKDIR): Delete unused macro.
+ * modules/mkdir (Files): Track file rename.
+ (configure.ac): Update macro name.
+ * modules/openat (Depends-on): Add mkdir.
+ * doc/posix-functions/mkdir.texi (mkdir): Document the bug.
+
mkdir, mkdirat: add tests
* modules/mkdir-tests: New test.
* tests/test-mkdir.h: New file.
@item
When the argument ends in a slash, the function call fails on some platforms.
@item
+This function mistakenly succeeds on @samp{mkdir("d/./",mode)} on
+some platforms:
+Cygwin 1.5.x, mingw.
+@item
On Windows platforms (excluding Cygwin), this function is called @code{_mkdir}
and takes only one argument. The fix (without Gnulib) is to define a macro
like this:
/* On some systems, mkdir ("foo/", 0700) fails because of the trailing
slash. On those systems, this wrapper removes the trailing slash.
- Copyright (C) 2001, 2003, 2006, 2008 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2003, 2006, 2008, 2009 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
#include <config.h>
/* Specification. */
-#include <sys/types.h>
#include <sys/stat.h>
+#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
{
tmp_dir = (char *) dir;
}
+#if FUNC_MKDIR_DOT_BUG
+ /* Additionally, cygwin 1.5 mistakenly creates a directory "d/./". */
+ {
+ char *last = last_component (tmp_dir);
+ if (*last == '.' && (last[1] == '\0'
+ || (last[1] == '.' && last[2] == '\0')))
+ {
+ struct stat st;
+ if (stat (tmp_dir, &st) == 0)
+ errno = EEXIST;
+ return -1;
+ }
+ }
+#endif /* FUNC_MKDIR_DOT_BUG */
ret_val = mkdir (tmp_dir, mode);
+++ /dev/null
-# serial 8
-
-# Copyright (C) 2001, 2003-2004, 2006, 2008-2009 Free Software Foundation, Inc.
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# On some systems, mkdir ("foo/", 0700) fails because of the trailing slash.
-# On such systems, arrange to use a wrapper function that removes any
-# trailing slashes.
-AC_DEFUN([gl_FUNC_MKDIR_TRAILING_SLASH],
-[dnl
- AC_REQUIRE([gl_SYS_STAT_H_DEFAULTS])
- AC_CHECK_HEADERS_ONCE([unistd.h])
- AC_CACHE_CHECK([whether mkdir fails due to a trailing slash],
- gl_cv_func_mkdir_trailing_slash_bug,
- [
- # Arrange for deletion of the temporary directory this test might create.
- ac_clean_files="$ac_clean_files confdir-slash"
- AC_RUN_IFELSE([AC_LANG_SOURCE([[
-# include <sys/types.h>
-# include <sys/stat.h>
-# include <stdlib.h>
-# ifdef HAVE_UNISTD_H
-# include <unistd.h>
-# endif
- int main ()
- {
- rmdir ("confdir-slash");
- exit (mkdir ("confdir-slash/", 0700));
- }
- ]])],
- [gl_cv_func_mkdir_trailing_slash_bug=no],
- [gl_cv_func_mkdir_trailing_slash_bug=yes],
- [gl_cv_func_mkdir_trailing_slash_bug=yes]
- )
- ]
- )
-
- if test $gl_cv_func_mkdir_trailing_slash_bug = yes; then
- REPLACE_MKDIR=1
- AC_LIBOBJ([mkdir])
- gl_PREREQ_MKDIR
- fi
-])
-
-# Prerequisites of lib/mkdir.c.
-AC_DEFUN([gl_PREREQ_MKDIR], [:])
--- /dev/null
+# serial 9
+
+# Copyright (C) 2001, 2003-2004, 2006, 2008-2009 Free Software Foundation, Inc.
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# On some systems, mkdir ("foo/", 0700) fails because of the trailing slash.
+# On others, mkdir ("foo/./", 0700) mistakenly succeeds.
+# On such systems, arrange to use a wrapper function.
+AC_DEFUN([gl_FUNC_MKDIR],
+[dnl
+ AC_REQUIRE([gl_SYS_STAT_H_DEFAULTS])
+ AC_CHECK_HEADERS_ONCE([unistd.h])
+ AC_CACHE_CHECK([whether mkdir handles trailing slash],
+ [gl_cv_func_mkdir_trailing_slash_works],
+ [rm -rf conftest.dir
+ AC_RUN_IFELSE([AC_LANG_PROGRAM([[
+# include <sys/types.h>
+# include <sys/stat.h>
+]], [return mkdir ("conftest.dir/", 0700);])],
+ [gl_cv_func_mkdir_trailing_slash_works=yes],
+ [gl_cv_func_mkdir_trailing_slash_works=no],
+ [gl_cv_func_mkdir_trailing_slash_works="guessing no"])
+ rm -rf conftest.dir
+ ]
+ )
+ if test "$gl_cv_func_mkdir_trailing_slash_works" != yes; then
+ REPLACE_MKDIR=1
+ AC_LIBOBJ([mkdir])
+ fi
+
+ AC_CACHE_CHECK([whether mkdir handles trailing dot],
+ [gl_cv_func_mkdir_trailing_dot_works],
+ [rm -rf conftest.dir
+ AC_RUN_IFELSE([AC_LANG_PROGRAM([[
+# include <sys/types.h>
+# include <sys/stat.h>
+]], [return !mkdir ("conftest.dir/./", 0700);])],
+ [gl_cv_func_mkdir_trailing_dot_works=yes],
+ [gl_cv_func_mkdir_trailing_dot_works=no],
+ [gl_cv_func_mkdir_trailing_dot_works="guessing no"])
+ rm -rf conftest.dir
+ ]
+ )
+ if test "$gl_cv_func_mkdir_trailing_dot_works" != yes; then
+ REPLACE_MKDIR=1
+ AC_LIBOBJ([mkdir])
+ AC_DEFINE([FUNC_MKDIR_DOT_BUG], [1], [Define to 1 if mkdir mistakenly
+ creates a directory given with a trailing dot component.])
+ fi
+])
Files:
lib/mkdir.c
-m4/mkdir-slash.m4
+m4/mkdir.m4
Depends-on:
sys_stat
dirname
configure.ac:
-gl_FUNC_MKDIR_TRAILING_SLASH
+gl_FUNC_MKDIR
Makefile.am:
intprops
lchown
lstat
+mkdir
open
openat-die
rmdir