Add a -D option to touch, which acts like the -d option added to
chmod/chown/chgrp (probably others) in the not too far distant past, and causes the operation to be a no-op if no actual change would be made (avoiding updating the file's ctime for no reason). That is, with touch, -D causes no modifying sys call to be made to a file if that file's atime and mtime are already set to the values that would be used. A common case for this is when a "-r ref-file" is also a target file for the operation. Unfortunately -d was already taken in touch, so next best available is -D.
This commit is contained in:
parent
69d75f9748
commit
b064b3fad8
|
@ -1,4 +1,4 @@
|
|||
.\" $NetBSD: touch.1,v 1.28 2024/02/09 23:41:48 kre Exp $
|
||||
.\" $NetBSD: touch.1,v 1.29 2024/02/10 00:19:30 kre Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1991, 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
|
@ -32,7 +32,7 @@
|
|||
.\"
|
||||
.\" @(#)touch.1 8.3 (Berkeley) 4/28/95
|
||||
.\"
|
||||
.Dd February 9, 2024
|
||||
.Dd February 10, 2024
|
||||
.Dt TOUCH 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -40,7 +40,7 @@
|
|||
.Nd change file access and modification times
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl acfhm
|
||||
.Op Fl acDfhm
|
||||
.Op Fl d Ar posix-datetime|human-datetime
|
||||
.Op Fl Fl \|date Ar posix-datetime|human-datetime
|
||||
.Op Fl R Ar ref-file
|
||||
|
@ -77,6 +77,11 @@ The
|
|||
.Nm
|
||||
utility does not treat this as an error.
|
||||
No error messages are displayed and the exit value is not affected.
|
||||
.Pp
|
||||
.It Fl D
|
||||
Do not attempt to adjust a
|
||||
.Ar file Ns 's
|
||||
times if they are already set to the values specified.
|
||||
.Pp
|
||||
.It Fl d Ar posix-datetime
|
||||
.It Fl d Ar human-datetime
|
||||
|
@ -360,6 +365,56 @@ of the
|
|||
.Ar path
|
||||
file to the current time of day.
|
||||
.Pp
|
||||
.Dl touch -Dh -d human-datetime -t CCYYMMDDhhmm.ss -R file file
|
||||
.Pp
|
||||
Provided
|
||||
.Ar file
|
||||
exists, this parses the
|
||||
.Ar human-datetime
|
||||
and
|
||||
.Ar CCYYMMDDhhmm.ss
|
||||
arguments,
|
||||
verifying that they would be suitable for use with
|
||||
.Nm ,
|
||||
then does nothing, as the final time specification
|
||||
.Pq Fl R
|
||||
specifies to take the times from
|
||||
.Ar file
|
||||
and apply them to
|
||||
.Ar file
|
||||
itself, changing nothing, which the
|
||||
.Fl D
|
||||
option then prevents from actually occurring.
|
||||
That is, this merely tests that the
|
||||
.Ar human-datetime
|
||||
and
|
||||
.Ar datetime
|
||||
argumments to
|
||||
.Fl d
|
||||
and
|
||||
.Fl t
|
||||
respectively are valid, and could be used to specify a time.
|
||||
Use of both
|
||||
.Fl h
|
||||
and
|
||||
.Fl R
|
||||
means this works if
|
||||
.Ar file
|
||||
is a symbolic link,
|
||||
even one which does not reference an existing file,
|
||||
as well as if it is some other file type.
|
||||
Use of
|
||||
.Fl R
|
||||
requires that
|
||||
.Ar file
|
||||
exists,
|
||||
though if it does not, and an error is generated for that reason,
|
||||
the
|
||||
.Fl d
|
||||
and
|
||||
.Fl t
|
||||
arguments would have already been successfully processed.
|
||||
.Pp
|
||||
.Dl touch -m -d '-1 day' somefile
|
||||
.Pp
|
||||
Set the modify time for
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: touch.c,v 1.39 2024/02/09 23:41:48 kre Exp $ */
|
||||
/* $NetBSD: touch.c,v 1.40 2024/02/10 00:19:30 kre 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.39 2024/02/09 23:41:48 kre Exp $");
|
||||
__RCSID("$NetBSD: touch.c,v 1.40 2024/02/10 00:19:30 kre Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
|
@ -91,18 +91,18 @@ main(int argc, char *argv[])
|
|||
{
|
||||
struct stat sb;
|
||||
struct timespec ts[2];
|
||||
int aflag, cflag, hflag, mflag, ch, fd, len, rval, timeset;
|
||||
int aflag, cflag, Dflag, hflag, mflag, ch, fd, len, rval, timeset;
|
||||
char *p;
|
||||
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;
|
||||
aflag = cflag = Dflag = hflag = mflag = timeset = 0;
|
||||
if (clock_gettime(CLOCK_REALTIME, &ts[0]))
|
||||
err(1, "clock_gettime");
|
||||
|
||||
while ((ch = getopt_long(argc, argv, "acd:fhmR:r:t:", touch_longopts,
|
||||
while ((ch = getopt_long(argc, argv, "acDd:fhmR:r:t:", touch_longopts,
|
||||
NULL)) != -1)
|
||||
switch (ch) {
|
||||
case 'a':
|
||||
|
@ -111,6 +111,9 @@ main(int argc, char *argv[])
|
|||
case 'c':
|
||||
cflag = 1;
|
||||
break;
|
||||
case 'D':
|
||||
Dflag = 1;
|
||||
break;
|
||||
case 'd':
|
||||
timeset = 1;
|
||||
if (!stime_posix(optarg, ts))
|
||||
|
@ -200,6 +203,11 @@ main(int argc, char *argv[])
|
|||
if (!mflag)
|
||||
ts[1] = sb.st_mtimespec;
|
||||
|
||||
if (Dflag &&
|
||||
timespeccmp(&ts[0], &sb.st_atimespec, ==) &&
|
||||
timespeccmp(&ts[1], &sb.st_mtimespec, ==))
|
||||
continue;
|
||||
|
||||
/* Try utimes(2). */
|
||||
if (!(*change_file_times)(*argv, ts))
|
||||
continue;
|
||||
|
@ -527,7 +535,7 @@ static void
|
|||
usage(void)
|
||||
{
|
||||
(void)fprintf(stderr,
|
||||
"Usage: %s [-acfhm] [-d|--date datetime] [-R|-r|--reference file]"
|
||||
"Usage: %s [-acDfhm] [-d|--date datetime] [-R|-r|--reference file]"
|
||||
" [-t time] file ...\n", getprogname());
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue