Skip to content

Commit 4db8db3

Browse files
committed
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.
1 parent 84a6600 commit 4db8db3

File tree

5 files changed

+41
-4
lines changed

5 files changed

+41
-4
lines changed

ChangeLog

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
2021-11-15 Paul Eggert <eggert@cs.ucla.edu>
2+
3+
lseek: port around macOS SEEK_DATA glitch
4+
Problem reported by Sudhip Nashi (Bug#51857).
5+
* doc/posix-functions/lseek.texi (lseek): Mention macOS SEEK_DATA
6+
issue.
7+
* lib/lseek.c (rpl_lseek): Work around macOS portability glitch.
8+
* m4/lseek.m4 (gl_FUNC_LSEEK): Replace lseek on Darwin.
9+
* modules/lseek (Depends-on): Depend on msvc-nothrow
10+
and fstat only if needed.
11+
112
2021-11-11 Fabrice Fontaine <fontaine.fabrice@gmail.com> (tiny change)
213

314
sigsegv: fix builds on microblazeel, or1k

doc/posix-functions/lseek.texi

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ Gnulib module: lseek
99
Portability problems fixed by Gnulib:
1010
@itemize
1111
@item
12+
On some platforms, @code{lseek (fd, offset, SEEK_DATA)} returns a value
13+
greater than @code{offset} even when @code{offset} addresses data:
14+
macOS 12
15+
@item
1216
This function is declared in a different header file (namely, @code{<io.h>})
1317
on some platforms:
1418
MSVC 14.

lib/lseek.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,22 @@ rpl_lseek (int fd, off_t offset, int whence)
5252
errno = ESPIPE;
5353
return -1;
5454
}
55+
#elif defined __APPLE__ && defined __MACH__ && defined SEEK_DATA
56+
if (whence == SEEK_DATA)
57+
{
58+
/* If OFFSET points to data, macOS lseek+SEEK_DATA returns the
59+
start S of the first data region that begins *after* OFFSET,
60+
where the region from OFFSET to S consists of possibly-empty
61+
data followed by a possibly-empty hole. To work around this
62+
portability glitch, check whether OFFSET is within data by
63+
using lseek+SEEK_HOLE, and if so return to OFFSET by using
64+
lseek+SEEK_SET. */
65+
off_t next_hole = lseek (fd, offset, SEEK_HOLE);
66+
if (next_hole < 0)
67+
return next_hole;
68+
if (next_hole != offset)
69+
whence = SEEK_SET;
70+
}
5571
#else
5672
/* BeOS lseek mistakenly succeeds on pipes... */
5773
struct stat statbuf;

m4/lseek.m4

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# lseek.m4 serial 11
1+
# lseek.m4 serial 12
22
dnl Copyright (C) 2007, 2009-2021 Free Software Foundation, Inc.
33
dnl This file is free software; the Free Software Foundation
44
dnl gives unlimited permission to copy and/or distribute it,
@@ -59,7 +59,7 @@ AC_DEFUN([gl_FUNC_LSEEK],
5959
;;
6060
esac
6161
])
62-
if test $gl_cv_func_lseek_pipe = no; then
62+
if test "$gl_cv_func_lseek_pipe" = no; then
6363
REPLACE_LSEEK=1
6464
AC_DEFINE([LSEEK_PIPE_BROKEN], [1],
6565
[Define to 1 if lseek does not detect pipes.])
@@ -69,4 +69,10 @@ AC_DEFUN([gl_FUNC_LSEEK],
6969
if test $WINDOWS_64_BIT_OFF_T = 1; then
7070
REPLACE_LSEEK=1
7171
fi
72+
73+
dnl macOS SEEK_DATA is incompatible with other platforms.
74+
case $host_os in
75+
darwin*)
76+
REPLACE_LSEEK=1;;
77+
esac
7278
])

modules/lseek

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ Depends-on:
99
unistd
1010
sys_types
1111
largefile
12-
msvc-nothrow [test $REPLACE_LSEEK = 1]
13-
fstat [test $REPLACE_LSEEK = 1]
12+
msvc-nothrow [test $WINDOWS_64_BIT_OFF_T = 1]
13+
fstat [test "$gl_cv_func_lseek_pipe" = no]
1414

1515
configure.ac:
1616
gl_FUNC_LSEEK

0 commit comments

Comments
 (0)