From db80f838ffe1edd53f211aa8ded97ac8d77bd892 Mon Sep 17 00:00:00 2001 From: Andrew Wood Date: Thu, 18 Sep 2025 06:18:18 +0100 Subject: [PATCH] Explicitly set an action variable to say which action to perform, instead of inferring it from other settings like whether a watch PID was set (#12). --- src/include/options.h | 12 +++++++++++- src/main/main.c | 28 ++++++++++++++++++---------- src/main/options.c | 20 +++++++++++--------- 3 files changed, 40 insertions(+), 20 deletions(-) diff --git a/src/include/options.h b/src/include/options.h index 23bbce3..72a8c10 100644 --- a/src/include/options.h +++ b/src/include/options.h @@ -23,6 +23,16 @@ extern "C" { struct opts_s; typedef struct opts_s *opts_t; +/* + * Overall program actions to select. + */ +typedef enum { + PV_ACTION_NOTHING, /* do nothing, and exit */ + PV_ACTION_TRANSFER, /* transfer data */ + PV_ACTION_STORE_AND_FORWARD, /* store to file, then output from it */ + PV_ACTION_WATCHFD /* watch process file descriptors */ +} pvaction_t; + /* * Structure describing run-time options. * @@ -58,7 +68,7 @@ struct opts_s { unsigned int argv_length; /* allocated array size */ unsigned int watchfd_count; /* number of watchfd items */ unsigned int watchfd_length; /* allocated array size */ - bool do_nothing; /* exit-without-doing-anything flag */ + pvaction_t action; /* the program action to perform */ bool progress; /* progress bar flag */ bool timer; /* timer flag */ bool eta; /* ETA flag */ diff --git a/src/main/main.c b/src/main/main.c index 347dfc9..6511abd 100644 --- a/src/main/main.c +++ b/src/main/main.c @@ -308,7 +308,7 @@ int main(int argc, char **argv) } /* Early exit if necessary, such as with "-h". */ - if (opts->do_nothing) { + if (PV_ACTION_NOTHING == opts->action) { debug("%s", "nothing to do - exiting with status 0"); opts_free(opts); return 0; @@ -465,7 +465,7 @@ int main(int argc, char **argv) pv_state_stop_at_size_set(state, opts->stop_at_size); /* Total size calculation, in normal transfer mode. */ - if (0 == opts->watch_pid) { + if (PV_ACTION_TRANSFER == opts->action) { /* * If no size was given, try to calculate the total size. */ @@ -533,22 +533,30 @@ int main(int argc, char **argv) pv_sig_init(state); /* Run the appropriate main loop. */ - if (0 == opts->watch_pid && NULL == opts->store_and_forward_file) { + switch (opts->action) { + case PV_ACTION_NOTHING: + break; + case PV_ACTION_TRANSFER: /* Normal "transfer data" mode. */ pv_remote_init(); retcode = pv_main_loop(state); pv_remote_fini(); - } else if (0 == opts->watch_pid && NULL != opts->store_and_forward_file) { + break; + case PV_ACTION_STORE_AND_FORWARD: /* Store-and-forward transfer mode. */ pv_remote_init(); retcode = pv__store_and_forward(state, opts, can_have_eta); pv_remote_fini(); - } else if (0 != opts->watch_pid && -1 == opts->watch_fd) { - /* "Watch all file descriptors of another process" mode. */ - retcode = pv_watchpid_loop(state); - } else if (0 != opts->watch_pid && -1 != opts->watch_fd) { - /* "Watch a specific file descriptor of another process" mode. */ - retcode = pv_watchfd_loop(state); + break; + case PV_ACTION_WATCHFD: + if (-1 == opts->watch_fd) { + /* "Watch all file descriptors of another process" mode. */ + retcode = pv_watchpid_loop(state); + } else if (-1 != opts->watch_fd) { + /* "Watch a specific file descriptor of another process" mode. */ + retcode = pv_watchfd_loop(state); + } + break; } /* Clear up the PID file, if one was written. */ diff --git a/src/main/options.c b/src/main/options.c index 9ac5d9f..4c95fd6 100644 --- a/src/main/options.c +++ b/src/main/options.c @@ -410,6 +410,7 @@ opts_t opts_parse(unsigned int argc, char **argv) numopts = 0; + opts->action = PV_ACTION_TRANSFER; opts->interval = 1; opts->delay_start = 0; opts->watch_pid = 0; @@ -507,10 +508,6 @@ opts_t opts_parse(unsigned int argc, char **argv) return NULL; /*@+mustfreefresh@ */ } - if (!opts_add_watchfd(opts, (pid_t) check_pid, check_fd)) { - opts_free(opts); - return NULL; - } break; default: break; @@ -522,11 +519,11 @@ opts_t opts_parse(unsigned int argc, char **argv) switch (c) { case 'h': display_help(); - opts->do_nothing = true; + opts->action = PV_ACTION_NOTHING; return opts; /* early return */ case 'V': display_version(); - opts->do_nothing = true; + opts->action = PV_ACTION_NOTHING; return opts; /* early return */ case 'p': opts->progress = true; @@ -683,6 +680,7 @@ opts_t opts_parse(unsigned int argc, char **argv) opts_free(opts); return NULL; } + opts->action = PV_ACTION_STORE_AND_FORWARD; break; case 'R': opts->remote = (pid_t) pv_getnum_count(optarg, false); @@ -718,6 +716,11 @@ opts_t opts_parse(unsigned int argc, char **argv) (void) sscanf(optarg, "%u:%d", &parse_pid, &parse_fd); opts->watch_pid = (pid_t) parse_pid; opts->watch_fd = parse_fd; + if (!opts_add_watchfd(opts, (pid_t) parse_pid, parse_fd)) { + opts_free(opts); + return NULL; + } + opts->action = PV_ACTION_WATCHFD; break; case 'o': opts->output = pv_strdup(optarg); @@ -766,7 +769,7 @@ opts_t opts_parse(unsigned int argc, char **argv) if (NULL == opts) return NULL; - if (0 != opts->watch_pid) { + if (PV_ACTION_WATCHFD == opts->action) { if (opts->linemode || opts->null_terminated_lines || opts->stop_at_size || (opts->skip_errors > 0) || (opts->buffer_size > 0) || (opts->rate_limit > 0)) { @@ -796,6 +799,7 @@ opts_t opts_parse(unsigned int argc, char **argv) /*@+mustfreefresh@ */ } + /* TODO: accept additional args as pid[:fd] */ if (optind < (int) argc) { /*@-mustfreefresh@ *//* see above */ fprintf(stderr, "%s: %s\n", opts->program_name, @@ -847,7 +851,5 @@ opts_t opts_parse(unsigned int argc, char **argv) } } - /* TODO: set an enum to say which mode to use (nothing, PV, watchfd) */ - return opts; }