Module Name:    src
Committed By:   kre
Date:           Sat Feb 10 00:19:30 UTC 2024

Modified Files:
        src/usr.bin/touch: touch.1 touch.c

Log Message:
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.


To generate a diff of this commit:
cvs rdiff -u -r1.28 -r1.29 src/usr.bin/touch/touch.1
cvs rdiff -u -r1.39 -r1.40 src/usr.bin/touch/touch.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/usr.bin/touch/touch.1
diff -u src/usr.bin/touch/touch.1:1.28 src/usr.bin/touch/touch.1:1.29
--- src/usr.bin/touch/touch.1:1.28	Fri Feb  9 23:41:48 2024
+++ src/usr.bin/touch/touch.1	Sat Feb 10 00:19:30 2024
@@ -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

Index: src/usr.bin/touch/touch.c
diff -u src/usr.bin/touch/touch.c:1.39 src/usr.bin/touch/touch.c:1.40
--- src/usr.bin/touch/touch.c:1.39	Fri Feb  9 23:41:48 2024
+++ src/usr.bin/touch/touch.c	Sat Feb 10 00:19:30 2024
@@ -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);
 }

Reply via email to