Dear all,

This patch adds a '-v' option to cp(1), mv(1), and rm(1). If the '-v'
option is used, the utility will display the name of each file after it
has been successfully copied, moved or removed.

This patch rolls in feedback from recent discussion. The manpage updates
are specific as to what the -v option does for each utility and the
messages written to the standard output are now minimalistic in nature.

example use:

        $ touch a
        $ mv -v a b
        a -> b
        $ cp -v b c
        b -> c
        $ rm -v b c
        b
        c

Hat tip to Paul de Weerd for helping with testing.

Kind regards,

Job

diff --git bin/cp/cp.1 bin/cp/cp.1
index 8573d801ca5..2896406498c 100644
--- bin/cp/cp.1
+++ bin/cp/cp.1
@@ -41,14 +41,14 @@
 .Nd copy files
 .Sh SYNOPSIS
 .Nm cp
-.Op Fl fip
+.Op Fl fipv
 .Oo
 .Fl R
 .Op Fl H | L | P
 .Oc
 .Ar source target
 .Nm cp
-.Op Fl fip
+.Op Fl fipv
 .Oo
 .Fl R
 .Op Fl H | L | P
@@ -145,6 +145,8 @@ use a utility such as
 or
 .Xr tar 1
 instead.
+.It Fl v
+Display the source and destination after each copy.
 .El
 .Pp
 For each destination file that already exists, its contents are
diff --git bin/cp/cp.c bin/cp/cp.c
index 643d82ed9fa..480f18b0ff1 100644
--- bin/cp/cp.c
+++ bin/cp/cp.c
@@ -71,7 +71,7 @@
 PATH_T to = { to.p_path, "" };
 
 uid_t myuid;
-int Rflag, fflag, iflag, pflag, rflag;
+int Rflag, fflag, iflag, pflag, rflag, vflag;
 mode_t myumask;
 
 enum op { FILE_TO_FILE, FILE_TO_DIR, DIR_TO_DNE };
@@ -88,7 +88,7 @@ main(int argc, char *argv[])
        char *target;
 
        Hflag = Lflag = Pflag = Rflag = 0;
-       while ((ch = getopt(argc, argv, "HLPRfipr")) != -1)
+       while ((ch = getopt(argc, argv, "HLPRfiprv")) != -1)
                switch (ch) {
                case 'H':
                        Hflag = 1;
@@ -119,6 +119,9 @@ main(int argc, char *argv[])
                case 'r':
                        rflag = 1;
                        break;
+               case 'v':
+                       vflag = 1;
+                       break;
                default:
                        usage();
                        break;
@@ -394,6 +397,9 @@ copy(char *argv[], enum op type, int fts_options)
                case S_IFLNK:
                        if (copy_link(curr, !fts_dne(curr)))
                                rval = 1;
+                       else if (vflag)
+                               (void)fprintf(stdout, "%s -> %s\n",
+                                   curr->fts_path, to.p_path);
                        break;
                case S_IFDIR:
                        if (!Rflag && !rflag) {
@@ -415,6 +421,9 @@ copy(char *argv[], enum op type, int fts_options)
                                if (mkdir(to.p_path,
                                    curr->fts_statp->st_mode | S_IRWXU) < 0)
                                        err(1, "%s", to.p_path);
+                               else if (vflag)
+                                       (void)fprintf(stdout, "%s -> %s\n",
+                                           curr->fts_path, to.p_path);
                        } else if (!S_ISDIR(to_stat.st_mode))
                                errc(1, ENOTDIR, "%s", to.p_path);
                        break;
@@ -426,6 +435,9 @@ copy(char *argv[], enum op type, int fts_options)
                        } else
                                if (copy_file(curr, fts_dne(curr)))
                                        rval = 1;
