Hi,

right now, i had to do some tests that required symlinks with
specifically crafted access and modification times.

For that purpose, NetBSD, FreeBSD and Linux agree on having the
non-POSIX touch(1) -h flag, in analogy to chown(8) and chgrp(1).
Here is a simple patch to add it to our touch(1).

NetBSD, FreeBSD and Linux also agree to have -h imply -c,
that is, to never create any new files when -h is given.
I see no compelling reason for that restriction, but prefer
to keep semantics consistent across systems.

NetBSD and FreeBSD *silently* skip non-existent files given on
the command line when -h is given, even when -c is not given.
That seems surprising behaviour to me, so with -h, i suggest to
report missing files to stderr unless -c is given, too.

The toughest call is the exit value when -h is given, but -c is
not, and at least one file is missing.  NetBSD and FreeBSD return
success, Linux returns failure.  I prefer success, even though i'm
printing a warning, because all other files are still processed,
even those given *after* the missing one.

Any OKs or concerns?
  Ingo


Index: touch.1
===================================================================
RCS file: /cvs/src/usr.bin/touch/touch.1,v
retrieving revision 1.28
diff -u -p -r1.28 touch.1
--- touch.1     16 Sep 2011 19:36:07 -0000      1.28
+++ touch.1     11 Jul 2012 12:19:09 -0000
@@ -41,7 +41,7 @@
 .Nd change file access and modification times
 .Sh SYNOPSIS
 .Nm touch
-.Op Fl acm
+.Op Fl achm
 .Sm off
 .Op Fl "d " Ar ccyy No - Ar mm No - Ar ddTHH : Ar MM : Ar SS Oo \&. Ar frac Oc 
Op Ar Z
 .Sm on
@@ -110,6 +110,13 @@ The timezone specifier, a capital letter
 indicating that the time is in UTC.
 If not specified, the time is in the local timezone.
 .El
+.It Fl h
+Do not follow symbolic links but change the times of the links themselves.
+This option implies
+.Fl c ,
+except that missing files are reported unless
+.Fl c
+is also specified.
 .It Fl m
 Change the modification time of the file.
 The access time of the file is not changed unless the
@@ -158,6 +165,10 @@ The
 utility is compliant with the
 .St -p1003.1-2008
 specification.
+.Pp
+The flag
+.Fl h
+is an extension to that specification.
 .Pp
 The obsolescent form of
 .Nm touch ,
Index: touch.c
===================================================================
RCS file: /cvs/src/usr.bin/touch/touch.c,v
retrieving revision 1.21
diff -u -p -r1.21 touch.c
--- touch.c     31 Aug 2011 08:48:40 -0000      1.21
+++ touch.c     11 Jul 2012 12:19:09 -0000
@@ -56,13 +56,14 @@ int
 main(int argc, char *argv[])
 {
        struct timespec  ts[2];
-       int              aflag, cflag, mflag, ch, fd, len, rval, timeset;
+       int              aflag, cflag, hflag, mflag, timeset;
+       int              ch, fd, len, rval;
        char            *p;
 
        (void)setlocale(LC_ALL, "");
 
-       aflag = cflag = mflag = timeset = 0;
-       while ((ch = getopt(argc, argv, "acd:fmr:t:")) != -1)
+       aflag = cflag = hflag = mflag = timeset = 0;
+       while ((ch = getopt(argc, argv, "acd:fhmr:t:")) != -1)
                switch (ch) {
                case 'a':
                        aflag = 1;
@@ -76,6 +77,9 @@ main(int argc, char *argv[])
                        break;
                case 'f':
                        break;
+               case 'h':
+                       hflag = AT_SYMLINK_NOFOLLOW;
+                       break;
                case 'm':
                        mflag = 1;
                        break;
@@ -124,7 +128,7 @@ main(int argc, char *argv[])
 
        for (rval = 0; *argv; ++argv) {
                /* Update the file's timestamp if it exists. */
-               if (! utimensat(AT_FDCWD, *argv, ts, 0))
+               if (! utimensat(AT_FDCWD, *argv, ts, hflag))
                        continue;
                if (errno != ENOENT) {
                        rval = 1;
@@ -135,6 +139,10 @@ main(int argc, char *argv[])
                /* Didn't exist; should we create it? */
                if (cflag)
                        continue;
+               if (hflag) {
+                       warn("%s", *argv);
+                       continue;
+               }
 
                /* Create the file. */
                fd = open(*argv, O_WRONLY | O_CREAT, DEFFILEMODE);
@@ -326,7 +334,7 @@ __dead void
 usage(void)
 {
        (void)fprintf(stderr,
-"usage: touch [-acm] [-d ccyy-mm-ddTHH:MM:SS[.frac][Z]] [-r file]\n"
+"usage: touch [-achm] [-d ccyy-mm-ddTHH:MM:SS[.frac][Z]] [-r file]\n"
 "             [-t [[cc]yy]mmddHHMM[.SS]] file ...\n");
        exit(1);
 }

Reply via email to