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:
parent
8aae5c1e3e
commit
c1e351a1b2
|
@ -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);
|
||||
}
|
||||
|
|
17
bin/mv/mv.c
17
bin/mv/mv.c
|
@ -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)) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue