Don't truncate at microseconds 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
This commit is contained in:
enami 2015-03-02 03:17:24 +00:00
parent 8aae5c1e3e
commit c1e351a1b2
5 changed files with 83 additions and 70 deletions

View File

@ -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/11 06:00:11 dholland Exp $");
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);
}

View File

@ -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, 1993, 1994\
#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;
@ -306,8 +315,12 @@ err: if (unlink(to))
#endif
#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)) {

View File

@ -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 *ctxp, long aseekpt)
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;

View File

@ -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) {

View File

@ -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/22 21:51:58 christos Exp $");
#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 *tvp)
}
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 timeval *tvp)
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