]> Savannah Git Hosting - gnulib.git/commitdiff
lseek: port around macOS SEEK_DATA glitch
authorPaul Eggert <eggert@cs.ucla.edu>
Mon, 15 Nov 2021 23:08:25 +0000 (15:08 -0800)
committerPaul Eggert <eggert@cs.ucla.edu>
Mon, 15 Nov 2021 23:11:57 +0000 (15:11 -0800)
Problem reported by Sudhip Nashi (Bug#51857).
* doc/posix-functions/lseek.texi (lseek): Mention macOS SEEK_DATA
issue.
* lib/lseek.c (rpl_lseek): Work around macOS portability glitch.
* m4/lseek.m4 (gl_FUNC_LSEEK): Replace lseek on Darwin.
* modules/lseek (Depends-on): Depend on msvc-nothrow
and fstat only if needed.

ChangeLog
doc/posix-functions/lseek.texi
lib/lseek.c
m4/lseek.m4
modules/lseek

index f47071a72de3d95237924d80bd2ecb915bfd7a92..71a22657065265fd115bb797e4dca5e5b73bcd4f 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2021-11-15  Paul Eggert  <eggert@cs.ucla.edu>
+
+       lseek: port around macOS SEEK_DATA glitch
+       Problem reported by Sudhip Nashi (Bug#51857).
+       * doc/posix-functions/lseek.texi (lseek): Mention macOS SEEK_DATA
+       issue.
+       * lib/lseek.c (rpl_lseek): Work around macOS portability glitch.
+       * m4/lseek.m4 (gl_FUNC_LSEEK): Replace lseek on Darwin.
+       * modules/lseek (Depends-on): Depend on msvc-nothrow
+       and fstat only if needed.
+
 2021-11-11  Fabrice Fontaine  <fontaine.fabrice@gmail.com>  (tiny change)
 
        sigsegv: fix builds on microblazeel, or1k
index 4a9d55dcf7c243e7337d20020221a9386cd29980..2f8e2b587767eab2874076ad6bff404210c95323 100644 (file)
@@ -9,6 +9,10 @@ Gnulib module: lseek
 Portability problems fixed by Gnulib:
 @itemize
 @item
+On some platforms, @code{lseek (fd, offset, SEEK_DATA)} returns a value
+greater than @code{offset} even when @code{offset} addresses data:
+macOS 12
+@item
 This function is declared in a different header file (namely, @code{<io.h>})
 on some platforms:
 MSVC 14.
index 0042546a8eeac84dffd9cf8377055de129b5ae13..7dcd6c9da703bfac2c065abed94861c5ecb41c30 100644 (file)
@@ -52,6 +52,22 @@ rpl_lseek (int fd, off_t offset, int whence)
       errno = ESPIPE;
       return -1;
     }
+#elif defined __APPLE__ && defined __MACH__ && defined SEEK_DATA
+  if (whence == SEEK_DATA)
+    {
+      /* If OFFSET points to data, macOS lseek+SEEK_DATA returns the
+         start S of the first data region that begins *after* OFFSET,
+         where the region from OFFSET to S consists of possibly-empty
+         data followed by a possibly-empty hole.  To work around this
+         portability glitch, check whether OFFSET is within data by
+         using lseek+SEEK_HOLE, and if so return to OFFSET by using
+         lseek+SEEK_SET.  */
+      off_t next_hole = lseek (fd, offset, SEEK_HOLE);
+      if (next_hole < 0)
+        return next_hole;
+      if (next_hole != offset)
+        whence = SEEK_SET;
+    }
 #else
   /* BeOS lseek mistakenly succeeds on pipes...  */
   struct stat statbuf;
index 0af63780ab71b935b98d28fd1729bff7907192db..faab09b734b0b6b54eaffcd142fcfda3e585428b 100644 (file)
@@ -1,4 +1,4 @@
-# lseek.m4 serial 11
+# lseek.m4 serial 12
 dnl Copyright (C) 2007, 2009-2021 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -59,7 +59,7 @@ AC_DEFUN([gl_FUNC_LSEEK],
          ;;
      esac
     ])
-  if test $gl_cv_func_lseek_pipe = no; then
+  if test "$gl_cv_func_lseek_pipe" = no; then
     REPLACE_LSEEK=1
     AC_DEFINE([LSEEK_PIPE_BROKEN], [1],
       [Define to 1 if lseek does not detect pipes.])
@@ -69,4 +69,10 @@ AC_DEFUN([gl_FUNC_LSEEK],
   if test $WINDOWS_64_BIT_OFF_T = 1; then
     REPLACE_LSEEK=1
   fi
+
+  dnl macOS SEEK_DATA is incompatible with other platforms.
+  case $host_os in
+    darwin*)
+      REPLACE_LSEEK=1;;
+  esac
 ])
index ced4431235b24fc61c7fcc32e3537c8ecba84716..f60809319fb8b64681e8a82b5c24f9f3f97d9e15 100644 (file)
@@ -9,8 +9,8 @@ Depends-on:
 unistd
 sys_types
 largefile
-msvc-nothrow    [test $REPLACE_LSEEK = 1]
-fstat           [test $REPLACE_LSEEK = 1]
+msvc-nothrow    [test $WINDOWS_64_BIT_OFF_T = 1]
+fstat           [test "$gl_cv_func_lseek_pipe" = no]
 
 configure.ac:
 gl_FUNC_LSEEK