Use PyUnicode_FromFormat() to create the temporary file name.

Also, as in importlib, append the id of an object to make the file name
pseudo-random.
This commit is contained in:
Antoine Pitrou 2011-11-15 22:27:32 +01:00
parent 6166519d2b
commit 8ad982cccf
1 changed files with 15 additions and 28 deletions

View File

@ -1195,17 +1195,15 @@ write_compiled_module(PyCodeObject *co, PyObject *cpathname,
Py_UCS4 *cpathname_ucs4; Py_UCS4 *cpathname_ucs4;
FILE *fp; FILE *fp;
time_t mtime = srcstat->st_mtime; time_t mtime = srcstat->st_mtime;
PyObject *cpathname_tmp;
#ifdef MS_WINDOWS /* since Windows uses different permissions */ #ifdef MS_WINDOWS /* since Windows uses different permissions */
mode_t mode = srcstat->st_mode & ~S_IEXEC; mode_t mode = srcstat->st_mode & ~S_IEXEC;
PyObject *cpathname_tmp;
Py_ssize_t cpathname_len;
#else #else
mode_t dirmode = (srcstat->st_mode | mode_t dirmode = (srcstat->st_mode |
S_IXUSR | S_IXGRP | S_IXOTH | S_IXUSR | S_IXGRP | S_IXOTH |
S_IWUSR | S_IWGRP | S_IWOTH); S_IWUSR | S_IWGRP | S_IWOTH);
PyObject *dirbytes; PyObject *dirbytes;
PyObject *cpathbytes, *cpathbytes_tmp; PyObject *cpathbytes, *cpathbytes_tmp;
Py_ssize_t cpathbytes_len;
#endif #endif
int fd; int fd;
PyObject *dirname; PyObject *dirname;
@ -1258,24 +1256,18 @@ write_compiled_module(PyCodeObject *co, PyObject *cpathname,
Py_DECREF(dirname); Py_DECREF(dirname);
/* We first write to a tmp file and then take advantage /* We first write to a tmp file and then take advantage
of atomic renaming (which *should* be true even under Windows). */ of atomic renaming (which *should* be true even under Windows).
#ifdef MS_WINDOWS As in importlib, we use id(something) to generate a pseudo-random
cpathname_len = PyUnicode_GET_LENGTH(cpathname); filename. mkstemp() can't be used since it doesn't allow specifying
cpathname_tmp = PyUnicode_New(cpathname_len + 4, the file access permissions.
PyUnicode_MAX_CHAR_VALUE(cpathname)); */
cpathname_tmp = PyUnicode_FromFormat("%U.%zd",
cpathname, (Py_ssize_t) co);
if (cpathname_tmp == NULL) { if (cpathname_tmp == NULL) {
PyErr_Clear(); PyErr_Clear();
return; return;
} }
if (PyUnicode_CopyCharacters(cpathname_tmp, 0, #ifdef MS_WINDOWS
cpathname, 0, cpathname_len) < 0) {
PyErr_Clear();
return;
}
PyUnicode_WriteChar(cpathname_tmp, cpathname_len + 0, '.');
PyUnicode_WriteChar(cpathname_tmp, cpathname_len + 1, 't');
PyUnicode_WriteChar(cpathname_tmp, cpathname_len + 2, 'm');
PyUnicode_WriteChar(cpathname_tmp, cpathname_len + 3, 'p');
(void)DeleteFileW(PyUnicode_AS_UNICODE(cpathname_tmp)); (void)DeleteFileW(PyUnicode_AS_UNICODE(cpathname_tmp));
fd = _wopen(PyUnicode_AS_UNICODE(cpathname_tmp), fd = _wopen(PyUnicode_AS_UNICODE(cpathname_tmp),
O_EXCL | O_CREAT | O_WRONLY | O_BINARY, O_EXCL | O_CREAT | O_WRONLY | O_BINARY,
@ -1285,22 +1277,17 @@ write_compiled_module(PyCodeObject *co, PyObject *cpathname,
else else
fp = NULL; fp = NULL;
#else #else
cpathbytes_tmp = PyUnicode_EncodeFSDefault(cpathname_tmp);
Py_DECREF(cpathname_tmp);
if (cpathbytes_tmp == NULL) {
PyErr_Clear();
return;
}
cpathbytes = PyUnicode_EncodeFSDefault(cpathname); cpathbytes = PyUnicode_EncodeFSDefault(cpathname);
if (cpathbytes == NULL) { if (cpathbytes == NULL) {
PyErr_Clear(); PyErr_Clear();
return; return;
} }
cpathbytes_len = PyBytes_GET_SIZE(cpathbytes);
cpathbytes_tmp = PyBytes_FromStringAndSize(NULL, cpathbytes_len + 4);
if (cpathbytes_tmp == NULL) {
Py_DECREF(cpathbytes);
PyErr_Clear();
return;
}
memcpy(PyBytes_AS_STRING(cpathbytes_tmp), PyBytes_AS_STRING(cpathbytes),
cpathbytes_len);
memcpy(PyBytes_AS_STRING(cpathbytes_tmp) + cpathbytes_len, ".tmp", 4);
fd = open(PyBytes_AS_STRING(cpathbytes_tmp), fd = open(PyBytes_AS_STRING(cpathbytes_tmp),
O_CREAT | O_EXCL | O_WRONLY, 0666); O_CREAT | O_EXCL | O_WRONLY, 0666);
if (0 <= fd) if (0 <= fd)