Use utimes(2) where available to support microsecond timestamps.
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
index 0c409ae..e442e79 100644
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
@@ -1400,6 +1400,31 @@
 }
 #endif /* HAVE_UNAME */
 
+static int
+extract_time(PyObject *t, long* sec, long* usec)
+{
+	long intval;
+	if (PyFloat_Check(t)) {
+		double tval = PyFloat_AsDouble(t);
+		PyObject *intobj = t->ob_type->tp_as_number->nb_int(t);
+		if (!intobj)
+			return -1;
+		intval = PyInt_AsLong(intobj);
+		Py_DECREF(intobj);
+		*sec = intval;
+		*usec = (tval - intval) * 1e6;
+		if (*usec < 0)
+			/* If rounding gave us a negative number,
+			   truncate.  */
+			*usec = 0;
+		return 0;
+	}
+	intval = PyInt_AsLong(t);
+	if (intval == -1 && PyErr_Occurred())
+		return -1;
+	*sec = intval;
+	*usec = 0;
+}
 
 PyDoc_STRVAR(posix_utime__doc__,
 "utime(path, (atime, utime))\n\
@@ -1411,22 +1436,26 @@
 posix_utime(PyObject *self, PyObject *args)
 {
 	char *path;
-	long atime, mtime;
+	long atime, mtime, ausec, musec;
 	int res;
 	PyObject* arg;
 
+#if defined(HAVE_UTIMES)
+	struct timeval buf[2];
+#define ATIME buf[0].tv_sec
+#define MTIME buf[1].tv_sec
+#elif defined(HAVE_UTIME_H)
 /* XXX should define struct utimbuf instead, above */
-#ifdef HAVE_UTIME_H
 	struct utimbuf buf;
 #define ATIME buf.actime
 #define MTIME buf.modtime
 #define UTIME_ARG &buf
-#else /* HAVE_UTIME_H */
+#else /* HAVE_UTIMES */
 	time_t buf[2];
 #define ATIME buf[0]
 #define MTIME buf[1]
 #define UTIME_ARG buf
-#endif /* HAVE_UTIME_H */
+#endif /* HAVE_UTIMES */
 
 	if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg))
 		return NULL;
@@ -1436,17 +1465,31 @@
 		res = utime(path, NULL);
 		Py_END_ALLOW_THREADS
 	}
-	else if (!PyArg_Parse(arg, "(ll)", &atime, &mtime)) {
+	else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
 		PyErr_SetString(PyExc_TypeError,
 				"utime() arg 2 must be a tuple (atime, mtime)");
 		return NULL;
 	}
 	else {
+		if (extract_time(PyTuple_GET_ITEM(arg, 0),
+				 &atime, &ausec) == -1)
+			return NULL;
+		if (extract_time(PyTuple_GET_ITEM(arg, 1),
+				 &mtime, &musec) == -1)
+			return NULL;
 		ATIME = atime;
 		MTIME = mtime;
+#ifdef HAVE_UTIMES
+		buf[0].tv_usec = ausec;
+		buf[1].tv_usec = musec;
+		Py_BEGIN_ALLOW_THREADS
+		res = utimes(path, buf);
+		Py_END_ALLOW_THREADS
+#else
 		Py_BEGIN_ALLOW_THREADS
 		res = utime(path, UTIME_ARG);
 		Py_END_ALLOW_THREADS
+#endif
 	}
 	if (res < 0)
 		return posix_error_with_filename(path);
diff --git a/configure b/configure
index c23b45f..e3100a8 100755
--- a/configure
+++ b/configure
@@ -1,5 +1,5 @@
 #! /bin/sh
-# From configure.in Revision: 1.342 .
+# From configure.in Revision: 1.343 .
 # Guess values for system-dependent variables and create Makefiles.
 # Generated by GNU Autoconf 2.53.
 #
@@ -11533,6 +11533,7 @@
 
 
 
+
 for ac_func in alarm chown chroot clock confstr ctermid ctermid_r execv \
  fchdir flock fork fsync fdatasync fpathconf ftime ftruncate \
  gai_strerror getgroups getlogin getpeername getpgid getpid getpwent getwd \
@@ -11543,7 +11544,7 @@
  setlocale setregid setreuid setsid setpgid setuid setvbuf snprintf \
  sigaction siginterrupt sigrelse strftime strptime symlink \
  sysconf tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \
- truncate uname unsetenv waitpid _getpty getpriority
+ truncate uname unsetenv utimes waitpid _getpty getpriority
 do
 as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
 echo "$as_me:$LINENO: checking for $ac_func" >&5
diff --git a/configure.in b/configure.in
index 037dc45..2954255 100644
--- a/configure.in
+++ b/configure.in
@@ -1644,7 +1644,7 @@
  setlocale setregid setreuid setsid setpgid setuid setvbuf snprintf \
  sigaction siginterrupt sigrelse strftime strptime symlink \
  sysconf tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \
- truncate uname unsetenv waitpid _getpty getpriority)
+ truncate uname unsetenv utimes waitpid _getpty getpriority)
 
 # check for openpty and forkpty
 
diff --git a/pyconfig.h.in b/pyconfig.h.in
index d664860..3622be8 100644
--- a/pyconfig.h.in
+++ b/pyconfig.h.in
@@ -574,6 +574,9 @@
    wchar_t must be 16-bit unsigned type. (see Include/unicodeobject.h). */
 #undef HAVE_USABLE_WCHAR_T
 
+/* Define to 1 if you have the `utimes' function. */
+#undef HAVE_UTIMES
+
 /* Define to 1 if you have the <utime.h> header file. */
 #undef HAVE_UTIME_H