[Midnightbsd-cvs] src [8235] trunk/usr.bin/touch: touch: Add the -d option from POSIX.1-2008.
laffer1 at midnightbsd.org
laffer1 at midnightbsd.org
Sat Sep 17 17:27:46 EDT 2016
Revision: 8235
http://svnweb.midnightbsd.org/src/?rev=8235
Author: laffer1
Date: 2016-09-17 17:27:46 -0400 (Sat, 17 Sep 2016)
Log Message:
-----------
touch: Add the -d option from POSIX.1-2008.
This is much like -t but with a different format which is ISO8601-like and
allows fractions of a second.
The precision is limited to microseconds because of utimes() and friends,
even though stat() returns nanoseconds.
Modified Paths:
--------------
trunk/usr.bin/touch/touch.1
trunk/usr.bin/touch/touch.c
Modified: trunk/usr.bin/touch/touch.1
===================================================================
--- trunk/usr.bin/touch/touch.1 2016-09-17 21:26:57 UTC (rev 8234)
+++ trunk/usr.bin/touch/touch.1 2016-09-17 21:27:46 UTC (rev 8235)
@@ -31,7 +31,7 @@
.\" @(#)touch.1 8.3 (Berkeley) 4/28/95
.\" $MidnightBSD$
.\"
-.Dd April 28, 1995
+.Dd June 10, 2012
.Dt TOUCH 1
.Os
.Sh NAME
@@ -43,6 +43,7 @@
.Op Fl acfhm
.Op Fl r Ar file
.Op Fl t Ar [[CC]YY]MMDDhhmm[.SS]
+.Op Fl d Ar YYYY-MM-DDThh:mm:SS[.frac][tz]
.Ar
.Sh DESCRIPTION
The
@@ -61,8 +62,10 @@
Selecting both is equivalent to the default.
By default, the timestamps are set to the current time.
The
+.Fl d
+and
.Fl t
-flag explicitly specifies a different time, and the
+flags explicitly specify a different time, and the
.Fl r
flag specifies to set the times those of the specified file.
The
@@ -112,6 +115,41 @@
.It Fl f
Attempt to force the update, even if the file permissions do not
currently permit it.
+.It Fl d
+Change the access and modification times to the specified time instead
+of the current time of day.
+The argument is of the form
+.Dq YYYY-MM-DDThh:mm:SS[.frac][tz]
+where the letters represent the following:
+.Bl -tag -width Ds -compact -offset indent
+.It Ar YYYY
+The year.
+.It Ar MM
+The month of the year, from 01 to 12.
+.It Ar DD
+The day of the month, from 01 to 31.
+.It Ar T
+The letter
+.Li T
+or a space.
+.It Ar hh
+The hour of the day, from 00 to 23.
+.It Ar mm
+The minute of the hour, from 00 to 59.
+.It Ar SS
+The second of the minute, from 00 to 61.
+.It Ar .frac
+An optional fraction,
+consisting of a period or a comma followed by one or more digits.
+The number of significant digits depends on the kernel configuration and
+the filesystem, and may be zero.
+.It Ar tz
+An optional letter
+.Li Z
+indicating the time is in
+.Tn UTC .
+Otherwise, the time is assumed to be in local time.
+.El
.It Fl h
If the file is a symbolic link, change the times of the link
itself rather than the file that the link points to.
Modified: trunk/usr.bin/touch/touch.c
===================================================================
--- trunk/usr.bin/touch/touch.c 2016-09-17 21:26:57 UTC (rev 8234)
+++ trunk/usr.bin/touch/touch.c 2016-09-17 21:27:46 UTC (rev 8235)
@@ -45,6 +45,7 @@
#include <sys/stat.h>
#include <sys/time.h>
+#include <ctype.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
@@ -58,6 +59,7 @@
int rw(char *, struct stat *, int);
void stime_arg1(char *, struct timeval *);
void stime_arg2(char *, int, struct timeval *);
+void stime_darg(char *, struct timeval *);
void stime_file(char *, struct timeval *);
int timeoffset(char *);
void usage(char *);
@@ -80,7 +82,7 @@
if (gettimeofday(&tv[0], NULL))
err(1, "gettimeofday");
- while ((ch = getopt(argc, argv, "A:acfhmr:t:")) != -1)
+ while ((ch = getopt(argc, argv, "A:acd:fhmr:t:")) != -1)
switch(ch) {
case 'A':
Aflag = timeoffset(optarg);
@@ -91,6 +93,10 @@
case 'c':
cflag = 1;
break;
+ case 'd':
+ timeset = 1;
+ stime_darg(optarg, tv);
+ break;
case 'f':
fflag = 1;
break;
@@ -327,6 +333,50 @@
tvp[0].tv_usec = tvp[1].tv_usec = 0;
}
+void
+stime_darg(char *arg, struct timeval *tvp)
+{
+ struct tm t = { .tm_sec = 0 };
+ const char *fmt, *colon;
+ char *p;
+ int val, isutc = 0;
+
+ tvp[0].tv_usec = 0;
+ t.tm_isdst = -1;
+ colon = strchr(arg, ':');
+ if (colon == NULL || strchr(colon + 1, ':') == NULL)
+ goto bad;
+ fmt = strchr(arg, 'T') != NULL ? "%Y-%m-%dT%H:%M:%S" :
+ "%Y-%m-%d %H:%M:%S";
+ p = strptime(arg, fmt, &t);
+ if (p == NULL)
+ goto bad;
+ /* POSIX: must have at least one digit after dot */
+ if ((*p == '.' || *p == ',') && isdigit((unsigned char)p[1])) {
+ p++;
+ val = 100000;
+ while (isdigit((unsigned char)*p)) {
+ tvp[0].tv_usec += val * (*p - '0');
+ p++;
+ val /= 10;
+ }
+ }
+ if (*p == 'Z') {
+ isutc = 1;
+ p++;
+ }
+ if (*p != '\0')
+ goto bad;
+
+ tvp[0].tv_sec = isutc ? timegm(&t) : mktime(&t);
+
+ tvp[1] = tvp[0];
+ return;
+
+bad:
+ errx(1, "out of range or illegal time specification: YYYY-MM-DDThh:mm:SS[.frac][tz]");
+}
+
/* Calculate a time offset in seconds, given an arg of the format [-]HHMMSS. */
int
timeoffset(char *arg)
@@ -420,7 +470,9 @@
void
usage(char *myname)
{
- fprintf(stderr, "usage:\n" "%s [-A [-][[hh]mm]SS] [-acfhm] [-r file] "
- "[-t [[CC]YY]MMDDhhmm[.SS]] file ...\n", myname);
+ fprintf(stderr, "usage: %s [-A [-][[hh]mm]SS] [-acfhm] [-r file] "
+ "[-t [[CC]YY]MMDDhhmm[.SS]]\n"
+ " [-d YYYY-MM-DDThh:mm:SS[.frac][tz]] "
+ "file ...\n", myname);
exit(1);
}
More information about the Midnightbsd-cvs
mailing list