Attached, please find a patch to add the --verbose (-v) option to the touch
command.
As for rm, cp, ln, etc.

Michael
From 00338cbd9d16d632a55b70ba9fdeeca5710f6a5a Mon Sep 17 00:00:00 2001
From: Michael Cook <mich...@waxrat.com>
Date: Wed, 7 Apr 2021 16:00:47 -0400
Subject: [PATCH] touch: Add --verbose (-v) option

As in rm, cp, ln, etc.
---
 src/touch.c | 37 ++++++++++++++++++++++++++++++++++---
 1 file changed, 34 insertions(+), 3 deletions(-)

diff --git a/src/touch.c b/src/touch.c
index 136e246bc..c9942c667 100644
--- a/src/touch.c
+++ b/src/touch.c
@@ -71,6 +71,9 @@ static bool amtime_now;
 /* New access and modification times to use when setting time.  */
 static struct timespec newtime[2];
 
+/* (-v) If true, explain what is being done.  */
+static bool verbose;
+
 /* File to use for -r. */
 static char *ref_file;
 
@@ -88,6 +91,7 @@ static struct option const longopts[] =
   {"date", required_argument, NULL, 'd'},
   {"reference", required_argument, NULL, 'r'},
   {"no-dereference", no_argument, NULL, 'h'},
+  {"verbose", no_argument, NULL, 'v'},
   {GETOPT_HELP_OPTION_DECL},
   {GETOPT_VERSION_OPTION_DECL},
   {NULL, 0, NULL, 0}
@@ -126,14 +130,33 @@ touch (const char *file)
   int fd = -1;
   int open_errno = 0;
   struct timespec const *t = newtime;
+  bool created = false;
 
   if (STREQ (file, "-"))
     fd = STDOUT_FILENO;
   else if (! (no_create || no_dereference))
     {
       /* Try to open FILE, creating it if necessary.  */
-      fd = fd_reopen (STDIN_FILENO, file,
-                      O_WRONLY | O_CREAT | O_NONBLOCK | O_NOCTTY, MODE_RW_UGO);
+      int flags = O_WRONLY | O_NONBLOCK | O_NOCTTY;
+      if (verbose)
+        {
+          fd = fd_reopen (STDIN_FILENO, file, flags, MODE_RW_UGO);
+          if (fd == -1 && errno == ENOENT)
+            {
+              /* There's a race here.  If the previous fd_reopen fails and
+                 then this fd_reopen succeeds we assume the second fd_reopen
+                 created the file.  But that's not necessarily true -- another
+                 process could have created the file in between our two
+                 invocations of fd_reopen.  We're using this `created` flag
+                 only to affect what we printf at the bottom of this function,
+                 so we assume that race won't be an actual problem.  */
+              fd = fd_reopen (STDIN_FILENO, file, flags | O_CREAT, MODE_RW_UGO);
+              if (fd != -1)
+                created = true;
+            }
+        }
+      else
+        fd = fd_reopen (STDIN_FILENO, file, flags | O_CREAT, MODE_RW_UGO);
 
       /* Don't save a copy of errno if it's EISDIR, since that would lead
          touch to give a bogus diagnostic for e.g., 'touch /' (assuming
@@ -200,6 +223,9 @@ touch (const char *file)
       return false;
     }
 
+  if (verbose)
+    printf (created ? _("created %s\n") : _("touched %s\n"), quoteaf (file));
+
   return true;
 }
 
@@ -241,6 +267,7 @@ change the times of the file associated with standard output.\n\
       --time=WORD        change the specified time:\n\
                            WORD is access, atime, or use: equivalent to -a\n\
                            WORD is modify or mtime: equivalent to -m\n\
+  -v, --verbose          explain what is being done\n\
 "), stdout);
       fputs (HELP_OPTION_DESCRIPTION, stdout);
       fputs (VERSION_OPTION_DESCRIPTION, stdout);
@@ -272,7 +299,7 @@ main (int argc, char **argv)
   change_times = 0;
   no_create = use_ref = false;
 
-  while ((c = getopt_long (argc, argv, "acd:fhmr:t:", longopts, NULL)) != -1)
+  while ((c = getopt_long (argc, argv, "acd:fhmr:t:v", longopts, NULL)) != -1)
     {
       switch (c)
         {
@@ -319,6 +346,10 @@ main (int argc, char **argv)
                                      time_args, time_masks);
           break;
 
+        case 'v':
+          verbose = true;
+          break;
+
         case_GETOPT_HELP_CHAR;
 
         case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
-- 
2.27.0

Reply via email to