summaryrefslogtreecommitdiffstats
path: root/usr.bin/touch
diff options
context:
space:
mode:
authorjilles <jilles@FreeBSD.org>2015-02-15 21:28:00 +0000
committerjilles <jilles@FreeBSD.org>2015-02-15 21:28:00 +0000
commite751f888a0a8701c0797b39e00ebe4beca4b8192 (patch)
treef69a8ee4347d34f3cd3a776c4d3fd1330fc4b1cb /usr.bin/touch
parentcf9516e251f044191dcf92fec3dcfca3451a8567 (diff)
downloadFreeBSD-src-e751f888a0a8701c0797b39e00ebe4beca4b8192.zip
FreeBSD-src-e751f888a0a8701c0797b39e00ebe4beca4b8192.tar.gz
touch: Fix some subtle bugs related to NULL times fallback:
* Do not subvert vfs.timestamp_precision by reading the time and passing that to utimensat(). Instead, pass UTIME_NOW. A fallback to a NULL times pointer is no longer used. * Do not ignore -a/-m if the user has write access but does not own the file. Leave timestamps unchanged using UTIME_OMIT and do not fall back to a NULL times pointer (which would set both timestamps) if that fails. Reviewed by: bde
Diffstat (limited to 'usr.bin/touch')
-rw-r--r--usr.bin/touch/touch.c39
1 files changed, 11 insertions, 28 deletions
diff --git a/usr.bin/touch/touch.c b/usr.bin/touch/touch.c
index c8bfd28..804af7e 100644
--- a/usr.bin/touch/touch.c
+++ b/usr.bin/touch/touch.c
@@ -76,8 +76,8 @@ main(int argc, char *argv[])
myname = basename(argv[0]);
Aflag = aflag = cflag = mflag = timeset = 0;
atflag = 0;
- if (clock_gettime(CLOCK_REALTIME, &ts[0]) == -1)
- err(1, "clock_gettime(CLOCK_REALTIME)");
+ ts[0].tv_sec = ts[1].tv_sec = 0;
+ ts[0].tv_nsec = ts[1].tv_nsec = UTIME_NOW;
while ((ch = getopt(argc, argv, "A:acd:fhmr:t:")) != -1)
switch(ch) {
@@ -152,6 +152,11 @@ main(int argc, char *argv[])
ts[1] = ts[0];
}
+ if (!aflag)
+ ts[0].tv_nsec = UTIME_OMIT;
+ if (!mflag)
+ ts[1].tv_nsec = UTIME_OMIT;
+
if (*argv == NULL)
usage(myname);
@@ -183,11 +188,6 @@ main(int argc, char *argv[])
continue;
}
- if (!aflag)
- ts[0] = sb.st_atim;
- if (!mflag)
- ts[1] = sb.st_mtim;
-
/*
* We're adjusting the times based on the file times, not a
* specified time (that gets handled above).
@@ -203,26 +203,9 @@ main(int argc, char *argv[])
}
}
- /* Try utimensat(2). */
if (!utimensat(AT_FDCWD, *argv, ts, atflag))
continue;
- /* If the user specified a time, nothing else we can do. */
- if (timeset || Aflag) {
- rval = 1;
- warn("%s", *argv);
- continue;
- }
-
- /*
- * System V and POSIX 1003.1 require that a NULL argument
- * set the access/modification times to the current time.
- * The permission checks are different, too, in that the
- * ability to write the file is sufficient. Take a shot.
- */
- if (!utimensat(AT_FDCWD, *argv, NULL, atflag))
- continue;
-
rval = 1;
warn("%s", *argv);
}
@@ -238,8 +221,8 @@ stime_arg1(const char *arg, struct timespec *tvp)
struct tm *t;
int yearset;
char *p;
- /* Start with the current time. */
- now = tvp[0].tv_sec;
+
+ now = time(NULL);
if ((t = localtime(&now)) == NULL)
err(1, "localtime");
/* [[CC]YY]MMDDhhmm[.SS] */
@@ -300,8 +283,8 @@ stime_arg2(const char *arg, int year, struct timespec *tvp)
{
time_t now;
struct tm *t;
- /* Start with the current time. */
- now = tvp[0].tv_sec;
+
+ now = time(NULL);
if ((t = localtime(&now)) == NULL)
err(1, "localtime");
OpenPOWER on IntegriCloud