From: Pádraig Brady Date: Fri, 17 Apr 2026 13:36:26 +0000 (+0100) Subject: yes: make operation independent of pipe size X-Git-Tag: v9.11~3 X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=3cbe0491bab713e07cf0b1e51f5e3dad2b707215;p=thirdparty%2Fcoreutils.git yes: make operation independent of pipe size * src/yes.c (splice_write): Always drain what we've written to an internal pipe, so there is no possibility of vmsplice() blocking. I.e., be defensive in the case that fcntl() fails, and our default buffer size (currently 16kiB) is larger than the pipe. https://github.com/coreutils/coreutils/issues/253 --- diff --git a/src/yes.c b/src/yes.c index d111b125ee..8774d73f3f 100644 --- a/src/yes.c +++ b/src/yes.c @@ -144,32 +144,32 @@ splice_write (MAYBE_UNUSED char const *buf, MAYBE_UNUSED idx_t copysize) while (iov.iov_len > 0) { - /* Use SPLICE_F_{GIFT,MOVE} to allow the kernel to take references - to the pages. I.e., we're indicating we won't make changes. - SPLICE_F_GIFT is only appropriate for full pages. */ + /* Use SPLICE_F_{GIFT,MOVE} to allow the kernel to take references + to the pages. I.e., we're indicating we won't make changes. + SPLICE_F_GIFT is only appropriate for full pages. */ unsigned int flags = iov.iov_len % page_size ? 0 : SPLICE_F_GIFT; ssize_t n = vmsplice (vmsplice_fd, &iov, 1, flags); if (n <= 0) goto done; + if (stdout_is_pipe) output_started = true; - iov.iov_base = (char *) iov.iov_base + n; - iov.iov_len -= n; - } - - /* For non-pipe stdout, drain intermediate pipe to stdout. */ - if (! stdout_is_pipe) - { - idx_t remaining = splice_bufsize; - while (remaining > 0) + else { - ssize_t s = splice (pipefd[0], NULL, STDOUT_FILENO, NULL, - remaining, SPLICE_F_MOVE); - if (s <= 0) - goto done; - output_started = true; - remaining -= s; + idx_t remaining = n; + while (remaining > 0) + { + ssize_t s = splice (pipefd[0], NULL, STDOUT_FILENO, NULL, + remaining, SPLICE_F_MOVE); + if (s <= 0) + goto done; + output_started = true; + remaining -= s; + } } + + iov.iov_base = (char *) iov.iov_base + n; + iov.iov_len -= n; } }