summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJim Meyering <jim@meyering.net>2003-05-02 12:53:02 +0000
committerJim Meyering <jim@meyering.net>2003-05-02 12:53:02 +0000
commit4ed5c260a3b39ba5a75a8399152dc8e7599fa012 (patch)
treed0546e407a592d7896083c60048b8e9d02d13771 /src
parentee0dc0c2ceca47f32eddd26e22248fffd8a4c80a (diff)
downloadcoreutils-4ed5c260a3b39ba5a75a8399152dc8e7599fa012.tar.xz
Work around nasty readdir bug with Darwin6.5 and hfs file system.
(IF_READDIR_NEEDS_REWINDDIR): Define. [! HAVE_WORKING_READDIR] (remove_cwd_entries): If readdir has just returned NULL and there has been at least one successful unlink or rmdir call since the opendir or previous rewinddir, then call rewinddir and reiterate the loop.
Diffstat (limited to 'src')
-rw-r--r--src/remove.c24
1 files changed, 23 insertions, 1 deletions
diff --git a/src/remove.c b/src/remove.c
index a8be3dac9..cf808dd21 100644
--- a/src/remove.c
+++ b/src/remove.c
@@ -55,6 +55,12 @@
# define ROOT_CAN_UNLINK_DIRS 1
#endif
+#if HAVE_WORKING_READDIR
+# define IF_READDIR_NEEDS_REWINDDIR(Code) /* empty */
+#else
+# define IF_READDIR_NEEDS_REWINDDIR(Code) Code
+#endif
+
enum Ternary
{
T_UNKNOWN = 2,
@@ -804,6 +810,7 @@ remove_cwd_entries (Dirstack_state *ds, char **subdir, struct stat *subdir_sb,
DIR *dirp = opendir (".");
struct AD_ent *top = AD_stack_top (ds);
enum RM_status status = top->status;
+ IF_READDIR_NEEDS_REWINDDIR (int performed_unlink_or_rmdir = 0);
assert (VALID_STATUS (status));
*subdir = NULL;
@@ -839,6 +846,19 @@ remove_cwd_entries (Dirstack_state *ds, char **subdir, struct stat *subdir_sb,
/* Arrange to give a diagnostic after exiting this loop. */
dirp = NULL;
}
+ else
+ {
+#if ! HAVE_WORKING_READDIR
+ /* On buggy systems, call rewinddir if we've called unlink
+ or rmdir since the opendir or a previous rewinddir. */
+ if (performed_unlink_or_rmdir)
+ {
+ rewinddir (dirp);
+ performed_unlink_or_rmdir = 0;
+ continue;
+ }
+#endif
+ }
break;
}
@@ -856,7 +876,9 @@ remove_cwd_entries (Dirstack_state *ds, char **subdir, struct stat *subdir_sb,
switch (tmp_status)
{
case RM_OK:
- /* do nothing */
+ /* On buggy systems, record the fact that we've just
+ removed a directory entry. */
+ IF_READDIR_NEEDS_REWINDDIR (performed_unlink_or_rmdir = 1);
break;
case RM_ERROR: