X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Fmkdir.c;h=481bbf375ec27df28586f0f7b35d17ffc86ffcc9;hb=1276a2c5f24c0c932426aca9c899fa524d2443f2;hp=8073dc8da402da6e21d7bc59a1e732fefdd782ac;hpb=bfca3459b4916724328bc9779cbc4e5934417c09;p=gnulib.git diff --git a/lib/mkdir.c b/lib/mkdir.c index 8073dc8da..481bbf375 100644 --- a/lib/mkdir.c +++ b/lib/mkdir.c @@ -1,7 +1,7 @@ /* 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-2014 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 @@ -21,15 +21,14 @@ #include /* Specification. */ -#include #include +#include #include #include #include #include "dirname.h" -#include "xalloc.h" /* Disable the definition of mkdir to rpl_mkdir (from the substitute) in this file. Otherwise, we'd get an endless recursion. */ @@ -37,15 +36,19 @@ /* mingw's _mkdir() function has 1 argument, but we pass 2 arguments. Additionally, it declares _mkdir (and depending on compile flags, an - alias mkdir), only in the nonstandard io.h. */ + alias mkdir), only in the nonstandard includes and , + which are included in the override. */ #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ # define mkdir(name,mode) _mkdir (name) +# define maybe_unused _GL_UNUSED +#else +# define maybe_unused /* empty */ #endif /* This function is required at least for NetBSD 1.5.2. */ int -rpl_mkdir (char const *dir, mode_t mode) +rpl_mkdir (char const *dir, mode_t mode maybe_unused) { int ret_val; char *tmp_dir; @@ -53,13 +56,33 @@ rpl_mkdir (char const *dir, mode_t mode) if (len && dir[len - 1] == '/') { - tmp_dir = xstrdup (dir); + tmp_dir = strdup (dir); + if (!tmp_dir) + { + /* Rather than rely on strdup-posix, we set errno ourselves. */ + errno = ENOMEM; + return -1; + } strip_trailing_slashes (tmp_dir); } else { 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);