prelude-lml/master: Import GnuLib fseeko & ftello modules

[email protected] Mon, 8 Feb 2010 11:53:29 +0100 (CET)
Newsgroups gmane.comp.security.ids.prelude.cvs
Message-ID <[email protected]>
commit 2dc68f1b8e27f9d1fca114e138237565d59c8693
Author: Yoann Vandoorselaere <[email protected]>
Date:   Mon Feb 8 11:40:28 2010 +0100

    Import GnuLib fseeko & ftello modules


========================================

 libmissing/Makefile.am             |   29 +++++++-
 libmissing/fseeko.c                |  147 ++++++++++++++++++++++++++++++++++++
 libmissing/ftello.c                |   54 +++++++++++++
 libmissing/lseek.c                 |   62 +++++++++++++++
 libmissing/m4/fseeko.m4            |   35 +++++++++
 libmissing/m4/ftello.m4            |   32 ++++++++
 libmissing/m4/gnulib-cache.m4      |    5 +-
 libmissing/m4/gnulib-comp.m4       |   29 +++++++
 libmissing/m4/lseek.m4             |   50 ++++++++++++
 libmissing/m4/ungetc.m4            |   36 +++++++++
 libmissing/stdio-impl.h            |   94 +++++++++++++++++++++++
 libmissing/tests/Makefile.am       |   39 ++++++++++
 libmissing/tests/binary-io.h       |   66 ++++++++++++++++
 libmissing/tests/test-binary-io.c  |   64 ++++++++++++++++
 libmissing/tests/test-binary-io.sh |   11 +++
 libmissing/tests/test-fseeko.c     |   74 ++++++++++++++++++
 libmissing/tests/test-fseeko.sh    |    5 +
 libmissing/tests/test-fseeko2.sh   |    3 +
 libmissing/tests/test-ftello.c     |  118 +++++++++++++++++++++++++++++
 libmissing/tests/test-ftello.sh    |    5 +
 libmissing/tests/test-ftello2.sh   |    3 +
 libmissing/tests/test-lseek.c      |   96 +++++++++++++++++++++++
 libmissing/tests/test-lseek.sh     |   17 ++++
 src/file-server.c                  |    2 +-
 24 files changed, 1072 insertions(+), 4 deletions(-)

========================================

diff --git a/libmissing/Makefile.am b/libmissing/Makefile.am
index 0f7a1e4..e10a83c 100644
--- a/libmissing/Makefile.am
+++ b/libmissing/Makefile.am
@@ -9,7 +9,7 @@
 # the same distribution terms as the rest of that program.
 #
 # Generated by gnulib-tool.
-# Reproduce by: gnulib-tool --import --dir=. --lib=libmissing --source-base=libmissing --m4-base=libmissing/m4 --doc-base=libmissing/doc --tests-base=libmissing/tests --aux-dir=. --with-tests --lgpl --libtool --macro-prefix=gl --no-vc-files bind close fnmatch-gnu getaddrinfo glob iconv imaxabs inet_ntop ioctl mktime nl_langinfo pathmax recvfrom servent sigaction sleep snprintf snprintf-posix socket socklen strptime strsep sys_select
+# Reproduce by: gnulib-tool --import --dir=. --lib=libmissing --source-base=libmissing --m4-base=libmissing/m4 --doc-base=libmissing/doc --tests-base=libmissing/tests --aux-dir=. --with-tests --lgpl --libtool --macro-prefix=gl --no-vc-files bind close fnmatch-gnu fseeko ftello getaddrinfo glob iconv imaxabs inet_ntop ioctl mktime nl_langinfo pathmax recvfrom servent sigaction sleep snprintf-posix socket socklen strptime strsep sys_select
 
 AUTOMAKE_OPTIONS = 1.5 gnits
 
@@ -362,6 +362,24 @@ EXTRA_libmissing_la_SOURCES += frexp.c frexpl.c
 
 ## end   gnulib module frexpl-nolibm
 
+## begin gnulib module fseeko
+
+
+EXTRA_DIST += fseeko.c stdio-impl.h
+
+EXTRA_libmissing_la_SOURCES += fseeko.c
+
+## end   gnulib module fseeko
+
+## begin gnulib module ftello
+
+
+EXTRA_DIST += ftello.c
+
+EXTRA_libmissing_la_SOURCES += ftello.c
+
+## end   gnulib module ftello
+
 ## begin gnulib module getaddrinfo
 
 
@@ -621,6 +639,15 @@ EXTRA_DIST += config.charset ref-add.sin ref-del.sin
 
 ## end   gnulib module localcharset
 
+## begin gnulib module lseek
+
+
+EXTRA_DIST += lseek.c
+
+EXTRA_libmissing_la_SOURCES += lseek.c
+
+## end   gnulib module lseek
+
 ## begin gnulib module malloc-posix
 
 
