From 83069df4633d21fc176aec2f4c9d9ba027514dcf Mon Sep 17 00:00:00 2001 From: Sergey Poznyakoff Date: Wed, 17 May 2023 18:54:40 +0300 Subject: genfile: implement the --set-time option * doc/genfile.texi: Document changes. * tests/genfile.c: New options: --set-time and --no-dereference. --- tests/genfile.c | 45 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 3 deletions(-) (limited to 'tests') diff --git a/tests/genfile.c b/tests/genfile.c index be4a2d3..0074c5c 100644 --- a/tests/genfile.c +++ b/tests/genfile.c @@ -77,7 +77,8 @@ enum genfile_mode mode_generate, mode_sparse, mode_stat, - mode_exec + mode_exec, + mode_set_times }; enum genfile_mode mode = mode_generate; @@ -106,6 +107,9 @@ int verbose; /* Quiet mode */ int quiet; +/* Don't dereference symlinks (for --stat) */ +int no_dereference_option; + const char *argp_program_version = "genfile (" PACKAGE ") " VERSION; const char *argp_program_bug_address = "<" PACKAGE_BUGREPORT ">"; static char doc[] = N_("genfile manipulates data files for GNU paxutils test suite.\n" @@ -155,6 +159,14 @@ static struct argp_option options[] = { N_("Print contents of struct stat for each given file. Default FORMAT is: ") DEFAULT_STAT_FORMAT, GRP+1 }, + {"no-dereference", 'h', NULL, 0, + N_("stat symbolic links instead of referenced files"), + GRP+1 }, + + {"set-times", 't', NULL, 0, + N_("Set access and modification times of the files to the time supplied" + " by --date option"), + GRP+1 }, #undef GRP #define GRP 20 @@ -348,6 +360,14 @@ parse_opt (int key, char *arg, struct argp_state *state) stat_format = arg; break; + case 't': + mode = mode_set_times; + break; + + case 'h': + no_dereference_option = 1; + break; + case 'r': mode = mode_exec; checkpoint_granularity = arg ? arg : "1"; @@ -647,7 +667,7 @@ print_stat (const char *name) char *fmt, *p; struct stat st; - if (stat (name, &st)) + if ((no_dereference_option ? lstat : stat) (name, &st)) { error (0, errno, _("stat(%s) failed"), name); return; @@ -725,6 +745,17 @@ print_stat (const char *name) free (fmt); } +void +set_times (char const *name) +{ + struct timespec ts[2]; + + ts[0] = ts[1] = touch_time; + if (utimensat (AT_FDCWD, name, ts, no_dereference_option ? AT_SYMLINK_NOFOLLOW : 0) != 0) + { + error (EXIT_FAILURE, errno, _("cannot set time on `%s'"), name); + } +} /* Exec Mode */ @@ -740,7 +771,7 @@ exec_checkpoint (struct action *p) struct timespec ts[2]; ts[0] = ts[1] = p->ts; - if (utimensat (AT_FDCWD, p->name, ts, 0) != 0) + if (utimensat (AT_FDCWD, p->name, ts, no_dereference_option ? AT_SYMLINK_NOFOLLOW : 0) != 0) { error (0, errno, _("cannot set time on `%s'"), p->name); break; @@ -987,6 +1018,14 @@ main (int argc, char **argv) print_stat (*argv++); break; + case mode_set_times: + if (argc == 0) + error (EXIT_USAGE, 0, _("--set-times requires file names")); + + while (argc--) + set_times (*argv++); + break; + case mode_sparse: generate_sparse_file (argc, argv); verify_file (file_name); -- cgit v1.2.1