diff options
author | Jim Meyering <jim@meyering.net> | 2003-05-02 12:53:02 +0000 |
---|---|---|
committer | Jim Meyering <jim@meyering.net> | 2003-05-02 12:53:02 +0000 |
commit | 4ed5c260a3b39ba5a75a8399152dc8e7599fa012 (patch) | |
tree | d0546e407a592d7896083c60048b8e9d02d13771 /src | |
parent | ee0dc0c2ceca47f32eddd26e22248fffd8a4c80a (diff) | |
download | coreutils-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.c | 24 |
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: |