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).

This commit is contained in:
Andrew Wood
2025-09-18 06:18:18 +01:00
parent 8c2e934768
commit db80f838ff
3 changed files with 40 additions and 20 deletions
+11 -1
View File
@@ -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 */
+18 -10
View File
@@ -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. */
+11 -9
View File
@@ -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;
}