| 554 | -1 if a serious problem has been diagnosed. */ |
| 555 | |
| 556 | static int |
| 557 | splice_cat (void) |
| 558 | { |
| 559 | bool some_copied = false; |
| 560 | bool in_ok = true; |
| 561 | bool out_ok = true; |
| 562 | |
| 563 | #if HAVE_SPLICE |
| 564 | |
| 565 | /* If PIPEFD[0] is a non-negative value, we have an open pipe from a |
| 566 | previous call to this function. At the start of this function the |
| 567 | pipe will always be empty. */ |
| 568 | static int pipefd[2] = { -1, -1 }; |
| 569 | |
| 570 | /* The size of the pipe referred to by PIPEFD. */ |
| 571 | static idx_t pipefd_pipe_size = 0; |
| 572 | |
| 573 | /* Create an intermediate pipe if it is not already open. |
| 574 | Even if both input and output are pipes, |
| 575 | so that read and write errors can be distinguished. */ |
| 576 | if (pipefd[0] < 0) |
| 577 | { |
| 578 | if (pipe (pipefd) < 0) |
| 579 | return false; |
| 580 | pipefd_pipe_size = increase_pipe_size (pipefd[1]); |
| 581 | } |
| 582 | |
| 583 | /* Increase the size of the pipe referred to by standard output. */ |
| 584 | static int stdout_is_pipe = -1; |
| 585 | static idx_t stdout_pipe_size = 0; |
| 586 | if (stdout_is_pipe == -1) |
| 587 | { |
| 588 | stdout_is_pipe = 0 < isapipe (STDOUT_FILENO); |
| 589 | if (stdout_is_pipe) |
| 590 | stdout_pipe_size = increase_pipe_size (STDOUT_FILENO); |
| 591 | } |
| 592 | |
| 593 | idx_t pipe_size = MAX (pipefd_pipe_size, stdout_pipe_size); |
| 594 | |
| 595 | while (true) |
| 596 | { |
| 597 | ssize_t bytes_read = splice (input_desc, NULL, pipefd[1], NULL, |
| 598 | pipe_size, 0); |
| 599 | /* If we successfully splice'd input previously, assume that any |
| 600 | subsequent error is fatal. If not, then fall back to read |
| 601 | and write. */ |
| 602 | in_ok = 0 <= bytes_read || ! some_copied; |
| 603 | if (bytes_read == 0) |
| 604 | some_copied = true; /* Indicate splice complete. */ |
| 605 | if (bytes_read <= 0) |
| 606 | goto done; |
| 607 | /* We need to drain the intermediate pipe to standard output. */ |
| 608 | while (0 < bytes_read) |
| 609 | { |
| 610 | ssize_t bytes_written = splice (pipefd[0], NULL, STDOUT_FILENO, NULL, |
| 611 | pipe_size, 0); |
| 612 | /* If we successfully splice'd output, assume any subsequent |
| 613 | error is fatal. If not, than drain the intermediate pipe and |
no test coverage detected