Minor cleanups after merge.

This commit is contained in:
Andrew Wood
2024-06-08 21:21:11 +01:00
parent 578c1613d1
commit addf25ff16
8 changed files with 67 additions and 31 deletions
+1
View File
@@ -91,5 +91,6 @@ is acknowledged and greatly appreciated:
* [gustav-b](https://codeberg.org/gustav-b) - suggested percentage formatting correction ([#80](https://codeberg.org/a-j-wood/pv/issues/80))
* [Thomas Bertels](https://codeberg.org/tbertels) - updated French translations ([#83](https://codeberg.org/a-j-wood/pv/pulls/83))
* [kevinruddy](https://codeberg.org/kevinruddy) - added decimal units option ([#85](https://codeberg.org/a-j-wood/pv/pulls/85))
* [xmort](https://codeberg.org/xmort) - added "`--output`" option ([#90](https://codeberg.org/a-j-wood/pv/pulls/90))
---
+4
View File
@@ -1,3 +1,7 @@
### NOT YET RELEASED
* feature: new "`--output`" option to write to a file instead of standard output (pull request [#90](https://codeberg.org/a-j-wood/pv/pulls/90)) supplied by [xmort](https://codeberg.org/xmort)
### 1.8.9 - 21 April 2024
* feature: new "`--si`" option to display and interpret size suffixes in multiples of 1000 rather than 1024 (pull request [#85](https://codeberg.org/a-j-wood/pv/pulls/85)) supplied by [kevinruddy](https://codeberg.org/kevinruddy)
+2 -1
View File
@@ -347,7 +347,8 @@ invocations in a single, long, pipeline.
.BI \-o\ FILE \fR,\ \fB\-\-output\ FILE
Write data to
.I FILE
rather than stdout.
rather than standard output. If the file already exists, it will be
overwritten from the start, but not truncated.
.TP
.BI \-L\ RATE \fR,\ \fB\-\-rate-limit\ RATE
Limit the transfer to a maximum of
+6
View File
@@ -257,6 +257,12 @@ that are explicitly switched on will be shown.
# DATA TRANSFER MODIFIERS
**-o FILE, \--output FILE**
: Write data to *FILE* rather than standard output. If the file
already exists, it will be overwritten from the start, but not
truncated.
**-L RATE, \--rate-limit RATE**
: Limit the transfer to a maximum of *RATE* bytes per second. A suffix
+17 -8
View File
@@ -12,7 +12,7 @@
#include "pv.h"
/* We do not set this because it breaks "dd" - see below. */
/* #undef MAKE_STDOUT_NONBLOCKING */
/* #undef MAKE_OUTPUT_NONBLOCKING */
#include <stdio.h>
#include <string.h>
@@ -306,23 +306,32 @@ int main(int argc, char **argv)
if (NULL == opts->output || 0 == strcmp(opts->output, "-")) {
pv_state_output_set(state, STDOUT_FILENO, "(stdout)");
} else {
int fd = open(opts->output, O_WRONLY | O_CREAT);
int fd = open(opts->output, O_WRONLY | O_CREAT, 0600); /* flawfinder: ignore */
/*
* flawfinder rationale: the output filename has been
* explicitly provided, and in many cases the operator will
* want to write to device files and other special
* destinations, so there is no sense-checking we can do to
* make this safer.
*/
if (fd < 0) {
fprintf(stderr, "%s: %s: %s\n", opts->program_name, opts->output, strerror(errno));
return 1;
pv_state_free(state);
opts_free(opts);
return 2;
}
pv_state_output_set(state, fd, opts->output);
}
#ifdef MAKE_STDOUT_NONBLOCKING
#ifdef MAKE_OUTPUT_NONBLOCKING
/*
* Try and make standard output use non-blocking I/O.
* Try and make the output use non-blocking I/O.
*
* Note that this can cause problems with (broken) applications
* such as dd.
* such as dd when used in a pipeline.
*/
fcntl(STDOUT_FILENO, F_SETFL, O_NONBLOCK | fcntl(STDOUT_FILENO, F_GETFL));
#endif /* MAKE_STDOUT_NONBLOCKING */
fcntl(state->control.output_fd, F_SETFL, O_NONBLOCK | fcntl(state->control.output_fd, F_GETFL));
#endif /* MAKE_OUTPUT_NONBLOCKING */
/* Initialise the signal handling. */
pv_sig_init(state);
+2 -1
View File
@@ -144,7 +144,8 @@ static off_t pv_calc_total_bytes(pvstate_t state)
total = end_position;
}
if (lseek(state->control.output_fd, 0, SEEK_SET) != 0) {
pv_error(state, "%s: %s: %s", state->control.output_name,
pv_error(state, "%s: %s: %s",
NULL == state->control.output_name ? "(null)" : state->control.output_name,
_("failed to seek to start of output"), strerror(errno));
state->status.exit_status |= 2;
}
+32 -20
View File
@@ -107,6 +107,26 @@ void pv_state_free(pvstate_t state)
if (0 == state)
return;
/*
* Close the output file first, so we can report any errors while we
* still know the program name and output filename.
*/
if (state->control.output_fd >= 0) {
if (STDOUT_FILENO != state->control.output_fd) {
if (close(state->control.output_fd) < 0) {
fprintf(stderr, "%s: %s: %s\n", state->status.program_name,
NULL == state->control.output_name ? "(null)" : state->control.output_name,
strerror(errno));
}
}
state->control.output_fd = -1;
}
if (NULL != state->control.output_name) {
free(state->control.output_name);
state->control.output_name = NULL;
}
if (NULL != state->status.program_name)
free(state->status.program_name);
state->status.program_name = NULL;
@@ -125,23 +145,6 @@ void pv_state_free(pvstate_t state)
state->control.format_string = NULL;
}
if (NULL != state->control.output_name) {
free(state->control.output_name);
state->control.output_name = NULL;
}
if (NULL != state->control.output_name) {
free(state->control.output_name);
state->control.output_name = NULL;
}
if (state->control.output_fd >= 0) {
if (STDOUT_FILENO != state->control.output_fd) {
close(state->control.output_fd);
}
state->control.output_fd = -1;
}
/*@-keeptrans@ */
if (NULL != state->transfer.transfer_buffer)
free(state->transfer.transfer_buffer);
@@ -367,12 +370,21 @@ void pv_state_watch_fd_set(pvstate_t state, int val)
void pv_state_output_set(pvstate_t state, int fd, const char *name)
{
/*
* Close any previous output file first, so we can report any errors
* before we store the new output filename.
*/
if (state->control.output_fd >= 0 && state->control.output_fd != STDOUT_FILENO) {
if (close(state->control.output_fd) < 0) {
fprintf(stderr, "%s: %s: %s\n", state->status.program_name,
NULL == state->control.output_name ? "(null)" : state->control.output_name,
strerror(errno));
}
}
if (NULL != state->control.output_name)
free(state->control.output_name);
if (state->control.output_fd >= 0 && state->control.output_fd != STDOUT_FILENO)
close(state->control.output_fd);
state->control.output_fd = fd;
state->control.output_name = strdup(name);
state->control.output_name = pv_strdup(name);
}
void pv_state_average_rate_window_set(pvstate_t state, unsigned int val)
+3 -1
View File
@@ -931,7 +931,9 @@ ssize_t pv_transfer(pvstate_t state, int fd, bool *eof_in, bool *eof_out, off_t
if (0 != fcntl(state->control.output_fd, F_SETFL,
(state->control.direct_io ? O_DIRECT : 0) |
fcntl(state->control.output_fd, F_GETFL))) {
debug("%s: %s: %s", state->control.output_name, "fcntl", strerror(errno));
debug("%s: %s: %s",
NULL == state->control.output_name ? "(null)" : state->control.output_name,
"fcntl", strerror(errno));
}
}
state->control.direct_io_changed = false;