(root)/
gettext-0.22.4/
gettext-tools/
gnulib-lib/
copy-file-range.c
       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  }