Correct the O_DIRECT flag setting to use the output file descriptor rather than assuming stdout.

This commit is contained in:
Andrew Wood
2024-10-05 14:17:15 +01:00
parent c548d1f2d8
commit de2fe7f6be
2 changed files with 20 additions and 15 deletions
+1
View File
@@ -8,6 +8,7 @@
* fix: prefix completion time ("`--fineta`") with *FIN* rather than *ETA* ([#43](https://codeberg.org/a-j-wood/pv/issues/43))
* fix: surround average rate ("`--average-rate`") with brackets rather than square brackets
* fix: correct a memory leak in "`--watchfd PID`"
* fix: make "`--direct-io`" work correctly with "`--output`" instead of assuming stdout
* fix: write UTC timestamps in debugging mode to avoid lockups in signal handlers
* cleanup: removed TODO.md, since it's just an outdated copy of the issue tracker
* cleanup: re-ordered structure members to reduce padding
+19 -15
View File
@@ -66,7 +66,7 @@ int pv_main_loop(pvstate_t state)
bool eof_in, eof_out, final_update;
struct timespec start_time, next_update, next_ratecheck, cur_time;
struct timespec init_time, next_remotecheck, transfer_elapsed;
int fd;
int input_fd, output_fd;
unsigned int file_idx;
/*
@@ -82,7 +82,11 @@ int pv_main_loop(pvstate_t state)
* The remaining variables are all unchanged by linemode.
*/
fd = -1;
input_fd = -1;
output_fd = state->control.output_fd;
if (output_fd < 0)
output_fd = STDOUT_FILENO;
pv_crs_init(state);
@@ -119,24 +123,24 @@ int pv_main_loop(pvstate_t state)
/*
* Open the first readable input file.
*/
fd = -1;
while (fd < 0 && file_idx < state->files.file_count) {
fd = pv_next_file(state, file_idx, -1);
if (fd < 0)
input_fd = -1;
while (input_fd < 0 && file_idx < state->files.file_count) {
input_fd = pv_next_file(state, file_idx, -1);
if (input_fd < 0)
file_idx++;
}
/*
* Exit early if there was no readable input file.
*/
if (fd < 0) {
if (input_fd < 0) {
if (state->control.cursor)
pv_crs_fini(state);
return state->status.exit_status;
}
#if HAVE_POSIX_FADVISE
/* Advise the OS that we will only be reading sequentially. */
(void) posix_fadvise(fd, 0, 0, POSIX_FADV_SEQUENTIAL);
(void) posix_fadvise(input_fd, 0, 0, POSIX_FADV_SEQUENTIAL);
#endif
#ifdef O_DIRECT
@@ -144,7 +148,7 @@ int pv_main_loop(pvstate_t state)
* Set or clear O_DIRECT on the output.
*/
if (0 !=
fcntl(STDOUT_FILENO, F_SETFL, (state->control.direct_io ? O_DIRECT : 0) | fcntl(STDOUT_FILENO, F_GETFL))) {
fcntl(output_fd, F_SETFL, (state->control.direct_io ? O_DIRECT : 0) | fcntl(output_fd, F_GETFL))) {
debug("%s: %s", "fcntl", strerror(errno));
}
state->control.direct_io_changed = false;
@@ -158,7 +162,7 @@ int pv_main_loop(pvstate_t state)
if (0 == state->control.target_buffer_size) {
struct stat sb;
memset(&sb, 0, sizeof(sb));
if (0 == fstat(fd, &sb)) {
if (0 == fstat(input_fd, &sb)) {
size_t sz;
sz = (size_t) (sb.st_blksize * 32);
if (sz > BUFFER_SIZE_MAX) {
@@ -224,7 +228,7 @@ int pv_main_loop(pvstate_t state)
&& (0 >= cansend) && eof_in && eof_out) {
written = 0;
} else {
written = pv_transfer(state, fd, &eof_in, &eof_out, cansend, &lineswritten);
written = pv_transfer(state, input_fd, &eof_in, &eof_out, cansend, &lineswritten);
}
/* End on write error. */
@@ -250,8 +254,8 @@ int pv_main_loop(pvstate_t state)
*/
while (eof_in && eof_out && file_idx < (state->files.file_count - 1)) {
file_idx++;
fd = pv_next_file(state, file_idx, fd);
if (fd >= 0) {
input_fd = pv_next_file(state, file_idx, input_fd);
if (input_fd >= 0) {
eof_in = false;
eof_out = false;
}
@@ -383,8 +387,8 @@ int pv_main_loop(pvstate_t state)
if (1 == state->flag.trigger_exit)
state->status.exit_status |= PV_ERROREXIT_SIGNAL;
if (fd >= 0)
(void) close(fd);
if (input_fd >= 0)
(void) close(input_fd);
/* Calculate and display the transfer statistics. */
if (state->control.show_stats && state->calc.measurements_taken > 0) {