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:
+10
-8
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user