If discarding input but /dev/null can't be used as a splice() destination, fall back to normal read() rather than exiting with an error (#192).

This commit is contained in:
Andrew Wood
2026-05-26 22:36:58 +01:00
parent a0a097decb
commit e74cab6985
2 changed files with 15 additions and 12 deletions
+10 -8
View File
@@ -533,20 +533,22 @@ int pv_next_file(pvstate_t state, unsigned int filenum, int oldfd)
/*
* Open a file descriptor to /dev/null, so that input can be
* spliced to it to implement -X.
*
* If this fails, transfer.discard_fd will be left at -1,
* which means the transfer functions will not use splice().
*/
state->transfer.discard_fd = open("/dev/null", O_WRONLY); /* flawfinder: ignore */
/* flawfinder: /dev/null is trusted. */
if (state->transfer.discard_fd < 0) {
pv_perror("%s", "/dev/null");
(void) close(fd);
fd = -1;
state->status.exit_status |= PV_ERROREXIT_TRANSITION;
debug("%s: %s", "/dev/null", strerror(errno));
state->transfer.discard_fd = -1;
}
if (!pv_fd_is_dev_null(state->transfer.discard_fd, true)) {
(void) close(fd);
fd = -1;
state->status.exit_status |= PV_ERROREXIT_TRANSITION;
if (!pv_fd_is_dev_null(state->transfer.discard_fd, false)) {
if (state->transfer.discard_fd >= 0)
(void) close(state->transfer.discard_fd);
state->transfer.discard_fd = -1;
}
debug("%s: %d", "discard_fd", state->transfer.discard_fd);
}
#endif /* HAVE_SPLICE */
+5 -4
View File
@@ -432,11 +432,12 @@ static ssize_t pv__transfer__splice_repeated(pvstate_t state, int input_fd, int
/*
* Early return via pv__transfer__read_repeated() if splice() is
* turned off, or if line mode is active, or if splice() already
* failed on this input file descriptor, or if there's anything
* waiting in the transfer buffer.
* turned off, or if line mode is active, or if there's no output
* fd, or if splice() already failed on this input file descriptor,
* or if there's anything waiting in the transfer buffer.
*/
if (state->control.no_splice || state->control.linemode || (input_fd == state->transfer.splice_failed_fd)
if (state->control.no_splice || state->control.linemode || (output_fd < 0)
|| (input_fd == state->transfer.splice_failed_fd)
|| (state->transfer.to_write > 0)) {
return pv__transfer__read_repeated(input_fd, buf, count);
}