tech-userlevel archive

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

bin/44246: enhance mv to work better with xargs



I've taken a look at bin/44246 and attempted to implement an
enhancement to resolve the PR.

While the PR suggested ``-x'', a review of other mv(1)
implementations showed that GNU's mv(1) has chosen ``-t'' for
the flag indicating the target directory.  Neither FreeBSD or
OpenBSD have implemented anything along these lines. 

Attached is the patch implementing the enhancement.  Similar
enhancements should probably be made to cp(1) and ln(1) for
consistency.

A test case still needs to be written as well.

Comments?

Thank you,
        Eric

--
Eric Schnoebelen                eric%cirr.com@localhost         
http://www.cirr.com
        "...I knew I was working way too hard when I started having 
                nightmares in FORTRAN" -- Brent Chapman
Index: bin/mv/mv.1
===================================================================
RCS file: /cvsroot/src/bin/mv/mv.1,v
retrieving revision 1.26
diff -b -u -w -r1.26 mv.1
--- bin/mv/mv.1 22 Mar 2012 07:58:17 -0000      1.26
+++ bin/mv/mv.1 13 Jan 2013 02:15:44 -0000
@@ -45,6 +45,9 @@
 .Nm
 .Op Fl fiv
 .Ar source ... directory
+.Nm
+.Op Fl fiv
+.Ar -t directory source ...
 .Sh DESCRIPTION
 In its first form, the
 .Nm
@@ -56,7 +59,7 @@
 This form is assumed when the last operand does not name an already
 existing directory.
 .Pp
-In its second form,
+In its second and third forms,
 .Nm
 moves each file named by a
 .Ar source
@@ -83,6 +86,9 @@
 Cause
 .Nm
 to be verbose, showing files as they are processed.
+.It Fl t 
+Causes the immediately following argument as the destination, instead of
+the final argument.
 .El
 .Pp
 The last of any
@@ -142,5 +148,7 @@
 .Pp
 The
 .Fl v
-option is an extension to
+and
+.Fl t
+options are extensions to
 .St -p1003.2 .
Index: bin/mv/mv.c
===================================================================
RCS file: /cvsroot/src/bin/mv/mv.c,v
retrieving revision 1.43
diff -b -u -w -r1.43 mv.c
--- bin/mv/mv.c 29 Aug 2011 14:46:54 -0000      1.43
+++ bin/mv/mv.c 13 Jan 2013 02:15:45 -0000
@@ -80,12 +80,13 @@
        char *p, *endp;
        struct stat sb;
        char path[MAXPATHLEN + 1];
+       char *target = NULL;
        size_t baselen;
 
        setprogname(argv[0]);
        (void)setlocale(LC_ALL, "");
 
-       while ((ch = getopt(argc, argv, "ifv")) != -1)
+       while ((ch = getopt(argc, argv, "ifvt:")) != -1)
                switch (ch) {
                case 'i':
                        fflg = 0;
@@ -98,13 +99,21 @@
                case 'v':
                        vflg = 1;
                        break;
+               case 't':
+                       target = optarg;
+                       break;
                default:
                        usage();
                }
        argc -= optind;
        argv += optind;
 
-       if (argc < 2)
+       if (target == NULL) {
+           target = argv[argc - 1];
+           argc--;
+       }
+
+       if (argc < 1)
                usage();
 
        stdin_ok = isatty(STDIN_FILENO);
@@ -113,22 +122,22 @@
         * If the stat on the target fails or the target isn't a directory,
         * try the move.  More than 2 arguments is an error in this case.
         */
-       if (stat(argv[argc - 1], &sb) || !S_ISDIR(sb.st_mode)) {
-               if (argc > 2)
+       if (stat(target, &sb) || !S_ISDIR(sb.st_mode)) {
+               if (argc > 1)
                        usage();
-               exit(do_move(argv[0], argv[1]));
+               exit(do_move(argv[0], target));
        }
 
        /* It's a directory, move each file into it. */
-       baselen = strlcpy(path, argv[argc - 1], sizeof(path));
+       baselen = strlcpy(path, target, sizeof(path));
        if (baselen >= sizeof(path))
-               errx(1, "%s: destination pathname too long", argv[argc - 1]);
+               errx(1, "%s: destination pathname too long", target);
        endp = &path[baselen];
        if (!baselen || *(endp - 1) != '/') {
                *endp++ = '/';
                ++baselen;
        }
-       for (rval = 0; --argc; ++argv) {
+       for (rval = 0; argc--; argv++) {
                p = *argv + strlen(*argv) - 1;
                while (*p == '/' && p != *argv)
                        *p-- = '\0';
@@ -385,8 +394,9 @@
 usage(void)
 {
        (void)fprintf(stderr, "usage: %s [-fiv] source target\n"
-           "       %s [-fiv] source ... directory\n", getprogname(),
-           getprogname());
+           "       %s [-fiv] source ... directory\n"
+           "       %s [-fiv] -t directory source ...\n", getprogname(),
+           getprogname(), getprogname());
        exit(1);
        /* NOTREACHED */
 }


Home | Main Index | Thread Index | Old Index