Import upstream version 1.29
[debian/tar] / gnu / unlinkat.c
index 242ad493650f75a3f2d0156db2595760ba7026db..af35256fd086552b9f9f5ac142128c5206e1b82a 100644 (file)
@@ -1,8 +1,6 @@
-/* -*- buffer-read-only: t -*- vi: set ro: */
-/* DO NOT EDIT! GENERATED AUTOMATICALLY! */
 /* Work around unlinkat bugs on Solaris 9 and Hurd.
 
-   Copyright (C) 2009-2014 Free Software Foundation, Inc.
+   Copyright (C) 2009-2015 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
 
 # undef unlinkat
 
-/* unlinkat without AT_REMOVEDIR does not honor trailing / on Solaris
-   9.  Solve it in a similar manner to unlink.  Hurd has the same
-   issue. */
+/* unlinkat without AT_REMOVEDIR does not honor trailing / on Solaris 9.
+   Hurd has the same issue.
+
+   unlinkat without AT_REMOVEDIR erroneously ignores ".." on Darwin 14.
+
+   Solve these in a similar manner to unlink.  */
 
 int
 rpl_unlinkat (int fd, char const *name, int flag)
@@ -80,7 +81,17 @@ rpl_unlinkat (int fd, char const *name, int flag)
         }
     }
   if (!result)
-    result = unlinkat (fd, name, flag);
+    {
+# if UNLINK_PARENT_BUG
+      if (len >= 2 && name[len - 1] == '.' && name[len - 2] == '.'
+          && (len == 2 || ISSLASH (name[len - 3])))
+        {
+          errno = EISDIR; /* could also use EPERM */
+          return -1;
+        }
+# endif
+      result = unlinkat (fd, name, flag);
+    }
   return result;
 }