X-Git-Url: https://git.gag.com/?a=blobdiff_plain;ds=sidebyside;f=lib%2Funlinkat.c;h=059f4e561a4f4a10081d0e2ddae35e3e5d5836fe;hb=92249085071a973e2c0621b0415b93d2e48bb00d;hp=008192e6d3fa8f72971d21b070b1c36e571be5fc;hpb=a2016c1de6e4884f6c8ed5cc498f3bf821c25ca4;p=debian%2Fgzip diff --git a/lib/unlinkat.c b/lib/unlinkat.c index 008192e..059f4e5 100644 --- a/lib/unlinkat.c +++ b/lib/unlinkat.c @@ -1,6 +1,6 @@ -/* Work around unlinkat bugs on Solaris 9. +/* Work around unlinkat bugs on Solaris 9 and Hurd. - Copyright (C) 2009-2010 Free Software Foundation, Inc. + Copyright (C) 2009-2018 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 @@ -13,7 +13,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program. If not, see . */ + along with this program. If not, see . */ /* Written by Eric Blake. */ @@ -26,14 +26,21 @@ #include #include +#include + +#include "dosname.h" #include "openat.h" #if HAVE_UNLINKAT # undef unlinkat -/* unlinkat without AT_REMOVEDIR does not honor trailing / on Solaris - 9. Solve it in a similar manner to unlink. */ +/* 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) @@ -74,14 +81,24 @@ 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; } #else /* !HAVE_UNLINKAT */ /* Replacement for Solaris' function by the same name. - + First, try to simulate it via (unlink|rmdir) ("/proc/self/fd/FD/FILE"). Failing that, simulate it via save_cwd/fchdir/(unlink|rmdir)/restore_cwd. If either the save_cwd or the restore_cwd fails (relatively unlikely),