unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* nanosecond-resolution time stamps
@ 2011-07-01  6:59 Paul Eggert
  2011-07-01  8:14 ` [PATCH 1/7] gnulib substrate for ns-resolution " Paul Eggert
                   ` (7 more replies)
  0 siblings, 8 replies; 18+ messages in thread
From: Paul Eggert @ 2011-07-01  6:59 UTC (permalink / raw)
  To: Emacs Development

Emacs currently uses microsecond-resolution time stamps internally,
whereas GNU and similar operating systems have all gone to
nanosecond-resolution time stamps internally.  This mismatch leads to
problems, for example, Emacs mishandles file time stamps when it
copies them.  I have prepared a set of patches to fix this, and would
like them to be considered for Emacs 24 if possible or for a later
version if not.  I'll send them in other email messages shortly.

The basic idea of these patches is to add 3 digits to the time stamp
format.  For example, currently (current-time) might return
(19981 28208 421496); with the patches, it returns
(19981 28208 421496053) at exactly the same instant.  That is, the
last number of the Emacs internal time stamp now counts nanoseconds,
not microseconds.  (On older machines that do not support finegrained
time stamps the trailing digits are always 000.)

If we're on a 32-bit machine and the nanosecond count exceeds 2**29,
Emacs falls back on floating point to represent the out-of-range
integer.  (There is a similar problem, by the way, with the *first*
number being out of range for integers, on some platforms, and the
patches use the same solution there.)

This change to the internal time stamp format is an incompatible
change and might cause problems with external packages.  If you like,
it'd be easy to alter to the patch to use any other reasonable format.
For example, if you'd prefer the format (19981 28208 421496 053)
(i.e., the sub-microsecond count is appended), I could easily do that.
But I thought I'd get my current code out the door, for review.

(I'm sending this first message now, just a few nanoseconds before
June ends, since that's the cutoff for Emacs 24 changes....)



^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH 1/7] gnulib substrate for ns-resolution time stamps
  2011-07-01  6:59 nanosecond-resolution time stamps Paul Eggert
@ 2011-07-01  8:14 ` Paul Eggert
  2011-07-01 11:20   ` Eli Zaretskii
  2011-07-01  8:14 ` [PATCH 2/7] etc/NEWS patch " Paul Eggert
                   ` (6 subsequent siblings)
  7 siblings, 1 reply; 18+ messages in thread
From: Paul Eggert @ 2011-07-01  8:14 UTC (permalink / raw)
  To: Emacs Development

This is build boilerplate; it's all automatically generated
or copied from gnulib.  It's probably of interest only to those
concerned with porting to Windows.

Prepare to add support for nanosecond-resolution time stamps.
This contains just the automatically-generated stuff from gnulib;
a later patch will contain the more-interesting stuff.
* lib/dtotimespec.c, lib/errno.in.h, lib/gettime.c:
* lib/gettimeofday.c, lib/pselect.c, lib/stat-time.h, lib/strtoll.c:
* lib/sys_select.in.h, lib/sys_time.in.h, lib/timespec-add.c:
* lib/timespec-sub.c, lib/timespec.h, lib/utimens.c, lib/utimens.h:
* m4/clock_time.m4, m4/errno_h.m4, m4/gettime.m4, m4/gettimeofday.m4:
* m4/pselect.m4, m4/stat-time.m4, m4/strtoimax.m4, m4/strtoll.m4:
* m4/sys_select_h.m4, m4/sys_socket_h.m4, m4/sys_time_h.m4:
* m4/timespec.m4, m4/utimbuf.m4, m4/utimens.m4, m4/utimes.m4:
New files, copied automatically from gnulib.
* lib/gnulib.mk, m4/gl-comp.m4: Merge from gnulib.
=== added file 'lib/dtotimespec.c'
--- lib/dtotimespec.c	1970-01-01 00:00:00 +0000
+++ lib/dtotimespec.c	2011-07-01 05:43:27 +0000
@@ -0,0 +1,69 @@
+/* Convert double to timespec.
+
+   Copyright (C) 2011 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 Paul Eggert */
+
+/* Convert the double value SEC to a struct timespec.  Round toward
+   positive infinity.  On overflow, return an extremal value.  */
+
+#include <config.h>
+
+#include "timespec.h"
+
+#include "intprops.h"
+
+struct timespec
+dtotimespec (double sec)
+{
+  enum { BILLION = 1000 * 1000 * 1000 };
+  double min_representable = TYPE_MINIMUM (time_t);
+  double max_representable =
+    ((TYPE_MAXIMUM (time_t) * (double) BILLION + (BILLION - 1))
+     / BILLION);
+  struct timespec r;
+
+  if (! (min_representable < sec))
+    {
+      r.tv_sec = TYPE_MINIMUM (time_t);
+      r.tv_nsec = 0;
+    }
+  else if (! (sec < max_representable))
+    {
+      r.tv_sec = TYPE_MAXIMUM (time_t);
+      r.tv_nsec = BILLION - 1;
+    }
+  else
+    {
+      time_t s = sec;
+      double frac = BILLION * (sec - s);
+      long ns = frac;
+      ns += ns < frac;
+      s += ns / BILLION;
+      ns %= BILLION;
+
+      if (ns < 0)
+        {
+          s--;
+          ns += BILLION;
+        }
+
+      r.tv_sec = s;
+      r.tv_nsec = ns;
+    }
+
+  return r;
+}

=== added file 'lib/errno.in.h'
--- lib/errno.in.h	1970-01-01 00:00:00 +0000
+++ lib/errno.in.h	2011-07-01 05:43:27 +0000
@@ -0,0 +1,167 @@
+/* A POSIX-like <errno.h>.
+
+   Copyright (C) 2008-2011 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+#ifndef _@GUARD_PREFIX@_ERRNO_H
+
+#if __GNUC__ >= 3
+@PRAGMA_SYSTEM_HEADER@
+#endif
+@PRAGMA_COLUMNS@
+
+/* The include_next requires a split double-inclusion guard.  */
+#@INCLUDE_NEXT@ @NEXT_ERRNO_H@
+
+#ifndef _@GUARD_PREFIX@_ERRNO_H
+#define _@GUARD_PREFIX@_ERRNO_H
+
+
+/* On native Windows platforms, many macros are not defined.  */
+# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+
+/* POSIX says that EAGAIN and EWOULDBLOCK may have the same value.  */
+#  define EWOULDBLOCK     EAGAIN
+
+/* Values >= 100 seem safe to use.  */
+#  define ETXTBSY   100
+#  define GNULIB_defined_ETXTBSY 1
+
+/* These are intentionally the same values as the WSA* error numbers, defined
+   in <winsock2.h>.  */
+#  define EINPROGRESS     10036
+#  define EALREADY        10037
+#  define ENOTSOCK        10038
+#  define EDESTADDRREQ    10039
+#  define EMSGSIZE        10040
+#  define EPROTOTYPE      10041
+#  define ENOPROTOOPT     10042
+#  define EPROTONOSUPPORT 10043
+#  define ESOCKTNOSUPPORT 10044  /* not required by POSIX */
+#  define EOPNOTSUPP      10045
+#  define EPFNOSUPPORT    10046  /* not required by POSIX */
+#  define EAFNOSUPPORT    10047
+#  define EADDRINUSE      10048
+#  define EADDRNOTAVAIL   10049
+#  define ENETDOWN        10050
+#  define ENETUNREACH     10051
+#  define ENETRESET       10052
+#  define ECONNABORTED    10053
+#  define ECONNRESET      10054
+#  define ENOBUFS         10055
+#  define EISCONN         10056
+#  define ENOTCONN        10057
+#  define ESHUTDOWN       10058  /* not required by POSIX */
+#  define ETOOMANYREFS    10059  /* not required by POSIX */
+#  define ETIMEDOUT       10060
+#  define ECONNREFUSED    10061
+#  define ELOOP           10062
+#  define EHOSTDOWN       10064  /* not required by POSIX */
+#  define EHOSTUNREACH    10065
+#  define EPROCLIM        10067  /* not required by POSIX */
+#  define EUSERS          10068  /* not required by POSIX */
+#  define EDQUOT          10069
+#  define ESTALE          10070
+#  define EREMOTE         10071  /* not required by POSIX */
+#  define GNULIB_defined_ESOCK 1
+
+# endif
+
+
+/* On OSF/1 5.1, when _XOPEN_SOURCE_EXTENDED is not defined, the macros
+   EMULTIHOP, ENOLINK, EOVERFLOW are not defined.  */
+# if @EMULTIHOP_HIDDEN@
+#  define EMULTIHOP @EMULTIHOP_VALUE@
+#  define GNULIB_defined_EMULTIHOP 1
+# endif
+# if @ENOLINK_HIDDEN@
+#  define ENOLINK   @ENOLINK_VALUE@
+#  define GNULIB_defined_ENOLINK 1
+# endif
+# if @EOVERFLOW_HIDDEN@
+#  define EOVERFLOW @EOVERFLOW_VALUE@
+#  define GNULIB_defined_EOVERFLOW 1
+# endif
+
+
+/* On OpenBSD 4.0 and on native Windows, the macros ENOMSG, EIDRM, ENOLINK,
+   EPROTO, EMULTIHOP, EBADMSG, EOVERFLOW, ENOTSUP, ECANCELED are not defined.
+   Likewise, on NonStop Kernel, EDQUOT is not defined.
+   Define them here.  Values >= 2000 seem safe to use: Solaris ESTALE = 151,
+   HP-UX EWOULDBLOCK = 246, IRIX EDQUOT = 1133.
+
+   Note: When one of these systems defines some of these macros some day,
+   binaries will have to be recompiled so that they recognizes the new
+   errno values from the system.  */
+
+# ifndef ENOMSG
+#  define ENOMSG    2000
+#  define GNULIB_defined_ENOMSG 1
+# endif
+
+# ifndef EIDRM
+#  define EIDRM     2001
+#  define GNULIB_defined_EIDRM 1
+# endif
+
+# ifndef ENOLINK
+#  define ENOLINK   2002
+#  define GNULIB_defined_ENOLINK 1
+# endif
+
+# ifndef EPROTO
+#  define EPROTO    2003
+#  define GNULIB_defined_EPROTO 1
+# endif
+
+# ifndef EMULTIHOP
+#  define EMULTIHOP 2004
+#  define GNULIB_defined_EMULTIHOP 1
+# endif
+
+# ifndef EBADMSG
+#  define EBADMSG   2005
+#  define GNULIB_defined_EBADMSG 1
+# endif
+
+# ifndef EOVERFLOW
+#  define EOVERFLOW 2006
+#  define GNULIB_defined_EOVERFLOW 1
+# endif
+
+# ifndef ENOTSUP
+#  define ENOTSUP   2007
+#  define GNULIB_defined_ENOTSUP 1
+# endif
+
+# ifndef ESTALE
+#  define ESTALE    2009
+#  define GNULIB_defined_ESTALE 1
+# endif
+
+# ifndef EDQUOT
+#  define EDQUOT 2010
+#  define GNULIB_defined_EDQUOT 1
+# endif
+
+# ifndef ECANCELED
+#  define ECANCELED 2008
+#  define GNULIB_defined_ECANCELED 1
+# endif
+
+
+#endif /* _@GUARD_PREFIX@_ERRNO_H */
+#endif /* _@GUARD_PREFIX@_ERRNO_H */

=== added file 'lib/gettime.c'
--- lib/gettime.c	1970-01-01 00:00:00 +0000
+++ lib/gettime.c	2011-07-01 05:43:27 +0000
@@ -0,0 +1,48 @@
+/* gettime -- get the system clock
+
+   Copyright (C) 2002, 2004-2007, 2009-2011 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 Paul Eggert.  */
+
+#include <config.h>
+
+#include "timespec.h"
+
+#include <sys/time.h>
+
+/* Get the system time into *TS.  */
+
+void
+gettime (struct timespec *ts)
+{
+#if HAVE_NANOTIME
+  nanotime (ts);
+#else
+
+# if defined CLOCK_REALTIME && HAVE_CLOCK_GETTIME
+  if (clock_gettime (CLOCK_REALTIME, ts) == 0)
+    return;
+# endif
+
+  {
+    struct timeval tv;
+    gettimeofday (&tv, NULL);
+    ts->tv_sec = tv.tv_sec;
+    ts->tv_nsec = tv.tv_usec * 1000;
+  }
+
+#endif
+}

=== added file 'lib/gettimeofday.c'
--- lib/gettimeofday.c	1970-01-01 00:00:00 +0000
+++ lib/gettimeofday.c	2011-07-01 05:43:27 +0000
@@ -0,0 +1,144 @@
+/* Provide gettimeofday for systems that don't have it or for which it's broken.
+
+   Copyright (C) 2001-2003, 2005-2007, 2009-2011 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+/* written by Jim Meyering */
+
+#include <config.h>
+
+/* Specification.  */
+#include <sys/time.h>
+
+#include <time.h>
+
+#if HAVE_SYS_TIMEB_H
+# include <sys/timeb.h>
+#endif
+
+#if GETTIMEOFDAY_CLOBBERS_LOCALTIME || TZSET_CLOBBERS_LOCALTIME
+
+/* Work around the bug in some systems whereby gettimeofday clobbers
+   the static buffer that localtime uses for its return value.  The
+   gettimeofday function from Mac OS X 10.0.4 (i.e., Darwin 1.3.7) has
+   this problem.  The tzset replacement is necessary for at least
+   Solaris 2.5, 2.5.1, and 2.6.  */
+
+static struct tm tm_zero_buffer;
+static struct tm *localtime_buffer_addr = &tm_zero_buffer;
+
+# undef localtime
+extern struct tm *localtime (time_t const *);
+
+# undef gmtime
+extern struct tm *gmtime (time_t const *);
+
+/* This is a wrapper for localtime.  It is used only on systems for which
+   gettimeofday clobbers the static buffer used for localtime's result.
+
+   On the first call, record the address of the static buffer that
+   localtime uses for its result.  */
+
+struct tm *
+rpl_localtime (time_t const *timep)
+{
+  struct tm *tm = localtime (timep);
+
+  if (localtime_buffer_addr == &tm_zero_buffer)
+    localtime_buffer_addr = tm;
+
+  return tm;
+}
+
+/* Same as above, since gmtime and localtime use the same buffer.  */
+struct tm *
+rpl_gmtime (time_t const *timep)
+{
+  struct tm *tm = gmtime (timep);
+
+  if (localtime_buffer_addr == &tm_zero_buffer)
+    localtime_buffer_addr = tm;
+
+  return tm;
+}
+
+#endif /* GETTIMEOFDAY_CLOBBERS_LOCALTIME || TZSET_CLOBBERS_LOCALTIME */
+
+#if TZSET_CLOBBERS_LOCALTIME
+
+# undef tzset
+extern void tzset (void);
+
+/* This is a wrapper for tzset, for systems on which tzset may clobber
+   the static buffer used for localtime's result.  */
+void
+rpl_tzset (void)
+{
+  /* Save and restore the contents of the buffer used for localtime's
+     result around the call to tzset.  */
+  struct tm save = *localtime_buffer_addr;
+  tzset ();
+  *localtime_buffer_addr = save;
+}
+#endif
+
+/* This is a wrapper for gettimeofday.  It is used only on systems
+   that lack this function, or whose implementation of this function
+   causes problems.  */
+
+int
+gettimeofday (struct timeval *restrict tv, void *restrict tz)
+{
+#undef gettimeofday
+#if HAVE_GETTIMEOFDAY
+# if GETTIMEOFDAY_CLOBBERS_LOCALTIME
+  /* Save and restore the contents of the buffer used for localtime's
+     result around the call to gettimeofday.  */
+  struct tm save = *localtime_buffer_addr;
+# endif
+
+  int result = gettimeofday (tv, (struct timezone *) tz);
+
+# if GETTIMEOFDAY_CLOBBERS_LOCALTIME
+  *localtime_buffer_addr = save;
+# endif
+
+  return result;
+
+#else
+
+# if HAVE__FTIME
+
+  struct _timeb timebuf;
+  _ftime (&timebuf);
+  tv->tv_sec = timebuf.time;
+  tv->tv_usec = timebuf.millitm * 1000;
+
+# else
+
+#  if !defined OK_TO_USE_1S_CLOCK
+#   error "Only 1-second nominal clock resolution found.  Is that intended?" \
+          "If so, compile with the -DOK_TO_USE_1S_CLOCK option."
+#  endif
+  tv->tv_sec = time (NULL);
+  tv->tv_usec = 0;
+
+# endif
+
+  return 0;
+
+#endif
+}

=== modified file 'lib/gnulib.mk'
--- lib/gnulib.mk	2011-06-25 08:40:38 +0000
+++ lib/gnulib.mk	2011-07-01 05:43:34 +0000
@@ -9,7 +9,7 @@
 # the same distribution terms as the rest of that program.
 #
 # Generated by gnulib-tool.
-# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=. --makefile-name=gnulib.mk --conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files alloca-opt careadlinkat crypto/md5 crypto/sha1 crypto/sha256 crypto/sha512 dtoastr dup2 filemode getloadavg getopt-gnu ignore-value intprops lstat mktime readlink socklen stdarg stdio strftime strtoumax symlink sys_stat
+# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=. --makefile-name=gnulib.mk --conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files alloca-opt careadlinkat crypto/md5 crypto/sha1 crypto/sha256 crypto/sha512 dtoastr dtotimespec dup2 filemode getloadavg getopt-gnu gettime gettimeofday ignore-value intprops lstat mktime pselect readlink socklen stat-time stdarg stdio strftime strtoimax strtoumax symlink sys_stat sys_time time timespec-add timespec-sub utimens


 MOSTLYCLEANFILES += core *.stackdump
@@ -159,6 +159,12 @@

 ## end   gnulib module dtoastr

+## begin gnulib module dtotimespec
+
+libgnu_a_SOURCES += dtotimespec.c
+
+## end   gnulib module dtotimespec
+
 ## begin gnulib module dup2


@@ -168,6 +174,40 @@

 ## end   gnulib module dup2

+## begin gnulib module errno
+
+BUILT_SOURCES += $(ERRNO_H)
+
+# We need the following in order to create <errno.h> when the system
+# doesn't have one that is POSIX compliant.
+if GL_GENERATE_ERRNO_H
+errno.h: errno.in.h $(top_builddir)/config.status
+	$(AM_V_GEN)rm -f $@-t $@ && \
+	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \
+	  sed -e 's|@''GUARD_PREFIX''@|GL|g' \
+	      -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
+	      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
+	      -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
+	      -e 's|@''NEXT_ERRNO_H''@|$(NEXT_ERRNO_H)|g' \
+	      -e 's|@''EMULTIHOP_HIDDEN''@|$(EMULTIHOP_HIDDEN)|g' \
+	      -e 's|@''EMULTIHOP_VALUE''@|$(EMULTIHOP_VALUE)|g' \
+	      -e 's|@''ENOLINK_HIDDEN''@|$(ENOLINK_HIDDEN)|g' \
+	      -e 's|@''ENOLINK_VALUE''@|$(ENOLINK_VALUE)|g' \
+	      -e 's|@''EOVERFLOW_HIDDEN''@|$(EOVERFLOW_HIDDEN)|g' \
+	      -e 's|@''EOVERFLOW_VALUE''@|$(EOVERFLOW_VALUE)|g' \
+	      < $(srcdir)/errno.in.h; \
+	} > $@-t && \
+	mv $@-t $@
+else
+errno.h: $(top_builddir)/config.status
+	rm -f $@
+endif
+MOSTLYCLEANFILES += errno.h errno.h-t
+
+EXTRA_DIST += errno.in.h
+
+## end   gnulib module errno
+
 ## begin gnulib module filemode

 libgnu_a_SOURCES += filemode.c
@@ -220,6 +260,21 @@
 endif
 ## end   gnulib module gettext-h

+## begin gnulib module gettime
+
+libgnu_a_SOURCES += gettime.c
+
+## end   gnulib module gettime
+
+## begin gnulib module gettimeofday
+
+
+EXTRA_DIST += gettimeofday.c
+
+EXTRA_libgnu_a_SOURCES += gettimeofday.c
+
+## end   gnulib module gettimeofday
+
 ## begin gnulib module ignore-value


@@ -294,6 +349,15 @@

 ## end   gnulib module mktime

+## begin gnulib module pselect
+
+
+EXTRA_DIST += pselect.c
+
+EXTRA_libgnu_a_SOURCES += pselect.c
+
+## end   gnulib module pselect
+
 ## begin gnulib module readlink


@@ -314,6 +378,13 @@

 ## end   gnulib module stat

+## begin gnulib module stat-time
+
+
+EXTRA_DIST += stat-time.h
+
+## end   gnulib module stat-time
+
 ## begin gnulib module stdarg

 BUILT_SOURCES += $(STDARG_H)
@@ -667,6 +738,26 @@

 ## end   gnulib module strftime

+## begin gnulib module strtoimax
+
+
+EXTRA_DIST += strtoimax.c
+
+EXTRA_libgnu_a_SOURCES += strtoimax.c
+
+## end   gnulib module strtoimax
+
+## begin gnulib module strtoll
+
+if gl_GNULIB_ENABLED_strtoll
+
+endif
+EXTRA_DIST += strtol.c strtoll.c
+
+EXTRA_libgnu_a_SOURCES += strtol.c strtoll.c
+
+## end   gnulib module strtoll
+
 ## begin gnulib module strtoull

 if gl_GNULIB_ENABLED_strtoull
@@ -696,6 +787,40 @@

 ## end   gnulib module symlink

+## begin gnulib module sys_select
+
+BUILT_SOURCES += sys/select.h
+
+# We need the following in order to create <sys/select.h> when the system
+# doesn't have one that works with the given compiler.
+sys/select.h: sys_select.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_ON_USE_H)
+	$(AM_V_at)$(MKDIR_P) sys
+	$(AM_V_GEN)rm -f $@-t $@ && \
+	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
+	  sed -e 's|@''GUARD_PREFIX''@|GL|g' \
+	      -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
+	      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
+	      -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
+	      -e 's|@''NEXT_SYS_SELECT_H''@|$(NEXT_SYS_SELECT_H)|g' \
+	      -e 's|@''HAVE_SYS_SELECT_H''@|$(HAVE_SYS_SELECT_H)|g' \
+	      -e 's/@''GNULIB_PSELECT''@/$(GNULIB_PSELECT)/g' \
+	      -e 's/@''GNULIB_SELECT''@/$(GNULIB_SELECT)/g' \
+	      -e 's|@''HAVE_WINSOCK2_H''@|$(HAVE_WINSOCK2_H)|g' \
+	      -e 's|@''HAVE_PSELECT''@|$(HAVE_PSELECT)|g' \
+	      -e 's|@''REPLACE_PSELECT''@|$(REPLACE_PSELECT)|g' \
+	      -e 's|@''REPLACE_SELECT''@|$(REPLACE_SELECT)|g' \
+	      -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
+	      -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \
+	      < $(srcdir)/sys_select.in.h; \
+	} > $@-t && \
+	mv $@-t $@
+MOSTLYCLEANFILES += sys/select.h sys/select.h-t
+MOSTLYCLEANDIRS += sys
+
+EXTRA_DIST += sys_select.in.h
+
+## end   gnulib module sys_select
+
 ## begin gnulib module sys_stat

 BUILT_SOURCES += sys/stat.h
@@ -756,6 +881,38 @@

 ## end   gnulib module sys_stat

+## begin gnulib module sys_time
+
+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 $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)
+	$(AM_V_at)$(MKDIR_P) sys
+	$(AM_V_GEN)rm -f $@-t $@ && \
+	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
+	  sed -e 's|@''GUARD_PREFIX''@|GL|g' \
+	      -e 's/@''HAVE_SYS_TIME_H''@/$(HAVE_SYS_TIME_H)/g' \
+	      -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
+	      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
+	      -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
+	      -e 's|@''NEXT_SYS_TIME_H''@|$(NEXT_SYS_TIME_H)|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 '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
+	      -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 $@
+MOSTLYCLEANFILES += sys/time.h sys/time.h-t
+
+EXTRA_DIST += sys_time.in.h
+
+## end   gnulib module sys_time
+
 ## begin gnulib module time

 BUILT_SOURCES += time.h
@@ -807,6 +964,25 @@

 ## end   gnulib module time_r

+## begin gnulib module timespec
+
+
+EXTRA_DIST += timespec.h
+
+## end   gnulib module timespec
+
+## begin gnulib module timespec-add
+
+libgnu_a_SOURCES += timespec-add.c
+
+## end   gnulib module timespec-add
+
+## begin gnulib module timespec-sub
+
+libgnu_a_SOURCES += timespec-sub.c
+
+## end   gnulib module timespec-sub
+
 ## begin gnulib module u64


@@ -952,6 +1128,14 @@

 ## end   gnulib module unistd

+## begin gnulib module utimens
+
+libgnu_a_SOURCES += utimens.c
+
+EXTRA_DIST += utimens.h
+
+## end   gnulib module utimens
+
 ## begin gnulib module verify

 if gl_GNULIB_ENABLED_verify

=== added file 'lib/pselect.c'
--- lib/pselect.c	1970-01-01 00:00:00 +0000
+++ lib/pselect.c	2011-07-01 05:43:27 +0000
@@ -0,0 +1,79 @@
+/* pselect - synchronous I/O multiplexing
+
+   Copyright 2011 Free Software Foundation, Inc.
+
+   This file is part of gnulib.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License along
+   with this program; if not, write to the Free Software Foundation,
+   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+/* written by Paul Eggert */
+
+#include <config.h>
+
+#include <sys/select.h>
+
+#include <errno.h>
+#include <signal.h>
+
+#undef pselect
+
+/* Examine the size-NFDS file descriptor sets in RFDS, WFDS, and XFDS
+   to see whether some of their descriptors are ready for reading,
+   ready for writing, or have exceptions pending.  Wait for at most
+   TIMEOUT seconds, and use signal mask SIGMASK while waiting.  A null
+   pointer parameter stands for no descriptors, an infinite timeout,
+   or an unaffected signal mask.  */
+
+int
+rpl_pselect (int nfds, fd_set *restrict rfds,
+             fd_set *restrict wfds, fd_set *restrict xfds,
+             struct timespec const *restrict timeout,
+             sigset_t const *restrict sigmask)
+{
+  int select_result;
+  sigset_t origmask;
+  struct timeval tv, *tvp;
+
+  if (timeout)
+    {
+      if (! (0 <= timeout->tv_nsec && timeout->tv_nsec < 1000000000))
+        {
+          errno = EINVAL;
+          return -1;
+        }
+
+      tv.tv_sec = timeout->tv_sec;
+      tv.tv_usec = (timeout->tv_nsec + 999) / 1000;
+      tvp = &tv;
+    }
+  else
+    tvp = NULL;
+
+  /* Signal mask munging should be atomic, but this is the best we can
+     do in this emulation.  */
+  if (sigmask)
+    sigprocmask (SIG_SETMASK, sigmask, &origmask);
+
+  select_result = select (nfds, rfds, wfds, xfds, tvp);
+
+  if (sigmask)
+    {
+      int select_errno = errno;
+      sigprocmask (SIG_SETMASK, &origmask, NULL);
+      errno = select_errno;
+    }
+
+  return select_result;
+}

=== added file 'lib/stat-time.h'
--- lib/stat-time.h	1970-01-01 00:00:00 +0000
+++ lib/stat-time.h	2011-07-01 05:43:28 +0000
@@ -0,0 +1,189 @@
+/* stat-related time functions.
+
+   Copyright (C) 2005, 2007, 2009-2011 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 Paul Eggert.  */
+
+#ifndef STAT_TIME_H
+#define STAT_TIME_H 1
+
+#include <sys/stat.h>
+#include <time.h>
+
+/* STAT_TIMESPEC (ST, ST_XTIM) is the ST_XTIM member for *ST of type
+   struct timespec, if available.  If not, then STAT_TIMESPEC_NS (ST,
+   ST_XTIM) is the nanosecond component of the ST_XTIM member for *ST,
+   if available.  ST_XTIM can be st_atim, st_ctim, st_mtim, or st_birthtim
+   for access, status change, data modification, or birth (creation)
+   time respectively.
+
+   These macros are private to stat-time.h.  */
+#if defined HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC
+# ifdef TYPEOF_STRUCT_STAT_ST_ATIM_IS_STRUCT_TIMESPEC
+#  define STAT_TIMESPEC(st, st_xtim) ((st)->st_xtim)
+# else
+#  define STAT_TIMESPEC_NS(st, st_xtim) ((st)->st_xtim.tv_nsec)
+# endif
+#elif defined HAVE_STRUCT_STAT_ST_ATIMESPEC_TV_NSEC
+# define STAT_TIMESPEC(st, st_xtim) ((st)->st_xtim##espec)
+#elif defined HAVE_STRUCT_STAT_ST_ATIMENSEC
+# define STAT_TIMESPEC_NS(st, st_xtim) ((st)->st_xtim##ensec)
+#elif defined HAVE_STRUCT_STAT_ST_ATIM_ST__TIM_TV_NSEC
+# define STAT_TIMESPEC_NS(st, st_xtim) ((st)->st_xtim.st__tim.tv_nsec)
+#endif
+
+/* Return the nanosecond component of *ST's access time.  */
+static inline long int
+get_stat_atime_ns (struct stat const *st)
+{
+# if defined STAT_TIMESPEC
+  return STAT_TIMESPEC (st, st_atim).tv_nsec;
+# elif defined STAT_TIMESPEC_NS
+  return STAT_TIMESPEC_NS (st, st_atim);
+# else
+  return 0;
+# endif
+}
+
+/* Return the nanosecond component of *ST's status change time.  */
+static inline long int
+get_stat_ctime_ns (struct stat const *st)
+{
+# if defined STAT_TIMESPEC
+  return STAT_TIMESPEC (st, st_ctim).tv_nsec;
+# elif defined STAT_TIMESPEC_NS
+  return STAT_TIMESPEC_NS (st, st_ctim);
+# else
+  return 0;
+# endif
+}
+
+/* Return the nanosecond component of *ST's data modification time.  */
+static inline long int
+get_stat_mtime_ns (struct stat const *st)
+{
+# if defined STAT_TIMESPEC
+  return STAT_TIMESPEC (st, st_mtim).tv_nsec;
+# elif defined STAT_TIMESPEC_NS
+  return STAT_TIMESPEC_NS (st, st_mtim);
+# else
+  return 0;
+# endif
+}
+
+/* Return the nanosecond component of *ST's birth time.  */
+static inline long int
+get_stat_birthtime_ns (struct stat const *st)
+{
+# if defined HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC
+  return STAT_TIMESPEC (st, st_birthtim).tv_nsec;
+# elif defined HAVE_STRUCT_STAT_ST_BIRTHTIMENSEC
+  return STAT_TIMESPEC_NS (st, st_birthtim);
+# else
+  /* Avoid a "parameter unused" warning.  */
+  (void) st;
+  return 0;
+# endif
+}
+
+/* Return *ST's access time.  */
+static inline struct timespec
+get_stat_atime (struct stat const *st)
+{
+#ifdef STAT_TIMESPEC
+  return STAT_TIMESPEC (st, st_atim);
+#else
+  struct timespec t;
+  t.tv_sec = st->st_atime;
+  t.tv_nsec = get_stat_atime_ns (st);
+  return t;
+#endif
+}
+
+/* Return *ST's status change time.  */
+static inline struct timespec
+get_stat_ctime (struct stat const *st)
+{
+#ifdef STAT_TIMESPEC
+  return STAT_TIMESPEC (st, st_ctim);
+#else
+  struct timespec t;
+  t.tv_sec = st->st_ctime;
+  t.tv_nsec = get_stat_ctime_ns (st);
+  return t;
+#endif
+}
+
+/* Return *ST's data modification time.  */
+static inline struct timespec
+get_stat_mtime (struct stat const *st)
+{
+#ifdef STAT_TIMESPEC
+  return STAT_TIMESPEC (st, st_mtim);
+#else
+  struct timespec t;
+  t.tv_sec = st->st_mtime;
+  t.tv_nsec = get_stat_mtime_ns (st);
+  return t;
+#endif
+}
+
+/* Return *ST's birth time, if available; otherwise return a value
+   with tv_sec and tv_nsec both equal to -1.  */
+static inline struct timespec
+get_stat_birthtime (struct stat const *st)
+{
+  struct timespec t;
+
+#if (defined HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC \
+     || defined HAVE_STRUCT_STAT_ST_BIRTHTIM_TV_NSEC)
+  t = STAT_TIMESPEC (st, st_birthtim);
+#elif defined HAVE_STRUCT_STAT_ST_BIRTHTIMENSEC
+  t.tv_sec = st->st_birthtime;
+  t.tv_nsec = st->st_birthtimensec;
+#elif (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+  /* Woe32 native platforms (but not Cygwin) put the "file creation
+     time" in st_ctime (!).  See
+     <http://msdn2.microsoft.com/de-de/library/14h5k7ff(VS.80).aspx>.  */
+  t.tv_sec = st->st_ctime;
+  t.tv_nsec = 0;
+#else
+  /* Birth time is not supported.  */
+  t.tv_sec = -1;
+  t.tv_nsec = -1;
+  /* Avoid a "parameter unused" warning.  */
+  (void) st;
+#endif
+
+#if (defined HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC \
+     || defined HAVE_STRUCT_STAT_ST_BIRTHTIM_TV_NSEC \
+     || defined HAVE_STRUCT_STAT_ST_BIRTHTIMENSEC)
+  /* FreeBSD and NetBSD sometimes signal the absence of knowledge by
+     using zero.  Attempt to work around this problem.  Alas, this can
+     report failure even for valid time stamps.  Also, NetBSD
+     sometimes returns junk in the birth time fields; work around this
+     bug if it is detected.  */
+  if (! (t.tv_sec && 0 <= t.tv_nsec && t.tv_nsec < 1000000000))
+    {
+      t.tv_sec = -1;
+      t.tv_nsec = -1;
+    }
+#endif
+
+  return t;
+}
+
+#endif

=== added file 'lib/strtoll.c'
--- lib/strtoll.c	1970-01-01 00:00:00 +0000
+++ lib/strtoll.c	2011-07-01 05:43:28 +0000
@@ -0,0 +1,33 @@
+/* Function to parse a `long long int' from text.
+   Copyright (C) 1995-1997, 1999, 2001, 2009-2011 Free Software Foundation,
+   Inc.
+   This file is part of the GNU C Library.
+
+   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/>.  */
+
+#define QUAD    1
+
+#include <strtol.c>
+
+#ifdef _LIBC
+# ifdef SHARED
+#  include <shlib-compat.h>
+
+#  if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2)
+compat_symbol (libc, __strtoll_internal, __strtoq_internal, GLIBC_2_0);
+#  endif
+
+# endif
+weak_alias (strtoll, strtoq)
+#endif

=== added file 'lib/sys_select.in.h'
--- lib/sys_select.in.h	1970-01-01 00:00:00 +0000
+++ lib/sys_select.in.h	2011-07-01 05:43:28 +0000
@@ -0,0 +1,159 @@
+/* Substitute for <sys/select.h>.
+   Copyright (C) 2007-2011 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+# if __GNUC__ >= 3
+@PRAGMA_SYSTEM_HEADER@
+# endif
+@PRAGMA_COLUMNS@
+
+/* On OSF/1, <sys/types.h> and <sys/time.h> include <sys/select.h>.
+   Simply delegate to the system's header in this case.  */
+#if @HAVE_SYS_SELECT_H@ && defined __osf__ && (defined _SYS_TYPES_H_ && !defined _GL_SYS_SELECT_H_REDIRECT_FROM_SYS_TYPES_H) && defined _OSF_SOURCE
+
+# define _GL_SYS_SELECT_H_REDIRECT_FROM_SYS_TYPES_H
+# @INCLUDE_NEXT@ @NEXT_SYS_SELECT_H@
+
+#elif @HAVE_SYS_SELECT_H@ && defined __osf__ && (defined _SYS_TIME_H_ && !defined _GL_SYS_SELECT_H_REDIRECT_FROM_SYS_TIME_H) && defined _OSF_SOURCE
+
+# define _GL_SYS_SELECT_H_REDIRECT_FROM_SYS_TIME_H
+# @INCLUDE_NEXT@ @NEXT_SYS_SELECT_H@
+
+#else
+
+#ifndef _@GUARD_PREFIX@_SYS_SELECT_H
+
+#if @HAVE_SYS_SELECT_H@
+
+/* On many platforms, <sys/select.h> assumes prior inclusion of
+   <sys/types.h>.  */
+# include <sys/types.h>
+
+/* On OSF/1 4.0, <sys/select.h> provides only a forward declaration
+   of 'struct timeval', and no definition of this type.
+   Also, MacOS X, AIX, HP-UX, IRIX, Solaris, Interix declare select()
+   in <sys/time.h>.
+   But avoid namespace pollution on glibc systems.  */
+# ifndef __GLIBC__
+#  include <sys/time.h>
+# endif
+
+/* On AIX 7 and Solaris 10, <sys/select.h> provides an FD_ZERO implementation
+   that relies on memset(), but without including <string.h>.
+   But in any case avoid namespace pollution on glibc systems.  */
+# if (defined __OpenBSD__ || defined _AIX || defined __sun || defined __osf__ || defined __BEOS__) \
+     && ! defined __GLIBC__
+#  include <string.h>
+# endif
+
+/* The include_next requires a split double-inclusion guard.  */
+# @INCLUDE_NEXT@ @NEXT_SYS_SELECT_H@
+
+#endif
+
+#ifndef _@GUARD_PREFIX@_SYS_SELECT_H
+#define _@GUARD_PREFIX@_SYS_SELECT_H
+
+#if !@HAVE_SYS_SELECT_H@
+/* A platform that lacks <sys/select.h>.  */
+/* Get the 'struct timeval' and 'fd_set' types and the FD_* macros
+   on most platforms.  */
+# include <sys/time.h>
+/* On HP-UX 11, <sys/time.h> provides an FD_ZERO implementation
+   that relies on memset(), but without including <string.h>.  */
+# if defined __hpux
+#  include <string.h>
+# endif
+/* On native Windows platforms:
+   Get the 'fd_set' type.  Also, gnulib's <sys/socket.h> redefines select
+   so as to hide the declaration from <winsock2.h>.  */
+# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+#  include <sys/socket.h>
+# endif
+#endif
+
+/* Get definition of 'sigset_t'.
+   But avoid namespace pollution on glibc systems.  */
+#if !(defined __GLIBC__ && !defined __UCLIBC__)
+# include <signal.h>
+#endif
+
+/* The definitions of _GL_FUNCDECL_RPL etc. are copied here.  */
+
+/* The definition of _GL_WARN_ON_USE is copied here.  */
+
+
+#if @GNULIB_PSELECT@
+# if @REPLACE_PSELECT@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef pselect
+#   define pselect rpl_pselect
+#  endif
+_GL_FUNCDECL_RPL (pselect, int,
+                  (int, fd_set *restrict, fd_set *restrict, fd_set *restrict,
+                   struct timespec const *restrict, const sigset_t *restrict));
+_GL_CXXALIAS_RPL (pselect, int,
+                  (int, fd_set *restrict, fd_set *restrict, fd_set *restrict,
+                   struct timespec const *restrict, const sigset_t *restrict));
+# else
+#  if !@HAVE_PSELECT@
+_GL_FUNCDECL_SYS (pselect, int,
+                  (int, fd_set *restrict, fd_set *restrict, fd_set *restrict,
+                   struct timespec const *restrict, const sigset_t *restrict));
+#  endif
+_GL_CXXALIAS_SYS (pselect, int,
+                  (int, fd_set *restrict, fd_set *restrict, fd_set *restrict,
+                   struct timespec const *restrict, const sigset_t *restrict));
+# endif
+_GL_CXXALIASWARN (pselect);
+#elif defined GNULIB_POSIXCHECK
+# undef pselect
+# if HAVE_RAW_DECL_PSELECT
+_GL_WARN_ON_USE (pselect, "pselect is not portable - "
+                 "use gnulib module pselect for portability");
+# endif
+#endif
+
+#if @GNULIB_SELECT@
+# if @REPLACE_SELECT@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef select
+#   define select rpl_select
+#  endif
+_GL_FUNCDECL_RPL (select, int,
+                  (int, fd_set *, fd_set *, fd_set *, struct timeval *));
+_GL_CXXALIAS_RPL (select, int,
+                  (int, fd_set *, fd_set *, fd_set *, struct timeval *));
+# else
+_GL_CXXALIAS_SYS (select, int,
+                  (int, fd_set *, fd_set *, fd_set *, struct timeval *));
+# endif
+_GL_CXXALIASWARN (select);
+#elif @HAVE_WINSOCK2_H@
+# undef select
+# define select select_used_without_requesting_gnulib_module_select
+#elif defined GNULIB_POSIXCHECK
+# undef select
+# if HAVE_RAW_DECL_SELECT
+_GL_WARN_ON_USE (select, "select is not always POSIX compliant - "
+                 "use gnulib module select for portability");
+# endif
+#endif
+
+
+#endif /* _@GUARD_PREFIX@_SYS_SELECT_H */
+#endif /* _@GUARD_PREFIX@_SYS_SELECT_H */
+#endif /* OSF/1 */

=== added file 'lib/sys_time.in.h'
--- lib/sys_time.in.h	1970-01-01 00:00:00 +0000
+++ lib/sys_time.in.h	2011-07-01 05:43:28 +0000
@@ -0,0 +1,101 @@
+/* Provide a more complete sys/time.h.
+
+   Copyright (C) 2007-2011 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+/* Written by Paul Eggert.  */
+
+#if __GNUC__ >= 3
+@PRAGMA_SYSTEM_HEADER@
+#endif
+@PRAGMA_COLUMNS@
+
+#if defined _@GUARD_PREFIX@_SYS_TIME_H
+
+/* Simply delegate to the system's header, without adding anything.  */
+# if @HAVE_SYS_TIME_H@
+#  @INCLUDE_NEXT@ @NEXT_SYS_TIME_H@
+# endif
+
+#else
+
+# define _@GUARD_PREFIX@_SYS_TIME_H
+
+# if @HAVE_SYS_TIME_H@
+#  @INCLUDE_NEXT@ @NEXT_SYS_TIME_H@
+# else
+#  include <time.h>
+# endif
+
+/* The definitions of _GL_FUNCDECL_RPL etc. are copied here.  */
+
+/* The definition of _GL_ARG_NONNULL is copied here.  */
+
+/* The definition of _GL_WARN_ON_USE is copied here.  */
+
+# ifdef __cplusplus
+extern "C" {
+# endif
+
+# if ! @HAVE_STRUCT_TIMEVAL@
+
+#  if !GNULIB_defined_struct_timeval
+struct timeval
+{
+  time_t tv_sec;
+  long int tv_usec;
+};
+#   define GNULIB_defined_struct_timeval 1
+#  endif
+
+# endif
+
+# ifdef __cplusplus
+}
+# endif
+
+# if @GNULIB_GETTIMEOFDAY@
+#  if @REPLACE_GETTIMEOFDAY@
+#   if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#    undef gettimeofday
+#    define gettimeofday rpl_gettimeofday
+#   endif
+_GL_FUNCDECL_RPL (gettimeofday, int,
+                  (struct timeval *restrict, void *restrict)
+                  _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (gettimeofday, int,
+                  (struct timeval *restrict, void *restrict));
+#  else
+#   if !@HAVE_GETTIMEOFDAY@
+_GL_FUNCDECL_SYS (gettimeofday, int,
+                  (struct timeval *restrict, void *restrict)
+                  _GL_ARG_NONNULL ((1)));
+#   endif
+/* Need to cast, because on glibc systems, by default, the second argument is
+                                                  struct timezone *.  */
+_GL_CXXALIAS_SYS_CAST (gettimeofday, int,
+                       (struct timeval *restrict, void *restrict));
+#  endif
+_GL_CXXALIASWARN (gettimeofday);
+# 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
+
+#endif /* _@GUARD_PREFIX@_SYS_TIME_H */

=== added file 'lib/timespec-add.c'
--- lib/timespec-add.c	1970-01-01 00:00:00 +0000
+++ lib/timespec-add.c	2011-07-01 05:43:28 +0000
@@ -0,0 +1,71 @@
+/* Add two struct timespec values.
+
+   Copyright (C) 2011 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 Paul Eggert.  */
+
+/* Return the sum of two timespec values A and B.  On overflow, return
+   an extremal value.  This assumes 0 <= tv_nsec <= 999999999.  */
+
+#include <config.h>
+#include "timespec.h"
+
+#include "intprops.h"
+
+struct timespec
+timespec_add (struct timespec a, struct timespec b)
+{
+  struct timespec r;
+  time_t rs = a.tv_sec;
+  time_t bs = b.tv_sec;
+  int ns = a.tv_nsec + b.tv_nsec;
+  int nsd = ns - 1000000000;
+  int rns = ns;
+
+  if (0 <= nsd)
+    {
+      rns = nsd;
+      if (rs == TYPE_MAXIMUM (time_t))
+        {
+          if (0 <= bs)
+            goto high_overflow;
+          bs++;
+        }
+      else
+        rs++;
+    }
+
+  if (INT_ADD_OVERFLOW (rs, bs))
+    {
+      if (rs < 0)
+        {
+          rs = TYPE_MINIMUM (time_t);
+          rns = 0;
+        }
+      else
+        {
+        high_overflow:
+          rs = TYPE_MAXIMUM (time_t);
+          rns = 999999999;
+        }
+    }
+  else
+    rs += bs;
+
+  r.tv_sec = rs;
+  r.tv_nsec = rns;
+  return r;
+}

=== added file 'lib/timespec-sub.c'
--- lib/timespec-sub.c	1970-01-01 00:00:00 +0000
+++ lib/timespec-sub.c	2011-07-01 05:43:28 +0000
@@ -0,0 +1,72 @@
+/* Subtract two struct timespec values.
+
+   Copyright (C) 2011 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 Paul Eggert.  */
+
+/* Return the difference between two timespec values A and B.  On
+   overflow, return an extremal value.  This assumes 0 <= tv_nsec <=
+   999999999.  */
+
+#include <config.h>
+#include <config.h>
+#include "timespec.h"
+
+#include "intprops.h"
+
+struct timespec
+timespec_sub (struct timespec a, struct timespec b)
+{
+  struct timespec r;
+  time_t rs = a.tv_sec;
+  time_t bs = b.tv_sec;
+  int ns = a.tv_nsec - b.tv_nsec;
+  int rns = ns;
+
+  if (ns < 0)
+    {
+      rns = ns + 1000000000;
+      if (rs == TYPE_MINIMUM (time_t))
+        {
+          if (bs <= 0)
+            goto low_overflow;
+          bs--;
+        }
+      else
+        rs--;
+    }
+
+  if (INT_SUBTRACT_OVERFLOW (rs, bs))
+    {
+      if (rs < 0)
+        {
+        low_overflow:
+          rs = TYPE_MINIMUM (time_t);
+          rns = 0;
+        }
+      else
+        {
+          rs = TYPE_MAXIMUM (time_t);
+          rns = 999999999;
+        }
+    }
+  else
+    rs -= bs;
+
+  r.tv_sec = rs;
+  r.tv_nsec = rns;
+  return r;
+}

=== added file 'lib/timespec.h'
--- lib/timespec.h	1970-01-01 00:00:00 +0000
+++ lib/timespec.h	2011-07-01 05:43:28 +0000
@@ -0,0 +1,82 @@
+/* timespec -- System time interface
+
+   Copyright (C) 2000, 2002, 2004-2005, 2007, 2009-2011 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/>.  */
+
+#if ! defined TIMESPEC_H
+# define TIMESPEC_H
+
+# include <time.h>
+
+/* Return negative, zero, positive if A < B, A == B, A > B, respectively.
+
+   For each time stamp T, this code assumes that either:
+
+     * T.tv_nsec is in the range 0..999999999; or
+     * T.tv_sec corresponds to a valid leap second on a host that supports
+       leap seconds, and T.tv_nsec is in the range 1000000000..1999999999; or
+     * T.tv_sec is the minimum time_t value and T.tv_nsec is -1; or
+       T.tv_sec is the maximum time_t value and T.tv_nsec is 2000000000.
+       This allows for special struct timespec values that are less or
+       greater than all possible valid time stamps.
+
+   In all these cases, it is safe to subtract two tv_nsec values and
+   convert the result to integer without worrying about overflow on
+   any platform of interest to the GNU project, since all such
+   platforms have 32-bit int or wider.
+
+   Replacing "(int) (a.tv_nsec - b.tv_nsec)" with something like
+   "a.tv_nsec < b.tv_nsec ? -1 : a.tv_nsec > b.tv_nsec" would cause
+   this function to work in some cases where the above assumption is
+   violated, but not in all cases (e.g., a.tv_sec==1, a.tv_nsec==-2,
+   b.tv_sec==0, b.tv_nsec==999999999) and is arguably not worth the
+   extra instructions.  Using a subtraction has the advantage of
+   detecting some invalid cases on platforms that detect integer
+   overflow.
+
+   The (int) cast avoids a gcc -Wconversion warning.  */
+
+static inline int
+timespec_cmp (struct timespec a, struct timespec b)
+{
+  return (a.tv_sec < b.tv_sec ? -1
+          : a.tv_sec > b.tv_sec ? 1
+          : (int) (a.tv_nsec - b.tv_nsec));
+}
+
+/* Return -1, 0, 1, depending on the sign of A.  A.tv_nsec must be
+   nonnegative.  */
+static inline int
+timespec_sign (struct timespec a)
+{
+  return a.tv_sec < 0 ? -1 : a.tv_sec || a.tv_nsec;
+}
+
+struct timespec timespec_add (struct timespec, struct timespec);
+struct timespec timespec_sub (struct timespec, struct timespec);
+struct timespec dtotimespec (double);
+
+/* Return an approximation to A, of type 'double'.  */
+static inline double
+timespectod (struct timespec a)
+{
+  return a.tv_sec + a.tv_nsec / 1e9;
+}
+
+void gettime (struct timespec *);
+int settime (struct timespec const *);
+
+#endif

=== added file 'lib/utimens.c'
--- lib/utimens.c	1970-01-01 00:00:00 +0000
+++ lib/utimens.c	2011-07-01 05:43:28 +0000
@@ -0,0 +1,538 @@
+/* Set file access and modification times.
+
+   Copyright (C) 2003-2011 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 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 Paul Eggert.  */
+
+/* derived from a function in touch.c */
+
+#include <config.h>
+
+#include "utimens.h"
+
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdbool.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <unistd.h>
+
+#include "stat-time.h"
+#include "timespec.h"
+
+#if HAVE_UTIME_H
+# include <utime.h>
+#endif
+
+/* Some systems (even some that do have <utime.h>) don't declare this
+   structure anywhere.  */
+#ifndef HAVE_STRUCT_UTIMBUF
+struct utimbuf
+{
+  long actime;
+  long modtime;
+};
+#endif
+
+/* Avoid recursion with rpl_futimens or rpl_utimensat.  */
+#undef futimens
+#undef utimensat
+
+/* Solaris 9 mistakenly succeeds when given a non-directory with a
+   trailing slash.  Force the use of rpl_stat for a fix.  */
+#ifndef REPLACE_FUNC_STAT_FILE
+# define REPLACE_FUNC_STAT_FILE 0
+#endif
+
+#if HAVE_UTIMENSAT || HAVE_FUTIMENS
+/* Cache variables for whether the utimensat syscall works; used to
+   avoid calling the syscall if we know it will just fail with ENOSYS,
+   and to avoid unnecessary work in massaging timestamps if the
+   syscall will work.  Multiple variables are needed, to distinguish
+   between the following scenarios on Linux:
+   utimensat doesn't exist, or is in glibc but kernel 2.6.18 fails with ENOSYS
+   kernel 2.6.22 and earlier rejects AT_SYMLINK_NOFOLLOW
+   kernel 2.6.25 and earlier reject UTIME_NOW/UTIME_OMIT with non-zero tv_sec
+   kernel 2.6.32 used with xfs or ntfs-3g fail to honor UTIME_OMIT
+   utimensat completely works
+   For each cache variable: 0 = unknown, 1 = yes, -1 = no.  */
+static int utimensat_works_really;
+static int lutimensat_works_really;
+#endif /* HAVE_UTIMENSAT || HAVE_FUTIMENS */
+
+/* Validate the requested timestamps.  Return 0 if the resulting
+   timespec can be used for utimensat (after possibly modifying it to
+   work around bugs in utimensat).  Return a positive value if the
+   timespec needs further adjustment based on stat results: 1 if any
+   adjustment is needed for utimes, and 2 if any adjustment is needed
+   for Linux utimensat.  Return -1, with errno set to EINVAL, if
+   timespec is out of range.  */
+static int
+validate_timespec (struct timespec timespec[2])
+{
+  int result = 0;
+  int utime_omit_count = 0;
+  assert (timespec);
+  if ((timespec[0].tv_nsec != UTIME_NOW
+       && timespec[0].tv_nsec != UTIME_OMIT
+       && (timespec[0].tv_nsec < 0 || 1000000000 <= timespec[0].tv_nsec))
+      || (timespec[1].tv_nsec != UTIME_NOW
+          && timespec[1].tv_nsec != UTIME_OMIT
+          && (timespec[1].tv_nsec < 0 || 1000000000 <= timespec[1].tv_nsec)))
+    {
+      errno = EINVAL;
+      return -1;
+    }
+  /* Work around Linux kernel 2.6.25 bug, where utimensat fails with
+     EINVAL if tv_sec is not 0 when using the flag values of tv_nsec.
+     Flag a Linux kernel 2.6.32 bug, where an mtime of UTIME_OMIT
+     fails to bump ctime.  */
+  if (timespec[0].tv_nsec == UTIME_NOW
+      || timespec[0].tv_nsec == UTIME_OMIT)
+    {
+      timespec[0].tv_sec = 0;
+      result = 1;
+      if (timespec[0].tv_nsec == UTIME_OMIT)
+        utime_omit_count++;
+    }
+  if (timespec[1].tv_nsec == UTIME_NOW
+      || timespec[1].tv_nsec == UTIME_OMIT)
+    {
+      timespec[1].tv_sec = 0;
+      result = 1;
+      if (timespec[1].tv_nsec == UTIME_OMIT)
+        utime_omit_count++;
+    }
+  return result + (utime_omit_count == 1);
+}
+
+/* Normalize any UTIME_NOW or UTIME_OMIT values in *TS, using stat
+   buffer STATBUF to obtain the current timestamps of the file.  If
+   both times are UTIME_NOW, set *TS to NULL (as this can avoid some
+   permissions issues).  If both times are UTIME_OMIT, return true
+   (nothing further beyond the prior collection of STATBUF is
+   necessary); otherwise return false.  */
+static bool
+update_timespec (struct stat const *statbuf, struct timespec *ts[2])
+{
+  struct timespec *timespec = *ts;
+  if (timespec[0].tv_nsec == UTIME_OMIT
+      && timespec[1].tv_nsec == UTIME_OMIT)
+    return true;
+  if (timespec[0].tv_nsec == UTIME_NOW
+      && timespec[1].tv_nsec == UTIME_NOW)
+    {
+      *ts = NULL;
+      return false;
+    }
+
+  if (timespec[0].tv_nsec == UTIME_OMIT)
+    timespec[0] = get_stat_atime (statbuf);
+  else if (timespec[0].tv_nsec == UTIME_NOW)
+    gettime (&timespec[0]);
+
+  if (timespec[1].tv_nsec == UTIME_OMIT)
+    timespec[1] = get_stat_mtime (statbuf);
+  else if (timespec[1].tv_nsec == UTIME_NOW)
+    gettime (&timespec[1]);
+
+  return false;
+}
+
+/* Set the access and modification time stamps of FD (a.k.a. FILE) to be
+   TIMESPEC[0] and TIMESPEC[1], respectively.
+   FD must be either negative -- in which case it is ignored --
+   or a file descriptor that is open on FILE.
+   If FD is nonnegative, then FILE can be NULL, which means
+   use just futimes (or equivalent) instead of utimes (or equivalent),
+   and fail if on an old system without futimes (or equivalent).
+   If TIMESPEC is null, set the time stamps to the current time.
+   Return 0 on success, -1 (setting errno) on failure.  */
+
+int
+fdutimens (int fd, char const *file, struct timespec const timespec[2])
+{
+  struct timespec adjusted_timespec[2];
+  struct timespec *ts = timespec ? adjusted_timespec : NULL;
+  int adjustment_needed = 0;
+  struct stat st;
+
+  if (ts)
+    {
+      adjusted_timespec[0] = timespec[0];
+      adjusted_timespec[1] = timespec[1];
+      adjustment_needed = validate_timespec (ts);
+    }
+  if (adjustment_needed < 0)
+    return -1;
+
+  /* Require that at least one of FD or FILE are valid.  Works around
+     a Linux bug where futimens (AT_FDCWD, NULL) changes "." rather
+     than failing.  */
+  if (!file)
+    {
+      if (fd < 0)
+        {
+          errno = EBADF;
+          return -1;
+        }
+      if (dup2 (fd, fd) != fd)
+        return -1;
+    }
+
+  /* Some Linux-based NFS clients are buggy, and mishandle time stamps
+     of files in NFS file systems in some cases.  We have no
+     configure-time test for this, but please see
+     <http://bugs.gentoo.org/show_bug.cgi?id=132673> for references to
+     some of the problems with Linux 2.6.16.  If this affects you,
+     compile with -DHAVE_BUGGY_NFS_TIME_STAMPS; this is reported to
+     help in some cases, albeit at a cost in performance.  But you
+     really should upgrade your kernel to a fixed version, since the
+     problem affects many applications.  */
+
+#if HAVE_BUGGY_NFS_TIME_STAMPS
+  if (fd < 0)
+    sync ();
+  else
+    fsync (fd);
+#endif
+
+  /* POSIX 2008 added two interfaces to set file timestamps with
+     nanosecond resolution; newer Linux implements both functions via
+     a single syscall.  We provide a fallback for ENOSYS (for example,
+     compiling against Linux 2.6.25 kernel headers and glibc 2.7, but
+     running on Linux 2.6.18 kernel).  */
+#if HAVE_UTIMENSAT || HAVE_FUTIMENS
+  if (0 <= utimensat_works_really)
+    {
+      int result;
+# if __linux__
+      /* As recently as Linux kernel 2.6.32 (Dec 2009), several file
+         systems (xfs, ntfs-3g) have bugs with a single UTIME_OMIT,
+         but work if both times are either explicitly specified or
+         UTIME_NOW.  Work around it with a preparatory [f]stat prior
+         to calling futimens/utimensat; fortunately, there is not much
+         timing impact due to the extra syscall even on file systems
+         where UTIME_OMIT would have worked.  FIXME: Simplify this in
+         2012, when file system bugs are no longer common.  */
+      if (adjustment_needed == 2)
+        {
+          if (fd < 0 ? stat (file, &st) : fstat (fd, &st))
+            return -1;
+          if (ts[0].tv_nsec == UTIME_OMIT)
+            ts[0] = get_stat_atime (&st);
+          else if (ts[1].tv_nsec == UTIME_OMIT)
+            ts[1] = get_stat_mtime (&st);
+          /* Note that st is good, in case utimensat gives ENOSYS.  */
+          adjustment_needed++;
+        }
+# endif /* __linux__ */
+# if HAVE_UTIMENSAT
+      if (fd < 0)
+        {
+          result = utimensat (AT_FDCWD, file, ts, 0);
+#  ifdef __linux__
+          /* Work around a kernel bug:
+             http://bugzilla.redhat.com/442352
+             http://bugzilla.redhat.com/449910
+             It appears that utimensat can mistakenly return 280 rather
+             than -1 upon ENOSYS failure.
+             FIXME: remove in 2010 or whenever the offending kernels
+             are no longer in common use.  */
+          if (0 < result)
+            errno = ENOSYS;
+#  endif /* __linux__ */
+          if (result == 0 || errno != ENOSYS)
+            {
+              utimensat_works_really = 1;
+              return result;
+            }
+        }
+# endif /* HAVE_UTIMENSAT */
+# if HAVE_FUTIMENS
+      if (0 <= fd)
+        {
+          result = futimens (fd, ts);
+#  ifdef __linux__
+          /* Work around the same bug as above.  */
+          if (0 < result)
+            errno = ENOSYS;
+#  endif /* __linux__ */
+          if (result == 0 || errno != ENOSYS)
+            {
+              utimensat_works_really = 1;
+              return result;
+            }
+        }
+# endif /* HAVE_FUTIMENS */
+    }
+  utimensat_works_really = -1;
+  lutimensat_works_really = -1;
+#endif /* HAVE_UTIMENSAT || HAVE_FUTIMENS */
+
+  /* The platform lacks an interface to set file timestamps with
+     nanosecond resolution, so do the best we can, discarding any
+     fractional part of the timestamp.  */
+
+  if (adjustment_needed || (REPLACE_FUNC_STAT_FILE && fd < 0))
+    {
+      if (adjustment_needed != 3
+          && (fd < 0 ? stat (file, &st) : fstat (fd, &st)))
+        return -1;
+      if (ts && update_timespec (&st, &ts))
+        return 0;
+    }
+
+  {
+#if HAVE_FUTIMESAT || HAVE_WORKING_UTIMES
+    struct timeval timeval[2];
+    struct timeval *t;
+    if (ts)
+      {
+        timeval[0].tv_sec = ts[0].tv_sec;
+        timeval[0].tv_usec = ts[0].tv_nsec / 1000;
+        timeval[1].tv_sec = ts[1].tv_sec;
+        timeval[1].tv_usec = ts[1].tv_nsec / 1000;
+        t = timeval;
+      }
+    else
+      t = NULL;
+
+    if (fd < 0)
+      {
+# if HAVE_FUTIMESAT
+        return futimesat (AT_FDCWD, file, t);
+# endif
+      }
+    else
+      {
+        /* If futimesat or futimes fails here, don't try to speed things
+           up by returning right away.  glibc can incorrectly fail with
+           errno == ENOENT if /proc isn't mounted.  Also, Mandrake 10.0
+           in high security mode doesn't allow ordinary users to read
+           /proc/self, so glibc incorrectly fails with errno == EACCES.
+           If errno == EIO, EPERM, or EROFS, it's probably safe to fail
+           right away, but these cases are rare enough that they're not
+           worth optimizing, and who knows what other messed-up systems
+           are out there?  So play it safe and fall back on the code
+           below.  */
+
+# if (HAVE_FUTIMESAT && !FUTIMESAT_NULL_BUG) || HAVE_FUTIMES
+#  if HAVE_FUTIMESAT && !FUTIMESAT_NULL_BUG
+#   undef futimes
+#   define futimes(fd, t) futimesat (fd, NULL, t)
+#  endif
+        if (futimes (fd, t) == 0)
+          {
+#  if __linux__ && __GLIBC__
+            /* Work around a longstanding glibc bug, still present as
+               of 2010-12-27.  On older Linux kernels that lack both
+               utimensat and utimes, glibc's futimes rounds instead of
+               truncating when falling back on utime.  The same bug
+               occurs in futimesat with a null 2nd arg.  */
+            if (t)
+              {
+                bool abig = 500000 <= t[0].tv_usec;
+                bool mbig = 500000 <= t[1].tv_usec;
+                if ((abig | mbig) && fstat (fd, &st) == 0)
+                  {
+                    /* If these two subtractions overflow, they'll
+                       track the overflows inside the buggy glibc.  */
+                    time_t adiff = st.st_atime - t[0].tv_sec;
+                    time_t mdiff = st.st_mtime - t[1].tv_sec;
+
+                    struct timeval *tt = NULL;
+                    struct timeval truncated_timeval[2];
+                    truncated_timeval[0] = t[0];
+                    truncated_timeval[1] = t[1];
+                    if (abig && adiff == 1 && get_stat_atime_ns (&st) == 0)
+                      {
+                        tt = truncated_timeval;
+                        tt[0].tv_usec = 0;
+                      }
+                    if (mbig && mdiff == 1 && get_stat_mtime_ns (&st) == 0)
+                      {
+                        tt = truncated_timeval;
+                        tt[1].tv_usec = 0;
+                      }
+                    if (tt)
+                      futimes (fd, tt);
+                  }
+              }
+#  endif
+
+            return 0;
+          }
+# endif
+      }
+#endif /* HAVE_FUTIMESAT || HAVE_WORKING_UTIMES */
+
+    if (!file)
+      {
+#if ! ((HAVE_FUTIMESAT && !FUTIMESAT_NULL_BUG)          \
+        || (HAVE_WORKING_UTIMES && HAVE_FUTIMES))
+        errno = ENOSYS;
+#endif
+        return -1;
+      }
+
+#if HAVE_WORKING_UTIMES
+    return utimes (file, t);
+#else
+    {
+      struct utimbuf utimbuf;
+      struct utimbuf *ut;
+      if (ts)
+        {
+          utimbuf.actime = ts[0].tv_sec;
+          utimbuf.modtime = ts[1].tv_sec;
+          ut = &utimbuf;
+        }
+      else
+        ut = NULL;
+
+      return utime (file, ut);
+    }
+#endif /* !HAVE_WORKING_UTIMES */
+  }
+}
+
+/* Set the access and modification time stamps of FILE to be
+   TIMESPEC[0] and TIMESPEC[1], respectively.  */
+int
+utimens (char const *file, struct timespec const timespec[2])
+{
+  return fdutimens (-1, file, timespec);
+}
+
+/* Set the access and modification time stamps of FILE to be
+   TIMESPEC[0] and TIMESPEC[1], respectively, without dereferencing
+   symlinks.  Fail with ENOSYS if the platform does not support
+   changing symlink timestamps, but FILE was a symlink.  */
+int
+lutimens (char const *file, struct timespec const timespec[2])
+{
+  struct timespec adjusted_timespec[2];
+  struct timespec *ts = timespec ? adjusted_timespec : NULL;
+  int adjustment_needed = 0;
+  struct stat st;
+
+  if (ts)
+    {
+      adjusted_timespec[0] = timespec[0];
+      adjusted_timespec[1] = timespec[1];
+      adjustment_needed = validate_timespec (ts);
+    }
+  if (adjustment_needed < 0)
+    return -1;
+
+  /* The Linux kernel did not support symlink timestamps until
+     utimensat, in version 2.6.22, so we don't need to mimic
+     fdutimens' worry about buggy NFS clients.  But we do have to
+     worry about bogus return values.  */
+
+#if HAVE_UTIMENSAT
+  if (0 <= lutimensat_works_really)
+    {
+      int result;
+# if __linux__
+      /* As recently as Linux kernel 2.6.32 (Dec 2009), several file
+         systems (xfs, ntfs-3g) have bugs with a single UTIME_OMIT,
+         but work if both times are either explicitly specified or
+         UTIME_NOW.  Work around it with a preparatory lstat prior to
+         calling utimensat; fortunately, there is not much timing
+         impact due to the extra syscall even on file systems where
+         UTIME_OMIT would have worked.  FIXME: Simplify this in 2012,
+         when file system bugs are no longer common.  */
+      if (adjustment_needed == 2)
+        {
+          if (lstat (file, &st))
+            return -1;
+          if (ts[0].tv_nsec == UTIME_OMIT)
+            ts[0] = get_stat_atime (&st);
+          else if (ts[1].tv_nsec == UTIME_OMIT)
+            ts[1] = get_stat_mtime (&st);
+          /* Note that st is good, in case utimensat gives ENOSYS.  */
+          adjustment_needed++;
+        }
+# endif /* __linux__ */
+      result = utimensat (AT_FDCWD, file, ts, AT_SYMLINK_NOFOLLOW);
+# ifdef __linux__
+      /* Work around a kernel bug:
+         http://bugzilla.redhat.com/442352
+         http://bugzilla.redhat.com/449910
+         It appears that utimensat can mistakenly return 280 rather
+         than -1 upon ENOSYS failure.
+         FIXME: remove in 2010 or whenever the offending kernels
+         are no longer in common use.  */
+      if (0 < result)
+        errno = ENOSYS;
+# endif
+      if (result == 0 || errno != ENOSYS)
+        {
+          utimensat_works_really = 1;
+          lutimensat_works_really = 1;
+          return result;
+        }
+    }
+  lutimensat_works_really = -1;
+#endif /* HAVE_UTIMENSAT */
+
+  /* The platform lacks an interface to set file timestamps with
+     nanosecond resolution, so do the best we can, discarding any
+     fractional part of the timestamp.  */
+
+  if (adjustment_needed || REPLACE_FUNC_STAT_FILE)
+    {
+      if (adjustment_needed != 3 && lstat (file, &st))
+        return -1;
+      if (ts && update_timespec (&st, &ts))
+        return 0;
+    }
+
+  /* On Linux, lutimes is a thin wrapper around utimensat, so there is
+     no point trying lutimes if utimensat failed with ENOSYS.  */
+#if HAVE_LUTIMES && !HAVE_UTIMENSAT
+  {
+    struct timeval timeval[2];
+    struct timeval *t;
+    int result;
+    if (ts)
+      {
+        timeval[0].tv_sec = ts[0].tv_sec;
+        timeval[0].tv_usec = ts[0].tv_nsec / 1000;
+        timeval[1].tv_sec = ts[1].tv_sec;
+        timeval[1].tv_usec = ts[1].tv_nsec / 1000;
+        t = timeval;
+      }
+    else
+      t = NULL;
+
+    result = lutimes (file, t);
+    if (result == 0 || errno != ENOSYS)
+      return result;
+  }
+#endif /* HAVE_LUTIMES && !HAVE_UTIMENSAT */
+
+  /* Out of luck for symlinks, but we still handle regular files.  */
+  if (!(adjustment_needed || REPLACE_FUNC_STAT_FILE) && lstat (file, &st))
+    return -1;
+  if (!S_ISLNK (st.st_mode))
+    return fdutimens (-1, file, ts);
+  errno = ENOSYS;
+  return -1;
+}

=== added file 'lib/utimens.h'
--- lib/utimens.h	1970-01-01 00:00:00 +0000
+++ lib/utimens.h	2011-07-01 05:43:28 +0000
@@ -0,0 +1,19 @@
+#include <time.h>
+int fdutimens (int, char const *, struct timespec const [2]);
+int utimens (char const *, struct timespec const [2]);
+int lutimens (char const *, struct timespec const [2]);
+
+#if GNULIB_FDUTIMENSAT
+# include <fcntl.h>
+# include <sys/stat.h>
+
+int fdutimensat (int fd, int dir, char const *name, struct timespec const [2],
+                 int atflag);
+
+/* Using this function makes application code slightly more readable.  */
+static inline int
+lutimensat (int dir, char const *file, struct timespec const times[2])
+{
+  return utimensat (dir, file, times, AT_SYMLINK_NOFOLLOW);
+}
+#endif

=== added file 'm4/clock_time.m4'
--- m4/clock_time.m4	1970-01-01 00:00:00 +0000
+++ m4/clock_time.m4	2011-07-01 05:43:28 +0000
@@ -0,0 +1,31 @@
+# clock_time.m4 serial 10
+dnl Copyright (C) 2002-2006, 2009-2011 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.
+
+# Check for clock_gettime and clock_settime, and set LIB_CLOCK_GETTIME.
+# For a program named, say foo, you should add a line like the following
+# in the corresponding Makefile.am file:
+# foo_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME)
+
+AC_DEFUN([gl_CLOCK_TIME],
+[
+  dnl Persuade glibc and Solaris <time.h> to declare these functions.
+  AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
+
+  # Solaris 2.5.1 needs -lposix4 to get the clock_gettime function.
+  # Solaris 7 prefers the library name -lrt to the obsolescent name -lposix4.
+
+  # Save and restore LIBS so e.g., -lrt, isn't added to it.  Otherwise, *all*
+  # programs in the package would end up linked with that potentially-shared
+  # library, inducing unnecessary run-time overhead.
+  LIB_CLOCK_GETTIME=
+  AC_SUBST([LIB_CLOCK_GETTIME])
+  gl_saved_libs=$LIBS
+    AC_SEARCH_LIBS([clock_gettime], [rt posix4],
+                   [test "$ac_cv_search_clock_gettime" = "none required" ||
+                    LIB_CLOCK_GETTIME=$ac_cv_search_clock_gettime])
+    AC_CHECK_FUNCS([clock_gettime clock_settime])
+  LIBS=$gl_saved_libs
+])

=== added file 'm4/errno_h.m4'
--- m4/errno_h.m4	1970-01-01 00:00:00 +0000
+++ m4/errno_h.m4	2011-07-01 05:43:28 +0000
@@ -0,0 +1,119 @@
+# errno_h.m4 serial 9
+dnl Copyright (C) 2004, 2006, 2008-2011 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN_ONCE([gl_HEADER_ERRNO_H],
+[
+  AC_REQUIRE([AC_PROG_CC])
+  AC_CACHE_CHECK([for complete errno.h], [gl_cv_header_errno_h_complete], [
+    AC_EGREP_CPP([booboo],[
+#include <errno.h>
+#if !defined ENOMSG
+booboo
+#endif
+#if !defined EIDRM
+booboo
+#endif
+#if !defined ENOLINK
+booboo
+#endif
+#if !defined EPROTO
+booboo
+#endif
+#if !defined EMULTIHOP
+booboo
+#endif
+#if !defined EBADMSG
+booboo
+#endif
+#if !defined EOVERFLOW
+booboo
+#endif
+#if !defined ENOTSUP
+booboo
+#endif
+#if !defined ESTALE
+booboo
+#endif
+#if !defined EDQUOT
+booboo
+#endif
+#if !defined ECANCELED
+booboo
+#endif
+      ],
+      [gl_cv_header_errno_h_complete=no],
+      [gl_cv_header_errno_h_complete=yes])
+  ])
+  if test $gl_cv_header_errno_h_complete = yes; then
+    ERRNO_H=''
+  else
+    gl_NEXT_HEADERS([errno.h])
+    ERRNO_H='errno.h'
+  fi
+  AC_SUBST([ERRNO_H])
+  AM_CONDITIONAL([GL_GENERATE_ERRNO_H], [test -n "$ERRNO_H"])
+  gl_REPLACE_ERRNO_VALUE([EMULTIHOP])
+  gl_REPLACE_ERRNO_VALUE([ENOLINK])
+  gl_REPLACE_ERRNO_VALUE([EOVERFLOW])
+])
+
+# Assuming $1 = EOVERFLOW.
+# The EOVERFLOW errno value ought to be defined in <errno.h>, according to
+# POSIX.  But some systems (like OpenBSD 4.0 or AIX 3) don't define it, and
+# some systems (like OSF/1) define it when _XOPEN_SOURCE_EXTENDED is defined.
+# Check for the value of EOVERFLOW.
+# Set the variables EOVERFLOW_HIDDEN and EOVERFLOW_VALUE.
+AC_DEFUN([gl_REPLACE_ERRNO_VALUE],
+[
+  if test -n "$ERRNO_H"; then
+    AC_CACHE_CHECK([for ]$1[ value], [gl_cv_header_errno_h_]$1, [
+      AC_EGREP_CPP([yes],[
+#include <errno.h>
+#ifdef ]$1[
+yes
+#endif
+      ],
+      [gl_cv_header_errno_h_]$1[=yes],
+      [gl_cv_header_errno_h_]$1[=no])
+      if test $gl_cv_header_errno_h_]$1[ = no; then
+        AC_EGREP_CPP([yes],[
+#define _XOPEN_SOURCE_EXTENDED 1
+#include <errno.h>
+#ifdef ]$1[
+yes
+#endif
+          ], [gl_cv_header_errno_h_]$1[=hidden])
+        if test $gl_cv_header_errno_h_]$1[ = hidden; then
+          dnl The macro exists but is hidden.
+          dnl Define it to the same value.
+          AC_COMPUTE_INT([gl_cv_header_errno_h_]$1, $1, [
+#define _XOPEN_SOURCE_EXTENDED 1
+#include <errno.h>
+/* The following two lines are a workaround against an autoconf-2.52 bug.  */
+#include <stdio.h>
+#include <stdlib.h>
+])
+        fi
+      fi
+    ])
+    case $gl_cv_header_errno_h_]$1[ in
+      yes | no)
+        ]$1[_HIDDEN=0; ]$1[_VALUE=
+        ;;
+      *)
+        ]$1[_HIDDEN=1; ]$1[_VALUE="$gl_cv_header_errno_h_]$1["
+        ;;
+    esac
+    AC_SUBST($1[_HIDDEN])
+    AC_SUBST($1[_VALUE])
+  fi
+])
+
+dnl Autoconf >= 2.61 has AC_COMPUTE_INT built-in.
+dnl Remove this when we can assume autoconf >= 2.61.
+m4_ifdef([AC_COMPUTE_INT], [], [
+  AC_DEFUN([AC_COMPUTE_INT], [_AC_COMPUTE_INT([$2],[$1],[$3],[$4])])
+])

=== added file 'm4/gettime.m4'
--- m4/gettime.m4	1970-01-01 00:00:00 +0000
+++ m4/gettime.m4	2011-07-01 05:43:28 +0000
@@ -0,0 +1,13 @@
+# gettime.m4 serial 8
+dnl Copyright (C) 2002, 2004-2006, 2009-2011 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_GETTIME],
+[
+  dnl Prerequisites of lib/gettime.c.
+  AC_REQUIRE([gl_CLOCK_TIME])
+  AC_REQUIRE([gl_TIMESPEC])
+  AC_CHECK_FUNCS_ONCE([gettimeofday nanotime])
+])

=== added file 'm4/gettimeofday.m4'
--- m4/gettimeofday.m4	1970-01-01 00:00:00 +0000
+++ m4/gettimeofday.m4	2011-07-01 05:43:28 +0000
@@ -0,0 +1,125 @@
+# serial 17
+
+# Copyright (C) 2001-2003, 2005, 2007, 2009-2011 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_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])
+
+  gl_gettimeofday_timezone=void
+  if test $ac_cv_func_gettimeofday != yes; then
+    HAVE_GETTIMEOFDAY=0
+  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
+    fi
+    m4_ifdef([gl_FUNC_TZSET_CLOBBER], [
+      gl_FUNC_TZSET_CLOBBER
+      if test $gl_cv_func_tzset_clobber = yes; then
+        REPLACE_GETTIMEOFDAY=1
+        gl_GETTIMEOFDAY_REPLACE_LOCALTIME
+        AC_DEFINE([tzset], [rpl_tzset],
+          [Define to rpl_tzset if the wrapper function should be used.])
+        AC_DEFINE([TZSET_CLOBBERS_LOCALTIME], [1],
+          [Define if tzset clobbers localtime's static buffer.])
+      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.])
+])
+
+
+dnl See if gettimeofday clobbers the static buffer that localtime uses
+dnl for its return value.  The gettimeofday function from Mac OS X 10.0.4
+dnl (i.e., Darwin 1.3.7) has this problem.
+dnl
+dnl If it does, then arrange to use gettimeofday and localtime only via
+dnl the wrapper functions that work around the problem.
+
+AC_DEFUN([gl_FUNC_GETTIMEOFDAY_CLOBBER],
+[
+ AC_REQUIRE([gl_HEADER_SYS_TIME_H])
+
+ AC_CACHE_CHECK([whether gettimeofday clobbers localtime buffer],
+  [gl_cv_func_gettimeofday_clobber],
+  [AC_RUN_IFELSE(
+     [AC_LANG_PROGRAM(
+        [[#include <string.h>
+          #include <sys/time.h>
+          #include <time.h>
+          #include <stdlib.h>
+        ]],
+        [[
+          time_t t = 0;
+          struct tm *lt;
+          struct tm saved_lt;
+          struct timeval tv;
+          lt = localtime (&t);
+          saved_lt = *lt;
+          gettimeofday (&tv, NULL);
+          return memcmp (lt, &saved_lt, sizeof (struct tm)) != 0;
+        ]])],
+     [gl_cv_func_gettimeofday_clobber=no],
+     [gl_cv_func_gettimeofday_clobber=yes],
+     dnl When crosscompiling, assume it is broken.
+     [gl_cv_func_gettimeofday_clobber=yes])])
+
+ if test $gl_cv_func_gettimeofday_clobber = yes; then
+   REPLACE_GETTIMEOFDAY=1
+   gl_GETTIMEOFDAY_REPLACE_LOCALTIME
+   AC_DEFINE([GETTIMEOFDAY_CLOBBERS_LOCALTIME], [1],
+     [Define if gettimeofday clobbers the localtime buffer.])
+ fi
+])
+
+AC_DEFUN([gl_GETTIMEOFDAY_REPLACE_LOCALTIME], [
+  AC_DEFINE([gmtime], [rpl_gmtime],
+    [Define to rpl_gmtime if the replacement function should be used.])
+  AC_DEFINE([localtime], [rpl_localtime],
+    [Define to rpl_localtime if the replacement function should be used.])
+])
+
+# Prerequisites of lib/gettimeofday.c.
+AC_DEFUN([gl_PREREQ_GETTIMEOFDAY], [
+  AC_CHECK_HEADERS([sys/timeb.h])
+  AC_CHECK_FUNCS([_ftime])
+])

=== modified file 'm4/gl-comp.m4'
--- m4/gl-comp.m4	2011-06-25 08:40:38 +0000
+++ m4/gl-comp.m4	2011-07-01 05:43:38 +0000
@@ -31,13 +31,16 @@
   # Code from module arg-nonnull:
   # Code from module c++defs:
   # Code from module careadlinkat:
+  # Code from module clock-time:
   # Code from module crypto/md5:
   # Code from module crypto/sha1:
   # Code from module crypto/sha256:
   # Code from module crypto/sha512:
   # Code from module dosname:
   # Code from module dtoastr:
+  # Code from module dtotimespec:
   # Code from module dup2:
+  # Code from module errno:
   # Code from module extensions:
   AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
   # Code from module filemode:
@@ -45,6 +48,8 @@
   # Code from module getopt-gnu:
   # Code from module getopt-posix:
   # Code from module gettext-h:
+  # Code from module gettime:
+  # Code from module gettimeofday:
   # Code from module ignore-value:
   # Code from module include_next:
   # Code from module intprops:
@@ -52,10 +57,12 @@
   # Code from module lstat:
   # Code from module mktime:
   # Code from module multiarch:
+  # Code from module pselect:
   # Code from module readlink:
   # Code from module socklen:
   # Code from module ssize_t:
   # Code from module stat:
+  # Code from module stat-time:
   # Code from module stdarg:
   dnl Some compilers (e.g., AIX 5.3 cc) need to be in c99 mode
   dnl for the builtin va_copy to work.  With Autoconf 2.60 or later,
@@ -68,14 +75,22 @@
   # Code from module stdio:
   # Code from module stdlib:
   # Code from module strftime:
+  # Code from module strtoimax:
+  # Code from module strtoll:
   # Code from module strtoull:
   # Code from module strtoumax:
   # Code from module symlink:
+  # Code from module sys_select:
   # Code from module sys_stat:
+  # Code from module sys_time:
   # Code from module time:
   # Code from module time_r:
+  # Code from module timespec:
+  # Code from module timespec-add:
+  # Code from module timespec-sub:
   # Code from module u64:
   # Code from module unistd:
+  # Code from module utimens:
   # Code from module verify:
   # Code from module warn-on-use:
 ])
@@ -98,6 +113,7 @@
   gl_source_base='lib'
 gl_FUNC_ALLOCA
 AC_CHECK_FUNCS_ONCE([readlinkat])
+gl_CLOCK_TIME
 gl_MD5
 gl_SHA1
 gl_SHA256
@@ -105,6 +121,7 @@
 AC_REQUIRE([gl_C99_STRTOLD])
 gl_FUNC_DUP2
 gl_UNISTD_MODULE_INDICATOR([dup2])
+gl_HEADER_ERRNO_H
 gl_FILEMODE
 gl_GETLOADAVG
 if test $HAVE_GETLOADAVG = 0; then
@@ -125,6 +142,13 @@
   AC_LIBOBJ([getopt1])
   gl_PREREQ_GETOPT
 fi
+gl_GETTIME
+gl_FUNC_GETTIMEOFDAY
+if test $HAVE_GETTIMEOFDAY = 0 || test $REPLACE_GETTIMEOFDAY = 1; then
+  AC_LIBOBJ([gettimeofday])
+  gl_PREREQ_GETTIMEOFDAY
+fi
+gl_SYS_TIME_MODULE_INDICATOR([gettimeofday])
 AC_REQUIRE([AC_C_INLINE])
 gl_INTTYPES_INCOMPLETE
 gl_FUNC_LSTAT
@@ -140,6 +164,11 @@
 fi
 gl_TIME_MODULE_INDICATOR([mktime])
 gl_MULTIARCH
+gl_FUNC_PSELECT
+if test $REPLACE_PSELECT = 1; then
+  AC_LIBOBJ([pselect])
+fi
+gl_SYS_SELECT_MODULE_INDICATOR([pselect])
 gl_FUNC_READLINK
 if test $HAVE_READLINK = 0 || test $REPLACE_READLINK = 1; then
   AC_LIBOBJ([readlink])
@@ -148,6 +177,8 @@
 gl_UNISTD_MODULE_INDICATOR([readlink])
 gl_TYPE_SOCKLEN_T
 gt_TYPE_SSIZE_T
+gl_STAT_TIME
+gl_STAT_BIRTHTIME
 gl_STDARG_H
 AM_STDBOOL_H
 gl_STDDEF_H
@@ -155,6 +186,12 @@
 gl_STDIO_H
 gl_STDLIB_H
 gl_FUNC_GNU_STRFTIME
+gl_FUNC_STRTOIMAX
+if test "$ac_cv_have_decl_strtoimax" != yes && test $ac_cv_func_strtoimax = no; then
+  AC_LIBOBJ([strtoimax])
+  gl_PREREQ_STRTOIMAX
+fi
+gl_INTTYPES_MODULE_INDICATOR([strtoimax])
 gl_FUNC_STRTOUMAX
 if test "$ac_cv_have_decl_strtoumax" != yes && test $ac_cv_func_strtoumax = no; then
   AC_LIBOBJ([strtoumax])
@@ -166,8 +203,12 @@
   AC_LIBOBJ([symlink])
 fi
 gl_UNISTD_MODULE_INDICATOR([symlink])
+gl_HEADER_SYS_SELECT
+AC_PROG_MKDIR_P
 gl_HEADER_SYS_STAT_H
 AC_PROG_MKDIR_P
+gl_HEADER_SYS_TIME_H
+AC_PROG_MKDIR_P
 gl_HEADER_TIME_H
 gl_TIME_R
 if test $HAVE_LOCALTIME_R = 0 || test $REPLACE_LOCALTIME_R = 1; then
@@ -175,11 +216,14 @@
   gl_PREREQ_TIME_R
 fi
 gl_TIME_MODULE_INDICATOR([time_r])
+gl_TIMESPEC
 AC_REQUIRE([AC_C_INLINE])
 gl_UNISTD_H
+gl_UTIMENS
   gl_gnulib_enabled_dosname=false
   gl_gnulib_enabled_be453cec5eecf5731a274f2de7f2db36=false
   gl_gnulib_enabled_stat=false
+  gl_gnulib_enabled_strtoll=false
   gl_gnulib_enabled_strtoull=false
   gl_gnulib_enabled_verify=false
   func_gl_gnulib_m4code_dosname ()
@@ -214,6 +258,18 @@
       fi
     fi
   }
+  func_gl_gnulib_m4code_strtoll ()
+  {
+    if ! $gl_gnulib_enabled_strtoll; then
+gl_FUNC_STRTOLL
+if test $HAVE_STRTOLL = 0; then
+  AC_LIBOBJ([strtoll])
+  gl_PREREQ_STRTOLL
+fi
+gl_STDLIB_MODULE_INDICATOR([strtoll])
+      gl_gnulib_enabled_strtoll=true
+    fi
+  }
   func_gl_gnulib_m4code_strtoull ()
   {
     if ! $gl_gnulib_enabled_strtoull; then
@@ -244,6 +300,12 @@
   if test $HAVE_READLINK = 0 || test $REPLACE_READLINK = 1; then
     func_gl_gnulib_m4code_stat
   fi
+  if test "$ac_cv_have_decl_strtoimax" != yes && test $ac_cv_func_strtoimax = no; then
+    func_gl_gnulib_m4code_verify
+  fi
+  if test "$ac_cv_have_decl_strtoimax" != yes && test $ac_cv_func_strtoimax = no && test $ac_cv_type_long_long_int = yes; then
+    func_gl_gnulib_m4code_strtoll
+  fi
   if test "$ac_cv_have_decl_strtoumax" != yes && test $ac_cv_func_strtoumax = no; then
     func_gl_gnulib_m4code_verify
   fi
@@ -254,6 +316,7 @@
   AM_CONDITIONAL([gl_GNULIB_ENABLED_dosname], [$gl_gnulib_enabled_dosname])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_be453cec5eecf5731a274f2de7f2db36], [$gl_gnulib_enabled_be453cec5eecf5731a274f2de7f2db36])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_stat], [$gl_gnulib_enabled_stat])
+  AM_CONDITIONAL([gl_GNULIB_ENABLED_strtoll], [$gl_gnulib_enabled_strtoll])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_strtoull], [$gl_gnulib_enabled_strtoull])
   AM_CONDITIONAL([gl_GNULIB_ENABLED_verify], [$gl_gnulib_enabled_verify])
   # End of code from modules
@@ -407,7 +470,9 @@
   lib/careadlinkat.h
   lib/dosname.h
   lib/dtoastr.c
+  lib/dtotimespec.c
   lib/dup2.c
+  lib/errno.in.h
   lib/filemode.c
   lib/filemode.h
   lib/ftoastr.c
@@ -418,6 +483,8 @@
   lib/getopt1.c
   lib/getopt_int.h
   lib/gettext.h
+  lib/gettime.c
+  lib/gettimeofday.c
   lib/ignore-value.h
   lib/intprops.h
   lib/inttypes.in.h
@@ -426,6 +493,7 @@
   lib/md5.h
   lib/mktime-internal.h
   lib/mktime.c
+  lib/pselect.c
   lib/readlink.c
   lib/sha1.c
   lib/sha1.h
@@ -433,6 +501,7 @@
   lib/sha256.h
   lib/sha512.c
   lib/sha512.h
+  lib/stat-time.h
   lib/stat.c
   lib/stdarg.in.h
   lib/stdbool.in.h
@@ -444,24 +513,36 @@
   lib/strftime.h
   lib/strtoimax.c
   lib/strtol.c
+  lib/strtoll.c
   lib/strtoul.c
   lib/strtoull.c
   lib/strtoumax.c
   lib/symlink.c
+  lib/sys_select.in.h
   lib/sys_stat.in.h
+  lib/sys_time.in.h
   lib/time.in.h
   lib/time_r.c
+  lib/timespec-add.c
+  lib/timespec-sub.c
+  lib/timespec.h
   lib/u64.h
   lib/unistd.in.h
+  lib/utimens.c
+  lib/utimens.h
   lib/verify.h
   m4/00gnulib.m4
   m4/alloca.m4
   m4/c-strtod.m4
+  m4/clock_time.m4
   m4/dup2.m4
+  m4/errno_h.m4
   m4/extensions.m4
   m4/filemode.m4
   m4/getloadavg.m4
   m4/getopt.m4
+  m4/gettime.m4
+  m4/gettimeofday.m4
   m4/gnulib-common.m4
   m4/include_next.m4
   m4/inttypes.m4
@@ -470,6 +551,7 @@
   m4/md5.m4
   m4/mktime.m4
   m4/multiarch.m4
+  m4/pselect.m4
   m4/readlink.m4
   m4/sha1.m4
   m4/sha256.m4
@@ -477,6 +559,7 @@
   m4/socklen.m4
   m4/ssize_t.m4
   m4/st_dm_mode.m4
+  m4/stat-time.m4
   m4/stat.m4
   m4/stdarg.m4
   m4/stdbool.m4
@@ -485,14 +568,23 @@
   m4/stdio_h.m4
   m4/stdlib_h.m4
   m4/strftime.m4
+  m4/strtoimax.m4
+  m4/strtoll.m4
   m4/strtoull.m4
   m4/strtoumax.m4
   m4/symlink.m4
+  m4/sys_select_h.m4
+  m4/sys_socket_h.m4
   m4/sys_stat_h.m4
+  m4/sys_time_h.m4
   m4/time_h.m4
   m4/time_r.m4
+  m4/timespec.m4
   m4/tm_gmtoff.m4
   m4/unistd_h.m4
+  m4/utimbuf.m4
+  m4/utimens.m4
+  m4/utimes.m4
   m4/warn-on-use.m4
   m4/wchar_t.m4
 ])

=== added file 'm4/pselect.m4'
--- m4/pselect.m4	1970-01-01 00:00:00 +0000
+++ m4/pselect.m4	2011-07-01 05:43:28 +0000
@@ -0,0 +1,31 @@
+# pselect.m4
+dnl Copyright (C) 2011 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_PSELECT],
+[
+  AC_REQUIRE([gl_HEADER_SYS_SELECT])
+  AC_REQUIRE([AC_C_RESTRICT])
+  AC_CHECK_FUNCS_ONCE([pselect])
+
+  if test $ac_cv_func_pselect = yes; then
+    AC_CACHE_CHECK([whether signature of pselect conforms to POSIX],
+      gl_cv_sig_pselect,
+      [AC_LINK_IFELSE(
+	 [AC_LANG_PROGRAM(
+	      [[#include <sys/select.h>
+		]],
+	      [[int (*p) (int, fd_set *, fd_set *, fd_set *restrict,
+			  struct timespec const *restrict,
+			  sigset_t const *restrict) = pselect;
+		return !p;]])],
+	 [gl_cv_sig_pselect=yes],
+	 [gl_cv_sig_pselect=no])])
+  fi
+
+  if test $ac_cv_func_pselect = no || test $gl_cv_sig_pselect = no; then
+    REPLACE_PSELECT=1
+  fi
+])

=== added file 'm4/stat-time.m4'
--- m4/stat-time.m4	1970-01-01 00:00:00 +0000
+++ m4/stat-time.m4	2011-07-01 05:43:28 +0000
@@ -0,0 +1,85 @@
+# Checks for stat-related time functions.
+
+# Copyright (C) 1998-1999, 2001, 2003, 2005-2007, 2009-2011 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 Paul Eggert.
+
+# st_atim.tv_nsec - Linux, Solaris, Cygwin
+# st_atimespec.tv_nsec - FreeBSD, NetBSD, if ! defined _POSIX_SOURCE
+# st_atimensec - FreeBSD, NetBSD, if defined _POSIX_SOURCE
+# st_atim.st__tim.tv_nsec - UnixWare (at least 2.1.2 through 7.1)
+
+# st_birthtimespec - FreeBSD, NetBSD (hidden on OpenBSD 3.9, anyway)
+# st_birthtim - Cygwin 1.7.0+
+
+AC_DEFUN([gl_STAT_TIME],
+[
+  AC_REQUIRE([AC_C_INLINE])
+  AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
+  AC_CHECK_HEADERS_ONCE([sys/time.h])
+
+  AC_CHECK_MEMBERS([struct stat.st_atim.tv_nsec],
+    [AC_CACHE_CHECK([whether struct stat.st_atim is of type struct timespec],
+       [ac_cv_typeof_struct_stat_st_atim_is_struct_timespec],
+       [AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
+          [[
+            #include <sys/types.h>
+            #include <sys/stat.h>
+            #if HAVE_SYS_TIME_H
+            # include <sys/time.h>
+            #endif
+            #include <time.h>
+            struct timespec ts;
+            struct stat st;
+          ]],
+          [[
+            st.st_atim = ts;
+          ]])],
+          [ac_cv_typeof_struct_stat_st_atim_is_struct_timespec=yes],
+          [ac_cv_typeof_struct_stat_st_atim_is_struct_timespec=no])])
+     if test $ac_cv_typeof_struct_stat_st_atim_is_struct_timespec = yes; then
+       AC_DEFINE([TYPEOF_STRUCT_STAT_ST_ATIM_IS_STRUCT_TIMESPEC], [1],
+         [Define to 1 if the type of the st_atim member of a struct stat is
+          struct timespec.])
+     fi],
+    [AC_CHECK_MEMBERS([struct stat.st_atimespec.tv_nsec], [],
+       [AC_CHECK_MEMBERS([struct stat.st_atimensec], [],
+          [AC_CHECK_MEMBERS([struct stat.st_atim.st__tim.tv_nsec], [], [],
+             [#include <sys/types.h>
+              #include <sys/stat.h>])],
+          [#include <sys/types.h>
+           #include <sys/stat.h>])],
+       [#include <sys/types.h>
+        #include <sys/stat.h>])],
+    [#include <sys/types.h>
+     #include <sys/stat.h>])
+])
+
+# Check for st_birthtime, a feature from UFS2 (FreeBSD, NetBSD, OpenBSD, etc.)
+# and NTFS (Cygwin).
+# There was a time when this field was named st_createtime (21 June
+# 2002 to 16 July 2002) But that window is very small and applied only
+# to development code, so systems still using that configuration are
+# not supported.  See revisions 1.10 and 1.11 of FreeBSD's
+# src/sys/ufs/ufs/dinode.h.
+#
+AC_DEFUN([gl_STAT_BIRTHTIME],
+[
+  AC_REQUIRE([AC_C_INLINE])
+  AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
+  AC_CHECK_HEADERS_ONCE([sys/time.h])
+  AC_CHECK_MEMBERS([struct stat.st_birthtimespec.tv_nsec], [],
+    [AC_CHECK_MEMBERS([struct stat.st_birthtimensec], [],
+      [AC_CHECK_MEMBERS([struct stat.st_birthtim.tv_nsec], [], [],
+         [#include <sys/types.h>
+          #include <sys/stat.h>])],
+       [#include <sys/types.h>
+        #include <sys/stat.h>])],
+    [#include <sys/types.h>
+     #include <sys/stat.h>])
+])

=== added file 'm4/strtoimax.m4'
--- m4/strtoimax.m4	1970-01-01 00:00:00 +0000
+++ m4/strtoimax.m4	2011-07-01 05:43:29 +0000
@@ -0,0 +1,23 @@
+# strtoimax.m4 serial 10
+dnl Copyright (C) 2002-2004, 2006, 2009-2011 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_STRTOIMAX],
+[
+  AC_REQUIRE([gl_INTTYPES_H_DEFAULTS])
+
+  AC_CHECK_DECLS_ONCE([strtoimax])
+  if test "$ac_cv_have_decl_strtoimax" != yes; then
+    HAVE_DECL_STRTOIMAX=0
+
+    AC_CHECK_FUNCS([strtoimax])
+  fi
+])
+
+# Prerequisites of lib/strtoimax.c.
+AC_DEFUN([gl_PREREQ_STRTOIMAX], [
+  AC_CHECK_DECLS([strtoll])
+  AC_REQUIRE([AC_TYPE_LONG_LONG_INT])
+])

=== added file 'm4/strtoll.m4'
--- m4/strtoll.m4	1970-01-01 00:00:00 +0000
+++ m4/strtoll.m4	2011-07-01 05:43:29 +0000
@@ -0,0 +1,24 @@
+# strtoll.m4 serial 7
+dnl Copyright (C) 2002, 2004, 2006, 2008-2011 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_STRTOLL],
+[
+  AC_REQUIRE([gl_STDLIB_H_DEFAULTS])
+  dnl We don't need (and can't compile) the replacement strtoll
+  dnl unless the type 'long long int' exists.
+  AC_REQUIRE([AC_TYPE_LONG_LONG_INT])
+  if test "$ac_cv_type_long_long_int" = yes; then
+    AC_CHECK_FUNCS([strtoll])
+    if test $ac_cv_func_strtoll = no; then
+      HAVE_STRTOLL=0
+    fi
+  fi
+])
+
+# Prerequisites of lib/strtoll.c.
+AC_DEFUN([gl_PREREQ_STRTOLL], [
+  :
+])

=== added file 'm4/sys_select_h.m4'
--- m4/sys_select_h.m4	1970-01-01 00:00:00 +0000
+++ m4/sys_select_h.m4	2011-07-01 05:43:29 +0000
@@ -0,0 +1,87 @@
+# sys_select_h.m4 serial 18
+dnl Copyright (C) 2006-2011 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_HEADER_SYS_SELECT],
+[
+  AC_REQUIRE([AC_C_RESTRICT])
+  AC_REQUIRE([gl_SYS_SELECT_H_DEFAULTS])
+  AC_CACHE_CHECK([whether <sys/select.h> is self-contained],
+    [gl_cv_header_sys_select_h_selfcontained],
+    [
+      dnl Test against two bugs:
+      dnl 1. On many platforms, <sys/select.h> assumes prior inclusion of
+      dnl    <sys/types.h>.
+      dnl 2. On OSF/1 4.0, <sys/select.h> provides only a forward declaration
+      dnl    of 'struct timeval', and no definition of this type.
+      AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/select.h>]],
+                                         [[struct timeval b;]])],
+        [gl_cv_header_sys_select_h_selfcontained=yes],
+        [gl_cv_header_sys_select_h_selfcontained=no])
+      dnl Test against another bug:
+      dnl 3. On Solaris 10, <sys/select.h> provides an FD_ZERO implementation
+      dnl    that relies on memset(), but without including <string.h>.
+      if test $gl_cv_header_sys_select_h_selfcontained = yes; then
+        AC_COMPILE_IFELSE(
+          [AC_LANG_PROGRAM([[#include <sys/select.h>]],
+                           [[int memset; int bzero;]])
+          ],
+          [AC_LINK_IFELSE(
+             [AC_LANG_PROGRAM([[#include <sys/select.h>]], [[
+                  #undef memset
+                  #define memset nonexistent_memset
+                  extern void *memset (void *, int, unsigned long);
+                  #undef bzero
+                  #define bzero nonexistent_bzero
+                  extern void bzero (void *, unsigned long);
+                  fd_set fds;
+                  FD_ZERO (&fds);
+                ]])
+             ],
+             [],
+             [gl_cv_header_sys_select_h_selfcontained=no])
+          ])
+      fi
+    ])
+  dnl <sys/select.h> is always overridden, because of GNULIB_POSIXCHECK.
+  gl_CHECK_NEXT_HEADERS([sys/select.h])
+  if test $ac_cv_header_sys_select_h = yes; then
+    HAVE_SYS_SELECT_H=1
+  else
+    HAVE_SYS_SELECT_H=0
+  fi
+  AC_SUBST([HAVE_SYS_SELECT_H])
+  gl_PREREQ_SYS_H_WINSOCK2
+
+  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([[
+/* Some systems require prerequisite headers.  */
+#include <sys/types.h>
+#if !(defined __GLIBC__ && !defined __UCLIBC__) && HAVE_SYS_TIME_H
+# include <sys/time.h>
+#endif
+#include <sys/select.h>
+    ]], [select])
+])
+
+AC_DEFUN([gl_SYS_SELECT_MODULE_INDICATOR],
+[
+  dnl Use AC_REQUIRE here, so that the default settings are expanded once only.
+  AC_REQUIRE([gl_SYS_SELECT_H_DEFAULTS])
+  gl_MODULE_INDICATOR_SET_VARIABLE([$1])
+  dnl Define it also as a C macro, for the benefit of the unit tests.
+  gl_MODULE_INDICATOR_FOR_TESTS([$1])
+])
+
+AC_DEFUN([gl_SYS_SELECT_H_DEFAULTS],
+[
+  GNULIB_PSELECT=0; AC_SUBST([GNULIB_PSELECT])
+  GNULIB_SELECT=0; AC_SUBST([GNULIB_SELECT])
+  dnl Assume proper GNU behavior unless another module says otherwise.
+  HAVE_PSELECT=1; AC_SUBST([HAVE_PSELECT])
+  REPLACE_PSELECT=0; AC_SUBST([REPLACE_PSELECT])
+  REPLACE_SELECT=0; AC_SUBST([REPLACE_SELECT])
+])

=== added file 'm4/sys_socket_h.m4'
--- m4/sys_socket_h.m4	1970-01-01 00:00:00 +0000
+++ m4/sys_socket_h.m4	2011-07-01 05:43:29 +0000
@@ -0,0 +1,177 @@
+# sys_socket_h.m4 serial 22
+dnl Copyright (C) 2005-2011 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 Simon Josefsson.
+
+AC_DEFUN([gl_HEADER_SYS_SOCKET],
+[
+  AC_REQUIRE([gl_SYS_SOCKET_H_DEFAULTS])
+  AC_REQUIRE([AC_CANONICAL_HOST])
+  AC_REQUIRE([AC_C_INLINE])
+
+  dnl On OSF/1, the functions recv(), send(), recvfrom(), sendto() have
+  dnl old-style declarations (with return type 'int' instead of 'ssize_t')
+  dnl unless _POSIX_PII_SOCKET is defined.
+  case "$host_os" in
+    osf*)
+      AC_DEFINE([_POSIX_PII_SOCKET], [1],
+        [Define to 1 in order to get the POSIX compatible declarations
+         of socket functions.])
+      ;;
+  esac
+
+  AC_CACHE_CHECK([whether <sys/socket.h> is self-contained],
+    [gl_cv_header_sys_socket_h_selfcontained],
+    [
+      AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/socket.h>]], [[]])],
+        [gl_cv_header_sys_socket_h_selfcontained=yes],
+        [gl_cv_header_sys_socket_h_selfcontained=no])
+    ])
+  if test $gl_cv_header_sys_socket_h_selfcontained = yes; then
+    dnl If the shutdown function exists, <sys/socket.h> should define
+    dnl SHUT_RD, SHUT_WR, SHUT_RDWR.
+    AC_CHECK_FUNCS([shutdown])
+    if test $ac_cv_func_shutdown = yes; then
+      AC_CACHE_CHECK([whether <sys/socket.h> defines the SHUT_* macros],
+        [gl_cv_header_sys_socket_h_shut],
+        [
+          AC_COMPILE_IFELSE(
+            [AC_LANG_PROGRAM([[#include <sys/socket.h>]],
+               [[int a[] = { SHUT_RD, SHUT_WR, SHUT_RDWR };]])],
+            [gl_cv_header_sys_socket_h_shut=yes],
+            [gl_cv_header_sys_socket_h_shut=no])
+        ])
+      if test $gl_cv_header_sys_socket_h_shut = no; then
+        SYS_SOCKET_H='sys/socket.h'
+      fi
+    fi
+  fi
+  # We need to check for ws2tcpip.h now.
+  gl_PREREQ_SYS_H_SOCKET
+  AC_CHECK_TYPES([struct sockaddr_storage, sa_family_t],,,[
+  /* sys/types.h is not needed according to POSIX, but the
+     sys/socket.h in i386-unknown-freebsd4.10 and
+     powerpc-apple-darwin5.5 required it. */
+#include <sys/types.h>
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_WS2TCPIP_H
+#include <ws2tcpip.h>
+#endif
+])
+  if test $ac_cv_type_struct_sockaddr_storage = no; then
+    HAVE_STRUCT_SOCKADDR_STORAGE=0
+  fi
+  if test $ac_cv_type_sa_family_t = no; then
+    HAVE_SA_FAMILY_T=0
+  fi
+  if test $ac_cv_type_struct_sockaddr_storage != no; then
+    AC_CHECK_MEMBERS([struct sockaddr_storage.ss_family],
+      [],
+      [HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY=0],
+      [#include <sys/types.h>
+       #ifdef HAVE_SYS_SOCKET_H
+       #include <sys/socket.h>
+       #endif
+       #ifdef HAVE_WS2TCPIP_H
+       #include <ws2tcpip.h>
+       #endif
+      ])
+  fi
+  if test $HAVE_STRUCT_SOCKADDR_STORAGE = 0 || test $HAVE_SA_FAMILY_T = 0 \
+     || test $HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY = 0; then
+    SYS_SOCKET_H='sys/socket.h'
+  fi
+  gl_PREREQ_SYS_H_WINSOCK2
+
+  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([[
+/* Some systems require prerequisite headers.  */
+#include <sys/types.h>
+#include <sys/socket.h>
+    ]], [socket connect accept bind getpeername getsockname getsockopt
+    listen recv send recvfrom sendto setsockopt shutdown accept4])
+])
+
+AC_DEFUN([gl_PREREQ_SYS_H_SOCKET],
+[
+  dnl Check prerequisites of the <sys/socket.h> replacement.
+  AC_REQUIRE([gl_CHECK_SOCKET_HEADERS])
+  gl_CHECK_NEXT_HEADERS([sys/socket.h])
+  if test $ac_cv_header_sys_socket_h = yes; then
+    HAVE_SYS_SOCKET_H=1
+    HAVE_WS2TCPIP_H=0
+  else
+    HAVE_SYS_SOCKET_H=0
+    if test $ac_cv_header_ws2tcpip_h = yes; then
+      HAVE_WS2TCPIP_H=1
+    else
+      HAVE_WS2TCPIP_H=0
+    fi
+  fi
+  AC_SUBST([HAVE_SYS_SOCKET_H])
+  AC_SUBST([HAVE_WS2TCPIP_H])
+])
+
+# Common prerequisites of the <sys/socket.h> replacement and of the
+# <sys/select.h> replacement.
+# Sets and substitutes HAVE_WINSOCK2_H.
+AC_DEFUN([gl_PREREQ_SYS_H_WINSOCK2],
+[
+  m4_ifdef([gl_UNISTD_H_DEFAULTS], [AC_REQUIRE([gl_UNISTD_H_DEFAULTS])])
+  m4_ifdef([gl_SYS_IOCTL_H_DEFAULTS], [AC_REQUIRE([gl_SYS_IOCTL_H_DEFAULTS])])
+  AC_CHECK_HEADERS_ONCE([sys/socket.h])
+  if test $ac_cv_header_sys_socket_h != yes; then
+    dnl We cannot use AC_CHECK_HEADERS_ONCE here, because that would make
+    dnl the check for those headers unconditional; yet cygwin reports
+    dnl that the headers are present but cannot be compiled (since on
+    dnl cygwin, all socket information should come from sys/socket.h).
+    AC_CHECK_HEADERS([winsock2.h])
+  fi
+  if test "$ac_cv_header_winsock2_h" = yes; then
+    HAVE_WINSOCK2_H=1
+    UNISTD_H_HAVE_WINSOCK2_H=1
+    SYS_IOCTL_H_HAVE_WINSOCK2_H=1
+  else
+    HAVE_WINSOCK2_H=0
+  fi
+  AC_SUBST([HAVE_WINSOCK2_H])
+])
+
+AC_DEFUN([gl_SYS_SOCKET_MODULE_INDICATOR],
+[
+  dnl Use AC_REQUIRE here, so that the default settings are expanded once only.
+  AC_REQUIRE([gl_SYS_SOCKET_H_DEFAULTS])
+  gl_MODULE_INDICATOR_SET_VARIABLE([$1])
+  dnl Define it also as a C macro, for the benefit of the unit tests.
+  gl_MODULE_INDICATOR_FOR_TESTS([$1])
+])
+
+AC_DEFUN([gl_SYS_SOCKET_H_DEFAULTS],
+[
+  GNULIB_SOCKET=0;      AC_SUBST([GNULIB_SOCKET])
+  GNULIB_CONNECT=0;     AC_SUBST([GNULIB_CONNECT])
+  GNULIB_ACCEPT=0;      AC_SUBST([GNULIB_ACCEPT])
+  GNULIB_BIND=0;        AC_SUBST([GNULIB_BIND])
+  GNULIB_GETPEERNAME=0; AC_SUBST([GNULIB_GETPEERNAME])
+  GNULIB_GETSOCKNAME=0; AC_SUBST([GNULIB_GETSOCKNAME])
+  GNULIB_GETSOCKOPT=0;  AC_SUBST([GNULIB_GETSOCKOPT])
+  GNULIB_LISTEN=0;      AC_SUBST([GNULIB_LISTEN])
+  GNULIB_RECV=0;        AC_SUBST([GNULIB_RECV])
+  GNULIB_SEND=0;        AC_SUBST([GNULIB_SEND])
+  GNULIB_RECVFROM=0;    AC_SUBST([GNULIB_RECVFROM])
+  GNULIB_SENDTO=0;      AC_SUBST([GNULIB_SENDTO])
+  GNULIB_SETSOCKOPT=0;  AC_SUBST([GNULIB_SETSOCKOPT])
+  GNULIB_SHUTDOWN=0;    AC_SUBST([GNULIB_SHUTDOWN])
+  GNULIB_ACCEPT4=0;     AC_SUBST([GNULIB_ACCEPT4])
+  HAVE_STRUCT_SOCKADDR_STORAGE=1; AC_SUBST([HAVE_STRUCT_SOCKADDR_STORAGE])
+  HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY=1;
+                        AC_SUBST([HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY])
+  HAVE_SA_FAMILY_T=1;   AC_SUBST([HAVE_SA_FAMILY_T])
+  HAVE_ACCEPT4=1;       AC_SUBST([HAVE_ACCEPT4])
+])

=== added file 'm4/sys_time_h.m4'
--- m4/sys_time_h.m4	1970-01-01 00:00:00 +0000
+++ m4/sys_time_h.m4	2011-07-01 05:43:29 +0000
@@ -0,0 +1,72 @@
+# Configure a replacement for <sys/time.h>.
+# serial 6
+
+# Copyright (C) 2007, 2009-2011 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.
+
+# Written by Paul Eggert and Martin Lambers.
+
+AC_DEFUN([gl_HEADER_SYS_TIME_H],
+[
+  dnl Use AC_REQUIRE here, so that the REPLACE_GETTIMEOFDAY=0 statement
+  dnl below is expanded once only, before all REPLACE_GETTIMEOFDAY=1
+  dnl statements that occur in other macros.
+  AC_REQUIRE([gl_HEADER_SYS_TIME_H_BODY])
+])
+
+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=0
+  fi
+
+  AC_CACHE_CHECK([for struct timeval], [gl_cv_sys_struct_timeval],
+    [AC_COMPILE_IFELSE(
+       [AC_LANG_PROGRAM(
+          [[#if HAVE_SYS_TIME_H
+             #include <sys/time.h>
+            #endif
+            #include <time.h>
+          ]],
+          [[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=0
+  fi
+
+  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])
+  gl_MODULE_INDICATOR_SET_VARIABLE([$1])
+  dnl Define it also as a C macro, for the benefit of the unit tests.
+  gl_MODULE_INDICATOR_FOR_TESTS([$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.
+  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])
+])

=== added file 'm4/timespec.m4'
--- m4/timespec.m4	1970-01-01 00:00:00 +0000
+++ m4/timespec.m4	2011-07-01 05:43:29 +0000
@@ -0,0 +1,15 @@
+#serial 14
+
+# Copyright (C) 2000-2001, 2003-2007, 2009-2011 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_TIMESPEC],
+[
+  dnl Prerequisites of lib/timespec.h.
+  AC_REQUIRE([AC_C_INLINE])
+])

=== added file 'm4/utimbuf.m4'
--- m4/utimbuf.m4	1970-01-01 00:00:00 +0000
+++ m4/utimbuf.m4	2011-07-01 05:43:29 +0000
@@ -0,0 +1,39 @@
+# serial 9
+
+# Copyright (C) 1998-2001, 2003-2004, 2007, 2009-2011 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
+
+dnl Define HAVE_STRUCT_UTIMBUF if `struct utimbuf' is declared --
+dnl usually in <utime.h>.
+dnl Some systems have utime.h but don't declare the struct anywhere.
+
+AC_DEFUN([gl_CHECK_TYPE_STRUCT_UTIMBUF],
+[
+  AC_CHECK_HEADERS_ONCE([sys/time.h utime.h])
+  AC_CACHE_CHECK([for struct utimbuf], [gl_cv_sys_struct_utimbuf],
+    [AC_COMPILE_IFELSE(
+       [AC_LANG_PROGRAM(
+          [[#if HAVE_SYS_TIME_H
+             #include <sys/time.h>
+            #endif
+            #include <time.h>
+            #ifdef HAVE_UTIME_H
+             #include <utime.h>
+            #endif
+          ]],
+          [[static struct utimbuf x; x.actime = x.modtime;]])],
+       [gl_cv_sys_struct_utimbuf=yes],
+       [gl_cv_sys_struct_utimbuf=no])])
+
+  if test $gl_cv_sys_struct_utimbuf = yes; then
+    AC_DEFINE([HAVE_STRUCT_UTIMBUF], [1],
+      [Define if struct utimbuf is declared -- usually in <utime.h>.
+       Some systems have utime.h but don't declare the struct anywhere. ])
+  fi
+])

=== added file 'm4/utimens.m4'
--- m4/utimens.m4	1970-01-01 00:00:00 +0000
+++ m4/utimens.m4	2011-07-01 05:43:29 +0000
@@ -0,0 +1,40 @@
+dnl Copyright (C) 2003-2011 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 serial 6
+
+AC_DEFUN([gl_UTIMENS],
+[
+  dnl Prerequisites of lib/utimens.c.
+  AC_REQUIRE([gl_FUNC_UTIMES])
+  AC_REQUIRE([gl_CHECK_TYPE_STRUCT_TIMESPEC])
+  AC_REQUIRE([gl_CHECK_TYPE_STRUCT_UTIMBUF])
+  AC_CHECK_FUNCS_ONCE([futimes futimesat futimens utimensat lutimes])
+
+  if test $ac_cv_func_futimens = no && test $ac_cv_func_futimesat = yes; then
+    dnl FreeBSD 8.0-rc2 mishandles futimesat(fd,NULL,time).  It is not
+    dnl standardized, but Solaris implemented it first and uses it as
+    dnl its only means to set fd time.
+    AC_CACHE_CHECK([whether futimesat handles NULL file],
+      [gl_cv_func_futimesat_works],
+      [touch conftest.file
+       AC_RUN_IFELSE([AC_LANG_PROGRAM([[
+#include <stddef.h>
+#include <sys/times.h>
+#include <fcntl.h>
+]], [[    int fd = open ("conftest.file", O_RDWR);
+          if (fd < 0) return 1;
+          if (futimesat (fd, NULL, NULL)) return 2;
+        ]])],
+        [gl_cv_func_futimesat_works=yes],
+        [gl_cv_func_futimesat_works=no],
+        [gl_cv_func_futimesat_works="guessing no"])
+      rm -f conftest.file])
+    if test "$gl_cv_func_futimesat_works" != yes; then
+      AC_DEFINE([FUTIMESAT_NULL_BUG], [1],
+        [Define to 1 if futimesat mishandles a NULL file name.])
+    fi
+  fi
+])

=== added file 'm4/utimes.m4'
--- m4/utimes.m4	1970-01-01 00:00:00 +0000
+++ m4/utimes.m4	2011-07-01 05:43:29 +0000
@@ -0,0 +1,136 @@
+# Detect some bugs in glibc's implementation of utimes.
+# serial 3
+
+dnl Copyright (C) 2003-2005, 2009-2011 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.
+
+# See if we need to work around bugs in glibc's implementation of
+# utimes from 2003-07-12 to 2003-09-17.
+# First, there was a bug that would make utimes set mtime
+# and atime to zero (1970-01-01) unconditionally.
+# Then, there was code to round rather than truncate.
+# Then, there was an implementation (sparc64, Linux-2.4.28, glibc-2.3.3)
+# that didn't honor the NULL-means-set-to-current-time semantics.
+# Finally, there was also a version of utimes that failed on read-only
+# files, while utime worked fine (linux-2.2.20, glibc-2.2.5).
+#
+# From Jim Meyering, with suggestions from Paul Eggert.
+
+AC_DEFUN([gl_FUNC_UTIMES],
+[
+  AC_CACHE_CHECK([whether the utimes function works],
+                 [gl_cv_func_working_utimes],
+  [
+  AC_RUN_IFELSE([AC_LANG_SOURCE([[
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/time.h>
+#include <time.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <utime.h>
+
+static int
+inorder (time_t a, time_t b, time_t c)
+{
+  return a <= b && b <= c;
+}
+
+int
+main ()
+{
+  int result = 0;
+  char const *file = "conftest.utimes";
+  static struct timeval timeval[2] = {{9, 10}, {999999, 999999}};
+
+  /* Test whether utimes() essentially works.  */
+  {
+    struct stat sbuf;
+    FILE *f = fopen (file, "w");
+    if (f == NULL)
+      result |= 1;
+    else if (fclose (f) != 0)
+      result |= 1;
+    else if (utimes (file, timeval) != 0)
+      result |= 2;
+    else if (lstat (file, &sbuf) != 0)
+      result |= 1;
+    else if (!(sbuf.st_atime == timeval[0].tv_sec
+               && sbuf.st_mtime == timeval[1].tv_sec))
+      result |= 4;
+    if (unlink (file) != 0)
+      result |= 1;
+  }
+
+  /* Test whether utimes() with a NULL argument sets the file's timestamp
+     to the current time.  Use 'fstat' as well as 'time' to
+     determine the "current" time, to accommodate NFS file systems
+     if there is a time skew between the host and the NFS server.  */
+  {
+    int fd = open (file, O_WRONLY|O_CREAT, 0644);
+    if (fd < 0)
+      result |= 1;
+    else
+      {
+        time_t t0, t2;
+        struct stat st0, st1, st2;
+        if (time (&t0) == (time_t) -1)
+          result |= 1;
+        else if (fstat (fd, &st0) != 0)
+          result |= 1;
+        else if (utimes (file, timeval) != 0)
+          result |= 2;
+        else if (utimes (file, NULL) != 0)
+          result |= 8;
+        else if (fstat (fd, &st1) != 0)
+          result |= 1;
+        else if (write (fd, "\n", 1) != 1)
+          result |= 1;
+        else if (fstat (fd, &st2) != 0)
+          result |= 1;
+        else if (time (&t2) == (time_t) -1)
+          result |= 1;
+        else
+          {
+            int m_ok_POSIX = inorder (t0, st1.st_mtime, t2);
+            int m_ok_NFS = inorder (st0.st_mtime, st1.st_mtime, st2.st_mtime);
+            if (! (st1.st_atime == st1.st_mtime))
+              result |= 16;
+            if (! (m_ok_POSIX || m_ok_NFS))
+              result |= 32;
+          }
+        if (close (fd) != 0)
+          result |= 1;
+      }
+    if (unlink (file) != 0)
+      result |= 1;
+  }
+
+  /* Test whether utimes() with a NULL argument works on read-only files.  */
+  {
+    int fd = open (file, O_WRONLY|O_CREAT, 0444);
+    if (fd < 0)
+      result |= 1;
+    else if (close (fd) != 0)
+      result |= 1;
+    else if (utimes (file, NULL) != 0)
+      result |= 64;
+    if (unlink (file) != 0)
+      result |= 1;
+  }
+
+  return result;
+}
+  ]])],
+       [gl_cv_func_working_utimes=yes],
+       [gl_cv_func_working_utimes=no],
+       [gl_cv_func_working_utimes=no])])
+
+  if test $gl_cv_func_working_utimes = yes; then
+    AC_DEFINE([HAVE_WORKING_UTIMES], [1], [Define if utimes works properly. ])
+  fi
+])





^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH 2/7] etc/NEWS patch for ns-resolution time stamps
  2011-07-01  6:59 nanosecond-resolution time stamps Paul Eggert
  2011-07-01  8:14 ` [PATCH 1/7] gnulib substrate for ns-resolution " Paul Eggert
@ 2011-07-01  8:14 ` Paul Eggert
  2011-07-01  8:15 ` [PATCH 3/7] Doc patches " Paul Eggert
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 18+ messages in thread
From: Paul Eggert @ 2011-07-01  8:14 UTC (permalink / raw)
  To: Emacs Development

* NEWS: Mention change to nanosecond-resolution time stamps.
=== modified file 'etc/NEWS'
--- etc/NEWS	2011-06-27 06:33:51 +0000
+++ etc/NEWS	2011-07-01 05:24:03 +0000
@@ -234,6 +234,11 @@
 *** Tramp offers handlers for file-selinux-context and set-file-selinux-context
 for remote machines which support SELinux.

+** The function current-time now returns time stamps (HIGH LOW NANOSEC)
+using nanosecond resolution instead of microsecond resolution.
+Other functions that use this format, such as file-attributes and
+format-time-string, have been changed accordingly.
+
 +++
 ** The function format-time-string now supports the %N directive, for
 higher-resolution time stamps.





^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH 3/7] Doc patches for ns-resolution time stamps
  2011-07-01  6:59 nanosecond-resolution time stamps Paul Eggert
  2011-07-01  8:14 ` [PATCH 1/7] gnulib substrate for ns-resolution " Paul Eggert
  2011-07-01  8:14 ` [PATCH 2/7] etc/NEWS patch " Paul Eggert
@ 2011-07-01  8:15 ` Paul Eggert
  2011-07-01  8:15 ` [PATCH 4/7] configure-time support " Paul Eggert
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 18+ messages in thread
From: Paul Eggert @ 2011-07-01  8:15 UTC (permalink / raw)
  To: Emacs Development

Document the change to nanosecond-resolution time stamps.
* os.texi (Time of Day, Time Parsing, Processor Run Time)
(Idle Timers):
* processes.texi (System Processes):
Time stamp resolution is now nanosecond, not microsecond.
=== modified file 'doc/lispref/os.texi'
--- doc/lispref/os.texi	2011-06-03 18:49:33 +0000
+++ doc/lispref/os.texi	2011-07-01 05:24:03 +0000
@@ -1111,7 +1111,7 @@
 as the times obtained from @code{current-time} (see below) and from
 @code{file-attributes} (@pxref{Definition of file-attributes}).  It
 should be a list whose first two elements are integers; a third
-(microsecond) element, if present, is ignored.  @var{time-value} can
+(nanosecond) element, if present, is ignored.  @var{time-value} can
 also be a cons of two integers, but this usage is obsolete.

 @example
@@ -1124,7 +1124,7 @@

 @defun current-time
 This function returns the system's time value as a list of three
-integers: @code{(@var{high} @var{low} @var{microsec})}.  The integers
+numbers: @code{(@var{high} @var{low} @var{nanosec})}.  The numbers
 @var{high} and @var{low} combine to give the number of seconds since
 0:00 January 1, 1970 UTC (Coordinated Universal Time), which is
 @ifnottex
@@ -1134,11 +1134,14 @@
 $high*2^{16}+low$.
 @end tex

-The third element, @var{microsec}, gives the microseconds since the
-start of the current second (or 0 for systems that return time with
-the resolution of only one second).
-
-The first two elements can be compared with file time values such as you
+The third number, @var{nanosec}, gives the nanoseconds since the
+start of the current second.  It may have trailing zeros on systems
+that return time with lower resolutions.
+
+The numbers are normally integers, but they are floating-point numbers
+if they are outside the integer range.
+
+The list can be compared with file time values such as you
 get with the function @code{file-attributes}.
 @xref{Definition of file-attributes}.
 @end defun
@@ -1340,8 +1343,6 @@
 This stands for the nanoseconds (000000000-999999999).  To ask for
 fewer digits, use @samp{%3N} for milliseconds, @samp{%6N} for
 microseconds, etc.  Any excess digits are discarded, without rounding.
-Currently Emacs time stamps are at best microsecond resolution so the
-last three digits generated by plain @samp{%N} are always zero.
 @item %p
 This stands for @samp{AM} or @samp{PM}, as appropriate.
 @item %r
@@ -1493,18 +1494,8 @@

 @defun get-internal-run-time
 This function returns the processor run time used by Emacs as a list
-of three integers: @code{(@var{high} @var{low} @var{microsec})}.  The
-integers @var{high} and @var{low} combine to give the number of
-seconds, which is
-@ifnottex
-@var{high} * 2**16 + @var{low}.
-@end ifnottex
-@tex
-$high*2^{16}+low$.
-@end tex
-
-The third element, @var{microsec}, gives the microseconds (or 0 for
-systems that return time with the resolution of only one second).
+of three numbers: @code{(@var{high} @var{low} @var{nanosec})}, using
+the same format as @code{current-time} (@pxref{Time of Day}).

 Note that the time returned by this function excludes the time Emacs
 was not using the processor, and if the Emacs process has several
@@ -1748,19 +1739,9 @@
 @c Emacs 19 feature
 @defun current-idle-time
 If Emacs is idle, this function returns the length of time Emacs has
-been idle, as a list of three integers: @code{(@var{high} @var{low}
-@var{microsec})}.  The integers @var{high} and @var{low} combine to
-give the number of seconds of idleness, which is
-@ifnottex
-@var{high} * 2**16 + @var{low}.
-@end ifnottex
-@tex
-$high*2^{16}+low$.
-@end tex
-
-The third element, @var{microsec}, gives the microseconds since the
-start of the current second (or 0 for systems that return time with
-the resolution of only one second).
+been idle, as a list of three numbers: @code{(@var{high} @var{low}
+@var{nanosec})}, using the same format as @code{current-time}
+(@pxref{Time of Day}).

 When Emacs is not idle, @code{current-idle-time} returns @code{nil}.
 This is a convenient way to test whether Emacs is idle.

=== modified file 'doc/lispref/processes.texi'
--- doc/lispref/processes.texi	2011-06-15 17:30:41 +0000
+++ doc/lispref/processes.texi	2011-07-01 05:24:03 +0000
@@ -1770,7 +1770,7 @@
 @item utime
 Time spent by the process in the user context, for running the
 application's code.  The corresponding @var{value} is in the
-@w{@code{(@var{high} @var{low} @var{microsec})}} format, the same
+@w{@code{(@var{high} @var{low} @var{nanosec})}} format, the same
 format used by functions @code{current-time} (@pxref{Time of Day,
 current-time}) and @code{file-attributes} (@pxref{File Attributes}).

@@ -1801,12 +1801,12 @@

 @item start
 The time when the process was started, in the same
-@w{@code{(@var{high} @var{low} @var{microsec})}} format used by
+@w{@code{(@var{high} @var{low} @var{nanosec})}} format used by
 @code{current-time} and @code{file-attributes}.

 @item etime
 The time elapsed since the process started, in the @w{@code{(@var{high}
-@var{low} @var{microsec})}} format.
+@var{low} @var{nanosec})}} format.

 @item vsize
 The virtual memory size of the process, measured in kilobytes.





^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH 4/7] configure-time support for ns-resolution time stamps
  2011-07-01  6:59 nanosecond-resolution time stamps Paul Eggert
                   ` (2 preceding siblings ...)
  2011-07-01  8:15 ` [PATCH 3/7] Doc patches " Paul Eggert
@ 2011-07-01  8:15 ` Paul Eggert
  2011-07-01  8:15 ` [PATCH 5/7] C-level " Paul Eggert
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 18+ messages in thread
From: Paul Eggert @ 2011-07-01  8:15 UTC (permalink / raw)
  To: Emacs Development

This is the hand-written part of the gnulib/autoconf stuff for
nanosecond-resolution time stamps.

Add configure-time support for nanosecond-resolution time stamps.
* Makefile.in (GNULIB_MODULES): Add dtotimespec, gettime, gettimeofday,
pselect, stat-time, strtoimax, sys_time, time, timespec-add,
timespec-sub, utimens.
* configure.in (gl_ASSERT_NO_GNULIB_POSIXCHECK)
(gl_ASSERT_NO_GNULIB_TESTS, gl_INIT): Move these up earlier, so
that the new clock stuff doesn't clash with RSVG_LIBS.
(AC_CHECK_HEADERS): Don't check for sys/select.h, sys/time.h, utime.h,
as gnulib does that for us now.
(emacs_cv_struct_utimbuf): Remove; gnulib does this.
=== modified file 'Makefile.in'
--- Makefile.in	2011-06-25 08:40:38 +0000
+++ Makefile.in	2011-07-01 05:27:05 +0000
@@ -334,9 +334,11 @@
 GNULIB_MODULES = \
   alloca-opt \
   careadlinkat crypto/md5 crypto/sha1 crypto/sha256 crypto/sha512 dtoastr \
-  dup2 \
-  filemode getloadavg getopt-gnu ignore-value intprops lstat mktime readlink \
-  socklen stdarg stdio strftime strtoumax symlink sys_stat
+  dtotimespec dup2 filemode getloadavg getopt-gnu gettime gettimeofday \
+  ignore-value intprops lstat mktime pselect readlink socklen \
+  stat-time stdarg stdio strftime strtoimax strtoumax \
+  symlink sys_stat sys_time \
+  time timespec-add timespec-sub utimens
 GNULIB_TOOL_FLAGS = \
  --conditional-dependencies --import --no-changelog --no-vc-files \
  --makefile-name=gnulib.mk

=== modified file 'configure.in'
--- configure.in	2011-06-30 14:32:07 +0000
+++ configure.in	2011-07-01 05:24:03 +0000
@@ -1103,6 +1103,13 @@
 AC_SUBST(CRT_DIR)


+# Configure gnulib before invoking PKG_CHECK_MODULES, as the latter might
+# for example add -lrt to RSVG_LIBS, which would then cause gnulib to incorrectly
+# conclude that -lrt is not needed to link clock_gettime.
+gl_ASSERT_NO_GNULIB_POSIXCHECK
+gl_ASSERT_NO_GNULIB_TESTS
+gl_INIT
+
 dnl This function definition taken from Gnome 2.0
 dnl PKG_CHECK_MODULES(GSTUFF, gtk+-2.0 >= 1.3 glib = 1.3.4, action-if, action-not)
 dnl defines GSTUFF_LIBS, GSTUFF_CFLAGS, see pkg-config man page
@@ -1210,7 +1217,7 @@
 fi

 dnl checks for header files
-AC_CHECK_HEADERS(sys/select.h sys/time.h unistd.h utime.h \
+AC_CHECK_HEADERS(unistd.h \
   linux/version.h sys/systeminfo.h limits.h \
   stdio_ext.h fcntl.h coff.h pty.h sys/mman.h \
   sys/vlimit.h sys/resource.h locale.h sys/_mbstate_t.h \
@@ -1243,26 +1250,6 @@
 fi
 AC_HEADER_SYS_WAIT

-dnl Some systems have utime.h but don't declare the struct anyplace.
-AC_CACHE_CHECK(for struct utimbuf, emacs_cv_struct_utimbuf,
-AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#ifdef TIME_WITH_SYS_TIME
-#include <sys/time.h>
-#include <time.h>
-#else
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#else
-#include <time.h>
-#endif
-#endif
-#ifdef HAVE_UTIME_H
-#include <utime.h>
-#endif]], [[static struct utimbuf x; x.actime = x.modtime;]])],
-  emacs_cv_struct_utimbuf=yes, emacs_cv_struct_utimbuf=no))
-if test $emacs_cv_struct_utimbuf = yes; then
-  AC_DEFINE(HAVE_STRUCT_UTIMBUF, 1, [Define to 1 if `struct utimbuf' is declared by <utime.h>.])
-fi
-
 dnl Check for speed_t typedef.
 AC_CACHE_CHECK(for speed_t, emacs_cv_speed_t,
   [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <termios.h>]], [[speed_t x = 1;]])],
@@ -1272,23 +1259,6 @@
   	   [Define to 1 if `speed_t' is declared by <termios.h>.])
 fi

-AC_CACHE_CHECK(for struct timeval, emacs_cv_struct_timeval,
-AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#ifdef TIME_WITH_SYS_TIME
-#include <sys/time.h>
-#include <time.h>
-#else
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#else
-#include <time.h>
-#endif
-#endif]], [[static struct timeval x; x.tv_sec = x.tv_usec;]])],
-  emacs_cv_struct_timeval=yes, emacs_cv_struct_timeval=no))
-HAVE_TIMEVAL=$emacs_cv_struct_timeval
-if test $emacs_cv_struct_timeval = yes; then
-  AC_DEFINE(HAVE_TIMEVAL, 1, [Define to 1 if `struct timeval' is declared by <sys/time.h>.])
-fi
-
 AC_CACHE_CHECK(for struct exception, emacs_cv_struct_exception,
 AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <math.h>]],
 [[static struct exception x; x.arg1 = x.arg2 = x.retval; x.name = ""; x.type = 1;]])],
@@ -2701,7 +2671,7 @@
 rename closedir mkdir rmdir sysinfo getrusage get_current_dir_name \
 random lrand48 logb frexp fmod rint cbrt ftime setsid \
 strerror fpathconf select euidaccess getpagesize tzset setlocale \
-utimes getrlimit setrlimit setpgid getcwd getwd shutdown getaddrinfo \
+getrlimit setrlimit setpgid getcwd getwd shutdown getaddrinfo \
 __fpending mblen mbrlen mbsinit strsignal setitimer ualarm strchr strrchr \
 sendto recvfrom getsockopt setsockopt getsockname getpeername \
 gai_strerror mkstemp getline getdelim mremap memmove fsync sync \
@@ -2725,11 +2695,6 @@

 AC_FUNC_GETPGRP

-# Configure gnulib.
-gl_ASSERT_NO_GNULIB_POSIXCHECK
-gl_ASSERT_NO_GNULIB_TESTS
-gl_INIT
-
 # UNIX98 PTYs.
 AC_CHECK_FUNCS(grantpt)

@@ -3019,33 +2984,6 @@
 	    [Define to 1 if localtime caches TZ.])
 fi

-if test "x$HAVE_TIMEVAL" = xyes; then
-  AC_CHECK_FUNCS(gettimeofday)
-  if test $ac_cv_func_gettimeofday = yes; then
-    AC_CACHE_CHECK(whether gettimeofday can accept two arguments,
-		   emacs_cv_gettimeofday_two_arguments,
-    [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
-#ifdef TIME_WITH_SYS_TIME
-#include <sys/time.h>
-#include <time.h>
-#else
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#else
-#include <time.h>
-#endif
-#endif]],
-      [[struct timeval time;
-       gettimeofday (&time, 0);]])],
-      emacs_cv_gettimeofday_two_arguments=yes,
-      emacs_cv_gettimeofday_two_arguments=no)])
-    if test $emacs_cv_gettimeofday_two_arguments = no; then
-      AC_DEFINE(GETTIMEOFDAY_ONE_ARGUMENT, 1,
-		[Define to 1 if gettimeofday accepts only one argument.])
-    fi
-  fi
-fi
-
 ok_so_far=yes
 AC_CHECK_FUNC(socket, , ok_so_far=no)
 if test $ok_so_far = yes; then





^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH 5/7] C-level support for ns-resolution time stamps
  2011-07-01  6:59 nanosecond-resolution time stamps Paul Eggert
                   ` (3 preceding siblings ...)
  2011-07-01  8:15 ` [PATCH 4/7] configure-time support " Paul Eggert
@ 2011-07-01  8:15 ` Paul Eggert
  2011-07-01  8:16 ` [PATCH 6/7] lib-src " Paul Eggert
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 18+ messages in thread
From: Paul Eggert @ 2011-07-01  8:15 UTC (permalink / raw)
  To: Emacs Development

This is the core of the patches; it affects the src subdirectory.

Add support for nanosecond-resolution time stamps.

* Makefile.in (LIB_CLOCK_GETTIME): New macro.
(LIBES): Use it.

* alloc.c (Fgarbage_collect): Port to ns-resolution time stamps.
Don't get current time unless it's needed.

* atimer.c: Include <sys/time.h> unconditionally, since gnulib
now provides it if it's absent.
(start_atimer): Port to ns-resolution time stamps.
Check for time stamp overflow.  Don't get current time more
often than is needed.

* buffer.c (reset_buffer):
* buffer.h (struct buffer): Buffer modtime now has ns resolution.
Include systime.h, not time.h.
(NONEXISTENT_MODTIME_NSECS, UNKNOWN_MODTIME_NSECS)
(OK_MODTIME_NSECS): New macros.

* dired.c: Include stat-time.h.
(Ffile-attributes): File times now have ns resolution.

* dispextern.h [HAVE_WINDOW_SYSTEM]: Include systime.h.
(struct image): Timestamp now has ns resolution.

* dispnew.c (PERIODIC_PREEMPTION_CHECKING): Remove, as Emacs always
has at least microseconds now.  All uses removed.
(update_frame, update_single_window, update_window, update_frame_1)
(Fsleep_for, sit_for): Port to ns-resolution time stamps.

* editfns.c (time_overflow): Now extern.
(hi_time, lo_time): Now return Lisp_Object, for convenience.
Do not assume high order part of time stamp fits in fixnum; it
doesn't, on some hosts.
(Fcurrent_time, get-internal-run-time, make_time, lisp_time_argument)
(float-time, Fformat_time_string, Fcurrent_time_string)
(Fcurrent_time_zone): Accept and generate ns-resolution time stamps.
(make_time_tail, make_lisp_time, dissassemble_lisp_time)
(decode_time_components, lisp_seconds_argument): New functions.
(make_time): Now static.
(lisp_time_argument): Now returns EMACS_TIME.  New arg ns_lower_bound.
Report an error if the time is invalid, rather than having the caller
do that.
(Fformat_time_string): Check for string overflow in a place it
was missed.  Allow floating-point year numbers (for really large
years).  Check for time overflow with large years (either integer
or floating point).

* fileio.c: Include <stat-time.h>
(Fcopy_file): Copy ns-resolution time stamps.
Prefer to set the time stamp via a file descriptor if that works.
(Fset_file_times, Finsert_file_contents, Fwrite_region)
(Fverify_visited_file_modtime, Fclear_visited_file_modtime)
(Fvisited_file_modtime, Fset_visited_file_modtime):
Support ns-resolution time stamps.

* gtkutil.c (xg_maybe_add_timer): Port to ns-resolution time stamps.

* image.c (prepare_image_for_display, clear_image_cache)
(lookup_image): Port to ns-resolution time stamps.

* keyboard.c (start_polling, bind_polling_period):
Check for time stamp overflow.
(read_char, kbd_buffer_get_event, timer_start_idle)
(timer_stop_idle, timer_resume_idle, timer_check_2, timer_check)
(Fcurrent_idle_time, init_keyboard, set_waiting_for_input):
Port to ns-resolution time stamps.  Do not assume time_t is signed.


* nsterm.m (select_timeout, timeval_subtract): Remove.
(ns_timeout): Use Emacs's facilities for time stamp arithmetic,
as they're a bit more accurate and handle overflow better.
(ns_select): Change prototype to be compatible with pselect.
(ns_select, ns_term_shutdown): Port to ns-resolution time stamps.
* nsterm.h (ns_select): Adjust prototype.

* msdos.c (EMACS_TIME_ZERO_OR_NEG_P): Remove, as it assumes
us-resolution time stamps.
(sys_select): Use the new EMACS_TIME_SIGN macro instead.

* lread.c (read_filtered_event): Port to ns-resolution time stamps.

* lisp.h (time_overflow): New decl.
(wait_reading_process_output): First arg is now intmax_t, not int,
to accommodate larger waits.

* process.h (struct Lisp_Process.read_output_delay):
Now counts nanoseconds, not microseconds.
* process.c (ADAPTIVE_READ_BUFFERING): Don't worry about
EMACS_HAS_USECS.
(READ_OUTPUT_DELAY_INCREMENT, Faccept_process_output)
(wait_reading_process_output):
Port to ns-resolution time stamps.
(Faccept_process_output, wait_reading_process_output):
Check for time stamp overflow.  Do not assume time_t is signed.
(select_wrapper): Remove; we now use pselect.
(Fprocess_attributes): Now generates ns-resolution time stamps.

* sysdep.c: Include utimens.h.  Don't include utime.h
or worry about struct utimbuf; gnulib does that for us now.
(gettimeofday): Remove; gnulib provides a substitute.
(make_timeval): New function.
(set_file_times): Now sets ns-resolution time stamps.
New arg FD; all uses changed.
(time_from_jiffies, ltime_from_jiffies, get_up_time)
(system_process_attributes):
Now returns ns-resolution time stamp.  All uses changed.
Check for time stamp overflow.

* sysselect.h: Don't depend on HAVE_SYS_SELECT_H; gnulib
provides a substitute now.

* systime.h: Include timespec.h rather than sys/time.h and time.h,
since it guarantees struct timespec.
(EMACS_TIME): Now struct timespec, so that we can support
ns-resolution time stamps.
(EMACS_TIME_RESOLUTION, LOG10_EMACS_TIME_RESOLUTION): New macros.
(EMACS_HAS_USECS): Remove; Emacs always has sub-second time stamps now.
(EMACS_USECS): Remove.
(EMACS_SET_USECS): The underlying time stamp now has ns resolution,
so multiply the arg by 1000 before storing it.
(EMACS_NSECS, EMACS_SECS_ADDR, EMACS_SET_NSECS, EMACS_SET_SECS_NSECS):
New macros.
(EMACS_GET_TIME, EMACS_ADD_TIME, EMACS_SUB_TIME):
Port to ns-resolution time stamps.
(EMACS_TIME_NEG_P): Remove; replaced by....
(EMACS_TIME_SIGN): New macro.
(EMACS_SET_INVALID_TIME, EMACS_TIME_VALID_P)
(EMACS_TIME_FROM_DOUBLE, EMACS_TIME_TO_DOUBLE): New macros.
(set_file_times, make_time, lisp_time_argument): Adjust signature.
(make_timeval, make_lisp_time, decode_time_components): New decls.
(EMACS_TIME_CMP): Remove; no longer used.  Plus, it was buggy, in
that it mishandled time_t overflow.  You can't compare by subtracting!
(EMACS_TIME_EQ, EMACS_TIME_NE, EMACS_TIME_GT, EMACS_TIME_GE)
(EMACS_TIME_LT, EMACS_TIME_LE): Rewrite in terms of timespec_cmp.

* term.c: Include <sys/time.h>.
(timeval_to_Time): New function, for proper overflow wraparound.
(term_mouse_position, term_mouse_click): Use it.

* undo.c (record_first_change): Put ns-resolution time stamps
into the undo buffer.
(Fprimitive_undo): Use them when restoring time stamps.

* w32.c (ltime, U64_TO_LISP_TIME, process_times, emacs_gnutls_pull):
Port to ns-resolution Emacs time stamps.

* xdisp.c (start_hourglass): Port to ns-resolution time stamps.

* xgselect.c, xgselect.h (xg_select): Add sigmask argument,
for compatibility with pselect.  Support ns-resolution time stamps.

* xmenu.c (x_menu_wait_for_event): Support ns-resolution time stamps.

* xselect.c (wait_for_property_change, x_get_foreign_selection):
Check for time stamp overflow, and support ns-resolution time stamps.

* xterm.c: Don't include sys/time.h; gnulib does that for us now.
Don't worry about whether HAVE_TIMEVAL and HAVE_SELECT are set.
(timeval_subtract): Remove; no longer needed.
(XTflash, XTring_bell, x_wait_for_event):
Port to ns-resolution time stamps.  Don't assume time_t is signed.
=== modified file 'src/Makefile.in'
--- src/Makefile.in	2011-06-30 14:00:26 +0000
+++ src/Makefile.in	2011-07-01 05:24:22 +0000
@@ -147,6 +147,8 @@
 M17N_FLT_CFLAGS = @M17N_FLT_CFLAGS@
 M17N_FLT_LIBS = @M17N_FLT_LIBS@

+LIB_CLOCK_GETTIME=@LIB_CLOCK_GETTIME@
+
 DBUS_CFLAGS = @DBUS_CFLAGS@
 DBUS_LIBS = @DBUS_LIBS@
 ## dbusbind.o if HAVE_DBUS, else empty.
@@ -379,7 +381,7 @@
 ## duplicated symbols.  If the standard libraries were compiled
 ## with GCC, we might need LIB_GCC again after them.
 LIBES = $(LIBS) $(LIBX_BASE) $(LIBX_OTHER) $(LIBSOUND) \
-   $(RSVG_LIBS) $(IMAGEMAGICK_LIBS) $(DBUS_LIBS) \
+   $(RSVG_LIBS) $(IMAGEMAGICK_LIBS) $(LIB_CLOCK_GETTIME) $(DBUS_LIBS) \
    $(LIBXML2_LIBS) $(LIBGPM) $(LIBRESOLV) $(LIBS_SYSTEM) \
    $(LIBS_TERMCAP) $(GETLOADAVG_LIBS) $(SETTINGS_LIBS) $(LIBSELINUX_LIBS) \
    $(FREETYPE_LIBS) $(FONTCONFIG_LIBS) $(LIBOTF_LIBS) $(M17N_FLT_LIBS) \

=== modified file 'src/alloc.c'
--- src/alloc.c	2011-06-24 21:25:22 +0000
+++ src/alloc.c	2011-07-01 05:24:22 +0000
@@ -5159,12 +5159,14 @@
     }

   /* Accumulate statistics.  */
-  EMACS_GET_TIME (t2);
-  EMACS_SUB_TIME (t3, t2, t1);
   if (FLOATP (Vgc_elapsed))
-    Vgc_elapsed = make_float (XFLOAT_DATA (Vgc_elapsed) +
-			      EMACS_SECS (t3) +
-			      EMACS_USECS (t3) * 1.0e-6);
+    {
+      EMACS_GET_TIME (t2);
+      EMACS_SUB_TIME (t3, t2, t1);
+      Vgc_elapsed = make_float (XFLOAT_DATA (Vgc_elapsed)
+				+ EMACS_TIME_TO_DOUBLE (t3));
+    }
+
   gcs_done++;

   return Flist (sizeof total / sizeof *total, total);

=== modified file 'src/atimer.c'
--- src/atimer.c	2011-04-11 06:04:34 +0000
+++ src/atimer.c	2011-07-01 05:24:23 +0000
@@ -26,10 +26,7 @@
 #include "blockinput.h"
 #include "atimer.h"
 #include <unistd.h>
-
-#ifdef HAVE_SYS_TIME_H
 #include <sys/time.h>
-#endif

 /* Free-list of atimer structures.  */

@@ -94,7 +91,8 @@
   /* Round TIME up to the next full second if we don't have
      itimers.  */
 #ifndef HAVE_SETITIMER
-  if (EMACS_USECS (timestamp) != 0)
+  if (EMACS_NSECS (timestamp) != 0
+      && EMACS_SECS (timestamp) < TYPE_MAXIMUM (time_t))
     {
       EMACS_SET_USECS (timestamp, 0);
       EMACS_SET_SECS (timestamp, EMACS_SECS (timestamp) + 1);
@@ -294,18 +292,21 @@

       /* Determine s/us till the next timer is ripe.  */
       EMACS_GET_TIME (now);
-      EMACS_SUB_TIME (timestamp, atimers->expiration, now);

-#ifdef HAVE_SETITIMER
       /* Don't set the interval to 0; this disables the timer.  */
       if (EMACS_TIME_LE (atimers->expiration, now))
 	{
 	  EMACS_SET_SECS (timestamp, 0);
 	  EMACS_SET_USECS (timestamp, 1000);
 	}
+      else
+	EMACS_SUB_TIME (timestamp, atimers->expiration, now);
+
+
+#ifdef HAVE_SETITIMER

       memset (&it, 0, sizeof it);
-      it.it_value = timestamp;
+      it.it_value = make_timeval (timestamp);
       setitimer (ITIMER_REAL, &it, 0);
 #else /* not HAVE_SETITIMER */
       alarm (max (EMACS_SECS (timestamp), 1));
@@ -341,11 +342,10 @@
 {
   EMACS_TIME now;

-  EMACS_GET_TIME (now);
-
   while (atimers
 	 && (pending_atimers = interrupt_input_blocked) == 0
-	 && EMACS_TIME_LE (atimers->expiration, now))
+	 && (EMACS_GET_TIME (now),
+	     EMACS_TIME_LE (atimers->expiration, now)))
     {
       struct atimer *t;

@@ -363,8 +363,6 @@
 	  t->next = free_atimers;
 	  free_atimers = t;
 	}
-
-      EMACS_GET_TIME (now);
     }

   if (! atimers)

=== modified file 'src/buffer.c'
--- src/buffer.c	2011-06-27 09:27:44 +0000
+++ src/buffer.c	2011-07-01 05:24:23 +0000
@@ -714,7 +714,7 @@
   BVAR (b, filename) = Qnil;
   BVAR (b, file_truename) = Qnil;
   BVAR (b, directory) = (current_buffer) ? BVAR (current_buffer, directory) : Qnil;
-  b->modtime = 0;
+  EMACS_SET_SECS_NSECS (b->modtime, 0, UNKNOWN_MODTIME_NSECS);
   b->modtime_size = -1;
   XSETFASTINT (BVAR (b, save_length), 0);
   b->last_window_start = 1;
@@ -5860,9 +5860,9 @@
 from (abs POSITION).  If POSITION is positive, point was at the front
 of the text being deleted; if negative, point was at the end.

-An entry (t HIGH . LOW) indicates that the buffer previously had
-\"unmodified\" status.  HIGH and LOW are the high and low 16-bit portions
-of the visited file's modification time, as of that time.  If the
+An entry (t HIGH LOW NSEC) indicates that the buffer was previously
+unmodified; (HIGH LOW NSEC) are in the same style as (current-time)
+and are the visited file's modification time, as of that time.  If the
 modification time of the most recent save is different, this entry is
 obsolete.


=== modified file 'src/buffer.h'
--- src/buffer.h	2011-06-21 21:32:10 +0000
+++ src/buffer.h	2011-07-01 05:24:23 +0000
@@ -18,7 +18,7 @@
 You should have received a copy of the GNU General Public License
 along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */

-#include <time.h> /* for time_t */
+#include "systime.h" /* for EMACS_TIME */

 /* Accessing the parameters of the current buffer.  */

@@ -550,10 +550,14 @@
   char local_flags[MAX_PER_BUFFER_VARS];

   /* Set to the modtime of the visited file when read or written.
-     -1 means visited file was nonexistent.
-     0 means visited file modtime unknown; in no case complain
-     about any mismatch on next save attempt.  */
-  time_t modtime;
+     EMACS_NSECS (modtime) == NONEXISTENT_MODTIME_NSECS means
+     visited file was nonexistent.  EMACS_NSECS (modtime) ==
+     UNKNOWN_MODTIME_NSECS means visited file modtime unknown;
+     in no case complain about any mismatch on next save attempt.  */
+#define NONEXISTENT_MODTIME_NSECS (-1)
+#define UNKNOWN_MODTIME_NSECS (-2)
+#define OK_MODTIME_NSECS(ns) (0 <= (ns))
+  EMACS_TIME modtime;
   /* Size of the file when modtime was set.  This is used to detect the
      case where the file grew while we were reading it, so the modtime
      is still the same (since it's rounded up to seconds) but we're actually

=== modified file 'src/dired.c'
--- src/dired.c	2011-06-24 21:25:22 +0000
+++ src/dired.c	2011-07-01 05:24:23 +0000
@@ -62,6 +62,7 @@
 #endif /* HAVE_DIRENT_H */

 #include <filemode.h>
+#include <stat-time.h>

 #ifdef MSDOS
 #define DIRENTRY_NONEMPTY(p) ((p)->d_name[0] != 0)
@@ -889,8 +890,8 @@
  2. File uid as a string or a number.  If a string value cannot be
   looked up, a numeric value, either an integer or a float, is returned.
  3. File gid, likewise.
- 4. Last access time, as a list of two integers.
-  First integer has high-order 16 bits of time, second has low 16 bits.
+ 4. Last access time, as a list of three numbers (HIGH LOW NSEC) in the
+  same style as (current-time).
   (See a note below about access time on FAT-based filesystems.)
  5. Last modification time, likewise.  This is the time of the last
   change to the file's contents.
@@ -975,9 +976,9 @@
   else
     values[3] = make_fixnum_or_float (s.st_gid);

-  values[4] = make_time (s.st_atime);
-  values[5] = make_time (s.st_mtime);
-  values[6] = make_time (s.st_ctime);
+  values[4] = make_lisp_time (get_stat_atime (&s));
+  values[5] = make_lisp_time (get_stat_mtime (&s));
+  values[6] = make_lisp_time (get_stat_ctime (&s));

   /* If the file size is a 4-byte type, assume that files of sizes in
      the 2-4 GiB range wrap around to negative values, as this is a

=== modified file 'src/dispextern.h'
--- src/dispextern.h	2011-06-22 18:15:23 +0000
+++ src/dispextern.h	2011-07-01 05:24:23 +0000
@@ -68,6 +68,10 @@
 typedef XImagePtr XImagePtr_or_DC;
 #endif

+#ifdef HAVE_WINDOW_SYSTEM
+# include "systime.h"
+#endif
+
 #ifndef HAVE_WINDOW_SYSTEM
 typedef int Cursor;
 #define No_Cursor (0)
@@ -2719,7 +2723,7 @@
 {
   /* The time in seconds at which the image was last displayed.  Set
      in prepare_image_for_display.  */
-  time_t timestamp;
+  EMACS_TIME timestamp;

   /* Pixmaps of the image.  */
   Pixmap pixmap, mask;

=== modified file 'src/dispnew.c'
--- src/dispnew.c	2011-06-25 18:21:00 +0000
+++ src/dispnew.c	2011-07-01 05:24:23 +0000
@@ -169,24 +169,11 @@
 static void adjust_frame_glyphs_for_frame_redisplay (struct frame *);

 \f
-/* Define PERIODIC_PREEMPTION_CHECKING to 1, if micro-second timers
-   are supported, so we can check for input during redisplay at
-   regular intervals.  */
-#ifdef EMACS_HAS_USECS
-#define PERIODIC_PREEMPTION_CHECKING 1
-#else
-#define PERIODIC_PREEMPTION_CHECKING 0
-#endif
-
-#if PERIODIC_PREEMPTION_CHECKING
-
 /* Redisplay preemption timers.  */

 static EMACS_TIME preemption_period;
 static EMACS_TIME preemption_next_check;

-#endif
-
 /* Nonzero upon entry to redisplay means do not assume anything about
    current contents of actual terminal frame; clear and redraw it.  */

@@ -3227,14 +3214,12 @@

   if (redisplay_dont_pause)
     force_p = 1;
-#if PERIODIC_PREEMPTION_CHECKING
   else if (NILP (Vredisplay_preemption_period))
     force_p = 1;
   else if (!force_p && NUMBERP (Vredisplay_preemption_period))
     {
       EMACS_TIME tm;
       double p = XFLOATINT (Vredisplay_preemption_period);
-      int sec, usec;

       if (detect_input_pending_ignore_squeezables ())
 	{
@@ -3242,14 +3227,10 @@
 	  goto do_pause;
 	}

-      sec = (int) p;
-      usec = (p - sec) * 1000000;
-
       EMACS_GET_TIME (tm);
-      EMACS_SET_SECS_USECS (preemption_period, sec, usec);
+      preemption_period = EMACS_TIME_FROM_DOUBLE (p);
       EMACS_ADD_TIME (preemption_next_check, tm, preemption_period);
     }
-#endif

   if (FRAME_WINDOW_P (f))
     {
@@ -3333,9 +3314,7 @@
 #endif
     }

-#if PERIODIC_PREEMPTION_CHECKING
  do_pause:
-#endif
   /* Reset flags indicating that a window should be updated.  */
   set_window_update_flags (root_window, 0);

@@ -3388,23 +3367,17 @@

       if (redisplay_dont_pause)
 	force_p = 1;
-#if PERIODIC_PREEMPTION_CHECKING
       else if (NILP (Vredisplay_preemption_period))
 	force_p = 1;
       else if (!force_p && NUMBERP (Vredisplay_preemption_period))
 	{
 	  EMACS_TIME tm;
 	  double p = XFLOATINT (Vredisplay_preemption_period);
-	  int sec, usec;
-
-	  sec = (int) p;
-	  usec = (p - sec) * 1000000;

 	  EMACS_GET_TIME (tm);
-	  EMACS_SET_SECS_USECS (preemption_period, sec, usec);
+	  preemption_period = EMACS_TIME_FROM_DOUBLE (p);
 	  EMACS_ADD_TIME (preemption_next_check, tm, preemption_period);
 	}
-#endif

       /* Update W.  */
       update_begin (f);
@@ -3649,10 +3622,9 @@
 #if PERIODIC_PREEMPTION_CHECKING
 	    if (!force_p)
 	      {
-		EMACS_TIME tm, dif;
+		EMACS_TIME tm;
 		EMACS_GET_TIME (tm);
-		EMACS_SUB_TIME (dif, preemption_next_check, tm);
-		if (EMACS_TIME_NEG_P (dif))
+		if (EMACS_TIME_LT (preemption_next_check, tm))
 		  {
 		    EMACS_ADD_TIME (preemption_next_check, tm, preemption_period);
 		    if (detect_input_pending_ignore_squeezables ())
@@ -4680,10 +4652,9 @@
 #if PERIODIC_PREEMPTION_CHECKING
 	  if (!force_p)
 	    {
-	      EMACS_TIME tm, dif;
+	      EMACS_TIME tm;
 	      EMACS_GET_TIME (tm);
-	      EMACS_SUB_TIME (dif, preemption_next_check, tm);
-	      if (EMACS_TIME_NEG_P (dif))
+	      if (EMACS_TIME_LT (preemption_next_check, tm))
 		{
 		  EMACS_ADD_TIME (preemption_next_check, tm, preemption_period);
 		  if (detect_input_pending_ignore_squeezables ())
@@ -5890,46 +5861,24 @@
        doc: /* Pause, without updating display, for SECONDS seconds.
 SECONDS may be a floating-point value, meaning that you can wait for a
 fraction of a second.  Optional second arg MILLISECONDS specifies an
-additional wait period, in milliseconds; this may be useful if your
-Emacs was built without floating point support.
+additional wait period, in milliseconds; this is for backwards compatibility.
 \(Not all operating systems support waiting for a fraction of a second.)  */)
   (Lisp_Object seconds, Lisp_Object milliseconds)
 {
-  int sec, usec;
-
-  if (NILP (milliseconds))
-    XSETINT (milliseconds, 0);
-  else
-    CHECK_NUMBER (milliseconds);
-  usec = XINT (milliseconds) * 1000;
-
-  {
-    double duration = extract_float (seconds);
-    sec = (int) duration;
-    usec += (duration - sec) * 1000000;
-  }
-
-#ifndef EMACS_HAS_USECS
-  if (sec == 0 && usec != 0)
-    error ("Millisecond `sleep-for' not supported on %s", SYSTEM_TYPE);
-#endif
-
-  /* Assure that 0 <= usec < 1000000.  */
-  if (usec < 0)
-    {
-      /* We can't rely on the rounding being correct if usec is negative.  */
-      if (-1000000 < usec)
-	sec--, usec += 1000000;
-      else
-	sec -= -usec / 1000000, usec = 1000000 - (-usec % 1000000);
-    }
-  else
-    sec += usec / 1000000, usec %= 1000000;
-
-  if (sec < 0 || (sec == 0 && usec == 0))
-    return Qnil;
-
-  wait_reading_process_output (sec, usec, 0, 0, Qnil, NULL, 0);
+  double duration = extract_float (seconds);
+
+  if (!NILP (milliseconds))
+    {
+      CHECK_NUMBER (milliseconds);
+      duration += XINT (milliseconds) / 1000.0;
+    }
+
+  if (0 < duration)
+    {
+      EMACS_TIME t = EMACS_TIME_FROM_DOUBLE (duration);
+      wait_reading_process_output (min (EMACS_SECS (t), INTMAX_MAX),
+				   EMACS_NSECS (t), 0, 0, Qnil, NULL, 0);
+    }

   return Qnil;
 }
@@ -5948,7 +5897,9 @@
 Lisp_Object
 sit_for (Lisp_Object timeout, int reading, int do_display)
 {
-  int sec, usec;
+  EMACS_TIME t;
+  intmax_t sec;
+  int nsec;

   swallow_events (do_display);

@@ -5962,30 +5913,36 @@
   if (INTEGERP (timeout))
     {
       sec = XINT (timeout);
-      usec = 0;
+      if (! (0 < sec))
+	return Qt;
+      nsec = 0;
     }
   else if (FLOATP (timeout))
     {
       double seconds = XFLOAT_DATA (timeout);
-      sec = (int) seconds;
-      usec = (int) ((seconds - sec) * 1000000);
+      if (! (0 < seconds))
+	return Qt;
+      else
+	{
+	  EMACS_TIME t = EMACS_TIME_FROM_DOUBLE (seconds);
+	  sec = min (EMACS_SECS (t), INTMAX_MAX);
+	  nsec = EMACS_NSECS (t);
+	}
     }
   else if (EQ (timeout, Qt))
     {
       sec = 0;
-      usec = 0;
+      nsec = 0;
     }
   else
     wrong_type_argument (Qnumberp, timeout);

-  if (sec == 0 && usec == 0 && !EQ (timeout, Qt))
-    return Qt;

 #ifdef SIGIO
   gobble_input (0);
 #endif

-  wait_reading_process_output (sec, usec, reading ? -1 : 1, do_display,
+  wait_reading_process_output (sec, nsec, reading ? -1 : 1, do_display,
 			       Qnil, NULL, 0);

   return detect_input_pending () ? Qnil : Qt;

=== modified file 'src/editfns.c'
--- src/editfns.c	2011-06-24 21:25:22 +0000
+++ src/editfns.c	2011-07-01 05:24:23 +0000
@@ -84,7 +84,6 @@
 extern Lisp_Object w32_get_internal_run_time (void);
 #endif

-static void time_overflow (void) NO_RETURN;
 static int tm_diff (struct tm *, struct tm *);
 static void update_buffer_properties (EMACS_INT, EMACS_INT);

@@ -1402,15 +1401,14 @@
 #endif

 /* Report that a time value is out of range for Emacs.  */
-static void
+void
 time_overflow (void)
 {
   error ("Specified time is not representable");
 }

-/* Return the upper part of the time T (everything but the bottom 16 bits),
-   making sure that it is representable.  */
-static EMACS_INT
+/* Return the upper part of the time T (everything but the bottom 16 bits).  */
+static Lisp_Object
 hi_time (time_t t)
 {
   time_t hi = t >> 16;
@@ -1418,59 +1416,53 @@
   /* Check for overflow, helping the compiler for common cases where
      no runtime check is needed, and taking care not to convert
      negative numbers to unsigned before comparing them.  */
-  if (! ((! TYPE_SIGNED (time_t)
-	  || MOST_NEGATIVE_FIXNUM <= TIME_T_MIN >> 16
-	  || MOST_NEGATIVE_FIXNUM <= hi)
-	 && (TIME_T_MAX >> 16 <= MOST_POSITIVE_FIXNUM
-	     || hi <= MOST_POSITIVE_FIXNUM)))
-    time_overflow ();
-
-  return hi;
+  if ((! TYPE_SIGNED (time_t)
+       || MOST_NEGATIVE_FIXNUM <= TIME_T_MIN >> 16
+       || MOST_NEGATIVE_FIXNUM <= hi)
+      && (TIME_T_MAX >> 16 <= MOST_POSITIVE_FIXNUM
+	  || hi <= MOST_POSITIVE_FIXNUM))
+    return make_number (hi);
+  else
+    return make_float (hi);
 }

 /* Return the bottom 16 bits of the time T.  */
-static EMACS_INT
+static Lisp_Object
 lo_time (time_t t)
 {
-  return t & ((1 << 16) - 1);
+  return make_number (t & ((1 << 16) - 1));
 }

 DEFUN ("current-time", Fcurrent_time, Scurrent_time, 0, 0, 0,
        doc: /* Return the current time, as the number of seconds since 1970-01-01 00:00:00.
-The time is returned as a list of three integers.  The first has the
-most significant 16 bits of the seconds, while the second has the
-least significant 16 bits.  The third integer gives the microsecond
-count.
-
-The microsecond count is zero on systems that do not provide
-resolution finer than a second.  */)
+The time is returned as a list (HIGH LOW NSEC).  HIGH has the most
+significant bits of the seconds, while LOW has the least significant
+16 bits.  NSEC gives the nanosecond count.  All three values are integers,
+except that the HIGH and NSEC may be floating-point on systems that
+cannot represent large-enough integers.  */)
   (void)
 {
   EMACS_TIME t;

   EMACS_GET_TIME (t);
-  return list3 (make_number (hi_time (EMACS_SECS (t))),
-		make_number (lo_time (EMACS_SECS (t))),
-		make_number (EMACS_USECS (t)));
+  return make_lisp_time (t);
 }

 DEFUN ("get-internal-run-time", Fget_internal_run_time, Sget_internal_run_time,
        0, 0, 0,
        doc: /* Return the current run time used by Emacs.
-The time is returned as a list of three integers.  The first has the
-most significant 16 bits of the seconds, while the second has the
-least significant 16 bits.  The third integer gives the microsecond
-count.
+The time is returned as a list (HIGH LOW NSEC), using the same style
+as (current-time).

 On systems that can't determine the run time, `get-internal-run-time'
-does the same thing as `current-time'.  The microsecond count is zero
-on systems that do not provide resolution finer than a second.  */)
+does the same thing as `current-time'.  */)
   (void)
 {
 #ifdef HAVE_GETRUSAGE
   struct rusage usage;
   time_t secs;
   int usecs;
+  EMACS_TIME t;

   if (getrusage (RUSAGE_SELF, &usage) < 0)
     /* This shouldn't happen.  What action is appropriate?  */
@@ -1484,10 +1476,8 @@
       usecs -= 1000000;
       secs++;
     }
-
-  return list3 (make_number (hi_time (secs)),
-		make_number (lo_time (secs)),
-		make_number (usecs));
+  EMACS_SET_SECS_USECS (t, secs, usecs);
+  return make_lisp_time (t);
 #else /* ! HAVE_GETRUSAGE  */
 #ifdef WINDOWSNT
   return w32_get_internal_run_time ();
@@ -1498,86 +1488,176 @@
 }
 \f

-/* Make a Lisp list that represents the time T.  */
-Lisp_Object
+/* Make a Lisp list that represents the time T with fraction TAIL.  */
+static Lisp_Object
+make_time_tail (time_t t, Lisp_Object tail)
+{
+  return Fcons (hi_time (t), Fcons (lo_time (t), tail));
+}
+
+/* Make a Lisp list that represents the system time T.  */
+static Lisp_Object
 make_time (time_t t)
 {
-  return list2 (make_number (hi_time (t)),
-		make_number (lo_time (t)));
+  return make_time_tail (t, Qnil);
+}
+
+/* Make a Lisp list that represents the Emacs time T.  T may be an
+   invalid time, with a slightly negative tv_nsec value such as
+   UNKNOWN_MODTIME_NSECS; in that case, the Lisp list contains a
+   slightly negative nanosecond count.  */
+Lisp_Object
+make_lisp_time (EMACS_TIME t)
+{
+  int ns = EMACS_NSECS (t);
+  int frac = ns;
+  Lisp_Object fraction =
+    (MOST_POSITIVE_FIXNUM < EMACS_TIME_RESOLUTION && MOST_POSITIVE_FIXNUM < frac
+     ? make_float (frac)
+     : make_number (frac));
+  return make_time_tail (EMACS_SECS (t), list1 (fraction));
 }

 /* Decode a Lisp list SPECIFIED_TIME that represents a time.
-   If SPECIFIED_TIME is nil, use the current time.
-   Set *RESULT to seconds since the Epoch.
-   If USEC is not null, set *USEC to the microseconds component.
+   Set *PHIGH, *PLOW, *PFRAC to its components; do not check their values.
    Return nonzero if successful.  */
+static int
+disassemble_lisp_time (Lisp_Object specified_time, Lisp_Object *phigh,
+		       Lisp_Object *plow, Lisp_Object *pfrac)
+{
+  if (CONSP (specified_time))
+    {
+      Lisp_Object low = XCDR (specified_time);
+      Lisp_Object frac = make_number (0);
+      if (CONSP (low))
+	{
+	  Lisp_Object low_tail = XCDR (low);
+	  low = XCAR (low);
+	  if (CONSP (low_tail))
+	    frac = XCAR (low_tail);
+	  else if (!NILP (low_tail))
+	    frac = low_tail;
+	}
+
+      *phigh = XCAR (specified_time);
+      *plow = low;
+      *pfrac = frac;
+      return 1;
+    }
+
+  return 0;
+}
+
+/* From the time components HIGH, LOW, and FRAC taken from a Lisp list,
+   and a NS_LOWER_BOUND threshold giving the minimum allowed value for FRAC,
+   generate the corresponding EMACS_TIME value *RESULT.  Return nonzero
+   if successful.  */
 int
-lisp_time_argument (Lisp_Object specified_time, time_t *result, int *usec)
+decode_time_components (Lisp_Object high, Lisp_Object low, Lisp_Object frac,
+			int ns_lower_bound, EMACS_TIME *result)
 {
-  if (NILP (specified_time))
-    {
-      if (usec)
-        {
-          EMACS_TIME t;
-
-          EMACS_GET_TIME (t);
-          *usec = EMACS_USECS (t);
-          *result = EMACS_SECS (t);
-          return 1;
-        }
-      else
-        return time (result) != -1;
-    }
-  else
-    {
-      Lisp_Object high, low;
-      EMACS_INT hi;
-      high = Fcar (specified_time);
-      CHECK_NUMBER (high);
-      low = Fcdr (specified_time);
-      if (CONSP (low))
-        {
-          if (usec)
-            {
-              Lisp_Object usec_l = Fcdr (low);
-              if (CONSP (usec_l))
-                usec_l = Fcar (usec_l);
-              if (NILP (usec_l))
-                *usec = 0;
-              else
-                {
-                  CHECK_NUMBER (usec_l);
-                  *usec = XINT (usec_l);
-                }
-            }
-          low = Fcar (low);
-        }
-      else if (usec)
-        *usec = 0;
-      CHECK_NUMBER (low);
-      hi = XINT (high);
-
-      /* Check for overflow, helping the compiler for common cases
-	 where no runtime check is needed, and taking care not to
-	 convert negative numbers to unsigned before comparing them.  */
+  time_t s;
+  int ns;
+
+  /* Check for overflow, helping the compiler for common cases
+     where no runtime check is needed, and taking care not to
+     convert negative to unsigned before comparison.  */
+  if (INTEGERP (high))
+    {
+      EMACS_INT h = XINT (high);
       if (! ((TYPE_SIGNED (time_t)
 	      ? (TIME_T_MIN >> 16 <= MOST_NEGATIVE_FIXNUM
-		 || TIME_T_MIN >> 16 <= hi)
-	      : 0 <= hi)
+		 || TIME_T_MIN >> 16 <= h)
+	      : 0 <= h)
 	     && (MOST_POSITIVE_FIXNUM <= TIME_T_MAX >> 16
-		 || hi <= TIME_T_MAX >> 16)))
-	return 0;
-
-      *result = (hi << 16) + (XINT (low) & 0xffff);
-      return 1;
-    }
-}
+		 || h <= TIME_T_MAX >> 16)))
+	return 0;
+      s = h;
+    }
+  else if (FLOATP (high))
+    {
+      double h = XFLOAT_DATA (high);
+      if (! (TIME_T_MIN >> 16 <= h && h < (TIME_T_MAX >> 16) + 1))
+	return 0;
+      s = h;
+      if (! (s == h))
+	return 0;
+    }
+  else
+    return 0;
+
+  if (! (INTEGERP (low) && 0 <= XINT (low) && XINT (low) < (1 << 16)))
+    return 0;
+  s = (s << 16) + XINT (low);
+
+  if (INTEGERP (frac))
+    {
+      EMACS_INT f = XINT (frac);
+      if (! (ns_lower_bound <= f && f < EMACS_TIME_RESOLUTION))
+	return 0;
+      ns = f;
+    }
+  else if (FLOATP (frac))
+    {
+      double f = XFLOAT_DATA (frac);
+      if (! (ns_lower_bound <= f && f < EMACS_TIME_RESOLUTION))
+	return 0;
+      ns = f;
+    }
+  else
+    return 0;
+
+  EMACS_SET_SECS_NSECS (*result, s, ns);
+  return 1;
+}
+
+/* Decode a Lisp list SPECIFIED_TIME that represents a time.
+   If SPECIFIED_TIME is nil, use the current time.
+   Return seconds since the Epoch.
+   NS_LOWER_BOUND gives the lowest allowable nanosecond count.
+   If NS_LOWER_BOUND < 0, the specified time may be invalid, and it's OK to
+   generate a list with the same invalid nanosecond count.
+   Signal an error if unsuccessful.  */
+EMACS_TIME
+lisp_time_argument (Lisp_Object specified_time, int ns_lower_bound)
+{
+  EMACS_TIME t;
+  if (NILP (specified_time))
+    EMACS_GET_TIME (t);
+  else
+    {
+      Lisp_Object high, low, frac;
+      if (! (disassemble_lisp_time (specified_time, &high, &low, &frac)
+	     && decode_time_components (high, low, frac, ns_lower_bound, &t)))
+	error ("Invalid time specification");
+    }
+  return t;
+}
+
+/* Like lisp_time_argument, except decode only the seconds part,
+   and do not check the nanoseconds part.  */
+static time_t
+lisp_seconds_argument (Lisp_Object specified_time)
+{
+  if (NILP (specified_time))
+    return time (NULL);
+  else
+    {
+      Lisp_Object high, low, frac;
+      EMACS_TIME t;
+      if (! (disassemble_lisp_time (specified_time, &high, &low, &frac)
+	     && decode_time_components (high, low, make_number (0), 0, &t)))
+	error ("Invalid time specification");
+      return EMACS_SECS (t);
+    }
+}
+

 DEFUN ("float-time", Ffloat_time, Sfloat_time, 0, 1, 0,
        doc: /* Return the current time, as a float number of seconds since the epoch.
 If SPECIFIED-TIME is given, it is the time to convert to float
 instead of the current time.  The argument should have the form
-(HIGH LOW) or (HIGH LOW USEC). Thus, you can use times obtained from
+(HIGH LOW) or (HIGH LOW NSEC).  Thus, you can use times obtained from
 `current-time' and from `file-attributes'.  SPECIFIED-TIME can also
 have the form (HIGH . LOW), but this is considered obsolete.

@@ -1586,13 +1666,8 @@
 or (if you need time as a string) `format-time-string'.  */)
   (Lisp_Object specified_time)
 {
-  time_t sec;
-  int usec;
-
-  if (! lisp_time_argument (specified_time, &sec, &usec))
-    error ("Invalid time specification");
-
-  return make_float ((sec * 1e6 + usec) / 1e6);
+  EMACS_TIME t = lisp_time_argument (specified_time, 0);
+  return make_float (EMACS_TIME_TO_DOUBLE (t));
 }

 /* Write information into buffer S of size MAXSIZE, according to the
@@ -1647,7 +1722,7 @@

 DEFUN ("format-time-string", Fformat_time_string, Sformat_time_string, 1, 3, 0,
        doc: /* Use FORMAT-STRING to format the time TIME, or now if omitted.
-TIME is specified as (HIGH LOW . IGNORED), as returned by
+TIME is specified as (HIGH LOW NSEC), as returned by
 `current-time' or `file-attributes'.  The obsolete form (HIGH . LOW)
 is also still accepted.
 The third, optional, argument UNIVERSAL, if non-nil, means describe TIME
@@ -1699,28 +1774,26 @@
 For example, to produce full ISO 8601 format, use "%Y-%m-%dT%T%z".  */)
   (Lisp_Object format_string, Lisp_Object timeval, Lisp_Object universal)
 {
-  time_t value;
-  int size;
-  int usec;
+  EMACS_TIME t;
+  ptrdiff_t size;
   int ns;
   struct tm *tm;
   int ut = ! NILP (universal);

   CHECK_STRING (format_string);

-  if (! (lisp_time_argument (timeval, &value, &usec)
-	 && 0 <= usec && usec < 1000000))
-    error ("Invalid time specification");
-  ns = usec * 1000;
+  t = lisp_time_argument (timeval, 0);

   format_string = code_convert_string_norecord (format_string,
 						Vlocale_coding_system, 1);

   /* This is probably enough.  */
-  size = SBYTES (format_string) * 6 + 50;
+  size = SBYTES (format_string);
+  if (size <= (STRING_BYTES_BOUND - 50) / 6)
+    size = size * 6 + 50;

   BLOCK_INPUT;
-  tm = ut ? gmtime (&value) : localtime (&value);
+  tm = ut ? gmtime (EMACS_SECS_ADDR (t)) : localtime (EMACS_SECS_ADDR (t));
   UNBLOCK_INPUT;
   if (! tm)
     time_overflow ();
@@ -1736,7 +1809,7 @@
       BLOCK_INPUT;
       result = emacs_nmemftime (buf, size, SSDATA (format_string),
 				SBYTES (format_string),
-				tm, ut, ns);
+				tm, ut, EMACS_NSECS (t));
       UNBLOCK_INPUT;
       if ((result > 0 && result < size) || (result == 0 && buf[0] == '\0'))
 	return code_convert_string_norecord (make_unibyte_string (buf, result),
@@ -1747,8 +1820,10 @@
       result = emacs_nmemftime (NULL, (size_t) -1,
 				SSDATA (format_string),
 				SBYTES (format_string),
-				tm, ut, ns);
+				tm, ut, EMACS_NSECS (t));
       UNBLOCK_INPUT;
+      if (STRING_BYTES_BOUND <= result)
+	string_overflow ();
       size = result + 1;
     }
 }
@@ -1762,7 +1837,7 @@
 and 60; SEC is 60 for a leap second, which only some operating systems
 support.  MINUTE is an integer between 0 and 59.  HOUR is an integer
 between 0 and 23.  DAY is an integer between 1 and 31.  MONTH is an
-integer between 1 and 12.  YEAR is an integer indicating the
+integer between 1 and 12.  YEAR is a number indicating the
 four-digit year.  DOW is the day of week, an integer between 0 and 6,
 where 0 is Sunday.  DST is t if daylight saving time is in effect,
 otherwise nil.  ZONE is an integer indicating the number of seconds
@@ -1770,29 +1845,29 @@
 DOW and ZONE.)  */)
   (Lisp_Object specified_time)
 {
-  time_t time_spec;
+  time_t time_spec = lisp_seconds_argument (specified_time);
   struct tm save_tm;
   struct tm *decoded_time;
   Lisp_Object list_args[9];

-  if (! lisp_time_argument (specified_time, &time_spec, NULL))
-    error ("Invalid time specification");
-
   BLOCK_INPUT;
   decoded_time = localtime (&time_spec);
   UNBLOCK_INPUT;
-  if (! (decoded_time
-	 && MOST_NEGATIVE_FIXNUM - TM_YEAR_BASE <= decoded_time->tm_year
-	 && decoded_time->tm_year <= MOST_POSITIVE_FIXNUM - TM_YEAR_BASE))
+  if (! decoded_time)
     time_overflow ();
   XSETFASTINT (list_args[0], decoded_time->tm_sec);
   XSETFASTINT (list_args[1], decoded_time->tm_min);
   XSETFASTINT (list_args[2], decoded_time->tm_hour);
   XSETFASTINT (list_args[3], decoded_time->tm_mday);
   XSETFASTINT (list_args[4], decoded_time->tm_mon + 1);
-  /* On 64-bit machines an int is narrower than EMACS_INT, thus the
-     cast below avoids overflow in int arithmetics.  */
-  XSETINT (list_args[5], TM_YEAR_BASE + (EMACS_INT) decoded_time->tm_year);
+
+  if (decoded_time
+      && MOST_NEGATIVE_FIXNUM - TM_YEAR_BASE <= decoded_time->tm_year
+      && decoded_time->tm_year <= MOST_POSITIVE_FIXNUM - TM_YEAR_BASE)
+    XSETINT (list_args[5], TM_YEAR_BASE + (EMACS_INT) decoded_time->tm_year);
+  else
+    list_args[5] = make_float (TM_YEAR_BASE + (double) decoded_time->tm_year);
+
   XSETFASTINT (list_args[6], decoded_time->tm_wday);
   list_args[7] = (decoded_time->tm_isdst)? Qt : Qnil;

@@ -1855,7 +1930,17 @@
   tm.tm_hour = check_tm_member (args[2], 0);
   tm.tm_mday = check_tm_member (args[3], 0);
   tm.tm_mon  = check_tm_member (args[4], 1);
-  tm.tm_year = check_tm_member (args[5], TM_YEAR_BASE);
+  if (FLOATP (args[5]))
+    {
+      double n = XFLOAT_DATA (args[5]) - TM_YEAR_BASE;
+      if (! (INT_MIN <= n && n < INT_MAX + 1.0))
+	time_overflow ();
+      tm.tm_year = n;
+      if (tm.tm_year != n)
+	time_overflow ();
+    }
+  else
+    tm.tm_year = check_tm_member (args[5], TM_YEAR_BASE);
   tm.tm_isdst = -1;

   if (CONSP (zone))
@@ -1925,13 +2010,10 @@
 but this is considered obsolete.  */)
   (Lisp_Object specified_time)
 {
-  time_t value;
+  time_t value = lisp_seconds_argument (specified_time);
   struct tm *tm;
   register char *tem;

-  if (! lisp_time_argument (specified_time, &value, NULL))
-    error ("Invalid time specification");
-
   /* Convert to a string, checking for out-of-range time stamps.
      Don't use 'ctime', as that might dump core if VALUE is out of
      range.  */
@@ -1987,23 +2069,18 @@
 the data it can't find.  */)
   (Lisp_Object specified_time)
 {
-  time_t value;
+  time_t value = lisp_seconds_argument (specified_time);
   struct tm *t;
   struct tm gmt;

-  if (!lisp_time_argument (specified_time, &value, NULL))
-    t = NULL;
-  else
+  BLOCK_INPUT;
+  t = gmtime (&value);
+  if (t)
     {
-      BLOCK_INPUT;
-      t = gmtime (&value);
-      if (t)
-	{
-	  gmt = *t;
-	  t = localtime (&value);
-	}
-      UNBLOCK_INPUT;
+      gmt = *t;
+      t = localtime (&value);
     }
+  UNBLOCK_INPUT;

   if (t)
     {

=== modified file 'src/fileio.c'
--- src/fileio.c	2011-06-24 21:25:22 +0000
+++ src/fileio.c	2011-07-01 05:24:23 +0000
@@ -76,6 +76,7 @@
 #endif

 #include "systime.h"
+#include <stat-time.h>

 #ifdef HPUX
 #include <netio.h>
@@ -1873,7 +1874,7 @@
       /* Ensure file is writable while its modified time is set.  */
       attributes = GetFileAttributes (filename);
       SetFileAttributes (filename, attributes & ~FILE_ATTRIBUTE_READONLY);
-      if (set_file_times (filename, now, now))
+      if (set_file_times (-1, filename, now, now))
 	{
 	  /* Restore original attributes.  */
 	  SetFileAttributes (filename, attributes);
@@ -1974,24 +1975,21 @@
     }
 #endif

-  /* Closing the output clobbers the file times on some systems.  */
-  if (emacs_close (ofd) < 0)
-    report_file_error ("I/O error", Fcons (newname, Qnil));
-
   if (input_file_statable_p)
     {
       if (!NILP (keep_time))
 	{
-	  EMACS_TIME atime, mtime;
-	  EMACS_SET_SECS_USECS (atime, st.st_atime, 0);
-	  EMACS_SET_SECS_USECS (mtime, st.st_mtime, 0);
-	  if (set_file_times (SSDATA (encoded_newname),
-			      atime, mtime))
+	  EMACS_TIME atime = get_stat_atime (&st);
+	  EMACS_TIME mtime = get_stat_mtime (&st);
+	  if (set_file_times (ofd, SSDATA (encoded_newname), atime, mtime))
 	    xsignal2 (Qfile_date_error,
 		      build_string ("Cannot set file date"), newname);
 	}
     }

+  if (emacs_close (ofd) < 0)
+    report_file_error ("I/O error", Fcons (newname, Qnil));
+
   emacs_close (ifd);

 #ifdef MSDOS
@@ -2932,11 +2930,7 @@
 {
   Lisp_Object absname, encoded_absname;
   Lisp_Object handler;
-  time_t sec;
-  int usec;
-
-  if (! lisp_time_argument (timestamp, &sec, &usec))
-    error ("Invalid time specification");
+  EMACS_TIME t = lisp_time_argument (timestamp, 0);

   absname = Fexpand_file_name (filename, BVAR (current_buffer, directory));

@@ -2949,12 +2943,7 @@
   encoded_absname = ENCODE_FILE (absname);

   {
-    EMACS_TIME t;
-
-    EMACS_SET_SECS (t, sec);
-    EMACS_SET_USECS (t, usec);
-
-    if (set_file_times (SSDATA (encoded_absname), t, t))
+    if (set_file_times (-1, SSDATA (encoded_absname), t, t))
       {
 #ifdef DOS_NT
         struct stat st;
@@ -4055,7 +4044,7 @@

       if (NILP (handler))
 	{
-	  current_buffer->modtime = st.st_mtime;
+	  current_buffer->modtime = get_stat_mtime (&st);
 	  current_buffer->modtime_size = st.st_size;
 	  BVAR (current_buffer, filename) = orig_filename;
 	}
@@ -4220,7 +4209,7 @@
     }

   if (!NILP (visit)
-      && current_buffer->modtime == -1)
+      && EMACS_NSECS (current_buffer->modtime) == NONEXISTENT_MODTIME_NSECS)
     {
       /* If visiting nonexistent file, return nil.  */
       report_file_error ("Opening input file", Fcons (orig_filename, Qnil));
@@ -4655,7 +4644,7 @@
      next attempt to save.  */
   if (visiting)
     {
-      current_buffer->modtime = st.st_mtime;
+      current_buffer->modtime = get_stat_mtime (&st);
       current_buffer->modtime_size = st.st_size;
     }

@@ -4932,6 +4921,7 @@
   struct stat st;
   Lisp_Object handler;
   Lisp_Object filename;
+  EMACS_TIME mtime, diff, one_second;

   if (NILP (buf))
     b = current_buffer;
@@ -4942,7 +4932,7 @@
     }

   if (!STRINGP (BVAR (b, filename))) return Qt;
-  if (b->modtime == 0) return Qt;
+  if (EMACS_NSECS (b->modtime) == UNKNOWN_MODTIME_NSECS) return Qt;

   /* If the file name has special constructs in it,
      call the corresponding file handler.  */
@@ -4953,20 +4943,25 @@

   filename = ENCODE_FILE (BVAR (b, filename));

-  if (stat (SSDATA (filename), &st) < 0)
+  if (stat (SSDATA (filename), &st) == 0)
+    mtime = get_stat_mtime (&st);
+  else
     {
       /* If the file doesn't exist now and didn't exist before,
 	 we say that it isn't modified, provided the error is a tame one.  */
-      if (errno == ENOENT || errno == EACCES || errno == ENOTDIR)
-	st.st_mtime = -1;
-      else
-	st.st_mtime = 0;
+      int ns = (errno == ENOENT || errno == EACCES || errno == ENOTDIR
+		? NONEXISTENT_MODTIME_NSECS
+		: UNKNOWN_MODTIME_NSECS);
+      EMACS_SET_SECS_NSECS (mtime, 0, ns);
     }
-  if ((st.st_mtime == b->modtime
-       /* If both are positive, accept them if they are off by one second.  */
-       || (st.st_mtime > 0 && b->modtime > 0
-	   && (st.st_mtime - 1 == b->modtime
-	       || st.st_mtime == b->modtime - 1)))
+  if ((EMACS_TIME_EQ (mtime, b->modtime)
+       /* If both exist, accept them if they are off by one second.  */
+       || (EMACS_TIME_VALID_P (mtime) && EMACS_TIME_VALID_P (b->modtime)
+	   && ((EMACS_TIME_LT (mtime, b->modtime)
+		? EMACS_SUB_TIME (diff, b->modtime, mtime)
+		: EMACS_SUB_TIME (diff, mtime, b->modtime)),
+	       EMACS_SET_SECS_NSECS (one_second, 1, 0),
+	       EMACS_TIME_LE (diff, one_second))))
       && (st.st_size == b->modtime_size
           || b->modtime_size < 0))
     return Qt;
@@ -4979,7 +4974,7 @@
 Next attempt to save will certainly not complain of a discrepancy.  */)
   (void)
 {
-  current_buffer->modtime = 0;
+  EMACS_SET_SECS_NSECS (current_buffer->modtime, 0, UNKNOWN_MODTIME_NSECS);
   current_buffer->modtime_size = -1;
   return Qnil;
 }
@@ -4987,15 +4982,15 @@
 DEFUN ("visited-file-modtime", Fvisited_file_modtime,
        Svisited_file_modtime, 0, 0, 0,
        doc: /* Return the current buffer's recorded visited file modification time.
-The value is a list of the form (HIGH LOW), like the time values
+The value is a list of the form (HIGH LOW NANOSECONDS), like the time values
 that `file-attributes' returns.  If the current buffer has no recorded
 file modification time, this function returns 0.
 See Info node `(elisp)Modification Time' for more details.  */)
   (void)
 {
-  if (! current_buffer->modtime)
+  if (EMACS_NSECS (current_buffer->modtime) < 0)
     return make_number (0);
-  return make_time (current_buffer->modtime);
+  return make_lisp_time (current_buffer->modtime);
 }

 DEFUN ("set-visited-file-modtime", Fset_visited_file_modtime,
@@ -5005,12 +5000,12 @@
 or if the file itself has been changed for some known benign reason.
 An argument specifies the modification time value to use
 \(instead of that of the visited file), in the form of a list
-\(HIGH . LOW) or (HIGH LOW).  */)
+\(HIGH LOW NSEC) or (HIGH LOW) or (HIGH . LOW).  */)
   (Lisp_Object time_list)
 {
   if (!NILP (time_list))
     {
-      CONS_TO_INTEGER (time_list, time_t, current_buffer->modtime);
+      current_buffer->modtime = lisp_time_argument (time_list, 0);
       current_buffer->modtime_size = -1;
     }
   else
@@ -5032,7 +5027,7 @@

       if (stat (SSDATA (filename), &st) >= 0)
         {
-	  current_buffer->modtime = st.st_mtime;
+	  current_buffer->modtime = get_stat_mtime (&st);
           current_buffer->modtime_size = st.st_size;
         }
     }

=== modified file 'src/gtkutil.c'
--- src/gtkutil.c	2011-06-26 18:47:07 +0000
+++ src/gtkutil.c	2011-07-01 05:24:23 +0000
@@ -1579,16 +1579,16 @@
 {
   struct xg_dialog_data *dd = (struct xg_dialog_data *) data;
   EMACS_TIME next_time = timer_check ();
-  long secs = EMACS_SECS (next_time);
-  long usecs = EMACS_USECS (next_time);

   dd->timerid = 0;

-  if (secs >= 0 && usecs >= 0 && secs < ((guint)-1)/1000)
+  if (EMACS_TIME_VALID_P (next_time))
     {
-      dd->timerid = g_timeout_add (secs * 1000 + usecs/1000,
-                                   xg_maybe_add_timer,
-                                   dd);
+      time_t s = EMACS_SECS (next_time);
+      int per_ms = EMACS_TIME_RESOLUTION / 1000;
+      int ms = (EMACS_NSECS (next_time) + per_ms - 1) / per_ms;
+      if (s <= ((guint) -1 - ms) / 1000)
+	dd->timerid = g_timeout_add (s * 1000 + ms, xg_maybe_add_timer, dd);
     }
   return FALSE;
 }

=== modified file 'src/image.c'
--- src/image.c	2011-06-23 00:46:41 +0000
+++ src/image.c	2011-07-01 05:24:23 +0000
@@ -1076,11 +1076,8 @@
 void
 prepare_image_for_display (struct frame *f, struct image *img)
 {
-  EMACS_TIME t;
-
   /* We're about to display IMG, so set its timestamp to `now'.  */
-  EMACS_GET_TIME (t);
-  img->timestamp = EMACS_SECS (t);
+  EMACS_GET_TIME (img->timestamp);

   /* If IMG doesn't have a pixmap yet, load it now, using the image
      type dependent loader function.  */
@@ -1524,9 +1521,9 @@
       else if (INTEGERP (Vimage_cache_eviction_delay))
 	{
 	  /* Free cache based on timestamp.  */
-	  EMACS_TIME t;
-	  time_t old;
-	  int delay, nimages = 0;
+	  EMACS_TIME old, t;
+	  double delay;
+	  unsigned nimages = 0;

 	  for (i = 0; i < c->used; ++i)
 	    if (c->images[i])
@@ -1534,17 +1531,18 @@

 	  /* If the number of cached images has grown unusually large,
 	     decrease the cache eviction delay (Bug#6230).  */
-	  delay = XFASTINT (Vimage_cache_eviction_delay);
+	  delay = XINT (Vimage_cache_eviction_delay);
 	  if (nimages > 40)
-	    delay = max (1, 1600 * delay / (nimages*nimages));
+	    delay = 1600 * delay / nimages / nimages;
+	  delay = max (1, delay);

 	  EMACS_GET_TIME (t);
-	  old = EMACS_SECS (t) - delay;
+	  EMACS_SUB_TIME (old, t, EMACS_TIME_FROM_DOUBLE (delay));

 	  for (i = 0; i < c->used; ++i)
 	    {
 	      struct image *img = c->images[i];
-	      if (img && img->timestamp < old)
+	      if (img && EMACS_TIME_LT (img->timestamp, old))
 		{
 		  free_image (f, img);
 		  ++nfreed;
@@ -1717,7 +1715,6 @@
 {
   struct image *img;
   EMACS_UINT hash;
-  EMACS_TIME now;

   /* F must be a window-system frame, and SPEC must be a valid image
      specification.  */
@@ -1812,8 +1809,7 @@
     }

   /* We're using IMG, so set its timestamp to `now'.  */
-  EMACS_GET_TIME (now);
-  img->timestamp = EMACS_SECS (now);
+  EMACS_GET_TIME (img->timestamp);

   /* Value is the image id.  */
   return img->id;

=== modified file 'src/keyboard.c'
--- src/keyboard.c	2011-06-20 06:07:16 +0000
+++ src/keyboard.c	2011-07-01 05:24:23 +0000
@@ -2003,12 +2003,13 @@
       if (poll_timer == NULL
 	  || EMACS_SECS (poll_timer->interval) != polling_period)
 	{
+	  time_t period = max (1, min (polling_period, TYPE_MAXIMUM (time_t)));
 	  EMACS_TIME interval;

 	  if (poll_timer)
 	    cancel_atimer (poll_timer);

-	  EMACS_SET_SECS_USECS (interval, polling_period, 0);
+	  EMACS_SET_SECS_USECS (interval, period, 0);
 	  poll_timer = start_atimer (ATIMER_CONTINUOUS, interval,
 				     poll_for_input, NULL);
 	}
@@ -2076,7 +2077,7 @@
 bind_polling_period (int n)
 {
 #ifdef POLL_FOR_INPUT
-  int new = polling_period;
+  EMACS_INT new = polling_period;

   if (n > new)
     new = n;
@@ -2206,7 +2207,7 @@
 /* Input of single characters from keyboard */

 static Lisp_Object kbd_buffer_get_event (KBOARD **kbp, int *used_mouse_menu,
-					 struct timeval *end_time);
+					 EMACS_TIME *end_time);
 static void record_char (Lisp_Object c);

 static Lisp_Object help_form_saved_window_configs;
@@ -2257,7 +2258,7 @@

 Lisp_Object
 read_char (int commandflag, int nmaps, Lisp_Object *maps, Lisp_Object prev_event,
-	   int *used_mouse_menu, struct timeval *end_time)
+	   int *used_mouse_menu, EMACS_TIME *end_time)
 {
   volatile Lisp_Object c;
   int jmpcount;
@@ -3758,7 +3759,7 @@
 static Lisp_Object
 kbd_buffer_get_event (KBOARD **kbp,
                       int *used_mouse_menu,
-                      struct timeval *end_time)
+                      EMACS_TIME *end_time)
 {
   register int c;
   Lisp_Object obj;
@@ -3831,8 +3832,9 @@
 	  else
 	    {
 	      EMACS_SUB_TIME (duration, *end_time, duration);
-	      wait_reading_process_output (EMACS_SECS (duration),
-					   EMACS_USECS (duration),
+	      wait_reading_process_output (min (EMACS_SECS (duration),
+						INTMAX_MAX),
+					   EMACS_NSECS (duration),
 					   -1, 1, Qnil, NULL, 0);
 	    }
 	}
@@ -4194,7 +4196,7 @@
   Lisp_Object timers;

   /* If we are already in the idle state, do nothing.  */
-  if (! EMACS_TIME_NEG_P (timer_idleness_start_time))
+  if (EMACS_TIME_VALID_P (timer_idleness_start_time))
     return;

   EMACS_GET_TIME (timer_idleness_start_time);
@@ -4219,7 +4221,7 @@
 static void
 timer_stop_idle (void)
 {
-  EMACS_SET_SECS_USECS (timer_idleness_start_time, -1, -1);
+  EMACS_SET_INVALID_TIME (timer_idleness_start_time);
 }

 /* Resume idle timer from last idle start time.  */
@@ -4227,7 +4229,7 @@
 static void
 timer_resume_idle (void)
 {
-  if (! EMACS_TIME_NEG_P (timer_idleness_start_time))
+  if (EMACS_TIME_VALID_P (timer_idleness_start_time))
     return;

   timer_idleness_start_time = timer_last_idleness_start_time;
@@ -4258,17 +4260,16 @@
 {
   EMACS_TIME nexttime;
   EMACS_TIME now;
-  EMACS_TIME idleness_now IF_LINT (= {0});
+  EMACS_TIME idleness_now;
   Lisp_Object timers, idle_timers, chosen_timer;
   struct gcpro gcpro1, gcpro2, gcpro3;

-  EMACS_SET_SECS (nexttime, -1);
-  EMACS_SET_USECS (nexttime, -1);
+  EMACS_SET_INVALID_TIME (nexttime);

   /* Always consider the ordinary timers.  */
   timers = Vtimer_list;
   /* Consider the idle timers only if Emacs is idle.  */
-  if (! EMACS_TIME_NEG_P (timer_idleness_start_time))
+  if (EMACS_TIME_VALID_P (timer_idleness_start_time))
     idle_timers = Vtimer_idle_list;
   else
     idle_timers = Qnil;
@@ -4286,8 +4287,10 @@
   if (CONSP (timers) || CONSP (idle_timers))
     {
       EMACS_GET_TIME (now);
-      if (! EMACS_TIME_NEG_P (timer_idleness_start_time))
+      if (EMACS_TIME_VALID_P (timer_idleness_start_time))
 	EMACS_SUB_TIME (idleness_now, now, timer_idleness_start_time);
+      else
+	EMACS_SET_SECS_NSECS (idleness_now, 0, 0);
     }

   while (CONSP (timers) || CONSP (idle_timers))
@@ -4296,113 +4299,102 @@
       Lisp_Object timer = Qnil, idle_timer = Qnil;
       EMACS_TIME timer_time, idle_timer_time;
       EMACS_TIME difference;
-      EMACS_TIME timer_difference IF_LINT (= {0});
-      EMACS_TIME idle_timer_difference IF_LINT (= {0});
-
-      /* Skip past invalid timers and timers already handled.  */
-      if (CONSP (timers))
-	{
-	  timer = XCAR (timers);
-	  if (!VECTORP (timer) || ASIZE (timer) != 8)
-	    {
-	      timers = XCDR (timers);
-	      continue;
-	    }
-	  vector = XVECTOR (timer)->contents;
-
-	  if (!INTEGERP (vector[1]) || !INTEGERP (vector[2])
-	      || !INTEGERP (vector[3])
-	      || ! NILP (vector[0]))
-	    {
-	      timers = XCDR (timers);
-	      continue;
-	    }
-	}
-      if (CONSP (idle_timers))
-	{
-	  timer = XCAR (idle_timers);
-	  if (!VECTORP (timer) || ASIZE (timer) != 8)
-	    {
-	      idle_timers = XCDR (idle_timers);
-	      continue;
-	    }
-	  vector = XVECTOR (timer)->contents;
-
-	  if (!INTEGERP (vector[1]) || !INTEGERP (vector[2])
-	      || !INTEGERP (vector[3])
-	      || ! NILP (vector[0]))
-	    {
-	      idle_timers = XCDR (idle_timers);
-	      continue;
-	    }
-	}
-
-      /* Set TIMER, TIMER_TIME and TIMER_DIFFERENCE
+      EMACS_TIME timer_difference, idle_timer_difference;
+      int ripe, timer_ripe = 0, idle_timer_ripe = 0;
+
+      EMACS_SET_INVALID_TIME (timer_difference);
+      EMACS_SET_INVALID_TIME (idle_timer_difference);
+
+      /* Set TIMER and TIMER_DIFFERENCE
 	 based on the next ordinary timer.
 	 TIMER_DIFFERENCE is the distance in time from NOW to when
-	 this timer becomes ripe (negative if it's already ripe).  */
+	 this timer becomes ripe (negative if it's already ripe).
+         Skip past invalid timers and timers already handled.  */
       if (CONSP (timers))
 	{
 	  timer = XCAR (timers);
+	  if (!VECTORP (timer) || ASIZE (timer) != 8)
+	    {
+	      timers = XCDR (timers);
+	      continue;
+	    }
 	  vector = XVECTOR (timer)->contents;
-	  EMACS_SET_SECS (timer_time,
-			  (XINT (vector[1]) << 16) | (XINT (vector[2])));
-	  EMACS_SET_USECS (timer_time, XINT (vector[3]));
-	  EMACS_SUB_TIME (timer_difference, timer_time, now);
+
+	  if (! (NILP (vector[0])
+		 && decode_time_components (vector[1], vector[2], vector[3],
+					    0, &timer_time)))
+	    {
+	      timers = XCDR (timers);
+	      continue;
+	    }
+
+	  timer_ripe = EMACS_TIME_LE (timer_time, now);
+	  if (timer_ripe)
+	    EMACS_SUB_TIME (timer_difference, now, timer_time);
+	  else
+	    EMACS_SUB_TIME (timer_difference, timer_time, now);
 	}

-      /* Set IDLE_TIMER, IDLE_TIMER_TIME and IDLE_TIMER_DIFFERENCE
+      /* Likewise for IDLE_TIMER and IDLE_TIMER_DIFFERENCE
 	 based on the next idle timer.  */
       if (CONSP (idle_timers))
 	{
 	  idle_timer = XCAR (idle_timers);
+	  if (!VECTORP (idle_timer) || ASIZE (idle_timer) != 8)
+	    {
+	      idle_timers = XCDR (idle_timers);
+	      continue;
+	    }
 	  vector = XVECTOR (idle_timer)->contents;
-	  EMACS_SET_SECS (idle_timer_time,
-			  (XINT (vector[1]) << 16) | (XINT (vector[2])));
-	  EMACS_SET_USECS (idle_timer_time, XINT (vector[3]));
-	  EMACS_SUB_TIME (idle_timer_difference, idle_timer_time, idleness_now);
+
+	  if (! (NILP (vector[0])
+		 && decode_time_components (vector[1], vector[2], vector[3],
+					    0, &idle_timer_time)))
+	    {
+	      idle_timers = XCDR (idle_timers);
+	      continue;
+	    }
+
+	  idle_timer_ripe = EMACS_TIME_LE (idle_timer_time, idleness_now);
+	  if (idle_timer_ripe)
+	    EMACS_SUB_TIME (idle_timer_difference,
+			    idleness_now, idle_timer_time);
+	  else
+	    EMACS_SUB_TIME (idle_timer_difference,
+			    idle_timer_time, idleness_now);
 	}

       /* Decide which timer is the next timer,
-	 and set CHOSEN_TIMER, VECTOR and DIFFERENCE accordingly.
+	 and set CHOSEN_TIMER, DIFFERENCE, and RIPE accordingly.
 	 Also step down the list where we found that timer.  */

-      if (CONSP (timers) && CONSP (idle_timers))
-	{
-	  EMACS_TIME temp;
-	  EMACS_SUB_TIME (temp, timer_difference, idle_timer_difference);
-	  if (EMACS_TIME_NEG_P (temp))
-	    {
-	      chosen_timer = timer;
-	      timers = XCDR (timers);
-	      difference = timer_difference;
-	    }
-	  else
-	    {
-	      chosen_timer = idle_timer;
-	      idle_timers = XCDR (idle_timers);
-	      difference = idle_timer_difference;
-	    }
-	}
-      else if (CONSP (timers))
+      if (EMACS_TIME_VALID_P (timer_difference)
+	  && (! EMACS_TIME_VALID_P (idle_timer_difference)
+	      || idle_timer_ripe < timer_ripe
+	      || (idle_timer_ripe == timer_ripe
+		  && (timer_ripe
+		      ? EMACS_TIME_LT (idle_timer_difference,
+				       timer_difference)
+		      : EMACS_TIME_LT (timer_difference,
+				       idle_timer_difference)))))
 	{
 	  chosen_timer = timer;
 	  timers = XCDR (timers);
 	  difference = timer_difference;
+	  ripe = timer_ripe;
 	}
       else
 	{
 	  chosen_timer = idle_timer;
 	  idle_timers = XCDR (idle_timers);
 	  difference = idle_timer_difference;
+	  ripe = idle_timer_ripe;
 	}
-      vector = XVECTOR (chosen_timer)->contents;

       /* If timer is ripe, run it if it hasn't been run.  */
-      if (EMACS_TIME_NEG_P (difference)
-	  || (EMACS_SECS (difference) == 0
-	      && EMACS_USECS (difference) == 0))
+      if (ripe)
 	{
+	  vector = XVECTOR (chosen_timer)->contents;
 	  if (NILP (vector[0]))
 	    {
 	      int count = SPECPDL_INDEX ();
@@ -4449,7 +4441,7 @@
    timer list for the time being.

    Returns the time to wait until the next timer fires.
-   If no timer is active, return -1.
+   If no timer is active, return an invalid value.

    As long as any timer is ripe, we run it.  */

@@ -4462,33 +4454,29 @@
     {
       nexttime = timer_check_2 ();
     }
-  while (EMACS_SECS (nexttime) == 0 && EMACS_USECS (nexttime) == 0);
+  while (EMACS_SECS (nexttime) == 0 && EMACS_NSECS (nexttime) == 0);

   return nexttime;
 }

 DEFUN ("current-idle-time", Fcurrent_idle_time, Scurrent_idle_time, 0, 0, 0,
        doc: /* Return the current length of Emacs idleness, or nil.
-The value when Emacs is idle is a list of three integers.  The first has
-the most significant 16 bits of the seconds, while the second has the least
-significant 16 bits.  The third integer gives the microsecond count.
+The value when Emacs is idle is a list of three numbers (HIGH LOW NSEC)
+in the same style as (current-time).

 The value when Emacs is not idle is nil.

-The microsecond count is zero on systems that do not provide
-resolution finer than a second.  */)
+NSEC is a multiple of the system clock resolution.  */)
   (void)
 {
-  if (! EMACS_TIME_NEG_P (timer_idleness_start_time))
+  if (EMACS_TIME_VALID_P (timer_idleness_start_time))
     {
       EMACS_TIME now, idleness_now;

       EMACS_GET_TIME (now);
       EMACS_SUB_TIME (idleness_now, now, timer_idleness_start_time);

-      return list3 (make_number ((EMACS_SECS (idleness_now) >> 16) & 0xffff),
-		    make_number ((EMACS_SECS (idleness_now) >> 0)  & 0xffff),
-		    make_number (EMACS_USECS (idleness_now)));
+      return make_lisp_time (idleness_now);
     }

   return Qnil;
@@ -10779,7 +10767,7 @@
 }
 \f
 void
-set_waiting_for_input (struct timeval *time_to_clear)
+set_waiting_for_input (EMACS_TIME *time_to_clear)
 {
   input_available_clear_time = time_to_clear;

@@ -11382,7 +11370,7 @@
   quit_char = Ctl ('g');
   Vunread_command_events = Qnil;
   unread_command_char = -1;
-  EMACS_SET_SECS_USECS (timer_idleness_start_time, -1, -1);
+  EMACS_SET_INVALID_TIME (timer_idleness_start_time);
   total_keys = 0;
   recent_keys_index = 0;
   kbd_fetch_ptr = kbd_buffer;

=== modified file 'src/lisp.h'
--- src/lisp.h	2011-06-24 21:25:22 +0000
+++ src/lisp.h	2011-07-01 05:24:23 +0000
@@ -3011,6 +3011,7 @@
 EXFUN (Fwiden, 0);
 EXFUN (Fuser_login_name, 1);
 EXFUN (Fsystem_name, 0);
+extern void time_overflow (void) NO_RETURN;
 EXFUN (Fcurrent_time, 0);
 EXFUN (Fget_internal_run_time, 0);
 extern EMACS_INT clip_to_bounds (EMACS_INT, EMACS_INT, EMACS_INT);
@@ -3307,7 +3308,7 @@
 EXFUN (Fwaiting_for_user_input_p, 0);
 extern Lisp_Object Qprocessp;
 extern void kill_buffer_processes (Lisp_Object);
-extern int wait_reading_process_output (int, int, int, int,
+extern int wait_reading_process_output (intmax_t, int, int, int,
                                         Lisp_Object,
                                         struct Lisp_Process *,
                                         int);

=== modified file 'src/lread.c'
--- src/lread.c	2011-06-24 21:25:22 +0000
+++ src/lread.c	2011-07-01 05:24:23 +0000
@@ -604,14 +604,10 @@
   /* Compute timeout.  */
   if (NUMBERP (seconds))
     {
-      EMACS_TIME wait_time;
-      int sec, usec;
       double duration = extract_float (seconds);
+      EMACS_TIME wait_time = EMACS_TIME_FROM_DOUBLE (duration);

-      sec  = (int) duration;
-      usec = (duration - sec) * 1000000;
       EMACS_GET_TIME (end_time);
-      EMACS_SET_SECS_USECS (wait_time, sec, usec);
       EMACS_ADD_TIME (end_time, end_time, wait_time);
     }


=== modified file 'src/msdos.c'
--- src/msdos.c	2011-06-24 21:25:22 +0000
+++ src/msdos.c	2011-07-01 05:24:23 +0000
@@ -4072,13 +4072,6 @@
 #ifndef HAVE_SELECT
 #include "sysselect.h"

-#ifndef EMACS_TIME_ZERO_OR_NEG_P
-#define EMACS_TIME_ZERO_OR_NEG_P(time)	\
-  ((long)(time).tv_sec < 0		\
-   || ((time).tv_sec == 0		\
-       && (long)(time).tv_usec <= 0))
-#endif
-
 /* This yields the rest of the current time slice to the task manager.
    It should be called by any code which knows that it has nothing
    useful to do except idle.
@@ -4147,12 +4140,12 @@

 	  /* When seconds wrap around, we assume that no more than
 	     1 minute passed since last `gettime'.  */
-	  if (EMACS_TIME_NEG_P (cldiff))
+	  if (EMACS_TIME_SIGN (cldiff) < 0)
 	    EMACS_SET_SECS (cldiff, EMACS_SECS (cldiff) + 60);
 	  EMACS_SUB_TIME (*timeout, *timeout, cldiff);

 	  /* Stop when timeout value crosses zero.  */
-	  if (EMACS_TIME_ZERO_OR_NEG_P (*timeout))
+	  if (EMACS_TIME_SIGN (*timeout) <= 0)
 	    return 0;
 	  cllast = clnow;
 	  dos_yield_time_slice ();

=== modified file 'src/nsterm.h'
--- src/nsterm.h	2011-06-22 06:16:16 +0000
+++ src/nsterm.h	2011-07-01 05:24:23 +0000
@@ -787,7 +787,8 @@

 /* This in nsterm.m */
 extern int ns_select (int nfds, fd_set *readfds, fd_set *writefds,
-                      fd_set *exceptfds, struct timeval *timeout);
+                      fd_set *exceptfds, EMACS_TIME *timeout,
+		      sigset_t *sigmask);
 extern unsigned long ns_get_rgb_color (struct frame *f,
                                        float r, float g, float b, float a);
 extern NSPoint last_mouse_motion_position;

=== modified file 'src/nsterm.m'
--- src/nsterm.m	2011-05-28 16:56:53 +0000
+++ src/nsterm.m	2011-07-01 05:24:23 +0000
@@ -180,7 +180,6 @@
 static NSTimer *fd_entry = nil;
 static NSTimer *scroll_repeat_entry = nil;
 static fd_set select_readfds, t_readfds;
-static struct timeval select_timeout;
 static int select_nfds;
 static NSAutoreleasePool *outerpool;
 static struct input_event *emacs_event = NULL;
@@ -383,67 +382,30 @@
     }
 }

-
-static int
-timeval_subtract (struct timeval *result, struct timeval x, struct timeval y)
-/* --------------------------------------------------------------------------
-   Subtract the `struct timeval' values X and Y, storing the result in RESULT.
-   Return 1 if the difference is negative, otherwise 0.
-   -------------------------------------------------------------------------- */
-{
-  /* Perform the carry for the later subtraction by updating y.
-     This is safer because on some systems
-     the tv_sec member is unsigned.  */
-  if (x.tv_usec < y.tv_usec)
-    {
-      int nsec = (y.tv_usec - x.tv_usec) / 1000000 + 1;
-      y.tv_usec -= 1000000 * nsec;
-      y.tv_sec += nsec;
-    }
-  if (x.tv_usec - y.tv_usec > 1000000)
-    {
-      int nsec = (y.tv_usec - x.tv_usec) / 1000000;
-      y.tv_usec += 1000000 * nsec;
-      y.tv_sec -= nsec;
-    }
-
-  /* Compute the time remaining to wait.  tv_usec is certainly positive.  */
-  result->tv_sec = x.tv_sec - y.tv_sec;
-  result->tv_usec = x.tv_usec - y.tv_usec;
-
-  /* Return indication of whether the result should be considered negative.  */
-  return x.tv_sec < y.tv_sec;
-}
-
 static void
 ns_timeout (int usecs)
 /* --------------------------------------------------------------------------
      Blocking timer utility used by ns_ring_bell
    -------------------------------------------------------------------------- */
 {
-  struct timeval wakeup;
+  EMACS_TIME wakeup, delay;

   EMACS_GET_TIME (wakeup);
-
-  /* Compute time to wait until, propagating carry from usecs.  */
-  wakeup.tv_usec += usecs;
-  wakeup.tv_sec += (wakeup.tv_usec / 1000000);
-  wakeup.tv_usec %= 1000000;
+  EMACS_SET_SECS_USECS (delay, 0, usecs);
+  EMACS_ADD_TIME (wakeup, wakeup, delay);

   /* Keep waiting until past the time wakeup.  */
   while (1)
     {
-      struct timeval timeout;
+      EMACS_TIME timeout;

       EMACS_GET_TIME (timeout);
-
-      /* In effect, timeout = wakeup - timeout.
-	 Break if result would be negative.  */
-      if (timeval_subtract (&timeout, wakeup, timeout))
+      if (EMACS_TIME_LE (wakeup, timeout))
 	break;
+      EMACS_SUB_TIME (timeout, wakeup, timeout);

       /* Try to wait that long--but we might wake up sooner.  */
-      select (0, NULL, NULL, NULL, &timeout);
+      pselect (0, NULL, NULL, NULL, &timeout, NULL);
     }
 }

@@ -3318,7 +3280,7 @@

 int
 ns_select (int nfds, fd_set *readfds, fd_set *writefds,
-           fd_set *exceptfds, struct timeval *timeout)
+           fd_set *exceptfds, EMACS_TIME *timeout, sigset_t *sigmask)
 /* --------------------------------------------------------------------------
      Replacement for select, checking for events
    -------------------------------------------------------------------------- */
@@ -3326,12 +3288,14 @@
   int result;
   double time;
   NSEvent *ev;
+  struct timespec select_timeout;
+
 /*  NSTRACE (ns_select); */

   if (NSApp == nil || inNsSelect == 1 /* || ([NSApp isActive] == NO &&
                       [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:nil
  inMode:NSDefaultRunLoopMode dequeue:NO] == nil) */)
-    return select (nfds, readfds, writefds, exceptfds, timeout);
+    return pselect (nfds, readfds, writefds, exceptfds, timeout, sigmask);

   /* Save file descriptor set, which gets overwritten in calls to select ()
      Note, this is called from process.c, and only readfds is ever set */
@@ -3344,8 +3308,9 @@
     select_nfds = 0;

     /* Try an initial select for pending data on input files */
-  select_timeout.tv_sec = select_timeout.tv_usec = 0;
-  result = select (nfds, readfds, writefds, exceptfds, &select_timeout);
+  select_timeout.tv_sec = select_timeout.tv_nsec = 0;
+  result = pselect (nfds, readfds, writefds, exceptfds,
+		    &select_timeout, sigmask);
   if (result)
     return result;

@@ -3354,7 +3319,7 @@

     /* set a timeout and run the main AppKit event loop while continuing
        to monitor the files */
-  time = ((double) timeout->tv_sec) + ((double) timeout->tv_usec)/1000000.0;
+  time = EMACS_TIME_TO_DOUBLE (*timeout);
   timed_entry = [[NSTimer scheduledTimerWithTimeInterval: time
                                            target: NSApp
                                          selector: @selector (timeout_handler:)
@@ -3362,7 +3327,7 @@
                                           repeats: YES] /* for safe removal */
                                                          retain];

-  /* set a periodic task to try the select () again */
+  /* set a periodic task to try the pselect () again */
   fd_entry = [[NSTimer scheduledTimerWithTimeInterval: 0.1
                                                target: NSApp
                                              selector: @selector (fd_handler:)
@@ -3404,7 +3369,7 @@
         }
       else
         {
-          /* Received back from select () in fd_handler; copy the results */
+          /* Received back from pselect () in fd_handler; copy the results */
           if (readfds)
             memcpy (readfds, &select_readfds, sizeof (fd_set));
           return t;
@@ -4367,6 +4332,7 @@
    -------------------------------------------------------------------------- */
 {
   int result;
+  struct timespec select_timeout;
   /* NSTRACE (fd_handler); */

   if (select_nfds == 0)
@@ -4374,9 +4340,8 @@

   memcpy (&t_readfds, &select_readfds, sizeof (fd_set));

-  select_timeout.tv_sec = select_timeout.tv_usec = 0;
-  result = select (select_nfds, &t_readfds, (SELECT_TYPE *)0, (SELECT_TYPE *)0,
-                  &select_timeout);
+  select_timeout.tv_sec = select_timeout.tv_nsec = 0;
+  result = pselect (select_nfds, &t_readfds, NULL, NULL, &select_timeout, NULL);
   if (result)
     {
       memcpy (&select_readfds, &t_readfds, sizeof (fd_set));

=== modified file 'src/process.c'
--- src/process.c	2011-06-26 03:40:40 +0000
+++ src/process.c	2011-07-01 05:24:23 +0000
@@ -210,13 +210,11 @@
 #endif

 #if !defined (ADAPTIVE_READ_BUFFERING) && !defined (NO_ADAPTIVE_READ_BUFFERING)
-#ifdef EMACS_HAS_USECS
 #define ADAPTIVE_READ_BUFFERING
 #endif
-#endif

 #ifdef ADAPTIVE_READ_BUFFERING
-#define READ_OUTPUT_DELAY_INCREMENT 10000
+#define READ_OUTPUT_DELAY_INCREMENT (EMACS_TIME_RESOLUTION / 100)
 #define READ_OUTPUT_DELAY_MAX       (READ_OUTPUT_DELAY_INCREMENT * 5)
 #define READ_OUTPUT_DELAY_MAX_MAX   (READ_OUTPUT_DELAY_INCREMENT * 7)

@@ -3264,7 +3262,7 @@
 	{
 	  /* Unlike most other syscalls connect() cannot be called
 	     again.  (That would return EALREADY.)  The proper way to
-	     wait for completion is select(). */
+	     wait for completion is pselect(). */
 	  int sc;
 	  socklen_t len;
 	  SELECT_TYPE fdset;
@@ -3272,8 +3270,7 @@
 	  FD_ZERO (&fdset);
 	  FD_SET (s, &fdset);
 	  QUIT;
-	  sc = select (s + 1, (SELECT_TYPE *)0, &fdset, (SELECT_TYPE *)0,
-		       (EMACS_TIME *)0);
+	  sc = pselect (s + 1, NULL, &fdset, NULL, NULL, NULL);
 	  if (sc == -1)
 	    {
 	      if (errno == EINTR)
@@ -3875,7 +3872,8 @@
 Return non-nil if we received any output before the timeout expired.  */)
   (register Lisp_Object process, Lisp_Object seconds, Lisp_Object millisec, Lisp_Object just_this_one)
 {
-  int secs, usecs = 0;
+  intmax_t secs;
+  int nsecs;

   if (! NILP (process))
     CHECK_PROCESS (process);
@@ -3894,27 +3892,36 @@
 	}
     }

+  secs = 0;
+  nsecs = -1;
+
   if (!NILP (seconds))
     {
       if (INTEGERP (seconds))
-	secs = XINT (seconds);
+	{
+	  if (0 < XINT (seconds))
+	    {
+	      secs = XINT (seconds);
+	      nsecs = 0;
+	    }
+	}
       else if (FLOATP (seconds))
 	{
-	  double timeout = XFLOAT_DATA (seconds);
-	  secs = (int) timeout;
-	  usecs = (int) ((timeout - (double) secs) * 1000000);
+	  if (0 < XFLOAT_DATA (seconds))
+	    {
+	      EMACS_TIME t = EMACS_TIME_FROM_DOUBLE (XFLOAT_DATA (seconds));
+	      secs = min (EMACS_SECS (t), INTMAX_MAX);
+	      nsecs = EMACS_NSECS (t);
+	    }
 	}
       else
 	wrong_type_argument (Qnumberp, seconds);
-
-      if (secs < 0 || (secs == 0 && usecs == 0))
-	secs = -1, usecs = 0;
     }
-  else
-    secs = NILP (process) ? -1 : 0;
+  else if (! NILP (process))
+    nsecs = 0;

   return
-    (wait_reading_process_output (secs, usecs, 0, 0,
+    (wait_reading_process_output (secs, nsecs, 0, 0,
 				  Qnil,
 				  !NILP (process) ? XPROCESS (process) : NULL,
 				  NILP (just_this_one) ? 0 :
@@ -4155,34 +4162,19 @@
 {
 }

-/* Use a wrapper around select to work around a bug in gdb 5.3.
-   Normally, the wrapper is optimized away by inlining.
-
-   If emacs is stopped inside select, the gdb backtrace doesn't
-   show the function which called select, so it is practically
-   impossible to step through wait_reading_process_output.  */
-
-#ifndef select
-static inline int
-select_wrapper (int n, fd_set *rfd, fd_set *wfd, fd_set *xfd, struct timeval *tmo)
-{
-  return select (n, rfd, wfd, xfd, tmo);
-}
-#define select select_wrapper
-#endif
-
 /* Read and dispose of subprocess output while waiting for timeout to
    elapse and/or keyboard input to be available.

    TIME_LIMIT is:
-     timeout in seconds, or
-     zero for no limit, or
-     -1 means gobble data immediately available but don't wait for any.
+     timeout in seconds
+     If negative, gobble data immediately available but don't wait for any.

-   MICROSECS is:
-     an additional duration to wait, measured in microseconds.
-     If this is nonzero and time_limit is 0, then the timeout
-     consists of MICROSECS only.
+   NSECS is:
+     an additional duration to wait, measured in nanoseconds
+     If TIME_LIMIT is zero, then:
+       If NSECS == 0, there is no limit.
+       If NSECS > 0, the timeout consists of NSEC only.
+       If NSECS < 0, gobble data immediately, as if TIME_LIMIT were negative.

    READ_KBD is a lisp value:
      0 to ignore keyboard input, or
@@ -4209,7 +4201,7 @@
    Otherwise, return true if we received input from any process.  */

 int
-wait_reading_process_output (int time_limit, int microsecs, int read_kbd,
+wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
 			     int do_display,
 			     Lisp_Object wait_for_cell,
 			     struct Lisp_Process *wait_proc, int just_wait_proc)
@@ -4229,7 +4221,7 @@
   FD_ZERO (&Available);
   FD_ZERO (&Writeok);

-  if (time_limit == 0 && microsecs == 0 && wait_proc && !NILP (Vinhibit_quit)
+  if (time_limit == 0 && nsecs == 0 && wait_proc && !NILP (Vinhibit_quit)
       && !(CONSP (wait_proc->status) && EQ (XCAR (wait_proc->status), Qexit)))
     message ("Blocking call to accept-process-output with quit inhibited!!");

@@ -4241,12 +4233,20 @@
 			 make_number (waiting_for_user_input_p));
   waiting_for_user_input_p = read_kbd;

+  if (time_limit < 0)
+    {
+      time_limit = 0;
+      nsecs = -1;
+    }
+  else if (TYPE_MAXIMUM (time_t) < time_limit)
+    time_limit = TYPE_MAXIMUM (time_t);
+
   /* Since we may need to wait several times,
      compute the absolute time to return at.  */
-  if (time_limit || microsecs)
+  if (time_limit || nsecs) /* FIXME neither should be negative, no? */
     {
       EMACS_GET_TIME (end_time);
-      EMACS_SET_SECS_USECS (timeout, time_limit, microsecs);
+      EMACS_SET_SECS_NSECS (timeout, time_limit, nsecs);
       EMACS_ADD_TIME (end_time, end_time, timeout);
     }

@@ -4270,7 +4270,7 @@

       /* Compute time from now till when time limit is up */
       /* Exit if already run out */
-      if (time_limit == -1)
+      if (nsecs < 0)
 	{
 	  /* -1 specified for timeout means
 	     gobble output available now
@@ -4278,12 +4278,12 @@

 	  EMACS_SET_SECS_USECS (timeout, 0, 0);
 	}
-      else if (time_limit || microsecs)
+      else if (time_limit || nsecs)
 	{
 	  EMACS_GET_TIME (timeout);
+	  if (EMACS_TIME_LE (end_time, timeout))
+	    break;
 	  EMACS_SUB_TIME (timeout, end_time, timeout);
-	  if (EMACS_TIME_NEG_P (timeout))
-	    break;
 	}
       else
 	{
@@ -4329,21 +4329,22 @@
 	      && requeued_events_pending_p ())
 	    break;

-	  if (! EMACS_TIME_NEG_P (timer_delay) && time_limit != -1)
-	    {
-	      EMACS_TIME difference;
-	      EMACS_SUB_TIME (difference, timer_delay, timeout);
-	      if (EMACS_TIME_NEG_P (difference))
-		{
-		  timeout = timer_delay;
-		  timeout_reduced_for_timers = 1;
-		}
-	    }
-	  /* If time_limit is -1, we are not going to wait at all.  */
-	  else if (time_limit != -1)
-	    {
-	      /* This is so a breakpoint can be put here.  */
-	      wait_reading_process_output_1 ();
+	  /* If time_limit is negative, we are not going to wait at all.  */
+	  if (0 <= nsecs)
+	    {
+	      if (EMACS_TIME_VALID_P (timer_delay))
+		{
+		  if (EMACS_TIME_LT (timer_delay, timeout))
+		    {
+		      timeout = timer_delay;
+		      timeout_reduced_for_timers = 1;
+		    }
+		}
+	      else
+		{
+		  /* This is so a breakpoint can be put here.  */
+		  wait_reading_process_output_1 ();
+		}
 	    }
 	}

@@ -4372,14 +4373,14 @@
 	  Ctemp = write_mask;

 	  EMACS_SET_SECS_USECS (timeout, 0, 0);
-	  if ((select (max (max_process_desc, max_input_desc) + 1,
-		       &Atemp,
+	  if ((pselect (max (max_process_desc, max_input_desc) + 1,
+			&Atemp,
 #ifdef NON_BLOCKING_CONNECT
-		       (num_pending_connects > 0 ? &Ctemp : (SELECT_TYPE *)0),
+			(num_pending_connects > 0 ? &Ctemp : NULL),
 #else
-		       (SELECT_TYPE *)0,
+			NULL,
 #endif
-		       (SELECT_TYPE *)0, &timeout)
+			NULL, &timeout, NULL)
 	       <= 0))
 	    {
 	      /* It's okay for us to do this and then continue with
@@ -4502,9 +4503,9 @@
 	     Vprocess_adaptive_read_buffering is nil.  */
 	  if (process_output_skip && check_delay > 0)
 	    {
-	      int usecs = EMACS_USECS (timeout);
-	      if (EMACS_SECS (timeout) > 0 || usecs > READ_OUTPUT_DELAY_MAX)
-		usecs = READ_OUTPUT_DELAY_MAX;
+	      int nsecs = EMACS_NSECS (timeout);
+	      if (EMACS_SECS (timeout) > 0 || nsecs > READ_OUTPUT_DELAY_MAX)
+		nsecs = READ_OUTPUT_DELAY_MAX;
 	      for (channel = 0; check_delay > 0 && channel <= max_process_desc; channel++)
 		{
 		  proc = chan_process[channel];
@@ -4519,11 +4520,11 @@
 			continue;
 		      FD_CLR (channel, &Available);
 		      XPROCESS (proc)->read_output_skip = 0;
-		      if (XPROCESS (proc)->read_output_delay < usecs)
-			usecs = XPROCESS (proc)->read_output_delay;
+		      if (XPROCESS (proc)->read_output_delay < nsecs)
+			nsecs = XPROCESS (proc)->read_output_delay;
 		    }
 		}
-	      EMACS_SET_SECS_USECS (timeout, 0, usecs);
+	      EMACS_SET_SECS_NSECS (timeout, 0, nsecs);
 	      process_output_skip = 0;
 	    }
 #endif
@@ -4532,12 +4533,12 @@
 #elif defined (HAVE_NS)
 	  nfds = ns_select
 #else
-	  nfds = select
+	  nfds = pselect
 #endif
             (max (max_process_desc, max_input_desc) + 1,
              &Available,
              (check_write ? &Writeok : (SELECT_TYPE *)0),
-             (SELECT_TYPE *)0, &timeout);
+             NULL, &timeout, NULL);

 #ifdef HAVE_GNUTLS
           /* GnuTLS buffers data internally.  In lowat mode it leaves
@@ -4564,7 +4565,7 @@
       /*  If we woke up due to SIGWINCH, actually change size now.  */
       do_pending_window_change (0);

-      if (time_limit && nfds == 0 && ! timeout_reduced_for_timers)
+      if ((time_limit || nsecs) && nfds == 0 && ! timeout_reduced_for_timers)
 	/* We wanted the full specified time, so return now.  */
 	break;
       if (nfds < 0)
@@ -4716,7 +4717,7 @@
 	      if (wait_channel == channel)
 		{
 		  wait_channel = -1;
-		  time_limit = -1;
+		  nsecs = -1;
 		  got_some_input = 1;
 		}
 	      proc = chan_process[channel];
@@ -5488,12 +5489,8 @@
 		      else if (STRINGP (object))
 			offset = buf - SSDATA (object);

-#ifdef EMACS_HAS_USECS
-		      wait_reading_process_output (0, 20000, 0, 0, Qnil, NULL, 0);
-#else
-		      wait_reading_process_output (1, 0, 0, 0, Qnil, NULL, 0);
-#endif
-
+		      wait_reading_process_output (0, 20 * 1000 * 1000,
+						   0, 0, Qnil, NULL, 0);
 		      if (BUFFERP (object))
 			buf = (char *) BUF_BYTE_ADDRESS (XBUFFER (object),
 							 offset);
@@ -6647,9 +6644,15 @@
    Wait for timeout to elapse and/or keyboard input to be available.

    time_limit is:
-     timeout in seconds, or
-     zero for no limit, or
-     -1 means gobble data immediately available but don't wait for any.
+     timeout in seconds
+     If negative, gobble data immediately available but don't wait for any.
+
+   nsec is:
+     an additional duration to wait, measured in nanoseconds
+     If TIME_LIMIT is zero, then:
+       If NSEC == 0, there is no limit.
+       If NSEC > 0, the timeout consists of NSEC only.
+       If NSECS < 0, gobble data immediately, as if TIME_LIMIT were negative.

    read_kbd is a Lisp_Object:
      0 to ignore keyboard input, or
@@ -6666,7 +6669,7 @@
    Return true if we received input from any process.  */

 int
-wait_reading_process_output (int time_limit, int microsecs, int read_kbd,
+wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
 			     int do_display,
 			     Lisp_Object wait_for_cell,
 			     struct Lisp_Process *wait_proc, int just_wait_proc)
@@ -6676,11 +6679,19 @@
   SELECT_TYPE waitchannels;
   int xerrno;

+  if (time_limit < 0)
+    {
+      time_limit = 0;
+      nsecs = -1;
+    }
+  else if (TYPE_MAXIMUM (time_t) < time_limit)
+    time_limit = TYPE_MAXIMUM (time_t);
+
   /* What does time_limit really mean?  */
-  if (time_limit || microsecs)
+  if (time_limit || nsecs) /* FIXME: what if negative? */
     {
       EMACS_GET_TIME (end_time);
-      EMACS_SET_SECS_USECS (timeout, time_limit, microsecs);
+      EMACS_SET_SECS_NSECS (timeout, time_limit, nsecs);
       EMACS_ADD_TIME (end_time, end_time, timeout);
     }

@@ -6706,7 +6717,7 @@

       /* Compute time from now till when time limit is up */
       /* Exit if already run out */
-      if (time_limit == -1)
+      if (nsecs < 0)
 	{
 	  /* -1 specified for timeout means
 	     gobble output available now
@@ -6714,12 +6725,12 @@

 	  EMACS_SET_SECS_USECS (timeout, 0, 0);
 	}
-      else if (time_limit || microsecs)
+      else if (time_limit || nsecs)
 	{
 	  EMACS_GET_TIME (timeout);
+	  if (EMACS_TIME_LE (end_time, timeout))
+	    break;
 	  EMACS_SUB_TIME (timeout, end_time, timeout);
-	  if (EMACS_TIME_NEG_P (timeout))
-	    break;
 	}
       else
 	{
@@ -6752,11 +6763,9 @@
 	      && requeued_events_pending_p ())
 	    break;

-	  if (! EMACS_TIME_NEG_P (timer_delay) && time_limit != -1)
+	  if (EMACS_TIME_VALID_P (timer_delay) && 0 <= nsecs)
 	    {
-	      EMACS_TIME difference;
-	      EMACS_SUB_TIME (difference, timer_delay, timeout);
-	      if (EMACS_TIME_NEG_P (difference))
+	      if (EMACS_TIME_LT (timer_delay, timeout))
 		{
 		  timeout = timer_delay;
 		  timeout_reduced_for_timers = 1;
@@ -6792,8 +6801,7 @@
 	  FD_ZERO (&waitchannels);
 	}
       else
-	nfds = select (1, &waitchannels, (SELECT_TYPE *)0, (SELECT_TYPE *)0,
-		       &timeout);
+	nfds = pselect (1, &waitchannels, NULL, NULL, &timeout, NULL);

       xerrno = errno;

@@ -6803,7 +6811,7 @@
       /*  If we woke up due to SIGWINCH, actually change size now.  */
       do_pending_window_change (0);

-      if (time_limit && nfds == 0 && ! timeout_reduced_for_timers)
+      if ((time_limit || nsecs) && nfds == 0 && ! timeout_reduced_for_timers)
 	/* We waited the full specified time, so return now.  */
 	break;

@@ -7106,19 +7114,19 @@
  majflt  -- number of major page faults (number)
  cminflt -- cumulative number of minor page faults (number)
  cmajflt -- cumulative number of major page faults (number)
- utime   -- user time used by the process, in the (HIGH LOW USEC) format
- stime   -- system time used by the process, in the (HIGH LOW USEC) format
- time    -- sum of utime and stime, in the (HIGH LOW USEC) format
- cutime  -- user time used by the process and its children, (HIGH LOW USEC)
- cstime  -- system time used by the process and its children, (HIGH LOW USEC)
- ctime   -- sum of cutime and cstime, in the (HIGH LOW USEC) format
+ utime   -- user time used by the process, in the (HIGH LOW NSEC) format
+ stime   -- system time used by the process, in the (HIGH LOW NSEC) format
+ time    -- sum of utime and stime, in the (HIGH LOW NSEC) format
+ cutime  -- user time used by the process and its children, (HIGH LOW NSEC)
+ cstime  -- system time used by the process and its children, (HIGH LOW NSEC)
+ ctime   -- sum of cutime and cstime, in the (HIGH LOW NSEC) format
  pri     -- priority of the process (number)
  nice    -- nice value of the process (number)
  thcount -- process thread count (number)
- start   -- time the process started, in the (HIGH LOW USEC) format
+ start   -- time the process started, in the (HIGH LOW NSEC) format
  vsize   -- virtual memory size of the process in KB's (number)
  rss     -- resident set size of the process in KB's (number)
- etime   -- elapsed time the process is running, in (HIGH LOW USEC) format
+ etime   -- elapsed time the process is running, in (HIGH LOW NSEC) format
  pcpu    -- percents of CPU time used by the process (floating-point number)
  pmem    -- percents of total physical memory used by process's resident set
               (floating-point number)

=== modified file 'src/process.h'
--- src/process.h	2011-05-12 07:07:06 +0000
+++ src/process.h	2011-07-01 05:24:23 +0000
@@ -104,8 +104,8 @@
        On some systems, e.g. GNU/Linux, Emacs is seen as
        an interactive app also when reading process output, meaning
        that process output can be read in as little as 1 byte at a
-       time.  Value is micro-seconds to delay reading output from
-       this process.  Range is 0 .. 50000.  */
+       time.  Value is nanoseconds to delay reading output from
+       this process.  Range is 0 .. 50 * 1000 * 1000.  */
     int read_output_delay;
     /* Should we delay reading output from this process.
        Initialized from `Vprocess_adaptive_read_buffering'.

=== modified file 'src/sysdep.c'
--- src/sysdep.c	2011-06-25 08:40:38 +0000
+++ src/sysdep.c	2011-07-01 05:24:23 +0000
@@ -34,6 +34,7 @@
 #include <allocator.h>
 #include <careadlinkat.h>
 #include <ignore-value.h>
+#include <utimens.h>

 #include "lisp.h"
 #include "sysselect.h"
@@ -103,20 +104,6 @@

 #include "syssignal.h"
 #include "systime.h"
-#ifdef HAVE_UTIME_H
-#include <utime.h>
-#endif
-
-#ifndef HAVE_UTIMES
-#ifndef HAVE_STRUCT_UTIMBUF
-/* We want to use utime rather than utimes, but we couldn't find the
-   structure declaration.  We'll use the traditional one.  */
-struct utimbuf {
-  long actime;
-  long modtime;
-};
-#endif
-#endif

 static int emacs_get_tty (int, struct emacs_tty *);
 static int emacs_set_tty (int, struct emacs_tty *, int);
@@ -2013,30 +2000,6 @@
 #endif /* HPUX and not HAVE_PERROR */

 /*
- *	Gettimeofday.  Simulate as much as possible.  Only accurate
- *	to nearest second.  Emacs doesn't use tzp so ignore it for now.
- *	Only needed when subprocesses are defined.
- */
-
-#ifndef HAVE_GETTIMEOFDAY
-#ifdef HAVE_TIMEVAL
-
-int
-gettimeofday (struct timeval *tp, struct timezone *tzp)
-{
-  extern long time (long);
-
-  tp->tv_sec = time ((long *)0);
-  tp->tv_usec = 0;
-  if (tzp != 0)
-    tzp->tz_minuteswest = -1;
-  return 0;
-}
-
-#endif
-#endif /* !HAVE_GETTIMEOFDAY && HAVE_TIMEVAL */
-
-/*
  *	This function will go away as soon as all the stubs fixed. (fnf)
  */

@@ -2072,20 +2035,43 @@
 #endif /* HAVE_DIRENT_H */

 \f
+/* Return a struct timeval that is roughly equivalent to T.
+   Use the least timeval not less than T.
+   Return an extremal value if the result would overflow.  */
+struct timeval
+make_timeval (EMACS_TIME t)
+{
+  struct timeval tv;
+  tv.tv_sec = t.tv_sec;
+  tv.tv_usec = t.tv_nsec / 1000;
+
+  if (t.tv_nsec % 1000 != 0)
+    {
+      if (tv.tv_usec < 999999)
+	tv.tv_usec++;
+      else if (tv.tv_sec < TYPE_MAXIMUM (time_t))
+	{
+	  tv.tv_sec++;
+	  tv.tv_usec = 0;
+	}
+    }
+
+  return tv;
+}
+
+/* Set the access and modification time stamps of FD (a.k.a. FILE) to be
+   ATIME and MTIME, respectively.
+   FD must be either negative -- in which case it is ignored --
+   or a file descriptor that is open on FILE.
+   If FD is nonnegative, then FILE can be NULL.  */
 int
-set_file_times (const char *filename, EMACS_TIME atime, EMACS_TIME mtime)
+set_file_times (int fd, const char *filename,
+		EMACS_TIME atime, EMACS_TIME mtime)
 {
-#ifdef HAVE_UTIMES
-  struct timeval tv[2];
-  tv[0] = atime;
-  tv[1] = mtime;
-  return utimes (filename, tv);
-#else /* not HAVE_UTIMES */
-  struct utimbuf utb;
-  utb.actime = EMACS_SECS (atime);
-  utb.modtime = EMACS_SECS (mtime);
-  return utime (filename, &utb);
-#endif /* not HAVE_UTIMES */
+  struct timespec timespec[2];
+  timespec[0] = atime;
+  timespec[1] = mtime;
+  return fdutimens (fd, filename, timespec);
 }
 \f
 /* mkdir and rmdir functions, for systems which don't have them.  */
@@ -2549,60 +2535,82 @@
 #endif /* !defined (WINDOWSNT) */

 #ifdef GNU_LINUX
-static void
-time_from_jiffies (unsigned long long tval, long hz,
-		   time_t *sec, unsigned *usec)
+static EMACS_TIME
+time_from_jiffies (unsigned long long tval, long hz)
 {
-  unsigned long long ullsec;
+  unsigned long long s = tval / hz;
+  unsigned long long frac = tval % hz;
+  int ns;
+  EMACS_TIME t;

-  *sec = tval / hz;
-  ullsec = *sec;
-  tval -= ullsec * hz;
-  /* Careful: if HZ > 1 million, then integer division by it yields zero.  */
-  if (hz <= 1000000)
-    *usec = tval * 1000000 / hz;
+  if (TYPE_MAXIMUM (time_t) < s)
+    time_overflow ();
+  if (LONG_MAX - 1 <= ULLONG_MAX / EMACS_TIME_RESOLUTION
+      || frac <= ULLONG_MAX / EMACS_TIME_RESOLUTION)
+    ns = frac * EMACS_TIME_RESOLUTION / hz;
   else
-    *usec = tval / (hz / 1000000);
+    {
+      /* This is reachable only in the unlikely case that HZ * HZ
+	 exceeds ULLONG_MAX.  It calculates an approximation that is
+	 guaranteed to be in range.  */
+      long hz_per_ns = (hz / EMACS_TIME_RESOLUTION
+			+ (hz % EMACS_TIME_RESOLUTION != 0));
+      ns = frac / hz_per_ns;
+    }
+
+  EMACS_SET_SECS_NSECS (t, s, ns);
+  return t;
 }

 static Lisp_Object
 ltime_from_jiffies (unsigned long long tval, long hz)
 {
-  time_t sec;
-  unsigned usec;
-
-  time_from_jiffies (tval, hz, &sec, &usec);
-
-  return list3 (make_number ((sec >> 16) & 0xffff),
-		make_number (sec & 0xffff),
-		make_number (usec));
+  EMACS_TIME t = time_from_jiffies (tval, hz);
+  return make_lisp_time (t);
 }

-static void
-get_up_time (time_t *sec, unsigned *usec)
+static EMACS_TIME
+get_up_time (void)
 {
   FILE *fup;
+  EMACS_TIME up;

-  *sec = *usec = 0;
+  EMACS_SET_SECS_NSECS (up, 0, 0);

   BLOCK_INPUT;
   fup = fopen ("/proc/uptime", "r");

   if (fup)
     {
-      double uptime, idletime;
+      unsigned long long upsec, upfrac, idlesec, idlefrac;
+      int upfrac_start, upfrac_end, idlefrac_start, idlefrac_end;

-      /* The numbers in /proc/uptime use C-locale decimal point, but
-	 we already set ourselves to the C locale (see `fixup_locale'
-	 in emacs.c).  */
-      if (2 <= fscanf (fup, "%lf %lf", &uptime, &idletime))
+      if (fscanf (fup, "%llu.%n%llu%n %llu.%n%llu%n",
+		  &upsec, &upfrac_start, &upfrac, &upfrac_end,
+		  &idlesec, &idlefrac_start, &idlefrac, &idlefrac_end)
+	  == 4)
 	{
-	  *sec = uptime;
-	  *usec = (uptime - *sec) * 1000000;
+	  if (TYPE_MAXIMUM (time_t) < upsec)
+	    {
+	      upsec = TYPE_MAXIMUM (time_t);
+	      upfrac = EMACS_TIME_RESOLUTION - 1;
+	    }
+	  else
+	    {
+	      int upfraclen = upfrac_end - upfrac_start;
+	      for (; upfraclen < LOG10_EMACS_TIME_RESOLUTION; upfraclen++)
+		upfrac *= 10;
+	      for (; LOG10_EMACS_TIME_RESOLUTION < upfraclen; upfraclen--)
+		upfrac /= 10;
+	      upfrac = min (upfrac, EMACS_TIME_RESOLUTION - 1);
+	    }
+	  EMACS_SET_SECS_NSECS (up, upsec, upfrac);
 	}
       fclose (fup);
     }
   UNBLOCK_INPUT;
+
+  return up;
 }

 #define MAJOR(d) (((unsigned)(d) >> 8) & 0xfff)
@@ -2701,7 +2709,7 @@
   unsigned long minflt, majflt, cminflt, cmajflt, vsize;
   time_t sec;
   unsigned usec;
-  EMACS_TIME tnow, tstart, tboot, telapsed;
+  EMACS_TIME tnow, tstart, tboot, telapsed, us_time;
   double pcpu, pmem;
   Lisp_Object attrs = Qnil;
   Lisp_Object cmd_str, decoded_cmd, tem;
@@ -2828,35 +2836,18 @@
 	  attrs = Fcons (Fcons (Qnice, make_number (niceness)), attrs);
 	  attrs = Fcons (Fcons (Qthcount, make_fixnum_or_float (thcount_eint)), attrs);
 	  EMACS_GET_TIME (tnow);
-	  get_up_time (&sec, &usec);
-	  EMACS_SET_SECS (telapsed, sec);
-	  EMACS_SET_USECS (telapsed, usec);
+	  telapsed = get_up_time ();
 	  EMACS_SUB_TIME (tboot, tnow, telapsed);
-	  time_from_jiffies (start, clocks_per_sec, &sec, &usec);
-	  EMACS_SET_SECS (tstart, sec);
-	  EMACS_SET_USECS (tstart, usec);
+	  tstart = time_from_jiffies (start, clocks_per_sec);
 	  EMACS_ADD_TIME (tstart, tboot, tstart);
-	  attrs = Fcons (Fcons (Qstart,
-				list3 (make_number
-				       ((EMACS_SECS (tstart) >> 16) & 0xffff),
-				       make_number
-				       (EMACS_SECS (tstart) & 0xffff),
-				       make_number
-				       (EMACS_USECS (tstart)))),
-			 attrs);
+	  attrs = Fcons (Fcons (Qstart, make_lisp_time (tstart)), attrs);
 	  attrs = Fcons (Fcons (Qvsize, make_fixnum_or_float (vsize/1024)), attrs);
 	  attrs = Fcons (Fcons (Qrss, make_fixnum_or_float (4*rss)), attrs);
 	  EMACS_SUB_TIME (telapsed, tnow, tstart);
-	  attrs = Fcons (Fcons (Qetime,
-				list3 (make_number
-				       ((EMACS_SECS (telapsed) >> 16) & 0xffff),
-				       make_number
-				       (EMACS_SECS (telapsed) & 0xffff),
-				       make_number
-				       (EMACS_USECS (telapsed)))),
-			 attrs);
-	  time_from_jiffies (u_time + s_time, clocks_per_sec, &sec, &usec);
-	  pcpu = (sec + usec / 1000000.0) / (EMACS_SECS (telapsed) + EMACS_USECS (telapsed) / 1000000.0);
+	  attrs = Fcons (Fcons (Qetime, make_lisp_time (telapsed)), attrs);
+	  us_time = time_from_jiffies (u_time + s_time, clocks_per_sec);
+	  pcpu = (EMACS_TIME_TO_DOUBLE (us_time)
+		  / EMACS_TIME_TO_DOUBLE (telapsed));
 	  if (pcpu > 1.0)
 	    pcpu = 1.0;
 	  attrs = Fcons (Fcons (Qpcpu, make_float (100 * pcpu)), attrs);
@@ -3037,27 +3028,13 @@
 		Qcstime
 		Are they available? */

-	  attrs = Fcons (Fcons (Qtime,
-	  			list3 (make_number (pinfo.pr_time.tv_sec >> 16),
-	  			       make_number (pinfo.pr_time.tv_sec & 0xffff),
-	  			       make_number (pinfo.pr_time.tv_nsec))),
-	  		 attrs);
-
-	  attrs = Fcons (Fcons (Qctime,
-	  			list3 (make_number (pinfo.pr_ctime.tv_sec >> 16),
-	  			       make_number (pinfo.pr_ctime.tv_sec & 0xffff),
-	  			       make_number (pinfo.pr_ctime.tv_nsec))),
-	  		 attrs);
-
+	  attrs = Fcons (Fcons (Qtime, make_lisp_time (pinfo.pr_time)), attrs);
+	  attrs = Fcons (Fcons (Qctime, make_lisp_time (pinfo.pr_ctime)), attrs);
 	  attrs = Fcons (Fcons (Qpri, make_number (pinfo.pr_lwp.pr_pri)), attrs);
 	  attrs = Fcons (Fcons (Qnice, make_number (pinfo.pr_lwp.pr_nice)), attrs);
 	  attrs = Fcons (Fcons (Qthcount, make_fixnum_or_float (pinfo.pr_nlwp)), attrs);

-	  attrs = Fcons (Fcons (Qstart,
-	  			list3 (make_number (pinfo.pr_start.tv_sec >> 16),
-	  			       make_number (pinfo.pr_start.tv_sec & 0xffff),
-	  			       make_number (pinfo.pr_start.tv_nsec))),
-	  		 attrs);
+	  attrs = Fcons (Fcons (Qstart, make_lisp_time (pinfo.pr_start.tv_sec)), attrs);
 	  attrs = Fcons (Fcons (Qvsize, make_fixnum_or_float (pinfo.pr_size)), attrs);
 	  attrs = Fcons (Fcons (Qrss, make_fixnum_or_float (pinfo.pr_rssize)), attrs);


=== modified file 'src/sysselect.h'
--- src/sysselect.h	2011-01-25 04:08:28 +0000
+++ src/sysselect.h	2011-07-01 05:24:23 +0000
@@ -16,7 +16,6 @@
 You should have received a copy of the GNU General Public License
 along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */

-#ifdef HAVE_SYS_SELECT_H
 #if defined (DARWIN_OS)
 #undef init_process
 #endif
@@ -24,7 +23,6 @@
 #if defined (DARWIN_OS)
 #define init_process emacs_init_process
 #endif
-#endif

 /* The w32 build defines select stuff in w32.h, which is included
    where w32 needs it, but not where sysselect.h is included.  The w32
@@ -52,4 +50,3 @@
 #if !defined (HAVE_SELECT)
 #define select sys_select
 #endif
-

=== modified file 'src/systime.h'
--- src/systime.h	2011-05-20 06:37:13 +0000
+++ src/systime.h	2011-07-01 05:24:23 +0000
@@ -19,16 +19,7 @@
 #ifndef EMACS_SYSTIME_H
 #define EMACS_SYSTIME_H

-#ifdef TIME_WITH_SYS_TIME
-#include <sys/time.h>
-#include <time.h>
-#else
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#else
-#include <time.h>
-#endif
-#endif
+#include <timespec.h>

 #ifdef emacs
 # ifdef HAVE_X_WINDOWS
@@ -59,91 +50,64 @@
 #endif
 #endif
 \f
-/* EMACS_TIME is the type to use to represent temporal intervals -
-   struct timeval on some systems, int on others.  It can be passed as
-   the timeout argument to the select  system call.
-
-   EMACS_SECS (TIME) is an rvalue for the seconds component of TIME.
+/* The type to use to represent temporal intervals.  It can be passed
+   as the timeout argument to the pselect system call.  */
+#define EMACS_TIME struct timespec
+
+/* Resolution of EMACS_TIME time stamps (in units per second), and log
+   base 10 of the resolution.  The log must be a positive integer.  */
+#define EMACS_TIME_RESOLUTION		1000000000
+#define LOG10_EMACS_TIME_RESOLUTION	9
+
+/* EMACS_SECS (TIME) is an rvalue for the seconds component of TIME.
+   EMACS_ADDR_SECS (time) is the address of the seconds component.
    EMACS_SET_SECS (TIME, SECONDS) sets that to SECONDS.

-   EMACS_HAS_USECS is defined if EMACS_TIME has a usecs component.
-   EMACS_USECS (TIME) is an rvalue for the microseconds component of TIME.
-   	This returns zero if EMACS_TIME doesn't have a microseconds component.
-   EMACS_SET_USECS (TIME, MICROSECONDS) sets that to MICROSECONDS.
-	This does nothing if EMACS_TIME doesn't have a microseconds component.
-
-   EMACS_SET_SECS_USECS (TIME, SECS, USECS) sets both components of TIME.
-
-   EMACS_GET_TIME (TIME) stores the current system time in TIME, which
-	should be an lvalue.
-
-   EMACS_ADD_TIME (DEST, SRC1, SRC2) adds SRC1 to SRC2 and stores the
-	result in DEST.  SRC should not be negative.
-
-   EMACS_SUB_TIME (DEST, SRC1, SRC2) subtracts SRC2 from SRC1 and
-	stores the result in DEST.  SRC should not be negative.
-   EMACS_TIME_NEG_P (TIME) is true if TIME is negative.
-
-*/
-
-#ifdef HAVE_TIMEVAL
-
-#define EMACS_HAS_USECS
-
-#define EMACS_TIME struct timeval
+   EMACS_NSECS (TIME) is an rvalue for the nanoseconds component of TIME.
+   EMACS_SET_NSECS (TIME, NANOSECONDS) sets that to NANOSECONDS.
+
+   EMACS_SET_SECS_NSECS (TIME, SECS, NSECS) sets both components of TIME.  */
 #define EMACS_SECS(time)		    ((time).tv_sec  + 0)
-#define EMACS_USECS(time)		    ((time).tv_usec + 0)
+#define EMACS_NSECS(time)		    ((time).tv_nsec + 0)
+#define EMACS_SECS_ADDR(time)		    (&(time).tv_sec)
 #define EMACS_SET_SECS(time, seconds)	    ((time).tv_sec  = (seconds))
-#define EMACS_SET_USECS(time, microseconds) ((time).tv_usec = (microseconds))
-
-/* On SVR4, the compiler may complain if given this extra BSD arg.  */
-#ifdef GETTIMEOFDAY_ONE_ARGUMENT
-#define EMACS_GET_TIME(time) gettimeofday (&(time))
-#else /* not GETTIMEOFDAY_ONE_ARGUMENT */
-/* Presumably the second arg is ignored.  */
-#define EMACS_GET_TIME(time) gettimeofday (&(time), NULL)
-#endif /* not GETTIMEOFDAY_ONE_ARGUMENT */
-
-#define EMACS_ADD_TIME(dest, src1, src2)		\
-  do {							\
-    (dest).tv_sec  = (src1).tv_sec  + (src2).tv_sec;	\
-    (dest).tv_usec = (src1).tv_usec + (src2).tv_usec;	\
-    if ((dest).tv_usec > 1000000)			\
-      (dest).tv_usec -= 1000000, (dest).tv_sec++;	\
-  } while (0)
-
-#define EMACS_SUB_TIME(dest, src1, src2)		\
-  do {							\
-    (dest).tv_sec  = (src1).tv_sec  - (src2).tv_sec;	\
-    (dest).tv_usec = (src1).tv_usec - (src2).tv_usec;	\
-    if ((dest).tv_usec < 0)				\
-      (dest).tv_usec += 1000000, (dest).tv_sec--;	\
-  } while (0)
-
-#define EMACS_TIME_NEG_P(time)					\
-  ((long)(time).tv_sec < 0					\
-   || ((time).tv_sec == 0					\
-       && (long)(time).tv_usec < 0))
-
-#else /* ! defined (HAVE_TIMEVAL) */
-
-#define EMACS_TIME int
-#define EMACS_SECS(time)		    (time)
-#define EMACS_USECS(time)		    0
-#define EMACS_SET_SECS(time, seconds)	    ((time) = (seconds))
-#define EMACS_SET_USECS(time, usecs)	    0
-
-#define EMACS_GET_TIME(t) ((t) = time ((long *) 0))
-#define EMACS_ADD_TIME(dest, src1, src2) ((dest) = (src1) + (src2))
-#define EMACS_SUB_TIME(dest, src1, src2) ((dest) = (src1) - (src2))
-#define EMACS_TIME_NEG_P(t) ((t) < 0)
-
-#endif /* ! defined (HAVE_TIMEVAL) */
-
+#define EMACS_SET_NSECS(time, ns)	    ((time).tv_nsec = (ns))
+#define EMACS_SET_SECS_NSECS(time, s, ns)				\
+  ((void) (EMACS_SET_SECS (time, s), EMACS_SET_NSECS (time, ns)))
+
+/* Convenience macros for older code that counts microseconds.  */
+#define EMACS_SET_USECS(time, us)  ((void) EMACS_SET_NSECS (time, (us) * 1000))
 #define EMACS_SET_SECS_USECS(time, secs, usecs) 		\
   (EMACS_SET_SECS (time, secs), EMACS_SET_USECS (time, usecs))

-extern int set_file_times (const char *, EMACS_TIME, EMACS_TIME);
+/* Set TIME to an invalid time stamp.  */
+#define EMACS_SET_INVALID_TIME(time)	    EMACS_SET_SECS_NSECS(time, 0, -1)
+
+/* Set TIME to the current system time.  */
+#define EMACS_GET_TIME(time)		    gettime (&(time))
+
+/* Put into DEST the result of adding SRC1 to SRC2, or of subtracting
+   SRC2 from SRC1.  On overflow, store an extremal value.  */
+#define EMACS_ADD_TIME(dest, src1, src2) ((dest) = timespec_add (src1, src2))
+#define EMACS_SUB_TIME(dest, src1, src2) ((dest) = timespec_sub (src1, src2))
+
+/* Return the sign of the valid time stamp TIME, either -1, 0, or 1.  */
+#define EMACS_TIME_SIGN(time)		timespec_sign (time)
+
+/* Return 1 if TIME is a valid time stamp.  */
+#define EMACS_TIME_VALID_P(time)	(0 <= (time).tv_nsec)
+
+/* Convert the double D to the greatest EMACS_TIME not greater than D.
+   On overflow, return an extremal value.  Return the minimum
+   EMACS_TIME if D is not a number.  */
+#define EMACS_TIME_FROM_DOUBLE(d)	dtotimespec (d)
+
+/* Convert the Emacs time T to an approximate double value D.  */
+#define EMACS_TIME_TO_DOUBLE(t)		timespectod (t)
+
+/* defined in sysdep.c */
+extern int set_file_times (int, const char *, EMACS_TIME, EMACS_TIME);
+extern struct timeval make_timeval (EMACS_TIME);

 /* defined in keyboard.c */
 extern void set_waiting_for_input (EMACS_TIME *);
@@ -152,29 +116,20 @@
    happen when this files is used outside the src directory).
    Use GCPRO1 to determine if lisp.h was included.  */
 #ifdef GCPRO1
-/* defined in editfns.c*/
-extern Lisp_Object make_time (time_t);
-extern int lisp_time_argument (Lisp_Object, time_t *, int *);
+/* defined in editfns.c */
+extern Lisp_Object make_lisp_time (EMACS_TIME);
+extern int decode_time_components (Lisp_Object, Lisp_Object, Lisp_Object, int,
+				   EMACS_TIME *);
+extern EMACS_TIME lisp_time_argument (Lisp_Object, int);
 #endif

-/* Compare times T1 and T2.  Value is 0 if T1 and T2 are the same.
-   Value is < 0 if T1 is less than T2.  Value is > 0 otherwise.  (Cast
-   to long is for those platforms where time_t is an unsigned
-   type, and where otherwise T1 will always be grater than T2.)  */
-
-#define EMACS_TIME_CMP(T1, T2)				\
-  ((long)EMACS_SECS (T1) - (long)EMACS_SECS (T2)	\
-   + (EMACS_SECS (T1) == EMACS_SECS (T2)		\
-      ? EMACS_USECS (T1) - EMACS_USECS (T2)		\
-      : 0))
-
 /* Compare times T1 and T2 for equality, inequality etc.  */

-#define EMACS_TIME_EQ(T1, T2) (EMACS_TIME_CMP (T1, T2) == 0)
-#define EMACS_TIME_NE(T1, T2) (EMACS_TIME_CMP (T1, T2) != 0)
-#define EMACS_TIME_GT(T1, T2) (EMACS_TIME_CMP (T1, T2) > 0)
-#define EMACS_TIME_GE(T1, T2) (EMACS_TIME_CMP (T1, T2) >= 0)
-#define EMACS_TIME_LT(T1, T2) (EMACS_TIME_CMP (T1, T2) < 0)
-#define EMACS_TIME_LE(T1, T2) (EMACS_TIME_CMP (T1, T2) <= 0)
+#define EMACS_TIME_EQ(T1, T2) (timespec_cmp (T1, T2) == 0)
+#define EMACS_TIME_NE(T1, T2) (timespec_cmp (T1, T2) != 0)
+#define EMACS_TIME_GT(T1, T2) (timespec_cmp (T1, T2) > 0)
+#define EMACS_TIME_GE(T1, T2) (timespec_cmp (T1, T2) >= 0)
+#define EMACS_TIME_LT(T1, T2) (timespec_cmp (T1, T2) < 0)
+#define EMACS_TIME_LE(T1, T2) (timespec_cmp (T1, T2) <= 0)

 #endif /* EMACS_SYSTIME_H */

=== modified file 'src/term.c'
--- src/term.c	2011-05-18 00:39:40 +0000
+++ src/term.c	2011-07-01 05:24:23 +0000
@@ -24,6 +24,7 @@
 #include <ctype.h>
 #include <errno.h>
 #include <sys/file.h>
+#include <sys/time.h>
 #include <unistd.h>
 #include <signal.h>
 #include <setjmp.h>
@@ -2683,6 +2684,18 @@
   return 0;
 }

+/* Return the Time that corresponds to T.  Wrap around on overflow.  */
+static Time
+timeval_to_Time (struct timeval const *t)
+{
+  Time s_1000, ms;
+
+  s_1000 = t->tv_sec;
+  s_1000 *= 1000;
+  ms = t->tv_usec / 1000;
+  return s_1000 + ms;
+}
+
 /* Return the current position of the mouse.

    Set *f to the frame the mouse is in, or zero if the mouse is in no
@@ -2702,7 +2715,6 @@
 		     Lisp_Object *y, Time *timeptr)
 {
   struct timeval now;
-  Time sec, usec;

   *fp = SELECTED_FRAME ();
   (*fp)->mouse_moved = 0;
@@ -2713,9 +2725,7 @@
   XSETINT (*x, last_mouse_x);
   XSETINT (*y, last_mouse_y);
   gettimeofday(&now, 0);
-  sec = now.tv_sec;
-  usec = now.tv_usec;
-  *timeptr = (sec * 1000) + (usec / 1000);
+  *timeptr = timeval_to_Time (&now);
 }

 /* Prepare a mouse-event in *RESULT for placement in the input queue.
@@ -2739,7 +2749,7 @@
       }
     }
   gettimeofday(&now, 0);
-  result->timestamp = (now.tv_sec * 1000) + (now.tv_usec / 1000);
+  result->timestamp = timeval_to_Time (&now);

   if (event->type & GPM_UP)
     result->modifiers = up_modifier;

=== modified file 'src/undo.c'
--- src/undo.c	2011-06-24 21:25:22 +0000
+++ src/undo.c	2011-07-01 05:24:23 +0000
@@ -225,7 +225,7 @@
     base_buffer = base_buffer->base_buffer;

   BVAR (current_buffer, undo_list) =
-    Fcons (Fcons (Qt, INTEGER_TO_CONS (base_buffer->modtime)),
+    Fcons (Fcons (Qt, make_lisp_time (base_buffer->modtime)),
 	   BVAR (current_buffer, undo_list));
 }

@@ -497,10 +497,10 @@
 	      cdr = XCDR (next);
 	      if (EQ (car, Qt))
 		{
-		  /* Element (t high . low) records previous modtime.  */
+		  /* Element (t . TIME) records previous modtime.  */
 		  struct buffer *base_buffer = current_buffer;
-		  time_t mod_time;
-		  CONS_TO_INTEGER (cdr, time_t, mod_time);
+		  EMACS_TIME mod_time =
+		    lisp_time_argument (cdr, UNKNOWN_MODTIME_NSECS);

 		  if (current_buffer->base_buffer)
 		    base_buffer = current_buffer->base_buffer;
@@ -508,7 +508,7 @@
 		  /* If this records an obsolete save
 		     (not matching the actual disk file)
 		     then don't mark unmodified.  */
-		  if (mod_time != base_buffer->modtime)
+		  if (EMACS_TIME_NE (mod_time, base_buffer->modtime))
 		    continue;
 #ifdef CLASH_DETECTION
 		  Funlock_buffer ();

=== modified file 'src/w32.c'
--- src/w32.c	2011-06-24 21:25:22 +0000
+++ src/w32.c	2011-07-01 05:24:23 +0000
@@ -4005,14 +4005,14 @@
 }

 static Lisp_Object
-ltime (long time_sec, long time_usec)
+ltime (long time_sec, long time_100nsec)
 {
   return list3 (make_number ((time_sec >> 16) & 0xffff),
 		make_number (time_sec & 0xffff),
-		make_number (time_usec));
+		make_number (time_100nsec * 100));
 }

-#define U64_TO_LISP_TIME(time) ltime ((time) / 1000000L, (time) % 1000000L)
+#define U64_TO_LISP_TIME(time) ltime ((time) / 10000000L, (time) % 10000000L)

 static int
 process_times (HANDLE h_proc, Lisp_Object *ctime, Lisp_Object *etime,
@@ -4031,11 +4031,9 @@
   GetSystemTimeAsFileTime (&ft_current);

   FILETIME_TO_U64 (tem1, ft_kernel);
-  tem1 /= 10L;
   *stime = U64_TO_LISP_TIME (tem1);

   FILETIME_TO_U64 (tem2, ft_user);
-  tem2 /= 10L;
   *utime = U64_TO_LISP_TIME (tem2);

   tem3 = tem1 + tem2;
@@ -4044,13 +4042,13 @@
   FILETIME_TO_U64 (tem, ft_creation);
   /* Process no 4 (System) returns zero creation time.  */
   if (tem)
-    tem = (tem - utc_base) / 10L;
+    tem -= utc_base;
   *ctime = U64_TO_LISP_TIME (tem);

   if (tem)
     {
       FILETIME_TO_U64 (tem3, ft_current);
-      tem = (tem3 - utc_base) / 10L - tem;
+      tem = (tem3 - utc_base) - tem;
     }
   *etime = U64_TO_LISP_TIME (tem);

@@ -6198,7 +6196,7 @@
 {
   int n, sc, err;
   SELECT_TYPE fdset;
-  EMACS_TIME timeout;
+  struct timeval timeout;
   struct Lisp_Process *process = (struct Lisp_Process *)p;
   int fd = process->infd;

@@ -6214,7 +6212,8 @@
       if (err == EWOULDBLOCK)
         {
           /* Set a small timeout.  */
-          EMACS_SET_SECS_USECS(timeout, 1, 0);
+	  timeout.tv_sec = 1;
+	  timeout.tv_usec = 0;
           FD_ZERO (&fdset);
           FD_SET ((int)fd, &fdset);


=== modified file 'src/xdisp.c'
--- src/xdisp.c	2011-06-24 21:25:22 +0000
+++ src/xdisp.c	2011-07-01 05:24:23 +0000
@@ -27098,25 +27098,20 @@
 {
 #if defined (HAVE_WINDOW_SYSTEM)
   EMACS_TIME delay;
-  int secs, usecs = 0;

   cancel_hourglass ();

   if (INTEGERP (Vhourglass_delay)
       && XINT (Vhourglass_delay) > 0)
-    secs = XFASTINT (Vhourglass_delay);
+    EMACS_SET_SECS_NSECS (delay,
+			  min (XINT (Vhourglass_delay), TYPE_MAXIMUM (time_t)),
+			  0);
   else if (FLOATP (Vhourglass_delay)
 	   && XFLOAT_DATA (Vhourglass_delay) > 0)
-    {
-      Lisp_Object tem;
-      tem = Ftruncate (Vhourglass_delay, Qnil);
-      secs = XFASTINT (tem);
-      usecs = (XFLOAT_DATA (Vhourglass_delay) - secs) * 1000000;
-    }
+    delay = EMACS_TIME_FROM_DOUBLE (XFLOAT_DATA (Vhourglass_delay));
   else
-    secs = DEFAULT_HOURGLASS_DELAY;
+    EMACS_SET_SECS_NSECS (delay, DEFAULT_HOURGLASS_DELAY, 0);

-  EMACS_SET_SECS_USECS (delay, secs, usecs);
   hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay,
 				   show_hourglass, NULL);
 #endif

=== modified file 'src/xgselect.c'
--- src/xgselect.c	2011-04-16 07:57:31 +0000
+++ src/xgselect.c	2011-07-01 05:24:23 +0000
@@ -33,14 +33,14 @@

 int
 xg_select (int max_fds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds,
-	   EMACS_TIME *timeout)
+	   EMACS_TIME *timeout, sigset_t *sigmask)
 {
   SELECT_TYPE all_rfds, all_wfds;
   EMACS_TIME tmo, *tmop = timeout;

   GMainContext *context = g_main_context_default ();
   int have_wfds = wfds != NULL;
-  int n_gfds = 0, our_tmo = 0, retval = 0, our_fds = 0;
+  int n_gfds = 0, retval = 0, our_fds = 0;
   int i, nfds, tmo_in_millisec;

   if (rfds) memcpy (&all_rfds, rfds, sizeof (all_rfds));
@@ -86,20 +86,12 @@
     {
       EMACS_SET_SECS_USECS (tmo, tmo_in_millisec/1000,
                             1000 * (tmo_in_millisec % 1000));
-      if (!timeout) our_tmo = 1;
-      else
-        {
-          EMACS_TIME difference;
-
-          EMACS_SUB_TIME (difference, tmo, *timeout);
-          if (EMACS_TIME_NEG_P (difference)) our_tmo = 1;
-        }
-
-      if (our_tmo) tmop = &tmo;
+      if (!timeout || EMACS_TIME_LT (tmo, *timeout))
+	tmop = &tmo;
     }

-  nfds = select (max_fds+1, &all_rfds, have_wfds ? &all_wfds : NULL,
-                 efds, tmop);
+  nfds = pselect (max_fds+1, &all_rfds, have_wfds ? &all_wfds : NULL,
+		  efds, tmop, sigmask);

   if (nfds < 0)
     retval = nfds;
@@ -128,7 +120,7 @@
         }
     }

-  if (our_fds > 0 || (nfds == 0 && our_tmo))
+  if (our_fds > 0 || (nfds == 0 && tmop == &tmo))
     {

       /* If Gtk+ is in use eventually gtk_main_iteration will be called,

=== modified file 'src/xgselect.h'
--- src/xgselect.h	2011-01-26 08:36:39 +0000
+++ src/xgselect.h	2011-07-01 05:24:23 +0000
@@ -28,9 +28,9 @@
                       SELECT_TYPE *rfds,
                       SELECT_TYPE *wfds,
                       SELECT_TYPE *efds,
-                      EMACS_TIME *timeout);
+                      EMACS_TIME *timeout,
+		      sigset_t *sigmask);

 extern void xgselect_initialize (void);

 #endif /* XGSELECT_H */
-

=== modified file 'src/xmenu.c'
--- src/xmenu.c	2011-06-24 21:25:22 +0000
+++ src/xmenu.c	2011-07-01 05:24:23 +0000
@@ -388,8 +388,6 @@
          )
     {
       EMACS_TIME next_time = timer_check (), *ntp;
-      long secs = EMACS_SECS (next_time);
-      long usecs = EMACS_USECS (next_time);
       SELECT_TYPE read_fds;
       struct x_display_info *dpyinfo;
       int n = 0;
@@ -403,12 +401,12 @@
           XFlush (dpyinfo->display);
         }

-      if (secs < 0 && usecs < 0)
+      if (! EMACS_TIME_VALID_P (next_time))
         ntp = 0;
       else
         ntp = &next_time;

-      select (n + 1, &read_fds, (SELECT_TYPE *)0, (SELECT_TYPE *)0, ntp);
+      pselect (n + 1, &read_fds, NULL, NULL, ntp, NULL);
     }
 }
 #endif /* ! MSDOS */

=== modified file 'src/xselect.c'
--- src/xselect.c	2011-06-21 02:16:54 +0000
+++ src/xselect.c	2011-07-01 05:24:23 +0000
@@ -1118,7 +1118,6 @@
 static void
 wait_for_property_change (struct prop_location *location)
 {
-  int secs, usecs;
   int count = SPECPDL_INDEX ();

   if (property_change_reply_object)
@@ -1135,10 +1134,11 @@
      property_change_reply, because property_change_reply_object says so.  */
   if (! location->arrived)
     {
-      secs = x_selection_timeout / 1000;
-      usecs = (x_selection_timeout % 1000) * 1000;
-      TRACE2 ("  Waiting %d secs, %d usecs", secs, usecs);
-      wait_reading_process_output (secs, usecs, 0, 0,
+      EMACS_INT timeout = max (0, x_selection_timeout);
+      EMACS_INT secs = timeout / 1000;
+      int nsecs = (timeout % 1000) * 1000000;
+      TRACE2 ("  Waiting %"pI"d secs, %d nsecs", secs, nsecs);
+      wait_reading_process_output (secs, nsecs, 0, 0,
 				   property_change_reply, NULL, 0);

       if (NILP (XCAR (property_change_reply)))
@@ -1207,7 +1207,8 @@
   Atom type_atom = (CONSP (target_type)
 		    ? symbol_to_x_atom (dpyinfo, XCAR (target_type))
 		    : symbol_to_x_atom (dpyinfo, target_type));
-  int secs, usecs;
+  EMACS_INT timeout, secs;
+  int nsecs;

   if (!FRAME_LIVE_P (f))
     return Qnil;
@@ -1243,10 +1244,11 @@
   UNBLOCK_INPUT;

   /* This allows quits.  Also, don't wait forever.  */
-  secs = x_selection_timeout / 1000;
-  usecs = (x_selection_timeout % 1000) * 1000;
-  TRACE1 ("  Start waiting %d secs for SelectionNotify", secs);
-  wait_reading_process_output (secs, usecs, 0, 0,
+  timeout = max (0, x_selection_timeout);
+  secs = timeout / 1000;
+  nsecs = (timeout % 1000) * 1000000;
+  TRACE1 ("  Start waiting %"pI"d secs for SelectionNotify", secs);
+  wait_reading_process_output (secs, nsecs, 0, 0,
 			       reading_selection_reply, NULL, 0);
   TRACE1 ("  Got event = %d", !NILP (XCAR (reading_selection_reply)));


=== modified file 'src/xterm.c'
--- src/xterm.c	2011-06-24 21:25:22 +0000
+++ src/xterm.c	2011-07-01 05:24:23 +0000
@@ -85,10 +85,6 @@
 #include <X11/Shell.h>
 #endif

-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif
-
 #include <unistd.h>

 #ifdef USE_GTK
@@ -2949,44 +2945,6 @@
 \f
 /* Invert the middle quarter of the frame for .15 sec.  */

-/* We use the select system call to do the waiting, so we have to make
-   sure it's available.  If it isn't, we just won't do visual bells.  */
-
-#if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
-
-
-/* Subtract the `struct timeval' values X and Y, storing the result in
-   *RESULT.  Return 1 if the difference is negative, otherwise 0.  */
-
-static int
-timeval_subtract (struct timeval *result, struct timeval x, struct timeval y)
-{
-  /* Perform the carry for the later subtraction by updating y.  This
-     is safer because on some systems the tv_sec member is unsigned.  */
-  if (x.tv_usec < y.tv_usec)
-    {
-      int nsec = (y.tv_usec - x.tv_usec) / 1000000 + 1;
-      y.tv_usec -= 1000000 * nsec;
-      y.tv_sec += nsec;
-    }
-
-  if (x.tv_usec - y.tv_usec > 1000000)
-    {
-      int nsec = (y.tv_usec - x.tv_usec) / 1000000;
-      y.tv_usec += 1000000 * nsec;
-      y.tv_sec -= nsec;
-    }
-
-  /* Compute the time remaining to wait.  tv_usec is certainly
-     positive.  */
-  result->tv_sec = x.tv_sec - y.tv_sec;
-  result->tv_usec = x.tv_usec - y.tv_usec;
-
-  /* Return indication of whether the result should be considered
-     negative.  */
-  return x.tv_sec < y.tv_sec;
-}
-
 static void
 XTflash (struct frame *f)
 {
@@ -3087,34 +3045,29 @@
       x_flush (f);

       {
-	struct timeval wakeup;
+	EMACS_TIME wakeup, delay;

 	EMACS_GET_TIME (wakeup);
-
-	/* Compute time to wait until, propagating carry from usecs.  */
-	wakeup.tv_usec += 150000;
-	wakeup.tv_sec += (wakeup.tv_usec / 1000000);
-	wakeup.tv_usec %= 1000000;
+	EMACS_SET_SECS_NSECS (delay, 0, 150 * 1000 * 1000);
+	EMACS_ADD_TIME (wakeup, wakeup, delay);

 	/* Keep waiting until past the time wakeup or any input gets
 	   available.  */
 	while (! detect_input_pending ())
 	  {
-	    struct timeval current;
-	    struct timeval timeout;
+	    EMACS_TIME current, timeout;

 	    EMACS_GET_TIME (current);

-	    /* Break if result would be negative.  */
-	    if (timeval_subtract (&current, wakeup, current))
+	    /* Break if result would not be positive.  */
+	    if (EMACS_TIME_LE (wakeup, current))
 	      break;

 	    /* How long `select' should wait.  */
-	    timeout.tv_sec = 0;
-	    timeout.tv_usec = 10000;
+	    EMACS_SET_SECS_NSECS (timeout, 0, 10 * 1000 * 1000);

 	    /* Try to wait that long--but we might wake up sooner.  */
-	    select (0, NULL, NULL, NULL, &timeout);
+	    pselect (0, NULL, NULL, NULL, &timeout, NULL);
 	  }
       }

@@ -3155,8 +3108,6 @@
   UNBLOCK_INPUT;
 }

-#endif /* defined (HAVE_TIMEVAL) && defined (HAVE_SELECT) */
-

 static void
 XTtoggle_invisible_pointer (FRAME_PTR f, int invisible)
@@ -3183,11 +3134,9 @@
 {
   if (FRAME_X_DISPLAY (f))
     {
-#if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
       if (visible_bell)
 	XTflash (f);
       else
-#endif
 	{
 	  BLOCK_INPUT;
 	  XBell (FRAME_X_DISPLAY (f), 0);
@@ -8713,9 +8662,11 @@
       FD_SET (fd, &fds);

       EMACS_GET_TIME (time_now);
+      if (EMACS_TIME_LT (tmo_at, time_now))
+	break;
+
       EMACS_SUB_TIME (tmo, tmo_at, time_now);
-
-      if (EMACS_TIME_NEG_P (tmo) || select (fd+1, &fds, NULL, NULL, &tmo) == 0)
+      if (pselect (fd + 1, &fds, NULL, NULL, &tmo, NULL) == 0)
         break; /* Timeout */
     }
   pending_event_wait.f = 0;





^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH 6/7] lib-src support for ns-resolution time stamps
  2011-07-01  6:59 nanosecond-resolution time stamps Paul Eggert
                   ` (4 preceding siblings ...)
  2011-07-01  8:15 ` [PATCH 5/7] C-level " Paul Eggert
@ 2011-07-01  8:16 ` Paul Eggert
  2011-07-01  8:16 ` [PATCH 7/7] Lisp-level " Paul Eggert
  2011-07-01 15:55 ` nanosecond-resolution " Stefan Monnier
  7 siblings, 0 replies; 18+ messages in thread
From: Paul Eggert @ 2011-07-01  8:16 UTC (permalink / raw)
  To: Emacs Development

This much-smaller patch is more C-level support, in the lib-src directory.
It's needed, so that lib-src can compile with the new src directory.

Add support for nanosecond-resolution time stamps.
* Makefile.in (LIB_CLOCK_GETTIME): New macro.
(profile${EXEEXT}): Use it.
* profile.c: Include inttyeps.h, intprops.h.
(time_string): Size conservatively; do not guess size.
(get_time): Now prints nanoseconds.
(gettimeofday): Remove replacement function; gnulib now does this.
=== modified file 'lib-src/Makefile.in'
--- lib-src/Makefile.in	2011-05-25 07:13:57 +0000
+++ lib-src/Makefile.in	2011-07-01 05:24:03 +0000
@@ -156,6 +156,8 @@
 LIBRESOLV=@LIBRESOLV@
 ## -llockfile if HAVE_LIBLOCKFILE or -lmail if HAVE_LIBMAIL
 LIBS_MAIL=@LIBS_MAIL@
+## empty or -lrt or -lposix4 if HAVE_CLOCK_GETTIME
+LIB_CLOCK_GETTIME = @LIB_CLOCK_GETTIME@

 ## Extra libraries to use when linking movemail.
 LIBS_MOVE = $(LIBS_MAIL) $(KRB4LIB) $(DESLIB) $(KRB5LIB) $(CRYPTOLIB) \
@@ -328,7 +330,8 @@
 	  regex.o $(LOADLIBES) -o ctags

 profile${EXEEXT}: ${srcdir}/profile.c ../src/config.h
-	$(CC) ${ALL_CFLAGS} ${srcdir}/profile.c $(LOADLIBES) -o profile
+	$(CC) ${ALL_CFLAGS} ${srcdir}/profile.c \
+	  $(LOADLIBES) $(LIB_CLOCK_GETTIME) -o profile

 make-docfile${EXEEXT}: ${srcdir}/make-docfile.c ../src/config.h
 	$(CC) ${ALL_CFLAGS} ${srcdir}/make-docfile.c $(LOADLIBES) \

=== modified file 'lib-src/profile.c'
--- lib-src/profile.c	2011-02-21 18:06:25 +0000
+++ lib-src/profile.c	2011-07-01 05:24:03 +0000
@@ -29,12 +29,17 @@
  **  operations: reset_watch, get_time
  */
 #include <config.h>
+
+#include <inttypes.h>
 #include <stdio.h>
+
+#include <intprops.h>
 #include <systime.h>

 static EMACS_TIME TV1, TV2;
 static int watch_not_started = 1; /* flag */
-static char time_string[30];
+static char time_string[INT_STRLEN_BOUND (uintmax_t) + sizeof "."
+			+ LOG10_EMACS_TIME_RESOLUTION];

 /* Reset the stopwatch to zero.  */

@@ -46,36 +51,23 @@
 }

 /* This call returns the time since the last reset_watch call.  The time
-   is returned as a string with the format  <seconds>.<micro-seconds>
+   is returned as a string with the format  <seconds>.<nanoseconds>
    If reset_watch was not called yet, exit.  */

 static char *
 get_time (void)
 {
+  uintmax_t s;
+  int ns;
   if (watch_not_started)
     exit (EXIT_FAILURE);  /* call reset_watch first ! */
   EMACS_GET_TIME (TV2);
   EMACS_SUB_TIME (TV2, TV2, TV1);
-  sprintf (time_string, "%lu.%06lu", (unsigned long)EMACS_SECS (TV2), (unsigned long)EMACS_USECS (TV2));
+  s = EMACS_SECS (TV2);
+  ns = EMACS_NSECS (TV2);
+  sprintf (time_string, "%"PRIuMAX".%0*d", s, LOG10_EMACS_TIME_RESOLUTION, ns);
   return time_string;
 }
-
-#if ! defined (HAVE_GETTIMEOFDAY) && defined (HAVE_TIMEVAL)
-
-/* ARGSUSED */
-gettimeofday (tp, tzp)
-     struct timeval *tp;
-     struct timezone *tzp;
-{
-  extern long time ();
-
-  tp->tv_sec = time ((long *)0);
-  tp->tv_usec = 0;
-  if (tzp != 0)
-    tzp->tz_minuteswest = -1;
-}
-
-#endif
 \f
 int
 main (void)




^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH 7/7] Lisp-level support for ns-resolution time stamps
  2011-07-01  6:59 nanosecond-resolution time stamps Paul Eggert
                   ` (5 preceding siblings ...)
  2011-07-01  8:16 ` [PATCH 6/7] lib-src " Paul Eggert
@ 2011-07-01  8:16 ` Paul Eggert
  2011-07-01 15:55 ` nanosecond-resolution " Stefan Monnier
  7 siblings, 0 replies; 18+ messages in thread
From: Paul Eggert @ 2011-07-01  8:16 UTC (permalink / raw)
  To: Emacs Development

[lisp/ChangeLog]
Switch to ns-resolution time stamps.

* calendar/time-date.el (make-fixnum-or-float): New function.
(seconds-to-time): Use it.  Don't assume 1st and 3rd components
are in fixnum range.
(seconds-to-time, time-subtract, time-add):
Switch to ns-resolution time stamps.

* emacs-lisp/timer.el (timer): Use nsecs, not usecs.
All uses changed.
(timer-next-integral-multiple-of-time): Time stamps now have
nanosecond resolution, not microsecond.
* emacs-lisp/timer.el (timer--activate):
* type-break.el (timep): The 1st and 3rd parts might be floats now.

* net/sasl.el (sasl-unique-id-function): Fix comment.
[lisp/gnus/ChangeLog]
* message.el (message-unique-id): Fix comment.
[lisp/org/ChangeLog]
* org-id.el (org-id-time-to-b36): Time stamps have ns-resolution now.
=== modified file 'lisp/calendar/time-date.el'
--- lisp/calendar/time-date.el	2011-04-19 04:11:01 +0000
+++ lisp/calendar/time-date.el	2011-07-01 07:43:11 +0000
@@ -26,9 +26,9 @@
 ;; Time values come in three formats.  The oldest format is a cons
 ;; cell of the form (HIGH . LOW).  This format is obsolete, but still
 ;; supported.  The two other formats are the lists (HIGH LOW) and
-;; (HIGH LOW MICRO).  The first two formats specify HIGH * 2^16 + LOW
-;; seconds; the third format specifies HIGH * 2^16 + LOW + MICRO /
-;; 1000000 seconds.  We should have 0 <= MICRO < 1000000 and 0 <= LOW
+;; (HIGH LOW NANO).  The first two formats specify HIGH * 2^16 + LOW
+;; seconds; the third format specifies HIGH * 2^16 + LOW + NANO /
+;; 1000000000 seconds.  We should have 0 <= NANO < 1000000000 and 0 <= LOW
 ;; < 2^16.  If the time value represents a point in time, then HIGH is
 ;; nonnegative.  If the time value is a time difference, then HIGH can
 ;; be negative as well.  The macro `with-decoded-time-value' and the
@@ -44,13 +44,13 @@
 The value of the last form in BODY is returned.

 Each element of the list VARLIST is a list of the form
-\(HIGH-SYMBOL LOW-SYMBOL MICRO-SYMBOL [TYPE-SYMBOL] TIME-VALUE).
+\(HIGH-SYMBOL LOW-SYMBOL NANO-SYMBOL [TYPE-SYMBOL] TIME-VALUE).
 The time value TIME-VALUE is decoded and the result it bound to
-the symbols HIGH-SYMBOL, LOW-SYMBOL and MICRO-SYMBOL.
+the symbols HIGH-SYMBOL, LOW-SYMBOL and NANO-SYMBOL.

 The optional TYPE-SYMBOL is bound to the type of the time value.
 Type 0 is the cons cell (HIGH . LOW), type 1 is the list (HIGH
-LOW), and type 2 is the list (HIGH LOW MICRO)."
+LOW), and type 2 is the list (HIGH LOW NANO)."
   (declare (indent 1)
 	   (debug ((&rest (symbolp symbolp symbolp &or [symbolp form] form))
 		   body)))
@@ -58,36 +58,36 @@
       (let* ((elt (pop varlist))
 	     (high (pop elt))
 	     (low (pop elt))
-	     (micro (pop elt))
+	     (nano (pop elt))
 	     (type (unless (eq (length elt) 1)
 		     (pop elt)))
 	     (time-value (car elt))
 	     (gensym (make-symbol "time")))
 	`(let* ,(append `((,gensym ,time-value)
 			  (,high (pop ,gensym))
-			  ,low ,micro)
+			  ,low ,nano)
 			(when type `(,type)))
 	   (if (consp ,gensym)
 	       (progn
 		 (setq ,low (pop ,gensym))
 		 (if ,gensym
-		     ,(append `(setq ,micro (car ,gensym))
+		     ,(append `(setq ,nano (car ,gensym))
 			      (when type `(,type 2)))
-		   ,(append `(setq ,micro 0)
+		   ,(append `(setq ,nano 0)
 			    (when type `(,type 1)))))
-	     ,(append `(setq ,low ,gensym ,micro 0)
+	     ,(append `(setq ,low ,gensym ,nano 0)
 		      (when type `(,type 0))))
 	   (with-decoded-time-value ,varlist ,@body)))
     `(progn ,@body)))

-(defun encode-time-value (high low micro type)
-  "Encode HIGH, LOW, and MICRO into a time value of type TYPE.
+(defun encode-time-value (high low nano type)
+  "Encode HIGH, LOW, and NANO into a time value of type TYPE.
 Type 0 is the cons cell (HIGH . LOW), type 1 is the list (HIGH LOW),
-and type 2 is the list (HIGH LOW MICRO)."
+and type 2 is the list (HIGH LOW NANO)."
   (cond
    ((eq type 0) (cons high low))
    ((eq type 1) (list high low))
-   ((eq type 2) (list high low micro))))
+   ((eq type 2) (list high low nano))))

 (autoload 'parse-time-string "parse-time")
 (autoload 'timezone-make-date-arpa-standard "timezone")
@@ -128,25 +128,33 @@
         (with-decoded-time-value ((high low micro time))
           (+ (* 1.0 high 65536)
              low
+	     ;; Divide by 1 million not 1 billion, since this is executed
+	     ;; only on older Emacs, for which 1 million is correct.
              (/ micro 1000000.0))))))

+(defun make-fixnum-or-float (val)
+  (if (and (<= most-negative-fixnum val) (<= val most-positive-fixnum))
+      (floor val)
+    val))
+
 ;;;###autoload
 (defun seconds-to-time (seconds)
   "Convert SECONDS (a floating point number) to a time value."
-  (list (floor seconds 65536)
+  (list (make-fixnum-or-float (ffloor (/ seconds 65536)))
 	(floor (mod seconds 65536))
-	(floor (* (- seconds (ffloor seconds)) 1000000))))
+	(make-fixnum-or-float (ffloor (* (- seconds (ffloor seconds))
+					 1000000000)))))

 ;;;###autoload
 (defun time-less-p (t1 t2)
   "Return non-nil if time value T1 is earlier than time value T2."
-  (with-decoded-time-value ((high1 low1 micro1 t1)
-			    (high2 low2 micro2 t2))
+  (with-decoded-time-value ((high1 low1 nano1 t1)
+			    (high2 low2 nano2 t2))
     (or (< high1 high2)
 	(and (= high1 high2)
 	     (or (< low1 low2)
 		 (and (= low1 low2)
-		      (< micro1 micro2)))))))
+		      (< nano1 nano2)))))))

 ;;;###autoload
 (defun days-to-time (days)
@@ -173,36 +181,36 @@
 (defun time-subtract (t1 t2)
   "Subtract two time values, T1 minus T2.
 Return the difference in the format of a time value."
-  (with-decoded-time-value ((high low micro type t1)
-			    (high2 low2 micro2 type2 t2))
+  (with-decoded-time-value ((high low nano type t1)
+			    (high2 low2 nano2 type2 t2))
     (setq high (- high high2)
 	  low (- low low2)
-	  micro (- micro micro2)
+	  nano (- nano nano2)
 	  type (max type type2))
-    (when (< micro 0)
+    (when (< nano 0)
       (setq low (1- low)
-	    micro (+ micro 1000000)))
+	    nano (+ nano 1000000000)))
     (when (< low 0)
       (setq high (1- high)
 	    low (+ low 65536)))
-    (encode-time-value high low micro type)))
+    (encode-time-value high low nano type)))

 ;;;###autoload
 (defun time-add (t1 t2)
   "Add two time values T1 and T2.  One should represent a time difference."
-  (with-decoded-time-value ((high low micro type t1)
-			    (high2 low2 micro2 type2 t2))
+  (with-decoded-time-value ((high low nano type t1)
+			    (high2 low2 nano2 type2 t2))
     (setq high (+ high high2)
 	  low (+ low low2)
-	  micro (+ micro micro2)
+	  nano (+ nano nano2)
 	  type (max type type2))
-    (when (>= micro 1000000)
+    (when (>= nano 1000000000)
       (setq low (1+ low)
-	    micro (- micro 1000000)))
+	    nano (- nano 1000000000)))
     (when (>= low 65536)
       (setq high (1+ high)
 	    low (- low 65536)))
-    (encode-time-value high low micro type)))
+    (encode-time-value high low nano type)))

 ;;;###autoload
 (defun date-to-day (date)

=== modified file 'lisp/emacs-lisp/timer.el'
--- lisp/emacs-lisp/timer.el	2011-07-01 01:27:40 +0000
+++ lisp/emacs-lisp/timer.el	2011-07-01 05:33:16 +0000
@@ -28,7 +28,7 @@
 ;;; Code:

 ;; Layout of a timer vector:
-;; [triggered-p high-seconds low-seconds usecs repeat-delay
+;; [triggered-p high-seconds low-seconds nsecs repeat-delay
 ;;  function args idle-delay]
 ;; triggered-p is nil if the timer is active (waiting to be triggered),
 ;;  t if it is inactive ("already triggered", in theory)
@@ -42,7 +42,7 @@
             (:type vector)
             (:conc-name timer--))
   (triggered t)
-  high-seconds low-seconds usecs repeat-delay function args idle-delay)
+  high-seconds low-seconds nsecs repeat-delay function args idle-delay)

 (defun timerp (object)
   "Return t if OBJECT is a timer."
@@ -52,7 +52,7 @@
 (defun timer--time (timer)
   (list (timer--high-seconds timer)
         (timer--low-seconds timer)
-        (timer--usecs timer)))
+        (timer--nsecs timer)))

 (defsetf timer--time
   (lambda (timer time)
@@ -60,7 +60,7 @@
     (setf (timer--high-seconds timer) (pop time))
     (setf (timer--low-seconds timer)
 	  (if (consp time) (car time) time))
-    (setf (timer--usecs timer) (or (and (consp time) (consp (cdr time))
+    (setf (timer--nsecs timer) (or (and (consp time) (consp (cdr time))
 					(cadr time))
 				   0))))

@@ -77,7 +77,7 @@
 (defun timer-set-idle-time (timer secs &optional repeat)
   "Set the trigger idle time of TIMER to SECS.
 SECS may be an integer, floating point number, or the internal
-time format (HIGH LOW USECS) returned by, e.g., `current-idle-time'.
+time format (HIGH LOW NSECS) returned by, e.g., `current-idle-time'.
 If optional third argument REPEAT is non-nil, make the timer
 fire each time Emacs is idle for that many seconds."
   (if (consp secs)
@@ -94,27 +94,27 @@
   (let ((time-base (ash 1 16)))
     ;; Use floating point, taking care to not lose precision.
     (let* ((float-time-base (float time-base))
-	   (million 1000000.0)
-	   (time-usec (+ (* million
+	   (billion 1e9)
+	   (time-nsec (+ (* billion
 			    (+ (* float-time-base (nth 0 time))
 			       (nth 1 time)))
 			 (nth 2 time)))
-	   (secs-usec (* million secs))
-	   (mod-usec (mod time-usec secs-usec))
-	   (next-usec (+ (- time-usec mod-usec) secs-usec))
-	   (time-base-million (* float-time-base million)))
-      (list (floor next-usec time-base-million)
-	    (floor (mod next-usec time-base-million) million)
-	    (floor (mod next-usec million))))))
+	   (secs-nsec (* billion secs))
+	   (mod-nsec (mod time-nsec secs-nsec))
+	   (next-nsec (+ (- time-nsec mod-nsec) secs-nsec))
+	   (time-base-billion (* float-time-base billion)))
+      (list (floor next-nsec time-base-billion)
+	    (floor (mod next-nsec time-base-billion) billion)
+	    (floor (mod next-nsec billion))))))

-(defun timer-relative-time (time secs &optional usecs)
-  "Advance TIME by SECS seconds and optionally USECS microseconds.
+(defun timer-relative-time (time secs &optional nsecs)
+  "Advance TIME by SECS seconds and optionally NSECS nanoseconds.
 SECS may be either an integer or a floating point number."
   (let ((delta (if (floatp secs)
 		   (seconds-to-time secs)
 		 (list (floor secs 65536) (mod secs 65536)))))
-    (if usecs
-	(setq delta (time-add delta (list 0 0 usecs))))
+    (if nsecs
+	(setq delta (time-add delta (list 0 0 nsecs))))
     (time-add time delta)))

 (defun timer--time-less-p (t1 t2)
@@ -128,20 +128,20 @@
                    (and (= low1 low2)
                         (< micro1 micro2))))))))

-(defun timer-inc-time (timer secs &optional usecs)
-  "Increment the time set in TIMER by SECS seconds and USECS microseconds.
-SECS may be a fraction.  If USECS is omitted, that means it is zero."
+(defun timer-inc-time (timer secs &optional nsecs)
+  "Increment the time set in TIMER by SECS seconds and NSECS nanoseconds.
+SECS may be a fraction.  If NSECS is omitted, that means it is zero."
   (setf (timer--time timer)
-        (timer-relative-time (timer--time timer) secs usecs)))
+        (timer-relative-time (timer--time timer) secs nsecs)))

 (defun timer-set-time-with-usecs (timer time usecs &optional delta)
   "Set the trigger time of TIMER to TIME plus USECS.
 TIME must be in the internal format returned by, e.g., `current-time'.
-The microsecond count from TIME is ignored, and USECS is used instead.
+The nanosecond count from TIME is ignored, and USECS is used instead.
 If optional fourth argument DELTA is a positive number, make the timer
 fire repeatedly that many seconds apart."
   (setf (timer--time timer) time)
-  (setf (timer--usecs timer) usecs)
+  (setf (timer--nsecs timer) (* usecs 1e3))
   (setf (timer--repeat-delay timer) (and (numberp delta) (> delta 0) delta))
   timer)
 (make-obsolete 'timer-set-time-with-usecs
@@ -158,9 +158,9 @@
 \f
 (defun timer--activate (timer &optional triggered-p reuse-cell idle)
   (if (and (timerp timer)
-	   (integerp (timer--high-seconds timer))
+	   (numberp (timer--high-seconds timer))
 	   (integerp (timer--low-seconds timer))
-	   (integerp (timer--usecs timer))
+	   (numberp (timer--nsecs timer))
 	   (timer--function timer))
       (let ((timers (if idle timer-idle-list timer-list))
 	    last)
@@ -394,7 +394,7 @@
   "Perform an action the next time Emacs is idle for SECS seconds.
 The action is to call FUNCTION with arguments ARGS.
 SECS may be an integer, a floating point number, or the internal
-time format (HIGH LOW USECS) returned by, e.g., `current-idle-time'.
+time format (HIGH LOW NSECS) returned by, e.g., `current-idle-time'.
 If Emacs is currently idle, and has been idle for N seconds (N < SECS),
 then it will call FUNCTION in SECS - N seconds from now.


=== modified file 'lisp/gnus/message.el'
--- lisp/gnus/message.el	2011-06-30 01:02:47 +0000
+++ lisp/gnus/message.el	2011-07-01 05:24:16 +0000
@@ -5486,7 +5486,7 @@
 ;; You might for example insert a "." somewhere (not next to another dot
 ;; or string boundary), or modify the "fsf" string.
 (defun message-unique-id ()
-  ;; Don't use microseconds from (current-time), they may be unsupported.
+  ;; Don't use nanoseconds from (current-time), they may be unsupported.
   ;; Instead we use this randomly inited counter.
   (setq message-unique-id-char
 	(% (1+ (or message-unique-id-char (logand (random t) (1- (lsh 1 20)))))

=== modified file 'lisp/net/sasl.el'
--- lisp/net/sasl.el	2011-01-25 04:08:28 +0000
+++ lisp/net/sasl.el	2011-07-01 05:24:17 +0000
@@ -180,7 +180,7 @@

 ;; stolen (and renamed) from message.el
 (defun sasl-unique-id-function ()
-  ;; Don't use microseconds from (current-time), they may be unsupported.
+  ;; Don't use nanoseconds from (current-time), they may be unsupported.
   ;; Instead we use this randomly inited counter.
   (setq sasl-unique-id-char
 	(% (1+ (or sasl-unique-id-char (logand (random t) (1- (lsh 1 20)))))

=== modified file 'lisp/org/org-id.el'
--- lisp/org/org-id.el	2011-03-06 00:30:16 +0000
+++ lisp/org/org-id.el	2011-07-01 05:24:18 +0000
@@ -385,7 +385,7 @@
   (setq time (or time (current-time)))
   (concat (org-id-int-to-b36 (nth 0 time) 4)
 	  (org-id-int-to-b36 (nth 1 time) 4)
-	  (org-id-int-to-b36 (or (nth 2 time) 0) 4)))
+	  (org-id-int-to-b36 (/ (or (nth 2 time) 0) 1000) 4)))

 (defun org-id-decode (id)
   "Split ID into the prefix and the time value that was used to create it.
@@ -642,6 +642,3 @@
 (provide 'org-id)

 ;;; org-id.el ends here
-
-
-

=== modified file 'lisp/type-break.el'
--- lisp/type-break.el	2011-07-01 04:36:40 +0000
+++ lisp/type-break.el	2011-07-01 05:24:20 +0000
@@ -503,9 +503,9 @@
 return TIME, else return nil."
   (and (listp time)
        (eq (length time) 3)
-       (integerp (car time))
+       (numberp (car time))
        (integerp (nth 1 time))
-       (integerp (nth 2 time))
+       (numberp (nth 2 time))
        time))

 (defun type-break-choose-file ()





^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 1/7] gnulib substrate for ns-resolution time stamps
  2011-07-01  8:14 ` [PATCH 1/7] gnulib substrate for ns-resolution " Paul Eggert
@ 2011-07-01 11:20   ` Eli Zaretskii
  2011-07-01 14:13     ` Eli Zaretskii
  2011-07-01 16:27     ` Paul Eggert
  0 siblings, 2 replies; 18+ messages in thread
From: Eli Zaretskii @ 2011-07-01 11:20 UTC (permalink / raw)
  To: Paul Eggert; +Cc: emacs-devel

> Date: Fri, 01 Jul 2011 01:14:19 -0700
> From: Paul Eggert <eggert@cs.ucla.edu>
> 
> This is build boilerplate; it's all automatically generated
> or copied from gnulib.  It's probably of interest only to those
> concerned with porting to Windows.

Thanks.  Could you perhaps tell more about the changes, and what they
should provide on Windows that we don't already have?  (The diffs are
very large and I couldn't understand the gist from a cursory scan.)

The resolution of the MS-Windows system clock is 10 ms, so it hardly
makes any sense to use anything as complex as these lib/ changes, if
all we need is to add 3 more zeros to the current values.  For file
time stamps, the MS-Windows port already provides the finest possible
100-nsec resolution in the replacement `stat' (on w32.c), so again
nothing is needed, I think.  But perhaps I'm missing something, which
is why I asked the question above.



^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 1/7] gnulib substrate for ns-resolution time stamps
  2011-07-01 11:20   ` Eli Zaretskii
@ 2011-07-01 14:13     ` Eli Zaretskii
  2011-07-01 16:27     ` Paul Eggert
  1 sibling, 0 replies; 18+ messages in thread
From: Eli Zaretskii @ 2011-07-01 14:13 UTC (permalink / raw)
  To: eggert, emacs-devel

> Date: Fri, 01 Jul 2011 14:20:56 +0300
> From: Eli Zaretskii <eliz@gnu.org>
> Cc: emacs-devel@gnu.org
> 
> For file time stamps, the MS-Windows port already provides the
> finest possible 100-nsec resolution in the replacement `stat' (on
> w32.c), so again nothing is needed, I think.

Actually, this is incorrect.  We do fetch the file times with 100-nsec
resolution, but lose it because the time members of struct stat are
still declared time_t.

However, since we define our own struct stat, we can easily add to it
the members supported by stat-time.h, define the appropriate macros,
and that's all that's needed on Windows.  Or did I miss something?



^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: nanosecond-resolution time stamps
  2011-07-01  6:59 nanosecond-resolution time stamps Paul Eggert
                   ` (6 preceding siblings ...)
  2011-07-01  8:16 ` [PATCH 7/7] Lisp-level " Paul Eggert
@ 2011-07-01 15:55 ` Stefan Monnier
  2011-07-01 17:15   ` Paul Eggert
  7 siblings, 1 reply; 18+ messages in thread
From: Stefan Monnier @ 2011-07-01 15:55 UTC (permalink / raw)
  To: Paul Eggert; +Cc: Emacs Development

> Emacs currently uses microsecond-resolution time stamps internally,
> whereas GNU and similar operating systems have all gone to
> nanosecond-resolution time stamps internally.  This mismatch leads to
> problems, for example, Emacs mishandles file time stamps when it
> copies them.  I have prepared a set of patches to fix this, and would
> like them to be considered for Emacs 24 if possible or for a later
> version if not.  I'll send them in other email messages shortly.

I think I'd rather wait for Emacs-24.2 for this change, tho maybe
I could be convinced otherwise.

> The basic idea of these patches is to add 3 digits to the time stamp
> format.  For example, currently (current-time) might return
> (19981 28208 421496); with the patches, it returns
> (19981 28208 421496053) at exactly the same instant.  That is, the
> last number of the Emacs internal time stamp now counts nanoseconds,
> not microseconds.  (On older machines that do not support finegrained
> time stamps the trailing digits are always 000.)

> If we're on a 32-bit machine and the nanosecond count exceeds 2**29,
> Emacs falls back on floating point to represent the out-of-range
> integer.

So we'll fallback on a floating point here about half the time?
I don't like that idea very much, it sounds like a source of problems.
We could actually stay within the fixnum limits by using the sign
bit, but that might introduce other problems.

> This change to the internal time stamp format is an incompatible
> change and might cause problems with external packages.  If you like,
> it'd be easy to alter to the patch to use any other reasonable format.
> For example, if you'd prefer the format (19981 28208 421496 053)

That would reduce compatibility problems, most likely.
Tho we might as well add 6 more digits rather than just 3 (just so that
all the sub-second integers encode the same number of digits).
Of course using a decimal encoding sounds like we're back in the bad old
days, but I guess we're stuck with it for now.


        Stefan



^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 1/7] gnulib substrate for ns-resolution time stamps
  2011-07-01 11:20   ` Eli Zaretskii
  2011-07-01 14:13     ` Eli Zaretskii
@ 2011-07-01 16:27     ` Paul Eggert
  2011-07-01 17:39       ` Eli Zaretskii
  2011-07-01 18:50       ` Paul Eggert
  1 sibling, 2 replies; 18+ messages in thread
From: Paul Eggert @ 2011-07-01 16:27 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

On 07/01/11 04:20, Eli Zaretskii wrote:
> since we define our own struct stat, we can easily add to it
> the members supported by stat-time.h, define the appropriate macros,
> and that's all that's needed on Windows.

Yes, that should be enough to read the 100 ns-resolution file time
stamps on Windows.  It's probably simplest to define
STAT_TIMESPEC in config.h, and to emulate the corresponding
behavior in struct stat.

> Could you perhaps tell more about the changes, and what they
> should provide on Windows that we don't already have?

They let Emacs set file ns-resolution file stamps as well.
And get the time of day to ns resolution.  And set delays
to ns resolution.  There's one exception: I don't yet have interval
timers to ns resolution.  I plan to add that, but my assumption
is that this won't affect Windows because the Windows port
doesn't use setitimer anyway.

I just now reread the patch with an eye for possible porting
problems to Windows.  Here are some issues you may
want to think about.  (I don't know Windows, so I may well
have missed something.)

The Windows emulation for <time.h> will need to define struct
timespec, if it doesn't already.

The Windows port should set high-resolution file time stamps.
Perhaps the simplest would be to define HAVE_UTIMENSAT, and to define
a Windows emulation for POSIX utimensat, and then compile
lib/utimens.c.  The utimensat emulation can assume that the first
argument is always AT_FDCWD (which means the second arg
is just an ordinary file name), and that the last argument
is always zero (so symlinks are always followed).  The usual
style in utimensat emulators is to truncate file time stamps
to the greatest supported value that is not greater than the supplied time
(i.e., discard the last 2 digits of the nanosecond count when converting to
a 100-ns resolution).

Does Windows support a BSD-style nanotime () or POSIX-style
clock_gettime (CLOCK_REALTIME, x)?  If so, all you'd need to
do is to define HAVE_NANOTIME or HAVE_CLOCK_GETTIME in config.h,
and arrange to compile lib/gettime.c on Windows.  If not, you'll
also need to supply a substitute for either of those two functions;
probably nanotime () as it's simpler.

Does Windows support a POSIX-style pselect ()?  If not, it'd be
nice to add one.  It should act like select () except it uses
nanosecond-style time stamps.  Emacs doesn't use the sigmask argument
of pselect so the Windows emulation can ignore that.  Assuming that
Windows has a 100ns-resolution equivalent to select(), the pselect()
should take any delay, round it up to the nearest multiple of 100ns,
and use that multiple.  If the conversion to Windows time overflows,
I suggest using the maximum possible delay.  Alternatively, you
can simply compile lib/pselect.c, which will use the Windows select()
emulator: that'll cause the Windows port to delay up to
900 ns more than it otherwise would, but this is no big deal.

Does Windows have sys/select.h?  If not, the port can supply one,
with the appropriate declaration for pselect.

The Windows port will need to compile a few more files under lib/,
namely, dtotimespec.c, gettime.c, timespec-add.c, and
timespec-sub.c.  These should all be straightforward, assuming
the above problems are solved.



^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: nanosecond-resolution time stamps
  2011-07-01 15:55 ` nanosecond-resolution " Stefan Monnier
@ 2011-07-01 17:15   ` Paul Eggert
  2011-07-04 15:04     ` Stefan Monnier
  0 siblings, 1 reply; 18+ messages in thread
From: Paul Eggert @ 2011-07-01 17:15 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Emacs Development

>> For example, if you'd prefer the format (19981 28208 421496 053)
> 
> That would reduce compatibility problems, most likely.
> Tho we might as well add 6 more digits rather than just 3 (just so that
> all the sub-second integers encode the same number of digits).

OK, that sounds good, and I'll revise the patch to do that.

> I think I'd rather wait for Emacs-24.2 for this change, tho maybe
> I could be convinced otherwise.

Obviously there's no rush.  To be honest, though, I'd like to do it now,
since it's all in my head and I'd rather get it done while it's
relatively fresh in my mind.

What would it take to convince you?  (Could I buy you a beer maybe?  :-)

Failing that, how about if we put in the underlying machinery to
do the nanosecond time stamps, *except* that we don't expose it to
Lisp?  That is, the Lisp format is (19981 28208 421496) just as
before.  This would let us shake out all the porting glitches
at the C level, without causing any problems to Lisp users.  (On the
other hand one could argue that this approach would cost us all the
porting pain without giving us any feature gain....)




^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 1/7] gnulib substrate for ns-resolution time stamps
  2011-07-01 16:27     ` Paul Eggert
@ 2011-07-01 17:39       ` Eli Zaretskii
  2011-07-01 18:50       ` Paul Eggert
  1 sibling, 0 replies; 18+ messages in thread
From: Eli Zaretskii @ 2011-07-01 17:39 UTC (permalink / raw)
  To: Paul Eggert; +Cc: emacs-devel

> Date: Fri, 01 Jul 2011 09:27:01 -0700
> From: Paul Eggert <eggert@cs.ucla.edu>
> CC: emacs-devel@gnu.org
> 
> > Could you perhaps tell more about the changes, and what they
> > should provide on Windows that we don't already have?
> 
> They let Emacs set file ns-resolution file stamps as well.
> And get the time of day to ns resolution.  And set delays
> to ns resolution.

Yes, I understand the motivation.  But given that the Windows system
clock is millisecond resolution anyway, we cannot really take
advantage of that, can we?  So all that needs to be done on Windows is
scale the times in nanosecond units, i.e. multiply the current values
by 1000.  The rest of the complexity is not really useful, right?

> The Windows emulation for <time.h> will need to define struct
> timespec, if it doesn't already.

Which functions require that, and why?

> The Windows port should set high-resolution file time stamps.

For which primitives?  Note that copy-file already uses a
Windows-specific API which takes care of copying the file time stamp
correctly.

> Does Windows support a BSD-style nanotime () or POSIX-style
> clock_gettime (CLOCK_REALTIME, x)?

No.  We can write their emulations, but again: given the 1 to 10
millisecond resolution of the Windows system clock, why is that a good
idea?  Just taking the result of gettimeofday and multiplying the
microseconds by 1000 will give us the same result for much less
effort.

> Does Windows support a POSIX-style pselect ()?

No.  Again, since the time resolution is milliseconds, there's no real
difference between pselect and select, apart of the signature.  We
will not be able to wait less than 1 millisecond.

> Alternatively, you can simply compile lib/pselect.c, which will use
> the Windows select() emulator

I don't think this will work.  Emacs uses its own emulation of
`select'; replacing it with gnulib's will not work out of the box.



^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 1/7] gnulib substrate for ns-resolution time stamps
  2011-07-01 16:27     ` Paul Eggert
  2011-07-01 17:39       ` Eli Zaretskii
@ 2011-07-01 18:50       ` Paul Eggert
  2011-07-01 19:52         ` Eli Zaretskii
  1 sibling, 1 reply; 18+ messages in thread
From: Paul Eggert @ 2011-07-01 18:50 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

On 07/01/11 10:39, Eli Zaretskii wrote:

> given that the Windows system clock is millisecond resolution anyway

Ah, sorry, I didn't know that.  That should simplify things.

> So all that needs to be done on Windows is scale the times in
> nanosecond units, i.e. multiply the current values by 1000.

Yes, that sounds right.  If Windows is currently scaling by 1000
to get microseconds, it can simply scale by 1000*1000 to get
nanoseconds.  This should work for both file time stamps and
for the pselect emulation.  E.g., Windows can emulate pselect the
same way it emulates select, except it multiplies by another 1000.

>> The Windows emulation for <time.h> will need to define struct
>> timespec, if it doesn't already.
> 
> Which functions require that, and why?

Any function that uses EMACS_TIME, because EMACS_TIME is now struct
timespec.  At the gnulib level (which doesn't use EMACS_TIME of
course), the functions involved include get_stat_mtime,
get_stat_atime, gettime, fdutimens, and pselect.

>> The Windows port should set high-resolution file time stamps.
> 
> For which primitives?  Note that copy-file already uses a
> Windows-specific API which takes care of copying the file time stamp
> correctly.

In that case, it should work the same way as before, and there's
no need to emulate utimensat or whatever.




^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 1/7] gnulib substrate for ns-resolution time stamps
  2011-07-01 18:50       ` Paul Eggert
@ 2011-07-01 19:52         ` Eli Zaretskii
  0 siblings, 0 replies; 18+ messages in thread
From: Eli Zaretskii @ 2011-07-01 19:52 UTC (permalink / raw)
  To: Paul Eggert; +Cc: emacs-devel

> Date: Fri, 01 Jul 2011 11:50:25 -0700
> From: Paul Eggert <eggert@cs.ucla.edu>
> CC: emacs-devel@gnu.org
> 
> > So all that needs to be done on Windows is scale the times in
> > nanosecond units, i.e. multiply the current values by 1000.
> 
> Yes, that sounds right.  If Windows is currently scaling by 1000
> to get microseconds, it can simply scale by 1000*1000 to get
> nanoseconds.  This should work for both file time stamps and
> for the pselect emulation.  E.g., Windows can emulate pselect the
> same way it emulates select, except it multiplies by another 1000.

Agree about pselect, but file time stamps _are_ more fine-grained on
Windows.  So struct stat needs to be modified and stat-file.h needs to
be used, as I wrote earlier.

> >> The Windows emulation for <time.h> will need to define struct
> >> timespec, if it doesn't already.
> > 
> > Which functions require that, and why?
> 
> Any function that uses EMACS_TIME, because EMACS_TIME is now struct
> timespec.

OK, then this should be added to nt/inc/sys/time.h.

Thanks for taking your time to explain these issues.



^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: nanosecond-resolution time stamps
  2011-07-01 17:15   ` Paul Eggert
@ 2011-07-04 15:04     ` Stefan Monnier
  2011-07-05  7:13       ` Paul Eggert
  0 siblings, 1 reply; 18+ messages in thread
From: Stefan Monnier @ 2011-07-04 15:04 UTC (permalink / raw)
  To: Paul Eggert; +Cc: Emacs Development

> What would it take to convince you?  (Could I buy you a beer maybe?  :-)

Beer wouldn't cut it, sorry.  But if you can show me a bug report that
gets fixed by this, then maybe I could change my mind.


        Stefan



^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: nanosecond-resolution time stamps
  2011-07-04 15:04     ` Stefan Monnier
@ 2011-07-05  7:13       ` Paul Eggert
  0 siblings, 0 replies; 18+ messages in thread
From: Paul Eggert @ 2011-07-05  7:13 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Emacs Development

On 07/04/11 08:04, Stefan Monnier wrote:

> if you can show me a bug report that
> gets fixed by this, then maybe I could change my mind.

OK, thanks I've filed a bug report (Bug#9000) for this.

http://debbugs.gnu.org/cgi/bugreport.cgi?bug=9000

That bug report also contains the improved patch,
which causes the new (current-time) to generate the
more-compatible time stamp format (HIGH LOW USEC PSEC).



^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2011-07-05  7:13 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-07-01  6:59 nanosecond-resolution time stamps Paul Eggert
2011-07-01  8:14 ` [PATCH 1/7] gnulib substrate for ns-resolution " Paul Eggert
2011-07-01 11:20   ` Eli Zaretskii
2011-07-01 14:13     ` Eli Zaretskii
2011-07-01 16:27     ` Paul Eggert
2011-07-01 17:39       ` Eli Zaretskii
2011-07-01 18:50       ` Paul Eggert
2011-07-01 19:52         ` Eli Zaretskii
2011-07-01  8:14 ` [PATCH 2/7] etc/NEWS patch " Paul Eggert
2011-07-01  8:15 ` [PATCH 3/7] Doc patches " Paul Eggert
2011-07-01  8:15 ` [PATCH 4/7] configure-time support " Paul Eggert
2011-07-01  8:15 ` [PATCH 5/7] C-level " Paul Eggert
2011-07-01  8:16 ` [PATCH 6/7] lib-src " Paul Eggert
2011-07-01  8:16 ` [PATCH 7/7] Lisp-level " Paul Eggert
2011-07-01 15:55 ` nanosecond-resolution " Stefan Monnier
2011-07-01 17:15   ` Paul Eggert
2011-07-04 15:04     ` Stefan Monnier
2011-07-05  7:13       ` Paul Eggert

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).