The diff below adds support to various utilities to preserve timestamps to
the nanosecond. Most of them already preserve down to microseconds and
this just makes them preserve the nanoseconds part too. That might seem
pointless but failure to do that can confuse programs when, for example,
"cp -p" leaves the output file as *older* than the input after the bottom
bits of the timestamp get zeroed.
As a bonus, it generally makes the code simpler by removing uses of
TIMESPEC_TO_TIMEVAL().
oks?
Philip
5~
Index: bin/cp/utils.c
===================================================================
RCS file: /cvs/src/bin/cp/utils.c,v
retrieving revision 1.31
diff -u -p -r1.31 utils.c
--- bin/cp/utils.c 23 Jun 2011 11:43:13 -0000 1.31
+++ bin/cp/utils.c 18 Aug 2011 01:20:27 -0000
@@ -251,16 +251,16 @@ copy_special(struct stat *from_stat, int
int
setfile(struct stat *fs, int fd)
{
- static struct timeval tv[2];
+ struct timespec ts[2];
int rval;
rval = 0;
fs->st_mode &= S_ISTXT | S_ISUID | S_ISGID | S_IRWXU | S_IRWXG |
S_IRWXO;
- TIMESPEC_TO_TIMEVAL(&tv[0], &fs->st_atimespec);
- TIMESPEC_TO_TIMEVAL(&tv[1], &fs->st_mtimespec);
- if (utimes(to.p_path, tv)) {
- warn("utimes: %s", to.p_path);
+ ts[0] = fs->st_atim;
+ ts[1] = fs->st_mtim;
+ if (utimensat(AT_FDCWD, to.p_path, ts, AT_SYMLINK_NOFOLLOW)) {
+ warn("utimensat: %s", to.p_path);
rval = 1;
}
/*
Index: bin/mv/mv.c
===================================================================
RCS file: /cvs/src/bin/mv/mv.c,v
retrieving revision 1.35
diff -u -p -r1.35 mv.c
--- bin/mv/mv.c 27 Oct 2009 23:59:22 -0000 1.35
+++ bin/mv/mv.c 18 Aug 2011 01:20:27 -0000
@@ -254,7 +254,7 @@ do_move(char *from, char *to)
int
fastcopy(char *from, char *to, struct stat *sbp)
{
- struct timeval tval[2];
+ struct timespec ts[2];
static u_int32_t blen;
static char *bp;
int nread, from_fd, to_fd;
@@ -323,9 +323,9 @@ err: if (unlink(to))
if (errno != EOPNOTSUPP || sbp->st_flags != 0)
warn("%s: set flags", to);
- TIMESPEC_TO_TIMEVAL(&tval[0], &sbp->st_atimespec);
- TIMESPEC_TO_TIMEVAL(&tval[1], &sbp->st_mtimespec);
- if (utimes(to, tval))
+ ts[0] = sbp->st_atim;
+ ts[1] = sbp->st_mtim;
+ if (futimens(to_fd, ts))
warn("%s: set times", to);
if (close(to_fd)) {
Index: usr.bin/compress/main.c
===================================================================
RCS file: /cvs/src/usr.bin/compress/main.c,v
retrieving revision 1.77
diff -u -p -r1.77 main.c
--- usr.bin/compress/main.c 5 Mar 2011 20:12:42 -0000 1.77
+++ usr.bin/compress/main.c 18 Aug 2011 01:20:28 -0000
@@ -733,7 +733,7 @@ dodecompress(const char *in, char *out,
void
setfile(const char *name, int fd, struct stat *fs)
{
- struct timeval tv[2];
+ struct timespec ts[2];
if (name == NULL || cat || testmode)
return;
@@ -767,10 +767,10 @@ setfile(const char *name, int fd, struct
if (fs->st_flags && fchflags(fd, fs->st_flags))
warn("fchflags: %s", name);
- TIMESPEC_TO_TIMEVAL(&tv[0], &fs->st_atimespec);
- TIMESPEC_TO_TIMEVAL(&tv[1], &fs->st_mtimespec);
- if (futimes(fd, tv))
- warn("futimes: %s", name);
+ ts[0] = fs->st_atim;
+ ts[1] = fs->st_mtim;
+ if (futimens(fd, ts))
+ warn("futimens: %s", name);
}
int
Index: usr.bin/cvs/file.c
===================================================================
RCS file: /cvs/src/usr.bin/cvs/file.c,v
retrieving revision 1.262
diff -u -p -r1.262 file.c
--- usr.bin/cvs/file.c 28 Oct 2010 15:02:41 -0000 1.262
+++ usr.bin/cvs/file.c 18 Aug 2011 01:20:28 -0000
@@ -1066,8 +1066,7 @@ int
cvs_file_copy(const char *from, const char *to)
{
struct stat st;
- struct timeval tv[2];
- time_t atime, mtime;
+ struct timespec ts[2];
int src, dst, ret;
ret = 0;
@@ -1083,9 +1082,6 @@ cvs_file_copy(const char *from, const ch
if (fstat(src, &st) == -1)
fatal("cvs_file_copy: `%s': %s", from, strerror(errno));
- atime = st.st_atimespec.tv_sec;
- mtime = st.st_mtimespec.tv_sec;
-
if (S_ISREG(st.st_mode)) {
char *p;
int saved_errno;
@@ -1118,10 +1114,10 @@ cvs_file_copy(const char *from, const ch
(void)munmap(p, st.st_size);
- tv[0].tv_sec = atime;
- tv[1].tv_sec = mtime;
+ ts[0] = st.st_atim;
+ ts[1] = st.st_mtim;
- if (futimes(dst, tv) == -1) {
+ if (futimens(dst, ts) == -1) {
saved_errno = errno;
(void)unlink(to);
fatal("cvs_file_copy: futimes: %s",
Index: usr.bin/mail/aux.c
===================================================================
RCS file: /cvs/src/usr.bin/mail/aux.c,v
retrieving revision 1.25
diff -u -p -r1.25 aux.c
--- usr.bin/mail/aux.c 27 Oct 2009 23:59:40 -0000 1.25
+++ usr.bin/mail/aux.c 18 Aug 2011 01:20:29 -0000
@@ -31,6 +31,7 @@
*/
#include "rcv.h"
+#include <fcntl.h>
#include "extern.h"
/*
@@ -328,18 +329,14 @@ void
alter(char *name)
{
struct stat sb;
- struct timeval tv[2];
+ struct timespec ts[2];
if (stat(name, &sb))
return;
- (void) gettimeofday(&tv[0], (struct timezone *)0);
- tv[0].tv_sec++;
-#ifdef TIMESPEC_TO_TIMEVAL
- TIMESPEC_TO_TIMEVAL(&tv[1], &sb.st_mtimespec);
-#else
- tv[1].tv_sec = sb.st_mtime;
-#endif
- (void)utimes(name, tv);
+ clock_gettime(CLOCK_REALTIME, &ts[0]);
+ ts[0].tv_sec++;
+ ts[1] = sb.st_mtim;
+ (void)utimensat(AT_FDCWD, name, ts, 0);
}
/*
Index: usr.bin/xinstall/xinstall.c
===================================================================
RCS file: /cvs/src/usr.bin/xinstall/xinstall.c,v
retrieving revision 1.49
diff -u -p -r1.49 xinstall.c
--- usr.bin/xinstall/xinstall.c 27 Oct 2009 23:59:50 -0000 1.49
+++ usr.bin/xinstall/xinstall.c 18 Aug 2011 01:20:30 -0000
@@ -199,7 +199,7 @@ void
install(char *from_name, char *to_name, u_long fset, u_int flags)
{
struct stat from_sb, to_sb;
- struct utimbuf utb;
+ struct timespec ts[2];
int devnull, from_fd, to_fd, serrno, files_match = 0;
char *p;
@@ -310,9 +310,10 @@ install(char *from_name, char *to_name,
* Need to preserve target file times, though.
*/
if (to_sb.st_nlink != 1) {
- utb.actime = to_sb.st_atime;
- utb.modtime = to_sb.st_mtime;
- (void)utime(tempfile, &utb);
+ ts[0] = to_sb.st_atim;
+ ts[1] = to_sb.st_mtim;
+ (void)utimensat(AT_FDCWD, tempfile, ts,
+ AT_SYMLINK_NOFOLLOW);
} else {
files_match = 1;
(void)unlink(tempfile);
@@ -326,9 +327,10 @@ install(char *from_name, char *to_name,
* Preserve the timestamp of the source file if necessary.
*/
if (dopreserve && !files_match) {
- utb.actime = from_sb.st_atime;
- utb.modtime = from_sb.st_mtime;
- (void)utime(safecopy ? tempfile : to_name, &utb);
+ ts[0] = from_sb.st_atim;
+ ts[1] = from_sb.st_mtim;
+ (void)utimensat(AT_FDCWD, safecopy ? tempfile : to_name,
+ ts, AT_SYMLINK_NOFOLLOW);
}
/*