diff options
author | Jim Meyering <jim@meyering.net> | 2002-07-14 11:46:41 +0000 |
---|---|---|
committer | Jim Meyering <jim@meyering.net> | 2002-07-14 11:46:41 +0000 |
commit | ab4c1d5532c685a1add2fd8fb8ac1f67c7f59b43 (patch) | |
tree | fb7faef0aaa7eb2bc2a26b7248d1dd6dec407902 | |
parent | 7678915a9e643147792b10cb68b2711ab2c052de (diff) | |
download | coreutils-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.c | 22 |
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; } |