1 /* Stub for copy_file_range 2 Copyright 2019-2023 Free Software Foundation, Inc. 3 4 This file is free software: you can redistribute it and/or modify 5 it under the terms of the GNU Lesser General Public License as 6 published by the Free Software Foundation; either version 2.1 of the 7 License, or (at your option) any later version. 8 9 This file is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU Lesser General Public License for more details. 13 14 You should have received a copy of the GNU Lesser General Public License 15 along with this program. If not, see <https://www.gnu.org/licenses/>. */ 16 17 #include <config.h> 18 19 #include <unistd.h> 20 21 #include <errno.h> 22 23 #if defined __linux__ && HAVE_COPY_FILE_RANGE 24 # include <sys/utsname.h> 25 #endif 26 27 ssize_t 28 copy_file_range (int infd, off_t *pinoff, 29 int outfd, off_t *poutoff, 30 size_t length, unsigned int flags) 31 { 32 #undef copy_file_range 33 34 #if defined __linux__ && HAVE_COPY_FILE_RANGE 35 /* The implementation of copy_file_range (which first appeared in 36 Linux kernel release 4.5) had many issues before release 5.3 37 <https://lwn.net/Articles/789527/>, so fail with ENOSYS for Linux 38 kernels 5.2 and earlier. 39 40 This workaround, and the configure-time check for Linux, can be 41 removed when such kernels (released March 2016 through September 42 2019) are no longer a consideration. As of January 2021, the 43 furthest-future planned kernel EOL is December 2024 for kernel 44 release 4.19. */ 45 46 static signed char ok; 47 48 if (! ok) 49 { 50 struct utsname name; 51 uname (&name); 52 char *p = name.release; 53 ok = ((p[1] != '.' || '5' < p[0] 54 || (p[0] == '5' && (p[3] != '.' || '2' < p[2]))) 55 ? 1 : -1); 56 } 57 58 if (0 < ok) 59 return copy_file_range (infd, pinoff, outfd, poutoff, length, flags); 60 #endif 61 62 /* There is little need to emulate copy_file_range with read+write, 63 since programs that use copy_file_range must fall back on 64 read+write anyway. */ 65 errno = ENOSYS; 66 return -1; 67 }