bug-coreutils
[Top][All Lists]
Advanced

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




reply via email to

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