prelude-manager/master: Update GnuLib code

[email protected] Tue, 9 Mar 2010 16:09:27 +0100 (CET)
Newsgroups gmane.comp.security.ids.prelude.cvs
Message-ID <[email protected]>
commit 4fcc62f4899937eb0d6f6029c0e36b5c74c2127c
Author: Yoann Vandoorselaere <[email protected]>
Date:   Wed Feb 24 14:08:36 2010 +0100

    Update GnuLib code


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

 libmissing/Makefile.am                |   19 +-
 libmissing/dup2.c                     |  128 ++++++++
 libmissing/fcntl.c                    |  294 ++++++++++++++++++
 libmissing/getdtablesize.c            |   63 ++++
 libmissing/gettimeofday.c             |    2 +-
 libmissing/m4/dos.m4                  |   71 +++++
 libmissing/m4/dup2.m4                 |   58 ++++
 libmissing/m4/fcntl-o.m4              |   81 +++++
 libmissing/m4/fcntl.m4                |   83 +++++
 libmissing/m4/getdtablesize.m4        |   15 +
 libmissing/m4/gettimeofday.m4         |   65 +++--
 libmissing/m4/gnulib-common.m4        |   15 +-
 libmissing/m4/gnulib-comp.m4          |    9 +-
 libmissing/m4/lstat.m4                |   28 ++
 libmissing/m4/mode_t.m4               |   26 ++
 libmissing/m4/open.m4                 |   74 +++++
 libmissing/m4/stat.m4                 |   63 ++++
 libmissing/m4/stddef_h.m4             |   45 +++
 libmissing/m4/stdio_h.m4              |    3 +-
 libmissing/m4/symlink.m4              |   38 +++
 libmissing/m4/sys_stat_h.m4           |   80 +++++
 libmissing/m4/sys_time_h.m4           |   45 ++-
 libmissing/m4/warn-on-use.m4          |   45 +++
 libmissing/netdb.in.h                 |   28 +-
 libmissing/stat.c                     |  104 +++++++
 libmissing/stddef.in.h                |   86 +++++
 libmissing/stdio.in.h                 |   88 +++---
 libmissing/sys_stat.in.h              |  548 +++++++++++++++++++++++++++++++++
 libmissing/sys_time.in.h              |   18 +-
 libmissing/tests/Makefile.am          |   15 +-
 libmissing/tests/binary-io.h          |   66 ++++
 libmissing/tests/ignore-value.h       |   37 +++
 libmissing/tests/lstat.c              |   91 ++++++
 libmissing/tests/macros.h             |   64 ++++
 libmissing/tests/open.c               |  166 ++++++++++
 libmissing/tests/same-inode.h         |   25 ++
 libmissing/tests/signature.h          |   48 +++
 libmissing/tests/symlink.c            |   57 ++++
 libmissing/tests/test-binary-io.c     |   64 ++++
 libmissing/tests/test-binary-io.sh    |   11 +
 libmissing/tests/test-dup2.c          |  193 ++++++++++++
 libmissing/tests/test-fcntl-h.c       |   38 +++
 libmissing/tests/test-getdtablesize.c |   34 ++
 libmissing/tests/test-gettimeofday.c  |    8 +-
 libmissing/tests/test-inet_ntop.c     |   56 ++++
 libmissing/tests/test-lstat.c         |   60 ++++
 libmissing/tests/test-lstat.h         |  116 +++++++
 libmissing/tests/test-open.c          |   41 +++
 libmissing/tests/test-open.h          |   87 ++++++
 libmissing/tests/test-stat.c          |   56 ++++
 libmissing/tests/test-stat.h          |  100 ++++++
 libmissing/tests/test-stddef.c        |   38 +++
 libmissing/tests/test-symlink.c       |   47 +++
 libmissing/tests/test-symlink.h       |   95 ++++++
 libmissing/tests/test-sys_stat.c      |  288 +++++++++++++++++
 55 files changed, 4003 insertions(+), 120 deletions(-)

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

diff --git a/libmissing/Makefile.am b/libmissing/Makefile.am
index 2c285db..72175d2 100644
--- a/libmissing/Makefile.am
+++ b/libmissing/Makefile.am
@@ -240,6 +240,15 @@ EXTRA_libmissing_la_SOURCES += gai_strerror.c getaddrinfo.c
 
 ## end   gnulib module getaddrinfo
 
+## begin gnulib module getdtablesize
+
+
+EXTRA_DIST += getdtablesize.c
+
+EXTRA_libmissing_la_SOURCES += getdtablesize.c
+
+## end   gnulib module getdtablesize
+
 ## begin gnulib module gettext-h
 
 libmissing_la_SOURCES += gettext.h
@@ -586,6 +595,7 @@ stdio.h: stdio.in.h $(WARN_ON_USE_H) $(ARG_NONNULL_H)
 	      -e 's|@''REPLACE_FSEEKO''@|$(REPLACE_FSEEKO)|g' \
 	      -e 's|@''REPLACE_FTELL''@|$(REPLACE_FTELL)|g' \
 	      -e 's|@''REPLACE_FTELLO''@|$(REPLACE_FTELLO)|g' \
+	      -e 's|@''REPLACE_GETDELIM''@|$(REPLACE_GETDELIM)|g' \
 	      -e 's|@''REPLACE_GETLINE''@|$(REPLACE_GETLINE)|g' \
 	      -e 's|@''REPLACE_OBSTACK_PRINTF''@|$(REPLACE_OBSTACK_PRINTF)|g' \
 	      -e 's|@''REPLACE_PERROR''@|$(REPLACE_PERROR)|g' \
@@ -824,11 +834,11 @@ EXTRA_DIST += sys_stat.in.h
 
 ## begin gnulib module sys_time
 
-BUILT_SOURCES += $(SYS_TIME_H)
+BUILT_SOURCES += sys/time.h
 
 # We need the following in order to create <sys/time.h> when the system
 # doesn't have one that works with the given compiler.
-sys/time.h: sys_time.in.h $(ARG_NONNULL_H)
+sys/time.h: sys_time.in.h $(WARN_ON_USE_H) $(ARG_NONNULL_H)
 	$(AM_V_at)$(MKDIR_P) sys
 	$(AM_V_GEN)rm -f $@-t $@ && \
 	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
@@ -836,9 +846,12 @@ sys/time.h: sys_time.in.h $(ARG_NONNULL_H)
 	      -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
 	      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
 	      -e 's|@''NEXT_SYS_TIME_H''@|$(NEXT_SYS_TIME_H)|g' \
-	      -e 's/@''REPLACE_GETTIMEOFDAY''@/$(REPLACE_GETTIMEOFDAY)/g' \
+	      -e 's/@''GNULIB_GETTIMEOFDAY''@/$(GNULIB_GETTIMEOFDAY)/g' \
+	      -e 's/@''HAVE_GETTIMEOFDAY''@/$(HAVE_GETTIMEOFDAY)/g' \
 	      -e 's/@''HAVE_STRUCT_TIMEVAL''@/$(HAVE_STRUCT_TIMEVAL)/g' \
+	      -e 's/@''REPLACE_GETTIMEOFDAY''@/$(REPLACE_GETTIMEOFDAY)/g' \
 	      -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \
+	      -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \
 	      < $(srcdir)/sys_time.in.h; \
 	} > $@-t && \
 	mv $@-t $@
diff --git a/libmissing/dup2.c b/libmissing/dup2.c
new file mode 100644
index 0000000..4b2deaf
--- /dev/null
+++ b/libmissing/dup2.c
@@ -0,0 +1,128 @@
+/* Duplicate an open file descriptor to a specified file descriptor.
+
+   Copyright (C) 1999, 2004-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/>.  */
+
+/* written by Paul Eggert */
+
+#include <config.h>
+
+/* Specification.  */
+#include <unistd.h>
+
+#include <errno.h>
+#include <fcntl.h>
+
+#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+/* Get declarations of the Win32 API functions.  */
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+#endif
+
+#if HAVE_DUP2
+
+# undef dup2
+
+int
+rpl_dup2 (int fd, int desired_fd)
+{
+  int result;
+# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+  /* If fd is closed, mingw hangs on dup2 (fd, fd).  If fd is open,
+     dup2 (fd, fd) returns 0, but all further attempts to use fd in
+     future dup2 calls will hang.  */
+  if (fd == desired_fd)
+    {
+      if ((HANDLE) _get_osfhandle (fd) == INVALID_HANDLE_VALUE)
+        {
+          errno = EBADF;
+          return -1;
+        }
+      return fd;
+    }
+  /* Wine 1.0.1 return 0 when desired_fd is negative but not -1:
+     http://bugs.winehq.org/show_bug.cgi?id=21289 */
+  if (desired_fd < 0)
+    {
+      errno = EBADF;
+      return -1;
+    }
+# endif
+  result = dup2 (fd, desired_fd);
+# ifdef __linux__
+  /* Correct a Linux return value.
+     <http://git.kernel.org/?p=linux/kernel/git/stable/linux-2.6.30.y.git;a=commitdiff;h=2b79bc4f7ebbd5af3c8b867968f9f15602d5f802>
+   */
+  if (fd == desired_fd && result == (unsigned int) -EBADF)
+    {
+      errno = EBADF;
+      result = -1;
+    }
+# endif
+  if (result == 0)
+    result = desired_fd;
+  /* Correct a cygwin 1.5.x errno value.  */
+  else if (result == -1 && errno == EMFILE)
+    errno = EBADF;
+# if REPLACE_FCHDIR
+  if (fd != desired_fd && result != -1)
+    result = _gl_register_dup (fd, result);
+# endif
+  return result;
+}
+
+#else /* !HAVE_DUP2 */
+
+/* On older platforms, dup2 did not exist.  */
+
+# ifndef F_DUPFD
+static int
+dupfd (int fd, int desired_fd)
+{
+  int duplicated_fd = dup (fd);
+  if (duplicated_fd < 0 || duplicated_fd == desired_fd)
+    return duplicated_fd;
+  else
+    {
+      int r = dupfd (fd, desired_fd);
+      int e = errno;
+      close (duplicated_fd);
+      errno = e;
+      return r;
+    }
+}
+# endif
+
+int
+dup2 (int fd, int desired_fd)
+{
+  int result = fcntl (fd, F_GETFL) < 0 ? -1 : fd;
+  if (result == -1 || fd == desired_fd)
+    return result;
+  close (desired_fd);
+# ifdef F_DUPFD
+  result = fcntl (fd, F_DUPFD, desired_fd);
+#  if REPLACE_FCHDIR
+  if (0 <= result)
+    result = _gl_register_dup (fd, result);
+#  endif
+# else
+  result = dupfd (fd, desired_fd);
+# endif
+  if (result == -1 && (errno == EMFILE || errno == EINVAL))
+    errno = EBADF;
+  return result;
+}
+#endif /* !HAVE_DUP2 */
diff --git a/libmissing/fcntl.c b/libmissing/fcntl.c
new file mode 100644
index 0000000..92bb52e
--- /dev/null
+++ b/libmissing/fcntl.c
@@ -0,0 +1,294 @@
+/* Provide file descriptor control.
+
+   Copyright (C) 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/>.  */
+
+/* Written by Eric Blake <[email protected]>.  */
+
+#include <config.h>
+
+/* Specification.  */
+#include <fcntl.h>
+
+#include <errno.h>
+#include <limits.h>
+#include <stdarg.h>
+#include <unistd.h>
+
+#if !HAVE_FCNTL
+# define rpl_fcntl fcntl
+#endif
+#undef fcntl
+
+#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+/* Get declarations of the Win32 API functions.  */
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+
+/* Upper bound on getdtablesize().  See lib/getdtablesize.c.  */
+# define OPEN_MAX_MAX 0x10000
+
+/* Duplicate OLDFD into the first available slot of at least NEWFD,
+   which must be positive, with FLAGS determining whether the duplicate
+   will be inheritable.  */
+static int
+dupfd (int oldfd, int newfd, int flags)
+{
+  /* Mingw has no way to create an arbitrary fd.  Iterate until all
+     file descriptors less than newfd are filled up.  */
+  HANDLE curr_process = GetCurrentProcess ();
+  HANDLE old_handle = (HANDLE) _get_osfhandle (oldfd);
+  unsigned char fds_to_close[OPEN_MAX_MAX / CHAR_BIT];
+  unsigned int fds_to_close_bound = 0;
+  int result;
+  BOOL inherit = flags & O_CLOEXEC ? FALSE : TRUE;
+  int mode;
+
+  if (newfd < 0 || getdtablesize () <= newfd)
+    {
+      errno = EINVAL;
+      return -1;
+    }
+  if (old_handle == INVALID_HANDLE_VALUE
+      || (mode = setmode (oldfd, O_BINARY)) == -1)
+    {
+      /* oldfd is not open, or is an unassigned standard file
+         descriptor.  */
+      errno = EBADF;
+      return -1;
+    }
+  setmode (oldfd, mode);
+  flags |= mode;
+
+  for (;;)
+    {
+      HANDLE new_handle;
+      int duplicated_fd;
+      unsigned int index;
+
+      if (!DuplicateHandle (curr_process,           /* SourceProcessHandle */
+                            old_handle,             /* SourceHandle */
+                            curr_process,           /* TargetProcessHandle */
+                            (PHANDLE) &new_handle,  /* TargetHandle */
+                            (DWORD) 0,              /* DesiredAccess */
+                            inherit,                /* InheritHandle */
+                            DUPLICATE_SAME_ACCESS)) /* Options */
+        {
+          /* TODO: Translate GetLastError () into errno.  */
+          errno = EMFILE;
+          result = -1;
+          break;
+        }
+      duplicated_fd = _open_osfhandle ((long) new_handle, flags);
+      if (duplicated_fd < 0)
+        {
+          CloseHandle (new_handle);
+          errno = EMFILE;
+          result = -1;
+          break;
+        }
+      if (newfd <= duplicated_fd)
+        {
+          result = duplicated_fd;
+          break;
+        }
+
+      /* Set the bit duplicated_fd in fds_to_close[].  */
+      index = (unsigned int) duplicated_fd / CHAR_BIT;
+      if (fds_to_close_bound <= index)
+        {
+          if (sizeof fds_to_close <= index)
+            /* Need to increase OPEN_MAX_MAX.  */
+            abort ();
+          memset (fds_to_close + fds_to_close_bound, '\0',
+                  index + 1 - fds_to_close_bound);
+          fds_to_close_bound = index + 1;
+        }
+      fds_to_close[index] |= 1 << ((unsigned int) duplicated_fd % CHAR_BIT);
+    }
+
+  /* Close the previous fds that turned out to be too small.  */
+  {
+    int saved_errno = errno;
+    unsigned int duplicated_fd;
+
+    for (duplicated_fd = 0;
+         duplicated_fd < fds_to_close_bound * CHAR_BIT;
+         duplicated_fd++)
+      if ((fds_to_close[duplicated_fd / CHAR_BIT]
+           >> (duplicated_fd % CHAR_BIT))
+          & 1)
+        close (duplicated_fd);
+
+    errno = saved_errno;
+  }
+
+# if REPLACE_FCHDIR
+  if (0 <= result)
+    result = _gl_register_dup (oldfd, result);
+# endif
+  return result;
+}
+#endif /* W32 */
+
+/* Perform the specified ACTION on the file descriptor FD, possibly
+   using the argument ARG further described below.  This replacement
+   handles the following actions, and forwards all others on to the
+   native fcntl.  An unrecognized ACTION returns -1 with errno set to
+   EINVAL.
+
+   F_DUPFD - duplicate FD, with int ARG being the minimum target fd.
+   If successful, return the duplicate, which will be inheritable;
+   otherwise return -1 and set errno.
+
+   F_DUPFD_CLOEXEC - duplicate FD, with int ARG being the minimum
+   target fd.  If successful, return the duplicate, which will not be
+   inheritable; otherwise return -1 and set errno.
+
+   F_GETFD - ARG need not be present.  If successful, return a
+   non-negative value containing the descriptor flags of FD (only
+   FD_CLOEXEC is portable, but other flags may be present); otherwise
+   return -1 and set errno.  */
+
+int
+rpl_fcntl (int fd, int action, /* arg */...)
+{
+  va_list arg;
+  int result = -1;
+  va_start (arg, action);
+  switch (action)
+    {
+
+#if !HAVE_FCNTL
+    case F_DUPFD:
+      {
+        int target = va_arg (arg, int);
+        result = dupfd (fd, target, 0);
+        break;
+      }
+#elif FCNTL_DUPFD_BUGGY || REPLACE_FCHDIR
+    case F_DUPFD:
+      {
+        int target = va_arg (arg, int);
+        /* Detect invalid target; needed for cygwin 1.5.x.  */
+        if (target < 0 || getdtablesize () <= target)
+          errno = EINVAL;
+        else
+          {
+            result = fcntl (fd, action, target);
+# if REPLACE_FCHDIR
+            if (0 <= result)
+              result = _gl_register_dup (fd, result);
+# endif
+          }
+        break;
+      } /* F_DUPFD */
+#endif /* FCNTL_DUPFD_BUGGY || REPLACE_FCHDIR */
+
+    case F_DUPFD_CLOEXEC:
+      {
+        int target = va_arg (arg, int);
+
+#if !HAVE_FCNTL
+        result = dupfd (fd, target, O_CLOEXEC);
+        break;
+#else /* HAVE_FCNTL */
+        /* Try the system call first, if the headers claim it exists
+           (that is, if GNULIB_defined_F_DUPFD_CLOEXEC is 0), since we
+           may be running with a glibc that has the macro but with an
+           older kernel that does not support it.  Cache the
+           information on whether the system call really works, but
+           avoid caching failure if the corresponding F_DUPFD fails
+           for any reason.  0 = unknown, 1 = yes, -1 = no.  */
+        static int have_dupfd_cloexec = GNULIB_defined_F_DUPFD_CLOEXEC ? -1 : 0;
+        if (0 <= have_dupfd_cloexec)
+          {
+            result = fcntl (fd, action, target);
+            if (0 <= result || errno != EINVAL)
+              {
+                have_dupfd_cloexec = 1;
+# if REPLACE_FCHDIR
+                if (0 <= result)
+                  result = _gl_register_dup (fd, result);
+# endif
+              }
+            else
+              {
+                result = rpl_fcntl (fd, F_DUPFD, target);
+                if (result < 0)
+                  break;
+                have_dupfd_cloexec = -1;
+              }
+          }
+        else
+          result = rpl_fcntl (fd, F_DUPFD, target);
+        if (0 <= result && have_dupfd_cloexec == -1)
+          {
+            int flags = fcntl (result, F_GETFD);
+            if (flags < 0 || fcntl (result, F_SETFD, flags | FD_CLOEXEC) == -1)
+              {
+                int saved_errno = errno;
+                close (result);
+                errno = saved_errno;
+                result = -1;
+              }
+          }
+        break;
+#endif /* HAVE_FCNTL */
+      } /* F_DUPFD_CLOEXEC */
+
+#if !HAVE_FCNTL
+    case F_GETFD:
+      {
+# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+        HANDLE handle = (HANDLE) _get_osfhandle (fd);
+        DWORD flags;
+        if (handle == INVALID_HANDLE_VALUE
+            || GetHandleInformation (handle, &flags) == 0)
+          errno = EBADF;
+        else
+          result = (flags & HANDLE_FLAG_INHERIT) ? 0 : FD_CLOEXEC;
+# else /* !W32 */
+        /* Use dup2 to reject invalid file descriptors.  No way to
+           access this information, so punt.  */
+        if (0 <= dup2 (fd, fd))
+          result = 0;
+# endif /* !W32 */
+        break;
+      } /* F_GETFD */
+#endif /* !HAVE_FCNTL */
+
+      /* Implementing F_SETFD on mingw is not trivial - there is no
+         API for changing the O_NOINHERIT bit on an fd, and merely
+         changing the HANDLE_FLAG_INHERIT bit on the underlying handle
+         can lead to odd state.  It may be possible by duplicating the
+         handle, using _open_osfhandle with the right flags, then
+         using dup2 to move the duplicate onto the original, but that
+         is not supported for now.  */
+
+    default:
+      {
+#if HAVE_FCNTL
+        void *p = va_arg (arg, void *);
+        result = fcntl (fd, action, p);
+#else
+        errno = EINVAL;
+#endif
+        break;
+      }
+    }
+  va_end (arg);
+  return result;
+}
diff --git a/libmissing/getdtablesize.c b/libmissing/getdtablesize.c
new file mode 100644
index 0000000..4d958f6
--- /dev/null
+++ b/libmissing/getdtablesize.c
@@ -0,0 +1,63 @@
+/* getdtablesize() function for platforms that don't have it.
+   Copyright (C) 2008-2010 Free Software Foundation, Inc.
+   Written by Bruno Haible <[email protected]>, 2008.
+
+   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 <unistd.h>
+
+#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+
+#include <stdio.h>
+
+/* Cache for the previous getdtablesize () result.  */
+static int dtablesize;
+
+int
+getdtablesize (void)
+{
+  if (dtablesize == 0)
+    {
+      /* We are looking for the number N such that the valid file descriptors
+         are 0..N-1.  It can be obtained through a loop as follows:
+           {
+             int fd;
+             for (fd = 3; fd < 65536; fd++)
+               if (dup2 (0, fd) == -1)
+                 break;
+             return fd;
+           }
+         On Windows XP, the result is 2048.
+         The drawback of this loop is that it allocates memory for a libc
+         internal array that is never freed.
+
+         The number N can also be obtained as the upper bound for
+         _getmaxstdio ().  _getmaxstdio () returns the maximum number of open
+         FILE objects.  The sanity check in _setmaxstdio reveals the maximum
+         number of file descriptors.  This too allocates memory, but it is
+         freed when we call _setmaxstdio with the original value.  */
+      int orig_max_stdio = _getmaxstdio ();
+      unsigned int bound;
+      for (bound = 0x10000; _setmaxstdio (bound) < 0; bound = bound / 2)
+        ;
+      _setmaxstdio (orig_max_stdio);
+      dtablesize = bound;
+    }
+  return dtablesize;
+}
+
+#endif
diff --git a/libmissing/gettimeofday.c b/libmissing/gettimeofday.c
index 87821ee..df8d09e 100644
--- a/libmissing/gettimeofday.c
+++ b/libmissing/gettimeofday.c
@@ -100,7 +100,7 @@ rpl_tzset (void)
    causes problems.  */
 
 int
