Although mv(1) will preserve atime and mtime for moved directories if
moved to a different file system, it doesn't preserve them when moved
in the same file system. Upon looking around, it appears to be standard
POSIX behavior, as the utility is meant to perform a rename() and exit.

This patch adds a "-p" flag as an extension to allow preserving the
time stamps, whilst allowing mv(1) to retain POSIX behaviour without
the flag.

I am not too sure about my man page wording though.

Index: bin/mv/mv.1
===================================================================
RCS file: /cvs/src/bin/mv/mv.1,v
retrieving revision 1.31
diff -u -p -r1.31 mv.1
--- bin/mv/mv.1 18 Jun 2012 23:41:13 -0000      1.31
+++ bin/mv/mv.1 7 Apr 2017 02:16:54 -0000
@@ -41,10 +41,10 @@
 .Nd move files
 .Sh SYNOPSIS
 .Nm mv
-.Op Fl fi
+.Op Fl fip
 .Ar source target
 .Nm mv
-.Op Fl fi
+.Op Fl fip
 .Ar source ... directory
 .Sh DESCRIPTION
 In its first form, the
@@ -103,6 +103,9 @@ The
 option overrides any previous
 .Fl f
 options.
+.It Fl p
+Preserve the modification and access times for all objects. These time stamps
+are not always preserved for some objects (such as directories) by default.
 .El
 .Pp
 The
@@ -165,6 +168,10 @@ The
 utility is compliant with the
 .St -p1003.1-2008
 specification.
+.Pp
+The
+.Fl p
+flag is an extension to that specification.
 .Sh HISTORY
 A
 .Nm
Index: bin/mv/mv.c
===================================================================
RCS file: /cvs/src/bin/mv/mv.c,v
retrieving revision 1.44
diff -u -p -r1.44 mv.c
--- bin/mv/mv.c 11 Oct 2016 16:16:44 -0000      1.44
+++ bin/mv/mv.c 7 Apr 2017 02:16:54 -0000
@@ -52,6 +52,7 @@
 extern char *__progname;
 
 int fflg, iflg;
+int pflg = 0;
 int stdin_ok;
 
 extern int cpmain(int argc, char **argv);
@@ -71,7 +72,7 @@ main(int argc, char *argv[])
        int ch;
        char path[PATH_MAX];
 
-       while ((ch = getopt(argc, argv, "if")) != -1)
+       while ((ch = getopt(argc, argv, "ifp")) != -1)
                switch (ch) {
                case 'i':
                        fflg = 0;
@@ -81,6 +82,9 @@ main(int argc, char *argv[])
                        iflg = 0;
                        fflg = 1;
                        break;
+               case 'p':
+                       pflg = 1;
+                       break;
                default:
                        usage();
                }
@@ -208,8 +212,22 @@ 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)) {
+               /*
+                * Extension to (2): If -p is specified, copy the atime and 
mtime
+                * as this is not always done with rename() for certain objects.
+                */
+               if(pflg) {
+                       struct timespec ts[2];
+                       ts[0] = fsb.st_atim;
+                       ts[1] = fsb.st_mtim;
+                       if (utimensat(AT_FDCWD, to, ts, AT_SYMLINK_NOFOLLOW)) {
+                               warn("update times: %s", to);
+                               return (1);
+                       }
+               }
                return (0);
+       }
 
        if (errno != EXDEV) {
                warn("rename %s to %s", from, to);
@@ -368,8 +386,8 @@ mvcopy(char *from, char *to)
 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 [-fip] source target\n", __progname);
+       (void)fprintf(stderr, "       %s [-fip] source ... directory\n",
            __progname);
        exit(1);
 }

Reply via email to