Skip to content

Commit

Permalink
lseek: avoid SEEK_HOLE bugs in FreeBSD, macOS
Browse files Browse the repository at this point in the history
This attempts to fix <https://bugs.gnu.org/61386>, 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
<https://bugs.freebsd.org/256205>, 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.
  • Loading branch information
eggert committed Feb 23, 2023
1 parent bb3fd10 commit 7352d9f
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 6 deletions.
14 changes: 14 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
2023-02-23 Paul Eggert <eggert@cs.ucla.edu>

lseek: avoid SEEK_HOLE bugs in FreeBSD, macOS
This attempts to fix <https://bugs.gnu.org/61386>, 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
<https://bugs.freebsd.org/256205>, 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 <bruno@clisp.org>

configmake: Add support for $build_os != $host_os.
Expand Down
5 changes: 5 additions & 0 deletions doc/posix-functions/lseek.texi
Original file line number Diff line number Diff line change
Expand Up @@ -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
18 changes: 18 additions & 0 deletions lib/unistd.in.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,24 @@
# undef _GL_INCLUDING_UNISTD_H
#endif

/* Avoid lseek bugs in FreeBSD, macOS <https://bugs.gnu.org/61386>.
This bug is fixed after FreeBSD 13; see <https://bugs.freebsd.org/256205>.
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 <AvailabilityMacros.h>
# endif
# if (!defined MAC_OS_X_VERSION_MIN_REQUIRED \
|| MAC_OS_X_VERSION_MIN_REQUIRED < 99990000)
# include <sys/fcntl.h> /* 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
Expand Down
32 changes: 26 additions & 6 deletions m4/lseek.m4
Original file line number Diff line number Diff line change
@@ -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,
Expand Down Expand Up @@ -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 <https://bugs.gnu.org/61386>.
[[#include <unistd.h>
#if defined __APPLE__ && defined __MACH__ && defined SEEK_DATA
# ifdef __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__
# include <AvailabilityMacros.h>
# 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])
])

0 comments on commit 7352d9f

Please sign in to comment.