If you cp -af a special file, it doesn't cope if the destination
exists.  After mknod fails with EEXIST, it should call unlink and then
retry the mknod again.  The patch below, against coreutils 5.96, does
this.

Thanks,
Ian.

[EMAIL PROTECTED]:d> ls
[EMAIL PROTECTED]:d> cp -a /dev/null a
[EMAIL PROTECTED]:d> cp -a /dev/null a
cp: cannot create special file `a': File exists
[EMAIL PROTECTED]:d> cp -af /dev/null a
cp: cannot create special file `a': File exists
[EMAIL PROTECTED]:d> cp -a --remove-destination /dev/null a
[EMAIL PROTECTED]:d>

--- coreutils-5.93/src/copy.c~  2006-07-03 17:23:18.000000000 +0100
+++ coreutils-5.96/src/copy.c   2006-07-03 18:05:25.000000000 +0100
@@ -1593,26 +1593,46 @@
        goto un_backup;
     }
   else
+#define CALL_PERHAPS_UNLINK(call,errormsg) do{                          \
+      if (call)                                                                
 \
+       {                                                                \
+         if (errno != EEXIST || !x->unlink_dest_after_failed_open)      \
+           {                                                            \
+             errormsg                                                   \
+             goto un_backup;                                            \
+           }                                                            \
+         if (unlink (dst_name) != 0)                                    \
+           {                                                            \
+             error (0, errno, _("cannot remove %s"), quote (dst_name)); \
+             goto un_backup;                                            \
+           }                                                            \
+         if (call)                                                      \
+           {                                                            \
+             errormsg                                                   \
+             goto un_backup;                                            \
+           }                                                            \
+       }                                                                \
+  }while(0)
 #ifdef S_ISFIFO
   if (S_ISFIFO (src_mode))
     {
-      if (mkfifo (dst_name, src_mode))
-       {
+      CALL_PERHAPS_UNLINK
+       (
+         mkfifo (dst_name, src_mode),
          error (0, errno, _("cannot create fifo %s"), quote (dst_name));
-         goto un_backup;
-       }
+       );
     }
   else
 #endif
     if (S_ISBLK (src_mode) || S_ISCHR (src_mode)
        || S_ISSOCK (src_mode))
     {
-      if (mknod (dst_name, src_mode, src_sb.st_rdev))
-       {
+      CALL_PERHAPS_UNLINK
+       (
+         mknod (dst_name, src_mode, src_sb.st_rdev),
          error (0, errno, _("cannot create special file %s"),
                 quote (dst_name));
-         goto un_backup;
-       }
+       );
     }
   else
 #ifdef S_ISLNK


_______________________________________________
Bug-coreutils mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/bug-coreutils

Reply via email to