1/* Work around rmdir bugs.
2
3   Copyright (C) 1988, 1990, 1999, 2003-2006, 2009-2022 Free Software
4   Foundation, Inc.
5
6   This file is free software: you can redistribute it and/or modify
7   it under the terms of the GNU Lesser General Public License as
8   published by the Free Software Foundation; either version 2.1 of the
9   License, or (at your option) any later version.
10
11   This file is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   GNU Lesser General Public License for more details.
15
16   You should have received a copy of the GNU Lesser General Public License
17   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
18
19#include <config.h>
20
21#include <unistd.h>
22
23#include <errno.h>
24#include <string.h>
25
26#include "filename.h"
27
28#undef rmdir
29#if defined _WIN32 && !defined __CYGWIN__
30# define rmdir _rmdir
31#endif
32
33/* Remove directory DIR.
34   Return 0 if successful, -1 if not.  */
35
36int
37rpl_rmdir (char const *dir)
38{
39  /* Work around cygwin 1.5.x bug where rmdir("dir/./") succeeds.  */
40  size_t len = strlen (dir);
41  int result;
42  while (len && ISSLASH (dir[len - 1]))
43    len--;
44  if (len && dir[len - 1] == '.' && (1 == len || ISSLASH (dir[len - 2])))
45    {
46      errno = EINVAL;
47      return -1;
48    }
49  result = rmdir (dir);
50  /* Work around mingw bug, where rmdir("file/") fails with EINVAL
51     instead of ENOTDIR.  We've already filtered out trailing ., the
52     only reason allowed by POSIX for EINVAL.  */
53  if (result == -1 && errno == EINVAL)
54    errno = ENOTDIR;
55  return result;
56}
57