diff --git a/bin/cat/cat.c b/bin/cat/cat.c --- a/bin/cat/cat.c +++ b/bin/cat/cat.c @@ -84,6 +84,7 @@ #ifndef BOOTSTRAP_CAT static void cook_cat(FILE *); #endif +static int in_kernel_copy(int); static void raw_cat(int); #ifndef NO_UDOM_SUPPORT @@ -280,7 +281,11 @@ } #endif } else { - raw_cat(fd); + if (in_kernel_copy(fd) == -1) { + if (errno == EINVAL) + raw_cat(fd); + else + err(1, "stdout"); if (fd != STDIN_FILENO) close(fd); } @@ -382,6 +387,20 @@ } #endif /* BOOTSTRAP_CAT */ +static int +in_kernel_copy(int rfd) +{ + int ret, wfd; + + wfd = fileno(stdout); + ret = 1; + + while (ret > 0) + ret = copy_file_range(rfd, NULL, wfd, NULL, SSIZE_MAX, 0); + + return (ret); +} + static void raw_cat(int rfd) {