From 00338cbd9d16d632a55b70ba9fdeeca5710f6a5a Mon Sep 17 00:00:00 2001 From: Michael Cook 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