From 7352d9fec59398c76c3bb8a2ef86ba58818f0342 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sun, 19 Feb 2023 00:05:24 -0600 Subject: [PATCH] lseek: avoid SEEK_HOLE bugs in FreeBSD, macOS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This attempts to fix , a bug in GNU cp caused by a serious data corruption bug in FreeBSD and macOS. * doc/posix-functions/lseek.texi: Mention the bug. * lib/unistd.in.h (SEEK_DATA, SEEK_HOLE): Undef in macOS < 13 and FreeBSD < 14. FreeBSD fixed the bug sometime during FreeBSD 13 , so the "FreeBSD < 14" is conservative. It’s unknown when Apple will fix macOS so use macOS "9999" as a placeholder. * m4/lseek.m4 (gl_FUNC_LSEEK): Replace lseek if on one of the above platforms. --- ChangeLog | 14 ++++++++++++++ doc/posix-functions/lseek.texi | 5 +++++ lib/unistd.in.h | 18 ++++++++++++++++++ m4/lseek.m4 | 32 ++++++++++++++++++++++++++------ 4 files changed, 63 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index c1ca610548..5e436f5b3a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2023-02-23 Paul Eggert + + lseek: avoid SEEK_HOLE bugs in FreeBSD, macOS + This attempts to fix , a bug in GNU cp + caused by a serious data corruption bug in FreeBSD and macOS. + * doc/posix-functions/lseek.texi: Mention the bug. + * lib/unistd.in.h (SEEK_DATA, SEEK_HOLE): Undef in macOS < 13 and + FreeBSD < 14. FreeBSD fixed the bug sometime during FreeBSD 13 + , so the "FreeBSD < 14" is + conservative. It’s unknown when Apple will fix macOS so use + macOS "9999" as a placeholder. + * m4/lseek.m4 (gl_FUNC_LSEEK): Replace lseek if on one of the + above platforms. + 2023-02-18 Bruno Haible configmake: Add support for $build_os != $host_os. diff --git a/doc/posix-functions/lseek.texi b/doc/posix-functions/lseek.texi index 2f8e2b5877..3470524b12 100644 --- a/doc/posix-functions/lseek.texi +++ b/doc/posix-functions/lseek.texi @@ -37,4 +37,9 @@ IRIX 6.5. @item Some systems do not support @code{SEEK_DATA} and @code{SEEK_HOLE}: AIX, HP-UX, Microsoft Windows, NetBSD, OpenBSD. +@item +Some systems have a buggy @code{SEEK_DATA} and @code{SEEK_HOLE}, +and Gnulib works around the problem via @code{#undef SEEK_DATA} +and @code{#undef SEEK_HOLE}: +FreeBSD 13, macOS 12. @end itemize diff --git a/lib/unistd.in.h b/lib/unistd.in.h index bfc501e5a7..8ba9867894 100644 --- a/lib/unistd.in.h +++ b/lib/unistd.in.h @@ -40,6 +40,24 @@ # undef _GL_INCLUDING_UNISTD_H #endif +/* Avoid lseek bugs in FreeBSD, macOS . + This bug is fixed after FreeBSD 13; see . + Use macOS "9999" to stand for a future fixed macOS version. */ +#if defined __FreeBSD__ && __FreeBSD__ < 14 +# undef SEEK_DATA +# undef SEEK_HOLE +#elif defined __APPLE__ && defined __MACH__ && defined SEEK_DATA +# ifdef __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ +# include +# endif +# if (!defined MAC_OS_X_VERSION_MIN_REQUIRED \ + || MAC_OS_X_VERSION_MIN_REQUIRED < 99990000) +# include /* It also defines the two macros. */ +# undef SEEK_DATA +# undef SEEK_HOLE +# endif +#endif + /* Get all possible declarations of gethostname(). */ #if @GNULIB_GETHOSTNAME@ && @UNISTD_H_HAVE_WINSOCK2_H@ \ && !defined _GL_INCLUDING_WINSOCK2_H diff --git a/m4/lseek.m4 b/m4/lseek.m4 index fd4f1f27d3..6e1ab6ffaa 100644 --- a/m4/lseek.m4 +++ b/m4/lseek.m4 @@ -1,4 +1,4 @@ -# lseek.m4 serial 12 +# lseek.m4 serial 13 dnl Copyright (C) 2007, 2009-2023 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -70,9 +70,29 @@ AC_DEFUN([gl_FUNC_LSEEK], REPLACE_LSEEK=1 fi - dnl macOS SEEK_DATA is incompatible with other platforms. - case $host_os in - darwin*) - REPLACE_LSEEK=1;; - esac + AS_IF([test $REPLACE_LSEEK = 0], + [AC_CACHE_CHECK([whether SEEK_DATA works but is incompatible with GNU], + [gl_cv_func_lseek_works_but_incompatible], + [AC_PREPROC_IFELSE( + [AC_LANG_SOURCE( + dnl Use macOS "9999" to stand for a future fixed macOS version. + dnl See ../lib/unistd.in.h and . + [[#include + #if defined __APPLE__ && defined __MACH__ && defined SEEK_DATA + # ifdef __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ + # include + # endif + # if 99990000 <= MAC_OS_X_VERSION_MIN_REQUIRED + # define LSEEK_WORKS_BUT_IS_INCOMPATIBLE_WITH_GNU + # endif + #endif + #ifndef LSEEK_WORKS_BUT_IS_INCOMPATIBLE_WITH_GNU + #error "No need to work around the bug" + #endif + ]])], + [gl_cv_func_lseek_works_but_incompatible=yes], + [gl_cv_func_lseek_works_but_incompatible=no])]) + if test "$gl_cv_func_lseek_works_but_incompatible" = yes; then + REPLACE_LSEEK=1 + fi]) ]) -- 2.39.2