Module Name:    src
Committed By:   enami
Date:           Mon Mar  2 03:17:24 UTC 2015

Modified Files:
        src/bin/cp: utils.c
        src/bin/mv: mv.c
        src/sbin/restore: dirs.c tape.c
        src/usr.bin/touch: touch.c

Log Message:
Don't truncate at sub-microsecond while preserving timestamps.

One of motivation of this change is to make the behavior of test(1)
-nt/ot with preserved copy (like cp -p) closer to the NetBSD 6.
Of course whether full timestamps are kept or not depends also on
underlying file system.

The ifdef added in mv(1) since existing ifdefs was our local change
to compile it on solaris (though I couldn't test it):
http://mail-index.netbsd.org/tech-userlevel/2014/11/28/msg008831.html


To generate a diff of this commit:
cvs rdiff -u -r1.42 -r1.43 src/bin/cp/utils.c
cvs rdiff -u -r1.43 -r1.44 src/bin/mv/mv.c
cvs rdiff -u -r1.50 -r1.51 src/sbin/restore/dirs.c
cvs rdiff -u -r1.67 -r1.68 src/sbin/restore/tape.c
cvs rdiff -u -r1.32 -r1.33 src/usr.bin/touch/touch.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/bin/cp/utils.c
diff -u src/bin/cp/utils.c:1.42 src/bin/cp/utils.c:1.43
--- src/bin/cp/utils.c:1.42	Wed Dec 11 06:00:11 2013
+++ src/bin/cp/utils.c	Mon Mar  2 03:17:24 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: utils.c,v 1.42 2013/12/11 06:00:11 dholland Exp $ */
+/* $NetBSD: utils.c,v 1.43 2015/03/02 03:17:24 enami Exp $ */
 
 /*-
  * Copyright (c) 1991, 1993, 1994
@@ -34,7 +34,7 @@
 #if 0
 static char sccsid[] = "@(#)utils.c	8.3 (Berkeley) 4/1/94";
 #else
-__RCSID("$NetBSD: utils.c,v 1.42 2013/12/11 06:00:11 dholland Exp $");
+__RCSID("$NetBSD: utils.c,v 1.43 2015/03/02 03:17:24 enami Exp $");
 #endif
 #endif /* not lint */
 
@@ -62,12 +62,12 @@ __RCSID("$NetBSD: utils.c,v 1.42 2013/12
 int
 set_utimes(const char *file, struct stat *fs)
 {
-    static struct timeval tv[2];
+    struct timespec ts[2];
 
-    TIMESPEC_TO_TIMEVAL(&tv[0], &fs->st_atimespec);
-    TIMESPEC_TO_TIMEVAL(&tv[1], &fs->st_mtimespec);
+    ts[0] = fs->st_atimespec;
+    ts[1] = fs->st_mtimespec;
 
-    if (lutimes(file, tv)) {
+    if (lutimens(file, ts)) {
 	warn("lutimes: %s", file);
 	return (1);
     }

Index: src/bin/mv/mv.c
diff -u src/bin/mv/mv.c:1.43 src/bin/mv/mv.c:1.44
--- src/bin/mv/mv.c:1.43	Mon Aug 29 14:46:54 2011
+++ src/bin/mv/mv.c	Mon Mar  2 03:17:24 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: mv.c,v 1.43 2011/08/29 14:46:54 joerg Exp $ */
+/* $NetBSD: mv.c,v 1.44 2015/03/02 03:17:24 enami Exp $ */
 
 /*
  * Copyright (c) 1989, 1993, 1994
@@ -42,7 +42,7 @@ __COPYRIGHT("@(#) Copyright (c) 1989, 19
 #if 0
 static char sccsid[] = "@(#)mv.c	8.2 (Berkeley) 4/2/94";
 #else
-__RCSID("$NetBSD: mv.c,v 1.43 2011/08/29 14:46:54 joerg Exp $");
+__RCSID("$NetBSD: mv.c,v 1.44 2015/03/02 03:17:24 enami Exp $");
 #endif
 #endif /* not lint */
 
@@ -255,7 +255,11 @@ do_move(char *from, char *to)
 static int
 fastcopy(char *from, char *to, struct stat *sbp)
 {
+#if defined(__NetBSD__)
+	struct timespec ts[2];
+#else
 	struct timeval tval[2];
+#endif
 	static blksize_t blen;
 	static char *bp;
 	int nread, from_fd, to_fd;
@@ -296,8 +300,13 @@ err:		if (unlink(to))
 
 	(void)close(from_fd);
 #ifdef BSD4_4
+#if defined(__NetBSD__)
+	ts[0] = sbp->st_atimespec;
+	ts[1] = sbp->st_mtimespec;
+#else
 	TIMESPEC_TO_TIMEVAL(&tval[0], &sbp->st_atimespec);
 	TIMESPEC_TO_TIMEVAL(&tval[1], &sbp->st_mtimespec);
+#endif
 #else
 	tval[0].tv_sec = sbp->st_atime;
 	tval[1].tv_sec = sbp->st_mtime;
@@ -307,8 +316,12 @@ err:		if (unlink(to))
 #ifdef __SVR4
 	if (utimes(to, tval))
 #else
+#if defined(__NetBSD__)
+	if (futimens(to_fd, ts))
+#else
 	if (futimes(to_fd, tval))
 #endif
+#endif
 		warn("%s: set times", to);
 	if (fchown(to_fd, sbp->st_uid, sbp->st_gid)) {
 		if (errno != EPERM)

Index: src/sbin/restore/dirs.c
diff -u src/sbin/restore/dirs.c:1.50 src/sbin/restore/dirs.c:1.51
--- src/sbin/restore/dirs.c:1.50	Sun Jun  9 17:57:09 2013
+++ src/sbin/restore/dirs.c	Mon Mar  2 03:17:24 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: dirs.c,v 1.50 2013/06/09 17:57:09 dholland Exp $	*/
+/*	$NetBSD: dirs.c,v 1.51 2015/03/02 03:17:24 enami Exp $	*/
 
 /*
  * Copyright (c) 1983, 1993
@@ -39,7 +39,7 @@
 #if 0
 static char sccsid[] = "@(#)dirs.c	8.7 (Berkeley) 5/1/95";
 #else
-__RCSID("$NetBSD: dirs.c,v 1.50 2013/06/09 17:57:09 dholland Exp $");
+__RCSID("$NetBSD: dirs.c,v 1.51 2015/03/02 03:17:24 enami Exp $");
 #endif
 #endif /* not lint */
 
@@ -84,8 +84,8 @@ static struct inotab *inotab[HASHSIZE];
  */
 struct modeinfo {
 	ino_t ino;
-	struct timeval ctimep[2];
-	struct timeval mtimep[2];
+	struct timespec ctimep[2];
+	struct timespec mtimep[2];
 	mode_t mode;
 	uid_t uid;
 	gid_t gid;
@@ -625,8 +625,8 @@ setdirmodes(int flags)
 		} else {
 			if (!Nflag) {
 				cp = myname(ep);
-				(void) utimes(cp, node.ctimep);
-				(void) utimes(cp, node.mtimep);
+				(void) utimens(cp, node.ctimep);
+				(void) utimens(cp, node.mtimep);
 				(void) chown(cp, node.uid, node.gid);
 				(void) chmod(cp, node.mode);
 				if (Mtreefile) {
@@ -723,13 +723,13 @@ allocinotab(FILE *mf, struct context *ct
 		return (itp);
 	node.ino = ctxp->ino;
 	node.mtimep[0].tv_sec = ctxp->atime_sec;
-	node.mtimep[0].tv_usec = ctxp->atime_nsec / 1000;
+	node.mtimep[0].tv_nsec = ctxp->atime_nsec;
 	node.mtimep[1].tv_sec = ctxp->mtime_sec;
-	node.mtimep[1].tv_usec = ctxp->mtime_nsec / 1000;
+	node.mtimep[1].tv_nsec = ctxp->mtime_nsec;
 	node.ctimep[0].tv_sec = ctxp->atime_sec;
-	node.ctimep[0].tv_usec = ctxp->atime_nsec / 1000;
+	node.ctimep[0].tv_nsec = ctxp->atime_nsec;
 	node.ctimep[1].tv_sec = ctxp->birthtime_sec;
-	node.ctimep[1].tv_usec = ctxp->birthtime_nsec / 1000;
+	node.ctimep[1].tv_nsec = ctxp->birthtime_nsec;
 	node.mode = ctxp->mode;
 	node.flags = ctxp->file_flags;
 	node.uid = ctxp->uid;

Index: src/sbin/restore/tape.c
diff -u src/sbin/restore/tape.c:1.67 src/sbin/restore/tape.c:1.68
--- src/sbin/restore/tape.c:1.67	Tue Jan 22 09:39:13 2013
+++ src/sbin/restore/tape.c	Mon Mar  2 03:17:24 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: tape.c,v 1.67 2013/01/22 09:39:13 dholland Exp $	*/
+/*	$NetBSD: tape.c,v 1.68 2015/03/02 03:17:24 enami Exp $	*/
 
 /*
  * Copyright (c) 1983, 1993
@@ -39,7 +39,7 @@
 #if 0
 static char sccsid[] = "@(#)tape.c	8.9 (Berkeley) 5/1/95";
 #else
-__RCSID("$NetBSD: tape.c,v 1.67 2013/01/22 09:39:13 dholland Exp $");
+__RCSID("$NetBSD: tape.c,v 1.68 2015/03/02 03:17:24 enami Exp $");
 #endif
 #endif /* not lint */
 
@@ -624,24 +624,24 @@ extractfile(char *name)
 	uid_t uid;
 	gid_t gid;
 	mode_t mode;
-	struct timeval mtimep[2], ctimep[2];
+	struct timespec mtimep[2], ctimep[2];
 	struct entry *ep;
 	int setbirth;
 
 	curfile.name = name;
 	curfile.action = USING;
 	mtimep[0].tv_sec = curfile.atime_sec;
-	mtimep[0].tv_usec = curfile.atime_nsec / 1000;
+	mtimep[0].tv_nsec = curfile.atime_nsec;
 	mtimep[1].tv_sec = curfile.mtime_sec;
-	mtimep[1].tv_usec = curfile.mtime_nsec / 1000;
+	mtimep[1].tv_nsec = curfile.mtime_nsec;
 
 	setbirth = curfile.birthtime_sec != 0;
 
 	if (setbirth) {
 		ctimep[0].tv_sec = curfile.atime_sec;
-		ctimep[0].tv_usec = curfile.atime_nsec / 1000;
+		ctimep[0].tv_nsec = curfile.atime_nsec;
 		ctimep[1].tv_sec = curfile.birthtime_sec;
-		ctimep[1].tv_usec = curfile.birthtime_nsec / 1000;
+		ctimep[1].tv_nsec = curfile.birthtime_nsec;
 	}
 	uid = curfile.uid;
 	gid = curfile.gid;
@@ -683,8 +683,8 @@ extractfile(char *name)
 			(void) unlink(name);
 		if (linkit(lnkbuf, name, SYMLINK) == GOOD) {
 			if (setbirth)
-				(void) lutimes(name, ctimep);
-			(void) lutimes(name, mtimep);
+				(void) lutimens(name, ctimep);
+			(void) lutimens(name, mtimep);
 			(void) lchown(name, uid, gid);
 			(void) lchmod(name, mode);
 			if (Mtreefile) {
@@ -714,8 +714,8 @@ extractfile(char *name)
 		}
 		skipfile();
 		if (setbirth)
-			(void) utimes(name, ctimep);
-		(void) utimes(name, mtimep);
+			(void) utimens(name, ctimep);
+		(void) utimens(name, mtimep);
 		(void) chown(name, uid, gid);
 		(void) chmod(name, mode);
 		if (Mtreefile) {
@@ -743,8 +743,8 @@ extractfile(char *name)
 		}
 		skipfile();
 		if (setbirth)
-			(void) utimes(name, ctimep);
-		(void) utimes(name, mtimep);
+			(void) utimens(name, ctimep);
+		(void) utimens(name, mtimep);
 		(void) chown(name, uid, gid);
 		(void) chmod(name, mode);
 		if (Mtreefile) {
@@ -779,8 +779,8 @@ extractfile(char *name)
 		if (Nflag)
 			return (GOOD);
 		if (setbirth)
-			(void) futimes(ofile, ctimep);
-		(void) futimes(ofile, mtimep);
+			(void) futimens(ofile, ctimep);
+		(void) futimens(ofile, mtimep);
 		(void) fchown(ofile, uid, gid);
 		(void) fchmod(ofile, mode);
 		if (Mtreefile) {

Index: src/usr.bin/touch/touch.c
diff -u src/usr.bin/touch/touch.c:1.32 src/usr.bin/touch/touch.c:1.33
--- src/usr.bin/touch/touch.c:1.32	Mon Oct 22 21:51:58 2012
+++ src/usr.bin/touch/touch.c	Mon Mar  2 03:17:24 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: touch.c,v 1.32 2012/10/22 21:51:58 christos Exp $	*/
+/*	$NetBSD: touch.c,v 1.33 2015/03/02 03:17:24 enami Exp $	*/
 
 /*
  * Copyright (c) 1993
@@ -39,7 +39,7 @@ __COPYRIGHT("@(#) Copyright (c) 1993\
 #if 0
 static char sccsid[] = "@(#)touch.c	8.2 (Berkeley) 4/28/95";
 #endif
-__RCSID("$NetBSD: touch.c,v 1.32 2012/10/22 21:51:58 christos Exp $");
+__RCSID("$NetBSD: touch.c,v 1.33 2015/03/02 03:17:24 enami Exp $");
 #endif /* not lint */
 
 #include <sys/types.h>
@@ -59,10 +59,10 @@ __RCSID("$NetBSD: touch.c,v 1.32 2012/10
 #include <util.h>
 #include <getopt.h>
 
-static void	stime_arg0(char *, struct timeval *);
-static void	stime_arg1(char *, struct timeval *);
-static void	stime_arg2(char *, int, struct timeval *);
-static void	stime_file(char *, struct timeval *);
+static void	stime_arg0(char *, struct timespec *);
+static void	stime_arg1(char *, struct timespec *);
+static void	stime_arg2(char *, int, struct timespec *);
+static void	stime_file(char *, struct timespec *);
 __dead static void	usage(void);
 
 struct option touch_longopts[] = {
@@ -78,17 +78,17 @@ int
 main(int argc, char *argv[])
 {
 	struct stat sb;
-	struct timeval tv[2];
+	struct timespec ts[2];
 	int aflag, cflag, hflag, mflag, ch, fd, len, rval, timeset;
 	char *p;
-	int (*change_file_times)(const char *, const struct timeval *);
+	int (*change_file_times)(const char *, const struct timespec *);
 	int (*get_file_status)(const char *, struct stat *);
 
 	setlocale(LC_ALL, "");
 
 	aflag = cflag = hflag = mflag = timeset = 0;
-	if (gettimeofday(&tv[0], NULL))
-		err(1, "gettimeofday");
+	if (clock_gettime(CLOCK_REALTIME, &ts[0]))
+		err(1, "clock_gettime");
 
 	while ((ch = getopt_long(argc, argv, "acd:fhmr:t:", touch_longopts,
 	    NULL)) != -1)
@@ -101,7 +101,7 @@ main(int argc, char *argv[])
 			break;
 		case 'd':
 			timeset = 1;
-			stime_arg0(optarg, tv);
+			stime_arg0(optarg, ts);
 			break;
 		case 'f':
 			break;
@@ -113,11 +113,11 @@ main(int argc, char *argv[])
 			break;
 		case 'r':
 			timeset = 1;
-			stime_file(optarg, tv);
+			stime_file(optarg, ts);
 			break;
 		case 't':
 			timeset = 1;
-			stime_arg1(optarg, tv);
+			stime_arg1(optarg, ts);
 			break;
 		case '?':
 		default:
@@ -132,10 +132,10 @@ main(int argc, char *argv[])
 
 	if (hflag) {
 		cflag = 1;		/* Don't create new file */
-		change_file_times = lutimes;
+		change_file_times = lutimens;
 		get_file_status = lstat;
 	} else {
-		change_file_times = utimes;
+		change_file_times = utimens;
 		get_file_status = stat;
 	}
 
@@ -148,13 +148,13 @@ main(int argc, char *argv[])
 		len = p - argv[0];
 		if (*p == '\0' && (len == 8 || len == 10)) {
 			timeset = 1;
-			stime_arg2(*argv++, len == 10, tv);
+			stime_arg2(*argv++, len == 10, ts);
 		}
 	}
 
 	/* Otherwise use the current time of day. */
 	if (!timeset)
-		tv[1] = tv[0];
+		ts[1] = ts[0];
 
 	if (*argv == NULL)
 		usage();
@@ -179,12 +179,12 @@ main(int argc, char *argv[])
 				continue;
 		}
 		if (!aflag)
-			TIMESPEC_TO_TIMEVAL(&tv[0], &sb.st_atimespec);
+			ts[0] = sb.st_atimespec;
 		if (!mflag)
-			TIMESPEC_TO_TIMEVAL(&tv[1], &sb.st_mtimespec);
+			ts[1] = sb.st_mtimespec;
 
 		/* Try utimes(2). */
-		if (!(*change_file_times)(*argv, tv))
+		if (!(*change_file_times)(*argv, ts))
 			continue;
 
 		/* If the user specified a time, nothing else we can do. */
@@ -211,23 +211,23 @@ main(int argc, char *argv[])
 #define	ATOI2(s)	((s) += 2, ((s)[-2] - '0') * 10 + ((s)[-1] - '0'))
 
 static void
-stime_arg0(char *arg, struct timeval *tvp)
+stime_arg0(char *arg, struct timespec *tsp)
 {
-	tvp[1].tv_sec = tvp[0].tv_sec = parsedate(arg, NULL, NULL);
-	if (tvp[0].tv_sec == -1)
+	tsp[1].tv_sec = tsp[0].tv_sec = parsedate(arg, NULL, NULL);
+	if (tsp[0].tv_sec == -1)
 		errx(EXIT_FAILURE, "Could not parse `%s'", arg);
-	tvp[0].tv_usec = tvp[1].tv_usec = 0;
+	tsp[0].tv_nsec = tsp[1].tv_nsec = 0;
 }
 
 static void
-stime_arg1(char *arg, struct timeval *tvp)
+stime_arg1(char *arg, struct timespec *tsp)
 {
 	struct tm *t;
 	time_t tmptime;
 	int yearset;
 	char *p;
 					/* Start with the current time. */
-	tmptime = tvp[0].tv_sec;
+	tmptime = tsp[0].tv_sec;
 	if ((t = localtime(&tmptime)) == NULL)
 		err(EXIT_FAILURE, "localtime");
 					/* [[CC]YY]MMDDhhmm[.SS] */
@@ -275,21 +275,21 @@ stime_arg1(char *arg, struct timeval *tv
 	}
 
 	t->tm_isdst = -1;		/* Figure out DST. */
-	tvp[0].tv_sec = tvp[1].tv_sec = mktime(t);
-	if (tvp[0].tv_sec == -1)
+	tsp[0].tv_sec = tsp[1].tv_sec = mktime(t);
+	if (tsp[0].tv_sec == -1)
 terr:		errx(EXIT_FAILURE,
 	"out of range or illegal time specification: [[CC]YY]MMDDhhmm[.SS]");
 
-	tvp[0].tv_usec = tvp[1].tv_usec = 0;
+	tsp[0].tv_nsec = tsp[1].tv_nsec = 0;
 }
 
 static void
-stime_arg2(char *arg, int year, struct timeval *tvp)
+stime_arg2(char *arg, int year, struct timespec *tsp)
 {
 	struct tm *t;
 	time_t tmptime;
 					/* Start with the current time. */
-	tmptime = tvp[0].tv_sec;
+	tmptime = tsp[0].tv_sec;
 	if ((t = localtime(&tmptime)) == NULL)
 		err(EXIT_FAILURE, "localtime");
 
@@ -308,23 +308,23 @@ stime_arg2(char *arg, int year, struct t
 	t->tm_sec = 0;
 
 	t->tm_isdst = -1;		/* Figure out DST. */
-	tvp[0].tv_sec = tvp[1].tv_sec = mktime(t);
-	if (tvp[0].tv_sec == -1)
+	tsp[0].tv_sec = tsp[1].tv_sec = mktime(t);
+	if (tsp[0].tv_sec == -1)
 		errx(EXIT_FAILURE,
 	"out of range or illegal time specification: MMDDhhmm[yy]");
 
-	tvp[0].tv_usec = tvp[1].tv_usec = 0;
+	tsp[0].tv_nsec = tsp[1].tv_nsec = 0;
 }
 
 static void
-stime_file(char *fname, struct timeval *tvp)
+stime_file(char *fname, struct timespec *tsp)
 {
 	struct stat sb;
 
 	if (stat(fname, &sb))
 		err(1, "%s", fname);
-	TIMESPEC_TO_TIMEVAL(&tvp[0], &sb.st_atimespec);
-	TIMESPEC_TO_TIMEVAL(&tvp[1], &sb.st_mtimespec);
+	tsp[0] = sb.st_atimespec;
+	tsp[1] = sb.st_mtimespec;
 }
 
 static void

Reply via email to