-rpl_gettimeofday (struct timeval *restrict tv, void *restrict tz)
+gettimeofday (struct timeval *restrict tv, void *restrict tz)
 {
 #undef gettimeofday
 #if HAVE_GETTIMEOFDAY
diff --git a/libmissing/m4/dos.m4 b/libmissing/m4/dos.m4
new file mode 100644
index 0000000..5660542
--- /dev/null
+++ b/libmissing/m4/dos.m4
@@ -0,0 +1,71 @@
+#serial 11   -*- autoconf -*-
+
+# Define some macros required for proper operation of code in lib/*.c
+# on MSDOS/Windows systems.
+
+# Copyright (C) 2000-2001, 2004-2006, 2009-2010 Free Software Foundation, Inc.
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# From Jim Meyering.
+
+AC_DEFUN([gl_AC_DOS],
+  [
+    AC_CACHE_CHECK([whether system is Windows or MSDOS], [ac_cv_win_or_dos],
+      [
+        AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [[
+#if !defined _WIN32 && !defined __WIN32__ && !defined __MSDOS__ && !defined __CYGWIN__
+neither MSDOS nor Windows
+#endif]])],
+        [ac_cv_win_or_dos=yes],
+        [ac_cv_win_or_dos=no])
+      ])
+
+    if test x"$ac_cv_win_or_dos" = xyes; then
+      ac_fs_accepts_drive_letter_prefix=1
+      ac_fs_backslash_is_file_name_separator=1
+      AC_CACHE_CHECK([whether drive letter can start relative path],
+                     [ac_cv_drive_letter_can_be_relative],
+        [
+          AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [[
+#if defined __CYGWIN__
+drive letters are always absolute
+#endif]])],
+          [ac_cv_drive_letter_can_be_relative=yes],
+          [ac_cv_drive_letter_can_be_relative=no])
+        ])
+      if test x"$ac_cv_drive_letter_can_be_relative" = xyes; then
+        ac_fs_drive_letter_can_be_relative=1
+      else
+        ac_fs_drive_letter_can_be_relative=0
+      fi
+    else
+      ac_fs_accepts_drive_letter_prefix=0
+      ac_fs_backslash_is_file_name_separator=0
+      ac_fs_drive_letter_can_be_relative=0
+    fi
+
+    AC_DEFINE_UNQUOTED([FILE_SYSTEM_ACCEPTS_DRIVE_LETTER_PREFIX],
+      $ac_fs_accepts_drive_letter_prefix,
+      [Define on systems for which file names may have a so-called
+       `drive letter' prefix, define this to compute the length of that
+       prefix, including the colon.])
+
+    AH_VERBATIM(ISSLASH,
+    [#if FILE_SYSTEM_BACKSLASH_IS_FILE_NAME_SEPARATOR
+# define ISSLASH(C) ((C) == '/' || (C) == '\\')
+#else
+# define ISSLASH(C) ((C) == '/')
+#endif])
+
+    AC_DEFINE_UNQUOTED([FILE_SYSTEM_BACKSLASH_IS_FILE_NAME_SEPARATOR],
+      $ac_fs_backslash_is_file_name_separator,
+      [Define if the backslash character may also serve as a file name
+       component separator.])
+
+    AC_DEFINE_UNQUOTED([FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE],
+      $ac_fs_drive_letter_can_be_relative,
+      [Define if a drive letter prefix denotes a relative path if it is
+       not followed by a file name component separator.])
+  ])
diff --git a/libmissing/m4/dup2.m4 b/libmissing/m4/dup2.m4
new file mode 100644
index 0000000..998d66f
--- /dev/null
+++ b/libmissing/m4/dup2.m4
@@ -0,0 +1,58 @@
+#serial 10
+dnl Copyright (C) 2002, 2005, 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_DUP2],
+[
+  AC_REQUIRE([gl_UNISTD_H_DEFAULTS])
+  AC_REQUIRE([AC_CANONICAL_HOST])
+  AC_CHECK_FUNCS_ONCE([dup2])
+  if test $ac_cv_func_dup2 = no; then
+    HAVE_DUP2=0
+    AC_LIBOBJ([dup2])
+  else
+    AC_CACHE_CHECK([whether dup2 works], [gl_cv_func_dup2_works],
+      [AC_RUN_IFELSE([
+         AC_LANG_PROGRAM([[#include <unistd.h>
+#include <errno.h>]],
+           [if (dup2 (1, 1) == 0)
+              return 1;
+            close (0);
+            if (dup2 (0, 0) != -1)
+              return 2;
+            /* Many gnulib modules require POSIX conformance of EBADF.  */
+            if (dup2 (1, 1000000) == -1 && errno != EBADF)
+              return 3;
+            return 0;
+           ])
+        ],
+        [gl_cv_func_dup2_works=yes], [gl_cv_func_dup2_works=no],
+        [case "$host_os" in
+           mingw*) # on this platform, dup2 always returns 0 for success
+             gl_cv_func_dup2_works=no;;
+           cygwin*) # on cygwin 1.5.x, dup2(1,1) returns 0
+             gl_cv_func_dup2_works=no;;
+           linux*) # On linux between 2008-07-27 and 2009-05-11, dup2 of a
+                   # closed fd may yield -EBADF instead of -1 / errno=EBADF.
+             gl_cv_func_dup2_works=no;;
+           freebsd*) # on FreeBSD 6.1, dup2(1,1000000) gives EMFILE, not EBADF.
+             gl_cv_func_dup2_works=no;;
+           *) gl_cv_func_dup2_works=yes;;
+         esac])
+      ])
+    if test "$gl_cv_func_dup2_works" = no; then
+      gl_REPLACE_DUP2
+    fi
+  fi
+])
+
+AC_DEFUN([gl_REPLACE_DUP2],
+[
+  AC_REQUIRE([gl_UNISTD_H_DEFAULTS])
+  if test $ac_cv_func_dup2 = yes; then
+    REPLACE_DUP2=1
+  fi
+  AC_LIBOBJ([dup2])
+])
diff --git a/libmissing/m4/fcntl-o.m4 b/libmissing/m4/fcntl-o.m4
new file mode 100644
index 0000000..67167cb
--- /dev/null
+++ b/libmissing/m4/fcntl-o.m4
@@ -0,0 +1,81 @@
+# fcntl-o.m4 serial 1
+dnl Copyright (C) 2006, 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.
+
+dnl Written by Paul Eggert.
+
+# Test whether the flags O_NOATIME and O_NOFOLLOW actually work.
+# Define HAVE_WORKING_O_NOATIME to 1 if O_NOATIME works, or to 0 otherwise.
+# Define HAVE_WORKING_O_NOFOLLOW to 1 if O_NOFOLLOW works, or to 0 otherwise.
+AC_DEFUN([gl_FCNTL_O_FLAGS],
+[
+  dnl Persuade glibc <fcntl.h> to define O_NOATIME and O_NOFOLLOW.
+  AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
+  AC_CACHE_CHECK([for working fcntl.h], [gl_cv_header_working_fcntl_h],
+    [AC_RUN_IFELSE(
+       [AC_LANG_PROGRAM(
+          [[#include <sys/types.h>
+           #include <sys/stat.h>
+           #include <unistd.h>
+           #include <fcntl.h>
+           #ifndef O_NOATIME
+            #define O_NOATIME 0
+           #endif
+           #ifndef O_NOFOLLOW
+            #define O_NOFOLLOW 0
+           #endif
+           static int const constants[] =
+            {
+              O_CREAT, O_EXCL, O_NOCTTY, O_TRUNC, O_APPEND,
+              O_NONBLOCK, O_SYNC, O_ACCMODE, O_RDONLY, O_RDWR, O_WRONLY
+            };
+          ]],
+          [[
+            int status = !constants;
+            {
+              static char const sym[] = "conftest.sym";
+              if (symlink (".", sym) != 0
+                  || close (open (sym, O_RDONLY | O_NOFOLLOW)) == 0)
+                status |= 32;
+              unlink (sym);
+            }
+            {
+              static char const file[] = "confdefs.h";
+              int fd = open (file, O_RDONLY | O_NOATIME);
+              char c;
+              struct stat st0, st1;
+              if (fd < 0
+                  || fstat (fd, &st0) != 0
+                  || sleep (1) != 0
+                  || read (fd, &c, 1) != 1
+                  || close (fd) != 0
+                  || stat (file, &st1) != 0
+                  || st0.st_atime != st1.st_atime)
+                status |= 64;
+            }
+            return status;]])],
+       [gl_cv_header_working_fcntl_h=yes],
+       [case $? in #(
+        32) gl_cv_header_working_fcntl_h='no (bad O_NOFOLLOW)';; #(
+        64) gl_cv_header_working_fcntl_h='no (bad O_NOATIME)';; #(
+        96) gl_cv_header_working_fcntl_h='no (bad O_NOATIME, O_NOFOLLOW)';; #(
+         *) gl_cv_header_working_fcntl_h='no';;
+        esac],
+       [gl_cv_header_working_fcntl_h=cross-compiling])])
+
+  case $gl_cv_header_working_fcntl_h in #(
+  *O_NOATIME* | no | cross-compiling) ac_val=0;; #(
+  *) ac_val=1;;
+  esac
+  AC_DEFINE_UNQUOTED([HAVE_WORKING_O_NOATIME], [$ac_val],
+    [Define to 1 if O_NOATIME works.])
+
+  case $gl_cv_header_working_fcntl_h in #(
+  *O_NOFOLLOW* | no | cross-compiling) ac_val=0;; #(
+  *) ac_val=1;;
+  esac
+  AC_DEFINE_UNQUOTED([HAVE_WORKING_O_NOFOLLOW], [$ac_val],
+    [Define to 1 if O_NOFOLLOW works.])
+])
diff --git a/libmissing/m4/fcntl.m4 b/libmissing/m4/fcntl.m4
new file mode 100644
index 0000000..fcb5f44
--- /dev/null
+++ b/libmissing/m4/fcntl.m4
@@ -0,0 +1,83 @@
+# fcntl.m4 serial 3
+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.
+
+# For now, this module ensures that fcntl()
+# - supports F_DUPFD correctly
+# - supports or emulates F_DUPFD_CLOEXEC
+# - supports F_GETFD
+# Still to be ported to mingw:
+# - F_SETFD
+# - F_GETFL, F_SETFL
+# - F_GETOWN, F_SETOWN
+# - F_GETLK, F_SETLK, F_SETLKW
+AC_DEFUN([gl_FUNC_FCNTL],
+[
+  dnl Persuade glibc to expose F_DUPFD_CLOEXEC.
+  AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
+  AC_REQUIRE([gl_FCNTL_H_DEFAULTS])
+  AC_REQUIRE([AC_CANONICAL_HOST])
+  AC_CHECK_FUNCS_ONCE([fcntl])
+  if test $ac_cv_func_fcntl = no; then
+    gl_REPLACE_FCNTL
+  else
+    dnl cygwin 1.5.x F_DUPFD has wrong errno, and allows negative target
+    AC_CACHE_CHECK([whether fcntl handles F_DUPFD correctly],
+      [gl_cv_func_fcntl_f_dupfd_works],
+      [AC_RUN_IFELSE([AC_LANG_PROGRAM([[
+#include <fcntl.h>
+]], [[return fcntl (0, F_DUPFD, -1) != -1;
+         ]])],
+         [gl_cv_func_fcntl_f_dupfd_works=yes],
+         [gl_cv_func_fcntl_f_dupfd_works=no],
+         [# Guess that it works on glibc systems
+          case $host_os in #((
+            *-gnu*) gl_cv_func_fcntl_f_dupfd_works="guessing yes";;
+            *)      gl_cv_func_fcntl_f_dupfd_works="guessing no";;
+          esac])])
+    case $gl_cv_func_fcntl_f_dupfd_works in
+      *yes) ;;
+      *) gl_REPLACE_FCNTL
+        AC_DEFINE([FCNTL_DUPFD_BUGGY], [1], [Define this to 1 if F_DUPFD
+          behavior does not match POSIX]) ;;
+    esac
+
+    dnl Many systems lack F_DUPFD_CLOEXEC
+    AC_CACHE_CHECK([whether fcntl understands F_DUPFD_CLOEXEC],
+      [gl_cv_func_fcntl_f_dupfd_cloexec],
+      [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#include <fcntl.h>
+#ifndef F_DUPFD_CLOEXEC
+choke me
+#endif
+         ]])],
+         [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#ifdef __linux__
+/* The Linux kernel only added F_DUPFD_CLOEXEC in 2.6.24, so we always replace
+   it to support the semantics on older kernels that failed with EINVAL.  */
+choke me
+#endif
+           ]])],
+           [gl_cv_func_fcntl_f_dupfd_cloexec=yes],
+           [gl_cv_func_fcntl_f_dupfd_cloexec="needs runtime check"])],
+         [gl_cv_func_fcntl_f_dupfd_cloexec=no])])
+    if test "$gl_cv_func_fcntl_f_dupfd_cloexec" != yes; then
+      gl_REPLACE_FCNTL
+      dnl No witness macro needed for this bug.
+    fi
+  fi
+])
+
+AC_DEFUN([gl_REPLACE_FCNTL],
+[
+  AC_REQUIRE([gl_FCNTL_H_DEFAULTS])
+  AC_CHECK_FUNCS_ONCE([fcntl])
+  if test $ac_cv_func_fcntl = no; then
+    HAVE_FCNTL=0
+  else
+    REPLACE_FCNTL=1
+  fi
+  AC_LIBOBJ([fcntl])
+])
diff --git a/libmissing/m4/getdtablesize.m4 b/libmissing/m4/getdtablesize.m4
new file mode 100644
index 0000000..d238628
--- /dev/null
+++ b/libmissing/m4/getdtablesize.m4
@@ -0,0 +1,15 @@
+# getdtablesize.m4 serial 1
+dnl Copyright (C) 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_GETDTABLESIZE],
+[
+  AC_REQUIRE([gl_UNISTD_H_DEFAULTS])
+  AC_CHECK_FUNCS_ONCE([getdtablesize])
+  if test $ac_cv_func_getdtablesize != yes; then
+    HAVE_GETDTABLESIZE=0
+    AC_LIBOBJ([getdtablesize])
+  fi
+])
diff --git a/libmissing/m4/gettimeofday.m4 b/libmissing/m4/gettimeofday.m4
index 735123e..709a4d4 100644
--- a/libmissing/m4/gettimeofday.m4
+++ b/libmissing/m4/gettimeofday.m4
@@ -1,4 +1,4 @@
-# serial 12
+# serial 15
 
 # Copyright (C) 2001-2003, 2005, 2007, 2009-2010 Free Software Foundation, Inc.
 # This file is free software; the Free Software Foundation
@@ -11,33 +11,53 @@ AC_DEFUN([gl_FUNC_GETTIMEOFDAY],
 [
   AC_REQUIRE([AC_C_RESTRICT])
   AC_REQUIRE([gl_HEADER_SYS_TIME_H])
+  AC_REQUIRE([gl_HEADER_SYS_TIME_H_DEFAULTS])
   AC_CHECK_FUNCS_ONCE([gettimeofday])
 
-  AC_CACHE_CHECK([for gettimeofday with POSIX signature],
-    [gl_cv_func_gettimeofday_posix_signature],
-    [AC_COMPILE_IFELSE(
-       [AC_LANG_PROGRAM(
-          [[#include <sys/time.h>
-            struct timeval c;
-          ]],
-          [[
-            int (*f) (struct timeval *restrict, void *restrict) = gettimeofday;
-            int x = f (&c, 0);
-            return !(x | c.tv_sec | c.tv_usec);
-          ]])],
-        [gl_cv_func_gettimeofday_posix_signature=yes],
-        [gl_cv_func_gettimeofday_posix_signature=no])])
-
-  gl_FUNC_GETTIMEOFDAY_CLOBBER
-
-  if test $gl_cv_func_gettimeofday_posix_signature != yes; then
-    REPLACE_GETTIMEOFDAY=1
-    SYS_TIME_H=sys/time.h
-    if test $gl_cv_func_gettimeofday_clobber != yes; then
+  gl_gettimeofday_timezone=void
+  if test $ac_cv_func_gettimeofday != yes; then
+    HAVE_GETTIMEOFDAY=0
+    AC_LIBOBJ([gettimeofday])
+    gl_PREREQ_GETTIMEOFDAY
+  else
+    gl_FUNC_GETTIMEOFDAY_CLOBBER
+    AC_CACHE_CHECK([for gettimeofday with POSIX signature],
+      [gl_cv_func_gettimeofday_posix_signature],
+      [AC_COMPILE_IFELSE(
+         [AC_LANG_PROGRAM(
+            [[#include <sys/time.h>
+              struct timeval c;
+              int gettimeofday (struct timeval *restrict, void *restrict);
+            ]],
+            [[/* glibc uses struct timezone * rather than the POSIX void *
+                 if _GNU_SOURCE is defined.  However, since the only portable
+                 use of gettimeofday uses NULL as the second parameter, and
+                 since the glibc definition is actually more typesafe, it is
+                 not worth wrapping this to get a compliant signature.  */
+              int (*f) (struct timeval *restrict, void *restrict)
+                = gettimeofday;
+              int x = f (&c, 0);
+              return !(x | c.tv_sec | c.tv_usec);
+            ]])],
+          [gl_cv_func_gettimeofday_posix_signature=yes],
+          [AC_COMPILE_IFELSE(
+            [AC_LANG_PROGRAM(
+              [[#include <sys/time.h>
+int gettimeofday (struct timeval *restrict, struct timezone *restrict);
+              ]])],
+            [gl_cv_func_gettimeofday_posix_signature=almost],
+            [gl_cv_func_gettimeofday_posix_signature=no])])])
+    if test $gl_cv_func_gettimeofday_posix_signature = almost; then
+      gl_gettimeofday_timezone='struct timezone'
+    elif test $gl_cv_func_gettimeofday_posix_signature != yes; then
+      REPLACE_GETTIMEOFDAY=1
       AC_LIBOBJ([gettimeofday])
       gl_PREREQ_GETTIMEOFDAY
     fi
   fi
+  AC_DEFINE_UNQUOTED([GETTIMEOFDAY_TIMEZONE], [$gl_gettimeofday_timezone],
+    [Define this to 'void' or 'struct timezone' to match the system's
+     declaration of the second argument to gettimeofday.])
 ])
 
 
@@ -78,7 +98,6 @@ AC_DEFUN([gl_FUNC_GETTIMEOFDAY_CLOBBER],
 
  if test $gl_cv_func_gettimeofday_clobber = yes; then
    REPLACE_GETTIMEOFDAY=1
-   SYS_TIME_H=sys/time.h
    gl_GETTIMEOFDAY_REPLACE_LOCALTIME
    AC_DEFINE([GETTIMEOFDAY_CLOBBERS_LOCALTIME], [1],
      [Define if gettimeofday clobbers the localtime buffer.])
diff --git a/libmissing/m4/gnulib-common.m4 b/libmissing/m4/gnulib-common.m4
index b7812a8..80ba263 100644
--- a/libmissing/m4/gnulib-common.m4
+++ b/libmissing/m4/gnulib-common.m4
@@ -1,4 +1,4 @@
-# gnulib-common.m4 serial 12
+# gnulib-common.m4 serial 13
 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,
@@ -61,9 +61,16 @@ m4_ifndef([AS_VAR_IF],
 [AS_IF([test x"AS_VAR_GET([$1])" = x""$2], [$3], [$4])])])
 
 # AC_PROG_MKDIR_P
-# is a backport of autoconf-2.60's AC_PROG_MKDIR_P.
-# Remove this macro when we can assume autoconf >= 2.60.
-m4_ifdef([AC_PROG_MKDIR_P], [], [
+# is a backport of autoconf-2.60's AC_PROG_MKDIR_P, with a fix
+# for interoperability with automake-1.9.6 from autoconf-2.62.
+# Remove this macro when we can assume autoconf >= 2.62 or
+# autoconf >= 2.60 && automake >= 1.10.
+m4_ifdef([AC_PROG_MKDIR_P], [
+  dnl For automake-1.9.6 && autoconf < 2.62: Ensure MKDIR_P is AC_SUBSTed.
+  m4_define([AC_PROG_MKDIR_P],
+    m4_defn([AC_PROG_MKDIR_P])[
+    AC_SUBST([MKDIR_P])])], [
+  dnl For autoconf < 2.60: Backport of AC_PROG_MKDIR_P.
   AC_DEFUN_ONCE([AC_PROG_MKDIR_P],
     [AC_REQUIRE([AM_PROG_MKDIR_P])dnl defined by automake
      MKDIR_P='$(mkdir_p)'
diff --git a/libmissing/m4/gnulib-comp.m4 b/libmissing/m4/gnulib-comp.m4
index b72b218..f924e77 100644
--- a/libmissing/m4/gnulib-comp.m4
+++ b/libmissing/m4/gnulib-comp.m4
@@ -57,9 +57,12 @@ AC_DEFUN([gl_INIT],
   gl_FUNC_FTW
   gl_GETADDRINFO
   gl_NETDB_MODULE_INDICATOR([getaddrinfo])
+  gl_FUNC_GETDTABLESIZE
+  gl_UNISTD_MODULE_INDICATOR([getdtablesize])
   AC_SUBST([LIBINTL])
   AC_SUBST([LTLIBINTL])
   gl_FUNC_GETTIMEOFDAY
+  gl_SYS_TIME_MODULE_INDICATOR([gettimeofday])
   gl_HOSTENT
   gl_INET_NTOP
   gl_ARPA_INET_MODULE_INDICATOR([inet_ntop])
@@ -148,8 +151,7 @@ AC_DEFUN([gl_INIT],
   m4_pushdef([gltests_LIBSOURCES_DIR], [])
   gl_COMMON
   gl_source_base='libmissing/tests'
-  gl_FUNC_GETDTABLESIZE
-  gl_UNISTD_MODULE_INDICATOR([getdtablesize])
+  AC_REQUIRE([AC_C_INLINE])
   AC_C_BIGENDIAN
   gl_FUNC_LSTAT
   gl_SYS_STAT_MODULE_INDICATOR([lstat])
@@ -275,6 +277,7 @@ AC_DEFUN([gl_FILE_LIST], [
   lib/ftw_.h
   lib/gai_strerror.c
   lib/getaddrinfo.c
+  lib/getdtablesize.c
   lib/gettext.h
   lib/gettimeofday.c
   lib/glthread/cond.c
@@ -445,8 +448,8 @@ AC_DEFUN([gl_FILE_LIST], [
   tests/zerosize-ptr.h
   tests=lib/binary-io.h
   tests=lib/dummy.c
-  tests=lib/getdtablesize.c
   tests=lib/glthread/yield.h
+  tests=lib/ignore-value.h
   tests=lib/intprops.h
   tests=lib/lstat.c
   tests=lib/open.c
diff --git a/libmissing/m4/lstat.m4 b/libmissing/m4/lstat.m4
new file mode 100644
index 0000000..5dbd16e
--- /dev/null
+++ b/libmissing/m4/lstat.m4
@@ -0,0 +1,28 @@
+# serial 20
+
+# Copyright (C) 1997-2001, 2003-2010 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+dnl From Jim Meyering.
+
+AC_DEFUN([gl_FUNC_LSTAT],
+[
+  AC_REQUIRE([gl_SYS_STAT_H_DEFAULTS])
+  dnl If lstat does not exist, the replacement <sys/stat.h> does
+  dnl "#define lstat stat", and lstat.c is a no-op.
+  AC_CHECK_FUNCS_ONCE([lstat])
+  if test $ac_cv_func_lstat = yes; then
+    AC_REQUIRE([AC_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK])
+    if test $ac_cv_func_lstat_dereferences_slashed_symlink = no; then
+      dnl Note: AC_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK does AC_LIBOBJ([lstat]).
+      REPLACE_LSTAT=1
+    fi
+    # Prerequisites of lib/lstat.c.
+    AC_REQUIRE([AC_C_INLINE])
+  else
+    HAVE_LSTAT=0
+  fi
+])
diff --git a/libmissing/m4/mode_t.m4 b/libmissing/m4/mode_t.m4
new file mode 100644
index 0000000..3178dfd
--- /dev/null
+++ b/libmissing/m4/mode_t.m4
@@ -0,0 +1,26 @@
+# mode_t.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.
+
+# For using mode_t, it's sufficient to use AC_TYPE_MODE_T and
+# include <sys/types.h>.
+
+# Define PROMOTED_MODE_T to the type that is the result of "default argument
+# promotion" (ISO C 6.5.2.2.(6)) of the type mode_t.
+AC_DEFUN([gl_PROMOTED_TYPE_MODE_T],
+[
+  AC_REQUIRE([AC_TYPE_MODE_T])
+  AC_CACHE_CHECK([for promoted mode_t type], [gl_cv_promoted_mode_t], [
+    dnl Assume mode_t promotes to 'int' if and only if it is smaller than 'int',
+    dnl and to itself otherwise. This assumption is not guaranteed by the ISO C
+    dnl standard, but we don't know of any real-world counterexamples.
+    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/types.h>]],
+      [[typedef int array[2 * (sizeof (mode_t) < sizeof (int)) - 1];]])],
+      [gl_cv_promoted_mode_t='int'],
+      [gl_cv_promoted_mode_t='mode_t'])
+  ])
+  AC_DEFINE_UNQUOTED([PROMOTED_MODE_T], [$gl_cv_promoted_mode_t],
+    [Define to the type that is the result of default argument promotions of type mode_t.])
+])
diff --git a/libmissing/m4/open.m4 b/libmissing/m4/open.m4
new file mode 100644
index 0000000..d705b3a
--- /dev/null
+++ b/libmissing/m4/open.m4
@@ -0,0 +1,74 @@
+# open.m4 serial 8
+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_OPEN],
+[
+  AC_REQUIRE([AC_CANONICAL_HOST])
+  case "$host_os" in
+    mingw* | pw*)
+      gl_REPLACE_OPEN
+      ;;
+    *)
+      dnl open("foo/") should not create a file when the file name has a
+      dnl trailing slash.  FreeBSD only has the problem on symlinks.
+      AC_CHECK_FUNCS_ONCE([lstat])
+      AC_CACHE_CHECK([whether open recognizes a trailing slash],
+        [gl_cv_func_open_slash],
+        [# Assume that if we have lstat, we can also check symlinks.
+          if test $ac_cv_func_lstat = yes; then
+            touch conftest.tmp
+            ln -s conftest.tmp conftest.lnk
+          fi
+          AC_TRY_RUN([
+#include <fcntl.h>
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+int main ()
+{
+#if HAVE_LSTAT
+  if (open ("conftest.lnk/", O_RDONLY) != -1) return 2;
+#endif
+  return open ("conftest.sl/", O_CREAT, 0600) >= 0;
+}], [gl_cv_func_open_slash=yes], [gl_cv_func_open_slash=no],
+            [
+changequote(,)dnl
+             case "$host_os" in
+               freebsd*)        gl_cv_func_open_slash="guessing no" ;;
+               solaris2.[0-9]*) gl_cv_func_open_slash="guessing no" ;;
+               hpux*)           gl_cv_func_open_slash="guessing no" ;;
+               *)               gl_cv_func_open_slash="guessing yes" ;;
+             esac
+changequote([,])dnl
+            ])
+          rm -f conftest.sl conftest.tmp conftest.lnk
+        ])
+      case "$gl_cv_func_open_slash" in
+        *no)
+          AC_DEFINE([OPEN_TRAILING_SLASH_BUG], [1],
+            [Define to 1 if open() fails to recognize a trailing slash.])
+          gl_REPLACE_OPEN
+          ;;
+      esac
+      ;;
+  esac
+])
+
+AC_DEFUN([gl_REPLACE_OPEN],
+[
+  AC_REQUIRE([gl_FCNTL_H_DEFAULTS])
+  REPLACE_OPEN=1
+  AC_LIBOBJ([open])
+  gl_PREREQ_OPEN
+])
+
+# Prerequisites of lib/open.c.
+AC_DEFUN([gl_PREREQ_OPEN],
+[
+  AC_REQUIRE([AC_C_INLINE])
+  AC_REQUIRE([gl_PROMOTED_TYPE_MODE_T])
+  :
+])
diff --git a/libmissing/m4/stat.m4 b/libmissing/m4/stat.m4
new file mode 100644
index 0000000..acd32d8
--- /dev/null
+++ b/libmissing/m4/stat.m4
@@ -0,0 +1,63 @@
+# serial 4
+
+# Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_FUNC_STAT],
+[
+  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+  AC_REQUIRE([gl_AC_DOS])
+  AC_REQUIRE([gl_SYS_STAT_H_DEFAULTS])
+  AC_CHECK_FUNCS_ONCE([lstat])
+  dnl mingw is the only known platform where stat(".") and stat("./") differ
+  AC_CACHE_CHECK([whether stat handles trailing slashes on directories],
+      [gl_cv_func_stat_dir_slash],
+      [AC_RUN_IFELSE(
+         [AC_LANG_PROGRAM(
+           [[#include <sys/stat.h>
+]], [[struct stat st; return stat (".", &st) != stat ("./", &st);]])],
+         [gl_cv_func_stat_dir_slash=yes], [gl_cv_func_stat_dir_slash=no],
+         [case $host_os in
+            mingw*) gl_cv_func_stat_dir_slash="guessing no";;
+            *) gl_cv_func_stat_dir_slash="guessing yes";;
+          esac])])
+  dnl Solaris 9 mistakenly succeeds on stat("file/")
+  dnl FreeBSD 7.2 mistakenly succeeds on stat("link-to-file/")
+  AC_CACHE_CHECK([whether stat handles trailing slashes on files],
+      [gl_cv_func_stat_file_slash],
+      [touch conftest.tmp
+       # Assume that if we have lstat, we can also check symlinks.
+       if test $ac_cv_func_lstat = yes; then
+         ln -s conftest.tmp conftest.lnk
+       fi
+       AC_RUN_IFELSE(
+         [AC_LANG_PROGRAM(
+           [[#include <sys/stat.h>
+]], [[struct stat st;
+      if (!stat ("conftest.tmp/", &st)) return 1;
+#if HAVE_LSTAT
+      if (!stat ("conftest.lnk/", &st)) return 2;
+#endif
+           ]])],
+         [gl_cv_func_stat_file_slash=yes], [gl_cv_func_stat_file_slash=no],
+         [gl_cv_func_stat_file_slash="guessing no"])
+       rm -f conftest.tmp conftest.lnk])
+  case $gl_cv_func_stat_dir_slash in
+    *no) REPLACE_STAT=1
+      AC_DEFINE([REPLACE_FUNC_STAT_DIR], [1], [Define to 1 if stat needs
+        help when passed a directory name with a trailing slash]);;
+  esac
+  case $gl_cv_func_stat_file_slash in
+    *no) REPLACE_STAT=1
+      AC_DEFINE([REPLACE_FUNC_STAT_FILE], [1], [Define to 1 if stat needs
+        help when passed a file name with a trailing slash]);;
+  esac
+  if test $REPLACE_STAT = 1; then
+    AC_LIBOBJ([stat])
+    dnl Prerequisites of lib/stat.c.
+    AC_REQUIRE([AC_C_INLINE])
+  fi
+])
diff --git a/libmissing/m4/stddef_h.m4 b/libmissing/m4/stddef_h.m4
new file mode 100644
index 0000000..c8572de
--- /dev/null
+++ b/libmissing/m4/stddef_h.m4
@@ -0,0 +1,45 @@
+dnl A placeholder for POSIX 2008 <stddef.h>, for platforms that have issues.
+# stddef_h.m4 serial 1
+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([gl_STDDEF_H],
+[
+  AC_REQUIRE([gl_STDDEF_H_DEFAULTS])
+  AC_REQUIRE([gt_TYPE_WCHAR_T])
+  if test $gt_cv_c_wchar_t = no; then
+    HAVE_WCHAR_T=0
+    STDDEF_H=stddef.h
+  fi
+  AC_CACHE_CHECK([whether NULL can be used in arbitrary expressions],
+    [gl_cv_decl_null_works],
+    [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <stddef.h>
+      int test[2 * (sizeof NULL == sizeof (void *)) -1];
+]])],
+      [gl_cv_decl_null_works=yes],
+      [gl_cv_decl_null_works=no])])
+  if test $gl_cv_decl_null_works = no; then
+    REPLACE_NULL=1
+    STDDEF_H=stddef.h
+  fi
+  if test -n "$STDDEF_H"; then
+    gl_CHECK_NEXT_HEADERS([stddef.h])
+  fi
+])
+
+AC_DEFUN([gl_STDDEF_MODULE_INDICATOR],
+[
+  dnl Use AC_REQUIRE here, so that the default settings are expanded once only.
+  AC_REQUIRE([gl_STDDEF_H_DEFAULTS])
+  GNULIB_[]m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./-],[ABCDEFGHIJKLMNOPQRSTUVWXYZ___])=1
+])
+
+AC_DEFUN([gl_STDDEF_H_DEFAULTS],
+[
+  dnl Assume proper GNU behavior unless another module says otherwise.
+  REPLACE_NULL=0;                AC_SUBST([REPLACE_NULL])
+  HAVE_WCHAR_T=1;                AC_SUBST([HAVE_WCHAR_T])
+  STDDEF_H='';                   AC_SUBST([STDDEF_H])
+])
diff --git a/libmissing/m4/stdio_h.m4 b/libmissing/m4/stdio_h.m4
index 20af579..781fa8d 100644
--- a/libmissing/m4/stdio_h.m4
+++ b/libmissing/m4/stdio_h.m4
@@ -1,4 +1,4 @@
-# stdio_h.m4 serial 24
+# stdio_h.m4 serial 25
 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,
@@ -111,6 +111,7 @@ AC_DEFUN([gl_STDIO_H_DEFAULTS],
   REPLACE_FSEEKO=0;              AC_SUBST([REPLACE_FSEEKO])
   REPLACE_FTELL=0;               AC_SUBST([REPLACE_FTELL])
   REPLACE_FTELLO=0;              AC_SUBST([REPLACE_FTELLO])
+  REPLACE_GETDELIM=0;            AC_SUBST([REPLACE_GETDELIM])
   REPLACE_GETLINE=0;             AC_SUBST([REPLACE_GETLINE])
   REPLACE_OBSTACK_PRINTF=0;      AC_SUBST([REPLACE_OBSTACK_PRINTF])
   REPLACE_PERROR=0;              AC_SUBST([REPLACE_PERROR])
diff --git a/libmissing/m4/symlink.m4 b/libmissing/m4/symlink.m4
new file mode 100644
index 0000000..3d14e69
--- /dev/null
+++ b/libmissing/m4/symlink.m4
@@ -0,0 +1,38 @@
+# serial 2
+# See if we need to provide symlink replacement.
+
+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.
+
+# Written by Eric Blake.
+
+AC_DEFUN([gl_FUNC_SYMLINK],
+[
+  AC_REQUIRE([gl_UNISTD_H_DEFAULTS])
+  AC_CHECK_FUNCS_ONCE([symlink])
+  dnl The best we can do on mingw is provide a dummy that always fails, so
+  dnl that compilation can proceed with fewer ifdefs.  On Solaris 9 and
+  dnl FreeBSD 7.2, we want to fix a bug with trailing slash handling.
+  if test $ac_cv_func_symlink = no; then
+    HAVE_SYMLINK=0
+    AC_LIBOBJ([symlink])
+  else
+    AC_CACHE_CHECK([whether symlink handles trailing slash correctly],
+      [gl_cv_func_symlink_works],
+      [AC_RUN_IFELSE(
+         [AC_LANG_PROGRAM(
+           [[#include <unistd.h>
+]], [[if (!symlink ("a", "conftest.link/")) return 1;
+      if (symlink ("conftest.f", "conftest.lnk2")) return 2;
+      if (!symlink ("a", "conftest.lnk2/")) return 3;]])],
+         [gl_cv_func_symlink_works=yes], [gl_cv_func_symlink_works=no],
+         [gl_cv_func_symlink_works="guessing no"])
+      rm -f conftest.f conftest.link conftest.lnk2])
+    if test "$gl_cv_func_symlink_works" != yes; then
+      REPLACE_SYMLINK=1
+      AC_LIBOBJ([symlink])
+    fi
+  fi
+])
diff --git a/libmissing/m4/sys_stat_h.m4 b/libmissing/m4/sys_stat_h.m4
new file mode 100644
index 0000000..5a113d0
--- /dev/null
+++ b/libmissing/m4/sys_stat_h.m4
@@ -0,0 +1,80 @@
+# sys_stat_h.m4 serial 22   -*- Autoconf -*-
+dnl Copyright (C) 2006-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.
+
+dnl From Eric Blake.
+dnl Provide a GNU-like <sys/stat.h>.
+
+AC_DEFUN([gl_HEADER_SYS_STAT_H],
+[
+  AC_REQUIRE([gl_SYS_STAT_H_DEFAULTS])
+
+  dnl For the mkdir substitute.
+  AC_REQUIRE([AC_C_INLINE])
+
+  dnl Check for broken stat macros.
+  AC_REQUIRE([AC_HEADER_STAT])
+
+  gl_CHECK_NEXT_HEADERS([sys/stat.h])
+
+  dnl Define types that are supposed to be defined in <sys/types.h> or
+  dnl <sys/stat.h>.
+  AC_CHECK_TYPE([nlink_t], [],
+    [AC_DEFINE([nlink_t], [int],
+       [Define to the type of st_nlink in struct stat, or a supertype.])],
+    [#include <sys/types.h>
+     #include <sys/stat.h>])
+
+  dnl Check for declarations of anything we want to poison if the
+  dnl corresponding gnulib module is not in use.
+  gl_WARN_ON_USE_PREPARE([[#include <sys/stat.h>
+    ]], [fchmodat fstatat futimens lchmod lstat mkdirat mkfifo mkfifoat
+    mknod mknodat stat utimensat])
+]) # gl_HEADER_SYS_STAT_H
+
+AC_DEFUN([gl_SYS_STAT_MODULE_INDICATOR],
+[
+  dnl Use AC_REQUIRE here, so that the default settings are expanded once only.
+  AC_REQUIRE([gl_SYS_STAT_H_DEFAULTS])
+  GNULIB_[]m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./-],[ABCDEFGHIJKLMNOPQRSTUVWXYZ___])=1
+])
+
+AC_DEFUN([gl_SYS_STAT_H_DEFAULTS],
+[
+  AC_REQUIRE([gl_UNISTD_H_DEFAULTS]) dnl for REPLACE_FCHDIR
+  GNULIB_FCHMODAT=0;    AC_SUBST([GNULIB_FCHMODAT])
+  GNULIB_FSTATAT=0;     AC_SUBST([GNULIB_FSTATAT])
+  GNULIB_FUTIMENS=0;    AC_SUBST([GNULIB_FUTIMENS])
+  GNULIB_LCHMOD=0;      AC_SUBST([GNULIB_LCHMOD])
+  GNULIB_LSTAT=0;       AC_SUBST([GNULIB_LSTAT])
+  GNULIB_MKDIRAT=0;     AC_SUBST([GNULIB_MKDIRAT])
+  GNULIB_MKFIFO=0;      AC_SUBST([GNULIB_MKFIFO])
+  GNULIB_MKFIFOAT=0;    AC_SUBST([GNULIB_MKFIFOAT])
+  GNULIB_MKNOD=0;       AC_SUBST([GNULIB_MKNOD])
+  GNULIB_MKNODAT=0;     AC_SUBST([GNULIB_MKNODAT])
+  GNULIB_STAT=0;        AC_SUBST([GNULIB_STAT])
+  GNULIB_UTIMENSAT=0;   AC_SUBST([GNULIB_UTIMENSAT])
+  dnl Assume proper GNU behavior unless another module says otherwise.
+  HAVE_FCHMODAT=1;      AC_SUBST([HAVE_FCHMODAT])
+  HAVE_FSTATAT=1;       AC_SUBST([HAVE_FSTATAT])
+  HAVE_FUTIMENS=1;      AC_SUBST([HAVE_FUTIMENS])
+  HAVE_LCHMOD=1;        AC_SUBST([HAVE_LCHMOD])
+  HAVE_LSTAT=1;         AC_SUBST([HAVE_LSTAT])
+  HAVE_MKDIRAT=1;       AC_SUBST([HAVE_MKDIRAT])
+  HAVE_MKFIFO=1;        AC_SUBST([HAVE_MKFIFO])
+  HAVE_MKFIFOAT=1;      AC_SUBST([HAVE_MKFIFOAT])
+  HAVE_MKNOD=1;         AC_SUBST([HAVE_MKNOD])
+  HAVE_MKNODAT=1;       AC_SUBST([HAVE_MKNODAT])
+  HAVE_UTIMENSAT=1;     AC_SUBST([HAVE_UTIMENSAT])
+  REPLACE_FSTAT=0;      AC_SUBST([REPLACE_FSTAT])
+  REPLACE_FSTATAT=0;    AC_SUBST([REPLACE_FSTATAT])
+  REPLACE_FUTIMENS=0;   AC_SUBST([REPLACE_FUTIMENS])
+  REPLACE_LSTAT=0;      AC_SUBST([REPLACE_LSTAT])
+  REPLACE_MKDIR=0;      AC_SUBST([REPLACE_MKDIR])
+  REPLACE_MKFIFO=0;     AC_SUBST([REPLACE_MKFIFO])
+  REPLACE_MKNOD=0;      AC_SUBST([REPLACE_MKNOD])
+  REPLACE_STAT=0;       AC_SUBST([REPLACE_STAT])
+  REPLACE_UTIMENSAT=0;  AC_SUBST([REPLACE_UTIMENSAT])
+])
diff --git a/libmissing/m4/sys_time_h.m4 b/libmissing/m4/sys_time_h.m4
index 9c16487..be6d7ec 100644
--- a/libmissing/m4/sys_time_h.m4
+++ b/libmissing/m4/sys_time_h.m4
@@ -1,5 +1,5 @@
 # Configure a replacement for <sys/time.h>.
-# serial 2
+# serial 4
 
 # Copyright (C) 2007, 2009, 2010 Free Software Foundation, Inc.
 # This file is free software; the Free Software Foundation
@@ -19,15 +19,13 @@ AC_DEFUN([gl_HEADER_SYS_TIME_H],
 AC_DEFUN([gl_HEADER_SYS_TIME_H_BODY],
 [
   AC_REQUIRE([AC_C_RESTRICT])
+  AC_REQUIRE([gl_HEADER_SYS_TIME_H_DEFAULTS])
   AC_CHECK_HEADERS_ONCE([sys/time.h])
   gl_CHECK_NEXT_HEADERS([sys/time.h])
 
-  if test $ac_cv_header_sys_time_h = yes; then
-    HAVE_SYS_TIME_H=1
-  else
+  if test $ac_cv_header_sys_time_h != yes; then
     HAVE_SYS_TIME_H=0
   fi
-  AC_SUBST([HAVE_SYS_TIME_H])
 
   AC_CACHE_CHECK([for struct timeval], [gl_cv_sys_struct_timeval],
     [AC_COMPILE_IFELSE(
@@ -40,20 +38,33 @@ AC_DEFUN([gl_HEADER_SYS_TIME_H_BODY],
           [[static struct timeval x; x.tv_sec = x.tv_usec;]])],
        [gl_cv_sys_struct_timeval=yes],
        [gl_cv_sys_struct_timeval=no])])
-  if test $gl_cv_sys_struct_timeval = yes; then
-    HAVE_STRUCT_TIMEVAL=1
-  else
+  if test $gl_cv_sys_struct_timeval != yes; then
     HAVE_STRUCT_TIMEVAL=0
   fi
-  AC_SUBST([HAVE_STRUCT_TIMEVAL])
 
+  dnl Check for declarations of anything we want to poison if the
+  dnl corresponding gnulib module is not in use.
+  gl_WARN_ON_USE_PREPARE([[
+#if HAVE_SYS_TIME_H
+# include <sys/time.h>
+#endif
+#include <time.h>
+    ]], [gettimeofday])
+])
+
+AC_DEFUN([gl_SYS_TIME_MODULE_INDICATOR],
+[
+  dnl Use AC_REQUIRE here, so that the default settings are expanded once only.
+  AC_REQUIRE([gl_HEADER_SYS_TIME_H_DEFAULTS])
+  GNULIB_[]m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./-],[ABCDEFGHIJKLMNOPQRSTUVWXYZ___])=1
+])
+
+AC_DEFUN([gl_HEADER_SYS_TIME_H_DEFAULTS],
+[
+  GNULIB_GETTIMEOFDAY=0;     AC_SUBST([GNULIB_GETTIMEOFDAY])
   dnl Assume POSIX behavior unless another module says otherwise.
-  REPLACE_GETTIMEOFDAY=0
-  AC_SUBST([REPLACE_GETTIMEOFDAY])
-  if test $HAVE_SYS_TIME_H = 0 || test $HAVE_STRUCT_TIMEVAL = 0; then
-    SYS_TIME_H=sys/time.h
-  else
-    SYS_TIME_H=
-  fi
-  AC_SUBST([SYS_TIME_H])
+  HAVE_GETTIMEOFDAY=1;       AC_SUBST([HAVE_GETTIMEOFDAY])
+  HAVE_STRUCT_TIMEVAL=1;     AC_SUBST([HAVE_STRUCT_TIMEVAL])
+  HAVE_SYS_TIME_H=1;         AC_SUBST([HAVE_SYS_TIME_H])
+  REPLACE_GETTIMEOFDAY=0;    AC_SUBST([REPLACE_GETTIMEOFDAY])
 ])
diff --git a/libmissing/m4/warn-on-use.m4 b/libmissing/m4/warn-on-use.m4
new file mode 100644
index 0000000..42daae8
--- /dev/null
+++ b/libmissing/m4/warn-on-use.m4
@@ -0,0 +1,45 @@
+# warn-on-use.m4 serial 2
+dnl Copyright (C) 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.
+
+# gl_WARN_ON_USE_PREPARE(INCLUDES, NAMES)
+# ---------------------------------------
+# For each whitespace-separated element in the list of NAMES, define
+# HAVE_RAW_DECL_name if the function has a declaration among INCLUDES
+# even after being undefined as a macro.
+#
+# See warn-on-use.h for some hints on how to poison function names, as
+# well as ideas on poisoning global variables and macros.  NAMES may
+# include global variables, but remember that only functions work with
+# _GL_WARN_ON_USE.  Typically, INCLUDES only needs to list a single
+# header, but if the replacement header pulls in other headers because
+# some systems declare functions in the wrong header, then INCLUDES
+# should do likewise.
+#
+# If you assume C89, then it is generally safe to assume declarations
+# for functions declared in that standard (such as gets) without
+# needing gl_WARN_ON_USE_PREPARE.
+AC_DEFUN([gl_WARN_ON_USE_PREPARE],
+[
+  m4_foreach_w([gl_decl], [$2],
+    [AH_TEMPLATE([HAVE_RAW_DECL_]AS_TR_CPP(m4_defn([gl_decl])),
+      [Define to 1 if ]m4_defn([gl_decl])[ is declared even after
+       undefining macros.])])dnl
+  for gl_func in m4_flatten([$2]); do
+    AS_VAR_PUSHDEF([gl_Symbol], [gl_cv_have_raw_decl_$gl_func])dnl
+    AC_CACHE_CHECK([whether $gl_func is declared without a macro],
+      gl_Symbol,
+      [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([$1],
+[@%:@undef $gl_func
+  (void) $gl_func;])],
+        [AS_VAR_SET(gl_Symbol, [yes])], [AS_VAR_SET(gl_Symbol, [no])])])
+     AS_VAR_IF(gl_Symbol, [yes],
+       [AC_DEFINE_UNQUOTED(AS_TR_CPP([HAVE_RAW_DECL_$gl_func]), [1])
+       dnl shortcut - if the raw declaration exists, then set a cache
+       dnl variable to allow skipping any later AC_CHECK_DECL efforts
+       eval ac_cv_have_decl_$gl_func=yes])
+    AS_VAR_POPDEF([gl_Symbol])dnl
+  done
+])
diff --git a/libmissing/netdb.in.h b/libmissing/netdb.in.h
index 981a432..8fa6164 100644
--- a/libmissing/netdb.in.h
+++ b/libmissing/netdb.in.h
@@ -74,18 +74,24 @@ struct addrinfo
 # endif
 
 # if 0
-/* The commented out definitions below are not yet implemented in the
-   GNULIB getaddrinfo() replacement, so are not yet needed and may, in fact,
-   cause conflicts on systems with a getaddrinfo() function which does not
-   define them.
-
-   If they are restored, be sure to protect the definitions with #ifndef.  */
 #  define AI_NUMERICHOST        0x0004  /* Don't use name resolution.  */
-#  define AI_V4MAPPED   0x0008  /* IPv4 mapped addresses are acceptable.  */
-#  define AI_ALL                0x0010  /* Return IPv4 mapped and IPv6 addresses.  */
-#  define AI_ADDRCONFIG 0x0020  /* Use configuration of this host to choose
-                                   returned address type..  */
-# endif /* 0 */
+# endif
+
+/* These symbolic constants are required to be present by POSIX, but
+   our getaddrinfo replacement doesn't use them (yet).  Setting them
+   to 0 on systems that doesn't have them avoids causing problems for
+   system getaddrinfo implementations that would be confused by
+   unknown values.  */
+# ifndef AI_V4MAPPED
+#  define AI_V4MAPPED    0 /* 0x0008: IPv4 mapped addresses are acceptable.  */
+# endif
+# ifndef AI_ALL
+#  define AI_ALL         0 /* 0x0010: Return IPv4 mapped and IPv6 addresses. */
+# endif
+# ifndef AI_ADDRCONFIG
+#  define AI_ADDRCONFIG  0 /* 0x0020: Use configuration of this host to choose
+                                      returned address type.  */
+# endif
 
 /* Error values for `getaddrinfo' function.  */
 # ifndef EAI_BADFLAGS
diff --git a/libmissing/stat.c b/libmissing/stat.c
new file mode 100644
index 0000000..60fe127
--- /dev/null
+++ b/libmissing/stat.c
@@ -0,0 +1,104 @@
+/* Work around platform bugs in stat.
+   Copyright (C) 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/>.  */
+
+/* written by Eric Blake */
+
+#include <config.h>
+
+/* Get the original definition of stat.  It might be defined as a macro.  */
+#define __need_system_sys_stat_h
+#include <sys/types.h>
+#include <sys/stat.h>
+#undef __need_system_sys_stat_h
+
+static inline int
+orig_stat (const char *filename, struct stat *buf)
+{
+  return stat (filename, buf);
+}
+
+/* Specification.  */
+#include <sys/stat.h>
+
+#include <errno.h>
+#include <limits.h>
+#include <stdbool.h>
+#include <string.h>
+
+/* Store information about NAME into ST.  Work around bugs with
+   trailing slashes.  Mingw has other bugs (such as st_ino always
+   being 0 on success) which this wrapper does not work around.  But
+   at least this implementation provides the ability to emulate fchdir
+   correctly.  */
+
+int
+rpl_stat (char const *name, struct stat *st)
+{
+  int result = orig_stat (name, st);
+#if REPLACE_FUNC_STAT_FILE
+  /* Solaris 9 mistakenly succeeds when given a non-directory with a
+     trailing slash.  */
+  if (result == 0 && !S_ISDIR (st->st_mode))
+    {
+      size_t len = strlen (name);
+      if (ISSLASH (name[len - 1]))
+        {
+          errno = ENOTDIR;
+          return -1;
+        }
+    }
+#endif /* REPLACE_FUNC_STAT_FILE */
+#if REPLACE_FUNC_STAT_DIR
+  if (result == -1 && errno == ENOENT)
+    {
+      /* Due to mingw's oddities, there are some directories (like
+         c:\) where stat() only succeeds with a trailing slash, and
+         other directories (like c:\windows) where stat() only
+         succeeds without a trailing slash.  But we want the two to be
+         synonymous, since chdir() manages either style.  Likewise, Mingw also
+         reports ENOENT for names longer than PATH_MAX, when we want
+         ENAMETOOLONG, and for stat("file/"), when we want ENOTDIR.
+         Fortunately, mingw PATH_MAX is small enough for stack
+         allocation.  */
+      char fixed_name[PATH_MAX + 1] = {0};
+      size_t len = strlen (name);
+      bool check_dir = false;
+      if (PATH_MAX <= len)
+        errno = ENAMETOOLONG;
+      else if (len)
+        {
+          strcpy (fixed_name, name);
+          if (ISSLASH (fixed_name[len - 1]))
+            {
+              check_dir = true;
+              while (len && ISSLASH (fixed_name[len - 1]))
+                fixed_name[--len] = '\0';
+              if (!len)
+                fixed_name[0] = '/';
+            }
+          else
+            fixed_name[len++] = '/';
+          result = orig_stat (fixed_name, st);
+          if (result == 0 && check_dir && !S_ISDIR (st->st_mode))
+            {
+              result = -1;
+              errno = ENOTDIR;
+            }
+        }
+    }
+#endif /* REPLACE_FUNC_STAT_DIR */
+  return result;
+}
diff --git a/libmissing/stddef.in.h b/libmissing/stddef.in.h
new file mode 100644
index 0000000..b1dfb67
--- /dev/null
+++ b/libmissing/stddef.in.h
@@ -0,0 +1,86 @@
+/* A substitute for POSIX 2008 <stddef.h>, for platforms that have issues.
+
+   Copyright (C) 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.  */
+
+/* Written by Eric Blake.  */
+
+/*
+ * POSIX 2008 <stddef.h> for platforms that have issues.
+ * <http://www.opengroup.org/susv3xbd/stddef.h.html>
+ */
+
+#if __GNUC__ >= 3
+@PRAGMA_SYSTEM_HEADER@
+#endif
+
+#if defined __need_wchar_t || defined __need_size_t  \
+  || defined __need_ptrdiff_t || defined __need_NULL \
+  || defined __need_wint_t
+/* Special invocation convention inside gcc header files.  In
+   particular, gcc provides a version of <stddef.h> that blindly
+   redefines NULL even when __need_wint_t was defined, even though
+   wint_t is not normally provided by <stddef.h>.  Hence, we must
+   remember if special invocation has ever been used to obtain wint_t,
+   in which case we need to clean up NULL yet again.  */
+
+# if !(defined _GL_STDDEF_H && defined _GL_STDDEF_WINT_T)
+#  ifdef __need_wint_t
+#   undef _GL_STDDEF_H
+#   define _GL_STDDEF_WINT_T
+#  endif
+#  @INCLUDE_NEXT@ @NEXT_STDDEF_H@
+# endif
+
+#else
+/* Normal invocation convention.  */
+
+# ifndef _GL_STDDEF_H
+
+/* The include_next requires a split double-inclusion guard.  */
+
+#  @INCLUDE_NEXT@ @NEXT_STDDEF_H@
+
+#  ifndef _GL_STDDEF_H
+#   define _GL_STDDEF_H
+
+/* On NetBSD 5.0, the definition of NULL lacks proper parentheses.  */
+#if @REPLACE_NULL@
+# undef NULL
+# ifdef __cplusplus
+   /* ISO C++ says that the macro NULL must expand to an integer constant
+      expression, hence '((void *) 0)' is not allowed in C++.  */
+#  if __GNUG__ >= 3
+    /* GNU C++ has a __null macro that behaves like an integer ('int' or
+       'long') but has the same size as a pointer.  Use that, to avoid
+       warnings.  */
+#   define NULL __null
+#  else
+#   define NULL 0L
+#  endif
+# else
+#  define NULL ((void *) 0)
+# endif
+#endif
+
+/* Some platforms lack wchar_t.  */
+#if !@HAVE_WCHAR_T@
+# define wchar_t int
+#endif
+
+#  endif /* _GL_STDDEF_H */
+# endif /* _GL_STDDEF_H */
+#endif /* __need_XXX */
diff --git a/libmissing/stdio.in.h b/libmissing/stdio.in.h
index 5454245..cfec2d6 100644
--- a/libmissing/stdio.in.h
+++ b/libmissing/stdio.in.h
@@ -133,20 +133,20 @@ _GL_WARN_ON_USE (fopen, "fopen on Win32 platforms is not POSIX compatible - "
                  "use gnulib module fopen for portability");
 #endif
 
-#if @GNULIB_FPRINTF_POSIX@
-# if @REPLACE_FPRINTF@
+#if @GNULIB_FPRINTF_POSIX@ || @GNULIB_FPRINTF@
+# if (@GNULIB_FPRINTF_POSIX@ && @REPLACE_FPRINTF@) \
+     || (@GNULIB_FPRINTF@ && @REPLACE_STDIO_WRITE_FUNCS@ && @GNULIB_STDIO_H_SIGPIPE@)
 #  define fprintf rpl_fprintf
+#  define GNULIB_overrides_fprintf 1
 extern int fprintf (FILE *fp, const char *format, ...)
        __attribute__ ((__format__ (__printf__, 2, 3)))
        _GL_ARG_NONNULL ((1, 2));
 # endif
-#elif @GNULIB_FPRINTF@ && @REPLACE_STDIO_WRITE_FUNCS@ && @GNULIB_STDIO_H_SIGPIPE@
-# define fprintf rpl_fprintf
-extern int fprintf (FILE *fp, const char *format, ...)
-       __attribute__ ((__format__ (__printf__, 2, 3)))
-       _GL_ARG_NONNULL ((1, 2));
-#elif defined GNULIB_POSIXCHECK
-# undef fprintf
+#endif
+#if !@GNULIB_FPRINTF_POSIX@ && defined GNULIB_POSIXCHECK
+# if !GNULIB_overrides_fprintf
+#  undef fprintf
+# endif
 /* Assume fprintf is always declared.  */
 _GL_WARN_ON_USE (fprintf, "fprintf is not always POSIX compliant - "
                  "use gnulib module fprintf-posix for portable "
@@ -200,6 +200,7 @@ _GL_WARN_ON_USE (freopen, "freopen on Win32 platforms is not POSIX compatible -
                  "use gnulib module freopen for portability");
 #endif
 
+
 /* Set up the following warnings, based on which modules are in use.
    GNU Coding Standards discourage the use of fseek, since it imposes
    an arbitrary limitation on some 32-bit hosts.  Remember that the
@@ -226,7 +227,7 @@ _GL_WARN_ON_USE (freopen, "freopen on Win32 platforms is not POSIX compatible -
    defined to silence the warning in particular compilation units.
 
    Most gnulib clients that perform stream operations should fall into
-   category three.  */
+   category 3.  */
 
 #if @GNULIB_FSEEK@
 # if defined GNULIB_POSIXCHECK && !defined _GL_NO_LARGE_FILES
@@ -280,7 +281,8 @@ _GL_WARN_ON_USE (fseek, "fseek cannot handle files larger than 4 GB "
                  "use fseeko function for handling of large files");
 #endif
 
-/* See the comments on fseek/fseeko.  */
+
+/* ftell, ftello.  See the comments on fseek/fseeko.  */
 
 #if @GNULIB_FTELL@
 # if defined GNULIB_POSIXCHECK && !defined _GL_NO_LARGE_FILES
@@ -332,6 +334,7 @@ _GL_WARN_ON_USE (ftell, "ftell cannot handle files larger than 4 GB "
                  "use ftello function for handling of large files");
 #endif
 
+
 #if @GNULIB_FWRITE@ && @REPLACE_STDIO_WRITE_FUNCS@ && @GNULIB_STDIO_H_SIGPIPE@
 # undef fwrite
 # define fwrite rpl_fwrite
@@ -340,7 +343,11 @@ extern size_t fwrite (const void *ptr, size_t s, size_t n, FILE *stream)
 #endif
 
 #if @GNULIB_GETDELIM@
-# if !@HAVE_DECL_GETDELIM@
+# if @REPLACE_GETDELIM@
+#  undef getdelim
+#  define getdelim rpl_getdelim
+# endif
+# if !@HAVE_DECL_GETDELIM@ || @REPLACE_GETDELIM@
 /* Read input, up to (and including) the next occurrence of DELIMITER, from
    STREAM, store it in *LINEPTR (and NUL-terminate it).
    *LINEPTR is a pointer returned from malloc (or NULL), pointing to *LINESIZE
@@ -382,9 +389,9 @@ _GL_WARN_ON_USE (getline, "getline is unportable - "
 # endif
 #endif
 
-#if @GNULIB_OBSTACK_PRINTF@
+#if @GNULIB_OBSTACK_PRINTF@ || @GNULIB_OBSTACK_PRINTF_POSIX@
 # if @REPLACE_OBSTACK_PRINTF@
-#  define obstack_printf rpl_osbtack_printf
+#  define obstack_printf rpl_obstack_printf
 #  define obstack_vprintf rpl_obstack_vprintf
 # endif
 # if @REPLACE_OBSTACK_PRINTF@ || !@HAVE_DECL_OBSTACK_PRINTF@
@@ -432,20 +439,20 @@ _GL_WARN_ON_USE (popen, "popen is buggy on some platforms - "
 # endif
 #endif
 
-#if @GNULIB_PRINTF_POSIX@
-# if @REPLACE_PRINTF@
+#if @GNULIB_PRINTF_POSIX@ || @GNULIB_PRINTF@
+# if (@GNULIB_PRINTF_POSIX@ && @REPLACE_PRINTF@) \
+     || (@GNULIB_PRINTF@ && @REPLACE_STDIO_WRITE_FUNCS@ && @GNULIB_STDIO_H_SIGPIPE@)
 /* Don't break __attribute__((format(printf,M,N))).  */
 #  define printf __printf__
+#  define GNULIB_overrides_printf 1
 extern int printf (const char *format, ...)
        __attribute__ ((__format__ (__printf__, 1, 2))) _GL_ARG_NONNULL ((1));
 # endif
-#elif @GNULIB_PRINTF@ && @REPLACE_STDIO_WRITE_FUNCS@ && @GNULIB_STDIO_H_SIGPIPE@
-/* Don't break __attribute__((format(printf,M,N))).  */
-# define printf __printf__
-extern int printf (const char *format, ...)
-       __attribute__ ((__format__ (__printf__, 1, 2))) _GL_ARG_NONNULL ((1));
-#elif defined GNULIB_POSIXCHECK
-# undef printf
+#endif
+#if !@GNULIB_PRINTF_POSIX@ && defined GNULIB_POSIXCHECK
+# if !GNULIB_overrides_printf
+#  undef printf
+# endif
 /* Assume printf is always declared.  */
 _GL_WARN_ON_USE (printf, "printf is not always POSIX compliant - "
                  "use gnulib module printf-posix for portable "
@@ -588,38 +595,39 @@ _GL_WARN_ON_USE (vdprintf, "vdprintf is unportable - "
 # endif
 #endif
 
-#if @GNULIB_VFPRINTF_POSIX@
-# if @REPLACE_VFPRINTF@
+#if @GNULIB_VFPRINTF_POSIX@ || @GNULIB_VFPRINTF@
+# if (@GNULIB_VFPRINTF_POSIX@ && @REPLACE_VFPRINTF@) \
+     || (@GNULIB_VFPRINTF@ && @REPLACE_STDIO_WRITE_FUNCS@ && @GNULIB_STDIO_H_SIGPIPE@)
 #  define vfprintf rpl_vfprintf
+#  define GNULIB_overrides_vfprintf 1
 extern int vfprintf (FILE *fp, const char *format, va_list args)
        __attribute__ ((__format__ (__printf__, 2, 0)))
        _GL_ARG_NONNULL ((1, 2));
 # endif
-#elif @GNULIB_VFPRINTF@ && @REPLACE_STDIO_WRITE_FUNCS@ && @GNULIB_STDIO_H_SIGPIPE@
-# define vfprintf rpl_vfprintf
-extern int vfprintf (FILE *fp, const char *format, va_list args)
-       __attribute__ ((__format__ (__printf__, 2, 0)))
-       _GL_ARG_NONNULL ((1, 2));
-#elif defined GNULIB_POSIXCHECK
-# undef vfprintf
+#endif
+#if !@GNULIB_VFPRINTF_POSIX@ && defined GNULIB_POSIXCHECK
+# if !GNULIB_overrides_vfprintf
+#  undef vfprintf
+# endif
 /* Assume vfprintf is always declared.  */
 _GL_WARN_ON_USE (vfprintf, "vfprintf is not always POSIX compliant - "
                  "use gnulib module vfprintf-posix for portable "
                       "POSIX compliance");
 #endif
 
-#if @GNULIB_VPRINTF_POSIX@
-# if @REPLACE_VPRINTF@
+#if @GNULIB_VPRINTF_POSIX@ || @GNULIB_VPRINTF@
+# if (@GNULIB_VPRINTF_POSIX@ && @REPLACE_VPRINTF@) \
+     || (@GNULIB_VPRINTF@ && @REPLACE_STDIO_WRITE_FUNCS@ && @GNULIB_STDIO_H_SIGPIPE@)
 #  define vprintf rpl_vprintf
+#  define GNULIB_overrides_vprintf 1
 extern int vprintf (const char *format, va_list args)
        __attribute__ ((__format__ (__printf__, 1, 0))) _GL_ARG_NONNULL ((1));
 # endif
-#elif @GNULIB_VPRINTF@ && @REPLACE_STDIO_WRITE_FUNCS@ && @GNULIB_STDIO_H_SIGPIPE@
-# define vprintf rpl_vprintf
-extern int vprintf (const char *format, va_list args)
-       __attribute__ ((__format__ (__printf__, 1, 0))) _GL_ARG_NONNULL ((1));
-#elif defined GNULIB_POSIXCHECK
-# undef vprintf
+#endif
+#if !@GNULIB_VPRINTF_POSIX@ && defined GNULIB_POSIXCHECK
+# if !GNULIB_overrides_vprintf
+#  undef vprintf
+# endif
 /* Assume vprintf is always declared.  */
 _GL_WARN_ON_USE (vprintf, "vprintf is not always POSIX compliant - "
                  "use gnulib module vprintf-posix for portable "
diff --git a/libmissing/sys_stat.in.h b/libmissing/sys_stat.in.h
new file mode 100644
index 0000000..ab5f161
--- /dev/null
+++ b/libmissing/sys_stat.in.h
@@ -0,0 +1,548 @@
+/* Provide a more complete sys/stat header file.
+   Copyright (C) 2005-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.  */
+
+/* Written by Eric Blake, Paul Eggert, and Jim Meyering.  */
+
+/* This file is supposed to be used on platforms where <sys/stat.h> is
+   incomplete.  It is intended to provide definitions and prototypes
+   needed by an application.  Start with what the system provides.  */
+
+#if __GNUC__ >= 3
+@PRAGMA_SYSTEM_HEADER@
+#endif
+
+#if defined __need_system_sys_stat_h
+/* Special invocation convention.  */
+
+#@INCLUDE_NEXT@ @NEXT_SYS_STAT_H@
+
+#else
+/* Normal invocation convention.  */
+
+#ifndef _GL_SYS_STAT_H
+
+/* Get nlink_t.  */
+#include <sys/types.h>
+
+/* Get struct timespec.  */
+#include <time.h>
+
+/* The include_next requires a split double-inclusion guard.  */
+#@INCLUDE_NEXT@ @NEXT_SYS_STAT_H@
+
+#ifndef _GL_SYS_STAT_H
+#define _GL_SYS_STAT_H
+
+/* The definition of _GL_ARG_NONNULL is copied here.  */
+
+/* The definition of _GL_WARN_ON_USE is copied here.  */
+
+/* Before doing "#define mkdir rpl_mkdir" below, we need to include all
+   headers that may declare mkdir().  */
+#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+# include <io.h>
+#endif
+
+#ifndef S_IFMT
+# define S_IFMT 0170000
+#endif
+
+#if STAT_MACROS_BROKEN
+# undef S_ISBLK
+# undef S_ISCHR
+# undef S_ISDIR
+# undef S_ISFIFO
+# undef S_ISLNK
+# undef S_ISNAM
+# undef S_ISMPB
+# undef S_ISMPC
+# undef S_ISNWK
+# undef S_ISREG
+# undef S_ISSOCK
+#endif
+
+#ifndef S_ISBLK
+# ifdef S_IFBLK
+#  define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
+# else
+#  define S_ISBLK(m) 0
+# endif
+#endif
+
+#ifndef S_ISCHR
+# ifdef S_IFCHR
+#  define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
+# else
+#  define S_ISCHR(m) 0
+# endif
+#endif
+
+#ifndef S_ISDIR
+# ifdef S_IFDIR
+#  define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
+# else
+#  define S_ISDIR(m) 0
+# endif
+#endif
+
+#ifndef S_ISDOOR /* Solaris 2.5 and up */
+# define S_ISDOOR(m) 0
+#endif
+
+#ifndef S_ISFIFO
+# ifdef S_IFIFO
+#  define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
+# else
+#  define S_ISFIFO(m) 0
+# endif
+#endif
+
+#ifndef S_ISLNK
+# ifdef S_IFLNK
+#  define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
+# else
+#  define S_ISLNK(m) 0
+# endif
+#endif
+
+#ifndef S_ISMPB /* V7 */
+# ifdef S_IFMPB
+#  define S_ISMPB(m) (((m) & S_IFMT) == S_IFMPB)
+#  define S_ISMPC(m) (((m) & S_IFMT) == S_IFMPC)
+# else
+#  define S_ISMPB(m) 0
+#  define S_ISMPC(m) 0
+# endif
+#endif
+
+#ifndef S_ISNAM /* Xenix */
+# ifdef S_IFNAM
+#  define S_ISNAM(m) (((m) & S_IFMT) == S_IFNAM)
+# else
+#  define S_ISNAM(m) 0
+# endif
+#endif
+
+#ifndef S_ISNWK /* HP/UX */
+# ifdef S_IFNWK
+#  define S_ISNWK(m) (((m) & S_IFMT) == S_IFNWK)
+# else
+#  define S_ISNWK(m) 0
+# endif
+#endif
+
+#ifndef S_ISPORT /* Solaris 10 and up */
+# define S_ISPORT(m) 0
+#endif
+
+#ifndef S_ISREG
+# ifdef S_IFREG
+#  define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
+# else
+#  define S_ISREG(m) 0
+# endif
+#endif
+
+#ifndef S_ISSOCK
+# ifdef S_IFSOCK
+#  define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
+# else
+#  define S_ISSOCK(m) 0
+# endif
+#endif
+
+
+#ifndef S_TYPEISMQ
+# define S_TYPEISMQ(p) 0
+#endif
+
+#ifndef S_TYPEISTMO
+# define S_TYPEISTMO(p) 0
+#endif
+
+
+#ifndef S_TYPEISSEM
+# ifdef S_INSEM
+#  define S_TYPEISSEM(p) (S_ISNAM ((p)->st_mode) && (p)->st_rdev == S_INSEM)
+# else
+#  define S_TYPEISSEM(p) 0
+# endif
+#endif
+
+#ifndef S_TYPEISSHM
+# ifdef S_INSHD
+#  define S_TYPEISSHM(p) (S_ISNAM ((p)->st_mode) && (p)->st_rdev == S_INSHD)
+# else
+#  define S_TYPEISSHM(p) 0
+# endif
+#endif
+
+/* high performance ("contiguous data") */
+#ifndef S_ISCTG
+# define S_ISCTG(p) 0
+#endif
+
+/* Cray DMF (data migration facility): off line, with data  */
+#ifndef S_ISOFD
+# define S_ISOFD(p) 0
+#endif
+
+/* Cray DMF (data migration facility): off line, with no data  */
+#ifndef S_ISOFL
+# define S_ISOFL(p) 0
+#endif
+
+/* 4.4BSD whiteout */
+#ifndef S_ISWHT
+# define S_ISWHT(m) 0
+#endif
+
+/* If any of the following are undefined,
+   define them to their de facto standard values.  */
+#if !S_ISUID
+# define S_ISUID 04000
+#endif
+#if !S_ISGID
+# define S_ISGID 02000
+#endif
+
+/* S_ISVTX is a common extension to POSIX.  */
+#ifndef S_ISVTX
+# define S_ISVTX 01000
+#endif
+
+#if !S_IRUSR && S_IREAD
+# define S_IRUSR S_IREAD
+#endif
+#if !S_IRUSR
+# define S_IRUSR 00400
+#endif
+#if !S_IRGRP
+# define S_IRGRP (S_IRUSR >> 3)
+#endif
+#if !S_IROTH
+# define S_IROTH (S_IRUSR >> 6)
+#endif
+
+#if !S_IWUSR && S_IWRITE
+# define S_IWUSR S_IWRITE
+#endif
+#if !S_IWUSR
+# define S_IWUSR 00200
+#endif
+#if !S_IWGRP
+# define S_IWGRP (S_IWUSR >> 3)
+#endif
+#if !S_IWOTH
+# define S_IWOTH (S_IWUSR >> 6)
+#endif
+
+#if !S_IXUSR && S_IEXEC
+# define S_IXUSR S_IEXEC
+#endif
+#if !S_IXUSR
+# define S_IXUSR 00100
+#endif
+#if !S_IXGRP
+# define S_IXGRP (S_IXUSR >> 3)
+#endif
+#if !S_IXOTH
+# define S_IXOTH (S_IXUSR >> 6)
+#endif
+
+#if !S_IRWXU
+# define S_IRWXU (S_IRUSR | S_IWUSR | S_IXUSR)
+#endif
+#if !S_IRWXG
+# define S_IRWXG (S_IRGRP | S_IWGRP | S_IXGRP)
+#endif
+#if !S_IRWXO
+# define S_IRWXO (S_IROTH | S_IWOTH | S_IXOTH)
+#endif
+
+/* S_IXUGO is a common extension to POSIX.  */
+#if !S_IXUGO
+# define S_IXUGO (S_IXUSR | S_IXGRP | S_IXOTH)
+#endif
+
+#ifndef S_IRWXUGO
+# define S_IRWXUGO (S_IRWXU | S_IRWXG | S_IRWXO)
+#endif
+
+/* Macros for futimens and utimensat.  */
+#ifndef UTIME_NOW
+# define UTIME_NOW (-1)
+# define UTIME_OMIT (-2)
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#if @GNULIB_FCHMODAT@
+# if !@HAVE_FCHMODAT@
+extern int fchmodat (int fd, char const *file, mode_t mode, int flag)
+     _GL_ARG_NONNULL ((2));
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef fchmodat
+# if HAVE_RAW_DECL_FCHMODAT
+_GL_WARN_ON_USE (fchmodat, "fchmodat is not portable - "
+                 "use gnulib module openat for portability");
+# endif
+#endif
+
+
+#if @REPLACE_FSTAT@
+# define fstat rpl_fstat
+extern int fstat (int fd, struct stat *buf) _GL_ARG_NONNULL ((2));
+#endif
+
+
+#if @GNULIB_FSTATAT@
+# if @REPLACE_FSTATAT@
+#  undef fstatat
+#  define fstatat rpl_fstatat
+# endif
+# if !@HAVE_FSTATAT@ || @REPLACE_FSTATAT@
+extern int fstatat (int fd, char const *name, struct stat *st, int flags)
+     _GL_ARG_NONNULL ((2, 3));
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef fstatat
+# if HAVE_RAW_DECL_FSTATAT
+_GL_WARN_ON_USE (fstatat, "fstatat is not portable - "
+                 "use gnulib module openat for portability");
+# endif
+#endif
+
+
+#if @GNULIB_FUTIMENS@
+# if @REPLACE_FUTIMENS@
+#  undef futimens
+#  define futimens rpl_futimens
+# endif
+# if !@HAVE_FUTIMENS@ || @REPLACE_FUTIMENS@
+extern int futimens (int fd, struct timespec const times[2]);
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef futimens
+# if HAVE_RAW_DECL_FUTIMENS
+_GL_WARN_ON_USE (futimens, "futimens is not portable - "
+                 "use gnulib module futimens for portability");
+# endif
+#endif
+
+
+#if @GNULIB_LCHMOD@
+/* Change the mode of FILENAME to MODE, without dereferencing it if FILENAME
+   denotes a symbolic link.  */
+# if !@HAVE_LCHMOD@
+/* The lchmod replacement follows symbolic links.  Callers should take
+   this into account; lchmod should be applied only to arguments that
+   are known to not be symbolic links.  On hosts that lack lchmod,
+   this can lead to race conditions between the check and the
+   invocation of lchmod, but we know of no workarounds that are
+   reliable in general.  You might try requesting support for lchmod
+   from your operating system supplier.  */
+#  define lchmod chmod
+# endif
+# if 0 /* assume already declared */
+extern int lchmod (const char *filename, mode_t mode) _GL_ARG_NONNULL ((1));
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef lchmod
+# if HAVE_RAW_DECL_LCHMOD
+_GL_WARN_ON_USE (lchmod, "lchmod is unportable - "
+                 "use gnulib module lchmod for portability");
+# endif
+#endif
+
+
+#if @GNULIB_LSTAT@
+# if ! @HAVE_LSTAT@
+/* mingw does not support symlinks, therefore it does not have lstat.  But
+   without links, stat does just fine.  */
+#  define lstat stat
+# elif @REPLACE_LSTAT@
+#  undef lstat
+#  define lstat rpl_lstat
+extern int rpl_lstat (const char *name, struct stat *buf)
+     _GL_ARG_NONNULL ((1, 2));
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef lstat
+# if HAVE_RAW_DECL_LSTAT
+_GL_WARN_ON_USE (lstat, "lstat is unportable - "
+                 "use gnulib module lstat for portability");
+# endif
+#endif
+
+
+#if @REPLACE_MKDIR@
+# undef mkdir
+# define mkdir rpl_mkdir
+extern int mkdir (char const *name, mode_t mode) _GL_ARG_NONNULL ((1));
+#else
+/* mingw's _mkdir() function has 1 argument, but we pass 2 arguments.
+   Additionally, it declares _mkdir (and depending on compile flags, an
+   alias mkdir), only in the nonstandard <io.h>, which is included above.  */
+# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+
+static inline int
+rpl_mkdir (char const *name, mode_t mode)
+{
+  return _mkdir (name);
+}
+
+#  define mkdir rpl_mkdir
+# endif
+#endif
+
+
+#if @GNULIB_MKDIRAT@
+# if !@HAVE_MKDIRAT@
+extern int mkdirat (int fd, char const *file, mode_t mode)
+     _GL_ARG_NONNULL ((2));
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef mkdirat
+# if HAVE_RAW_DECL_MKDIRAT
+_GL_WARN_ON_USE (mkdirat, "mkdirat is not portable - "
+                 "use gnulib module openat for portability");
+# endif
+#endif
+
+
+#if @GNULIB_MKFIFO@
+# if @REPLACE_MKFIFO@
+#  undef mkfifo
+#  define mkfifo rpl_mkfifo
+# endif
+# if !@HAVE_MKFIFO@ || @REPLACE_MKFIFO@
+extern int mkfifo (char const *file, mode_t mode) _GL_ARG_NONNULL ((1));
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef mkfifo
+# if HAVE_RAW_DECL_MKFIFO
+_GL_WARN_ON_USE (mkfifo, "mkfifo is not portable - "
+                 "use gnulib module mkfifo for portability");
+# endif
+#endif
+
+
+#if @GNULIB_MKFIFOAT@
+# if !@HAVE_MKFIFOAT@
+extern int mkfifoat (int fd, char const *file, mode_t mode)
+     _GL_ARG_NONNULL ((2));
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef mkfifoat
+# if HAVE_RAW_DECL_MKFIFOAT
+_GL_WARN_ON_USE (mkfifoat, "mkfifoat is not portable - "
+                 "use gnulib module mkfifoat for portability");
+# endif
+#endif
+
+
+#if @GNULIB_MKNOD@
+# if @REPLACE_MKNOD@
+#  undef mknod
+#  define mknod rpl_mknod
+# endif
+# if !@HAVE_MKNOD@ || @REPLACE_MKNOD@
+extern int mknod (char const *file, mode_t mode, dev_t dev)
+     _GL_ARG_NONNULL ((1));
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef mknod
+# if HAVE_RAW_DECL_MKNOD
+_GL_WARN_ON_USE (mknod, "mknod is not portable - "
+                 "use gnulib module mknod for portability");
+# endif
+#endif
+
+
+#if @GNULIB_MKNODAT@
+# if !@HAVE_MKNODAT@
+extern int mknodat (int fd, char const *file, mode_t mode, dev_t dev)
+     _GL_ARG_NONNULL ((2));
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef mknodat
+# if HAVE_RAW_DECL_MKNODAT
+_GL_WARN_ON_USE (mknodat, "mknodat is not portable - "
+                 "use gnulib module mkfifoat for portability");
+# endif
+#endif
+
+
+#if @GNULIB_STAT@
+# if @REPLACE_STAT@
+/* We can't use the object-like #define stat rpl_stat, because of
+   struct stat.  This means that rpl_stat will not be used if the user
+   does (stat)(a,b).  Oh well.  */
+#  undef stat
+#  ifdef _LARGE_FILES
+    /* With _LARGE_FILES defined, AIX (only) defines stat to stat64,
+       so we have to replace stat64() instead of stat(). */
+#   define stat stat64
+#   undef stat64
+#   define stat64(name, st) rpl_stat (name, st)
+#  else /* !_LARGE_FILES */
+#   define stat(name, st) rpl_stat (name, st)
+#  endif /* !_LARGE_FILES */
+extern int stat (const char *name, struct stat *buf) _GL_ARG_NONNULL ((1, 2));
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef stat
+# if HAVE_RAW_DECL_STAT
+_GL_WARN_ON_USE (stat, "stat is unportable - "
+                 "use gnulib module stat for portability");
+# endif
+#endif
+
+
+#if @GNULIB_UTIMENSAT@
+# if @REPLACE_UTIMENSAT@
+#  undef utimensat
+#  define utimensat rpl_utimensat
+# endif
+# if !@HAVE_UTIMENSAT@ || @REPLACE_UTIMENSAT@
+   extern int utimensat (int fd, char const *name,
+                         struct timespec const times[2], int flag)
+        _GL_ARG_NONNULL ((2));
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef utimensat
+# if HAVE_RAW_DECL_UTIMENSAT
+_GL_WARN_ON_USE (utimensat, "utimensat is not portable - "
+                 "use gnulib module utimensat for portability");
+# endif
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* _GL_SYS_STAT_H */
+#endif /* _GL_SYS_STAT_H */
+#endif
diff --git a/libmissing/sys_time.in.h b/libmissing/sys_time.in.h
index 544a725..797ef46 100644
--- a/libmissing/sys_time.in.h
+++ b/libmissing/sys_time.in.h
@@ -41,6 +41,8 @@
 
 /* The definition of _GL_ARG_NONNULL is copied here.  */
 
+/* The definition of _GL_WARN_ON_USE is copied here.  */
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -53,11 +55,21 @@ struct timeval
 };
 # endif
 
-# if @REPLACE_GETTIMEOFDAY@
-#  undef gettimeofday
-#  define gettimeofday rpl_gettimeofday
+# if @GNULIB_GETTIMEOFDAY@
+#  if @REPLACE_GETTIMEOFDAY@
+#   undef gettimeofday
+#   define gettimeofday rpl_gettimeofday
+#  endif
+#  if @REPLACE_GETTIMEOFDAY@ || !@HAVE_GETTIMEOFDAY@
 extern int gettimeofday (struct timeval *restrict, void *restrict)
      _GL_ARG_NONNULL ((1));
+#  endif
+# elif defined GNULIB_POSIXCHECK
+#  undef gettimeofday
+#  if HAVE_RAW_DECL_GETTIMEOFDAY
+_GL_WARN_ON_USE (gettimeofday, "gettimeofday is unportable - "
+		 "use gnulib module gettimeofday for portability");
+#  endif
 # endif
 
 #ifdef __cplusplus
diff --git a/libmissing/tests/Makefile.am b/libmissing/tests/Makefile.am
index e3aac06..2d94540 100644
--- a/libmissing/tests/Makefile.am
+++ b/libmissing/tests/Makefile.am
@@ -161,15 +161,6 @@ EXTRA_DIST += signature.h test-getaddrinfo.c
 
 ## end   gnulib module getaddrinfo-tests
 
-## begin gnulib module getdtablesize
-
-
-EXTRA_DIST += getdtablesize.c
-
-EXTRA_libtests_a_SOURCES += getdtablesize.c
-
-## end   gnulib module getdtablesize
-
 ## begin gnulib module getdtablesize-tests
 
 TESTS += test-getdtablesize
@@ -187,6 +178,12 @@ EXTRA_DIST += signature.h test-gettimeofday.c
 
 ## end   gnulib module gettimeofday-tests
 
+## begin gnulib module ignore-value
+
+libtests_a_SOURCES += ignore-value.h
+
+## end   gnulib module ignore-value
+
 ## begin gnulib module inet_ntop-tests
 
 TESTS += test-inet_ntop
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/ignore-value.h b/libmissing/tests/ignore-value.h
new file mode 100644
index 0000000..2eb6918
--- /dev/null
+++ b/libmissing/tests/ignore-value.h
@@ -0,0 +1,37 @@
+/* ignore a function return without a compiler warning
+
+   Copyright (C) 2008-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 Jim Meyering.  */
+
+/* Use these functions to avoid a warning when using a function declared with
+   gcc's warn_unused_result attribute, but for which you really do want to
+   ignore the result.  Traditionally, people have used a "(void)" cast to
+   indicate that a function's return value is deliberately unused.  However,
+   if the function is declared with __attribute__((warn_unused_result)),
+   gcc issues a warning even with the cast.
+
+   Caution: most of the time, you really should heed gcc's warning, and
+   check the return value.  However, in those exceptional cases in which
+   you're sure you know what you're doing, use this function.
+
+   For the record, here's one of the ignorable warnings:
+   "copy.c:233: warning: ignoring return value of 'fchown',
+   declared with attribute warn_unused_result".  */
+
+static inline void ignore_value (int i) { (void) i; }
+static inline void ignore_ptr (void* p) { (void) p; }
+/* FIXME: what about aggregate types? */
diff --git a/libmissing/tests/lstat.c b/libmissing/tests/lstat.c
new file mode 100644
index 0000000..586ab16
--- /dev/null
+++ b/libmissing/tests/lstat.c
@@ -0,0 +1,91 @@
+/* Work around a bug of lstat on some systems
+
+   Copyright (C) 1997-2006, 2008-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 Jim Meyering */
+
+#include <config.h>
+
+#if !HAVE_LSTAT
+/* On systems that lack symlinks, our replacement <sys/stat.h> already
+   defined lstat as stat, so there is nothing further to do other than
+   avoid an empty file.  */
+typedef int dummy;
+#else /* HAVE_LSTAT */
+
+/* Get the original definition of lstat.  It might be defined as a macro.  */
+# define __need_system_sys_stat_h
+# include <sys/types.h>
+# include <sys/stat.h>
+# undef __need_system_sys_stat_h
+
+static inline int
+orig_lstat (const char *filename, struct stat *buf)
+{
+  return lstat (filename, buf);
+}
+
+/* Specification.  */
+# include <sys/stat.h>
+
+# include <string.h>
+# include <errno.h>
+
+/* lstat works differently on Linux and Solaris systems.  POSIX (see
+   `pathname resolution' in the glossary) requires that programs like
+   `ls' take into consideration the fact that FILE has a trailing slash
+   when FILE is a symbolic link.  On Linux and Solaris 10 systems, the
+   lstat function already has the desired semantics (in treating
+   `lstat ("symlink/", sbuf)' just like `lstat ("symlink/.", sbuf)',
+   but on Solaris 9 and earlier it does not.
+
+   If FILE has a trailing slash and specifies a symbolic link,
+   then use stat() to get more info on the referent of FILE.
+   If the referent is a non-directory, then set errno to ENOTDIR
+   and return -1.  Otherwise, return stat's result.  */
+
+int
+rpl_lstat (const char *file, struct stat *sbuf)
+{
+  size_t len;
+  int lstat_result = orig_lstat (file, sbuf);
+
+  if (lstat_result != 0)
+    return lstat_result;
+
+  /* This replacement file can blindly check against '/' rather than
+     using the ISSLASH macro, because all platforms with '\\' either
+     lack symlinks (mingw) or have working lstat (cygwin) and thus do
+     not compile this file.  0 len should have already been filtered
+     out above, with a failure return of ENOENT.  */
+  len = strlen (file);
+  if (file[len - 1] != '/' || S_ISDIR (sbuf->st_mode))
+    return 0;
+
+  /* At this point, a trailing slash is only permitted on
+     symlink-to-dir; but it should have found information on the
+     directory, not the symlink.  Call stat() to get info about the
+     link's referent.  Our replacement stat guarantees valid results,
+     even if the symlink is not pointing to a directory.  */
+  if (!S_ISLNK (sbuf->st_mode))
+    {
+      errno = ENOTDIR;
+      return -1;
+    }
+  return stat (file, sbuf);
+}
+
+#endif /* HAVE_LSTAT */
diff --git a/libmissing/tests/macros.h b/libmissing/tests/macros.h
new file mode 100644
index 0000000..11db5a8
--- /dev/null
+++ b/libmissing/tests/macros.h
@@ -0,0 +1,64 @@
+/* Common macros used by gnulib tests.
+   Copyright (C) 2006-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/>.  */
+
+
+/* This file contains macros that are used by many gnulib tests.
+   Put here only frequently used macros, say, used by 10 tests or more.  */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+/* Define ASSERT_STREAM before including this file if ASSERT must
+   target a stream other than stderr.  */
+#ifndef ASSERT_STREAM
+# define ASSERT_STREAM stderr
+#endif
+
+/* ASSERT (condition);
+   verifies that the specified condition is fulfilled.  If not, a message
+   is printed to ASSERT_STREAM if defined (defaulting to stderr if
+   undefined) and the program is terminated with an error code.
+
+   This macro has the following properties:
+     - The programmer specifies the expected condition, not the failure
+       condition.  This simplifies thinking.
+     - The condition is tested always, regardless of compilation flags.
+       (Unlike the macro from <assert.h>.)
+     - On Unix platforms, the tester can debug the test program with a
+       debugger (provided core dumps are enabled: "ulimit -c unlimited").
+     - For the sake of platforms where no debugger is available (such as
+       some mingw systems), an error message is printed on the error
+       stream that includes the source location of the ASSERT invocation.
+ */
+#define ASSERT(expr) \
+  do                                                                         \
+    {                                                                        \
+      if (!(expr))                                                           \
+        {                                                                    \
+          fprintf (ASSERT_STREAM, "%s:%d: assertion failed\n",               \
+                   __FILE__, __LINE__);                                      \
+          fflush (ASSERT_STREAM);                                            \
+          abort ();                                                          \
+        }                                                                    \
+    }                                                                        \
+  while (0)
+
+/* SIZEOF (array)
+   returns the number of elements of an array.  It works for arrays that are
+   declared outside functions and for local variables of array type.  It does
+   *not* work for function parameters of array type, because they are actually
+   parameters of pointer type.  */
+#define SIZEOF(array) (sizeof (array) / sizeof (array[0]))
diff --git a/libmissing/tests/open.c b/libmissing/tests/open.c
new file mode 100644
index 0000000..f612b80
--- /dev/null
+++ b/libmissing/tests/open.c
@@ -0,0 +1,166 @@
+/* Open a descriptor to a file.
+   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 Bruno Haible <[email protected]>, 2007.  */
+
+#include <config.h>
+
+/* Get the original definition of open.  It might be defined as a macro.  */
+#define __need_system_fcntl_h
+#include <fcntl.h>
+#undef __need_system_fcntl_h
+#include <sys/types.h>
+
+static inline int
+orig_open (const char *filename, int flags, mode_t mode)
+{
+  return open (filename, flags, mode);
+}
+
+/* Specification.  */
+#include <fcntl.h>
+
+#include <errno.h>
+#include <stdarg.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#ifndef REPLACE_OPEN_DIRECTORY
+# define REPLACE_OPEN_DIRECTORY 0
+#endif
+
+int
+open (const char *filename, int flags, ...)
+{
+  mode_t mode;
+  int fd;
+
+  mode = 0;
+  if (flags & O_CREAT)
+    {
+      va_list arg;
+      va_start (arg, flags);
+
+      /* We have to use PROMOTED_MODE_T instead of mode_t, otherwise GCC 4
+         creates crashing code when 'mode_t' is smaller than 'int'.  */
+      mode = va_arg (arg, PROMOTED_MODE_T);
+
+      va_end (arg);
+    }
+
+#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+  if (strcmp (filename, "/dev/null") == 0)
+    filename = "NUL";
+#endif
+
+#if OPEN_TRAILING_SLASH_BUG
+  /* If the filename ends in a slash and one of O_CREAT, O_WRONLY, O_RDWR
+     is specified, then fail.
+     Rationale: POSIX <http://www.opengroup.org/susv3/basedefs/xbd_chap04.html>
+     says that
+       "A pathname that contains at least one non-slash character and that
+        ends with one or more trailing slashes shall be resolved as if a
+        single dot character ( '.' ) were appended to the pathname."
+     and
+       "The special filename dot shall refer to the directory specified by
+        its predecessor."
+     If the named file already exists as a directory, then
+       - if O_CREAT is specified, open() must fail because of the semantics
+         of O_CREAT,
+       - if O_WRONLY or O_RDWR is specified, open() must fail because POSIX
+         <http://www.opengroup.org/susv3/functions/open.html> says that it
+         fails with errno = EISDIR in this case.
+     If the named file does not exist or does not name a directory, then
+       - if O_CREAT is specified, open() must fail since open() cannot create
+         directories,
+       - if O_WRONLY or O_RDWR is specified, open() must fail because the
+         file does not contain a '.' directory.  */
+  if (flags & (O_CREAT | O_WRONLY | O_RDWR))
+    {
+      size_t len = strlen (filename);
+      if (len > 0 && filename[len - 1] == '/')
+        {
+          errno = EISDIR;
+          return -1;
+        }
+    }
+#endif
+
+  fd = orig_open (filename, flags, mode);
+
+#if REPLACE_FCHDIR
+  /* Implementing fchdir and fdopendir requires the ability to open a
+     directory file descriptor.  If open doesn't support that (as on
+     mingw), we use a dummy file that behaves the same as directories
+     on Linux (ie. always reports EOF on attempts to read()), and
+     override fstat() in fchdir.c to hide the fact that we have a
+     dummy.  */
+  if (REPLACE_OPEN_DIRECTORY && fd < 0 && errno == EACCES
+      && (flags & O_ACCMODE) == O_RDONLY)
+    {
+      struct stat statbuf;
+      if (stat (filename, &statbuf) == 0 && S_ISDIR (statbuf.st_mode))
+        {
+          /* Maximum recursion depth of 1.  */
+          fd = open ("/dev/null", flags, mode);
+          if (0 <= fd)
+            fd = _gl_register_fd (fd, filename);
+        }
+      else
+        errno = EACCES;
+    }
+#endif
+
+#if OPEN_TRAILING_SLASH_BUG
+  /* If the filename ends in a slash and fd does not refer to a directory,
+     then fail.
+     Rationale: POSIX <http://www.opengroup.org/susv3/basedefs/xbd_chap04.html>
+     says that
+       "A pathname that contains at least one non-slash character and that
+        ends with one or more trailing slashes shall be resolved as if a
+        single dot character ( '.' ) were appended to the pathname."
+     and
+       "The special filename dot shall refer to the directory specified by
+        its predecessor."
+     If the named file without the slash is not a directory, open() must fail
+     with ENOTDIR.  */
+  if (fd >= 0)
+    {
+      /* We know len is positive, since open did not fail with ENOENT.  */
+      size_t len = strlen (filename);
+      if (filename[len - 1] == '/')
+        {
+          struct stat statbuf;
+
+          if (fstat (fd, &statbuf) >= 0 && !S_ISDIR (statbuf.st_mode))
+            {
+              close (fd);
+              errno = ENOTDIR;
+              return -1;
+            }
+        }
+    }
+#endif
+
+#if REPLACE_FCHDIR
+  if (!REPLACE_OPEN_DIRECTORY && 0 <= fd)
+    fd = _gl_register_fd (fd, filename);
+#endif
+
+  return fd;
+}
diff --git a/libmissing/tests/same-inode.h b/libmissing/tests/same-inode.h
new file mode 100644
index 0000000..e978abb
--- /dev/null
+++ b/libmissing/tests/same-inode.h
@@ -0,0 +1,25 @@
+/* Determine whether two stat buffers refer to the same file.
+
+   Copyright (C) 2006, 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 SAME_INODE_H
+# define SAME_INODE_H 1
+
+# define SAME_INODE(Stat_buf_1, Stat_buf_2) \
+   ((Stat_buf_1).st_ino == (Stat_buf_2).st_ino \
+    && (Stat_buf_1).st_dev == (Stat_buf_2).st_dev)
+
+#endif
diff --git a/libmissing/tests/signature.h b/libmissing/tests/signature.h
new file mode 100644
index 0000000..6e15c43
--- /dev/null
+++ b/libmissing/tests/signature.h
@@ -0,0 +1,48 @@
+/* Macro for checking that a function declaration is compliant.
+   Copyright (C) 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 SIGNATURE_CHECK
+
+/* Check that the function FN takes the specified arguments ARGS with
+   a return type of RET.  This header is designed to be included after
+   <config.h> and the one system header that is supposed to contain
+   the function being checked, but prior to any other system headers
+   that are necessary for the unit test.  Therefore, this file does
+   not include any system headers, nor reference anything outside of
+   the macro arguments.  For an example, if foo.h should provide:
+
+   extern int foo (char, float);
+
+   then the unit test named test-foo.c would start out with:
+
+   #include <config.h>
+   #include <foo.h>
+   #include "signature.h"
+   SIGNATURE_CHECK (foo, int, (char, float));
+   #include <other.h>
+   ...
+*/
+# define SIGNATURE_CHECK(fn, ret, args) \
+  SIGNATURE_CHECK1 (fn, ret, args, __LINE__)
+
+/* Necessary to allow multiple SIGNATURE_CHECK lines in a unit test.
+   Note that the checks must not occupy the same line.  */
+# define SIGNATURE_CHECK1(fn, ret, args, id) \
+  SIGNATURE_CHECK2 (fn, ret, args, id) /* macroexpand line */
+# define SIGNATURE_CHECK2(fn, ret, args, id) \
+  static ret (* _GL_UNUSED signature_check ## id) args = fn
+
+#endif /* SIGNATURE_CHECK */
diff --git a/libmissing/tests/symlink.c b/libmissing/tests/symlink.c
new file mode 100644
index 0000000..40bbb80
--- /dev/null
+++ b/libmissing/tests/symlink.c
@@ -0,0 +1,57 @@
+/* Stub for symlink().
+   Copyright (C) 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/>.  */
+
+#include <config.h>
+
+/* Specification.  */
+#include <unistd.h>
+
+#include <errno.h>
+#include <string.h>
+#include <sys/stat.h>
+
+
+#if HAVE_SYMLINK
+
+# undef symlink
+
+/* Create a symlink, but reject trailing slash.  */
+int
+rpl_symlink (char const *contents, char const *name)
+{
+  size_t len = strlen (name);
+  if (len && name[len - 1] == '/')
+    {
+      struct stat st;
+      if (lstat (name, &st) == 0)
+        errno = EEXIST;
+      return -1;
+    }
+  return symlink (contents, name);
+}
+
+#else /* !HAVE_SYMLINK */
+
+/* The system does not support symlinks.  */
+int
+symlink (char const *contents _GL_UNUSED,
+         char const *name _GL_UNUSED)
+{
+  errno = ENOSYS;
+  return -1;
+}
+
+#endif /* !HAVE_SYMLINK */
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-dup2.c b/libmissing/tests/test-dup2.c
new file mode 100644
index 0000000..3bad63a
--- /dev/null
+++ b/libmissing/tests/test-dup2.c
@@ -0,0 +1,193 @@
+/* Test duplicating file descriptors.
+   Copyright (C) 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 Eric Blake <[email protected]>, 2009.  */
+
+#include <config.h>
+
+#include <unistd.h>
+
+#include "signature.h"
+SIGNATURE_CHECK (dup2, int, (int, int));
+
+#include <errno.h>
+#include <fcntl.h>
+
+#include "binary-io.h"
+
+#if GNULIB_CLOEXEC
+# include "cloexec.h"
+#endif
+
+#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+/* Get declarations of the Win32 API functions.  */
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+#endif
+
+#include "macros.h"
+
+/* Return non-zero if FD is open.  */
+static int
+is_open (int fd)
+{
+#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+  /* On Win32, the initial state of unassigned standard file
+     descriptors is that they are open but point to an
+     INVALID_HANDLE_VALUE, and there is no fcntl.  */
+  return (HANDLE) _get_osfhandle (fd) != INVALID_HANDLE_VALUE;
+#else
+# ifndef F_GETFL
+#  error Please port fcntl to your platform
+# endif
+  return 0 <= fcntl (fd, F_GETFL);
+#endif
+}
+
+#if GNULIB_CLOEXEC
+/* Return non-zero if FD is open and inheritable across exec/spawn.  */
+static int
+is_inheritable (int fd)
+{
+# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+  /* On Win32, the initial state of unassigned standard file
+     descriptors is that they are open but point to an
+     INVALID_HANDLE_VALUE, and there is no fcntl.  */
+  HANDLE h = (HANDLE) _get_osfhandle (fd);
+  DWORD flags;
+  if (h == INVALID_HANDLE_VALUE || GetHandleInformation (h, &flags) == 0)
+    return 0;
+  return (flags & HANDLE_FLAG_INHERIT) != 0;
+# else
+#  ifndef F_GETFD
+#   error Please port fcntl to your platform
+#  endif
+  int i = fcntl (fd, F_GETFD);
+  return 0 <= i && (i & FD_CLOEXEC) == 0;
+# endif
+}
+#endif /* GNULIB_CLOEXEC */
+
+#if !O_BINARY
+# define setmode(f,m) zero ()
+static int zero (void) { return 0; }
+#endif
+
+/* Return non-zero if FD is open in the given MODE, which is either
+   O_TEXT or O_BINARY.  */
+static int
+is_mode (int fd, int mode)
+{
+  int value = setmode (fd, O_BINARY);
+  setmode (fd, value);
+  return mode == value;
+}
+
+int
+main (void)
+{
+  const char *file = "test-dup2.tmp";
+  char buffer[1];
+  int fd = open (file, O_CREAT | O_TRUNC | O_RDWR, 0600);
+
+  /* Assume std descriptors were provided by invoker.  */
+  ASSERT (STDERR_FILENO < fd);
+  ASSERT (is_open (fd));
+  /* Ignore any other fd's leaked into this process.  */
+  close (fd + 1);
+  close (fd + 2);
+  ASSERT (!is_open (fd + 1));
+  ASSERT (!is_open (fd + 2));
+
+  /* Assigning to self must be a no-op.  */
+  ASSERT (dup2 (fd, fd) == fd);
+  ASSERT (is_open (fd));
+
+  /* The source must be valid.  */
+  errno = 0;
+  ASSERT (dup2 (-1, fd) == -1);
+  ASSERT (errno == EBADF);
+  errno = 0;
+  ASSERT (dup2 (AT_FDCWD, fd) == -1);
+  ASSERT (errno == EBADF);
+  ASSERT (is_open (fd));
+
+  /* If the source is not open, then the destination is unaffected.  */
+  errno = 0;
+  ASSERT (dup2 (fd + 1, fd + 1) == -1);
+  ASSERT (errno == EBADF);
+  ASSERT (!is_open (fd + 1));
+  errno = 0;
+  ASSERT (dup2 (fd + 1, fd) == -1);
+  ASSERT (errno == EBADF);
+  ASSERT (is_open (fd));
+
+  /* The destination must be valid.  */
+  errno = 0;
+  ASSERT (dup2 (fd, -2) == -1);
+  ASSERT (errno == EBADF);
+  errno = 0;
+  ASSERT (dup2 (fd, 10000000) == -1);
+  ASSERT (errno == EBADF);
+
+  /* Using dup2 can skip fds.  */
+  ASSERT (dup2 (fd, fd + 2) == fd + 2);
+  ASSERT (is_open (fd));
+  ASSERT (!is_open (fd + 1));
+  ASSERT (is_open (fd + 2));
+
+  /* Verify that dup2 closes the previous occupant of a fd.  */
+  ASSERT (open ("/dev/null", O_WRONLY, 0600) == fd + 1);
+  ASSERT (dup2 (fd + 1, fd) == fd);
+  ASSERT (close (fd + 1) == 0);
+  ASSERT (write (fd, "1", 1) == 1);
+  ASSERT (dup2 (fd + 2, fd) == fd);
+  ASSERT (lseek (fd, 0, SEEK_END) == 0);
+  ASSERT (write (fd + 2, "2", 1) == 1);
+  ASSERT (lseek (fd, 0, SEEK_SET) == 0);
+  ASSERT (read (fd, buffer, 1) == 1);
+  ASSERT (*buffer == '2');
+
+#if GNULIB_CLOEXEC
+  /* Any new fd created by dup2 must not be cloexec.  */
+  ASSERT (close (fd + 2) == 0);
+  ASSERT (dup_cloexec (fd) == fd + 1);
+  ASSERT (!is_inheritable (fd + 1));
+  ASSERT (dup2 (fd + 1, fd + 1) == fd + 1);
+  ASSERT (!is_inheritable (fd + 1));
+  ASSERT (dup2 (fd + 1, fd + 2) == fd + 2);
+  ASSERT (is_inheritable (fd + 2));
+#endif
+
+  /* On systems that distinguish between text and binary mode, dup2
+     reuses the mode of the source.  */
+  setmode (fd, O_BINARY);
+  ASSERT (is_mode (fd, O_BINARY));
+  ASSERT (dup2 (fd, fd + 1) == fd + 1);
+  ASSERT (is_mode (fd + 1, O_BINARY));
+  setmode (fd, O_TEXT);
+  ASSERT (is_mode (fd, O_TEXT));
+  ASSERT (dup2 (fd, fd + 1) == fd + 1);
+  ASSERT (is_mode (fd + 1, O_TEXT));
+
+  /* Clean up.  */
+  ASSERT (close (fd + 2) == 0);
+  ASSERT (close (fd + 1) == 0);
+  ASSERT (close (fd) == 0);
+  ASSERT (unlink (file) == 0);
+
+  return 0;
+}
diff --git a/libmissing/tests/test-fcntl-h.c b/libmissing/tests/test-fcntl-h.c
new file mode 100644
index 0000000..0ce33f0
--- /dev/null
+++ b/libmissing/tests/test-fcntl-h.c
@@ -0,0 +1,38 @@
+/* Test of <fcntl.h> substitute.
+   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 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>
+
+#include <fcntl.h>
+
+/* Check that the various O_* macros are defined.  */
+int o = O_DIRECT | O_DIRECTORY | O_DSYNC | O_NDELAY | O_NOATIME | O_NONBLOCK
+        | O_NOCTTY | O_NOFOLLOW | O_NOLINKS | O_RSYNC | O_SYNC | O_TTY_INIT
+        | O_BINARY | O_TEXT;
+
+/* Check that the various SEEK_* macros are defined.  */
+int sk[] = { SEEK_CUR, SEEK_END, SEEK_SET };
+
+/* Check that the FD_* macros are defined.  */
+int fd = FD_CLOEXEC;
+
+int
+main (void)
+{
+  return 0;
+}
diff --git a/libmissing/tests/test-getdtablesize.c b/libmissing/tests/test-getdtablesize.c
new file mode 100644
index 0000000..20e1873
--- /dev/null
+++ b/libmissing/tests/test-getdtablesize.c
@@ -0,0 +1,34 @@
+/* Test of getdtablesize() function.
+   Copyright (C) 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]>, 2008.  */
+
+#include <config.h>
+
+#include <unistd.h>
+
+#include "signature.h"
+SIGNATURE_CHECK (getdtablesize, int, (void));
+
+#include "macros.h"
+
+int
+main (int argc, char *argv[])
+{
+  ASSERT (getdtablesize () >= 3);
+
+  return 0;
+}
diff --git a/libmissing/tests/test-gettimeofday.c b/libmissing/tests/test-gettimeofday.c
index 2a07814..ff2bc72 100644
--- a/libmissing/tests/test-gettimeofday.c
+++ b/libmissing/tests/test-gettimeofday.c
@@ -20,7 +20,8 @@
 #include <sys/time.h>
 
 #include "signature.h"
-SIGNATURE_CHECK (gettimeofday, int, (struct timeval *, void *));
+SIGNATURE_CHECK (gettimeofday, int,
+                 (struct timeval *, GETTIMEOFDAY_TIMEZONE *));
 
 #include <time.h>
 
@@ -42,8 +43,5 @@ main (void)
       fprintf (stderr, "gettimeofday still clobbers the localtime buffer!\n");
       return 1;
     }
-  else
-    {
-      return 0;
-    }
+  return 0;
 }
diff --git a/libmissing/tests/test-inet_ntop.c b/libmissing/tests/test-inet_ntop.c
new file mode 100644
index 0000000..d3b045c
--- /dev/null
+++ b/libmissing/tests/test-inet_ntop.c
@@ -0,0 +1,56 @@
+/* Test of inet_ntop function.
+   Copyright (C) 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]>, 2009.  */
+
+#include <config.h>
+
+#include <arpa/inet.h>
+
+#include "signature.h"
+SIGNATURE_CHECK (inet_ntop, char const *, (int, void const *, char *,
+                                           socklen_t));
+
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <string.h>
+
+#include "macros.h"
+
+int
+main (void)
+{
+#if defined AF_INET /* HAVE_IPV4 */
+  {
+    struct in_addr internal;
+    char printable[16];
+    const char *result;
+
+    /* This machine was for a long time known as
+       ma2s2.mathematik.uni-karlsruhe.de.  */
+# ifdef WORDS_BIGENDIAN
+    internal.s_addr = 0x810D7302;
+# else
+    internal.s_addr = 0x02730D81;
+# endif
+    result = inet_ntop (AF_INET, &internal, printable, sizeof (printable));
+    ASSERT (result != NULL);
+    ASSERT (strcmp (result, "129.13.115.2") == 0);
+  }
+#endif
+
+  return 0;
+}
diff --git a/libmissing/tests/test-lstat.c b/libmissing/tests/test-lstat.c
new file mode 100644
index 0000000..b8f9237
--- /dev/null
+++ b/libmissing/tests/test-lstat.c
@@ -0,0 +1,60 @@
+/* Test of lstat() function.
+   Copyright (C) 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 Simon Josefsson, 2008; and Eric Blake, 2009.  */
+
+#include <config.h>
+
+#include <sys/stat.h>
+
+/* Caution: lstat may be a function-like macro.  Although this
+   signature check must pass, it may be the signature of the real (and
+   broken) lstat rather than rpl_lstat.  Most code should not use the
+   address of lstat.  */
+#include "signature.h"
+SIGNATURE_CHECK (lstat, int, (char const *, struct stat *));
+
+#include <fcntl.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "same-inode.h"
+#include "ignore-value.h"
+#include "macros.h"
+
+#define BASE "test-lstat.t"
+
+#include "test-lstat.h"
+
+/* Wrapper around lstat, which works even if lstat is a function-like
+   macro, where test_lstat_func(lstat) would do the wrong thing.  */
+static int
+do_lstat (char const *name, struct stat *st)
+{
+  return lstat (name, st);
+}
+
+int
+main (void)
+{
+  /* Remove any leftovers from a previous partial run.  */
+  ignore_value (system ("rm -rf " BASE "*"));
+
+  return test_lstat_func (do_lstat, true);
+}
diff --git a/libmissing/tests/test-lstat.h b/libmissing/tests/test-lstat.h
new file mode 100644
index 0000000..f120f4c
--- /dev/null
+++ b/libmissing/tests/test-lstat.h
@@ -0,0 +1,116 @@
+/* Test of lstat() function.
+   Copyright (C) 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 Simon Josefsson, 2008; and Eric Blake, 2009.  */
+
+/* This file is designed to test both lstat(n,buf) and
+   fstatat(AT_FDCWD,n,buf,AT_SYMLINK_NOFOLLOW).  FUNC is the function
+   to test.  Assumes that BASE and ASSERT are already defined, and
+   that appropriate headers are already included.  If PRINT, warn
+   before skipping symlink tests with status 77.  */
+
+static int
+test_lstat_func (int (*func) (char const *, struct stat *), bool print)
+{
+  struct stat st1;
+  struct stat st2;
+
+  /* Test for common directories.  */
+  ASSERT (func (".", &st1) == 0);
+  ASSERT (func ("./", &st2) == 0);
+  ASSERT (SAME_INODE (st1, st2));
+  ASSERT (S_ISDIR (st1.st_mode));
+  ASSERT (S_ISDIR (st2.st_mode));
+  ASSERT (func ("/", &st1) == 0);
+  ASSERT (func ("///", &st2) == 0);
+  ASSERT (SAME_INODE (st1, st2));
+  ASSERT (S_ISDIR (st1.st_mode));
+  ASSERT (S_ISDIR (st2.st_mode));
+  ASSERT (func ("..", &st1) == 0);
+  ASSERT (S_ISDIR (st1.st_mode));
+
+  /* Test for error conditions.  */
+  errno = 0;
+  ASSERT (func ("", &st1) == -1);
+  ASSERT (errno == ENOENT);
+  errno = 0;
+  ASSERT (func ("nosuch", &st1) == -1);
+  ASSERT (errno == ENOENT);
+  errno = 0;
+  ASSERT (func ("nosuch/", &st1) == -1);
+  ASSERT (errno == ENOENT);
+
+  ASSERT (close (creat (BASE "file", 0600)) == 0);
+  ASSERT (func (BASE "file", &st1) == 0);
+  ASSERT (S_ISREG (st1.st_mode));
+  errno = 0;
+  ASSERT (func (BASE "file/", &st1) == -1);
+  ASSERT (errno == ENOTDIR);
+
+  /* Now for some symlink tests, where supported.  We set up:
+     link1 -> directory
+     link2 -> file
+     link3 -> dangling
+     link4 -> loop
+     then test behavior both with and without trailing slash.
+  */
+  if (symlink (".", BASE "link1") != 0)
+    {
+      ASSERT (unlink (BASE "file") == 0);
+      if (print)
+        fputs ("skipping test: symlinks not supported on this file system\n",
+               stderr);
+      return 77;
+    }
+  ASSERT (symlink (BASE "file", BASE "link2") == 0);
+  ASSERT (symlink (BASE "nosuch", BASE "link3") == 0);
+  ASSERT (symlink (BASE "link4", BASE "link4") == 0);
+
+  ASSERT (func (BASE "link1", &st1) == 0);
+  ASSERT (S_ISLNK (st1.st_mode));
+  ASSERT (func (BASE "link1/", &st1) == 0);
+  ASSERT (stat (BASE "link1", &st2) == 0);
+  ASSERT (S_ISDIR (st1.st_mode));
+  ASSERT (S_ISDIR (st2.st_mode));
+  ASSERT (SAME_INODE (st1, st2));
+
+  ASSERT (func (BASE "link2", &st1) == 0);
+  ASSERT (S_ISLNK (st1.st_mode));
+  errno = 0;
+  ASSERT (func (BASE "link2/", &st1) == -1);
+  ASSERT (errno == ENOTDIR);
+
+  ASSERT (func (BASE "link3", &st1) == 0);
+  ASSERT (S_ISLNK (st1.st_mode));
+  errno = 0;
+  ASSERT (func (BASE "link3/", &st1) == -1);
+  ASSERT (errno == ENOENT);
+
+  ASSERT (func (BASE "link4", &st1) == 0);
+  ASSERT (S_ISLNK (st1.st_mode));
+  errno = 0;
+  ASSERT (func (BASE "link4/", &st1) == -1);
+  ASSERT (errno == ELOOP);
+
+  /* Cleanup.  */
+  ASSERT (unlink (BASE "file") == 0);
+  ASSERT (unlink (BASE "link1") == 0);
+  ASSERT (unlink (BASE "link2") == 0);
+  ASSERT (unlink (BASE "link3") == 0);
+  ASSERT (unlink (BASE "link4") == 0);
+
+  return 0;
+}
diff --git a/libmissing/tests/test-open.c b/libmissing/tests/test-open.c
new file mode 100644
index 0000000..ae9b3ac
--- /dev/null
+++ b/libmissing/tests/test-open.c
@@ -0,0 +1,41 @@
+/* Test of opening a file descriptor.
+   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 Bruno Haible <[email protected]>, 2007.  */
+
+#include <config.h>
+
+#include <fcntl.h>
+
+#include "signature.h"
+SIGNATURE_CHECK (open, int, (char const *, int, ...));
+
+#include <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include "macros.h"
+
+#define BASE "test-open.t"
+
+#include "test-open.h"
+
+int
+main (void)
+{
+  return test_open (open, true);
+}
diff --git a/libmissing/tests/test-open.h b/libmissing/tests/test-open.h
new file mode 100644
index 0000000..6341a63
--- /dev/null
+++ b/libmissing/tests/test-open.h
@@ -0,0 +1,87 @@
+/* Test of opening a file descriptor.
+   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 Bruno Haible <[email protected]>, 2007.  */
+
+/* This file is designed to test both open(n,buf[,mode]) and
+   openat(AT_FDCWD,n,buf[,mode]).  FUNC is the function to test.
+   Assumes that BASE and ASSERT are already defined, and that
+   appropriate headers are already included.  If PRINT, warn before
+   skipping symlink tests with status 77.  */
+
+static int
+test_open (int (*func) (char const *, int, ...), bool print)
+{
+  int fd;
+  /* Remove anything from prior partial run.  */
+  unlink (BASE "file");
+
+  /* Cannot create directory.  */
+  errno = 0;
+  ASSERT (func ("nonexist.ent/", O_CREAT | O_RDONLY, 0600) == -1);
+  ASSERT (errno == ENOTDIR || errno == EISDIR || errno == ENOENT
+          || errno == EINVAL);
+
+  /* Create a regular file.  */
+  fd = func (BASE "file", O_CREAT | O_RDONLY, 0600);
+  ASSERT (0 <= fd);
+  ASSERT (close (fd) == 0);
+
+  /* Trailing slash handling.  */
+  errno = 0;
+  ASSERT (func (BASE "file/", O_RDONLY) == -1);
+  ASSERT (errno == ENOTDIR || errno == EISDIR || errno == EINVAL);
+
+  /* Directories cannot be opened for writing.  */
+  errno = 0;
+  ASSERT (func (".", O_WRONLY) == -1);
+  ASSERT (errno == EISDIR || errno == EACCES);
+
+  /* /dev/null must exist, and be writable.  */
+  fd = func ("/dev/null", O_RDONLY);
+  ASSERT (0 <= fd);
+  {
+    char c;
+    ASSERT (read (fd, &c, 1) == 0);
+  }
+  ASSERT (close (fd) == 0);
+  fd = func ("/dev/null", O_WRONLY);
+  ASSERT (0 <= fd);
+  ASSERT (write (fd, "c", 1) == 1);
+  ASSERT (close (fd) == 0);
+
+  /* Symlink handling, where supported.  */
+  if (symlink (BASE "file", BASE "link") != 0)
+    {
+      ASSERT (unlink (BASE "file") == 0);
+      if (print)
+        fputs ("skipping test: symlinks not supported on this file system\n",
+               stderr);
+      return 77;
+    }
+  errno = 0;
+  ASSERT (func (BASE "link/", O_RDONLY) == -1);
+  ASSERT (errno == ENOTDIR);
+  fd = func (BASE "link", O_RDONLY);
+  ASSERT (0 <= fd);
+  ASSERT (close (fd) == 0);
+
+  /* Cleanup.  */
+  ASSERT (unlink (BASE "file") == 0);
+  ASSERT (unlink (BASE "link") == 0);
+
+  return 0;
+}
diff --git a/libmissing/tests/test-stat.c b/libmissing/tests/test-stat.c
new file mode 100644
index 0000000..05dd375
--- /dev/null
+++ b/libmissing/tests/test-stat.c
@@ -0,0 +1,56 @@
+/* Tests of stat.
+   Copyright (C) 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 Eric Blake <[email protected]>, 2009.  */
+
+#include <config.h>
+
+#include <sys/stat.h>
+
+/* Caution: stat may be a function-like macro.  Although this
+   signature check must pass, it may be the signature of the real (and
+   broken) stat rather than rpl_stat.  Most code should not use the
+   address of stat.  */
+#include "signature.h"
+SIGNATURE_CHECK (stat, int, (char const *, struct stat *));
+
+#include <fcntl.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include "pathmax.h"
+#include "same-inode.h"
+#include "macros.h"
+
+#define BASE "test-stat.t"
+
+#include "test-stat.h"
+
+/* Wrapper around stat, which works even if stat is a function-like
+   macro, where test_stat_func(stat) would do the wrong thing.  */
+static int
+do_stat (char const *name, struct stat *st)
+{
+  return stat (name, st);
+}
+
+int
+main (void)
+{
+  return test_stat_func (do_stat, true);
+}
diff --git a/libmissing/tests/test-stat.h b/libmissing/tests/test-stat.h
new file mode 100644
index 0000000..f090420
--- /dev/null
+++ b/libmissing/tests/test-stat.h
@@ -0,0 +1,100 @@
+/* Tests of stat.
+   Copyright (C) 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 Eric Blake <[email protected]>, 2009.  */
+
+/* This file is designed to test both stat(n,buf) and
+   fstatat(AT_FDCWD,n,buf,0).  FUNC is the function to test.  Assumes
+   that BASE and ASSERT are already defined, and that appropriate
+   headers are already included.  If PRINT, warn before skipping
+   symlink tests with status 77.  */
+
+static int
+test_stat_func (int (*func) (char const *, struct stat *), bool print)
+{
+  struct stat st1;
+  struct stat st2;
+  char cwd[PATH_MAX];
+
+  ASSERT (getcwd (cwd, PATH_MAX) == cwd);
+  ASSERT (func (".", &st1) == 0);
+  ASSERT (func ("./", &st2) == 0);
+  ASSERT (SAME_INODE (st1, st2));
+  ASSERT (func (cwd, &st2) == 0);
+  ASSERT (SAME_INODE (st1, st2));
+  ASSERT (func ("/", &st1) == 0);
+  ASSERT (func ("///", &st2) == 0);
+  ASSERT (SAME_INODE (st1, st2));
+
+  errno = 0;
+  ASSERT (func ("", &st1) == -1);
+  ASSERT (errno == ENOENT);
+  errno = 0;
+  ASSERT (func ("nosuch", &st1) == -1);
+  ASSERT (errno == ENOENT);
+  errno = 0;
+  ASSERT (func ("nosuch/", &st1) == -1);
+  ASSERT (errno == ENOENT);
+
+  ASSERT (close (creat (BASE "file", 0600)) == 0);
+  ASSERT (func (BASE "file", &st1) == 0);
+  errno = 0;
+  ASSERT (func (BASE "file/", &st1) == -1);
+  ASSERT (errno == ENOTDIR);
+
+  /* Now for some symlink tests, where supported.  We set up:
+     link1 -> directory
+     link2 -> file
+     link3 -> dangling
+     link4 -> loop
+     then test behavior with trailing slash.
+  */
+  if (symlink (".", BASE "link1") != 0)
+    {
+      ASSERT (unlink (BASE "file") == 0);
+      if (print)
+        fputs ("skipping test: symlinks not supported on this file system\n",
+               stderr);
+      return 77;
+    }
+  ASSERT (symlink (BASE "file", BASE "link2") == 0);
+  ASSERT (symlink (BASE "nosuch", BASE "link3") == 0);
+  ASSERT (symlink (BASE "link4", BASE "link4") == 0);
+
+  ASSERT (func (BASE "link1/", &st1) == 0);
+  ASSERT (S_ISDIR (st1.st_mode));
+
+  errno = 0;
+  ASSERT (func (BASE "link2/", &st1) == -1);
+  ASSERT (errno == ENOTDIR);
+
+  errno = 0;
+  ASSERT (func (BASE "link3/", &st1) == -1);
+  ASSERT (errno == ENOENT);
+
+  errno = 0;
+  ASSERT (func (BASE "link4/", &st1) == -1);
+  ASSERT (errno == ELOOP);
+
+  /* Cleanup.  */
+  ASSERT (unlink (BASE "file") == 0);
+  ASSERT (unlink (BASE "link1") == 0);
+  ASSERT (unlink (BASE "link2") == 0);
+  ASSERT (unlink (BASE "link3") == 0);
+  ASSERT (unlink (BASE "link4") == 0);
+
+  return 0;
+}
diff --git a/libmissing/tests/test-stddef.c b/libmissing/tests/test-stddef.c
new file mode 100644
index 0000000..d047e57
--- /dev/null
+++ b/libmissing/tests/test-stddef.c
@@ -0,0 +1,38 @@
+/* Test of <stddef.h> substitute.
+   Copyright (C) 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 Eric Blake <[email protected]>, 2009.  */
+
+#include <config.h>
+
+#include <stddef.h>
+
+#include "verify.h"
+
+/* Check that appropriate types are defined.  */
+wchar_t a = 'c';
+ptrdiff_t b = 1;
+size_t c = 2;
+
+/* Check that NULL can be passed through varargs as a pointer type,
+   per POSIX 2008.  */
+verify (sizeof NULL == sizeof (void *));
+
+int
+main (void)
+{
+  return 0;
+}
diff --git a/libmissing/tests/test-symlink.c b/libmissing/tests/test-symlink.c
new file mode 100644
index 0000000..d2df54c
--- /dev/null
+++ b/libmissing/tests/test-symlink.c
@@ -0,0 +1,47 @@
+/* Tests of symlink.
+   Copyright (C) 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 Eric Blake <[email protected]>, 2009.  */
+
+#include <config.h>
+
+#include <unistd.h>
+
+#include "signature.h"
+SIGNATURE_CHECK (symlink, int, (char const *, char const *));
+
+#include <fcntl.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+
+#include "ignore-value.h"
+#include "macros.h"
+
+#define BASE "test-symlink.t"
+
+#include "test-symlink.h"
+
+int
+main (void)
+{
+  /* Remove any leftovers from a previous partial run.  */
+  ignore_value (system ("rm -rf " BASE "*"));
+
+  return test_symlink (symlink, true);
+}
diff --git a/libmissing/tests/test-symlink.h b/libmissing/tests/test-symlink.h
new file mode 100644
index 0000000..0c92bd4
--- /dev/null
+++ b/libmissing/tests/test-symlink.h
@@ -0,0 +1,95 @@
+/* Tests of symlink.
+   Copyright (C) 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 Eric Blake <[email protected]>, 2009.  */
+
+/* This file is designed to test both symlink(a,b) and
+   symlinkat(a,AT_FDCWD,b).  FUNC is the function to test.  Assumes
+   that BASE and ASSERT are already defined, and that appropriate
+   headers are already included.  If PRINT, warn before skipping
+   symlink tests with status 77.  */
+
+static int
+test_symlink (int (*func) (char const *, char const *), bool print)
+{
+  if (func ("nowhere", BASE "link1"))
+    {
+      if (print)
+        fputs ("skipping test: symlinks not supported on this file system\n",
+               stderr);
+      return 77;
+    }
+
+  /* Some systems allow the creation of 0-length symlinks as a synonym
+     for "."; but most reject it.  */
+  {
+    int status;
+    errno = 0;
+    status = func ("", BASE "link2");
+    if (status == -1)
+      ASSERT (errno == ENOENT || errno == EINVAL);
+    else
+      {
+        ASSERT (status == 0);
+        ASSERT (unlink (BASE "link2") == 0);
+      }
+  }
+
+  /* Sanity checks of failures.  */
+  errno = 0;
+  ASSERT (func ("nowhere", "") == -1);
+  ASSERT (errno == ENOENT);
+  errno = 0;
+  ASSERT (func ("nowhere", ".") == -1);
+  ASSERT (errno == EEXIST || errno == EINVAL);
+  errno = 0;
+  ASSERT (func ("somewhere", BASE "link1") == -1);
+  ASSERT (errno == EEXIST);
+  errno = 0;
+  ASSERT (func ("nowhere", BASE "link2/") == -1);
+  ASSERT (errno == ENOTDIR || errno == ENOENT);
+  ASSERT (mkdir (BASE "dir", 0700) == 0);
+  errno = 0;
+  ASSERT (func ("nowhere", BASE "dir") == -1);
+  ASSERT (errno == EEXIST);
+  errno = 0;
+  ASSERT (func ("nowhere", BASE "dir/") == -1);
+  ASSERT (errno == EEXIST || errno == EINVAL);
+  ASSERT (close (creat (BASE "file", 0600)) == 0);
+  errno = 0;
+  ASSERT (func ("nowhere", BASE "file") == -1);
+  ASSERT (errno == EEXIST);
+  errno = 0;
+  ASSERT (func ("nowhere", BASE "file/") == -1);
+  ASSERT (errno == EEXIST || errno == ENOTDIR || errno == ENOENT);
+
+  /* Trailing slash must always be rejected.  */
+  ASSERT (unlink (BASE "link1") == 0);
+  ASSERT (func (BASE "link2", BASE "link1") == 0);
+  errno = 0;
+  ASSERT (func (BASE "nowhere", BASE "link1/") == -1);
+  ASSERT (errno == EEXIST || errno == ENOTDIR || errno == ENOENT);
+  errno = 0;
+  ASSERT (unlink (BASE "link2") == -1);
+  ASSERT (errno == ENOENT);
+
+  /* Cleanup.  */
+  ASSERT (rmdir (BASE "dir") == 0);
+  ASSERT (unlink (BASE "file") == 0);
+  ASSERT (unlink (BASE "link1") == 0);
+
+  return 0;
+}
diff --git a/libmissing/tests/test-sys_stat.c b/libmissing/tests/test-sys_stat.c
new file mode 100644
index 0000000..5f1aacd
--- /dev/null
+++ b/libmissing/tests/test-sys_stat.c
@@ -0,0 +1,288 @@
+/* Test of <sys/stat.h> substitute.
+   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 Bruno Haible <[email protected]>, 2007.  */
+
+#include <config.h>
+
+#include <sys/stat.h>
+
+#include "verify.h"
+
+/* Check the existence of some macros.  */
+int a[] =
+  {
+    S_IFMT,
+    S_IFBLK, S_IFCHR, S_IFDIR, S_IFIFO, S_IFREG,
+#ifdef S_IFLNK /* missing on mingw and djgpp */
+    S_IFLNK,
+#endif
+#ifdef S_IFSOCK /* missing on mingw and djgpp */
+    S_IFSOCK,
+#endif
+    S_IRWXU, S_IRUSR, S_IWUSR, S_IXUSR,
+    S_IRWXG, S_IRGRP, S_IWGRP, S_IXGRP,
+    S_IRWXO, S_IROTH, S_IWOTH, S_IXOTH,
+    S_ISUID, S_ISGID, S_ISVTX,
+    S_ISBLK (S_IFREG),
+    S_ISCHR (S_IFREG),
+    S_ISDIR (S_IFREG),
+    S_ISFIFO (S_IFREG),
+    S_ISREG (S_IFREG),
+    S_ISLNK (S_IFREG),
+    S_ISSOCK (S_IFREG),
+    S_ISDOOR (S_IFREG),
+    S_ISMPB (S_IFREG),
+    S_ISNAM (S_IFREG),
+    S_ISNWK (S_IFREG),
+    S_ISPORT (S_IFREG),
+    S_ISCTG (S_IFREG),
+    S_ISOFD (S_IFREG),
+    S_ISOFL (S_IFREG),
+    S_ISWHT (S_IFREG)
+  };
+
+/* Sanity checks.  */
+
+verify (S_IRWXU == (S_IRUSR | S_IWUSR | S_IXUSR));
+verify (S_IRWXG == (S_IRGRP | S_IWGRP | S_IXGRP));
+verify (S_IRWXO == (S_IROTH | S_IWOTH | S_IXOTH));
+
+verify (S_ISBLK (S_IFBLK));
+verify (!S_ISBLK (S_IFCHR));
+verify (!S_ISBLK (S_IFDIR));
+verify (!S_ISBLK (S_IFIFO));
+verify (!S_ISBLK (S_IFREG));
+#ifdef S_IFLNK
+verify (!S_ISBLK (S_IFLNK));
+#endif
+#ifdef S_IFSOCK
+verify (!S_ISBLK (S_IFSOCK));
+#endif
+
+verify (!S_ISCHR (S_IFBLK));
+verify (S_ISCHR (S_IFCHR));
+verify (!S_ISCHR (S_IFDIR));
+verify (!S_ISCHR (S_IFIFO));
+verify (!S_ISCHR (S_IFREG));
+#ifdef S_IFLNK
+verify (!S_ISCHR (S_IFLNK));
+#endif
+#ifdef S_IFSOCK
+verify (!S_ISCHR (S_IFSOCK));
+#endif
+
+verify (!S_ISDIR (S_IFBLK));
+verify (!S_ISDIR (S_IFCHR));
+verify (S_ISDIR (S_IFDIR));
+verify (!S_ISDIR (S_IFIFO));
+verify (!S_ISDIR (S_IFREG));
+#ifdef S_IFLNK
+verify (!S_ISDIR (S_IFLNK));
+#endif
+#ifdef S_IFSOCK
+verify (!S_ISDIR (S_IFSOCK));
+#endif
+
+verify (!S_ISFIFO (S_IFBLK));
+verify (!S_ISFIFO (S_IFCHR));
+verify (!S_ISFIFO (S_IFDIR));
+verify (S_ISFIFO (S_IFIFO));
+verify (!S_ISFIFO (S_IFREG));
+#ifdef S_IFLNK
+verify (!S_ISFIFO (S_IFLNK));
+#endif
+#ifdef S_IFSOCK
+verify (!S_ISFIFO (S_IFSOCK));
+#endif
+
+verify (!S_ISREG (S_IFBLK));
+verify (!S_ISREG (S_IFCHR));
+verify (!S_ISREG (S_IFDIR));
+verify (!S_ISREG (S_IFIFO));
+verify (S_ISREG (S_IFREG));
+#ifdef S_IFLNK
+verify (!S_ISREG (S_IFLNK));
+#endif
+#ifdef S_IFSOCK
+verify (!S_ISREG (S_IFSOCK));
+#endif
+
+verify (!S_ISLNK (S_IFBLK));
+verify (!S_ISLNK (S_IFCHR));
+verify (!S_ISLNK (S_IFDIR));
+verify (!S_ISLNK (S_IFIFO));
+verify (!S_ISLNK (S_IFREG));
+#ifdef S_IFLNK
+verify (S_ISLNK (S_IFLNK));
+#endif
+#ifdef S_IFSOCK
+verify (!S_ISLNK (S_IFSOCK));
+#endif
+
+verify (!S_ISSOCK (S_IFBLK));
+verify (!S_ISSOCK (S_IFCHR));
+verify (!S_ISSOCK (S_IFDIR));
+verify (!S_ISSOCK (S_IFIFO));
+verify (!S_ISSOCK (S_IFREG));
+#ifdef S_IFLNK
+verify (!S_ISSOCK (S_IFLNK));
+#endif
+#ifdef S_IFSOCK
+verify (S_ISSOCK (S_IFSOCK));
+#endif
+
+verify (!S_ISDOOR (S_IFBLK));
+verify (!S_ISDOOR (S_IFCHR));
+verify (!S_ISDOOR (S_IFDIR));
+verify (!S_ISDOOR (S_IFIFO));
+verify (!S_ISDOOR (S_IFREG));
+#ifdef S_IFLNK
+verify (!S_ISDOOR (S_IFLNK));
+#endif
+#ifdef S_IFSOCK
+verify (!S_ISDOOR (S_IFSOCK));
+#endif
+
+verify (!S_ISMPB (S_IFBLK));
+verify (!S_ISMPB (S_IFCHR));
+verify (!S_ISMPB (S_IFDIR));
+verify (!S_ISMPB (S_IFIFO));
+verify (!S_ISMPB (S_IFREG));
+#ifdef S_IFLNK
+verify (!S_ISMPB (S_IFLNK));
+#endif
+#ifdef S_IFSOCK
+verify (!S_ISMPB (S_IFSOCK));
+#endif
+
+verify (!S_ISNAM (S_IFBLK));
+verify (!S_ISNAM (S_IFCHR));
+verify (!S_ISNAM (S_IFDIR));
+verify (!S_ISNAM (S_IFIFO));
+verify (!S_ISNAM (S_IFREG));
+#ifdef S_IFLNK
+verify (!S_ISNAM (S_IFLNK));
+#endif
+#ifdef S_IFSOCK
+verify (!S_ISNAM (S_IFSOCK));
+#endif
+
+verify (!S_ISNWK (S_IFBLK));
+verify (!S_ISNWK (S_IFCHR));
+verify (!S_ISNWK (S_IFDIR));
+verify (!S_ISNWK (S_IFIFO));
+verify (!S_ISNWK (S_IFREG));
+#ifdef S_IFLNK
+verify (!S_ISNWK (S_IFLNK));
+#endif
+#ifdef S_IFSOCK
+verify (!S_ISNWK (S_IFSOCK));
+#endif
+
+verify (!S_ISPORT (S_IFBLK));
+verify (!S_ISPORT (S_IFCHR));
+verify (!S_ISPORT (S_IFDIR));
+verify (!S_ISPORT (S_IFIFO));
+verify (!S_ISPORT (S_IFREG));
+#ifdef S_IFLNK
+verify (!S_ISPORT (S_IFLNK));
+#endif
+#ifdef S_IFSOCK
+verify (!S_ISPORT (S_IFSOCK));
+#endif
+
+verify (!S_ISCTG (S_IFBLK));
+verify (!S_ISCTG (S_IFCHR));
+verify (!S_ISCTG (S_IFDIR));
+verify (!S_ISCTG (S_IFIFO));
+verify (!S_ISCTG (S_IFREG));
+#ifdef S_IFLNK
+verify (!S_ISCTG (S_IFLNK));
+#endif
+#ifdef S_IFSOCK
+verify (!S_ISCTG (S_IFSOCK));
+#endif
+
+verify (!S_ISOFD (S_IFBLK));
+verify (!S_ISOFD (S_IFCHR));
+verify (!S_ISOFD (S_IFDIR));
+verify (!S_ISOFD (S_IFIFO));
+verify (!S_ISOFD (S_IFREG));
+#ifdef S_IFLNK
+verify (!S_ISOFD (S_IFLNK));
+#endif
+#ifdef S_IFSOCK
+verify (!S_ISOFD (S_IFSOCK));
+#endif
+
+verify (!S_ISOFL (S_IFBLK));
+verify (!S_ISOFL (S_IFCHR));
+verify (!S_ISOFL (S_IFDIR));
+verify (!S_ISOFL (S_IFIFO));
+verify (!S_ISOFL (S_IFREG));
+#ifdef S_IFLNK
+verify (!S_ISOFL (S_IFLNK));
+#endif
+#ifdef S_IFSOCK
+verify (!S_ISOFL (S_IFSOCK));
+#endif
+
+verify (!S_ISWHT (S_IFBLK));
+verify (!S_ISWHT (S_IFCHR));
+verify (!S_ISWHT (S_IFDIR));
+verify (!S_ISWHT (S_IFIFO));
+verify (!S_ISWHT (S_IFREG));
+#ifdef S_IFLNK
+verify (!S_ISWHT (S_IFLNK));
+#endif
+#ifdef S_IFSOCK
+verify (!S_ISWHT (S_IFSOCK));
+#endif
+
+/* POSIX 2008 requires traditional encoding of permission constants.  */
+verify (S_IRWXU == 00700);
+verify (S_IRUSR == 00400);
+verify (S_IWUSR == 00200);
+verify (S_IXUSR == 00100);
+verify (S_IRWXG == 00070);
+verify (S_IRGRP == 00040);
+verify (S_IWGRP == 00020);
+verify (S_IXGRP == 00010);
+verify (S_IRWXO == 00007);
+verify (S_IROTH == 00004);
+verify (S_IWOTH == 00002);
+verify (S_IXOTH == 00001);
+verify (S_ISUID == 04000);
+verify (S_ISGID == 02000);
+verify (S_ISVTX == 01000);
+
+#if ((0 <= UTIME_NOW && UTIME_NOW < 1000000000)           \
+     || (0 <= UTIME_OMIT && UTIME_OMIT < 1000000000)      \
+     || UTIME_NOW == UTIME_OMIT)
+invalid UTIME macros
+#endif
+
+/* Check the existence of some types.  */
+nlink_t t1;
+
+struct timespec t2;
+
+int
+main (void)
+{
+  return 0;
+}
_______________________________________________
Prelude-cvslog site list
[email protected]
http://lists.prelude-technologies.com/mailman/listinfo/prelude-cvslog