svn commit: r297782 - in stable/10: bin/cp bin/mv usr.bin/touch

Jilles Tjoelker jilles at FreeBSD.org
Sun Apr 10 15:02:30 UTC 2016


Author: jilles
Date: Sun Apr 10 15:02:29 2016
New Revision: 297782
URL: https://svnweb.freebsd.org/changeset/base/297782

Log:
  MFC r277645: cp,mv,touch: Set timestamps with nanosecond precision.
  
  This uses utimensat().

Modified:
  stable/10/bin/cp/utils.c
  stable/10/bin/mv/mv.c
  stable/10/usr.bin/touch/touch.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/bin/cp/utils.c
==============================================================================
--- stable/10/bin/cp/utils.c	Sun Apr 10 07:11:29 2016	(r297781)
+++ stable/10/bin/cp/utils.c	Sun Apr 10 15:02:29 2016	(r297782)
@@ -344,7 +344,7 @@ copy_special(struct stat *from_stat, int
 int
 setfile(struct stat *fs, int fd)
 {
-	static struct timeval tv[2];
+	static struct timespec tspec[2];
 	struct stat ts;
 	int rval, gotstat, islink, fdval;
 
@@ -354,10 +354,11 @@ setfile(struct stat *fs, int fd)
 	fs->st_mode &= S_ISUID | S_ISGID | S_ISVTX |
 	    S_IRWXU | S_IRWXG | S_IRWXO;
 
-	TIMESPEC_TO_TIMEVAL(&tv[0], &fs->st_atim);
-	TIMESPEC_TO_TIMEVAL(&tv[1], &fs->st_mtim);
-	if (islink ? lutimes(to.p_path, tv) : utimes(to.p_path, tv)) {
-		warn("%sutimes: %s", islink ? "l" : "", to.p_path);
+	tspec[0] = fs->st_atim;
+	tspec[1] = fs->st_mtim;
+	if (utimensat(AT_FDCWD, to.p_path, tspec,
+	    islink ? AT_SYMLINK_NOFOLLOW : 0)) {
+		warn("utimensat: %s", to.p_path);
 		rval = 1;
 	}
 	if (fdval ? fstat(fd, &ts) :

Modified: stable/10/bin/mv/mv.c
==============================================================================
--- stable/10/bin/mv/mv.c	Sun Apr 10 07:11:29 2016	(r297781)
+++ stable/10/bin/mv/mv.c	Sun Apr 10 15:02:29 2016	(r297782)
@@ -273,7 +273,7 @@ do_move(const char *from, const char *to
 static int
 fastcopy(const char *from, const char *to, struct stat *sbp)
 {
-	struct timeval tval[2];
+	struct timespec ts[2];
 	static u_int blen = MAXPHYS;
 	static char *bp = NULL;
 	mode_t oldmode;
@@ -341,10 +341,9 @@ err:		if (unlink(to))
 		if (errno != EOPNOTSUPP || sbp->st_flags != 0)
 			warn("%s: set flags (was: 0%07o)", to, sbp->st_flags);
 
-	tval[0].tv_sec = sbp->st_atime;
-	tval[1].tv_sec = sbp->st_mtime;
-	tval[0].tv_usec = tval[1].tv_usec = 0;
-	if (utimes(to, tval))
+	ts[0] = sbp->st_atim;
+	ts[1] = sbp->st_mtim;
+	if (utimensat(AT_FDCWD, to, ts, 0))
 		warn("%s: set times", to);
 
 	if (close(to_fd)) {

Modified: stable/10/usr.bin/touch/touch.c
==============================================================================
--- stable/10/usr.bin/touch/touch.c	Sun Apr 10 07:11:29 2016	(r297781)
+++ stable/10/usr.bin/touch/touch.c	Sun Apr 10 15:02:29 2016	(r297782)
@@ -56,10 +56,10 @@ static const char sccsid[] = "@(#)touch.
 #include <time.h>
 #include <unistd.h>
 
-static void	stime_arg1(const char *, struct timeval *);
-static void	stime_arg2(const char *, int, struct timeval *);
-static void	stime_darg(const char *, struct timeval *);
-static void	stime_file(const char *, struct timeval *);
+static void	stime_arg1(const char *, struct timespec *);
+static void	stime_arg2(const char *, int, struct timespec *);
+static void	stime_darg(const char *, struct timespec *);
+static void	stime_file(const char *, struct timespec *);
 static int	timeoffset(const char *);
 static void	usage(const char *);
 
@@ -67,19 +67,17 @@ int
 main(int argc, char *argv[])
 {
 	struct stat sb;
-	struct timeval tv[2];
-	int (*stat_f)(const char *, struct stat *);
-	int (*utimes_f)(const char *, const struct timeval *);
+	struct timespec ts[2];
+	int atflag;
 	int Aflag, aflag, cflag, mflag, ch, fd, len, rval, timeset;
 	char *p;
 	char *myname;
 
 	myname = basename(argv[0]);
 	Aflag = aflag = cflag = mflag = timeset = 0;
-	stat_f = stat;
-	utimes_f = utimes;
-	if (gettimeofday(&tv[0], NULL) == -1)
-		err(1, "gettimeofday");
+	atflag = 0;
+	if (clock_gettime(CLOCK_REALTIME, &ts[0]) == -1)
+		err(1, "clock_gettime(CLOCK_REALTIME)");
 
 	while ((ch = getopt(argc, argv, "A:acd:fhmr:t:")) != -1)
 		switch(ch) {
@@ -94,26 +92,25 @@ main(int argc, char *argv[])
 			break;
 		case 'd':
 			timeset = 1;
-			stime_darg(optarg, tv);
+			stime_darg(optarg, ts);
 			break;
 		case 'f':
 			/* No-op for compatibility. */
 			break;
 		case 'h':
 			cflag = 1;
-			stat_f = lstat;
-			utimes_f = lutimes;
+			atflag = AT_SYMLINK_NOFOLLOW;
 			break;
 		case 'm':
 			mflag = 1;
 			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;
 		default:
 			usage(myname);
@@ -132,9 +129,9 @@ main(int argc, char *argv[])
 			 * that time once and for all here.
 			 */
 			if (aflag)
-				tv[0].tv_sec += Aflag;
+				ts[0].tv_sec += Aflag;
 			if (mflag)
-				tv[1].tv_sec += Aflag;
+				ts[1].tv_sec += Aflag;
 			Aflag = 0;		/* done our job */
 		}
 	} else {
@@ -148,11 +145,11 @@ 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);
 			}
 		}
 		/* Both times default to the same. */
-		tv[1] = tv[0];
+		ts[1] = ts[0];
 	}
 
 	if (*argv == NULL)
@@ -163,7 +160,7 @@ main(int argc, char *argv[])
 
 	for (rval = 0; *argv; ++argv) {
 		/* See if the file exists. */
-		if (stat_f(*argv, &sb) != 0) {
+		if (fstatat(AT_FDCWD, *argv, &sb, atflag) != 0) {
 			if (errno != ENOENT) {
 				rval = 1;
 				warn("%s", *argv);
@@ -187,9 +184,9 @@ main(int argc, char *argv[])
 		}
 
 		if (!aflag)
-			TIMESPEC_TO_TIMEVAL(&tv[0], &sb.st_atim);
+			ts[0] = sb.st_atim;
 		if (!mflag)
-			TIMESPEC_TO_TIMEVAL(&tv[1], &sb.st_mtim);
+			ts[1] = sb.st_mtim;
 
 		/*
 		 * We're adjusting the times based on the file times, not a
@@ -197,17 +194,17 @@ main(int argc, char *argv[])
 		 */
 		if (Aflag) {
 			if (aflag) {
-				TIMESPEC_TO_TIMEVAL(&tv[0], &sb.st_atim);
-				tv[0].tv_sec += Aflag;
+				ts[0] = sb.st_atim;
+				ts[0].tv_sec += Aflag;
 			}
 			if (mflag) {
-				TIMESPEC_TO_TIMEVAL(&tv[1], &sb.st_mtim);
-				tv[1].tv_sec += Aflag;
+				ts[1] = sb.st_mtim;
+				ts[1].tv_sec += Aflag;
 			}
 		}
 
-		/* Try utimes(2). */
-		if (!utimes_f(*argv, tv))
+		/* Try utimensat(2). */
+		if (!utimensat(AT_FDCWD, *argv, ts, atflag))
 			continue;
 
 		/* If the user specified a time, nothing else we can do. */
@@ -223,7 +220,7 @@ main(int argc, char *argv[])
 		 * The permission checks are different, too, in that the
 		 * ability to write the file is sufficient.  Take a shot.
 		 */
-		 if (!utimes_f(*argv, NULL))
+		 if (!utimensat(AT_FDCWD, *argv, NULL, atflag))
 			continue;
 
 		rval = 1;
@@ -235,7 +232,7 @@ main(int argc, char *argv[])
 #define	ATOI2(ar)	((ar)[0] - '0') * 10 + ((ar)[1] - '0'); (ar) += 2;
 
 static void
-stime_arg1(const char *arg, struct timeval *tvp)
+stime_arg1(const char *arg, struct timespec *tvp)
 {
 	time_t now;
 	struct tm *t;
@@ -291,7 +288,7 @@ stime_arg1(const char *arg, struct timev
 	if (tvp[0].tv_sec == -1)
 		goto terr;
 
-	tvp[0].tv_usec = tvp[1].tv_usec = 0;
+	tvp[0].tv_nsec = tvp[1].tv_nsec = 0;
 	return;
 
 terr:
@@ -299,7 +296,7 @@ terr:
 }
 
 static void
-stime_arg2(const char *arg, int year, struct timeval *tvp)
+stime_arg2(const char *arg, int year, struct timespec *tvp)
 {
 	time_t now;
 	struct tm *t;
@@ -325,18 +322,18 @@ stime_arg2(const char *arg, int year, st
 		errx(1,
 	"out of range or illegal time specification: MMDDhhmm[yy]");
 
-	tvp[0].tv_usec = tvp[1].tv_usec = 0;
+	tvp[0].tv_nsec = tvp[1].tv_nsec = 0;
 }
 
 static void
-stime_darg(const char *arg, struct timeval *tvp)
+stime_darg(const char *arg, struct timespec *tvp)
 {
 	struct tm t = { .tm_sec = 0 };
 	const char *fmt, *colon;
 	char *p;
 	int val, isutc = 0;
 
-	tvp[0].tv_usec = 0;
+	tvp[0].tv_nsec = 0;
 	t.tm_isdst = -1;
 	colon = strchr(arg, ':');
 	if (colon == NULL || strchr(colon + 1, ':') == NULL)
@@ -349,9 +346,9 @@ stime_darg(const char *arg, struct timev
 	/* POSIX: must have at least one digit after dot */
 	if ((*p == '.' || *p == ',') && isdigit((unsigned char)p[1])) {
 		p++;
-		val = 100000;
+		val = 100000000;
 		while (isdigit((unsigned char)*p)) {
-			tvp[0].tv_usec += val * (*p - '0');
+			tvp[0].tv_nsec += val * (*p - '0');
 			p++;
 			val /= 10;
 		}
@@ -403,14 +400,14 @@ timeoffset(const char *arg)
 }
 
 static void
-stime_file(const char *fname, struct timeval *tvp)
+stime_file(const char *fname, struct timespec *tsp)
 {
 	struct stat sb;
 
 	if (stat(fname, &sb))
 		err(1, "%s", fname);
-	TIMESPEC_TO_TIMEVAL(tvp, &sb.st_atim);
-	TIMESPEC_TO_TIMEVAL(tvp + 1, &sb.st_mtim);
+	tsp[0] = sb.st_atim;
+	tsp[1] = sb.st_mtim;
 }
 
 static void


More information about the svn-src-all mailing list