bug-coreutils
[Top][All Lists]
Advanced

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

mv feature request: -z swap files


From: TL Mieszkowski
Subject: mv feature request: -z swap files
Date: Sat, 31 Jan 2009 16:52:24 -0500
User-agent: Mutt/1.5.18 (2008-05-17)

I've needed to swap two filenames more than once,
but no UNIX program I can find does it. 

The patch I've included works on two regular files,
one regular file and a directory, but if you provide two
directories or 1 directory first it trashes the first directory.  
I think this is due the vagaries of the 
rename function, but I can't understand why it happens.
It says it can't copy a directory into itself, but the target
doesn't even exist.

There may also be issues across filesystems, since
it uses the /tmp directory? Is there a way to do it without
a /tmp? Is it possible to do it right, without just calling 
mv? Is this workable at all?

--- coreutils-git-orig/src/mv.c 2009-01-28 23:32:41.000000000 -0500
+++ coreutils-git/src/mv.c      2009-01-31 15:24:59.362747668 -0500
@@ -69,6 +70,7 @@
   {"target-directory", required_argument, NULL, 't'},
   {"update", no_argument, NULL, 'u'},
   {"verbose", no_argument, NULL, 'v'},
+  {"swap", no_argument, NULL, 'z'},
   {GETOPT_HELP_OPTION_DECL},
   {GETOPT_VERSION_OPTION_DECL},
   {NULL, 0, NULL, 0}
@@ -283,6 +285,7 @@
 Usage: %s [OPTION]... [-T] SOURCE DEST\n\
   or:  %s [OPTION]... SOURCE... DIRECTORY\n\
   or:  %s [OPTION]... -t DIRECTORY SOURCE...\n\
+  or:  %s [OPTION]... -z FILE1 FILE2...\n\
 "),
              program_name, program_name, program_name);
       fputs (_("\
@@ -312,6 +315,7 @@
                                  than the destination file or when the\n\
                                  destination file is missing\n\
   -v, --verbose                explain what is being done\n\
+  -z, --swap                swap the names of FILE1 and FILE2\n\
 "), stdout);
       fputs (HELP_OPTION_DESCRIPTION, stdout);
       fputs (VERSION_OPTION_DESCRIPTION, stdout);
@@ -338,6 +342,8 @@
 {
   int c;
   bool ok;
+  bool swap_files = false;
+  char *tmp;
   bool make_backups = false;
   char *backup_suffix_string;
   char *version_control_string = NULL;
@@ -361,7 +367,7 @@
      we'll actually use backup_suffix_string.  */
   backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX");
 
-  while ((c = getopt_long (argc, argv, "bfint:uvS:T", long_options, NULL))
+  while ((c = getopt_long (argc, argv, "bfint:uvzS:T", long_options, NULL))
         != -1)
     {
       switch (c)
@@ -410,6 +416,9 @@
          make_backups = true;
          backup_suffix_string = optarg;
          break;
+       case 'z':
+    swap_files = true;    
+         break;
        case_GETOPT_HELP_CHAR;
        case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
        default:
@@ -430,6 +440,25 @@
       usage (EXIT_FAILURE);
     }
+  
+  if (swap_files)
+  {
+      tmp = tempnam("/tmp/",NULL);
+      if (tmp)
+      {
+          hash_init ();
+          ok = true;
+          ok &= movefile (file[0], tmp, false, &x);
+          ok &= movefile (file[1], file[0], false, &x);
+          ok &= movefile (tmp, file[1], false, &x);
+          exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);
+      }
+      else
+          error (0, 0, _("tempnam error"));
+      exit(EXIT_FAILURE);
+  }
+
   if (no_target_directory)
     {
       if (target_directory)




reply via email to

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