From ac514c895c5586e7f9880a189203c6da3733b905 Mon Sep 17 00:00:00 2001 From: Amaury Forgeot d'Arc Date: Mon, 3 Jan 2011 00:50:57 +0000 Subject: [PATCH] Merged revisions 87666 via svnmerge from svn+ssh://pythondev@svn.python.org/python/branches/py3k ........ r87666 | amaury.forgeotdarc | 2011-01-03 01:19:11 +0100 (lun., 03 janv. 2011) | 4 lines #8278: In the Windows implementation of stat() and utime(), use time_t instead of int. This gives support for dates after 2038, at least when compiled with VS2003 or later, where time_t is 64bit. ........ --- Lib/test/test_os.py | 5 +++++ Misc/NEWS | 3 +++ Modules/posixmodule.c | 33 +++++++++++++++++++++------------ 3 files changed, 29 insertions(+), 12 deletions(-) diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index 6f4709d1751..6f6862055c4 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -322,6 +322,11 @@ class StatAttributeTests(unittest.TestCase): os.utime(self.fname, (t1, t1)) self.assertEqual(os.stat(self.fname).st_mtime, t1) + def test_large_time(self): + t1 = 5000000000 # some day in 2128 + os.utime(self.fname, (t1, t1)) + self.assertEqual(os.stat(self.fname).st_mtime, t1) + def test_1686475(self): # Verify that an open file can be stat'ed try: diff --git a/Misc/NEWS b/Misc/NEWS index c627e3135bc..9c900ffc570 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -9,6 +9,9 @@ What's New in Python 2.7.2? Core and Builtins ----------------- +- Issue #8278: On Windows and with a NTFS filesystem, os.stat() and os.utime() + can now handle dates after 2038. + - Issue #4236: Py_InitModule4 now checks the import machinery directly rather than the Py_IsInitialized flag, avoiding a Fatal Python error in certain circumstances when an import is done in __del__. diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index b1242ddf018..bcc1219666c 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -858,18 +858,18 @@ struct win32_stat{ int st_gid; int st_rdev; __int64 st_size; - int st_atime; + time_t st_atime; int st_atime_nsec; - int st_mtime; + time_t st_mtime; int st_mtime_nsec; - int st_ctime; + time_t st_ctime; int st_ctime_nsec; }; static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */ static void -FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, int *time_out, int* nsec_out) +FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, time_t *time_out, int* nsec_out) { /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */ /* Cannot simply cast and dereference in_ptr, @@ -877,12 +877,11 @@ FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, int *time_out, int* nsec_out) __int64 in; memcpy(&in, in_ptr, sizeof(in)); *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */ - /* XXX Win32 supports time stamps past 2038; we currently don't */ - *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, int); + *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, time_t); } static void -time_t_to_FILE_TIME(int time_in, int nsec_in, FILETIME *out_ptr) +time_t_to_FILE_TIME(time_t time_in, int nsec_in, FILETIME *out_ptr) { /* XXX endianness */ __int64 out; @@ -2727,15 +2726,19 @@ posix_uname(PyObject *self, PyObject *noargs) #endif /* HAVE_UNAME */ static int -extract_time(PyObject *t, long* sec, long* usec) +extract_time(PyObject *t, time_t* sec, long* usec) { - long intval; + time_t intval; if (PyFloat_Check(t)) { double tval = PyFloat_AsDouble(t); - PyObject *intobj = Py_TYPE(t)->tp_as_number->nb_int(t); + PyObject *intobj = PyNumber_Long(t); if (!intobj) return -1; +#if SIZEOF_TIME_T > SIZEOF_LONG + intval = PyInt_AsUnsignedLongLongMask(intobj); +#else intval = PyInt_AsLong(intobj); +#endif Py_DECREF(intobj); if (intval == -1 && PyErr_Occurred()) return -1; @@ -2747,7 +2750,11 @@ extract_time(PyObject *t, long* sec, long* usec) *usec = 0; return 0; } +#if SIZEOF_TIME_T > SIZEOF_LONG + intval = PyInt_AsUnsignedLongLongMask(t); +#else intval = PyInt_AsLong(t); +#endif if (intval == -1 && PyErr_Occurred()) return -1; *sec = intval; @@ -2770,7 +2777,8 @@ posix_utime(PyObject *self, PyObject *args) wchar_t *wpath = NULL; char *apath = NULL; HANDLE hFile; - long atimesec, mtimesec, ausec, musec; + time_t atimesec, mtimesec; + long ausec, musec; FILETIME atime, mtime; PyObject *result = NULL; @@ -2844,7 +2852,8 @@ done: #else /* MS_WINDOWS */ char *path = NULL; - long atime, mtime, ausec, musec; + time_t atime, mtime; + long ausec, musec; int res; PyObject* arg;