Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 6aa9fdb

Browse files
committed
Use utimes(2) where available to support microsecond timestamps.
1 parent a32c994 commit 6aa9fdb

4 files changed

Lines changed: 55 additions & 8 deletions

File tree

Modules/posixmodule.c

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1400,6 +1400,31 @@ posix_uname(PyObject *self, PyObject *args)
14001400
}
14011401
#endif /* HAVE_UNAME */
14021402

1403+
static int
1404+
extract_time(PyObject *t, long* sec, long* usec)
1405+
{
1406+
long intval;
1407+
if (PyFloat_Check(t)) {
1408+
double tval = PyFloat_AsDouble(t);
1409+
PyObject *intobj = t->ob_type->tp_as_number->nb_int(t);
1410+
if (!intobj)
1411+
return -1;
1412+
intval = PyInt_AsLong(intobj);
1413+
Py_DECREF(intobj);
1414+
*sec = intval;
1415+
*usec = (tval - intval) * 1e6;
1416+
if (*usec < 0)
1417+
/* If rounding gave us a negative number,
1418+
truncate. */
1419+
*usec = 0;
1420+
return 0;
1421+
}
1422+
intval = PyInt_AsLong(t);
1423+
if (intval == -1 && PyErr_Occurred())
1424+
return -1;
1425+
*sec = intval;
1426+
*usec = 0;
1427+
}
14031428

14041429
PyDoc_STRVAR(posix_utime__doc__,
14051430
"utime(path, (atime, utime))\n\
@@ -1411,22 +1436,26 @@ static PyObject *
14111436
posix_utime(PyObject *self, PyObject *args)
14121437
{
14131438
char *path;
1414-
long atime, mtime;
1439+
long atime, mtime, ausec, musec;
14151440
int res;
14161441
PyObject* arg;
14171442

1443+
#if defined(HAVE_UTIMES)
1444+
struct timeval buf[2];
1445+
#define ATIME buf[0].tv_sec
1446+
#define MTIME buf[1].tv_sec
1447+
#elif defined(HAVE_UTIME_H)
14181448
/* XXX should define struct utimbuf instead, above */
1419-
#ifdef HAVE_UTIME_H
14201449
struct utimbuf buf;
14211450
#define ATIME buf.actime
14221451
#define MTIME buf.modtime
14231452
#define UTIME_ARG &buf
1424-
#else /* HAVE_UTIME_H */
1453+
#else /* HAVE_UTIMES */
14251454
time_t buf[2];
14261455
#define ATIME buf[0]
14271456
#define MTIME buf[1]
14281457
#define UTIME_ARG buf
1429-
#endif /* HAVE_UTIME_H */
1458+
#endif /* HAVE_UTIMES */
14301459

14311460
if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg))
14321461
return NULL;
@@ -1436,17 +1465,31 @@ posix_utime(PyObject *self, PyObject *args)
14361465
res = utime(path, NULL);
14371466
Py_END_ALLOW_THREADS
14381467
}
1439-
else if (!PyArg_Parse(arg, "(ll)", &atime, &mtime)) {
1468+
else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
14401469
PyErr_SetString(PyExc_TypeError,
14411470
"utime() arg 2 must be a tuple (atime, mtime)");
14421471
return NULL;
14431472
}
14441473
else {
1474+
if (extract_time(PyTuple_GET_ITEM(arg, 0),
1475+
&atime, &ausec) == -1)
1476+
return NULL;
1477+
if (extract_time(PyTuple_GET_ITEM(arg, 1),
1478+
&mtime, &musec) == -1)
1479+
return NULL;
14451480
ATIME = atime;
14461481
MTIME = mtime;
1482+
#ifdef HAVE_UTIMES
1483+
buf[0].tv_usec = ausec;
1484+
buf[1].tv_usec = musec;
1485+
Py_BEGIN_ALLOW_THREADS
1486+
res = utimes(path, buf);
1487+
Py_END_ALLOW_THREADS
1488+
#else
14471489
Py_BEGIN_ALLOW_THREADS
14481490
res = utime(path, UTIME_ARG);
14491491
Py_END_ALLOW_THREADS
1492+
#endif
14501493
}
14511494
if (res < 0)
14521495
return posix_error_with_filename(path);

configure

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#! /bin/sh
2-
# From configure.in Revision: 1.342 .
2+
# From configure.in Revision: 1.343 .
33
# Guess values for system-dependent variables and create Makefiles.
44
# Generated by GNU Autoconf 2.53.
55
#
@@ -11531,6 +11531,7 @@ echo "${ECHO_T}MACHDEP_OBJS" >&6
1153111531
1153211532
1153311533
11534+
1153411535
1153511536
1153611537
for ac_func in alarm chown chroot clock confstr ctermid ctermid_r execv \
@@ -11543,7 +11544,7 @@ for ac_func in alarm chown chroot clock confstr ctermid ctermid_r execv \
1154311544
setlocale setregid setreuid setsid setpgid setuid setvbuf snprintf \
1154411545
sigaction siginterrupt sigrelse strftime strptime symlink \
1154511546
sysconf tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \
11546-
truncate uname unsetenv waitpid _getpty getpriority
11547+
truncate uname unsetenv utimes waitpid _getpty getpriority
1154711548
do
1154811549
as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
1154911550
echo "$as_me:$LINENO: checking for $ac_func" >&5

configure.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1644,7 +1644,7 @@ AC_CHECK_FUNCS(alarm chown chroot clock confstr ctermid ctermid_r execv \
16441644
setlocale setregid setreuid setsid setpgid setuid setvbuf snprintf \
16451645
sigaction siginterrupt sigrelse strftime strptime symlink \
16461646
sysconf tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \
1647-
truncate uname unsetenv waitpid _getpty getpriority)
1647+
truncate uname unsetenv utimes waitpid _getpty getpriority)
16481648

16491649
# check for openpty and forkpty
16501650

pyconfig.h.in

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -574,6 +574,9 @@
574574
wchar_t must be 16-bit unsigned type. (see Include/unicodeobject.h). */
575575
#undef HAVE_USABLE_WCHAR_T
576576

577+
/* Define to 1 if you have the `utimes' function. */
578+
#undef HAVE_UTIMES
579+
577580
/* Define to 1 if you have the <utime.h> header file. */
578581
#undef HAVE_UTIME_H
579582

0 commit comments

Comments
 (0)