Kaydet (Commit) a251a853 authored tarafından Amaury Forgeot d'Arc's avatar Amaury Forgeot d'Arc

#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.
üst 9f6d48ba
...@@ -365,6 +365,11 @@ class StatAttributeTests(unittest.TestCase): ...@@ -365,6 +365,11 @@ class StatAttributeTests(unittest.TestCase):
os.utime(self.fname, (t1, t1)) os.utime(self.fname, (t1, t1))
self.assertEqual(os.stat(self.fname).st_mtime, 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): def test_1686475(self):
# Verify that an open file can be stat'ed # Verify that an open file can be stat'ed
try: try:
......
...@@ -8,6 +8,9 @@ What's New in Python 3.2 Release Candidate 1 ...@@ -8,6 +8,9 @@ What's New in Python 3.2 Release Candidate 1
Core and Builtins Core and Builtins
----------------- -----------------
- Issue #8278: On Windows and with a NTFS filesystem, os.stat() and os.utime()
can now handle dates after 2038.
- Issue #10780: PyErr_SetFromWindowsErrWithFilename() and - Issue #10780: PyErr_SetFromWindowsErrWithFilename() and
PyErr_SetExcFromWindowsErrWithFilename() decode the filename from the PyErr_SetExcFromWindowsErrWithFilename() decode the filename from the
filesystem encoding instead of UTF-8. filesystem encoding instead of UTF-8.
......
...@@ -976,18 +976,18 @@ struct win32_stat{ ...@@ -976,18 +976,18 @@ struct win32_stat{
int st_gid; int st_gid;
int st_rdev; int st_rdev;
__int64 st_size; __int64 st_size;
int st_atime; time_t st_atime;
int st_atime_nsec; int st_atime_nsec;
int st_mtime; time_t st_mtime;
int st_mtime_nsec; int st_mtime_nsec;
int st_ctime; time_t st_ctime;
int st_ctime_nsec; int st_ctime_nsec;
}; };
static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */ static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
static void 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 */ /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
/* Cannot simply cast and dereference in_ptr, /* Cannot simply cast and dereference in_ptr,
...@@ -995,12 +995,11 @@ FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, int *time_out, int* nsec_out) ...@@ -995,12 +995,11 @@ FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, int *time_out, int* nsec_out)
__int64 in; __int64 in;
memcpy(&in, in_ptr, sizeof(in)); memcpy(&in, in_ptr, sizeof(in));
*nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */ *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, time_t);
*time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, int);
} }
static void 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 */ /* XXX endianness */
__int64 out; __int64 out;
...@@ -3138,15 +3137,19 @@ posix_uname(PyObject *self, PyObject *noargs) ...@@ -3138,15 +3137,19 @@ posix_uname(PyObject *self, PyObject *noargs)
#endif /* HAVE_UNAME */ #endif /* HAVE_UNAME */
static int 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)) { if (PyFloat_Check(t)) {
double tval = PyFloat_AsDouble(t); double tval = PyFloat_AsDouble(t);
PyObject *intobj = Py_TYPE(t)->tp_as_number->nb_int(t); PyObject *intobj = PyNumber_Long(t);
if (!intobj) if (!intobj)
return -1; return -1;
#if SIZEOF_TIME_T > SIZEOF_LONG
intval = PyLong_AsUnsignedLongLongMask(intobj);
#else
intval = PyLong_AsLong(intobj); intval = PyLong_AsLong(intobj);
#endif
Py_DECREF(intobj); Py_DECREF(intobj);
if (intval == -1 && PyErr_Occurred()) if (intval == -1 && PyErr_Occurred())
return -1; return -1;
...@@ -3158,7 +3161,11 @@ extract_time(PyObject *t, long* sec, long* usec) ...@@ -3158,7 +3161,11 @@ extract_time(PyObject *t, long* sec, long* usec)
*usec = 0; *usec = 0;
return 0; return 0;
} }
#if SIZEOF_TIME_T > SIZEOF_LONG
intval = PyLong_AsUnsignedLongLongMask(t);
#else
intval = PyLong_AsLong(t); intval = PyLong_AsLong(t);
#endif
if (intval == -1 && PyErr_Occurred()) if (intval == -1 && PyErr_Occurred())
return -1; return -1;
*sec = intval; *sec = intval;
...@@ -3182,7 +3189,8 @@ posix_utime(PyObject *self, PyObject *args) ...@@ -3182,7 +3189,8 @@ posix_utime(PyObject *self, PyObject *args)
PyObject *oapath; PyObject *oapath;
char *apath; char *apath;
HANDLE hFile; HANDLE hFile;
long atimesec, mtimesec, ausec, musec; time_t atimesec, mtimesec;
long ausec, musec;
FILETIME atime, mtime; FILETIME atime, mtime;
PyObject *result = NULL; PyObject *result = NULL;
...@@ -3258,7 +3266,8 @@ done: ...@@ -3258,7 +3266,8 @@ done:
PyObject *opath; PyObject *opath;
char *path; char *path;
long atime, mtime, ausec, musec; time_t atime, mtime;
long ausec, musec;
int res; int res;
PyObject* arg; PyObject* arg;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment