bug-coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: rm -r gives up before going deeper upon encountering hindrances


From: Jim Meyering
Subject: Re: rm -r gives up before going deeper upon encountering hindrances
Date: Fri, 07 May 2004 18:50:30 +0200

Dan Jacobson <address@hidden> wrote:
> Here I though rm would go in and still remove all it could.
> But it turns out that it gives up before going deeper upon encountering 
> hindrances.
> $ id
> uid=1000(jidanni) gid=1000(jidanni) groups=1000(jidanni)
> $ ls -la cds
> drwxrwxrwx    3 root     staff        4096 2003-12-06 10:49 .
> drwxrwsr-x    4 root     staff        4096 2003-12-06 10:29 ..
> -r--r--r--    1 jidanni  jidanni  510021216 2003-12-06 10:15 data.bin
> $ /bin/rm -rf *
> /bin/rm: cannot remove `cds': Permission denied
> $ /bin/rm -rf cds
> /bin/rm: cannot remove `cds': Permission denied
> $ ls -l cds/data.bin
> -r--r--r--    1 jidanni  jidanni  510021216 2003-12-06 10:15 cds/data.bin
> $ /bin/rm -rf cds/data.bin
> The file is now finally gone.
> OK, next time I'll use find cds -type f|xargs rm, etc.
> Anyway, the docs don't seem to document the above case.

Thank you for noticing and reporting that!
Here's a tentative patch:

Index: remove.c
===================================================================
RCS file: /fetish/cu/src/remove.c,v
retrieving revision 1.102
diff -u -p -r1.102 remove.c
--- a/remove.c  27 Apr 2004 15:00:32 -0000      1.102
+++ b/remove.c  7 May 2004 15:23:14 -0000
@@ -762,10 +762,11 @@ remove_entry (Dirstack_state const *ds,
 
   DO_UNLINK (filename, x);
 
-  /* Accept either EISDIR or EPERM as an indication that FILENAME may be
-     a directory.  POSIX says that unlink must set errno to EPERM when it
-     fails to remove a directory, while Linux-2.4.18 sets it to EISDIR.  */
-  if ((errno != EISDIR && errno != EPERM) || ! x->recursive)
+  /* Accept either EISDIR, EPERM, or EACCES as an indication that FILENAME may
+     be a directory.  POSIX says that unlink must set errno to EPERM when it
+     fails to remove a directory, while Linux-2.4.18 sets it to EISDIR.
+     unlink fails with EACCES when the parent directory is write-protected.  */
+  if ((errno != EISDIR && errno != EPERM && errno != EACCES) || ! x->recursive)
     {
       /* some other error code.  Report it and fail.
         Likewise, if we're trying to remove a directory without
@@ -993,10 +994,12 @@ remove_dir (Dirstack_state *ds, char con
     {
       if (! S_ISDIR (dir_sb.st_mode))
        {
-         /* This happens on Linux-2.4.18 when a non-privileged user tries
-            to delete a file that is owned by another user in a directory
-            like /tmp that has the S_ISVTX flag set.  */
-         assert (saved_errno == EPERM);
+         /* saved_errno is EPERM on Linux-2.4.18 when a non-privileged user
+            tries to delete a file that is owned by another user in a directory
+            like /tmp that has the S_ISVTX flag set.  It is far more common
+            to have saved_errno == EACCES -- that happens at least when failing
+            to unlink a non-directory due to restricted permissions.  */
+         assert (saved_errno == EPERM || saved_errno == EACCES);
          error (0, saved_errno,
                 _("cannot remove %s"), quote (full_filename (dir)));
        }




reply via email to

[Prev in Thread] Current Thread [Next in Thread]