X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=tests%2Fgenfile.c;h=8541be6c4d8e692b3f790989f7259f452fd977c9;hb=HEAD;hp=1b338bce2f95a77635abe7f7f6926b53802d4395;hpb=cf7169a2ede9bb08b71de68fe0c8bbecf827abe6;p=tar diff --git a/tests/genfile.c b/tests/genfile.c index 1b338bc..8541be6 100644 --- a/tests/genfile.c +++ b/tests/genfile.c @@ -2,7 +2,7 @@ Print statistics for existing files. Copyright (C) 1995, 1996, 1997, 2001, 2003, 2004, 2005, 2006, 2007, - 2008 Free Software Foundation, Inc. + 2008, 2009 Free Software Foundation, Inc. François Pinard , 1995. Sergey Poznyakoff , 2004, 2005, 2006, 2007, 2008. @@ -28,8 +28,7 @@ #include #include #include -#include -#include +#include #include #include #include @@ -99,6 +98,7 @@ char *buffer; /* Number of arguments and argument vector for mode == mode_exec */ int exec_argc; char **exec_argv; +char *checkpoint_option; /* Time for --touch option */ struct timespec touch_time; @@ -119,6 +119,7 @@ static char doc[] = N_("genfile manipulates data files for GNU paxutils test sui #define OPT_DATE 261 #define OPT_VERBOSE 262 #define OPT_SEEK 263 +#define OPT_UNLINK 264 static struct argp_option options[] = { #define GRP 0 @@ -159,8 +160,8 @@ static struct argp_option options[] = { {NULL, 0, NULL, 0, N_("Synchronous execution options:"), GRP}, - {"run", 'r', N_("COMMAND"), 0, - N_("Execute given COMMAND. Useful with --checkpoint and one of --cut, --append, --touch"), + {"run", 'r', N_("OPTION"), OPTION_ARG_OPTIONAL, + N_("Execute ARGS. Useful with --checkpoint and one of --cut, --append, --touch, --unlink"), GRP+1 }, {"checkpoint", OPT_CHECKPOINT, N_("NUMBER"), 0, N_("Perform given action (see below) upon reaching checkpoint NUMBER"), @@ -189,6 +190,9 @@ static struct argp_option options[] = { {"exec", OPT_EXEC, N_("COMMAND"), 0, N_("Execute COMMAND"), GRP+1 }, + {"unlink", OPT_UNLINK, N_("FILE"), 0, + N_("Unlink FILE"), + GRP+1 }, #undef GRP { NULL, } }; @@ -333,7 +337,11 @@ parse_opt (int key, char *arg, struct argp_state *state) case 'r': mode = mode_exec; - argcv_get (arg, "", NULL, &exec_argc, &exec_argv); + if (arg) + { + argcv_get (arg, "", NULL, &exec_argc, &exec_argv); + checkpoint_option = "--checkpoint"; + } break; case 'T': @@ -355,7 +363,7 @@ parse_opt (int key, char *arg, struct argp_state *state) break; case OPT_DATE: - if (!get_date (&touch_time, arg, NULL)) + if (! parse_datetime (&touch_time, arg, NULL)) argp_error (state, _("Unknown date format")); break; @@ -363,6 +371,7 @@ parse_opt (int key, char *arg, struct argp_state *state) case OPT_TRUNCATE: case OPT_TOUCH: case OPT_EXEC: + case OPT_UNLINK: reg_action (key, arg); break; @@ -572,13 +581,13 @@ print_stat (const char *name) printf ("%lu", (unsigned long) st.st_ino); else if (strncmp (p, "mode", 4) == 0) { - mode_t mask = ~0; + unsigned val = st.st_mode; - if (ispunct (p[4])) + if (ispunct ((unsigned char) p[4])) { char *q; - mask = strtoul (p + 5, &q, 8); + val &= strtoul (p + 5, &q, 8); if (*q) { printf ("\n"); @@ -590,7 +599,7 @@ print_stat (const char *name) printf ("\n"); error (EXIT_FAILURE, 0, _("Unknown field `%s'"), p); } - printf ("%0o", st.st_mode & mask); + printf ("%0o", val); } else if (strcmp (p, "nlink") == 0) printf ("%lu", (unsigned long) st.st_nlink); @@ -646,7 +655,7 @@ exec_checkpoint (struct action *p) struct timespec ts[2]; ts[0] = ts[1] = p->ts; - if (utimens (p->name, ts) != 0) + if (utimensat (AT_FDCWD, p->name, ts, 0) != 0) { error (0, errno, _("cannot set time on `%s'"), p->name); break; @@ -685,6 +694,11 @@ exec_checkpoint (struct action *p) system (p->name); break; + case OPT_UNLINK: + if (unlink (p->name)) + error (0, errno, _("cannot unlink `%s'"), p->name); + break; + default: abort (); } @@ -730,11 +744,17 @@ exec_command (void) /* Insert --checkpoint option. FIXME: This assumes that exec_argv does not use traditional tar options - (without dash) */ - exec_argc++; - exec_argv = xrealloc (exec_argv, (exec_argc + 1) * sizeof (*exec_argv)); - memmove (exec_argv+2, exec_argv+1, (exec_argc - 1) * sizeof (*exec_argv)); - exec_argv[1] = "--checkpoint"; + (without dash). + FIXME: There is no way to set checkpoint argument (granularity). + */ + if (checkpoint_option) + { + exec_argc++; + exec_argv = xrealloc (exec_argv, (exec_argc + 1) * sizeof (*exec_argv)); + memmove (exec_argv+2, exec_argv+1, + (exec_argc - 1) * sizeof (*exec_argv)); + exec_argv[1] = checkpoint_option; + } #ifdef SIGCHLD /* System V fork+wait does not work if SIGCHLD is ignored. */ @@ -760,7 +780,7 @@ exec_command (void) setenv ("LC_ALL", "POSIX", 1); execvp (exec_argv[0], exec_argv); - error (EXIT_FAILURE, errno, "execvp"); + error (EXIT_FAILURE, errno, "execvp %s", exec_argv[0]); } /* Master */ @@ -771,12 +791,12 @@ exec_command (void) while ((p = fgets (buf, sizeof buf, fp))) { - while (*p && !isspace (*p) && *p != ':') + while (*p && !isspace ((unsigned char) *p) && *p != ':') p++; if (*p == ':') { - for (p++; *p && isspace (*p); p++) + for (p++; *p && isspace ((unsigned char) *p); p++) ; if (*p @@ -784,7 +804,7 @@ exec_command (void) { char *end; size_t n = strtoul (p + sizeof CHECKPOINT_TEXT - 1, &end, 10); - if (!(*end && !isspace (*end))) + if (!(*end && !isspace ((unsigned char) *end))) { process_checkpoint (n); continue; @@ -834,7 +854,7 @@ main (int argc, char **argv) bindtextdomain (PACKAGE, LOCALEDIR); textdomain (PACKAGE); - get_date (&touch_time, "now", NULL); + parse_datetime (&touch_time, "now", NULL); /* Decode command options. */ @@ -872,6 +892,13 @@ main (int argc, char **argv) break; case mode_exec: + if (!checkpoint_option) + { + exec_argc = argc; + exec_argv = argv; + } + else if (argc) + error (EXIT_FAILURE, 0, _("too many arguments")); exec_command (); break;