Blame gnulib/lib/mkdir.c

Packit Service a2ae7a
/* On some systems, mkdir ("foo/", 0700) fails because of the trailing
Packit Service a2ae7a
   slash.  On those systems, this wrapper removes the trailing slash.
Packit Service a2ae7a
Packit Service a2ae7a
   Copyright (C) 2001, 2003, 2006, 2008-2019 Free Software Foundation, Inc.
Packit Service a2ae7a
Packit Service a2ae7a
   This program is free software: you can redistribute it and/or modify
Packit Service a2ae7a
   it under the terms of the GNU Lesser General Public License as published by
Packit Service a2ae7a
   the Free Software Foundation; either version 2.1 of the License, or
Packit Service a2ae7a
   (at your option) any later version.
Packit Service a2ae7a
Packit Service a2ae7a
   This program is distributed in the hope that it will be useful,
Packit Service a2ae7a
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service a2ae7a
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service a2ae7a
   GNU Lesser General Public License for more details.
Packit Service a2ae7a
Packit Service a2ae7a
   You should have received a copy of the GNU Lesser General Public License
Packit Service a2ae7a
   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
Packit Service a2ae7a
Packit Service a2ae7a
/* written by Jim Meyering */
Packit Service a2ae7a
Packit Service a2ae7a
#include <config.h>
Packit Service a2ae7a
Packit Service a2ae7a
/* Specification.  */
Packit Service a2ae7a
#include <sys/stat.h>
Packit Service a2ae7a
Packit Service a2ae7a
#include <errno.h>
Packit Service a2ae7a
#include <stdio.h>
Packit Service a2ae7a
#include <stdlib.h>
Packit Service a2ae7a
#include <string.h>
Packit Service a2ae7a
Packit Service a2ae7a
#include "dirname.h"
Packit Service a2ae7a
Packit Service a2ae7a
/* Disable the definition of mkdir to rpl_mkdir (from the <sys/stat.h>
Packit Service a2ae7a
   substitute) in this file.  Otherwise, we'd get an endless recursion.  */
Packit Service a2ae7a
#undef mkdir
Packit Service a2ae7a
Packit Service a2ae7a
/* mingw's _mkdir() function has 1 argument, but we pass 2 arguments.
Packit Service a2ae7a
   Additionally, it declares _mkdir (and depending on compile flags, an
Packit Service a2ae7a
   alias mkdir), only in the nonstandard includes <direct.h> and <io.h>,
Packit Service a2ae7a
   which are included in the <sys/stat.h> override.  */
Packit Service a2ae7a
#if defined _WIN32 && ! defined __CYGWIN__
Packit Service a2ae7a
# define mkdir(name,mode) _mkdir (name)
Packit Service a2ae7a
# define maybe_unused _GL_UNUSED
Packit Service a2ae7a
#else
Packit Service a2ae7a
# define maybe_unused /* empty */
Packit Service a2ae7a
#endif
Packit Service a2ae7a
Packit Service a2ae7a
/* This function is required at least for NetBSD 1.5.2.  */
Packit Service a2ae7a
Packit Service a2ae7a
int
Packit Service a2ae7a
rpl_mkdir (char const *dir, mode_t mode maybe_unused)
Packit Service a2ae7a
{
Packit Service a2ae7a
  int ret_val;
Packit Service a2ae7a
  char *tmp_dir;
Packit Service a2ae7a
  size_t len = strlen (dir);
Packit Service a2ae7a
Packit Service a2ae7a
  if (len && dir[len - 1] == '/')
Packit Service a2ae7a
    {
Packit Service a2ae7a
      tmp_dir = strdup (dir);
Packit Service a2ae7a
      if (!tmp_dir)
Packit Service a2ae7a
        {
Packit Service a2ae7a
          /* Rather than rely on strdup-posix, we set errno ourselves.  */
Packit Service a2ae7a
          errno = ENOMEM;
Packit Service a2ae7a
          return -1;
Packit Service a2ae7a
        }
Packit Service a2ae7a
      strip_trailing_slashes (tmp_dir);
Packit Service a2ae7a
    }
Packit Service a2ae7a
  else
Packit Service a2ae7a
    {
Packit Service a2ae7a
      tmp_dir = (char *) dir;
Packit Service a2ae7a
    }
Packit Service a2ae7a
#if FUNC_MKDIR_DOT_BUG
Packit Service a2ae7a
  /* Additionally, cygwin 1.5 mistakenly creates a directory "d/./".  */
Packit Service a2ae7a
  {
Packit Service a2ae7a
    char *last = last_component (tmp_dir);
Packit Service a2ae7a
    if (*last == '.' && (last[1] == '\0'
Packit Service a2ae7a
                         || (last[1] == '.' && last[2] == '\0')))
Packit Service a2ae7a
      {
Packit Service a2ae7a
        struct stat st;
Packit Service a2ae7a
        if (stat (tmp_dir, &st) == 0)
Packit Service a2ae7a
          errno = EEXIST;
Packit Service a2ae7a
        return -1;
Packit Service a2ae7a
      }
Packit Service a2ae7a
  }
Packit Service a2ae7a
#endif /* FUNC_MKDIR_DOT_BUG */
Packit Service a2ae7a
Packit Service a2ae7a
  ret_val = mkdir (tmp_dir, mode);
Packit Service a2ae7a
Packit Service a2ae7a
  if (tmp_dir != dir)
Packit Service a2ae7a
    free (tmp_dir);
Packit Service a2ae7a
Packit Service a2ae7a
  return ret_val;
Packit Service a2ae7a
}