From b3925d944ed94cc76bbcbb14a799ec9beeb8d1bf Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 10 Apr 2024 22:25:44 +0200 Subject: Adding upstream version 1.21.4. Signed-off-by: Daniel Baumann --- lib/lseek.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 lib/lseek.c (limited to 'lib/lseek.c') diff --git a/lib/lseek.c b/lib/lseek.c new file mode 100644 index 0000000..7919b03 --- /dev/null +++ b/lib/lseek.c @@ -0,0 +1,89 @@ +/* An lseek() function that detects pipes. + Copyright (C) 2007, 2009-2023 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#include + +/* Specification. */ +#include + +#if defined _WIN32 && ! defined __CYGWIN__ +/* Windows platforms. */ +/* Get GetFileType. */ +# include +/* Get _get_osfhandle. */ +# if GNULIB_MSVC_NOTHROW +# include "msvc-nothrow.h" +# else +# include +# endif +#else +# include +#endif +#include + +#undef lseek + +off_t +rpl_lseek (int fd, off_t offset, int whence) +{ +#if defined _WIN32 && ! defined __CYGWIN__ + /* mingw lseek mistakenly succeeds on pipes, sockets, and terminals. */ + HANDLE h = (HANDLE) _get_osfhandle (fd); + if (h == INVALID_HANDLE_VALUE) + { + errno = EBADF; + return -1; + } + if (GetFileType (h) != FILE_TYPE_DISK) + { + 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. Also, contrary to the macOS documentation, + lseek+SEEK_HOLE can fail with ENXIO if there are no holes on + or after OFFSET. What a mess! */ + off_t next_hole = lseek (fd, offset, SEEK_HOLE); + if (next_hole < 0) + return errno == ENXIO ? offset : next_hole; + if (next_hole != offset) + whence = SEEK_SET; + } +#else + /* BeOS lseek mistakenly succeeds on pipes... */ + struct stat statbuf; + if (fstat (fd, &statbuf) < 0) + return -1; + if (!S_ISREG (statbuf.st_mode)) + { + errno = ESPIPE; + return -1; + } +#endif +#if _GL_WINDOWS_64_BIT_OFF_T || (defined __MINGW32__ && defined _FILE_OFFSET_BITS && (_FILE_OFFSET_BITS == 64)) + return _lseeki64 (fd, offset, whence); +#else + return lseek (fd, offset, whence); +#endif +} -- cgit v1.2.3