+                       if (!rval && vflag)
+                               (void)fprintf(stdout, "%s -> %s\n",
+                                   curr->fts_path, to.p_path);
                        break;
                case S_IFIFO:
                        if (Rflag) {
@@ -434,6 +446,9 @@ copy(char *argv[], enum op type, int fts_options)
                        } else
                                if (copy_file(curr, fts_dne(curr)))
                                        rval = 1;
+                       if (!rval && vflag)
+                               (void)fprintf(stdout, "%s -> %s\n",
+                                   curr->fts_path, to.p_path);
                        break;
                case S_IFSOCK:
                        warnc(EOPNOTSUPP, "%s", curr->fts_path);
@@ -441,6 +456,9 @@ copy(char *argv[], enum op type, int fts_options)
                default:
                        if (copy_file(curr, fts_dne(curr)))
                                rval = 1;
+                       else if (vflag)
+                               (void)fprintf(stdout, "%s -> %s\n",
+                                       curr->fts_path, to.p_path);
                        break;
                }
        }
diff --git bin/cp/utils.c bin/cp/utils.c
index 6a3c5178647..2189dd4be1f 100644
--- bin/cp/utils.c
+++ bin/cp/utils.c
@@ -307,9 +307,9 @@ void
 usage(void)
 {
        (void)fprintf(stderr,
-           "usage: %s [-fip] [-R [-H | -L | -P]] source target\n", __progname);
+           "usage: %s [-fipv] [-R [-H | -L | -P]] source target\n", 
__progname);
        (void)fprintf(stderr,
-           "       %s [-fip] [-R [-H | -L | -P]] source ... directory\n",
+           "       %s [-fipv] [-R [-H | -L | -P]] source ... directory\n",
            __progname);
        exit(1);
 }
diff --git bin/mv/mv.1 bin/mv/mv.1
index cb6c9d92673..9d782b71a33 100644
--- bin/mv/mv.1
+++ bin/mv/mv.1
@@ -103,6 +103,8 @@ The
 option overrides any previous
 .Fl f
 options.
+.It Fl v
+Display the source and destination after each move.
 .El
 .Pp
 The
diff --git bin/mv/mv.c bin/mv/mv.c
index 003aca59e87..8ce76a2eed8 100644
--- bin/mv/mv.c
+++ bin/mv/mv.c
@@ -51,7 +51,7 @@
 
 extern char *__progname;
 
-int fflg, iflg;
+int fflg, iflg, vflg;
 int stdin_ok;
 
 extern int cpmain(int argc, char **argv);
@@ -71,7 +71,7 @@ main(int argc, char *argv[])
        int ch;
        char path[PATH_MAX];
 
-       while ((ch = getopt(argc, argv, "if")) != -1)
+       while ((ch = getopt(argc, argv, "ifv")) != -1)
                switch (ch) {
                case 'i':
                        fflg = 0;
@@ -81,6 +81,9 @@ main(int argc, char *argv[])
                        iflg = 0;
                        fflg = 1;
                        break;
+               case 'v':
+                       vflg = 1;
+                       break;
                default:
                        usage();
                }
@@ -208,8 +211,11 @@ do_move(char *from, char *to)
         *      message to standard error, and do nothing more with the
         *      current source file...
         */
-       if (!rename(from, to))
+       if (!rename(from, to)) {
+               if (vflg)
+                       (void)fprintf(stdout, "%s -> %s\n", from, to);
                return (0);
+       }
 
        if (errno != EXDEV) {
                warn("rename %s to %s", from, to);
@@ -339,6 +345,10 @@ err:               if (unlink(to))
                warn("%s: remove", from);
                return (1);
        }
+
+       if (vflg)
+               (void)fprintf(stdout, "%s -> %s\n", from, to);
+
        return (0);
 }
 
@@ -362,14 +372,23 @@ mvcopy(char *from, char *to)
                _exit(1);
        }
 
