1/* An lseek() function that detects pipes.
2   Copyright (C) 2007, 2009-2014 Free Software Foundation, Inc.
3
4   This program is free software; you can redistribute it and/or modify
5   it under the terms of the GNU General Public License as published by
6   the Free Software Foundation; either version 3, or (at your option)
7   any later version.
8
9   This program is distributed in the hope that it will be useful,
10   but WITHOUT ANY WARRANTY; without even the implied warranty of
11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12   GNU General Public License for more details.
13
14   You should have received a copy of the GNU General Public License along
15   with this program; if not, see <http://www.gnu.org/licenses/>.  */
16
17#include <config.h>
18
19/* Specification.  */
20#include <unistd.h>
21
22#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
23/* Windows platforms.  */
24/* Get GetFileType.  */
25# include <windows.h>
26/* Get _get_osfhandle.  */
27# include "msvc-nothrow.h"
28#else
29# include <sys/stat.h>
30#endif
31#include <errno.h>
32
33#undef lseek
34
35off_t
36rpl_lseek (int fd, off_t offset, int whence)
37{
38#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
39  /* mingw lseek mistakenly succeeds on pipes, sockets, and terminals.  */
40  HANDLE h = (HANDLE) _get_osfhandle (fd);
41  if (h == INVALID_HANDLE_VALUE)
42    {
43      errno = EBADF;
44      return -1;
45    }
46  if (GetFileType (h) != FILE_TYPE_DISK)
47    {
48      errno = ESPIPE;
49      return -1;
50    }
51#else
52  /* BeOS lseek mistakenly succeeds on pipes...  */
53  struct stat statbuf;
54  if (fstat (fd, &statbuf) < 0)
55    return -1;
56  if (!S_ISREG (statbuf.st_mode))
57    {
58      errno = ESPIPE;
59      return -1;
60    }
61#endif
62#if _GL_WINDOWS_64_BIT_OFF_T
63  return _lseeki64 (fd, offset, whence);
64#else
65  return lseek (fd, offset, whence);
66#endif
67}
68