From f07a7b1c8740803462e223039e5f744c3a42e8f8 Mon Sep 17 00:00:00 2001 From: Andrew Wood Date: Fri, 24 Oct 2025 09:24:31 +0100 Subject: [PATCH] Correct the noise interrupting the display of the original pv if the querying pv is terminated. Correct the transfer of size information to main() so that ETA can still be shown. (#101) --- src/main/main.c | 4 ++-- src/main/remote.c | 49 +++++++++++++++++++++++++++++++---------------- src/pv/loop.c | 4 ++-- 3 files changed, 36 insertions(+), 21 deletions(-) diff --git a/src/main/main.c b/src/main/main.c index d09c9fc..024a330 100644 --- a/src/main/main.c +++ b/src/main/main.c @@ -24,7 +24,7 @@ #endif int pv_remote_set(opts_t, pvstate_t); -int pv_remote_transferstate_fetch(pvstate_t, pid_t, bool); +int pv_remote_transferstate_fetch(pvstate_t, pid_t, /*@null@ */ off_t *, bool); /* * Write a PID file, returning nonzero on error. Write it atomically, such @@ -500,7 +500,7 @@ int main(int argc, char **argv) */ if (PV_ACTION_QUERY == opts->action) { opts->size = 0; - retcode = pv_remote_transferstate_fetch(state, opts->query, false); + retcode = pv_remote_transferstate_fetch(state, opts->query, &(opts->size), false); if (0 != retcode) { pv_sig_fini(state); pv_state_free(state); diff --git a/src/main/remote.c b/src/main/remote.c index 2ea0d76..2b53593 100644 --- a/src/main/remote.c +++ b/src/main/remote.c @@ -342,12 +342,16 @@ static bool pv__rxsignal_usr2(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. In both cases, the receiver of the message - * deletes the associated control file. + * If a type 0 message was received (query), then write a type 1 (response) + * message to the control file and send a SIGUSR1 to the sending process. + * + * If a type 1 message was received (response), update the state from the + * message in the control file. + * + * In both cases, the receiver of the message deletes its control file. + * + * The state transferred by message is transfer.elapsed_seconds, + * transfer.transferred, and control.size. * * Returns true if a signal was received and dealt with, false otherwise. * @@ -380,10 +384,16 @@ static bool pv__rxsignal_usr1(pvstate_t state, pid_t match_sender) return false; } + /* + * Note that we use debug() rather than pv_error() here so that the + * display of a running pv doesn't get interrupted by, for example, + * a querying pv being terminated. + */ + 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)); + debug("%s: %s", control_filename, strerror(errno)); return false; } @@ -392,25 +402,26 @@ static bool pv__rxsignal_usr1(pvstate_t state, pid_t match_sender) * and delete it. */ if (1 != fread(&msgbuf, sizeof(msgbuf), 1, control_fptr)) { - pv_error("%s", strerror(errno)); + debug("fread: %s", strerror(errno)); (void) fclose(control_fptr); return false; } if (0 != fclose(control_fptr)) { - pv_error("%s", strerror(errno)); + debug("fclose: %s", strerror(errno)); return false; } debug("%s: %s", "removing", control_filename); if (0 != remove(control_filename)) { - pv_error("%s", strerror(errno)); + debug("remove: %s", strerror(errno)); return false; } if (msgbuf.response) { /* Response message - update local state. */ - debug("%s: %d", "query response received", signal_sender); + debug("%s: %d [%Lg, %ld, %ld]", "query response received", signal_sender, msgbuf.elapsed_seconds, + msgbuf.transferred, msgbuf.size); state->transfer.elapsed_seconds = msgbuf.elapsed_seconds; state->transfer.transferred = msgbuf.transferred; state->control.size = msgbuf.size; @@ -429,19 +440,19 @@ static bool pv__rxsignal_usr1(pvstate_t state, pid_t match_sender) memset(control_filename, 0, sizeof(control_filename)); control_fptr = pv_open_controlfile(control_filename, sizeof(control_filename), (pid_t) getpid(), SIGUSR1, true); if (NULL == control_fptr) { - pv_error("%s", strerror(errno)); + debug("%s", strerror(errno)); return true; /* true since the signal was received. */ } if (1 != fwrite(&msgbuf, sizeof(msgbuf), 1, control_fptr)) { - pv_error("%s", strerror(errno)); + debug("fwrite: %s", strerror(errno)); (void) fclose(control_fptr); (void) remove(control_filename); return true; /* as above. */ } if (0 != fclose(control_fptr)) { - pv_error("%s", strerror(errno)); + debug("fclose: %s", strerror(errno)); (void) remove(control_filename); return true; } @@ -451,7 +462,7 @@ static bool pv__rxsignal_usr1(pvstate_t state, pid_t match_sender) * query response message is ready to read. */ if (kill((pid_t) (signal_sender), SIGUSR1) != 0) { - pv_error("%u: %s", signal_sender, strerror(errno)); + debug("%u: %s", signal_sender, strerror(errno)); (void) remove(control_filename); return true; } @@ -487,11 +498,13 @@ bool pv_remote_check(pvstate_t state) /* * Replace the transfer state with that of the given process, including the - * total transfer size. + * total transfer size. If sizeptr is not NULL, the size is also copied to + * *sizeptr (this is so a caller can get the size without knowing the + * structure of pvstate_t). * * Returns nonzero on error. If "silent" is false, reports the error. */ -int pv_remote_transferstate_fetch(pvstate_t state, pid_t query, bool silent) +int pv_remote_transferstate_fetch(pvstate_t state, pid_t query, /*@null@ */ off_t * sizeptr, bool silent) { char control_filename[4096]; /* flawfinder: ignore */ FILE *control_fptr; @@ -586,6 +599,8 @@ int pv_remote_transferstate_fetch(pvstate_t state, pid_t query, bool silent) if (pv__rxsignal_usr1(state, query)) { debug("%s", "response received"); received = true; + if (NULL != sizeptr) + *sizeptr = state->control.size; } } diff --git a/src/pv/loop.c b/src/pv/loop.c index 1be2112..0c6a98d 100644 --- a/src/pv/loop.c +++ b/src/pv/loop.c @@ -28,7 +28,7 @@ #include #endif -int pv_remote_transferstate_fetch(pvstate_t, pid_t, bool); +int pv_remote_transferstate_fetch(pvstate_t, pid_t, /*@null@ */ off_t *, bool); #if HAVE_SQRTL @@ -1250,7 +1250,7 @@ int pv_query_loop(pvstate_t state, pid_t query) * every short while. */ if (pv_elapsedtime_compare(&cur_time, &next_remotecheck) > 0) { - if (0 != pv_remote_transferstate_fetch(state, query, true)) + if (0 != pv_remote_transferstate_fetch(state, query, NULL, true)) break; (void) pv_remote_check(state); pv_elapsedtime_add_nsec(&next_remotecheck, REMOTE_INTERVAL);