+       /*
+        * XXX
+        * The external cpmain(), rmmain() approach (to avoid
+        * fork+exec) hides some of the details on what was moved.
+        * This can be improved upon during a refactor.
+        */
+       if (vflg)
+               (void)fprintf(stdout, "%s -> %s\n", from, to);
+
        return (0);
 }
 
 void
 usage(void)
 {
-       (void)fprintf(stderr, "usage: %s [-fi] source target\n", __progname);
-       (void)fprintf(stderr, "       %s [-fi] source ... directory\n",
+       (void)fprintf(stderr, "usage: %s [-fiv] source target\n", __progname);
+       (void)fprintf(stderr, "       %s [-fiv] source ... directory\n",
            __progname);
        exit(1);
 }
diff --git bin/rm/rm.1 bin/rm/rm.1
index 5c8aefaab7d..0170db1107e 100644
--- bin/rm/rm.1
+++ bin/rm/rm.1
@@ -95,6 +95,8 @@ that directory is skipped.
 .It Fl r
 Equivalent to
 .Fl R .
+.It Fl v
+Display each file name after it was removed.
 .El
 .Pp
 The
@@ -148,7 +150,7 @@ utility is compliant with the
 specification.
 .Pp
 The flags
-.Op Fl dP
+.Op Fl dPv
 are extensions to that specification.
 .Sh HISTORY
 An
diff --git bin/rm/rm.c bin/rm/rm.c
index 3242ef5f410..fc0904d0325 100644
--- bin/rm/rm.c
+++ bin/rm/rm.c
@@ -50,7 +50,7 @@
 
 extern char *__progname;
 
-int dflag, eval, fflag, iflag, Pflag, stdin_ok;
+int dflag, eval, fflag, iflag, Pflag, vflag, stdin_ok;
 
 int    check(char *, char *, struct stat *);
 void   checkdot(char **);
@@ -73,7 +73,7 @@ main(int argc, char *argv[])
        int ch, rflag;
 
        Pflag = rflag = 0;
-       while ((ch = getopt(argc, argv, "dfiPRr")) != -1)
+       while ((ch = getopt(argc, argv, "dfiPRrv")) != -1)
                switch(ch) {
                case 'd':
                        dflag = 1;
@@ -93,6 +93,9 @@ main(int argc, char *argv[])
                case 'r':                       /* Compatibility. */
                        rflag = 1;
                        break;
+               case 'v':
+                       vflag = 1;
+                       break;
                default:
                        usage();
                }
@@ -201,8 +204,11 @@ rm_tree(char **argv)
                case FTS_DP:
                case FTS_DNR:
                        if (!rmdir(p->fts_accpath) ||
-                           (fflag && errno == ENOENT))
+                           (fflag && errno == ENOENT)) {
+                               if (vflag)
+                                       (void)fprintf(stdout, "%s\n", 
p->fts_path);
                                continue;
+                       }
                        break;
 
                case FTS_F:
@@ -213,8 +219,11 @@ rm_tree(char **argv)
                        /* FALLTHROUGH */
                default:
                        if (!unlink(p->fts_accpath) ||
-                           (fflag && errno == ENOENT))
+                           (fflag && errno == ENOENT)) {
+                               if (vflag)
+                                       (void)fprintf(stdout, "%s\n", 
p->fts_path);
                                continue;
+                       }
                }
                warn("%s", p->fts_path);
                eval = 1;
@@ -262,7 +271,8 @@ rm_file(char **argv)
                if (rval && (!fflag || errno != ENOENT)) {
                        warn("%s", f);
                        eval = 1;
-               }
+               } else if (vflag)
+                       (void)fprintf(stdout, "%s\n", f);
        }
 }
 
@@ -430,6 +440,6 @@ skip:
 void
 usage(void)
 {
-       (void)fprintf(stderr, "usage: %s [-dfiPRr] file ...\n", __progname);
+       (void)fprintf(stderr, "usage: %s [-dfiPRrv] file ...\n", __progname);
        exit(1);
 }

Reply via email to