diff --git a/libmissing/fseeko.c b/libmissing/fseeko.c
new file mode 100644
index 0000000..8ac3af6
--- /dev/null
+++ b/libmissing/fseeko.c
@@ -0,0 +1,147 @@
+/* An fseeko() function that, together with fflush(), is POSIX compliant.
+   Copyright (C) 2007-2010 Free Software Foundation, Inc.
+
+   This program 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, 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 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, write to the Free Software Foundation,
+   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+#include <config.h>
+
+/* Specification.  */
+#include <stdio.h>
+
+/* Get off_t and lseek.  */
+#include <unistd.h>
+
+#include "stdio-impl.h"
+
+#undef fseeko
+#if !HAVE_FSEEKO
+# undef fseek
+# define fseeko fseek
+#endif
+
+int
+rpl_fseeko (FILE *fp, off_t offset, int whence)
+{
+#if LSEEK_PIPE_BROKEN
+  /* mingw gives bogus answers rather than failure on non-seekable files.  */
+  if (lseek (fileno (fp), 0, SEEK_CUR) == -1)
+    return EOF;
+#endif
+
+  /* These tests are based on fpurge.c.  */
+#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+  if (fp->_IO_read_end == fp->_IO_read_ptr
+      && fp->_IO_write_ptr == fp->_IO_write_base
+      && fp->_IO_save_base == NULL)
+#elif defined __sferror || defined __DragonFly__ /* FreeBSD, NetBSD, OpenBSD, DragonFly, MacOS X, Cygwin */
+# if defined __SL64 && defined __SCLE /* Cygwin */
+  if ((fp->_flags & __SL64) == 0)
+    {
+      /* Cygwin 1.5.0 through 1.5.24 failed to open stdin in 64-bit
+         mode; but has an fseeko that requires 64-bit mode.  */
+      FILE *tmp = fopen ("/dev/null", "r");
+      if (!tmp)
+        return -1;
+      fp->_flags |= __SL64;
+      fp->_seek64 = tmp->_seek64;
+      fclose (tmp);
+    }
+# endif
+  if (fp_->_p == fp_->_bf._base
+      && fp_->_r == 0
+      && fp_->_w == ((fp_->_flags & (__SLBF | __SNBF | __SRD)) == 0 /* fully buffered and not currently reading? */
+                     ? fp_->_bf._size
+                     : 0)
+      && fp_ub._base == NULL)
+#elif defined __EMX__               /* emx+gcc */
+  if (fp->_ptr == fp->_buffer
+      && fp->_rcount == 0
+      && fp->_wcount == 0
+      && fp->_ungetc_count == 0)
+#elif defined _IOERR                /* AIX, HP-UX, IRIX, OSF/1, Solaris, OpenServer, mingw */
+  if (fp_->_ptr == fp_->_base
+      && (fp_->_ptr == NULL || fp_->_cnt == 0))
+#elif defined __UCLIBC__            /* uClibc */
+  if (((fp->__modeflags & __FLAG_WRITING) == 0
+       || fp->__bufpos == fp->__bufstart)
+      && ((fp->__modeflags & (__FLAG_READONLY | __FLAG_READING)) == 0
+          || fp->__bufpos == fp->__bufread))
+#elif defined __QNX__               /* QNX */
+  if ((fp->_Mode & 0x2000 /* _MWRITE */ ? fp->_Next == fp->_Buf : fp->_Next == fp->_Rend)
+      && fp->_Rback == fp->_Back + sizeof (fp->_Back)
+      && fp->_Rsave == NULL)
+#elif defined __MINT__              /* Atari FreeMiNT */
+  if (fp->__bufp == fp->__buffer
+      && fp->__get_limit == fp->__bufp
+      && fp->__put_limit == fp->__bufp
+      && !fp->__pushed_back)
+#else
+  #error "Please port gnulib fseeko.c to your platform! Look at the code in fpurge.c, then report this to bug-gnulib."
+#endif
+    {
+      /* We get here when an fflush() call immediately preceded this one.  We
+         know there are no buffers.
+         POSIX requires us to modify the file descriptor's position.
+         But we cannot position beyond end of file here.  */
+      off_t pos =
+        lseek (fileno (fp),
+               whence == SEEK_END && offset > 0 ? 0 : offset,
+               whence);
+      if (pos == -1)
+        {
+#if defined __sferror || defined __DragonFly__ /* FreeBSD, NetBSD, OpenBSD, DragonFly, MacOS X, Cygwin */
+          fp_->_flags &= ~__SOFF;
+#endif
+          return -1;
+        }
+
+#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+      fp->_flags &= ~_IO_EOF_SEEN;
+#elif defined __sferror || defined __DragonFly__ /* FreeBSD, NetBSD, OpenBSD, DragonFly, MacOS X, Cygwin */
+# if defined __CYGWIN__
+      /* fp_->_offset is typed as an integer.  */
+      fp_->_offset = pos;
+# else
+      /* fp_->_offset is an fpos_t.  */
+      {
+        /* Use a union, since on NetBSD, the compilation flags
+           determine whether fpos_t is typedef'd to off_t or a struct
+           containing a single off_t member.  */
+        union
+          {
+            fpos_t f;
+            off_t o;
+          } u;
+        u.o = pos;
+        fp_->_offset = u.f;
+      }
+# endif
+      fp_->_flags |= __SOFF;
+      fp_->_flags &= ~__SEOF;
+#elif defined __EMX__               /* emx+gcc */
+      fp->_flags &= ~_IOEOF;
+#elif defined _IOERR                /* AIX, HP-UX, IRIX, OSF/1, Solaris, OpenServer, mingw */
+      fp->_flag &= ~_IOEOF;
+#elif defined __MINT__              /* Atari FreeMiNT */
+      fp->__offset = pos;
+      fp->__eof = 0;
+#endif
+      /* If we were not requested to position beyond end of file, we're
+         done.  */
+      if (!(whence == SEEK_END && offset > 0))
+        return 0;
+    }
+  return fseeko (fp, offset, whence);
+}
diff --git a/libmissing/ftello.c b/libmissing/ftello.c
new file mode 100644
index 0000000..2b52244
--- /dev/null
+++ b/libmissing/ftello.c
@@ -0,0 +1,54 @@
+/* An ftello() function that works around platform bugs.
+   Copyright (C) 2007, 2009, 2010 Free Software Foundation, Inc.
+
+   This program 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 3 of the License, 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 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 <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+
+/* Specification.  */
+#include <stdio.h>
+
+/* Get lseek.  */
+#include <unistd.h>
+
+#undef ftello
+#if !HAVE_FTELLO
+# undef ftell
+# define ftello ftell
+#endif
+
+off_t
+rpl_ftello (FILE *fp)
+{
+#if LSEEK_PIPE_BROKEN
+  /* mingw gives bogus answers rather than failure on non-seekable files.  */
+  if (lseek (fileno (fp), 0, SEEK_CUR) == -1)
+    return -1;
+#endif
+
+#if defined __SL64 && defined __SCLE /* Cygwin */
+  if ((fp->_flags & __SL64) == 0)
+    {
+      /* Cygwin 1.5.0 through 1.5.24 failed to open stdin in 64-bit
+         mode; but has an ftello that requires 64-bit mode.  */
+      FILE *tmp = fopen ("/dev/null", "r");
+      if (!tmp)
+        return -1;
+      fp->_flags |= __SL64;
+      fp->_seek64 = tmp->_seek64;
+      fclose (tmp);
+    }
+#endif
+  return ftello (fp);
+}
diff --git a/libmissing/lseek.c b/libmissing/lseek.c
new file mode 100644
index 0000000..13baee0
--- /dev/null
+++ b/libmissing/lseek.c
@@ -0,0 +1,62 @@
+/* An lseek() function that detects pipes.
+   Copyright (C) 2007, 2009, 2010 Free Software Foundation, Inc.
+
+   This program 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, 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 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, write to the Free Software Foundation,
+   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+#include <config.h>
+
+/* Specification.  */
+#include <unistd.h>
+
+#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+/* Windows platforms.  */
+/* Get GetFileType.  */
+# include <windows.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
+  return lseek (fd, offset, whence);
+}
diff --git a/libmissing/m4/fseeko.m4 b/libmissing/m4/fseeko.m4
new file mode 100644
index 0000000..5f7f977
--- /dev/null
+++ b/libmissing/m4/fseeko.m4
@@ -0,0 +1,35 @@
+# fseeko.m4 serial 7
+dnl Copyright (C) 2007-2010 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_FUNC_FSEEKO],
+[
+  AC_REQUIRE([gl_STDIO_H_DEFAULTS])
+  AC_REQUIRE([AC_PROG_CC])
+  AC_REQUIRE([gl_STDIN_LARGE_OFFSET])
+
+  dnl Persuade glibc <stdio.h> to declare fseeko().
+  AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
+
+  AC_CACHE_CHECK([for fseeko], [gl_cv_func_fseeko],
+    [
+      AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <stdio.h>
+]], [fseeko (stdin, 0, 0);])],
+        [gl_cv_func_fseeko=yes], [gl_cv_func_fseeko=no])
+    ])
+  if test $gl_cv_func_fseeko = no \
+      || test $gl_cv_var_stdin_large_offset = no; then
+    gl_REPLACE_FSEEKO
+  fi
+])
+
+AC_DEFUN([gl_REPLACE_FSEEKO],
+[
+  AC_LIBOBJ([fseeko])
+  AC_REQUIRE([gl_STDIO_H_DEFAULTS])
+  REPLACE_FSEEKO=1
+  dnl If we are also using the fseek module, then fseek needs replacing, too.
+  m4_ifdef([gl_REPLACE_FSEEK], [gl_REPLACE_FSEEK])
+])
diff --git a/libmissing/m4/ftello.m4 b/libmissing/m4/ftello.m4
new file mode 100644
index 0000000..2dff6ee
--- /dev/null
+++ b/libmissing/m4/ftello.m4
@@ -0,0 +1,32 @@
+# ftello.m4 serial 5
+dnl Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_FUNC_FTELLO],
+[
+  AC_REQUIRE([gl_STDIO_H_DEFAULTS])
+  AC_REQUIRE([AC_PROG_CC])
+  AC_REQUIRE([gl_STDIN_LARGE_OFFSET])
+
+  dnl Persuade glibc <stdio.h> to declare fseeko().
+  AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
+
+  AC_CACHE_CHECK([for ftello], [gl_cv_func_ftello],
+    [
+      AC_TRY_LINK([#include <stdio.h>], [ftello (stdin);],
+        [gl_cv_func_ftello=yes], [gl_cv_func_ftello=no])
+    ])
+  if test $gl_cv_func_ftello = no \
+      || test $gl_cv_var_stdin_large_offset = no; then
+    gl_REPLACE_FTELLO
+  fi
+])
+
+AC_DEFUN([gl_REPLACE_FTELLO],
+[
+  AC_LIBOBJ([ftello])
+  AC_REQUIRE([gl_STDIO_H_DEFAULTS])
+  REPLACE_FTELLO=1
+])
diff --git a/libmissing/m4/gnulib-cache.m4 b/libmissing/m4/gnulib-cache.m4
index a00e64d..99cd2aa 100644
--- a/libmissing/m4/gnulib-cache.m4
+++ b/libmissing/m4/gnulib-cache.m4
@@ -15,7 +15,7 @@
 
 
 # Specification in the form of a command-line invocation:
