bug-coreutils
[Top][All Lists]
Advanced

[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)




reply via email to

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