bug-coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

cp -af fails on special files


From: Ian Jackson
Subject: cp -af fails on special files
Date: Tue, 4 Jul 2006 19:19:08 +0100

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.

address@hidden:d> ls
address@hidden:d> cp -a /dev/null a
address@hidden:d> cp -a /dev/null a
cp: cannot create special file `a': File exists
address@hidden:d> cp -af /dev/null a
cp: cannot create special file `a': File exists
address@hidden:d> cp -a --remove-destination /dev/null a
address@hidden: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




reply via email to

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