| 519 | -1 if a serious problem has been diagnosed. */ |
| 520 | |
| 521 | static int |
| 522 | copy_cat (void) |
| 523 | { |
| 524 | /* Copy at most COPY_MAX bytes at a time; this is min |
| 525 | (SSIZE_MAX, SIZE_MAX) truncated to a value that is |
| 526 | surely aligned well. */ |
| 527 | ssize_t copy_max = MIN (SSIZE_MAX, SIZE_MAX) >> 30 << 30; |
| 528 | |
| 529 | /* copy_file_range does not support some cases, and it |
| 530 | incorrectly returns 0 when reading from the proc file |
| 531 | system on the Linux kernel through at least 5.6.19 (2020), |
| 532 | so fall back on read+write if the copy_file_range is |
| 533 | unsupported or the input file seems empty. */ |
| 534 | |
| 535 | for (bool some_copied = false; ; some_copied = true) |
| 536 | switch (copy_file_range (input_desc, NULL, STDOUT_FILENO, NULL, |
| 537 | copy_max, 0)) |
| 538 | { |
| 539 | case 0: |
| 540 | return some_copied; |
| 541 | |
| 542 | case -1: |
| 543 | if (errno == ENOSYS || is_ENOTSUP (errno) || errno == EINVAL |
| 544 | || errno == EBADF || errno == EXDEV || errno == ETXTBSY |
| 545 | || errno == EPERM || errno == EFBIG) |
| 546 | return 0; |
| 547 | error (0, errno, "%s", quotef (infile)); |
| 548 | return -1; |
| 549 | } |
| 550 | } |
| 551 | |
| 552 | /* Copy data from input to output using splice if possible. |
| 553 | Return 1 if successful, 0 if ordinary read+write should be tried, |