]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
yes: make operation independent of pipe size
authorPádraig Brady <P@draigBrady.com>
Fri, 17 Apr 2026 13:36:26 +0000 (14:36 +0100)
committerPádraig Brady <P@draigBrady.com>
Fri, 17 Apr 2026 15:15:08 +0000 (16:15 +0100)
* 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

src/yes.c

index d111b125ee6a3f78cebe9db119500fa5bb420936..8774d73f3f6878043d8e33c065c965e86f437b46 100644 (file)
--- 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;
         }
     }