merge heads

This commit is contained in:
Benjamin Peterson 2012-12-31 21:40:42 -06:00
commit 1f7df8f207
55 changed files with 768 additions and 220 deletions

View file

@ -904,10 +904,9 @@ open_exclusive(char *filename, mode_t mode)
remove the file. */
static void
write_compiled_module(PyCodeObject *co, char *cpathname, struct stat *srcstat)
write_compiled_module(PyCodeObject *co, char *cpathname, struct stat *srcstat, time_t mtime)
{
FILE *fp;
time_t mtime = srcstat->st_mtime;
#ifdef MS_WINDOWS /* since Windows uses different permissions */
mode_t mode = srcstat->st_mode & ~S_IEXEC;
/* Issue #6074: We ensure user write access, so we can delete it later
@ -993,6 +992,38 @@ update_compiled_module(PyCodeObject *co, char *pathname)
return 1;
}
#ifdef MS_WINDOWS
/* Seconds between 1.1.1601 and 1.1.1970 */
static __int64 secs_between_epochs = 11644473600;
/* Get mtime from file pointer. */
static time_t
win32_mtime(FILE *fp, char *pathname)
{
__int64 filetime;
HANDLE fh;
BY_HANDLE_FILE_INFORMATION file_information;
fh = (HANDLE)_get_osfhandle(fileno(fp));
if (fh == INVALID_HANDLE_VALUE ||
!GetFileInformationByHandle(fh, &file_information)) {
PyErr_Format(PyExc_RuntimeError,
"unable to get file status from '%s'",
pathname);
return -1;
}
/* filetime represents the number of 100ns intervals since
1.1.1601 (UTC). Convert to seconds since 1.1.1970 (UTC). */
filetime = (__int64)file_information.ftLastWriteTime.dwHighDateTime << 32 |
file_information.ftLastWriteTime.dwLowDateTime;
return filetime / 10000000 - secs_between_epochs;
}
#endif /* #ifdef MS_WINDOWS */
/* Load a source module from a given file and return its module
object WITH INCREMENTED REFERENCE COUNT. If there's a matching
byte-compiled file, use that instead. */
@ -1006,6 +1037,7 @@ load_source_module(char *name, char *pathname, FILE *fp)
char *cpathname;
PyCodeObject *co = NULL;
PyObject *m;
time_t mtime;
if (fstat(fileno(fp), &st) != 0) {
PyErr_Format(PyExc_RuntimeError,
@ -1013,13 +1045,21 @@ load_source_module(char *name, char *pathname, FILE *fp)
pathname);
return NULL;
}
if (sizeof st.st_mtime > 4) {
#ifdef MS_WINDOWS
mtime = win32_mtime(fp, pathname);
if (mtime == (time_t)-1 && PyErr_Occurred())
return NULL;
#else
mtime = st.st_mtime;
#endif
if (sizeof mtime > 4) {
/* Python's .pyc timestamp handling presumes that the timestamp fits
in 4 bytes. Since the code only does an equality comparison,
ordering is not important and we can safely ignore the higher bits
(collisions are extremely unlikely).
*/
st.st_mtime &= 0xFFFFFFFF;
mtime &= 0xFFFFFFFF;
}
buf = PyMem_MALLOC(MAXPATHLEN+1);
if (buf == NULL) {
@ -1028,7 +1068,7 @@ load_source_module(char *name, char *pathname, FILE *fp)
cpathname = make_compiled_pathname(pathname, buf,
(size_t)MAXPATHLEN + 1);
if (cpathname != NULL &&
(fpc = check_compiled_module(pathname, st.st_mtime, cpathname))) {
(fpc = check_compiled_module(pathname, mtime, cpathname))) {
co = read_compiled_module(cpathname, fpc);
fclose(fpc);
if (co == NULL)
@ -1053,7 +1093,7 @@ load_source_module(char *name, char *pathname, FILE *fp)
if (b < 0)
goto error_exit;
if (!b)
write_compiled_module(co, cpathname, &st);
write_compiled_module(co, cpathname, &st, mtime);
}
}
m = PyImport_ExecCodeModuleEx(name, (PyObject *)co, pathname);