[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: rm: avoiding a race condition on non-glibc systems
From: |
Paul Eggert |
Subject: |
Re: rm: avoiding a race condition on non-glibc systems |
Date: |
Mon, 16 May 2005 13:32:05 -0700 |
User-agent: |
Gnus/5.1006 (Gnus v5.10.6) Emacs/21.4 (gnu/linux) |
Eric Blake <address@hidden> writes:
> This change broke cygwin. Cygwin does not have struct dirent.d_type, so
> DT_IS_DIR is defined as do_not_use_this_macro. I think protecting this if
> statement with HAVE_STRUCT_DIRENT_D_TYPE, and letting cygwin fall through
> to the unlink, will fix the problem.
Thanks for reporting it. I'd rather avoid yet another #if inside
expressions, so I installed the following patch instead. The main
idea is to remove DT_IS_DIR (with its confusing semantics) and replace
it with DT_IS_KNOWN and DT_MUST_BE (with, I hope, less confusing
semantics :-). This lets us remove an #if rather than add one.
2005-05-16 Paul Eggert <address@hidden>
Fix Cygwin porting problem reported by Eric Blake.
* src/remove.c (DT_IS_DIR): Remove.
(DT_IS_KNOWN, DT_MUST_BE): New macros.
(remove_entry): Use them.
--- remove.c 14 May 2005 08:05:35 -0000 1.125
+++ remove.c 16 May 2005 20:28:53 -0000 1.126
@@ -664,10 +664,16 @@ prompt (Dirstack_state const *ds, char c
}
#if HAVE_STRUCT_DIRENT_D_TYPE
-# define DT_IS_DIR(D) ((D)->d_type == DT_DIR)
+
+/* True if the type of the directory entry D is known. */
+# define DT_IS_KNOWN(d) ((d)->d_type != DT_UNKNOWN)
+
+/* True if the type of the directory entry D must be T. */
+# define DT_MUST_BE(d, t) ((d)->d_type == (t))
+
#else
-/* Use this only if the member exists -- i.e., don't return 0. */
-# define DT_IS_DIR(D) do_not_use_this_macro
+# define DT_IS_KNOWN(d) false
+# define DT_MUST_BE(d, t) false
#endif
#define DO_UNLINK(Filename, X) \
@@ -755,7 +761,7 @@ remove_entry (Dirstack_state const *ds,
unlink call. If FILENAME is a command-line argument, then dp is NULL,
so we'll first try to unlink it. Using unlink here is ok, because it
cannot remove a directory. */
- if ((dp && DT_IS_DIR (dp)) || is_dir == T_YES)
+ if ((dp && DT_MUST_BE (dp, DT_DIR)) || is_dir == T_YES)
return RM_NONEMPTY_DIR;
DO_UNLINK (filename, x);
@@ -777,11 +783,9 @@ remove_entry (Dirstack_state const *ds,
Then, if it's a non-directory, we can use unlink on it. */
if (is_dir == T_UNKNOWN)
{
-#if HAVE_STRUCT_DIRENT_D_TYPE
- if (dp && dp->d_type != DT_UNKNOWN)
- is_dir = DT_IS_DIR (dp) ? T_YES : T_NO;
+ if (dp && DT_IS_KNOWN (dp))
+ is_dir = DT_MUST_BE (dp, DT_DIR) ? T_YES : T_NO;
else
-#endif
{
struct stat sbuf;
if (lstat (filename, &sbuf))