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); }