From 588df316d95e633dde9b878745c451bc7d2ad306 Mon Sep 17 00:00:00 2001 From: Jim Meyering Date: Wed, 2 Nov 2005 09:47:39 +0000 Subject: (remove_entry): Emit a better diagnostic when rm (without -r) fails to remove a directory on a non-Linux system. This change affects only newer Solaris systems (with priv_* functions like priv_allocset). Reported by Keith Thompson. --- src/remove.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'src') diff --git a/src/remove.c b/src/remove.c index 6572245fd..52ef3b625 100644 --- a/src/remove.c +++ b/src/remove.c @@ -657,6 +657,19 @@ prompt (Dirstack_state const *ds, char const *filename, return RM_OK; } +/* Return true if FILENAME is a directory (and not a symlink to a directory). + Otherwise, including the case in which lstat fails, return false. + Do not modify errno. */ +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 +773,12 @@ remove_entry (Dirstack_state const *ds, char const *filename, DO_UNLINK (filename, x); + /* Upon a failed attempt to unlink a directory, most non-Linux systems + set errno to the POSIX-required value 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) -- cgit v1.2.3-70-g09d2