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: l...@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+ l...@goober:~$ mkdir chbouib l...@goober:~$ rpctrace -o remove.log ./remove chbouib ./remove: failed: Operation not permitted l...@goober:~$ rpctrace -o rmdir.log rmdir chbouib l...@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/