1/* An lseek() function that detects pipes.
2   Copyright (C) 2007 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, write to the Free Software Foundation,
16   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
17
18#include <config.h>
19
20/* Specification.  */
21#include <unistd.h>
22
23#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
24/* Windows platforms.  */
25/* Get GetFileType.  */
26# include <windows.h>
27#else
28# include <sys/stat.h>
29#endif
30#include <errno.h>
31
32#undef lseek
33
34off_t
35rpl_lseek (int fd, off_t offset, int whence)
36{
37#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
38  /* mingw lseek mistakenly succeeds on pipes, sockets, and terminals.  */
39  HANDLE h = (HANDLE) _get_osfhandle (fd);
40  if (h == INVALID_HANDLE_VALUE)
41    {
42      errno = EBADF;
43      return -1;
44    }
45  if (GetFileType (h) != FILE_TYPE_DISK)
46    {
47      errno = ESPIPE;
48      return -1;
49    }
50#else
51  /* BeOS lseek mistakenly succeeds on pipes...  */
52  struct stat statbuf;
53  if (fstat (fd, &statbuf) < 0)
54    return -1;
55  if (!S_ISREG (statbuf.st_mode))
56    {
57      errno = ESPIPE;
58      return -1;
59    }
60#endif
61  return lseek (fd, offset, whence);
62}
63