From: Antoine Pitrou Date: Wed, 25 Jan 2012 17:06:07 +0000 (+0100) Subject: Port import fixes from 2.7. X-Git-Tag: v3.3.0a1~306 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=581616624da7918e1050f3d02d0fb1e66e68c332;p=thirdparty%2FPython%2Fcpython.git Port import fixes from 2.7. --- 581616624da7918e1050f3d02d0fb1e66e68c332 diff --cc Python/import.c index 487347ccfbd9,beda7f97d274..d5b89d59668f --- a/Python/import.c +++ b/Python/import.c @@@ -1338,59 -1215,25 +1338,59 @@@ write_compiled_module(PyCodeObject *co return; } PyMarshal_WriteLongToFile(pyc_magic, fp, Py_MARSHAL_VERSION); - /* First write a 0 for mtime */ + /* First write a 0 for mtime and size */ + PyMarshal_WriteLongToFile(0L, fp, Py_MARSHAL_VERSION); PyMarshal_WriteLongToFile(0L, fp, Py_MARSHAL_VERSION); PyMarshal_WriteObjectToFile((PyObject *)co, fp, Py_MARSHAL_VERSION); + fflush(fp); - /* Now write the true mtime and size */ ++ /* Now write the true mtime and size (as 32-bit fields) */ + fseek(fp, 4L, 0); - assert(mtime < LONG_MAX); ++ assert(mtime <= 0xFFFFFFFF); + PyMarshal_WriteLongToFile((long)mtime, fp, Py_MARSHAL_VERSION); + PyMarshal_WriteLongToFile(size, fp, Py_MARSHAL_VERSION); if (fflush(fp) != 0 || ferror(fp)) { if (Py_VerboseFlag) - PySys_WriteStderr("# can't write %s\n", cpathname); + PySys_FormatStderr("# can't write %R\n", cpathname); /* Don't keep partial file */ fclose(fp); - (void) unlink(cpathname); +#ifdef MS_WINDOWS + (void)DeleteFileW(wpathname_tmp); + Py_DECREF(cpathname_tmp); +#else + (void) unlink(PyBytes_AS_STRING(cpathbytes_tmp)); + Py_DECREF(cpathbytes); + Py_DECREF(cpathbytes_tmp); +#endif return; } - /* Now write the true mtime (as a 32-bit field) */ - fseek(fp, 4L, 0); - assert(mtime <= 0xFFFFFFFF); - PyMarshal_WriteLongToFile((long)mtime, fp, Py_MARSHAL_VERSION); - fflush(fp); fclose(fp); + /* Do a (hopefully) atomic rename */ +#ifdef MS_WINDOWS + if (!MoveFileExW(wpathname_tmp, wpathname, MOVEFILE_REPLACE_EXISTING)) { + if (Py_VerboseFlag) + PySys_FormatStderr("# can't write %R\n", cpathname); + /* Don't keep tmp file */ + (void) DeleteFileW(wpathname_tmp); + Py_DECREF(cpathname_tmp); + return; + } + Py_DECREF(cpathname_tmp); +#else + if (rename(PyBytes_AS_STRING(cpathbytes_tmp), + PyBytes_AS_STRING(cpathbytes))) { + if (Py_VerboseFlag) + PySys_FormatStderr("# can't write %R\n", cpathname); + /* Don't keep tmp file */ + unlink(PyBytes_AS_STRING(cpathbytes_tmp)); + Py_DECREF(cpathbytes); + Py_DECREF(cpathbytes_tmp); + return; + } + Py_DECREF(cpathbytes); + Py_DECREF(cpathbytes_tmp); +#endif if (Py_VerboseFlag) - PySys_WriteStderr("# wrote %s\n", cpathname); + PySys_FormatStderr("# wrote %R\n", cpathname); } static void @@@ -1472,28 -1298,22 +1472,28 @@@ load_source_module(PyObject *name, PyOb if (fstat(fileno(fp), &st) != 0) { PyErr_Format(PyExc_RuntimeError, - "unable to get file status from '%s'", + "unable to get file status from %R", pathname); - return NULL; + goto error; } - #if SIZEOF_TIME_T > 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; - #endif + if (sizeof st.st_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; + } - cpathname = make_compiled_pathname( - pathname, buf, (size_t)MAXPATHLEN + 1, !Py_OptimizeFlag); - if (cpathname != NULL && - (fpc = check_compiled_module(pathname, st.st_mtime, cpathname))) { + if (PyUnicode_READY(pathname) < 0) + return NULL; + cpathname = make_compiled_pathname(pathname, !Py_OptimizeFlag); + + if (cpathname != NULL) + fpc = check_compiled_module(pathname, &st, cpathname); + else + fpc = NULL; + + if (fpc) { co = read_compiled_module(cpathname, fpc); fclose(fpc); if (co == NULL)