summaryrefslogtreecommitdiffstats
path: root/libgnu/lseek.c
diff options
context:
space:
mode:
authorUlf Hermann <[email protected]>2017-02-23 17:22:41 +0100
committerUlf Hermann <[email protected]>2017-04-27 15:56:33 +0000
commit121d248c1da7f2130a2edde6d158f116c89ed407 (patch)
treead7a348a88db648da6e2df366d89fcb7b7436a1c /libgnu/lseek.c
parentf10810fff6fda147f9c07fea0e1b33a7c4d79ad1 (diff)
Add gnulib modules to replace missing libc functionality
This enables us to build a fully featured elfutils package on systems with reduced C libraries, such as windows. All the modules are built into libgnu.a, which is then linked into all binaries if --enable-gnulib is given on the configure line. Change-Id: I743fd22172bc85d9f10dcc3dad8eb921f462b554 Reviewed-by: Christian Kandeler <[email protected]>
Diffstat (limited to 'libgnu/lseek.c')
-rw-r--r--libgnu/lseek.c67
1 files changed, 67 insertions, 0 deletions
diff --git a/libgnu/lseek.c b/libgnu/lseek.c
new file mode 100644
index 00000000..3b2fdf2e
--- /dev/null
+++ b/libgnu/lseek.c
@@ -0,0 +1,67 @@
+/* An lseek() function that detects pipes.
+ Copyright (C) 2007, 2009-2017 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, see <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+/* Specification. */
+#include <unistd.h>
+
+#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+/* Windows platforms. */
+/* Get GetFileType. */
+# include <windows.h>
+/* Get _get_osfhandle. */
+# include "msvc-nothrow.h"
+#else
+# include <sys/stat.h>
+#endif
+#include <errno.h>
+
+#undef lseek
+
+off_t
+rpl_lseek (int fd, off_t offset, int whence)
+{
+#if (defined _WIN32 || 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;
+ }
+#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
+ return _lseeki64 (fd, offset, whence);
+#else
+ return lseek (fd, offset, whence);
+#endif
+}