[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: coreutils 5.92, rm <dir> on Solaris, bad error message
From: |
Jim Meyering |
Subject: |
Re: coreutils 5.92, rm <dir> on Solaris, bad error message |
Date: |
Wed, 02 Nov 2005 00:34:31 +0100 |
Keith Thompson <address@hidden> wrote:
> On solaris 9:
>
> % uname -a
> SunOS elmak 5.9 Generic_117171-17 sun4u sparc SUNW,Sun-Blade-100 Solaris
> % rm --version | head -1
> rm (GNU coreutils) 5.92
> % mkdir tmpdir
> % ls -ld tmpdir
> drwxr-xr-x 2 kst sys200 117 Oct 31 19:38 tmpdir
> % rm tmpdir
> rm: cannot remove `tmpdir': Not owner
Thanks for the report.
Here's a proof of concept patch that makes rm give a better diagnostic,
in spite of Solaris's slightly bogus errno==EPERM failure mode.
I expect to put something like this on both the trunk and the branch,
but with a test or two (relatively fragile) only on the trunk.
FYI, this arose with rm/remove's change to use the race-free
IF-branch of the `if (cannot_unlink_dir ())' block on newer Solaris
systems. Before, they used the ELSE-block.
Catching up on email...
Index: src/remove.c
===================================================================
RCS file: /fetish/cu/src/remove.c,v
retrieving revision 1.132
diff -u -p -r1.132 remove.c
--- src/remove.c 20 Sep 2005 17:48:02 -0000 1.132
+++ src/remove.c 1 Nov 2005 23:11:08 -0000
@@ -657,6 +657,16 @@ prompt (Dirstack_state const *ds, char c
return RM_OK;
}
+static inline bool
+is_dir_lstat (char const *filename)
+{
+ struct stat sbuf;
+ int saved_errno = errno;
+ bool is_dir = lstat (filename, &sbuf) == 0 && S_ISDIR (sbuf.st_mode);
+ errno = saved_errno;
+ return is_dir;
+}
+
#if HAVE_STRUCT_DIRENT_D_TYPE
/* True if the type of the directory entry D is known. */
@@ -760,6 +770,12 @@ remove_entry (Dirstack_state const *ds,
DO_UNLINK (filename, x);
+ /* Upon a failed attempt to unlink a directory, Solaris 9 sets
+ errno to EPERM. In that case, change errno to EISDIR so that
+ we emit a better diagnostic. */
+ if (! x->recursive && errno == EPERM && is_dir_lstat (filename))
+ errno = EISDIR;
+
if (! x->recursive
|| errno == ENOENT || errno == ENOTDIR
|| errno == ELOOP || errno == ENAMETOOLONG)