summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim Meyering <jim@meyering.net>2002-07-14 11:46:41 +0000
committerJim Meyering <jim@meyering.net>2002-07-14 11:46:41 +0000
commitab4c1d5532c685a1add2fd8fb8ac1f67c7f59b43 (patch)
treefb7faef0aaa7eb2bc2a26b7248d1dd6dec407902
parent7678915a9e643147792b10cb68b2711ab2c052de (diff)
downloadcoreutils-ab4c1d5532c685a1add2fd8fb8ac1f67c7f59b43.tar.xz
Under some circumstances, rm would fail due to a lack of
permissions, but give a misleading diagnostic like this: rm: cannot chdir from `.' to `foo': Not a directory (remove_dir): Detect the case in which unlinking a non-directory fails with EPERM, and give an appropriate diagnostic.
-rw-r--r--src/remove.c22
1 files changed, 19 insertions, 3 deletions
diff --git a/src/remove.c b/src/remove.c
index 394e4c484..8fa482e05 100644
--- a/src/remove.c
+++ b/src/remove.c
@@ -888,6 +888,10 @@ remove_dir (char const *dir, struct saved_cwd **cwd_state,
enum RM_status status;
struct stat dir_sb;
+ /* Save any errno (from caller's failed remove_entry call), in case DIR
+ is not a directory, so that we can give a reasonable diagnostic. */
+ int saved_errno = errno;
+
if (*cwd_state == NULL)
{
*cwd_state = XMALLOC (struct saved_cwd, 1);
@@ -911,9 +915,21 @@ remove_dir (char const *dir, struct saved_cwd **cwd_state,
if (chdir (dir))
{
- error (0, errno,
- _("cannot chdir from %s to %s"),
- quote_n (0, full_filename (".")), quote_n (1, dir));
+ 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);
+ error (0, saved_errno,
+ _("cannot remove %s"), quote (full_filename (dir)));
+ }
+ else
+ {
+ error (0, errno,
+ _("cannot chdir from %s to %s"),
+ quote_n (0, full_filename (".")), quote_n (1, dir));
+ }
return RM_ERROR;
}