bug-hurd
[Top][All Lists]
Advanced

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

[bug #28859] remove(3) fails to remove an empty directory


From: Ludovic Courtès
Subject: [bug #28859] remove(3) fails to remove an empty directory
Date: Wed, 10 Feb 2010 16:28:08 +0000
User-agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.5) Gecko/20091214 IceCat/3.5.5

URL:
  <http://savannah.gnu.org/bugs/?28859>

                 Summary: remove(3) fails to remove an empty directory
                 Project: The GNU Hurd
            Submitted by: civodul
            Submitted on: Wed 10 Feb 2010 04:28:07 PM GMT
                Category: Hurd Servers
                Severity: 3 - Normal
                Priority: 5 - Normal
              Item Group: None
                  Status: None
                 Privacy: Public
             Assigned to: None
         Originator Name: Ludovic Courtès
        Originator Email: ludo@gnu.org
             Open/Closed: Open
         Discussion Lock: Any
         Reproducibility: None
              Size (loc): None
         Planned Release: None
                  Effort: 0.00
Wiki-like text discussion box: 

    _______________________________________________________

Details:

Hello,

The remove(3) libc function fails to remove an empty directory.

Consider this program:

#v+
#include <stdio.h>
#include <error.h>
#include <errno.h>

int
main (int argc, char *argv[])
{
  if (remove (argv[1]))
    error (1, errno, "failed");

  return 0;
}
#v-

Here's a comparison of Coreutils' `rm' and this program:

#v+
ludo@goober:~$ mkdir chbouib
ludo@goober:~$ rpctrace -o remove.log ./remove chbouib
./remove: failed: Operation not permitted
ludo@goober:~$ rpctrace -o rmdir.log rmdir chbouib
ludo@goober:~$ grep -C3 chbouib {remove,rmdir}.log
remove.log-task15378->vm_allocate (17147851 4096 1) = 0 16941056
remove.log-task15378->vm_deallocate (16936960 16) = 0 
remove.log-task15378->mach_port_mod_refs (pn{  8} 0 1) = 0 
remove.log:  56->dir_unlink ("chbouib") = 0x40000001 (Operation not
permitted) 
remove.log-task15378->mach_port_deallocate (pn{  8}) = 0 
remove.log-  54->io_write_request ("./remove: " -1) = 0 10
remove.log-  54->io_write_request ("failed" -1) = 0 6
--
rmdir.log-task15343->vm_allocate (17147851 4096 1) = 0 16941056
rmdir.log-task15343->vm_deallocate (16936960 16) = 0 
rmdir.log-task15343->mach_port_mod_refs (pn{  8} 0 1) = 0 
rmdir.log:  56->dir_rmdir ("chbouib") = 0 
rmdir.log-task15343->mach_port_deallocate (pn{  8}) = 0 
rmdir.log-task15343->mach_port_deallocate (pn{  5}) = 0 
rmdir.log-task15343->mach_port_deallocate (pn{  6}) = 0 
#v-

My guess is that this is a problem in glibc:

#v+
int
remove (file)
     const char *file;
{
  /* First try to unlink since this is more frequently the necessary action.
*/
  if (__unlink (file) != 0
      /* If it is indeed a directory...  */
      && (errno != EISDIR
          /* ...try to remove it.  */
          || __rmdir (file) != 0))
    /* Cannot remove the object for whatever reason.  */
    return -1;

  return 0;
}
#v-

Here glibc should be prepared to deal with `EPERM', which is the suitable
error code for this case according to POSIX 2008.  The "Rationale" section at
http://www.opengroup.org/onlinepubs/9699919799/functions/unlink.html says that
"[aA]pplications written for portability to both POSIX.1-2008 and the LSB
should be prepared to handle either error code."  Thus I think the right fix
is to have glibc's remove(3) handle both `EISDIR' and `EPERM', regardless of
the underlying kernel.

What do you think?

Thanks,
Ludo'.




    _______________________________________________________

Reply to this item at:

  <http://savannah.gnu.org/bugs/?28859>

_______________________________________________
  Message sent via/by Savannah
  http://savannah.gnu.org/





reply via email to

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