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