-#   gnulib-tool --import --dir=. --lib=libmissing --source-base=libmissing --m4-base=libmissing/m4 --doc-base=libmissing/doc --tests-base=libmissing/tests --aux-dir=. --with-tests --lgpl --libtool --macro-prefix=gl --no-vc-files bind close fnmatch-gnu getaddrinfo glob iconv imaxabs inet_ntop ioctl mktime nl_langinfo pathmax recvfrom servent sigaction sleep snprintf snprintf-posix socket socklen strptime strsep sys_select
+#   gnulib-tool --import --dir=. --lib=libmissing --source-base=libmissing --m4-base=libmissing/m4 --doc-base=libmissing/doc --tests-base=libmissing/tests --aux-dir=. --with-tests --lgpl --libtool --macro-prefix=gl --no-vc-files bind close fnmatch-gnu fseeko ftello getaddrinfo glob iconv imaxabs inet_ntop ioctl mktime nl_langinfo pathmax recvfrom servent sigaction sleep snprintf-posix socket socklen strptime strsep sys_select
 
 # Specification in the form of a few gnulib-tool.m4 macro invocations:
 gl_LOCAL_DIR([])
@@ -23,6 +23,8 @@ gl_MODULES([
   bind
   close
   fnmatch-gnu
+  fseeko
+  ftello
   getaddrinfo
   glob
   iconv
@@ -36,7 +38,6 @@ gl_MODULES([
   servent
   sigaction
   sleep
-  snprintf
   snprintf-posix
   socket
   socklen
diff --git a/libmissing/m4/gnulib-comp.m4 b/libmissing/m4/gnulib-comp.m4
index 570e577..eb9c789 100644
--- a/libmissing/m4/gnulib-comp.m4
+++ b/libmissing/m4/gnulib-comp.m4
@@ -27,6 +27,8 @@ AC_DEFUN([gl_EARLY],
   AC_REQUIRE([AC_PROG_RANLIB])
   AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
   AC_REQUIRE([gl_FP_IEEE])
+  AC_REQUIRE([AC_FUNC_FSEEKO])
+  AC_REQUIRE([AC_FUNC_FSEEKO])
 ])
 
 # This macro should be invoked from ./configure.in, in the section
@@ -70,6 +72,10 @@ AC_SUBST([LTALLOCA])
   gl_MATH_MODULE_INDICATOR([frexp])
   gl_FUNC_FREXPL_NO_LIBM
   gl_MATH_MODULE_INDICATOR([frexpl])
+  gl_FUNC_FSEEKO
+  gl_STDIO_MODULE_INDICATOR([fseeko])
+  gl_FUNC_FTELLO
+  gl_STDIO_MODULE_INDICATOR([ftello])
   gl_GETADDRINFO
   gl_NETDB_MODULE_INDICATOR([getaddrinfo])
   gl_GETLOGIN_R
@@ -106,6 +112,8 @@ AC_SUBST([LTALLOCA])
   gl_LOCALCHARSET
   LOCALCHARSET_TESTS_ENVIRONMENT="CHARSETALIASDIR=\"\$(top_builddir)/$gl_source_base\""
   AC_SUBST([LOCALCHARSET_TESTS_ENVIRONMENT])
+  gl_FUNC_LSEEK
+  gl_UNISTD_MODULE_INDICATOR([lseek])
   gl_FUNC_MALLOC_POSIX
   gl_STDLIB_MODULE_INDICATOR([malloc-posix])
   gl_MATH_H
@@ -234,6 +242,8 @@ AC_SUBST([LTALLOCA])
   gl_source_base='libmissing/tests'
   gt_LOCALE_FR
   gt_LOCALE_TR_UTF8
+  gl_FUNC_UNGETC_WORKS
+  gl_FUNC_UNGETC_WORKS
   AC_C_BIGENDIAN
   gl_DOUBLE_EXPONENT_LOCATION
   gl_FLOAT_EXPONENT_LOCATION
@@ -378,6 +388,8 @@ AC_DEFUN([gl_FILE_LIST], [
   lib/fpucw.h
   lib/frexp.c
   lib/frexpl.c
+  lib/fseeko.c
+  lib/ftello.c
   lib/gai_strerror.c
   lib/getaddrinfo.c
   lib/getlogin_r.c
@@ -400,6 +412,7 @@ AC_DEFUN([gl_FILE_LIST], [
   lib/langinfo.in.h
   lib/localcharset.c
   lib/localcharset.h
+  lib/lseek.c
   lib/malloc.c
   lib/math.in.h
   lib/mbrtowc.c
@@ -442,6 +455,7 @@ AC_DEFUN([gl_FILE_LIST], [
   lib/stdbool.in.h
   lib/stddef.in.h
   lib/stdint.in.h
+  lib/stdio-impl.h
   lib/stdio-write.c
   lib/stdio.in.h
   lib/stdlib.in.h
@@ -489,6 +503,8 @@ AC_DEFUN([gl_FILE_LIST], [
   m4/fpieee.m4
   m4/frexp.m4
   m4/frexpl.m4
+  m4/fseeko.m4
+  m4/ftello.m4
   m4/getaddrinfo.m4
   m4/getlogin_r.m4
   m4/glibc21.m4
@@ -517,6 +533,7 @@ AC_DEFUN([gl_FILE_LIST], [
   m4/locale-tr.m4
   m4/locale-zh.m4
   m4/longlong.m4
+  m4/lseek.m4
   m4/malloc.m4
   m4/math_h.m4
   m4/mbrtowc.m4
@@ -569,6 +586,7 @@ AC_DEFUN([gl_FILE_LIST], [
   m4/time_h.m4
   m4/time_r.m4
   m4/tm_gmtoff.m4
+  m4/ungetc.m4
   m4/unistd_h.m4
   m4/vasnprintf.m4
   m4/warn-on-use.m4
@@ -584,6 +602,8 @@ AC_DEFUN([gl_FILE_LIST], [
   tests/test-alignof.c
   tests/test-alloca-opt.c
   tests/test-arpa_inet.c
+  tests/test-binary-io.c
+  tests/test-binary-io.sh
   tests/test-c-ctype.c
   tests/test-c-strcase.sh
   tests/test-c-strcasecmp.c
@@ -593,6 +613,12 @@ AC_DEFUN([gl_FILE_LIST], [
   tests/test-fnmatch.c
   tests/test-frexp.c
   tests/test-frexpl.c
+  tests/test-fseeko.c
+  tests/test-fseeko.sh
+  tests/test-fseeko2.sh
+  tests/test-ftello.c
+  tests/test-ftello.sh
+  tests/test-ftello2.sh
   tests/test-getaddrinfo.c
   tests/test-getlogin_r.c
   tests/test-glob.c
@@ -606,6 +632,8 @@ AC_DEFUN([gl_FILE_LIST], [
   tests/test-isnanl-nolibm.c
   tests/test-isnanl.h
   tests/test-langinfo.c
+  tests/test-lseek.c
+  tests/test-lseek.sh
   tests/test-math.c
   tests/test-mbrtowc.c
   tests/test-mbrtowc1.sh
@@ -653,6 +681,7 @@ AC_DEFUN([gl_FILE_LIST], [
   tests/test-wchar.c
   tests/test-wctype.c
   tests/zerosize-ptr.h
+  tests=lib/binary-io.h
   tests=lib/c-ctype.c
   tests=lib/c-ctype.h
   tests=lib/c-strcase.h
diff --git a/libmissing/m4/lseek.m4 b/libmissing/m4/lseek.m4
new file mode 100644
index 0000000..f308495
--- /dev/null
+++ b/libmissing/m4/lseek.m4
@@ -0,0 +1,50 @@
+# lseek.m4 serial 4
+dnl Copyright (C) 2007, 2009, 2010 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_FUNC_LSEEK],
+[
+  AC_REQUIRE([gl_UNISTD_H_DEFAULTS])
+  AC_REQUIRE([AC_PROG_CC])
+  AC_CACHE_CHECK([whether lseek detects pipes], [gl_cv_func_lseek_pipe],
+    [if test $cross_compiling = no; then
+       AC_LINK_IFELSE([
+#include <sys/types.h> /* for off_t */
+#include <stdio.h> /* for SEEK_CUR */
+#include <unistd.h>
+int main ()
+{
+  /* Exit with success only if stdin is seekable.  */
+  return lseek (0, (off_t)0, SEEK_CUR) < 0;
+}],
+         [if test -s conftest$ac_exeext \
+             && ./conftest$ac_exeext < conftest.$ac_ext \
+             && { echo hi | ./conftest$ac_exeext; test $? = 1; }; then
+            gl_cv_func_lseek_pipe=yes
+          else
+            gl_cv_func_lseek_pipe=no
+          fi],
+         [gl_cv_func_lseek_pipe=no])
+     else
+       AC_COMPILE_IFELSE([
+#if ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__) || defined __BEOS__
+/* mingw and BeOS mistakenly return 0 when trying to seek on pipes.  */
+  Choke me.
+#endif],
+         [gl_cv_func_lseek_pipe=yes], [gl_cv_func_lseek_pipe=no])
+     fi])
+  if test $gl_cv_func_lseek_pipe = no; then
+    gl_REPLACE_LSEEK
+  fi
+])
+
+AC_DEFUN([gl_REPLACE_LSEEK],
+[
+  AC_LIBOBJ([lseek])
+  AC_REQUIRE([gl_UNISTD_H_DEFAULTS])
+  REPLACE_LSEEK=1
+  AC_DEFINE([LSEEK_PIPE_BROKEN], [1],
+            [Define to 1 if lseek does not detect pipes.])
+])
diff --git a/libmissing/m4/ungetc.m4 b/libmissing/m4/ungetc.m4
new file mode 100644
index 0000000..68ccf88
--- /dev/null
+++ b/libmissing/m4/ungetc.m4
@@ -0,0 +1,36 @@
+# ungetc.m4 serial 2
+dnl Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN_ONCE([gl_FUNC_UNGETC_WORKS],
+[
+  AC_REQUIRE([AC_PROG_CC])
+
+  AC_CACHE_CHECK([whether ungetc works on arbitrary bytes],
+    [gl_cv_func_ungetc_works],
+    [AC_RUN_IFELSE([AC_LANG_PROGRAM([[
+#include <stdio.h>
+      ]], [FILE *f;
+           if (!(f = fopen ("conftest.tmp", "w+"))) return 1;
+           if (fputs ("abc", f) < 0) return 2;
+           rewind (f);
+           if (fgetc (f) != 'a') return 3;
+           if (fgetc (f) != 'b') return 4;
+           if (ungetc ('d', f) != 'd') return 5;
+           if (ftell (f) != 1) return 6;
+           if (fgetc (f) != 'd') return 7;
+           if (ftell (f) != 2) return 8;
+           if (fseek (f, 0, SEEK_CUR) != 0) return 9;
+           if (ftell (f) != 2) return 10;
+           if (fgetc (f) != 'c') return 11;
+           fclose (f); remove ("conftest.tmp");])],
+        [gl_cv_func_ungetc_works=yes], [gl_cv_func_ungetc_works=no],
+        [gl_cv_func_ungetc_works='guessing no'])
+    ])
+  if test "$gl_cv_func_ungetc_works" != yes; then
+    AC_DEFINE([FUNC_UNGETC_BROKEN], [1],
+      [Define to 1 if ungetc is broken when used on arbitrary bytes.])
+  fi
+])
diff --git a/libmissing/stdio-impl.h b/libmissing/stdio-impl.h
new file mode 100644
index 0000000..697b8bc
--- /dev/null
+++ b/libmissing/stdio-impl.h
@@ -0,0 +1,94 @@
+/* Implementation details of FILE streams.
+   Copyright (C) 2007-2010 Free Software Foundation, Inc.
+
+   This program 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 3 of the License, 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 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 <http://www.gnu.org/licenses/>.  */
+
+/* Many stdio implementations have the same logic and therefore can share
+   the same implementation of stdio extension API, except that some fields
+   have different naming conventions, or their access requires some casts.  */
+
+
+/* BSD stdio derived implementations.  */
+
+#if defined __sferror || defined __DragonFly__ /* FreeBSD, NetBSD, OpenBSD, DragonFly, MacOS X, Cygwin */
+
+# if defined __DragonFly__          /* DragonFly */
+  /* See <http://www.dragonflybsd.org/cvsweb/src/lib/libc/stdio/priv_stdio.h?rev=HEAD&content-type=text/x-cvsweb-markup>.  */
+#  define fp_ ((struct { struct __FILE_public pub; \
+                         struct { unsigned char *_base; int _size; } _bf; \
+                         void *cookie; \
+                         void *_close; \
+                         void *_read; \
+                         void *_seek; \
+                         void *_write; \
+                         struct { unsigned char *_base; int _size; } _ub; \
+                         int _ur; \
+                         unsigned char _ubuf[3]; \
+                         unsigned char _nbuf[1]; \
+                         struct { unsigned char *_base; int _size; } _lb; \
+                         int _blksize; \
+                         fpos_t _offset; \
+                         /* More fields, not relevant here.  */ \
+                       } *) fp)
+  /* See <http://www.dragonflybsd.org/cvsweb/src/include/stdio.h?rev=HEAD&content-type=text/x-cvsweb-markup>.  */
+#  define _p pub._p
+#  define _flags pub._flags
+#  define _r pub._r
+#  define _w pub._w
+# else
+#  define fp_ fp
+# endif
+
+# if defined __NetBSD__ || defined __OpenBSD__ /* NetBSD, OpenBSD */
+  /* See <http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libc/stdio/fileext.h?rev=HEAD&content-type=text/x-cvsweb-markup>
+     and <http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/stdio/fileext.h?rev=HEAD&content-type=text/x-cvsweb-markup> */
+  struct __sfileext
+    {
+      struct  __sbuf _ub; /* ungetc buffer */
+      /* More fields, not relevant here.  */
+    };
+#  define fp_ub ((struct __sfileext *) fp->_ext._base)->_ub
+# else                                         /* FreeBSD, DragonFly, MacOS X, Cygwin */
+#  define fp_ub fp_->_ub
+# endif
+
+# define HASUB(fp) (fp_ub._base != NULL)
+
+#endif
+
+
+/* SystemV derived implementations.  */
+
+#if defined _IOERR
+
+# if defined __sun && defined _LP64 /* Solaris/{SPARC,AMD64} 64-bit */
+#  define fp_ ((struct { unsigned char *_ptr; \
+                         unsigned char *_base; \
+                         unsigned char *_end; \
+                         long _cnt; \
+                         int _file; \
+                         unsigned int _flag; \
+                       } *) fp)
+# else
+#  define fp_ fp
+# endif
+
+# if defined _SCO_DS                /* OpenServer */
+#  define _cnt __cnt
+#  define _ptr __ptr
+#  define _base __base
+#  define _flag __flag
+# endif
+
+#endif
diff --git a/libmissing/tests/Makefile.am b/libmissing/tests/Makefile.am
index 3ca03e7..655fc40 100644
--- a/libmissing/tests/Makefile.am
+++ b/libmissing/tests/Makefile.am
@@ -95,6 +95,21 @@ EXTRA_DIST += test-arpa_inet.c
 
 ## end   gnulib module arpa_inet-tests
 
+## begin gnulib module binary-io
+
+libtests_a_SOURCES += binary-io.h
+
+## end   gnulib module binary-io
+
+## begin gnulib module binary-io-tests
+
+TESTS += test-binary-io.sh
+check_PROGRAMS += test-binary-io
+
+EXTRA_DIST += test-binary-io.sh test-binary-io.c macros.h
+
+## end   gnulib module binary-io-tests
+
 ## begin gnulib module c-ctype
 
 libtests_a_SOURCES += c-ctype.h c-ctype.c
@@ -168,6 +183,22 @@ EXTRA_DIST += test-frexpl.c signature.h macros.h
 
 ## end   gnulib module frexpl-nolibm-tests
 
+## begin gnulib module fseeko-tests
+
+TESTS += test-fseeko.sh test-fseeko2.sh
+check_PROGRAMS += test-fseeko
+EXTRA_DIST += test-fseeko.c test-fseeko.sh test-fseeko2.sh signature.h macros.h
+
+## end   gnulib module fseeko-tests
+
+## begin gnulib module ftello-tests
+
+TESTS += test-ftello.sh test-ftello2.sh
+check_PROGRAMS += test-ftello
+EXTRA_DIST += test-ftello.c test-ftello.sh test-ftello2.sh signature.h macros.h
+
+## end   gnulib module ftello-tests
+
 ## begin gnulib module getaddrinfo-tests
 
 TESTS += test-getaddrinfo
@@ -262,6 +293,14 @@ EXTRA_DIST += test-langinfo.c
 
 ## end   gnulib module langinfo-tests
 
+## begin gnulib module lseek-tests
+
+TESTS += test-lseek.sh
+check_PROGRAMS += test-lseek
+EXTRA_DIST += test-lseek.c test-lseek.sh signature.h macros.h
+
+## end   gnulib module lseek-tests
+
 ## begin gnulib module math-tests
 
 TESTS += test-math
diff --git a/libmissing/tests/binary-io.h b/libmissing/tests/binary-io.h
new file mode 100644
index 0000000..5451fd4
--- /dev/null
+++ b/libmissing/tests/binary-io.h
@@ -0,0 +1,66 @@
+/* Binary mode I/O.
+   Copyright (C) 2001, 2003, 2005, 2008, 2009, 2010 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 of the License, 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/>.  */
+
+#ifndef _BINARY_H
+#define _BINARY_H
+
+/* For systems that distinguish between text and binary I/O.
+   O_BINARY is usually declared in <fcntl.h>. */
+#include <fcntl.h>
+
+/* The MSVC7 <stdio.h> doesn't like to be included after '#define fileno ...',
+   so we include it here first.  */
+#include <stdio.h>
+
+#if !defined O_BINARY && defined _O_BINARY
+  /* For MSC-compatible compilers.  */
+# define O_BINARY _O_BINARY
+# define O_TEXT _O_TEXT
+#endif
+#if defined __BEOS__ || defined __HAIKU__
+  /* BeOS 5 and Haiku have O_BINARY and O_TEXT, but they have no effect.  */
+# undef O_BINARY
+# undef O_TEXT
+#endif
+
+/* SET_BINARY (fd);
+   changes the file descriptor fd to perform binary I/O.  */
+#if O_BINARY
+# if defined __EMX__ || defined __DJGPP__ || defined __CYGWIN__
+#  include <io.h> /* declares setmode() */
+# else
+#  define setmode _setmode
+#  undef fileno
+#  define fileno _fileno
+# endif
+# ifdef __DJGPP__
+#  include <unistd.h> /* declares isatty() */
+   /* Avoid putting stdin/stdout in binary mode if it is connected to
+      the console, because that would make it impossible for the user
+      to interrupt the program through Ctrl-C or Ctrl-Break.  */
+#  define SET_BINARY(fd) ((void) (!isatty (fd) ? (setmode (fd, O_BINARY), 0) : 0))
+# else
+#  define SET_BINARY(fd) ((void) setmode (fd, O_BINARY))
+# endif
+#else
+  /* On reasonable systems, binary I/O is the default.  */
+# undef O_BINARY
+# define O_BINARY 0
+# define SET_BINARY(fd) /* do nothing */ ((void) 0)
+#endif
+
+#endif /* _BINARY_H */
diff --git a/libmissing/tests/test-binary-io.c b/libmissing/tests/test-binary-io.c
new file mode 100644
index 0000000..125150b
--- /dev/null
+++ b/libmissing/tests/test-binary-io.c
@@ -0,0 +1,64 @@
+/* Test of binary mode I/O.
+   Copyright (C) 2005, 2007-2010 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 of the License, 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/>.  */
+
+/* Written by Bruno Haible <[email protected]>, 2005.  */
+
+#include <config.h>
+
+#include "binary-io.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "macros.h"
+
+int
+main ()
+{
+  /* Test the O_BINARY macro.  */
+  {
+    int fd =
+      open ("t-bin-out2.tmp", O_CREAT | O_TRUNC | O_RDWR | O_BINARY, 0600);
+    if (write (fd, "Hello\n", 6) < 0)
+      exit (1);
+    close (fd);
+  }
+  {
+    struct stat statbuf;
+    if (stat ("t-bin-out2.tmp", &statbuf) < 0)
+      exit (1);
+    ASSERT (statbuf.st_size == 6);
+  }
+  unlink ("t-bin-out2.tmp");
+
+  /* Test the SET_BINARY macro.  */
+  SET_BINARY (1);
+  fputs ("Hello\n", stdout);
+  fclose (stdout);
+  fclose (stderr);
+  {
+    struct stat statbuf;
+    if (stat ("t-bin-out1.tmp", &statbuf) < 0)
+      exit (1);
+    ASSERT (statbuf.st_size == 6);
+  }
+
+  return 0;
+}
diff --git a/libmissing/tests/test-binary-io.sh b/libmissing/tests/test-binary-io.sh
new file mode 100755
index 0000000..33e128c
--- /dev/null
+++ b/libmissing/tests/test-binary-io.sh
@@ -0,0 +1,11 @@
+#!/bin/sh
+
+tmpfiles=""
+trap 'rm -fr $tmpfiles' 1 2 3 15
+
+tmpfiles="$tmpfiles t-bin-out1.tmp t-bin-out2.tmp"
+./test-binary-io${EXEEXT} > t-bin-out1.tmp || exit 1
+
+rm -fr $tmpfiles
+
+exit 0
diff --git a/libmissing/tests/test-fseeko.c b/libmissing/tests/test-fseeko.c
new file mode 100644
index 0000000..be2a78d
--- /dev/null
+++ b/libmissing/tests/test-fseeko.c
@@ -0,0 +1,74 @@
+/* Test of fseeko() function.
+   Copyright (C) 2007, 2008, 2009, 2010 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 of the License, 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/>.  */
+
+/* Written by Bruno Haible <[email protected]>, 2007.  */
+
+#include <config.h>
+
+/* None of the files accessed by this test are large, so disable the
+   fseek link warning if we are not using the gnulib fseek module.  */
+#define _GL_NO_LARGE_FILES
+#include <stdio.h>
+
+#include "signature.h"
+SIGNATURE_CHECK (fseeko, int, (FILE *, off_t, int));
+
+
+#include "macros.h"
+
+#ifndef FUNC_UNGETC_BROKEN
+# define FUNC_UNGETC_BROKEN 0
+#endif
+
+int
+main (int argc, char **argv _GL_UNUSED)
+{
+  /* Assume stdin is non-empty, seekable, and starts with '#!/bin/sh'
+     iff argc > 1.  */
+  int expected = argc > 1 ? 0 : -1;
+  /* Exit with success only if fseek/fseeko agree.  */
+  int r1 = fseeko (stdin, 0, SEEK_CUR);
+  int r2 = fseek (stdin, 0, SEEK_CUR);
+  ASSERT (r1 == r2 && r1 == expected);
+  if (argc > 1)
+    {
+      /* Test that fseek discards previously read ungetc data.  */
+      int ch = fgetc (stdin);
+      ASSERT (ch == '#');
+      ASSERT (ungetc (ch, stdin) == ch);
+      ASSERT (fseeko (stdin, 2, SEEK_SET) == 0);
+      ch = fgetc (stdin);
+      ASSERT (ch == '/');
+      if (2 < argc)
+        {
+          if (FUNC_UNGETC_BROKEN)
+            {
+              fputs ("Skipping test: ungetc cannot handle arbitrary bytes\n",
+                     stderr);
+              return 77;
+            }
+          /* Test that fseek discards random ungetc data.  */
+          ASSERT (ungetc (ch ^ 0xff, stdin) == (ch ^ 0xff));
+        }
+      ASSERT (fseeko (stdin, 0, SEEK_END) == 0);
+      ASSERT (fgetc (stdin) == EOF);
+      /* Test that fseek resets end-of-file marker.  */
+      ASSERT (feof (stdin));
+      ASSERT (fseeko (stdin, 0, SEEK_END) == 0);
+      ASSERT (!feof (stdin));
+    }
+  return 0;
+}
diff --git a/libmissing/tests/test-fseeko.sh b/libmissing/tests/test-fseeko.sh
new file mode 100755
index 0000000..5c55827
--- /dev/null
+++ b/libmissing/tests/test-fseeko.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+./test-fseeko${EXEEXT} 1 < "$srcdir/test-fseeko.sh" || exit 1
+echo hi | ./test-fseeko${EXEEXT} || exit 1
+exit 0
diff --git a/libmissing/tests/test-fseeko2.sh b/libmissing/tests/test-fseeko2.sh
new file mode 100755
index 0000000..6e1130c
--- /dev/null
+++ b/libmissing/tests/test-fseeko2.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+exec ./test-fseeko${EXEEXT} 1 2 < "$srcdir/test-fseeko2.sh"
diff --git a/libmissing/tests/test-ftello.c b/libmissing/tests/test-ftello.c
new file mode 100644
index 0000000..5fae570
--- /dev/null
+++ b/libmissing/tests/test-ftello.c
@@ -0,0 +1,118 @@
+/* Test of ftello() function.
+   Copyright (C) 2007, 2008, 2009, 2010 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 of the License, 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/>.  */
+
+/* Written by Bruno Haible <[email protected]>, 2007.  */
+
+#include <config.h>
+
+/* None of the files accessed by this test are large, so disable the
+   fseek link warning if we are not using the gnulib fseek module.  */
+#define _GL_NO_LARGE_FILES
+#include <stdio.h>
+
+#include "signature.h"
+SIGNATURE_CHECK (ftello, off_t, (FILE *));
+
+#include "binary-io.h"
+#include "macros.h"
+
+#ifndef FUNC_UNGETC_BROKEN
+# define FUNC_UNGETC_BROKEN 0
+#endif
+
+int
+main (int argc, char **argv _GL_UNUSED)
+{
+  int ch;
+  /* Assume stdin is seekable iff argc > 1.  */
+  if (argc == 1)
+    {
+      ASSERT (ftell (stdin) == -1);
+      ASSERT (ftello (stdin) == -1);
+      return 0;
+    }
+
+  /* mingw ftell is unreliable on text mode input.  */
+  SET_BINARY (0);
+
+  /* Simple tests.  For each test, make sure ftell and ftello agree.  */
+  ASSERT (ftell (stdin) == 0);
+  ASSERT (ftello (stdin) == 0);
+
+  ch = fgetc (stdin);
+  ASSERT (ch == '#');
+  ASSERT (ftell (stdin) == 1);
+  ASSERT (ftello (stdin) == 1);
+
+  /* Test ftell after ungetc of read input.  */
+  ch = ungetc ('#', stdin);
+  ASSERT (ch == '#');
+  ASSERT (ftell (stdin) == 0);
+  ASSERT (ftello (stdin) == 0);
+
+  ch = fgetc (stdin);
+  ASSERT (ch == '#');
+  ASSERT (ftell (stdin) == 1);
+  ASSERT (ftello (stdin) == 1);
+
+  /* Test ftell after fseek.  */
+  ASSERT (fseek (stdin, 2, SEEK_SET) == 0);
+  ASSERT (ftell (stdin) == 2);
+  ASSERT (ftello (stdin) == 2);
+
+  /* Test ftell after random ungetc.  */
+  ch = fgetc (stdin);
+  ASSERT (ch == '/');
+  ch = ungetc ('@', stdin);
+  ASSERT (ch == '@');
+  ASSERT (ftell (stdin) == 2);
+  ASSERT (ftello (stdin) == 2);
+
+  ch = fgetc (stdin);
+  ASSERT (ch == '@');
+  ASSERT (ftell (stdin) == 3);
+  ASSERT (ftello (stdin) == 3);
+
+  if (2 < argc)
+    {
+      if (FUNC_UNGETC_BROKEN)
+        {
+          fputs ("Skipping test: ungetc cannot handle arbitrary bytes\n",
+                 stderr);
+          return 77;
+        }
+      /* Test ftell after ungetc without read.  */
+      ASSERT (fseek (stdin, 0, SEEK_CUR) == 0);
+      ASSERT (ftell (stdin) == 3);
+      ASSERT (ftello (stdin) == 3);
+
+      ch = ungetc ('~', stdin);
+      ASSERT (ch == '~');
+      ASSERT (ftell (stdin) == 2);
+      ASSERT (ftello (stdin) == 2);
+    }
+
+#if !defined __MINT__ /* FreeMiNT has problems seeking past end of file */
+  /* Test ftell beyond end of file.  */
+  ASSERT (fseek (stdin, 0, SEEK_END) == 0);
+  ch = ftello (stdin);
+  ASSERT (fseek (stdin, 10, SEEK_END) == 0);
+  ASSERT (ftell (stdin) == ch + 10);
+  ASSERT (ftello (stdin) == ch + 10);
+#endif
+
+  return 0;
+}
diff --git a/libmissing/tests/test-ftello.sh b/libmissing/tests/test-ftello.sh
new file mode 100755
index 0000000..33d2e83
--- /dev/null
+++ b/libmissing/tests/test-ftello.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+./test-ftello${EXEEXT} 1 < "$srcdir/test-ftello.sh" || exit 1
+echo hi | ./test-ftello${EXEEXT} || exit 1
+exit 0
diff --git a/libmissing/tests/test-ftello2.sh b/libmissing/tests/test-ftello2.sh
new file mode 100755
index 0000000..ba750b0
--- /dev/null
+++ b/libmissing/tests/test-ftello2.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+exec ./test-ftello${EXEEXT} 1 2 < "$srcdir/test-ftello2.sh"
diff --git a/libmissing/tests/test-lseek.c b/libmissing/tests/test-lseek.c
new file mode 100644
index 0000000..bafa9b5
--- /dev/null
+++ b/libmissing/tests/test-lseek.c
@@ -0,0 +1,96 @@
+/* Test of lseek() function.
+   Copyright (C) 2007-2010 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 of the License, 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/>.  */
+
+/* Written by Eric Blake, 2007.  */
+
+#include <config.h>
+
+#include <unistd.h>
+
+#include "signature.h"
+SIGNATURE_CHECK (lseek, off_t, (int, off_t, int));
+
+#include <errno.h>
+
+#include "macros.h"
+
+/* ARGC must be 2; *ARGV[1] is '0' if stdin and stdout are files, '1'
+   if they are pipes, and '2' if they are closed.  Check for proper
+   semantics of lseek.  */
+int
+main (int argc, char **argv)
+{
+  if (argc != 2)
+    return 2;
+  switch (*argv[1])
+    {
+    case '0': /* regular files */
+      ASSERT (lseek (0, (off_t)2, SEEK_SET) == 2);
+      ASSERT (lseek (0, (off_t)-4, SEEK_CUR) == -1);
+      ASSERT (errno == EINVAL);
+      errno = 0;
+#if ! defined __BEOS__
+      /* POSIX says that the last lseek call, when failing, does not change
+         the current offset.  But BeOS sets it to 0.  */
+      ASSERT (lseek (0, (off_t)0, SEEK_CUR) == 2);
+#endif
+#if 0 /* leads to SIGSYS on IRIX 6.5 */
+      ASSERT (lseek (0, (off_t)0, (SEEK_SET | SEEK_CUR | SEEK_END) + 1) == -1);
+      ASSERT (errno == EINVAL);
+#endif
+      ASSERT (lseek (1, (off_t)2, SEEK_SET) == 2);
+      errno = 0;
+      ASSERT (lseek (1, (off_t)-4, SEEK_CUR) == -1);
+      ASSERT (errno == EINVAL);
+      errno = 0;
+#if ! defined __BEOS__
+      /* POSIX says that the last lseek call, when failing, does not change
+         the current offset.  But BeOS sets it to 0.  */
+      ASSERT (lseek (1, (off_t)0, SEEK_CUR) == 2);
+#endif
+#if 0 /* leads to SIGSYS on IRIX 6.5 */
+      ASSERT (lseek (1, (off_t)0, (SEEK_SET | SEEK_CUR | SEEK_END) + 1) == -1);
+      ASSERT (errno == EINVAL);
+#endif
+      break;
+
+    case '1': /* pipes */
+      errno = 0;
+      ASSERT (lseek (0, (off_t)0, SEEK_CUR) == -1);
+      ASSERT (errno == ESPIPE);
+      errno = 0;
+      ASSERT (lseek (1, (off_t)0, SEEK_CUR) == -1);
+      ASSERT (errno == ESPIPE);
+      break;
+
+    case '2': /* closed */
+      /* Explicitly close file descriptors 0 and 1.  The <&- and >&- in the
+         invoking shell are not enough on HP-UX.  */
+      close (0);
+      close (1);
+      errno = 0;
+      ASSERT (lseek (0, (off_t)0, SEEK_CUR) == -1);
+      ASSERT (errno == EBADF);
+      errno = 0;
+      ASSERT (lseek (1, (off_t)0, SEEK_CUR) == -1);
+      ASSERT (errno == EBADF);
+      break;
+
+    default:
+      return 1;
+    }
+  return 0;
+}
diff --git a/libmissing/tests/test-lseek.sh b/libmissing/tests/test-lseek.sh
new file mode 100755
index 0000000..e84c2bb
--- /dev/null
+++ b/libmissing/tests/test-lseek.sh
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+tmpfiles=
+trap 'rm -fr $tmpfiles' 1 2 3 15
+
+tmpfiles=t-lseek.tmp
+# seekable files
+./test-lseek${EXEEXT} 0 < "$srcdir/test-lseek.sh" > t-lseek.tmp || exit 1
+
+# pipes
+echo hi | ./test-lseek${EXEEXT} 1 | cat || exit 1
+
+# closed descriptors
+./test-lseek${EXEEXT} 2 <&- >&- || exit 1
+
+rm -rf $tmpfiles
+exit 0
diff --git a/src/file-server.c b/src/file-server.c
index 4eef647..880adea 100644
--- a/src/file-server.c
+++ b/src/file-server.c
@@ -528,7 +528,7 @@ static int check_logfile_data(monitor_fd_t *monitor, struct stat *st)
                  */
                 if ( (slen = prelude_string_get_len(monitor->buf)) ) {
                         lml_dispatch_log(monitor->source, prelude_string_get_string(monitor->buf), slen);
-                        file_metadata_save(monitor, ftell(monitor->fd) - monitor->current_line_len);
+                        file_metadata_save(monitor, ftello(monitor->fd) - monitor->current_line_len);
                 }
 
                 monitor->current_line_len = 0;
_______________________________________________
Prelude-cvslog site list
[email protected]
http://lists.prelude-technologies.com/mailman/listinfo/prelude-cvslog