From 590a3535d88af947484299bf75393a463efed983 Mon Sep 17 00:00:00 2001 From: Andrew Wood Date: Tue, 21 Oct 2025 23:39:17 +0100 Subject: [PATCH] Don't keep PV_REMOTE_QUERY separate from PV_REMOTE_CONTROL after all since they will need to work together; extend pv_remote_check() so it will check for both -R and -Q signals (#101). --- src/include/config-aux.h | 10 +--- src/include/pv-internal.h | 4 -- src/include/pv.h | 5 ++ src/main/help.c | 4 +- src/main/remote.c | 118 ++++++++++++++++++++++++++++---------- src/pv/signal.c | 11 +--- 6 files changed, 98 insertions(+), 54 deletions(-) diff --git a/src/include/config-aux.h b/src/include/config-aux.h index 80cc089..86d9270 100644 --- a/src/include/config-aux.h +++ b/src/include/config-aux.h @@ -44,18 +44,10 @@ typedef bool _Bool; # define __bool_true_false_are_defined 1 #endif -/* Whether "--remote" should be available. */ +/* Whether "--remote" and "--query" should be available. */ #undef PV_REMOTE_CONTROL #if HAVE_DECL_SA_SIGINFO # if SIGINFO_PROVIDES_PID #define PV_REMOTE_CONTROL 1 # endif #endif - -/* Whether "--query" should be available. */ -#undef PV_REMOTE_QUERY -#if HAVE_DECL_SA_SIGINFO -# if SIGINFO_PROVIDES_PID -#define PV_REMOTE_QUERY 1 -# endif -#endif diff --git a/src/include/pv-internal.h b/src/include/pv-internal.h index b1b39ce..43a9459 100644 --- a/src/include/pv-internal.h +++ b/src/include/pv-internal.h @@ -230,8 +230,6 @@ struct pvstate_s { struct sigaction old_sigterm; #ifdef PV_REMOTE_CONTROL struct sigaction old_sigusr2; -#endif -#ifdef PV_REMOTE_QUERY struct sigaction old_sigusr1; #endif struct sigaction old_sigalrm; @@ -240,8 +238,6 @@ struct pvstate_s { #ifdef PV_REMOTE_CONTROL volatile sig_atomic_t rxusr2; /* whether SIGUSR2 was received */ volatile pid_t sender_usr2; /* PID of sending process for SIGUSR2 */ -#endif -#ifdef PV_REMOTE_QUERY volatile sig_atomic_t rxusr1; /* whether SIGUSR1 was received */ volatile pid_t sender_usr1; /* PID of sending process for SIGUSR1 */ #endif diff --git a/src/include/pv.h b/src/include/pv.h index 5554039..626d250 100644 --- a/src/include/pv.h +++ b/src/include/pv.h @@ -267,6 +267,11 @@ extern void pv_sig_init(pvstate_t); * Return true if SIGUSR2 has been received, and indicate the sender. */ extern bool pv_sigusr2_received(pvstate_t, pid_t *); + +/* + * Return true if SIGUSR1 has been received, and indicate the sender. + */ +extern bool pv_sigusr1_received(pvstate_t, pid_t *); #endif /* diff --git a/src/main/help.c b/src/main/help.c index 673f719..9859480 100644 --- a/src/main/help.c +++ b/src/main/help.c @@ -368,12 +368,10 @@ void display_help(void) { "-R", "--remote", N_("PID"), N_("update settings of process PID"), { 0, 0, 0, 0} }, -#endif /* PV_REMOTE_CONTROL */ -#ifdef PV_REMOTE_QUERY { "-Q", "--query", N_("PID"), N_("show progress of process PID"), { 0, 0, 0, 0} }, -#endif /* PV_REMOTE_QUERY */ +#endif /* PV_REMOTE_CONTROL */ { "", NULL, NULL, NULL, { 0, 0, 0, 0} }, { "-P", "--pidfile", N_("FILE"), N_("save process ID in FILE"), diff --git a/src/main/remote.c b/src/main/remote.c index 90a7330..867a68a 100644 --- a/src/main/remote.c +++ b/src/main/remote.c @@ -233,15 +233,16 @@ int pv_remote_set(opts_t opts, pvstate_t state) /* - * Check for a remote control message and, if there is one, replace the - * current process's options with those being passed in. + * Check for a --remote message (SIGUSR2), returning false if none was + * found. * - * NB relies on pv_state_set_format() causing the output format to be - * reparsed. + * If a message was received, update the current process's options with the + * ones in the message. * - * Returns true if something was received, false otherwise. + * Note that this relies on pv_state_set_format() causing the output format + * to be reparsed. */ -bool pv_remote_check(pvstate_t state) +static bool pv__rxsignal_usr2(pvstate_t state) { pid_t signal_sender; char control_filename[4096]; /* flawfinder: ignore */ @@ -287,7 +288,7 @@ bool pv_remote_check(pvstate_t state) debug("%u: %s", signal_sender, strerror(errno)); } - debug("%s", "received remote message"); + debug("%s", "received remote control message"); pv_state_format_string_set(state, NULL); pv_state_name_set(state, NULL); @@ -325,11 +326,91 @@ bool pv_remote_check(pvstate_t state) } +/* + * Check for a --query message (SIGUSR1). + * + * If a message was received, then if it's type 0 (query), write a type 1 + * message containing the total size and current transfer state to the + * control file and send a SIGUSR1 to the sending process. If it's type 1 + * (response), update the transfer state - and control.size - from the + * message in the control file. + */ +static void pv__rxsignal_usr1(pvstate_t state) +{ + pid_t signal_sender; + char control_filename[4096]; /* flawfinder: ignore */ + FILE *control_fptr; + + /* flawfinder rationale: as above. */ + + /* + * Return early if a SIGUSR1 signal has not been received. + */ + signal_sender = 0; + if (!pv_sigusr1_received(state, &signal_sender)) + return; + + memset(control_filename, 0, sizeof(control_filename)); + control_fptr = pv_open_controlfile(control_filename, sizeof(control_filename), signal_sender, SIGUSR1, false); + if (NULL == control_fptr) { + pv_error("%s: %s", control_filename, strerror(errno)); + return; + } + +/* TODO: read the message */ + + if (0 != fclose(control_fptr)) { + pv_error("%s", strerror(errno)); + return; + } + +/* TODO: handle message */ +} + + +/* + * Check for remote control messages. For a SIGUSR2 (--remote), replace the + * current process's options with those being passed in. For a SIGUSR1 + * (--query), either receive transfer state from the sending process, or + * send our transfer state to the sending process, depending on the content + * of the message. + * + * NB --remote relies on pv_state_set_format() causing the output format to + * be reparsed. + * + * Returns true if a --remote message was received, false otherwise. + */ +bool pv_remote_check(pvstate_t state) +{ + bool received_remote; + + received_remote = pv__rxsignal_usr2(state); + pv__rxsignal_usr1(state); + + return received_remote; +} + + +/* + * Replace the transfer state with that of the given process, populating + * *sizeptr with that process's idea of the total transfer size if sizeptr + * isn't NULL. + * + * Returns nonzero on error, after reporting the error. + */ +int pv_remote_transferstate_fetch(pvstate_t state, pid_t query, /*@null@ */ off_t * sizeptr) +{ + /* TODO: write this */ + return PV_ERROREXIT_REMOTE_OR_PID; +} + + #else /* !PV_REMOTE_CONTROL */ /* * Dummy stubs for remote control when we don't have PV_REMOTE_CONTROL. */ + void pv_remote_check( /*@unused@ */ __attribute__((unused)) pvstate_t state) { } @@ -344,27 +425,6 @@ int pv_remote_set( /*@unused@ */ return PV_ERROREXIT_REMOTE_OR_PID; } -#endif /* PV_REMOTE_CONTROL */ - -#ifdef PV_REMOTE_QUERY -/* - * Replace the transfer state with that of the given process, populating - * *sizeptr with that process's idea of the total transfer size if sizeptr - * isn't NULL. - * - * Returns nonzero on error, after reporting the error. - */ -int pv_remote_transferstate_fetch(pvstate_t state, pid_t query, /*@null@ */ off_t * sizeptr) -{ - /* TODO: write this */ - return PV_ERROREXIT_REMOTE_OR_PID; -} - -#else /* !PV_REMOTE_QUERY */ - -/* - * Dummy stubs for remote querying when we don't have PV_REMOTE_QUERY. - */ int pv_remote_transferstate_fetch( /*@unused@ */ __attribute__((unused)) pvstate_t state, /*@unused@ */ @@ -377,4 +437,4 @@ int pv_remote_transferstate_fetch( /*@unused@ */ return PV_ERROREXIT_REMOTE_OR_PID; } -#endif /* PV_REMOTE_QUERY */ +#endif /* PV_REMOTE_CONTROL */ diff --git a/src/pv/signal.c b/src/pv/signal.c index 5bba99b..b76003c 100644 --- a/src/pv/signal.c +++ b/src/pv/signal.c @@ -260,10 +260,7 @@ bool pv_sigusr2_received(pvstate_t state, pid_t * pid) return true; } -#endif - -#ifdef PV_REMOTE_QUERY /* * Handle a SIGUSR1 by setting a flag to say we received it, after recording * the sending PID. @@ -297,7 +294,7 @@ bool pv_sigusr1_received(pvstate_t state, pid_t * pid) return true; } -#endif +#endif /* PV_REMOTE_CONTROL */ /* @@ -425,9 +422,7 @@ void pv_sig_init(pvstate_t state) /*@+unrecog@ */ (void) sigaction(SIGUSR2, &sa, &(pv_sig_state->signal.old_sigusr2)); memset(&sa, 0, sizeof(sa)); -#endif -#ifdef PV_REMOTE_QUERY /* * Handle SIGUSR1 by setting a flag to say the signal has been * received, and storing the sending process's PID. @@ -440,7 +435,7 @@ void pv_sig_init(pvstate_t state) /*@+unrecog@ */ (void) sigaction(SIGUSR1, &sa, &(pv_sig_state->signal.old_sigusr1)); memset(&sa, 0, sizeof(sa)); -#endif +#endif /* PV_REMOTE_CONTROL */ /* * Ensure that the TOSTOP terminal attribute is set, so that a @@ -485,8 +480,6 @@ void pv_sig_fini( /*@unused@ */ __attribute__((unused)) pvstate_t state) (void) sigaction(SIGTERM, &(pv_sig_state->signal.old_sigterm), NULL); #ifdef PV_REMOTE_CONTROL (void) sigaction(SIGUSR2, &(pv_sig_state->signal.old_sigusr2), NULL); -#endif -#ifdef PV_REMOTE_QUERY (void) sigaction(SIGUSR1, &(pv_sig_state->signal.old_sigusr1), NULL); #endif (void) sigaction(SIGALRM, &(pv_sig_state->signal.old_sigalrm), NULL);