On Wed, Jul 11, 2012 at 03:06:25PM +0200, Ingo Schwarze wrote:
> 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.
> 

as a user, if -h implies -c, i'd be more surprised that it wasn;t
silent. it seems even weirder (actually, horrible) that -h implies -c,
but not specifying -c gives a different behaviour to specifying -c.

note that you saw no reason for -h to imply -c, but wanted consistency.
then you've undone it by changing its behaviour ;)

i see that you've documented it, so no one can really complain. but i
think if you want to do this, maybe better to just say that -h does not
create files, and avoid mentioning -c.

everything else looks fine to me (that's an ok, however you decide).
one nit inline though...

jmc

> 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.

we use ".Op Fl" everywhere for this text, so please keep it the same.

>  .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